@ledgerhq/coin-tester-polkadot 1.3.6 → 1.4.0-nightly.1
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 +27 -0
- package/chopsticks.Dockerfile +4 -1
- package/{coin-tester-chopsticks.yml → coin-tester-chopsticks/polkadot.yml} +4 -6
- package/coin-tester-chopsticks/westend.yml +21 -0
- package/docker-compose.yml +2 -0
- package/lib/src/chopsticks-sidecar.d.ts +1 -1
- package/lib/src/chopsticks-sidecar.d.ts.map +1 -1
- package/lib/src/chopsticks-sidecar.js +2 -2
- package/lib/src/chopsticks-sidecar.js.map +1 -1
- package/lib/src/helpers.d.ts +1 -0
- package/lib/src/helpers.d.ts.map +1 -1
- package/lib/src/helpers.js +2 -1
- package/lib/src/helpers.js.map +1 -1
- package/lib/src/scenarii/Polkadot.d.ts.map +1 -1
- package/lib/src/scenarii/Polkadot.js +5 -1
- package/lib/src/scenarii/Polkadot.js.map +1 -1
- package/lib/src/scenarii/Westend.d.ts +4 -0
- package/lib/src/scenarii/Westend.d.ts.map +1 -0
- package/lib/src/scenarii/Westend.js +322 -0
- package/lib/src/scenarii/Westend.js.map +1 -0
- package/lib/src/scenarii.test.d.ts.map +1 -1
- package/lib/src/scenarii.test.js +12 -0
- package/lib/src/scenarii.test.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib-es/src/chopsticks-sidecar.d.ts +1 -1
- package/lib-es/src/chopsticks-sidecar.d.ts.map +1 -1
- package/lib-es/src/chopsticks-sidecar.js +2 -2
- package/lib-es/src/chopsticks-sidecar.js.map +1 -1
- package/lib-es/src/helpers.d.ts +1 -0
- package/lib-es/src/helpers.d.ts.map +1 -1
- package/lib-es/src/helpers.js +1 -0
- package/lib-es/src/helpers.js.map +1 -1
- package/lib-es/src/scenarii/Polkadot.d.ts.map +1 -1
- package/lib-es/src/scenarii/Polkadot.js +5 -1
- package/lib-es/src/scenarii/Polkadot.js.map +1 -1
- package/lib-es/src/scenarii/Westend.d.ts +4 -0
- package/lib-es/src/scenarii/Westend.d.ts.map +1 -0
- package/lib-es/src/scenarii/Westend.js +316 -0
- package/lib-es/src/scenarii/Westend.js.map +1 -0
- package/lib-es/src/scenarii.test.d.ts.map +1 -1
- package/lib-es/src/scenarii.test.js +12 -0
- package/lib-es/src/scenarii.test.js.map +1 -1
- package/lib-es/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/src/chopsticks-sidecar.ts +2 -3
- package/src/helpers.ts +1 -0
- package/src/scenarii/Polkadot.ts +6 -1
- package/src/scenarii/Westend.ts +410 -0
- package/src/scenarii.test.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-tester-polkadot",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0-nightly.1",
|
|
4
4
|
"description": "Ledger Polkadot Coin Tester",
|
|
5
5
|
"main": "src/scenarii.test.ts",
|
|
6
6
|
"keywords": [
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"dotenv": "^16.4.5",
|
|
51
51
|
"expect": "^27.4.6",
|
|
52
52
|
"msw": "^2.2.1",
|
|
53
|
-
"@ledgerhq/coin-framework": "^6.
|
|
54
|
-
"@ledgerhq/coin-polkadot": "^6.
|
|
53
|
+
"@ledgerhq/coin-framework": "^6.7.0-nightly.1",
|
|
54
|
+
"@ledgerhq/coin-polkadot": "^6.11.0-nightly.1",
|
|
55
55
|
"@ledgerhq/coin-tester": "^0.10.1",
|
|
56
|
-
"@ledgerhq/cryptoassets": "^13.
|
|
56
|
+
"@ledgerhq/cryptoassets": "^13.31.0-nightly.1",
|
|
57
57
|
"@ledgerhq/hw-app-polkadot": "^6.34.8",
|
|
58
|
-
"@ledgerhq/types-cryptoassets": "^7.
|
|
59
|
-
"@ledgerhq/types-live": "^6.
|
|
58
|
+
"@ledgerhq/types-cryptoassets": "^7.29.0-nightly.0",
|
|
59
|
+
"@ledgerhq/types-live": "^6.87.0-nightly.1"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@polkadot/util": "12.6.2",
|
|
@@ -15,14 +15,13 @@ const ensureEnv = () => {
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export async function spawnChopsticksAndSidecar() {
|
|
18
|
+
export async function spawnChopsticksAndSidecar(chopsticksConfig: string): Promise<void> {
|
|
19
19
|
ensureEnv();
|
|
20
20
|
console.log("Starting chopsticks and sidecar...");
|
|
21
|
-
|
|
22
21
|
await compose.upAll({
|
|
23
22
|
cwd,
|
|
24
23
|
log: Boolean(process.env.DEBUG),
|
|
25
|
-
env: process.env,
|
|
24
|
+
env: { ...process.env, CHOPSTICKS_CONFIG: chopsticksConfig },
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
let chopsticksStarted = false;
|
package/src/helpers.ts
CHANGED
package/src/scenarii/Polkadot.ts
CHANGED
|
@@ -227,11 +227,15 @@ const coinConfig: PolkadotCoinConfig = {
|
|
|
227
227
|
node: {
|
|
228
228
|
url: LOCAL_TESTNODE_WS_URL,
|
|
229
229
|
},
|
|
230
|
+
indexer: {
|
|
231
|
+
url: "https://polkadot.coin.ledger.com",
|
|
232
|
+
},
|
|
230
233
|
sidecar: {
|
|
231
234
|
url: SIDECAR_BASE_URL,
|
|
232
235
|
},
|
|
233
236
|
metadataShortener: {
|
|
234
237
|
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
238
|
+
id: "dot",
|
|
235
239
|
},
|
|
236
240
|
metadataHash: {
|
|
237
241
|
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
@@ -242,12 +246,13 @@ const subscriptions: any[] = [];
|
|
|
242
246
|
|
|
243
247
|
export const PolkadotScenario: Scenario<PolkadotTransaction, PolkadotAccount> = {
|
|
244
248
|
name: "Polkadot Ledger Live transactions",
|
|
249
|
+
|
|
245
250
|
setup: async () => {
|
|
246
251
|
const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
|
|
247
252
|
spawnSpeculos(
|
|
248
253
|
`/${defaultNanoApp.firmware}/PolkadotMigration/app_${defaultNanoApp.version}.elf`,
|
|
249
254
|
),
|
|
250
|
-
spawnChopsticksAndSidecar(),
|
|
255
|
+
spawnChopsticksAndSidecar("coin-tester-chopsticks/polkadot.yml"),
|
|
251
256
|
]);
|
|
252
257
|
|
|
253
258
|
const onSignerConfirmation = getOnSpeculosConfirmation("APPROVE");
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import Polkadot from "@ledgerhq/hw-app-polkadot";
|
|
3
|
+
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
4
|
+
import { ApiPromise, Keyring, WsProvider } from "@polkadot/api";
|
|
5
|
+
import { Scenario, ScenarioTransaction } from "@ledgerhq/coin-tester/main";
|
|
6
|
+
import { killSpeculos, spawnSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
|
|
7
|
+
import { formatCurrencyUnit, parseCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
|
|
8
|
+
import { killChopsticksAndSidecar, spawnChopsticksAndSidecar } from "../chopsticks-sidecar";
|
|
9
|
+
import { PolkadotCoinConfig } from "@ledgerhq/coin-polkadot/config";
|
|
10
|
+
import { ExplorerExtrinsic } from "@ledgerhq/coin-polkadot";
|
|
11
|
+
import { defaultNanoApp } from "../scenarii.test";
|
|
12
|
+
import { createBridges } from "@ledgerhq/coin-polkadot/bridge/index";
|
|
13
|
+
import { makeAccount } from "../fixtures";
|
|
14
|
+
import { indexOperation } from "../indexer";
|
|
15
|
+
import { westend } from "../helpers";
|
|
16
|
+
import resolver from "@ledgerhq/coin-polkadot/signer/index";
|
|
17
|
+
import {
|
|
18
|
+
PolkadotAccount,
|
|
19
|
+
PolkadotOperationExtra,
|
|
20
|
+
Transaction as PolkadotTransaction,
|
|
21
|
+
} from "@ledgerhq/coin-polkadot/types/bridge";
|
|
22
|
+
|
|
23
|
+
type PolkadotScenarioTransaction = ScenarioTransaction<PolkadotTransaction, PolkadotAccount>;
|
|
24
|
+
|
|
25
|
+
const getTransactions = () => {
|
|
26
|
+
const send1DotTransaction: PolkadotScenarioTransaction = {
|
|
27
|
+
name: "Send 1 WND",
|
|
28
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
29
|
+
amount: parseCurrencyUnit(westend.units[0], "1"),
|
|
30
|
+
expect: (previousAccount, currentAccount) => {
|
|
31
|
+
const [latestOperation] = currentAccount.operations;
|
|
32
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
33
|
+
expect(latestOperation.type).toBe("OUT");
|
|
34
|
+
expect(latestOperation.value.toFixed()).toBe(
|
|
35
|
+
latestOperation.fee.plus(parseCurrencyUnit(westend.units[0], "1")).toFixed(),
|
|
36
|
+
);
|
|
37
|
+
expect(currentAccount.balance.toFixed()).toBe(
|
|
38
|
+
previousAccount.balance.minus(latestOperation.value).toFixed(),
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const send100DotTransaction: PolkadotScenarioTransaction = {
|
|
44
|
+
name: "Send 100 WND",
|
|
45
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
46
|
+
amount: parseCurrencyUnit(westend.units[0], "100"),
|
|
47
|
+
expect: (previousAccount, currentAccount) => {
|
|
48
|
+
const [latestOperation] = currentAccount.operations;
|
|
49
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
50
|
+
expect(latestOperation.type).toBe("OUT");
|
|
51
|
+
expect(latestOperation.value.toFixed()).toBe(
|
|
52
|
+
latestOperation.fee.plus(parseCurrencyUnit(westend.units[0], "100")).toFixed(),
|
|
53
|
+
);
|
|
54
|
+
expect(currentAccount.balance.toFixed()).toBe(
|
|
55
|
+
previousAccount.balance.minus(latestOperation.value).toFixed(),
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const bond500DotTransaction: PolkadotScenarioTransaction = {
|
|
61
|
+
name: "Bond 500 WND",
|
|
62
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
63
|
+
amount: parseCurrencyUnit(westend.units[0], "500"),
|
|
64
|
+
mode: "bond",
|
|
65
|
+
expect: (previousAccount, currentAccount) => {
|
|
66
|
+
const [latestOperation] = currentAccount.operations;
|
|
67
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
68
|
+
expect(latestOperation.type).toBe("BOND");
|
|
69
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe("staking.bond");
|
|
70
|
+
expect(
|
|
71
|
+
parseCurrencyUnit(
|
|
72
|
+
westend.units[0],
|
|
73
|
+
(latestOperation.extra as PolkadotOperationExtra).bondedAmount!.toFixed(),
|
|
74
|
+
).toFixed(),
|
|
75
|
+
).toBe("50000000000000000000000");
|
|
76
|
+
expect(currentAccount.balance.toFixed()).toBe(
|
|
77
|
+
previousAccount.balance.minus(latestOperation.value).toFixed(),
|
|
78
|
+
);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const unbond100DotTransaction: PolkadotScenarioTransaction = {
|
|
83
|
+
name: "Unbond 100 WND",
|
|
84
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
85
|
+
amount: parseCurrencyUnit(westend.units[0], "100"),
|
|
86
|
+
mode: "unbond",
|
|
87
|
+
expect: (previousAccount, currentAccount) => {
|
|
88
|
+
const [latestOperation] = currentAccount.operations;
|
|
89
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
90
|
+
expect(latestOperation.type).toBe("UNBOND");
|
|
91
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe("staking.unbond");
|
|
92
|
+
expect(
|
|
93
|
+
parseCurrencyUnit(
|
|
94
|
+
westend.units[0],
|
|
95
|
+
(latestOperation.extra as PolkadotOperationExtra).unbondedAmount!.toFixed(),
|
|
96
|
+
).toFixed(),
|
|
97
|
+
).toBe("10000000000000000000000");
|
|
98
|
+
expect(
|
|
99
|
+
parseCurrencyUnit(
|
|
100
|
+
westend.units[0],
|
|
101
|
+
currentAccount.polkadotResources.unlockingBalance.toFixed(),
|
|
102
|
+
).toFixed(),
|
|
103
|
+
).toBe("10000000000000000000000");
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const rebond50DotTransaction: PolkadotScenarioTransaction = {
|
|
108
|
+
name: "Rebond 50 WND",
|
|
109
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
110
|
+
amount: parseCurrencyUnit(westend.units[0], "50"),
|
|
111
|
+
mode: "rebond",
|
|
112
|
+
expect: (previousAccount, currentAccount) => {
|
|
113
|
+
const [latestOperation] = currentAccount.operations;
|
|
114
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
115
|
+
expect(latestOperation.type).toBe("BOND");
|
|
116
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe("staking.rebond");
|
|
117
|
+
expect(
|
|
118
|
+
parseCurrencyUnit(
|
|
119
|
+
westend.units[0],
|
|
120
|
+
(latestOperation.extra as PolkadotOperationExtra).bondedAmount!.toFixed(),
|
|
121
|
+
).toFixed(),
|
|
122
|
+
).toBe("5000000000000000000000"); // Should be 450 DOT no ?
|
|
123
|
+
expect(
|
|
124
|
+
parseCurrencyUnit(
|
|
125
|
+
westend.units[0],
|
|
126
|
+
currentAccount.polkadotResources.unlockingBalance.toFixed(),
|
|
127
|
+
).toFixed(),
|
|
128
|
+
).toBe("5000000000000000000000");
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const nomminateTransaction: PolkadotScenarioTransaction = {
|
|
133
|
+
name: "Nominate",
|
|
134
|
+
mode: "nominate",
|
|
135
|
+
// https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fpolkadot-rpc.publicnode.com#/staking
|
|
136
|
+
validators: [
|
|
137
|
+
"15ANfaUMadXk65NtRqzCKuhAiVSA47Ks6fZs8rUcRQX11pzM",
|
|
138
|
+
"19KaPfHSSjv4soqNW1tqPMwAnSGmG3pGydPzrPvaNLXLFDZ",
|
|
139
|
+
],
|
|
140
|
+
expect: (previousAccount, currentAccount) => {
|
|
141
|
+
const [latestOperation] = currentAccount.operations;
|
|
142
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
143
|
+
expect(latestOperation.type).toBe("NOMINATE");
|
|
144
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe(
|
|
145
|
+
"staking.nominate",
|
|
146
|
+
);
|
|
147
|
+
expect((latestOperation.extra as PolkadotOperationExtra).validators?.length).toBe(2);
|
|
148
|
+
expect(currentAccount.polkadotResources.nominations?.length).toBe(2);
|
|
149
|
+
expect(
|
|
150
|
+
currentAccount.polkadotResources.nominations?.every(
|
|
151
|
+
nominiation => nominiation.status === "waiting" || nominiation.status === "inactive",
|
|
152
|
+
),
|
|
153
|
+
).toBe(true);
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const chillTransaction: PolkadotScenarioTransaction = {
|
|
158
|
+
name: "Chill",
|
|
159
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
160
|
+
mode: "chill",
|
|
161
|
+
expect: (previousAccount, currentAccount) => {
|
|
162
|
+
const [latestOperation] = currentAccount.operations;
|
|
163
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
164
|
+
expect(latestOperation.type).toBe("CHILL");
|
|
165
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe("staking.chill");
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const withdraw250DotTransaction: PolkadotScenarioTransaction = {
|
|
170
|
+
name: "Withdraw 250 WND",
|
|
171
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
172
|
+
amount: parseCurrencyUnit(westend.units[0], "250"),
|
|
173
|
+
mode: "withdrawUnbonded",
|
|
174
|
+
expect: (previousAccount, currentAccount) => {
|
|
175
|
+
const [latestOperation] = currentAccount.operations;
|
|
176
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
177
|
+
expect(latestOperation.type).toBe("WITHDRAW_UNBONDED");
|
|
178
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe(
|
|
179
|
+
"staking.withdrawUnbonded",
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const claimRewardTransaction: PolkadotScenarioTransaction = {
|
|
185
|
+
name: "Claim reward",
|
|
186
|
+
recipient: "15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5",
|
|
187
|
+
mode: "claimReward",
|
|
188
|
+
validators: [
|
|
189
|
+
"15ANfaUMadXk65NtRqzCKuhAiVSA47Ks6fZs8rUcRQX11pzM",
|
|
190
|
+
"13TrdLhMVLcwcEhMYLcqrkxAgq9M5gnK1LZKAF4VupVfQDUg",
|
|
191
|
+
"19KaPfHSSjv4soqNW1tqPMwAnSGmG3pGydPzrPvaNLXLFDZ",
|
|
192
|
+
],
|
|
193
|
+
expect: (previousAccount, currentAccount) => {
|
|
194
|
+
const [latestOperation] = currentAccount.operations;
|
|
195
|
+
expect(currentAccount.operations.length - previousAccount.operations.length).toBe(1);
|
|
196
|
+
expect(latestOperation.type).toBe("FEES");
|
|
197
|
+
expect((latestOperation.extra as PolkadotOperationExtra).palletMethod).toBe(
|
|
198
|
+
"staking.payoutStakers",
|
|
199
|
+
);
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return [
|
|
204
|
+
send1DotTransaction,
|
|
205
|
+
send100DotTransaction,
|
|
206
|
+
bond500DotTransaction,
|
|
207
|
+
unbond100DotTransaction,
|
|
208
|
+
rebond50DotTransaction,
|
|
209
|
+
nomminateTransaction,
|
|
210
|
+
chillTransaction,
|
|
211
|
+
withdraw250DotTransaction,
|
|
212
|
+
claimRewardTransaction,
|
|
213
|
+
];
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const LOCAL_TESTNODE_WS_URL = "ws://127.0.0.1:8000";
|
|
217
|
+
const SIDECAR_BASE_URL = "http://127.0.0.1:8080";
|
|
218
|
+
|
|
219
|
+
const wsProvider = new WsProvider(LOCAL_TESTNODE_WS_URL, false);
|
|
220
|
+
let api: ApiPromise;
|
|
221
|
+
let unsubscribeNewBlockListener: () => void;
|
|
222
|
+
|
|
223
|
+
const coinConfig: PolkadotCoinConfig = {
|
|
224
|
+
status: {
|
|
225
|
+
type: "active",
|
|
226
|
+
},
|
|
227
|
+
node: {
|
|
228
|
+
url: LOCAL_TESTNODE_WS_URL,
|
|
229
|
+
},
|
|
230
|
+
indexer: {
|
|
231
|
+
url: "https://explorers.api.live.ledger.com/blockchain/dot_westend",
|
|
232
|
+
},
|
|
233
|
+
sidecar: {
|
|
234
|
+
url: SIDECAR_BASE_URL,
|
|
235
|
+
},
|
|
236
|
+
metadataShortener: {
|
|
237
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/transaction/metadata",
|
|
238
|
+
id: "dot-hub",
|
|
239
|
+
},
|
|
240
|
+
metadataHash: {
|
|
241
|
+
url: "https://polkadot-westend-metadata-shortener.api.live.ledger.com/node/metadata/hash",
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const subscriptions: any[] = [];
|
|
246
|
+
|
|
247
|
+
export const WestendScenario: Scenario<PolkadotTransaction, PolkadotAccount> = {
|
|
248
|
+
name: "Westend Ledger Live transactions",
|
|
249
|
+
setup: async () => {
|
|
250
|
+
const [{ transport, getOnSpeculosConfirmation }] = await Promise.all([
|
|
251
|
+
spawnSpeculos(
|
|
252
|
+
`/${defaultNanoApp.firmware}/PolkadotMigration/app_${defaultNanoApp.version}.elf`,
|
|
253
|
+
),
|
|
254
|
+
spawnChopsticksAndSidecar("coin-tester-chopsticks/westend.yml"),
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
const onSignerConfirmation = getOnSpeculosConfirmation("APPROVE");
|
|
258
|
+
|
|
259
|
+
await cryptoWaitReady();
|
|
260
|
+
await wsProvider.connect();
|
|
261
|
+
api = await ApiPromise.create({ provider: wsProvider, noInitWarn: true });
|
|
262
|
+
|
|
263
|
+
const keyring = new Keyring({ type: "sr25519" });
|
|
264
|
+
keyring.setSS58Format(0);
|
|
265
|
+
|
|
266
|
+
const signerContext: Parameters<typeof resolver>[0] = (_, fn) => fn(new Polkadot(transport));
|
|
267
|
+
|
|
268
|
+
const { accountBridge, currencyBridge } = createBridges(signerContext, () => coinConfig);
|
|
269
|
+
|
|
270
|
+
const getAddress = resolver(signerContext);
|
|
271
|
+
const { address } = await getAddress("", {
|
|
272
|
+
path: "44'/354'/0'/0'/0'",
|
|
273
|
+
currency: westend,
|
|
274
|
+
derivationMode: "polkadotbip44",
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const polkadotScenarioAccountPair = keyring.addFromAddress(address, {
|
|
278
|
+
name: "BASIC_SCENARIO_ACCOUNT",
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// https://polkadot.js.org/docs/keyring/start/suri/#dev-accounts
|
|
282
|
+
const alice = keyring.addFromUri("//Alice");
|
|
283
|
+
|
|
284
|
+
const unsub = await api.tx.balances
|
|
285
|
+
.transferAllowDeath(
|
|
286
|
+
polkadotScenarioAccountPair.address,
|
|
287
|
+
parseCurrencyUnit(westend.units[0], "500000").toNumber(),
|
|
288
|
+
)
|
|
289
|
+
.signAndSend(alice, result => {
|
|
290
|
+
if (result.status.isFinalized) {
|
|
291
|
+
unsub();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const account = makeAccount(polkadotScenarioAccountPair.address, westend);
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
accountBridge,
|
|
299
|
+
currencyBridge,
|
|
300
|
+
address: polkadotScenarioAccountPair.address,
|
|
301
|
+
account,
|
|
302
|
+
onSignerConfirmation,
|
|
303
|
+
};
|
|
304
|
+
},
|
|
305
|
+
getTransactions,
|
|
306
|
+
mockIndexer: async (account, optimistic) => {
|
|
307
|
+
unsubscribeNewBlockListener = await api.rpc.chain.subscribeNewHeads(async header => {
|
|
308
|
+
const blockHash = header.hash.toString();
|
|
309
|
+
|
|
310
|
+
const res = await fetch(`${SIDECAR_BASE_URL}/blocks/${blockHash}`);
|
|
311
|
+
const blockInfo = await res.json();
|
|
312
|
+
|
|
313
|
+
const extrinsic = blockInfo.extrinsics.find((extrinsic: any) => {
|
|
314
|
+
return extrinsic.hash === optimistic.hash;
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// we only need the transactions made during the test
|
|
318
|
+
if (!extrinsic) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const { nonce } = (await api.query.system.account(account.freshAddress)) as any;
|
|
323
|
+
|
|
324
|
+
const polkadotExtra = optimistic.extra as PolkadotOperationExtra;
|
|
325
|
+
let amount = new BigNumber(0);
|
|
326
|
+
let staking: ExplorerExtrinsic["staking"] = {} as ExplorerExtrinsic["staking"];
|
|
327
|
+
let validatorStash = "";
|
|
328
|
+
|
|
329
|
+
switch (polkadotExtra.palletMethod) {
|
|
330
|
+
case "balances.transfer":
|
|
331
|
+
case "balances.transferAllowDeath":
|
|
332
|
+
case "balances.transferKeepAlive":
|
|
333
|
+
amount = new BigNumber(polkadotExtra.transferAmount!);
|
|
334
|
+
break;
|
|
335
|
+
case "staking.bond":
|
|
336
|
+
case "staking.rebond":
|
|
337
|
+
amount = new BigNumber(polkadotExtra.bondedAmount!);
|
|
338
|
+
break;
|
|
339
|
+
case "staking.unbond":
|
|
340
|
+
amount = new BigNumber(polkadotExtra.unbondedAmount!);
|
|
341
|
+
break;
|
|
342
|
+
case "staking.withdrawUnbonded":
|
|
343
|
+
staking = {
|
|
344
|
+
validators: polkadotExtra.validators?.map(address => ({ address })) ?? [],
|
|
345
|
+
eventStaking: [
|
|
346
|
+
{
|
|
347
|
+
section: "staking",
|
|
348
|
+
method: "Withdraw",
|
|
349
|
+
value: polkadotExtra.withdrawUnbondedAmount!.toNumber(),
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
};
|
|
353
|
+
break;
|
|
354
|
+
case "staking.nominate":
|
|
355
|
+
staking = {
|
|
356
|
+
validators: polkadotExtra.validators?.map(address => ({ address })) ?? [],
|
|
357
|
+
eventStaking: [
|
|
358
|
+
{
|
|
359
|
+
section: "staking",
|
|
360
|
+
method: "Nominate",
|
|
361
|
+
value: 0,
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
break;
|
|
366
|
+
case "staking.chill":
|
|
367
|
+
break;
|
|
368
|
+
case "staking.payoutStakers":
|
|
369
|
+
validatorStash = extrinsic.args.validator_stash!;
|
|
370
|
+
break;
|
|
371
|
+
default:
|
|
372
|
+
throw new Error(`Unsupported pallet method: ${polkadotExtra.palletMethod}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
indexOperation(account.freshAddress, {
|
|
376
|
+
blockNumber: blockInfo.number,
|
|
377
|
+
timestamp: optimistic.date.getTime(),
|
|
378
|
+
nonce,
|
|
379
|
+
hash: optimistic.hash,
|
|
380
|
+
signer: extrinsic.signature.signer.id,
|
|
381
|
+
affectedAddress1: optimistic.recipients[0],
|
|
382
|
+
method: extrinsic.method.method,
|
|
383
|
+
section: extrinsic.method.pallet,
|
|
384
|
+
isSuccess: extrinsic.success,
|
|
385
|
+
amount: amount.toNumber(),
|
|
386
|
+
partialFee: optimistic.fee.toNumber(),
|
|
387
|
+
staking: staking!,
|
|
388
|
+
validatorStash,
|
|
389
|
+
index: 2, // not used by coin-module
|
|
390
|
+
isBatch: false, // batch transactions are not supported in this coin module
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
},
|
|
394
|
+
beforeAll: async account => {
|
|
395
|
+
expect(formatCurrencyUnit(westend.units[0], account.balance, { useGrouping: false })).toBe(
|
|
396
|
+
"500000",
|
|
397
|
+
);
|
|
398
|
+
},
|
|
399
|
+
beforeSync: async () => {
|
|
400
|
+
await wsProvider.send("dev_newBlock", [{ count: 1 }]);
|
|
401
|
+
},
|
|
402
|
+
afterEach: async () => {
|
|
403
|
+
unsubscribeNewBlockListener();
|
|
404
|
+
},
|
|
405
|
+
teardown: async () => {
|
|
406
|
+
subscriptions.forEach(unsub => unsub());
|
|
407
|
+
await wsProvider.disconnect();
|
|
408
|
+
await Promise.all([killSpeculos(), killChopsticksAndSidecar()]);
|
|
409
|
+
},
|
|
410
|
+
};
|
package/src/scenarii.test.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { executeScenario } from "@ledgerhq/coin-tester/main";
|
|
|
3
3
|
import { killSpeculos } from "@ledgerhq/coin-tester/signers/speculos";
|
|
4
4
|
import { killChopsticksAndSidecar } from "./chopsticks-sidecar";
|
|
5
5
|
import { PolkadotScenario } from "./scenarii/Polkadot";
|
|
6
|
+
import { WestendScenario } from "./scenarii/Westend";
|
|
6
7
|
|
|
7
8
|
global.console = console;
|
|
8
9
|
jest.setTimeout(300_000);
|
|
@@ -20,6 +21,17 @@ describe("Polkadot Deterministic Tester", () => {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
});
|
|
24
|
+
|
|
25
|
+
it.skip("scenario Westend", async () => {
|
|
26
|
+
try {
|
|
27
|
+
await executeScenario(WestendScenario);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
if (e != "done") {
|
|
30
|
+
await Promise.all([killSpeculos(), killChopsticksAndSidecar()]);
|
|
31
|
+
throw e;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
23
35
|
});
|
|
24
36
|
|
|
25
37
|
["exit", "SIGINT", "SIGQUIT", "SIGTERM", "SIGUSR1", "SIGUSR2", "uncaughtException"].map(e =>
|