Skip to content

Commit a5f0002

Browse files
Merge pull request #54 from developerfred/improve-error-handling-code-runner
Add Asset Hub Operations Example
2 parents 86629dd + 14b86b6 commit a5f0002

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import type { Network } from "../types/network";
2+
import { ExampleFactory } from "./factory";
3+
4+
export class AssetHubExample extends ExampleFactory {
5+
constructor() {
6+
super({
7+
id: "asset-hub-operations",
8+
name: "Asset Hub Operations",
9+
description: "Demonstrate Asset Hub operations: foreign assets, teleport assets, and reserve transfers",
10+
level: "advanced",
11+
categories: ["assets", "xcm", "transfers", "parachains"],
12+
});
13+
}
14+
15+
generateCode(network: Network): string {
16+
return `// Asset Hub Operations Example on ${network.name}
17+
${this.getImports(network, true)}
18+
19+
// Connect to ${network.name} Asset Hub
20+
const client = createClient(
21+
withPolkadotSdkCompat(
22+
getWsProvider("${network.endpoint}")
23+
)
24+
);
25+
26+
// Get the typed API using the descriptors
27+
const typedApi = client.getTypedApi(${network.descriptorKey});
28+
29+
// Asset Hub operations demonstration
30+
const demonstrateAssetHubOperations = async () => {
31+
try {
32+
console.log("🚀 Starting Asset Hub operations demonstration...");
33+
34+
// 1. Query foreign assets
35+
console.log("\\n🔍 Querying foreign assets:");
36+
const foreignAssets = await typedApi.query.ForeignAssets.Asset.getEntries();
37+
console.log("Found", foreignAssets.length, "foreign assets");
38+
39+
if (foreignAssets.length > 0) {
40+
const firstAsset = foreignAssets[0];
41+
console.log("First asset details:", {
42+
assetId: firstAsset.key?.args?.[0],
43+
details: firstAsset.value
44+
});
45+
}
46+
47+
// 2. Query asset balances
48+
console.log("\\n💰 Querying asset balances:");
49+
const aliceAddress = "${this.getTestAccount("alice")}";
50+
51+
// Native token balance (DOT/KSM)
52+
const nativeBalance = await typedApi.query.System.Account.getValue(aliceAddress);
53+
console.log("Native balance:", nativeBalance.data.free.toString(), "${network.tokenSymbol}");
54+
55+
// 3. Demonstrate asset transfer (would require foreign asset)
56+
console.log("\\n📤 Asset Transfer Example:");
57+
console.log("This would transfer foreign assets between accounts:");
58+
const transferTx = typedApi.tx.ForeignAssets.transfer({
59+
id: { parents: 0, interior: { X1: { PalletInstance: 50 } } }, // Example asset ID
60+
target: MultiAddress.Id("${this.getTestAccount("bob")}"),
61+
amount: 1000000000000n // 1000 tokens (adjust for decimals)
62+
});
63+
console.log("Asset transfer transaction created (not submitted in simulator)");
64+
65+
// 4. Demonstrate teleport assets (XCM)
66+
console.log("\\n✈️ Teleport Assets Example:");
67+
console.log("This would teleport assets to another parachain:");
68+
const teleportTx = typedApi.tx.PolkadotXcm.teleport_assets({
69+
dest: {
70+
V4: {
71+
parents: 1,
72+
interior: {
73+
X1: { Parachain: 2000 } // Example parachain ID
74+
}
75+
}
76+
},
77+
beneficiary: {
78+
V4: {
79+
parents: 0,
80+
interior: {
81+
X1: { AccountId32: { id: "${this.getTestAccount("alice")}" } }
82+
}
83+
}
84+
},
85+
assets: {
86+
V4: [{
87+
id: { Concrete: { parents: 1, interior: "Here" } },
88+
fun: { Fungible: 1000000000000n }
89+
}]
90+
},
91+
fee_asset_item: 0
92+
});
93+
console.log("Teleport transaction created (not submitted in simulator)");
94+
95+
// 5. Query reserve transfers
96+
console.log("\\n🔄 Reserve Transfer Example:");
97+
console.log("This would perform a reserve transfer to another parachain:");
98+
const reserveTransferTx = typedApi.tx.PolkadotXcm.reserve_transfer_assets({
99+
dest: {
100+
V4: {
101+
parents: 1,
102+
interior: {
103+
X1: { Parachain: 2000 }
104+
}
105+
}
106+
},
107+
beneficiary: {
108+
V4: {
109+
parents: 0,
110+
interior: {
111+
X1: { AccountId32: { id: "${this.getTestAccount("bob")}" } }
112+
}
113+
}
114+
},
115+
assets: {
116+
V4: [{
117+
id: { Concrete: { parents: 1, interior: "Here" } },
118+
fun: { Fungible: 500000000000n }
119+
}]
120+
},
121+
fee_asset_item: 0
122+
});
123+
console.log("Reserve transfer transaction created (not submitted in simulator)");
124+
125+
// 6. Query asset metadata
126+
console.log("\\n📋 Asset Metadata:");
127+
try {
128+
const assetMetadata = await typedApi.query.ForeignAssets.Metadata.getEntries();
129+
console.log("Found metadata for", assetMetadata.length, "assets");
130+
131+
if (assetMetadata.length > 0) {
132+
const firstMetadata = assetMetadata[0];
133+
console.log("Asset metadata:", {
134+
assetId: firstMetadata.key?.args?.[0],
135+
name: firstMetadata.value?.name?.toString(),
136+
symbol: firstMetadata.value?.symbol?.toString(),
137+
decimals: firstMetadata.value?.decimals?.toString()
138+
});
139+
}
140+
} catch (error) {
141+
console.log("Asset metadata not available or different structure");
142+
}
143+
144+
// 7. Query asset approvals
145+
console.log("\\n✅ Asset Approvals:");
146+
try {
147+
const approvals = await typedApi.query.ForeignAssets.Approvals.getEntries();
148+
console.log("Found", approvals.length, "asset approvals");
149+
} catch (error) {
150+
console.log("Asset approvals query not available");
151+
}
152+
153+
console.log("\\n✅ Asset Hub operations demonstration completed!");
154+
console.log("Note: Asset Hub operations typically require:");
155+
console.log("- Foreign asset registration on the hub");
156+
console.log("- Sufficient balance of the asset");
157+
console.log("- Proper XCM configuration between chains");
158+
console.log("- In a real application, you would sign and submit these transactions");
159+
160+
} catch (error) {
161+
console.error("❌ Error in Asset Hub operations:", error);
162+
}
163+
};
164+
165+
demonstrateAssetHubOperations().catch(console.error);
166+
`;
167+
}
168+
}

src/lib/examples/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* eslint-disable @typescript-eslint/ban-ts-comment */
22
import { exampleRegistry } from "./factory";
33
import { StakingOperationsExample } from "./StakingOperationsExample";
4+
import { AssetHubExample } from "./AssetHubExample";
5+
46

57
import { SimpleTransferExample } from "./SimpleTransferExample";
68
import { NetworkDashboardExample } from "./NetworkDashboardExample";
@@ -10,6 +12,8 @@ import { AcalaDeFiExample } from "./AcalaDeFiExample";
1012
import type { Example, ExampleLevel } from "../types/example";
1113
import { PolkadotGovernanceExample } from "./PolkadotGovernanceExample";
1214

15+
new AssetHubExample(),
16+
1317
new StakingOperationsExample(),
1418

1519
exampleRegistry.registerMany([

0 commit comments

Comments
 (0)