Skip to content

Commit 9eb6bde

Browse files
Add scripts
1 parent 04bb02f commit 9eb6bde

File tree

5 files changed

+609
-48
lines changed

5 files changed

+609
-48
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<div class="termynal" data-termynal>
2+
<pre data-ty>
3+
[
4+
{
5+
"type": "ReserveAssetDeposited",
6+
"value": [...]
7+
},
8+
{
9+
"type": "ClearOrigin"
10+
},
11+
{
12+
"type": "BuyExecution",
13+
"value": {...}
14+
},
15+
{
16+
"type": "DepositAsset",
17+
"value": {...}
18+
},
19+
{
20+
"type": "SetTopic",
21+
"value": "0xb4b8d2c87622cbad983d8f2c92bfe28e12d587e13d15ea4fdabe8f771bf86bce"
22+
}
23+
]
24+
</pre>
25+
</div>
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import {Binary, createClient, Enum, Transaction} from "polkadot-api";
2+
import {withPolkadotSdkCompat} from "polkadot-api/polkadot-sdk-compat";
3+
import {getPolkadotSigner} from "polkadot-api/signer";
4+
import {getWsProvider} from "polkadot-api/ws-provider/web";
5+
import {
6+
acala,
7+
assetHub,
8+
XcmV3MultiassetFungibility,
9+
XcmV3WeightLimit,
10+
XcmV5Junction,
11+
XcmV5Junctions,
12+
XcmVersionedAssets,
13+
XcmVersionedLocation,
14+
} from "@polkadot-api/descriptors";
15+
import {sr25519CreateDerive} from "@polkadot-labs/hdkd";
16+
import {
17+
DEV_PHRASE,
18+
entropyToMiniSecret,
19+
mnemonicToEntropy,
20+
ss58Address,
21+
} from "@polkadot-labs/hdkd-helpers";
22+
23+
const XCM_VERSION = 5;
24+
25+
const toHuman = (_key: any, value: any) => {
26+
if (typeof value === "bigint") {
27+
return Number(value);
28+
}
29+
30+
if (value && typeof value === "object" && typeof value.asHex === "function") {
31+
return value.asHex();
32+
}
33+
34+
return value;
35+
};
36+
37+
async function main() {
38+
const assetHubClient = createClient(
39+
withPolkadotSdkCompat(getWsProvider("ws://localhost:8000")),
40+
);
41+
const assetHubApi = assetHubClient.getTypedApi(assetHub);
42+
43+
const parachainName = "Acala";
44+
const parachainClient = createClient(
45+
withPolkadotSdkCompat(getWsProvider("ws://localhost:8001")),
46+
);
47+
const parachainApi = parachainClient.getTypedApi(acala);
48+
49+
const entropy = mnemonicToEntropy(DEV_PHRASE);
50+
const miniSecret = entropyToMiniSecret(entropy);
51+
const derive = sr25519CreateDerive(miniSecret);
52+
const alice = derive("//Alice");
53+
const alicePublicKey = alice.publicKey;
54+
const aliceSigner = getPolkadotSigner(alicePublicKey, "Sr25519", alice.sign);
55+
const aliceAddress = ss58Address(alicePublicKey);
56+
57+
const origin = Enum("system", Enum("Signed", aliceAddress));
58+
const tx: Transaction<any, string, string, any> =
59+
assetHubApi.tx.PolkadotXcm.limited_reserve_transfer_assets({
60+
dest: XcmVersionedLocation.V5({
61+
parents: 1,
62+
interior: XcmV5Junctions.X1(XcmV5Junction.Parachain(2000)),
63+
}),
64+
beneficiary: XcmVersionedLocation.V5({
65+
parents: 0,
66+
interior: XcmV5Junctions.X1(
67+
XcmV5Junction.AccountId32({
68+
id: Binary.fromHex(
69+
"0x9818ff3c27d256631065ecabf0c50e02551e5c5342b8669486c1e566fcbf847f",
70+
),
71+
}),
72+
),
73+
}),
74+
assets: XcmVersionedAssets.V5([
75+
{
76+
id: {
77+
parents: 0,
78+
interior: XcmV5Junctions.X2([
79+
XcmV5Junction.PalletInstance(50),
80+
XcmV5Junction.GeneralIndex(1984n),
81+
]),
82+
},
83+
fun: XcmV3MultiassetFungibility.Fungible(500_000_000n),
84+
},
85+
]),
86+
fee_asset_item: 0,
87+
weight_limit: XcmV3WeightLimit.Unlimited(),
88+
});
89+
const decodedCall = tx.decodedCall as any;
90+
console.log("👀 Executing XCM:", JSON.stringify(decodedCall, toHuman, 2));
91+
92+
try {
93+
const dryRunResult: any = await assetHubApi.apis.DryRunApi.dry_run_call(
94+
origin,
95+
decodedCall,
96+
XCM_VERSION,
97+
);
98+
console.log(
99+
"📦 Dry run result:",
100+
JSON.stringify(dryRunResult.value, toHuman, 2),
101+
);
102+
103+
const executionResult = dryRunResult.value.execution_result;
104+
if (!dryRunResult.success || !executionResult.success) {
105+
console.error("❌ Local dry run failed!");
106+
} else {
107+
console.log("✅ Local dry run successful.");
108+
109+
const parachainBlockBefore = await parachainClient.getFinalizedBlock();
110+
const extrinsic = await tx.signAndSubmit(aliceSigner);
111+
const block = extrinsic.block;
112+
console.log(
113+
`📦 Finalised on Polkadot Asset Hub in block #${block.number}: ${block.hash}`,
114+
);
115+
116+
if (!extrinsic.ok) {
117+
const dispatchError = extrinsic.dispatchError;
118+
if (dispatchError.type === "Module") {
119+
const modErr: any = dispatchError.value;
120+
console.error(
121+
`❌ Dispatch error in module: ${modErr.type}${modErr.value?.type}`,
122+
);
123+
} else {
124+
console.error(
125+
"❌ Dispatch error:",
126+
JSON.stringify(dispatchError, toHuman, 2),
127+
);
128+
}
129+
}
130+
131+
const sentEvents = await assetHubApi.event.PolkadotXcm.Sent.pull();
132+
if (sentEvents.length > 0) {
133+
const sentMessageId = sentEvents[0].payload.message_id.asHex();
134+
console.log(
135+
`📣 Last message Sent on Polkadot Asset Hub: ${sentMessageId}`,
136+
);
137+
138+
let processedMessageId = undefined;
139+
const maxRetries = 8;
140+
for (let i = 0; i < maxRetries; i++) {
141+
const parachainBlockAfter = await parachainClient.getFinalizedBlock();
142+
if (parachainBlockAfter.number == parachainBlockBefore.number) {
143+
const waiting = 1_000 * (i + 1);
144+
console.log(
145+
`⏳ Waiting ${waiting}ms for ${parachainName} block to be finalised (${i + 1}/${maxRetries})...`,
146+
);
147+
await new Promise((resolve) => setTimeout(resolve, waiting));
148+
continue;
149+
}
150+
151+
console.log(
152+
`📦 Finalised on ${parachainName} in block #${parachainBlockAfter.number}: ${parachainBlockAfter.hash}`,
153+
);
154+
const processedEvents =
155+
await parachainApi.event.MessageQueue.Processed.pull();
156+
if (processedEvents.length > 0) {
157+
processedMessageId = processedEvents[0].payload.id.asHex();
158+
console.log(
159+
`📣 Last message Processed on ${parachainName}: ${processedMessageId}`,
160+
);
161+
} else {
162+
console.log(`📣 No Processed events on ${parachainName} found.`);
163+
}
164+
165+
break;
166+
}
167+
168+
if (processedMessageId === sentMessageId) {
169+
console.log("✅ Message ID matched.");
170+
} else {
171+
console.error(
172+
"❌ Processed message ID does not match sent message ID.",
173+
);
174+
}
175+
} else {
176+
console.log("📣 No Sent events on Polkadot Asset Hub found.");
177+
}
178+
}
179+
} finally {
180+
assetHubClient.destroy();
181+
parachainClient.destroy();
182+
}
183+
}
184+
185+
main().catch(console.error);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<div class="termynal" data-termynal>
2+
<pre data-ty>
3+
{
4+
"type": "TransferAsset",
5+
"value": {
6+
"assets": [...],
7+
"beneficiary": {...}
8+
}
9+
}
10+
</pre>
11+
</div>

0 commit comments

Comments
 (0)