@ledgerhq/coin-polkadot 6.13.1-nightly.20251202023925 → 6.14.0-nightly.20251203105022
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 +10 -6
- package/lib/bridge/preload.d.ts.map +1 -1
- package/lib/bridge/preload.js +7 -1
- package/lib/bridge/preload.js.map +1 -1
- package/lib/network/index.d.ts +3 -3
- package/lib/network/index.d.ts.map +1 -1
- package/lib/network/index.js.map +1 -1
- package/lib/network/node/validators.d.ts.map +1 -1
- package/lib/network/node/validators.js +7 -3
- package/lib/network/node/validators.js.map +1 -1
- package/lib/network/sidecar.d.ts +4 -4
- package/lib/network/sidecar.d.ts.map +1 -1
- package/lib/network/sidecar.js +14 -3
- package/lib/network/sidecar.js.map +1 -1
- package/lib/network/sidecar.mock.d.ts +1 -1
- package/lib/network/sidecar.mock.d.ts.map +1 -1
- package/lib/network/sidecar.mock.js +1 -1
- package/lib/network/sidecar.mock.js.map +1 -1
- package/lib/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib/test/bridgeDatasetTest.js +10 -17
- package/lib/test/bridgeDatasetTest.js.map +1 -1
- package/lib-es/bridge/preload.d.ts.map +1 -1
- package/lib-es/bridge/preload.js +7 -1
- package/lib-es/bridge/preload.js.map +1 -1
- package/lib-es/network/index.d.ts +3 -3
- package/lib-es/network/index.d.ts.map +1 -1
- package/lib-es/network/index.js.map +1 -1
- package/lib-es/network/node/validators.d.ts.map +1 -1
- package/lib-es/network/node/validators.js +7 -3
- package/lib-es/network/node/validators.js.map +1 -1
- package/lib-es/network/sidecar.d.ts +4 -4
- package/lib-es/network/sidecar.d.ts.map +1 -1
- package/lib-es/network/sidecar.js +14 -3
- package/lib-es/network/sidecar.js.map +1 -1
- package/lib-es/network/sidecar.mock.d.ts +1 -1
- package/lib-es/network/sidecar.mock.d.ts.map +1 -1
- package/lib-es/network/sidecar.mock.js +1 -1
- package/lib-es/network/sidecar.mock.js.map +1 -1
- package/lib-es/test/bridgeDatasetTest.d.ts.map +1 -1
- package/lib-es/test/bridgeDatasetTest.js +10 -17
- package/lib-es/test/bridgeDatasetTest.js.map +1 -1
- package/package.json +6 -6
- package/src/api/index.integ.test.ts +7 -7
- package/src/bridge/preload.ts +8 -1
- package/src/bridge/synchronization.test.ts +167 -0
- package/src/logic/broadcast.test.ts +11 -8
- package/src/network/index.ts +2 -2
- package/src/network/node/validators.ts +8 -3
- package/src/network/sidecar.integ.test.ts +249 -90
- package/src/network/sidecar.mock.ts +1 -1
- package/src/network/sidecar.ts +19 -7
- package/src/network/sidecar.unit.test.ts +7 -6
- package/src/test/bridgeDatasetTest.ts +10 -17
|
@@ -183,6 +183,173 @@ describe("getAccountShape", () => {
|
|
|
183
183
|
expect(shape.operationsCount).toEqual(0);
|
|
184
184
|
expect(shape.operations).toEqual([]);
|
|
185
185
|
});
|
|
186
|
+
|
|
187
|
+
it("does not migrate when assethub has not been migrated", async () => {
|
|
188
|
+
mockGetCoinConfig.mockImplementation((currency?: CryptoCurrency): any => {
|
|
189
|
+
if (currency?.id === "assethub_polkadot") {
|
|
190
|
+
return {
|
|
191
|
+
hasBeenMigrated: false,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const initialAccount = undefined;
|
|
197
|
+
const accountInfo = createAccountInfo();
|
|
198
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
199
|
+
mockGetOperations.mockResolvedValue([]);
|
|
200
|
+
|
|
201
|
+
await getAccountShape(
|
|
202
|
+
{
|
|
203
|
+
index: -1,
|
|
204
|
+
derivationPath: "not used",
|
|
205
|
+
currency: CURRENCY,
|
|
206
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
207
|
+
initialAccount,
|
|
208
|
+
derivationMode: "polkadotbip44",
|
|
209
|
+
},
|
|
210
|
+
{ paginationConfig: {} },
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
expect(mockGetAccount).toHaveBeenCalledTimes(1);
|
|
214
|
+
expect(mockGetAccount.mock.lastCall[1]).toEqual(CURRENCY);
|
|
215
|
+
expect(mockGetOperations).toHaveBeenCalledTimes(1);
|
|
216
|
+
expect(mockGetOperations.mock.lastCall[2]).toEqual(CURRENCY);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("does not migrate when currency is not polkadot", async () => {
|
|
220
|
+
const nonPolkadotCurrency = getCryptoCurrencyById("westend");
|
|
221
|
+
mockGetCoinConfig.mockImplementation((currency?: CryptoCurrency): any => {
|
|
222
|
+
if (currency?.id === "assethub_polkadot") {
|
|
223
|
+
return {
|
|
224
|
+
hasBeenMigrated: true,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const initialAccount = undefined;
|
|
230
|
+
const accountInfo = createAccountInfo();
|
|
231
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
232
|
+
mockGetOperations.mockResolvedValue([]);
|
|
233
|
+
|
|
234
|
+
await getAccountShape(
|
|
235
|
+
{
|
|
236
|
+
index: -1,
|
|
237
|
+
derivationPath: "not used",
|
|
238
|
+
currency: nonPolkadotCurrency,
|
|
239
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
240
|
+
initialAccount,
|
|
241
|
+
derivationMode: "polkadotbip44",
|
|
242
|
+
},
|
|
243
|
+
{ paginationConfig: {} },
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
expect(mockGetAccount).toHaveBeenCalledTimes(1);
|
|
247
|
+
expect(mockGetAccount.mock.lastCall[1]).toEqual(nonPolkadotCurrency);
|
|
248
|
+
expect(mockGetOperations).toHaveBeenCalledTimes(1);
|
|
249
|
+
expect(mockGetOperations.mock.lastCall[2]).toEqual(nonPolkadotCurrency);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("generates correct account ID with migration", async () => {
|
|
253
|
+
const initialAccount = undefined;
|
|
254
|
+
const accountInfo = createAccountInfo();
|
|
255
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
256
|
+
mockGetOperations.mockResolvedValue([]);
|
|
257
|
+
|
|
258
|
+
const shape = await getAccountShape(
|
|
259
|
+
{
|
|
260
|
+
index: -1,
|
|
261
|
+
derivationPath: "not used",
|
|
262
|
+
currency: CURRENCY,
|
|
263
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
264
|
+
initialAccount,
|
|
265
|
+
derivationMode: "polkadotbip44",
|
|
266
|
+
},
|
|
267
|
+
{ paginationConfig: {} },
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
expect(shape.id).toEqual(
|
|
271
|
+
"js:2:assethub_polkadot:5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J:polkadotbip44",
|
|
272
|
+
);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it("generates correct account ID without migration", async () => {
|
|
276
|
+
mockGetCoinConfig.mockImplementation((currency?: CryptoCurrency): any => {
|
|
277
|
+
if (currency?.id === "assethub_polkadot") {
|
|
278
|
+
return {
|
|
279
|
+
hasBeenMigrated: false,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const initialAccount = undefined;
|
|
285
|
+
const accountInfo = createAccountInfo();
|
|
286
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
287
|
+
mockGetOperations.mockResolvedValue([]);
|
|
288
|
+
|
|
289
|
+
const shape = await getAccountShape(
|
|
290
|
+
{
|
|
291
|
+
index: -1,
|
|
292
|
+
derivationPath: "not used",
|
|
293
|
+
currency: CURRENCY,
|
|
294
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
295
|
+
initialAccount,
|
|
296
|
+
derivationMode: "polkadotbip44",
|
|
297
|
+
},
|
|
298
|
+
{ paginationConfig: {} },
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
expect(shape.id).toEqual(
|
|
302
|
+
"js:2:polkadot:5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J:polkadotbip44",
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("returns correct currency in account shape", async () => {
|
|
307
|
+
const accountInfo = createAccountInfo();
|
|
308
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
309
|
+
mockGetOperations.mockResolvedValue([]);
|
|
310
|
+
|
|
311
|
+
const shape = await getAccountShape(
|
|
312
|
+
{
|
|
313
|
+
index: -1,
|
|
314
|
+
derivationPath: "not used",
|
|
315
|
+
currency: CURRENCY,
|
|
316
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
317
|
+
initialAccount: undefined,
|
|
318
|
+
derivationMode: "polkadotbip44",
|
|
319
|
+
},
|
|
320
|
+
{ paginationConfig: {} },
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
expect(shape.currency).toEqual(EXPECTED_CURRENCY);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it("returns correct currency in account shape without migration", async () => {
|
|
327
|
+
mockGetCoinConfig.mockImplementation((currency?: CryptoCurrency): any => {
|
|
328
|
+
if (currency?.id === "assethub_polkadot") {
|
|
329
|
+
return {
|
|
330
|
+
hasBeenMigrated: false,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const accountInfo = createAccountInfo();
|
|
336
|
+
mockGetAccount.mockResolvedValue(accountInfo);
|
|
337
|
+
mockGetOperations.mockResolvedValue([]);
|
|
338
|
+
|
|
339
|
+
const shape = await getAccountShape(
|
|
340
|
+
{
|
|
341
|
+
index: -1,
|
|
342
|
+
derivationPath: "not used",
|
|
343
|
+
currency: CURRENCY,
|
|
344
|
+
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
|
|
345
|
+
initialAccount: undefined,
|
|
346
|
+
derivationMode: "polkadotbip44",
|
|
347
|
+
},
|
|
348
|
+
{ paginationConfig: {} },
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
expect(shape.currency).toEqual(CURRENCY);
|
|
352
|
+
});
|
|
186
353
|
});
|
|
187
354
|
|
|
188
355
|
function createAccountInfo() {
|
|
@@ -15,16 +15,19 @@ describe("broadcast", () => {
|
|
|
15
15
|
submitExtrinsicMock.mockClear();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it("
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
it.each(["polkadot", "assethub_polkadot", "westend", "assethub_westend"])(
|
|
19
|
+
"should broadcast using %s when provided",
|
|
20
|
+
async currencyId => {
|
|
21
|
+
const signature = "some random signature";
|
|
22
|
+
await broadcast(signature, currencyId);
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
expect(submitExtrinsicMock).toHaveBeenCalledTimes(1);
|
|
25
|
+
expect(submitExtrinsicMock.mock.lastCall[0]).toEqual(signature);
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
const currency = getCryptoCurrencyById(currencyId);
|
|
28
|
+
expect(submitExtrinsicMock.mock.lastCall[1]).toEqual(currency);
|
|
29
|
+
},
|
|
30
|
+
);
|
|
28
31
|
|
|
29
32
|
it("should broadcast using only signature when no currency provided", async () => {
|
|
30
33
|
const signature = "some random signature";
|
package/src/network/index.ts
CHANGED
|
@@ -99,7 +99,7 @@ const isControllerAddress = makeLRUCache(
|
|
|
99
99
|
minutes(5),
|
|
100
100
|
);
|
|
101
101
|
const isElectionClosed = makeLRUCache(
|
|
102
|
-
(currency: CryptoCurrency
|
|
102
|
+
(currency: CryptoCurrency) => sidecarIsElectionClosed(currency),
|
|
103
103
|
() => "",
|
|
104
104
|
minutes(1),
|
|
105
105
|
);
|
|
@@ -139,7 +139,7 @@ const shortenMetadata = async (transaction: string, currency?: CryptoCurrency):
|
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
export default {
|
|
142
|
-
getAccount: async (address: string, currency
|
|
142
|
+
getAccount: async (address: string, currency: CryptoCurrency): Promise<PolkadotAPIAccount> =>
|
|
143
143
|
sidecardGetAccount(address, currency),
|
|
144
144
|
getBalances: async (
|
|
145
145
|
address: string,
|
|
@@ -29,11 +29,16 @@ export const fetchValidators = async (
|
|
|
29
29
|
const api = await getApiPromise(currency);
|
|
30
30
|
|
|
31
31
|
const [activeOpt, allStashes, elected] = await Promise.all([
|
|
32
|
-
|
|
33
|
-
api.
|
|
34
|
-
api.
|
|
32
|
+
// staking can be undefined if the currency is not supported
|
|
33
|
+
api.query.staking?.activeEra?.(),
|
|
34
|
+
api.derive.staking?.stashes?.(),
|
|
35
|
+
api.query.session?.validators?.(),
|
|
35
36
|
]);
|
|
36
37
|
|
|
38
|
+
if (!activeOpt) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
const { index: activeEra } = activeOpt.unwrapOrDefault();
|
|
38
43
|
|
|
39
44
|
let selected: string[] = [];
|
|
@@ -1,107 +1,266 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getAccount,
|
|
4
|
+
getStakingInfo,
|
|
5
|
+
getStakingProgress,
|
|
6
|
+
getValidators,
|
|
7
|
+
getBalances,
|
|
8
|
+
getMinimumBondBalance,
|
|
9
|
+
isElectionClosed,
|
|
10
|
+
isNewAccount,
|
|
11
|
+
isControllerAddress,
|
|
12
|
+
getTransactionParams,
|
|
13
|
+
getRegistry,
|
|
14
|
+
getLastBlock,
|
|
15
|
+
fetchChainSpec,
|
|
16
|
+
} from "./sidecar";
|
|
3
17
|
import coinConfig from "../config";
|
|
4
18
|
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
|
|
5
19
|
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
20
|
+
const CURRENCY_CONFIGS = {
|
|
21
|
+
polkadot: {
|
|
22
|
+
currency: getCryptoCurrencyById("polkadot"),
|
|
23
|
+
config: {
|
|
24
|
+
status: { type: "active" as const },
|
|
25
|
+
node: { url: "https://polkadot-rpc.publicnode.com" },
|
|
26
|
+
sidecar: { url: "https://polkadot-sidecar.coin.ledger.com" },
|
|
27
|
+
indexer: { url: "https://polkadot.coin.ledger.com" },
|
|
28
|
+
staking: { electionStatusThreshold: 25 },
|
|
29
|
+
metadataShortener: {
|
|
30
|
+
id: "dot",
|
|
31
|
+
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
32
|
+
},
|
|
33
|
+
metadataHash: {
|
|
34
|
+
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
13
35
|
},
|
|
14
|
-
|
|
15
|
-
|
|
36
|
+
},
|
|
37
|
+
testAddress: "163WJAxWrQzsAVEZdn2w6mq4gmT4FmEgvCfex3uEEUHTE9GL",
|
|
38
|
+
},
|
|
39
|
+
assethub_polkadot: {
|
|
40
|
+
currency: getCryptoCurrencyById("assethub_polkadot"),
|
|
41
|
+
config: {
|
|
42
|
+
status: { type: "active" as const },
|
|
43
|
+
sidecar: { url: "https://polkadot-asset-hub-sidecar.coin.ledger.com" },
|
|
44
|
+
node: { url: "https://polkadot-asset-hub-fullnodes.api.live.ledger.com" },
|
|
45
|
+
indexer: { url: "https://explorers.api.live.ledger.com/blockchain/dot_asset_hub" },
|
|
46
|
+
staking: { electionStatusThreshold: 25 },
|
|
47
|
+
metadataShortener: {
|
|
48
|
+
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
49
|
+
id: "dot-hub",
|
|
16
50
|
},
|
|
17
|
-
|
|
18
|
-
url: "https://polkadot-
|
|
51
|
+
metadataHash: {
|
|
52
|
+
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
53
|
+
id: "dot-hub",
|
|
19
54
|
},
|
|
20
|
-
|
|
21
|
-
|
|
55
|
+
hasBeenMigrated: true,
|
|
56
|
+
},
|
|
57
|
+
testAddress: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
|
58
|
+
},
|
|
59
|
+
westend: {
|
|
60
|
+
currency: getCryptoCurrencyById("westend"),
|
|
61
|
+
config: {
|
|
62
|
+
status: { type: "active" as const },
|
|
63
|
+
sidecar: { url: "https://polkadot-westend-sidecar.coin.ledger.com/rc" },
|
|
64
|
+
node: { url: "https://polkadot-westend-fullnodes.api.live.ledger.com" },
|
|
65
|
+
indexer: { url: "https://explorers.api.live.ledger.com/blockchain/dot_westend" },
|
|
66
|
+
metadataShortener: {
|
|
67
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
68
|
+
id: "dot-hub",
|
|
22
69
|
},
|
|
23
|
-
|
|
24
|
-
|
|
70
|
+
metadataHash: {
|
|
71
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
72
|
+
id: "dot-hub",
|
|
25
73
|
},
|
|
74
|
+
},
|
|
75
|
+
testAddress: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
|
76
|
+
},
|
|
77
|
+
assethub_westend: {
|
|
78
|
+
currency: getCryptoCurrencyById("assethub_westend"),
|
|
79
|
+
config: {
|
|
80
|
+
status: { type: "active" as const },
|
|
81
|
+
sidecar: { url: "https://polkadot-westend-sidecar.coin.ledger.com" },
|
|
82
|
+
node: { url: "https://polkadot-westend-asset-hub-fullnodes.api.live.ledger.com" },
|
|
83
|
+
indexer: { url: "https://explorers.api.live.ledger.com/blockchain/dot_asset_hub_westend" },
|
|
26
84
|
metadataShortener: {
|
|
27
|
-
|
|
28
|
-
|
|
85
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
86
|
+
id: "dot-hub",
|
|
29
87
|
},
|
|
30
88
|
metadataHash: {
|
|
31
|
-
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
89
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
90
|
+
id: "dot-hub",
|
|
32
91
|
},
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
92
|
+
},
|
|
93
|
+
testAddress: "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
describe("sidecar integration test", () => {
|
|
98
|
+
describe.each(Object.entries(CURRENCY_CONFIGS))(
|
|
99
|
+
"%s tests",
|
|
100
|
+
(currencyId, { currency, config, testAddress }) => {
|
|
101
|
+
beforeAll(() => {
|
|
102
|
+
coinConfig.setCoinConfig(() => config);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe("getValidators", () => {
|
|
106
|
+
it(`returns expected result with ${currencyId}`, async () => {
|
|
107
|
+
const result = await getValidators(undefined, currency);
|
|
108
|
+
|
|
109
|
+
expect(result).toEqual(
|
|
110
|
+
expect.arrayContaining([
|
|
111
|
+
expect.objectContaining({
|
|
112
|
+
address: expect.any(String),
|
|
113
|
+
commission: expect.any(BigNumber),
|
|
114
|
+
identity: expect.any(String),
|
|
115
|
+
isElected: expect.any(Boolean),
|
|
116
|
+
isOversubscribed: expect.any(Boolean),
|
|
117
|
+
nominatorsCount: expect.any(Number),
|
|
118
|
+
selfBonded: expect.any(BigNumber),
|
|
119
|
+
totalBonded: expect.any(BigNumber),
|
|
120
|
+
}),
|
|
121
|
+
]),
|
|
122
|
+
);
|
|
123
|
+
}, 10000); // 10 seconds, because more than 5s may be required
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("getAccount", () => {
|
|
127
|
+
it(`works with ${currencyId}`, async () => {
|
|
128
|
+
const result = await getAccount(testAddress, currency);
|
|
129
|
+
|
|
130
|
+
expect(result).toMatchObject({
|
|
131
|
+
balance: expect.any(BigNumber),
|
|
132
|
+
blockHeight: expect.any(Number),
|
|
133
|
+
lockedBalance: expect.any(BigNumber),
|
|
134
|
+
nominations: expect.any(Array),
|
|
135
|
+
nonce: expect.any(Number),
|
|
136
|
+
spendableBalance: expect.any(BigNumber),
|
|
137
|
+
unlockedBalance: expect.any(BigNumber),
|
|
138
|
+
unlockingBalance: expect.any(BigNumber),
|
|
139
|
+
unlockings: expect.any(Array),
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe("getStakingInfo", () => {
|
|
145
|
+
it(`works with ${currencyId}`, async () => {
|
|
146
|
+
const result = await getStakingInfo(testAddress, currency);
|
|
147
|
+
|
|
148
|
+
expect(result).toMatchObject({
|
|
149
|
+
unlockedBalance: expect.any(BigNumber),
|
|
150
|
+
unlockingBalance: expect.any(BigNumber),
|
|
151
|
+
unlockings: expect.any(Array),
|
|
152
|
+
});
|
|
153
|
+
});
|
|
45
154
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
155
|
+
|
|
156
|
+
describe("getStakingProgress", () => {
|
|
157
|
+
it(`works with ${currencyId}`, async () => {
|
|
158
|
+
const result = await getStakingProgress(currency);
|
|
159
|
+
|
|
160
|
+
expect(result).toMatchObject({
|
|
161
|
+
activeEra: expect.any(Number),
|
|
162
|
+
bondingDuration: expect.any(Number),
|
|
163
|
+
electionClosed: expect.any(Boolean),
|
|
164
|
+
maxNominatorRewardedPerValidator: expect.any(Number),
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe("getBalances", () => {
|
|
170
|
+
it(`works with ${currencyId}`, async () => {
|
|
171
|
+
const result = await getBalances(testAddress, currency);
|
|
172
|
+
|
|
173
|
+
expect(result).toMatchObject({
|
|
174
|
+
balance: expect.any(BigNumber),
|
|
175
|
+
blockHeight: expect.any(Number),
|
|
176
|
+
lockedBalance: expect.any(BigNumber),
|
|
177
|
+
nonce: expect.any(Number),
|
|
178
|
+
spendableBalance: expect.any(BigNumber),
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("getMinimumBondBalance", () => {
|
|
184
|
+
it(`works with ${currencyId}`, async () => {
|
|
185
|
+
const result = await getMinimumBondBalance(currency);
|
|
186
|
+
|
|
187
|
+
expect(result).toBeInstanceOf(BigNumber);
|
|
188
|
+
expect(result.isGreaterThanOrEqualTo(0)).toBe(true);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe("isElectionClosed", () => {
|
|
193
|
+
it(`works with ${currencyId}`, async () => {
|
|
194
|
+
const result = await isElectionClosed(currency);
|
|
195
|
+
|
|
196
|
+
expect(typeof result).toBe("boolean");
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe("isNewAccount", () => {
|
|
201
|
+
it(`works with ${currencyId}`, async () => {
|
|
202
|
+
const result = await isNewAccount(testAddress, currency);
|
|
203
|
+
|
|
204
|
+
expect(typeof result).toBe("boolean");
|
|
205
|
+
});
|
|
61
206
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
207
|
+
|
|
208
|
+
describe("isControllerAddress", () => {
|
|
209
|
+
it(`works with ${currencyId}`, async () => {
|
|
210
|
+
const result = await isControllerAddress(testAddress, currency);
|
|
211
|
+
|
|
212
|
+
expect(typeof result).toBe("boolean");
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
describe("getTransactionParams", () => {
|
|
217
|
+
it(`works with ${currencyId}`, async () => {
|
|
218
|
+
const result = await getTransactionParams(currency);
|
|
219
|
+
|
|
220
|
+
expect(result).toMatchObject({
|
|
221
|
+
blockHash: expect.any(String),
|
|
222
|
+
blockNumber: expect.any(String),
|
|
223
|
+
chainName: expect.any(String),
|
|
224
|
+
genesisHash: expect.any(String),
|
|
225
|
+
specName: expect.any(String),
|
|
226
|
+
transactionVersion: expect.any(String),
|
|
227
|
+
specVersion: expect.any(String),
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
describe("getRegistry", () => {
|
|
233
|
+
it(`works with ${currencyId}`, async () => {
|
|
234
|
+
const result = await getRegistry(currency);
|
|
235
|
+
|
|
236
|
+
expect(result).toMatchObject({
|
|
237
|
+
registry: expect.any(Object),
|
|
238
|
+
extrinsics: expect.any(Object),
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
describe("getLastBlock", () => {
|
|
244
|
+
it(`works with ${currencyId}`, async () => {
|
|
245
|
+
const result = await getLastBlock(currency);
|
|
246
|
+
|
|
247
|
+
expect(result).toMatchObject({
|
|
248
|
+
hash: expect.any(String),
|
|
249
|
+
height: expect.any(Number),
|
|
250
|
+
time: expect.any(Date),
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("fetchChainSpec", () => {
|
|
256
|
+
it(`works with ${currencyId}`, async () => {
|
|
257
|
+
const result = await fetchChainSpec(currency);
|
|
258
|
+
|
|
259
|
+
expect(result).toMatchObject({
|
|
260
|
+
properties: expect.any(Object),
|
|
261
|
+
});
|
|
262
|
+
});
|
|
83
263
|
});
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
describe("getValidators", () => {
|
|
88
|
-
it.skip("returns expected result", async () => {
|
|
89
|
-
const result = await getValidators(undefined, getCryptoCurrencyById("polkadot"));
|
|
90
|
-
|
|
91
|
-
expect(result).toEqual(
|
|
92
|
-
expect.arrayContaining([
|
|
93
|
-
expect.objectContaining({
|
|
94
|
-
address: "111B8CxcmnWbuDLyGvgUmRezDCK1brRZmvUuQ6SrFdMyc3S",
|
|
95
|
-
commission: BigNumber("1"),
|
|
96
|
-
identity: "",
|
|
97
|
-
isElected: true,
|
|
98
|
-
isOversubscribed: false,
|
|
99
|
-
nominatorsCount: expect.any(Number),
|
|
100
|
-
selfBonded: BigNumber("0"),
|
|
101
|
-
totalBonded: expect.any(BigNumber),
|
|
102
|
-
}),
|
|
103
|
-
]),
|
|
104
|
-
);
|
|
105
|
-
}, 10000); // 10 seconds, because more than 5s may be required
|
|
106
|
-
});
|
|
264
|
+
},
|
|
265
|
+
);
|
|
107
266
|
});
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
fixtureTxMaterialWithMetadata,
|
|
7
7
|
} from "./sidecar.fixture";
|
|
8
8
|
|
|
9
|
-
export const SIDECAR_BASE_URL_TEST = "https://polkadot-sidecar.coin.ledger.com";
|
|
9
|
+
export const SIDECAR_BASE_URL_TEST = "https://polkadot-asset-hub-sidecar.coin.ledger.com";
|
|
10
10
|
|
|
11
11
|
const handlers = [
|
|
12
12
|
http.get(`${SIDECAR_BASE_URL_TEST}/accounts/:addr/balance-info`, () => {
|
package/src/network/sidecar.ts
CHANGED
|
@@ -48,10 +48,10 @@ const getSidecarUrl = (route: string, currency?: CryptoCurrency): string => {
|
|
|
48
48
|
route = `/rc${route}`;
|
|
49
49
|
} else if (
|
|
50
50
|
currency?.id === "westend" &&
|
|
51
|
-
(route.startsWith("/pallets/staking") || route.startsWith("/transaction
|
|
51
|
+
(route.startsWith("/pallets/staking") || route.startsWith("/transaction"))
|
|
52
52
|
) {
|
|
53
53
|
// Fetch Staking Info from Westend AssetHub (remove /rc)
|
|
54
|
-
sidecarUrl =
|
|
54
|
+
sidecarUrl = sidecarUrl.replace("/rc", "");
|
|
55
55
|
}
|
|
56
56
|
return `${sidecarUrl}${route || ""}`;
|
|
57
57
|
};
|
|
@@ -61,6 +61,7 @@ const getElectionOptimisticThreshold = (currency?: CryptoCurrency): number => {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const VALIDATOR_COMISSION_RATIO = 1000000000;
|
|
64
|
+
const UNSUPPORTED_STAKING_NETWORKS = ["polkadot", "westend"];
|
|
64
65
|
|
|
65
66
|
// blocks = 2 minutes 30
|
|
66
67
|
|
|
@@ -277,7 +278,9 @@ export const fetchChainSpec = async (currency?: CryptoCurrency) => {
|
|
|
277
278
|
*
|
|
278
279
|
* @returns {boolean}
|
|
279
280
|
*/
|
|
280
|
-
export const isElectionClosed = async (currency
|
|
281
|
+
export const isElectionClosed = async (currency: CryptoCurrency): Promise<boolean> => {
|
|
282
|
+
if (UNSUPPORTED_STAKING_NETWORKS.includes(currency.id)) return true;
|
|
283
|
+
|
|
281
284
|
const progress = await fetchStakingProgress(currency);
|
|
282
285
|
return !progress.electionStatus?.status?.Open;
|
|
283
286
|
};
|
|
@@ -334,7 +337,7 @@ export const verifyValidatorAddresses = async (
|
|
|
334
337
|
* @async
|
|
335
338
|
* @param {*} addr
|
|
336
339
|
*/
|
|
337
|
-
export const getAccount = async (addr: string, currency
|
|
340
|
+
export const getAccount = async (addr: string, currency: CryptoCurrency) => {
|
|
338
341
|
const balances = await getBalances(addr, currency);
|
|
339
342
|
const stakingInfo = await getStakingInfo(addr, currency);
|
|
340
343
|
const nominations = await getNominations(addr);
|
|
@@ -371,13 +374,13 @@ export const getBalances = async (addr: string, currency?: CryptoCurrency) => {
|
|
|
371
374
|
* @async
|
|
372
375
|
* @param {*} addr
|
|
373
376
|
*/
|
|
374
|
-
export const getStakingInfo = async (addr: string, currency
|
|
377
|
+
export const getStakingInfo = async (addr: string, currency: CryptoCurrency) => {
|
|
375
378
|
const [stash, controller] = await Promise.all([
|
|
376
379
|
fetchStashAddr(addr, currency),
|
|
377
380
|
fetchControllerAddr(addr, currency),
|
|
378
381
|
]);
|
|
379
382
|
// If account is not a stash, no need to fetch staking-info (it would return an error)
|
|
380
|
-
if (!controller || currency
|
|
383
|
+
if (!controller || UNSUPPORTED_STAKING_NETWORKS.includes(currency.id)) {
|
|
381
384
|
return {
|
|
382
385
|
controller: null,
|
|
383
386
|
stash: stash || null,
|
|
@@ -566,8 +569,17 @@ export const getValidators = async (
|
|
|
566
569
|
* @returns {PolkadotStakingProgress}
|
|
567
570
|
*/
|
|
568
571
|
export const getStakingProgress = async (
|
|
569
|
-
currency
|
|
572
|
+
currency: CryptoCurrency,
|
|
570
573
|
): Promise<PolkadotStakingProgress> => {
|
|
574
|
+
if (UNSUPPORTED_STAKING_NETWORKS.includes(currency.id)) {
|
|
575
|
+
return {
|
|
576
|
+
electionClosed: true,
|
|
577
|
+
activeEra: 0,
|
|
578
|
+
maxNominatorRewardedPerValidator: 128,
|
|
579
|
+
bondingDuration: 28,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
|
|
571
583
|
const [progress, consts] = await Promise.all([
|
|
572
584
|
fetchStakingProgress(currency),
|
|
573
585
|
getConstants(currency),
|