1- import { paseoAssetHub , paseoBridgeHub } from "@polkadot-api/descriptors" ;
2- import {
3- createClient ,
4- FixedSizeBinary ,
5- Enum ,
6- } from "polkadot-api" ;
7- import { getWsProvider } from "polkadot-api/ws-provider/node" ;
8- import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat" ;
1+ import { paseoAssetHub , paseoBridgeHub } from '@polkadot-api/descriptors' ;
2+ import { createClient , FixedSizeBinary , Enum } from 'polkadot-api' ;
3+ import { getWsProvider } from 'polkadot-api/ws-provider/node' ;
4+ import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat' ;
95import {
106 XcmVersionedLocation ,
117 XcmVersionedAssetId ,
@@ -17,20 +13,21 @@ import {
1713 XcmV5Junction ,
1814 XcmV5AssetFilter ,
1915 XcmV5WildAsset ,
20- } from " @polkadot-api/descriptors" ;
16+ } from ' @polkadot-api/descriptors' ;
2117
2218// 1 PAS = 10^10 units
2319const PAS_UNITS = 10_000_000_000n ; // 1 PAS
2420const PAS_CENTS = 100_000_000n ; // 0.01 PAS
2521
2622// Paseo Asset Hub constants
27- const PASEO_ASSET_HUB_RPC_ENDPOINT = " ws://localhost:8001" ;
28- const ASSET_HUB_ACCOUNT = " 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5" ; // Alice (Paseo Asset Hub)
23+ const PASEO_ASSET_HUB_RPC_ENDPOINT = ' ws://localhost:8001' ;
24+ const ASSET_HUB_ACCOUNT = ' 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5' ; // Alice (Paseo Asset Hub)
2925
3026// Bridge Hub destination
31- const BRIDGE_HUB_RPC_ENDPOINT = " ws://localhost:8000" ;
27+ const BRIDGE_HUB_RPC_ENDPOINT = ' ws://localhost:8000' ;
3228const BRIDGE_HUB_PARA_ID = 1002 ;
33- const BRIDGE_HUB_BENEFICIARY = "14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3" ; // Bob (Bridge Hub)
29+ const BRIDGE_HUB_BENEFICIARY =
30+ '14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3' ; // Bob (Bridge Hub)
3431
3532// Create the XCM message for teleport (Asset Hub → Bridge Hub)
3633function createTeleportXcmToBridgeHub ( paraId : number ) {
@@ -56,7 +53,7 @@ function createTeleportXcmToBridgeHub(paraId: number) {
5653 interior : XcmV5Junctions . X1 ( XcmV5Junction . Parachain ( paraId ) ) ,
5754 } ,
5855 remote_fees : Enum (
59- " Teleport" ,
56+ ' Teleport' ,
6057 XcmV5AssetFilter . Definite ( [
6158 {
6259 id : { parents : 1 , interior : XcmV5Junctions . Here ( ) } ,
@@ -74,50 +71,65 @@ function createTeleportXcmToBridgeHub(paraId: number) {
7471 XcmV5Junction . AccountId32 ( {
7572 network : undefined ,
7673 id : FixedSizeBinary . fromAccountId32 ( BRIDGE_HUB_BENEFICIARY ) ,
77- } )
74+ } ) ,
7875 ) ,
7976 } ,
8077 } ) ,
8178 ] ,
8279 assets : [
83- Enum ( " Teleport" , XcmV5AssetFilter . Wild ( XcmV5WildAsset . AllCounted ( 1 ) ) ) , // Send everything.
80+ Enum ( ' Teleport' , XcmV5AssetFilter . Wild ( XcmV5WildAsset . AllCounted ( 1 ) ) ) , // Send everything.
8481 ] ,
8582 } ) ,
8683 ] ) ;
8784}
8885
89- async function estimateXcmFeesFromAssetHubToBridgeHub ( xcm : any , assetHubApi : any ) {
90- console . log ( "=== Fee Estimation Process (Asset Hub → Bridge Hub) ===" ) ;
86+ async function estimateXcmFeesFromAssetHubToBridgeHub (
87+ xcm : any ,
88+ assetHubApi : any ,
89+ ) {
90+ console . log ( '=== Fee Estimation Process (Asset Hub → Bridge Hub) ===' ) ;
9191
9292 // 1. LOCAL EXECUTION FEES on Asset Hub
93- console . log ( " 1. Calculating local execution fees on Asset Hub..." ) ;
93+ console . log ( ' 1. Calculating local execution fees on Asset Hub...' ) ;
9494 let localExecutionFees = 0n ;
9595
96- const weightResult = await assetHubApi . apis . XcmPaymentApi . query_xcm_weight ( xcm ) ;
96+ const weightResult =
97+ await assetHubApi . apis . XcmPaymentApi . query_xcm_weight ( xcm ) ;
9798 if ( weightResult . success ) {
98- console . log ( " ✓ XCM weight (Asset Hub):" , weightResult . value ) ;
99+ console . log ( ' ✓ XCM weight (Asset Hub):' , weightResult . value ) ;
99100
100101 // Convert weight to PAS fees from Asset Hub's perspective (parents:1, Here)
101- const executionFeesResult = await assetHubApi . apis . XcmPaymentApi . query_weight_to_asset_fee (
102- weightResult . value ,
103- XcmVersionedAssetId . V4 ( {
104- parents : 1 ,
105- interior : XcmV3Junctions . Here ( ) ,
106- } )
107- ) ;
102+ const executionFeesResult =
103+ await assetHubApi . apis . XcmPaymentApi . query_weight_to_asset_fee (
104+ weightResult . value ,
105+ XcmVersionedAssetId . V4 ( {
106+ parents : 1 ,
107+ interior : XcmV3Junctions . Here ( ) ,
108+ } ) ,
109+ ) ;
108110
109111 if ( executionFeesResult . success ) {
110112 localExecutionFees = executionFeesResult . value ;
111- console . log ( "✓ Local execution fees (Asset Hub):" , localExecutionFees . toString ( ) , "PAS units" ) ;
113+ console . log (
114+ '✓ Local execution fees (Asset Hub):' ,
115+ localExecutionFees . toString ( ) ,
116+ 'PAS units' ,
117+ ) ;
112118 } else {
113- console . log ( "✗ Failed to calculate local execution fees:" , executionFeesResult . value ) ;
119+ console . log (
120+ '✗ Failed to calculate local execution fees:' ,
121+ executionFeesResult . value ,
122+ ) ;
114123 }
115124 } else {
116- console . log ( "✗ Failed to query XCM weight on Asset Hub:" , weightResult . value ) ;
125+ console . log (
126+ '✗ Failed to query XCM weight on Asset Hub:' ,
127+ weightResult . value ,
128+ ) ;
117129 }
118130
119131 // 2. DELIVERY FEES + REMOTE EXECUTION FEES
120- console . log ( " \n2. Calculating delivery and remote execution fees..." ) ;
132+ console . log ( ' \n2. Calculating delivery and remote execution fees...' ) ;
121133 let deliveryFees = 0n ;
122134 let remoteExecutionFees = 0n ; // Skipped (Bridge Hub descriptor not available)
123135
@@ -128,83 +140,119 @@ async function estimateXcmFeesFromAssetHubToBridgeHub(xcm: any, assetHubApi: any
128140 XcmV5Junction . AccountId32 ( {
129141 id : FixedSizeBinary . fromAccountId32 ( ASSET_HUB_ACCOUNT ) ,
130142 network : undefined ,
131- } )
143+ } ) ,
132144 ) ,
133145 } ) ;
134146
135147 // Dry run the XCM locally on Asset Hub
136- const dryRunResult = await assetHubApi . apis . DryRunApi . dry_run_xcm ( origin , xcm ) ;
148+ const dryRunResult = await assetHubApi . apis . DryRunApi . dry_run_xcm (
149+ origin ,
150+ xcm ,
151+ ) ;
137152
138- if ( dryRunResult . success && dryRunResult . value . execution_result . type === "Complete" ) {
139- console . log ( "✓ Local dry run on Asset Hub successful" ) ;
153+ if (
154+ dryRunResult . success &&
155+ dryRunResult . value . execution_result . type === 'Complete'
156+ ) {
157+ console . log ( '✓ Local dry run on Asset Hub successful' ) ;
140158
141159 const { forwarded_xcms : forwardedXcms } = dryRunResult . value ;
142160
143161 // Find the XCM message sent to Bridge Hub (parents:1, interior: X1(Parachain(1002)))
144162 const bridgeHubXcmEntry = forwardedXcms . find (
145163 ( [ location , _ ] : [ any , any ] ) =>
146- ( location . type === "V4" || location . type === "V5" ) &&
164+ ( location . type === 'V4' || location . type === 'V5' ) &&
147165 location . value . parents === 1 &&
148- location . value . interior ?. type === "X1" &&
149- location . value . interior . value ?. type === " Parachain" &&
150- location . value . interior . value . value === BRIDGE_HUB_PARA_ID
166+ location . value . interior ?. type === 'X1' &&
167+ location . value . interior . value ?. type === ' Parachain' &&
168+ location . value . interior . value . value === BRIDGE_HUB_PARA_ID ,
151169 ) ;
152170
153171 if ( bridgeHubXcmEntry ) {
154172 const [ destination , messages ] = bridgeHubXcmEntry ;
155173 const remoteXcm = messages [ 0 ] ;
156174
157- console . log ( " ✓ Found XCM message to Bridge Hub" ) ;
175+ console . log ( ' ✓ Found XCM message to Bridge Hub' ) ;
158176
159177 // Calculate delivery fees from Asset Hub to Bridge Hub
160- const deliveryFeesResult = await assetHubApi . apis . XcmPaymentApi . query_delivery_fees (
161- destination ,
162- remoteXcm
163- ) ;
178+ const deliveryFeesResult =
179+ await assetHubApi . apis . XcmPaymentApi . query_delivery_fees (
180+ destination ,
181+ remoteXcm ,
182+ ) ;
164183
165184 if (
166185 deliveryFeesResult . success &&
167- deliveryFeesResult . value . type === "V5" &&
168- deliveryFeesResult . value . value [ 0 ] ?. fun ?. type === " Fungible"
186+ deliveryFeesResult . value . type === 'V5' &&
187+ deliveryFeesResult . value . value [ 0 ] ?. fun ?. type === ' Fungible'
169188 ) {
170189 deliveryFees = deliveryFeesResult . value . value [ 0 ] . fun . value ;
171- console . log ( " ✓ Delivery fees:" , deliveryFees . toString ( ) , " PAS units" ) ;
190+ console . log ( ' ✓ Delivery fees:' , deliveryFees . toString ( ) , ' PAS units' ) ;
172191 } else {
173- console . log ( " ✗ Failed to calculate delivery fees:" , deliveryFeesResult ) ;
192+ console . log ( ' ✗ Failed to calculate delivery fees:' , deliveryFeesResult ) ;
174193 }
175194
176- // 3. REMOTE EXECUTION FEES on Bridge Hub
177- console . log ( "\n3. Calculating remote execution fees on Bridge Hub" ) ;
178- try {
179- const bridgeHubClient = createClient ( withPolkadotSdkCompat ( getWsProvider ( BRIDGE_HUB_RPC_ENDPOINT ) ) ) ;
180- const bridgeHubApi = bridgeHubClient . getTypedApi ( paseoBridgeHub ) ;
181- const remoteWeightResult = await bridgeHubApi . apis . XcmPaymentApi . query_xcm_weight ( remoteXcm ) ;
182- const remoteFeesResult = await bridgeHubApi . apis . XcmPaymentApi . query_weight_to_asset_fee (
183- remoteWeightResult . value as { ref_time : bigint ; proof_size : bigint } ,
184- XcmVersionedAssetId . V4 ( { parents : 1 , interior : XcmV3Junctions . Here ( ) } )
195+ // 3. REMOTE EXECUTION FEES on Bridge Hub
196+ console . log ( '\n3. Calculating remote execution fees on Bridge Hub' ) ;
197+ try {
198+ const bridgeHubClient = createClient (
199+ withPolkadotSdkCompat ( getWsProvider ( BRIDGE_HUB_RPC_ENDPOINT ) ) ,
200+ ) ;
201+ const bridgeHubApi = bridgeHubClient . getTypedApi ( paseoBridgeHub ) ;
202+ const remoteWeightResult =
203+ await bridgeHubApi . apis . XcmPaymentApi . query_xcm_weight ( remoteXcm ) ;
204+ const remoteFeesResult =
205+ await bridgeHubApi . apis . XcmPaymentApi . query_weight_to_asset_fee (
206+ remoteWeightResult . value as {
207+ ref_time : bigint ;
208+ proof_size : bigint ;
209+ } ,
210+ XcmVersionedAssetId . V4 ( {
211+ parents : 1 ,
212+ interior : XcmV3Junctions . Here ( ) ,
213+ } ) ,
185214 ) ;
186- bridgeHubClient . destroy ( ) ;
187- remoteExecutionFees = remoteFeesResult . value as bigint ;
188- console . log ( "✓ Remote execution fees:" , remoteExecutionFees . toString ( ) , "PAS units" ) ;
189- } catch ( error ) {
190- console . error ( "Error calculating remote execution fees on Bridge Hub:" , error ) ;
191- }
215+ bridgeHubClient . destroy ( ) ;
216+ remoteExecutionFees = remoteFeesResult . value as bigint ;
217+ console . log (
218+ '✓ Remote execution fees:' ,
219+ remoteExecutionFees . toString ( ) ,
220+ 'PAS units' ,
221+ ) ;
222+ } catch ( error ) {
223+ console . error (
224+ 'Error calculating remote execution fees on Bridge Hub:' ,
225+ error ,
226+ ) ;
227+ }
192228 } else {
193- console . log ( " ✗ No XCM message found to Bridge Hub" ) ;
229+ console . log ( ' ✗ No XCM message found to Bridge Hub' ) ;
194230 }
195231 } else {
196- console . log ( " ✗ Local dry run failed on Asset Hub:" , dryRunResult . value ) ;
232+ console . log ( ' ✗ Local dry run failed on Asset Hub:' , dryRunResult . value ) ;
197233 }
198234
199235 // 4. TOTAL FEES
200236 const totalFees = localExecutionFees + deliveryFees + remoteExecutionFees ;
201237
202- console . log ( "\n=== Fee Summary (Asset Hub → Bridge Hub) ===" ) ;
203- console . log ( "Local execution fees:" , localExecutionFees . toString ( ) , "PAS units" ) ;
204- console . log ( "Delivery fees:" , deliveryFees . toString ( ) , "PAS units" ) ;
205- console . log ( "Remote execution fees:" , remoteExecutionFees . toString ( ) , "PAS units" ) ;
206- console . log ( "TOTAL FEES:" , totalFees . toString ( ) , "PAS units" ) ;
207- console . log ( "TOTAL FEES:" , ( Number ( totalFees ) / Number ( PAS_UNITS ) ) . toFixed ( 4 ) , "PAS" ) ;
238+ console . log ( '\n=== Fee Summary (Asset Hub → Bridge Hub) ===' ) ;
239+ console . log (
240+ 'Local execution fees:' ,
241+ localExecutionFees . toString ( ) ,
242+ 'PAS units' ,
243+ ) ;
244+ console . log ( 'Delivery fees:' , deliveryFees . toString ( ) , 'PAS units' ) ;
245+ console . log (
246+ 'Remote execution fees:' ,
247+ remoteExecutionFees . toString ( ) ,
248+ 'PAS units' ,
249+ ) ;
250+ console . log ( 'TOTAL FEES:' , totalFees . toString ( ) , 'PAS units' ) ;
251+ console . log (
252+ 'TOTAL FEES:' ,
253+ ( Number ( totalFees ) / Number ( PAS_UNITS ) ) . toFixed ( 4 ) ,
254+ 'PAS' ,
255+ ) ;
208256
209257 return {
210258 localExecutionFees,
@@ -216,7 +264,9 @@ async function estimateXcmFeesFromAssetHubToBridgeHub(xcm: any, assetHubApi: any
216264
217265async function main ( ) {
218266 // Connect to the Asset Hub parachain
219- const assetHubClient = createClient ( withPolkadotSdkCompat ( getWsProvider ( PASEO_ASSET_HUB_RPC_ENDPOINT ) ) ) ;
267+ const assetHubClient = createClient (
268+ withPolkadotSdkCompat ( getWsProvider ( PASEO_ASSET_HUB_RPC_ENDPOINT ) ) ,
269+ ) ;
220270
221271 // Get the typed API for Asset Hub
222272 const assetHubApi = assetHubClient . getTypedApi ( paseoAssetHub ) ;
@@ -225,11 +275,11 @@ async function main() {
225275 // Create the XCM message for teleport (Asset Hub → Bridge Hub)
226276 const xcm = createTeleportXcmToBridgeHub ( BRIDGE_HUB_PARA_ID ) ;
227277
228- console . log ( " === XCM Teleport: Paseo Asset Hub → Bridge Hub ===" ) ;
229- console . log ( " From:" , ASSET_HUB_ACCOUNT , " (Alice on Asset Hub)" ) ;
230- console . log ( " To:" , BRIDGE_HUB_BENEFICIARY , " (Beneficiary on Bridge Hub)" ) ;
231- console . log ( " Amount:" , " 1 PAS" ) ;
232- console . log ( "" ) ;
278+ console . log ( ' === XCM Teleport: Paseo Asset Hub → Bridge Hub ===' ) ;
279+ console . log ( ' From:' , ASSET_HUB_ACCOUNT , ' (Alice on Asset Hub)' ) ;
280+ console . log ( ' To:' , BRIDGE_HUB_BENEFICIARY , ' (Beneficiary on Bridge Hub)' ) ;
281+ console . log ( ' Amount:' , ' 1 PAS' ) ;
282+ console . log ( '' ) ;
233283
234284 // Estimate all fees
235285 const fees = await estimateXcmFeesFromAssetHubToBridgeHub ( xcm , assetHubApi ) ;
@@ -244,12 +294,12 @@ async function main() {
244294 } ,
245295 } ) ;
246296
247- console . log ( " \n=== Transaction Details ===" ) ;
248- console . log ( " Transaction hex:" , ( await tx . getEncodedData ( ) ) . asHex ( ) ) ;
249- console . log ( " Ready to submit!" ) ;
297+ console . log ( ' \n=== Transaction Details ===' ) ;
298+ console . log ( ' Transaction hex:' , ( await tx . getEncodedData ( ) ) . asHex ( ) ) ;
299+ console . log ( ' Ready to submit!' ) ;
250300 } catch ( error ) {
251- console . log ( " Error stack:" , ( error as Error ) . stack ) ;
252- console . error ( " Error occurred:" , ( error as Error ) . message ) ;
301+ console . log ( ' Error stack:' , ( error as Error ) . stack ) ;
302+ console . error ( ' Error occurred:' , ( error as Error ) . message ) ;
253303 if ( ( error as Error ) . cause ) {
254304 console . dir ( ( error as Error ) . cause , { depth : null } ) ;
255305 }
@@ -259,4 +309,4 @@ async function main() {
259309 }
260310}
261311
262- main ( ) . catch ( console . error ) ;
312+ main ( ) . catch ( console . error ) ;
0 commit comments