Created
February 19, 2026 12:53
-
-
Save franciscoaguirre/bbc220de10562b0e9e7b5f1232f41e74 to your computer and use it in GitHub Desktop.
Transfer, swap and back
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { ahp, XcmV3MultiassetFungibility, XcmV5AssetFilter, XcmV5Instruction, XcmV5Junction, XcmV5Junctions, XcmV5WildAsset, XcmVersionedXcm } from "@polkadot-api/descriptors"; | |
| import { sr25519CreateDerive } from "@polkadot-labs/hdkd"; | |
| import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy } from "@polkadot-labs/hdkd-helpers"; | |
| import { createClient, Enum, FixedSizeBinary } from "polkadot-api"; | |
| import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat"; | |
| import { getPolkadotSigner } from "polkadot-api/signer"; | |
| import { getWsProvider } from "polkadot-api/ws-provider/web"; | |
| const entropy = mnemonicToEntropy(DEV_PHRASE); | |
| const miniSecret = entropyToMiniSecret(entropy); | |
| const derive = sr25519CreateDerive(miniSecret); | |
| const keyPair = derive("//Alice"); | |
| const polkadotSigner = getPolkadotSigner( | |
| keyPair.publicKey, | |
| "Sr25519", | |
| keyPair.sign, | |
| ); | |
| // Connect to Polkadot Asset Hub. | |
| // Pointing to localhost since we're using chopsticks in this example. | |
| const client = createClient( | |
| withPolkadotSdkCompat(getWsProvider("ws://localhost:8000")), | |
| ); | |
| // We get the typed api, a typesafe API for interacting with the chain. | |
| const ahpApi = client.getTypedApi(ahp); | |
| const ASSET_HUB_ID = 1000; | |
| const ASSETS_PALLET_INSTANCE = 50; | |
| const USDC_INDEX = 1337n; | |
| const HYDRATION_ID = 2034; | |
| const DOT = { | |
| parents: 1, | |
| interior: XcmV5Junctions.Here(), | |
| }; | |
| const USDC_HYDRATION_POV = { | |
| parents: 1, | |
| interior: XcmV5Junctions.X3([ | |
| XcmV5Junction.Parachain(ASSET_HUB_ID), | |
| XcmV5Junction.PalletInstance(ASSETS_PALLET_INSTANCE), | |
| XcmV5Junction.GeneralIndex(USDC_INDEX), | |
| ]), | |
| }; | |
| const DOT_UNITS = 10_000_000_000n; | |
| const USDX_UNITS = 1_000_000n; | |
| // Swap parameters. | |
| const DOT_TO_SWAP = 100n * DOT_UNITS; | |
| const DOT_FOR_FEES = 1n * DOT_UNITS; | |
| const USDC_WANT_AMOUNT = 100n * USDX_UNITS; | |
| const USDC_FOR_FEES = 1n * USDX_UNITS; | |
| const remoteXcm = [ | |
| XcmV5Instruction.ExchangeAsset({ | |
| give: XcmV5AssetFilter.Wild(XcmV5WildAsset.AllCounted(1)), | |
| want: [{ | |
| id: USDC_HYDRATION_POV, | |
| fun: XcmV3MultiassetFungibility.Fungible(USDC_WANT_AMOUNT), | |
| }], | |
| maximal: true | |
| }), | |
| XcmV5Instruction.InitiateTransfer({ | |
| destination: { | |
| parents: 1, | |
| interior: XcmV5Junctions.X1(XcmV5Junction.Parachain(ASSET_HUB_ID)) | |
| }, | |
| remote_fees: Enum('ReserveWithdraw', XcmV5AssetFilter.Definite([ | |
| { | |
| id: USDC_HYDRATION_POV, | |
| fun: XcmV3MultiassetFungibility.Fungible(USDC_FOR_FEES), | |
| }, | |
| ])), | |
| preserve_origin: false, | |
| remote_xcm: [ | |
| XcmV5Instruction.DepositAsset({ | |
| assets: XcmV5AssetFilter.Wild(XcmV5WildAsset.AllCounted(1)), | |
| beneficiary: { | |
| parents: 0, | |
| interior: XcmV5Junctions.X1(XcmV5Junction.AccountId32({ | |
| network: undefined, | |
| id: FixedSizeBinary.fromBytes(polkadotSigner.publicKey), | |
| })), | |
| }, | |
| }), | |
| ], | |
| assets: [ | |
| Enum('ReserveWithdraw', XcmV5AssetFilter.Wild(XcmV5WildAsset.AllCounted(1))), | |
| ], | |
| }), | |
| ]; | |
| const xcm = XcmVersionedXcm.V5([ | |
| XcmV5Instruction.WithdrawAsset([ | |
| { | |
| id: DOT, | |
| fun: XcmV3MultiassetFungibility.Fungible(DOT_TO_SWAP + DOT_FOR_FEES), | |
| }, | |
| ]), | |
| XcmV5Instruction.PayFees({ | |
| asset: { | |
| id: DOT, | |
| fun: XcmV3MultiassetFungibility.Fungible(DOT_FOR_FEES / 2n), | |
| }, | |
| }), | |
| XcmV5Instruction.InitiateTransfer({ | |
| destination: { | |
| parents: 1, | |
| interior: XcmV5Junctions.X1(XcmV5Junction.Parachain(HYDRATION_ID)), | |
| }, | |
| remote_fees: Enum('ReserveDeposit', XcmV5AssetFilter.Definite([ | |
| { | |
| id: DOT, | |
| fun: XcmV3MultiassetFungibility.Fungible(DOT_FOR_FEES / 2n), | |
| }, | |
| ])), | |
| preserve_origin: false, | |
| remote_xcm: remoteXcm, | |
| assets: [ | |
| Enum('ReserveDeposit', XcmV5AssetFilter.Wild(XcmV5WildAsset.AllCounted(1))) | |
| ], | |
| }), | |
| ]); | |
| const weight = await ahpApi.apis.XcmPaymentApi.query_xcm_weight(xcm); | |
| if (weight.success) { | |
| const tx = ahpApi.tx.PolkadotXcm.execute({ | |
| message: xcm, | |
| max_weight: weight.value | |
| }); | |
| await tx.signAndSubmit(polkadotSigner); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment