Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 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
bd6034d
Merge branch 'master' into release/5.36.0
piyalbasu Nov 21, 2025
1f3710d
use redux selector for allAccounts to properly update rename (#2403)
piyalbasu Nov 21, 2025
50cde89
Add docs for 5.36.0 (#2408)
piyalbasu Nov 24, 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