@ledgerhq/coin-sui 0.17.0-nightly.2 → 0.17.0-nightly.20251030160608
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +20 -20
- package/lib/bridge/preload.js +2 -2
- package/lib/bridge/preload.js.map +1 -1
- package/lib/bridge/synchronisation.d.ts.map +1 -1
- package/lib/bridge/synchronisation.js +19 -20
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib/network/index.d.ts +1 -5
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/sdk.d.ts +6 -5
- package/lib/network/sdk.d.ts.map +1 -1
- package/lib/network/sdk.js +11 -3
- package/lib/network/sdk.js.map +1 -1
- package/lib/test/bridge.dataset.d.ts.map +1 -1
- package/lib/test/bridge.dataset.js +1 -0
- package/lib/test/bridge.dataset.js.map +1 -1
- package/lib/types/bridge.d.ts +1 -0
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib-es/bridge/preload.js +1 -1
- package/lib-es/bridge/preload.js.map +1 -1
- package/lib-es/bridge/synchronisation.d.ts.map +1 -1
- package/lib-es/bridge/synchronisation.js +19 -20
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/lib-es/network/index.d.ts +1 -5
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/sdk.d.ts +6 -5
- package/lib-es/network/sdk.d.ts.map +1 -1
- package/lib-es/network/sdk.js +11 -3
- package/lib-es/network/sdk.js.map +1 -1
- package/lib-es/test/bridge.dataset.d.ts.map +1 -1
- package/lib-es/test/bridge.dataset.js +1 -0
- package/lib-es/test/bridge.dataset.js.map +1 -1
- package/lib-es/types/bridge.d.ts +1 -0
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/bridge/preload.ts +1 -1
- package/src/bridge/synchronisation.test.ts +118 -5
- package/src/bridge/synchronisation.ts +31 -29
- package/src/logic/estimateFees.integration.test.ts +1 -1
- package/src/network/sdk.test.ts +22 -0
- package/src/network/sdk.ts +21 -4
- package/src/test/bridge.dataset.ts +1 -0
- package/src/types/bridge.ts +1 -0
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
type GetAccountShape,
|
|
11
11
|
} from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
12
12
|
import { type Operation } from "@ledgerhq/types-live";
|
|
13
|
-
import { listTokensForCryptoCurrency } from "@ledgerhq/cryptoassets/tokens";
|
|
14
13
|
import { getAccountBalances, getOperations, getStakesRaw } from "../network";
|
|
15
|
-
import { DEFAULT_COIN_TYPE } from "../network/sdk";
|
|
14
|
+
import { AccountBalance, DEFAULT_COIN_TYPE } from "../network/sdk";
|
|
16
15
|
import { SuiOperationExtra, SuiAccount } from "../types";
|
|
17
16
|
import type { SyncConfig, TokenAccount } from "@ledgerhq/types-live";
|
|
18
17
|
import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
|
|
19
18
|
import { promiseAllBatched } from "@ledgerhq/live-promise";
|
|
19
|
+
import { getCryptoAssetsStore } from "@ledgerhq/coin-framework/crypto-assets/index";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Get the shape of the account including its operations and balance.
|
|
@@ -53,28 +53,28 @@ export const getAccountShape: GetAccountShape<SuiAccount> = async (info, syncCon
|
|
|
53
53
|
);
|
|
54
54
|
|
|
55
55
|
const accountBalances = await getAccountBalances(address);
|
|
56
|
-
const tokensCurrencies = listTokensForCryptoCurrency(currency);
|
|
57
|
-
const tokensCurrenciesMap = tokensCurrencies.reduce(
|
|
58
|
-
(acc, token) => {
|
|
59
|
-
acc[token.contractAddress] = token;
|
|
60
|
-
return acc;
|
|
61
|
-
},
|
|
62
|
-
{} as Record<string, (typeof tokensCurrencies)[0]>,
|
|
63
|
-
);
|
|
64
56
|
const balance =
|
|
65
57
|
accountBalances.find(({ coinType }) => coinType === DEFAULT_COIN_TYPE)?.balance ?? BigNumber(0);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
58
|
+
|
|
59
|
+
const subAccountsBalances: AccountBalance[] = [];
|
|
60
|
+
for (const accountBalance of accountBalances) {
|
|
61
|
+
const token = await getCryptoAssetsStore().findTokenByAddressInCurrency(
|
|
62
|
+
accountBalance.coinType,
|
|
63
|
+
currency.id,
|
|
64
|
+
);
|
|
65
|
+
if (token) {
|
|
66
|
+
subAccountsBalances.push(accountBalance);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
69
|
|
|
70
70
|
const subAccounts =
|
|
71
71
|
(await buildSubAccounts({
|
|
72
72
|
accountId,
|
|
73
|
-
initialAccount,
|
|
74
73
|
operations,
|
|
75
74
|
subAccountsBalances,
|
|
76
75
|
syncConfig,
|
|
77
|
-
|
|
76
|
+
currencyId: currency.id,
|
|
77
|
+
subAccounts: initialAccount?.subAccounts ?? [],
|
|
78
78
|
})) || [];
|
|
79
79
|
|
|
80
80
|
return {
|
|
@@ -102,39 +102,41 @@ export const sync = makeSync({ getAccountShape, shouldMergeOps: false });
|
|
|
102
102
|
|
|
103
103
|
async function buildSubAccounts({
|
|
104
104
|
accountId,
|
|
105
|
-
initialAccount,
|
|
106
105
|
operations,
|
|
107
106
|
subAccountsBalances,
|
|
108
107
|
syncConfig,
|
|
109
|
-
|
|
108
|
+
currencyId,
|
|
109
|
+
subAccounts,
|
|
110
110
|
}: {
|
|
111
111
|
accountId: string;
|
|
112
|
-
initialAccount?: SuiAccount | null | undefined;
|
|
113
112
|
operations: Operation[];
|
|
114
113
|
subAccountsBalances: { coinType: string; blockHeight: number; balance: BigNumber }[];
|
|
115
114
|
syncConfig: SyncConfig;
|
|
116
|
-
|
|
115
|
+
currencyId: string;
|
|
116
|
+
subAccounts: TokenAccount[];
|
|
117
117
|
}) {
|
|
118
|
-
if (
|
|
118
|
+
if (subAccountsBalances.length === 0) return undefined;
|
|
119
119
|
const { blacklistedTokenIds = [] } = syncConfig;
|
|
120
120
|
const tokenAccounts: TokenAccount[] = [];
|
|
121
121
|
const existingAccountByTicker: { [ticker: string]: TokenAccount } = {}; // used for fast lookup
|
|
122
122
|
const existingAccountTickers: string[] = []; // used to keep track of ordering
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
existingAccountByTicker[ticker] = existingSubAccount;
|
|
131
|
-
}
|
|
124
|
+
for (const existingSubAccount of subAccounts) {
|
|
125
|
+
if (existingSubAccount.type === "TokenAccount") {
|
|
126
|
+
const { ticker, id } = existingSubAccount.token;
|
|
127
|
+
if (!blacklistedTokenIds.includes(id)) {
|
|
128
|
+
existingAccountTickers.push(ticker);
|
|
129
|
+
existingAccountByTicker[ticker] = existingSubAccount;
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
132
|
}
|
|
135
133
|
|
|
136
134
|
await promiseAllBatched(3, subAccountsBalances, async accountBalance => {
|
|
137
|
-
const token =
|
|
135
|
+
const token = await getCryptoAssetsStore().findTokenByAddressInCurrency(
|
|
136
|
+
accountBalance.coinType,
|
|
137
|
+
currencyId,
|
|
138
|
+
);
|
|
139
|
+
|
|
138
140
|
if (token && !blacklistedTokenIds.includes(token.id)) {
|
|
139
141
|
const initialTokenAccount = existingAccountByTicker[token.ticker];
|
|
140
142
|
const tokenAccount = await buildSubAccount({
|
|
@@ -3,7 +3,7 @@ import { getFullnodeUrl } from "@mysten/sui/client";
|
|
|
3
3
|
import coinConfig from "../config";
|
|
4
4
|
import { estimateFees } from "./estimateFees";
|
|
5
5
|
|
|
6
|
-
const SENDER = "
|
|
6
|
+
const SENDER = "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164";
|
|
7
7
|
const RECIPIENT = "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164";
|
|
8
8
|
|
|
9
9
|
describe("estimateFees", () => {
|
package/src/network/sdk.test.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
TransactionBlockData,
|
|
8
8
|
SuiTransactionBlockResponse,
|
|
9
9
|
SuiTransactionBlockKind,
|
|
10
|
+
PaginatedTransactionResponse,
|
|
10
11
|
} from "@mysten/sui/client";
|
|
11
12
|
import assert, { fail } from "assert";
|
|
12
13
|
|
|
@@ -2121,6 +2122,27 @@ describe("getCoinsForAmount", () => {
|
|
|
2121
2122
|
});
|
|
2122
2123
|
});
|
|
2123
2124
|
|
|
2125
|
+
describe.only("dedup", () => {
|
|
2126
|
+
const outs: PaginatedTransactionResponse = {
|
|
2127
|
+
data: [],
|
|
2128
|
+
hasNextPage: false,
|
|
2129
|
+
};
|
|
2130
|
+
const ins: PaginatedTransactionResponse = {
|
|
2131
|
+
data: [],
|
|
2132
|
+
hasNextPage: true,
|
|
2133
|
+
};
|
|
2134
|
+
|
|
2135
|
+
test("handles no data in asc mode", async () => {
|
|
2136
|
+
const r = sdk.dedupOperations(outs, ins, "asc");
|
|
2137
|
+
expect(r.operations.length).toBe(0);
|
|
2138
|
+
});
|
|
2139
|
+
|
|
2140
|
+
test("handles no data in desc mode", async () => {
|
|
2141
|
+
const r = sdk.dedupOperations(outs, ins, "desc");
|
|
2142
|
+
expect(r.operations.length).toBe(0);
|
|
2143
|
+
});
|
|
2144
|
+
});
|
|
2145
|
+
|
|
2124
2146
|
describe("pagination", () => {
|
|
2125
2147
|
test("handles single page scenarios", async () => {
|
|
2126
2148
|
const mockCoins = createMockCoins(["800", "400", "300"]);
|
package/src/network/sdk.ts
CHANGED
|
@@ -137,10 +137,16 @@ function isUnstaking(block?: SuiTransactionBlockKind): block is ProgrammableTran
|
|
|
137
137
|
return hasMoveCallWithFunction("request_withdraw_stake", block);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
export type AccountBalance = {
|
|
141
|
+
coinType: string;
|
|
142
|
+
blockHeight: number;
|
|
143
|
+
balance: BigNumber;
|
|
144
|
+
};
|
|
145
|
+
|
|
140
146
|
/**
|
|
141
147
|
* Get account balance (native and tokens)
|
|
142
148
|
*/
|
|
143
|
-
export const getAccountBalances = async (addr: string) => {
|
|
149
|
+
export const getAccountBalances = async (addr: string): Promise<AccountBalance[]> => {
|
|
144
150
|
const balances = await getAllBalancesCached(addr);
|
|
145
151
|
return balances.map(({ coinType, totalBalance }) => ({
|
|
146
152
|
coinType,
|
|
@@ -196,7 +202,18 @@ export const getOperationRecipients = (transaction?: TransactionBlockData): stri
|
|
|
196
202
|
recipients.push(String(input.value));
|
|
197
203
|
}
|
|
198
204
|
});
|
|
199
|
-
if (
|
|
205
|
+
if (isStaking(transaction.transaction)) {
|
|
206
|
+
const address = transaction.transaction.inputs.find(
|
|
207
|
+
(input: SuiCallArg) => "valueType" in input && input.valueType === "address",
|
|
208
|
+
);
|
|
209
|
+
if (address && address.type === "pure" && address.valueType === "address") {
|
|
210
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
211
|
+
recipients.push(address.value as string);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (isUnstaking(transaction.transaction)) {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
200
217
|
return recipients;
|
|
201
218
|
}
|
|
202
219
|
return [];
|
|
@@ -680,8 +697,8 @@ export const getListOperations = async (
|
|
|
680
697
|
});
|
|
681
698
|
|
|
682
699
|
const oldestOpTime = (ops: PaginatedTransactionResponse) =>
|
|
683
|
-
Number(ops.data[ops.data.length - 1]
|
|
684
|
-
const newestOpTime = (ops: PaginatedTransactionResponse) => Number(ops.data[0]
|
|
700
|
+
Number(ops.data[ops.data.length - 1]?.timestampMs ?? 0);
|
|
701
|
+
const newestOpTime = (ops: PaginatedTransactionResponse) => Number(ops.data[0]?.timestampMs ?? 0);
|
|
685
702
|
|
|
686
703
|
/**
|
|
687
704
|
* Some IN operations are also OUT operations because the sender receive a new version of the coin objects,
|