Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
45323d4
Feature/move history fetch to bg (#2273)
piyalbasu Oct 7, 2025
b61ec65
check for updated appdata before showing password modal (#2300)
piyalbasu Oct 8, 2025
91a49a5
stringify errors rather than using `cause` (#2302)
piyalbasu Oct 9, 2025
cc130fc
Feature/move icons to own hook (#2308)
piyalbasu Oct 15, 2025
c50cbc1
skip blockaid scan on first fetch of account-balances (#2310)
piyalbasu Oct 17, 2025
89b00b0
Merge branch 'master' into release/5.36.0
piyalbasu Oct 23, 2025
47203df
Dropdown menu option to copy wallet address (#2316)
leofelix077 Oct 27, 2025
3da9b6b
scroll on long strings; pretty print json (#2320)
piyalbasu Oct 27, 2025
9218e3f
Merge branch 'master' into release/5.36.0
aristidesstaffieri Oct 29, 2025
077117e
re-searching so should abort any in flight API requests (#2323)
piyalbasu Oct 30, 2025
45f8bd6
[FEATURE] new send/swap navigation flow (#2353)
aristidesstaffieri Nov 5, 2025
1779c51
[FEATURE] adds send and swap buttons to asset detail view (#2351)
aristidesstaffieri Nov 7, 2025
5199754
only fetch asset list data if needed (#2369)
piyalbasu Nov 7, 2025
cdafa95
[BUG] SAC token management improvements (#2374)
aristidesstaffieri Nov 10, 2025
85014fb
Merge branch 'master' into release/5.36.0
piyalbasu Nov 11, 2025
5e591ce
Feature/cache token prices (#2373)
piyalbasu Nov 11, 2025
6268562
load backend settings async on Account view (#2381)
piyalbasu Nov 13, 2025
4f2b5c6
Feature/use ledger key for home domains (#2363)
piyalbasu Nov 14, 2025
9a0dd5e
update version numbers for release
piyalbasu Nov 17, 2025
0aed2a4
rm unnecessary calls to make flows even faster (#2391)
piyalbasu Nov 19, 2025
1e8117a
makes send swap buttons stay in the container in full screen mode (#2…
piyalbasu Nov 19, 2025
d50e25b
add v1 of memo-required flow for transaction confirmation
leofelix077 Nov 20, 2025
631356b
adjust memo required flow for dapp and tx rebuild
leofelix077 Nov 21, 2025
f4bb26b
add memo max bytes error handling
leofelix077 Nov 21, 2025
37ab418
update transaction loose text strings
leofelix077 Nov 21, 2025
adbb936
update transaction loose text strings
leofelix077 Nov 21, 2025
5ef1a5b
Merge branch 'master' into feature/check-memo-required-on-send
leofelix077 Nov 21, 2025
d33b807
update tranlation with uppercase
leofelix077 Nov 21, 2025
6f912f8
Merge branch 'feature/check-memo-required-on-send' of github.com:stel…
leofelix077 Nov 21, 2025
99b5099
fix transaction fee setting
leofelix077 Nov 21, 2025
63ddc20
Merge branch 'release/5.36.0' of github.com:stellar/freighter into fe…
leofelix077 Nov 21, 2025
bd6034d
Merge branch 'master' into release/5.36.0
piyalbasu Nov 21, 2025
2b20b9d
Merge branch 'release/5.36.0' of github.com:stellar/freighter into fe…
leofelix077 Nov 21, 2025
ad3091e
adjust memo required on revalidation and add a container for message
leofelix077 Nov 21, 2025
4e74e54
update memo-required flow to slide from right
leofelix077 Nov 21, 2025
619a4af
update translation keys and memo required panes
leofelix077 Nov 21, 2025
1f3710d
use redux selector for allAccounts to properly update rename (#2403)
piyalbasu Nov 21, 2025
dc88115
Merge branch 'release/5.36.0' of github.com:stellar/freighter into fe…
leofelix077 Nov 21, 2025
7d52b3e
fix unit tests
leofelix077 Nov 21, 2025
1e9be95
Merge branch 'release/5.37.0' of github.com:stellar/freighter into fe…
leofelix077 Nov 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions @shared/api/__tests__/internal.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { TESTNET_NETWORK_DETAILS } from "@shared/constants/stellar";
import * as GetLedgerKeyAccounts from "../helpers/getLedgerKeyAccounts";
import * as internalApi from "../internal";

describe("internalApi", () => {
afterEach(() => {
jest.clearAllMocks();
});
describe("getAssetDomains", () => {
it("should return a list of domains from a list of issuers", async () => {
jest
.spyOn(GetLedgerKeyAccounts, "getLedgerKeyAccounts")
.mockResolvedValue({
G1: {
account_id:
"GDF32CQINROD3E2LMCGZUDVMWTXCJFR5SBYVRJ7WAAIAS3P7DCVWZEFY",
home_domain: "stellar1.org",
balance: "1000000000000000000",
seq_num: 1,
num_sub_entries: 1,
inflation_dest: "G1",
flags: 1,
thresholds: "1000000000000000000",
signers: [
{
key: "GDF32CQINROD3E2LMCGZUDVMWTXCJFR5SBYVRJ7WAAIAS3P7DCVWZEFY",
weight: 1,
},
],
sequence_number: 1,
},
G2: {
account_id:
"GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
home_domain: "stellar2.org",
balance: "1000000000000000000",
seq_num: 1,
num_sub_entries: 1,
inflation_dest:
"GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
flags: 1,
thresholds: "1000000000000000000",
signers: [
{
key: "GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
weight: 1,
},
],
sequence_number: 1,
},
});
const assetDomains = await internalApi.getAssetDomains({
assetIssuerDomainsToFetch: [
"GDF32CQINROD3E2LMCGZUDVMWTXCJFR5SBYVRJ7WAAIAS3P7DCVWZEFY",
"GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
],
networkDetails: TESTNET_NETWORK_DETAILS,
});

expect(assetDomains).toEqual({
G1: "stellar1.org",
G2: "stellar2.org",
});
});
it("should return an empty object if the fetch fails", async () => {
jest
.spyOn(GetLedgerKeyAccounts, "getLedgerKeyAccounts")
.mockRejectedValue(new Error("Fetch failed"));
const assetDomains = await internalApi.getAssetDomains({
assetIssuerDomainsToFetch: ["G1", "G2"],
networkDetails: TESTNET_NETWORK_DETAILS,
});
expect(assetDomains).toEqual({});
});
it("should return an empty object if not valid public keys are provided", async () => {
const getLedgerKeyAccountsSpy = jest.spyOn(
GetLedgerKeyAccounts,
"getLedgerKeyAccounts",
);
const assetDomains = await internalApi.getAssetDomains({
assetIssuerDomainsToFetch: [
"CAZXRTOKNUQ2JQQF3NCRU7GYMDJNZ2NMQN6IGN4FCT5DWPODMPVEXSND",
],
networkDetails: TESTNET_NETWORK_DETAILS,
});
expect(getLedgerKeyAccountsSpy).not.toHaveBeenCalled();
expect(assetDomains).toEqual({});
});
});
});
93 changes: 93 additions & 0 deletions @shared/api/helpers/__tests__/getIconUrlFromIssuer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { TESTNET_NETWORK_DETAILS } from "@shared/constants/stellar";
import { getIconUrlFromIssuer } from "../getIconUrlFromIssuer";
import * as ExtensionMessaging from "@shared/api/helpers/extensionMessaging";
import * as ApiInternal from "@shared/api/internal";

jest.mock("stellar-sdk", () => {
const original = jest.requireActual("stellar-sdk");
return {
...original,
StellarToml: {
Resolver: {
resolve: jest.fn().mockResolvedValue({
CURRENCIES: [
{
code: "USDC",
issuer:
"GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
image: "http://tomldomain.com/baz.png",
},
],
}),
},
},
};
});

describe("getIconUrlFromIssuer", () => {
afterEach(() => {
jest.clearAllMocks();
});
it("should return the icon url for a given issuer from the background cache", async () => {
jest
.spyOn(ExtensionMessaging, "sendMessageToBackground")
.mockImplementationOnce(() =>
Promise.resolve({
iconUrl: "http://bgdomain.com/baz.png",
} as any),
);
const iconUrl = await getIconUrlFromIssuer({
key: "GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
code: "USDC",
networkDetails: TESTNET_NETWORK_DETAILS,
});
expect(iconUrl).toBe("http://bgdomain.com/baz.png");
});
it("should return the icon url for a given issuer from a passed home domain", async () => {
// mock both calls to the background
jest
.spyOn(ExtensionMessaging, "sendMessageToBackground")
.mockImplementationOnce(() => Promise.resolve({} as any));
jest
.spyOn(ExtensionMessaging, "sendMessageToBackground")
.mockImplementationOnce(() => Promise.resolve({} as any));
const iconUrl = await getIconUrlFromIssuer({
key: "GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
code: "USDC",
networkDetails: TESTNET_NETWORK_DETAILS,
homeDomain: "http://home.com/baz.png",
});
expect(iconUrl).toBe("http://tomldomain.com/baz.png");
});
it("should return the icon url for a given issuer from a passed home domain", async () => {
// mock both calls to the background
jest
.spyOn(ExtensionMessaging, "sendMessageToBackground")
.mockImplementationOnce(() => Promise.resolve({} as any));
jest
.spyOn(ExtensionMessaging, "sendMessageToBackground")
.mockImplementationOnce(() => Promise.resolve({} as any));

const getAssetDomainsSpy = jest
.spyOn(ApiInternal, "getAssetDomains")
.mockImplementationOnce(() =>
Promise.resolve({
GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH:
"http://ledgerkeydomain.com/baz.png",
}),
);
const iconUrl = await getIconUrlFromIssuer({
key: "GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
code: "USDC",
networkDetails: TESTNET_NETWORK_DETAILS,
});

expect(getAssetDomainsSpy).toHaveBeenCalledWith({
assetIssuerDomainsToFetch: [
"GBKWMR7TJ7BBICOOXRY2SWXKCWPTOHZPI6MP4LNNE5A73VP3WADGG3CH",
],
networkDetails: TESTNET_NETWORK_DETAILS,
});
expect(iconUrl).toBe("http://tomldomain.com/baz.png");
});
});
92 changes: 92 additions & 0 deletions @shared/api/helpers/__tests__/getLedgerKeyAccounts.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { TESTNET_NETWORK_DETAILS } from "@shared/constants/stellar";
import { getLedgerKeyAccounts } from "../getLedgerKeyAccounts";

describe("getDomainFromIssuer", () => {
it("should return a list of domains from a list of issuers", async () => {
const fetchSpy = jest.spyOn(global, "fetch").mockImplementation(() =>
Promise.resolve({
ok: true,
json: () =>
Promise.resolve({
data: {
ledger_key_accounts: {
G1: { account_id: "G1", home_domain: "stellar1.org" },
g2: { account_id: "g2", home_domain: "stellar2.org" },
},
},
}),
} as any),
);
const ledgerKeyAccounts = await getLedgerKeyAccounts({
accountList: ["G1", "g2"],
networkDetails: TESTNET_NETWORK_DETAILS,
});

expect(fetchSpy).toHaveBeenCalledWith(
new URL(
"http://localhost:3003/api/v1/ledger-key/accounts?network=TESTNET",
),
{
body: '{"public_keys":["G1","g2"]}',
headers: { "Content-Type": "application/json" },
method: "POST",
},
);

expect(ledgerKeyAccounts).toEqual({
G1: { account_id: "G1", home_domain: "stellar1.org" },
g2: { account_id: "g2", home_domain: "stellar2.org" },
});
});
it("should return an empty object if the fetch fails", async () => {
const fetchSpy = jest.spyOn(global, "fetch").mockImplementation(() =>
Promise.resolve({
ok: false,
} as any),
);
const ledgerKeyAccounts = await getLedgerKeyAccounts({
accountList: ["G1", "g2"],
networkDetails: TESTNET_NETWORK_DETAILS,
});

expect(fetchSpy).toHaveBeenCalledWith(
new URL(
"http://localhost:3003/api/v1/ledger-key/accounts?network=TESTNET",
),
{
body: '{"public_keys":["G1","g2"]}',
headers: { "Content-Type": "application/json" },
method: "POST",
},
);

expect(ledgerKeyAccounts).toEqual({});
});

it("should return an empty object if the fetch returns an error", async () => {
const fetchSpy = jest.spyOn(global, "fetch").mockImplementation(() =>
Promise.resolve({
ok: true,
json: () => Promise.resolve({ error: "test" }),
} as any),
);

const ledgerKeyAccounts = await getLedgerKeyAccounts({
accountList: ["G1", "g2"],
networkDetails: TESTNET_NETWORK_DETAILS,
});

expect(fetchSpy).toHaveBeenCalledWith(
new URL(
"http://localhost:3003/api/v1/ledger-key/accounts?network=TESTNET",
),
{
body: '{"public_keys":["G1","g2"]}',
headers: { "Content-Type": "application/json" },
method: "POST",
},
);

expect(ledgerKeyAccounts).toEqual({});
});
});
58 changes: 0 additions & 58 deletions @shared/api/helpers/getDomainFromIssuer.ts

This file was deleted.

13 changes: 13 additions & 0 deletions @shared/api/helpers/getIconFromTokenList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {
import { NetworkDetails } from "@shared/constants/stellar";
import { getCanonicalFromAsset } from "@shared/helpers/stellar";

import { sendMessageToBackground } from "./extensionMessaging";
import { SERVICE_TYPES } from "../../constants/services";

export const getIconFromTokenLists = async ({
issuerId,
contractId,
Expand Down Expand Up @@ -36,6 +39,7 @@ export const getIconFromTokenLists = async ({
issuerId &&
record.issuer &&
record.issuer === issuerId &&
record.code === code &&
record.icon
) {
verifiedToken = record;
Expand All @@ -46,6 +50,15 @@ export const getIconFromTokenLists = async ({
}
}

if (verifiedToken?.icon) {
await sendMessageToBackground({
activePublicKey: null,
assetCanonical: `${code}:${contractId || issuerId}`,
iconUrl: verifiedToken?.icon,
type: SERVICE_TYPES.CACHE_ASSET_ICON,
});
}

return {
icon: verifiedToken?.icon,
canonicalAsset,
Expand Down
Loading
Loading