From 2e8caa7da84e5408c80b7cfea5dfcb265fe6f359 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 10 Mar 2026 12:20:00 +0100 Subject: [PATCH 01/16] using node 23 --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 8fdd954df..409940768 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22 \ No newline at end of file +23 From a0029d043f4f5d348f8d5bbe197c41b321671d1f Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 10 Mar 2026 22:19:16 +0100 Subject: [PATCH 02/16] insta bridge EURC Base -> Hydration support --- .../xc-cfg/src/builders/ContractBuilder.ts | 2 + .../src/builders/contracts/InstaBridge.ts | 71 +++++++++++++++++++ packages/xc-cfg/src/chains/evm/base.ts | 3 + packages/xc-cfg/src/configs/evm/base/index.ts | 11 ++- .../xc-cfg/src/configs/evm/base/templates.ts | 37 ++++++++-- packages/xc-cfg/src/tags.ts | 1 + packages/xc-core/src/chain/EvmChain.ts | 12 ++++ packages/xc-core/src/evm/abi/InstaBridge.ts | 32 +++++++++ packages/xc-core/src/evm/abi/index.ts | 2 + 9 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 packages/xc-cfg/src/builders/contracts/InstaBridge.ts create mode 100644 packages/xc-core/src/evm/abi/InstaBridge.ts diff --git a/packages/xc-cfg/src/builders/ContractBuilder.ts b/packages/xc-cfg/src/builders/ContractBuilder.ts index c6324c9bd..7e6b80c12 100644 --- a/packages/xc-cfg/src/builders/ContractBuilder.ts +++ b/packages/xc-cfg/src/builders/ContractBuilder.ts @@ -1,5 +1,6 @@ import { Batch } from './contracts/Batch'; import { Erc20 } from './contracts/Erc20'; +import { InstaBridge } from './contracts/InstaBridge'; import { PolkadotXcm } from './contracts/PolkadotXcm'; import { Snowbridge } from './contracts/Snowbridge'; import { Wormhole } from './contracts/Wormhole'; @@ -8,6 +9,7 @@ export function ContractBuilder() { return { Batch, Erc20, + InstaBridge, PolkadotXcm, Snowbridge, Wormhole, diff --git a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts new file mode 100644 index 000000000..1227de41b --- /dev/null +++ b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts @@ -0,0 +1,71 @@ +import { + addr, + Abi, + Asset, + ContractConfig, + ContractConfigBuilder, + EvmChain, + EvmParachain, + Wormhole as Wh, +} from '@galacticcouncil/xc-core'; + +import { parseAssetId } from '../utils'; + +const { Ss58Addr } = addr; + +/** + * Encode Hydration asset ID to EVM precompile address. + * Follows HydraErc20Mapping encoding from Hydration runtime. + */ +function toHydrationPrecompile(assetId: number): `0x${string}` { + const bytes = new Uint8Array(20); + bytes[15] = 1; + bytes[16] = (assetId >> 24) & 0xff; + bytes[17] = (assetId >> 16) & 0xff; + bytes[18] = (assetId >> 8) & 0xff; + bytes[19] = assetId & 0xff; + return ('0x' + Buffer.from(bytes).toString('hex')) as `0x${string}`; +} + +type BridgeViaWormholeOpts = { + destChain: EvmParachain; + destAsset: Asset; +}; + +const bridgeViaWormhole = (opts: BridgeViaWormholeOpts): ContractConfigBuilder => ({ + build: async (params) => { + const { address, amount, asset, source, destination } = params; + const ctx = source.chain as EvmChain; + const rcv = destination.chain as EvmParachain; + + const rcvWh = Wh.fromChain(opts.destChain); + + const assetId = ctx.getAssetId(asset); + const destAssetId = rcv.getAssetId(opts.destAsset); + + const instaBridgeAddress = ctx.getInstaBridge(); + if (!instaBridgeAddress) { + throw new Error(`InstaBridge not configured for ${ctx.name}`); + } + + return new ContractConfig({ + abi: Abi.InstaBridge, + address: instaBridgeAddress, + args: [ + parseAssetId(assetId), + amount, + rcvWh.getWormholeId(), + toHydrationPrecompile(destAssetId as number), + Ss58Addr.getPubKey(address) as `0x${string}`, + ], + func: 'bridgeViaWormhole', + module: 'InstaBridge', + }); + }, +}); + +export const InstaBridge = () => { + return { + bridgeViaWormhole, + }; +}; diff --git a/packages/xc-cfg/src/chains/evm/base.ts b/packages/xc-cfg/src/chains/evm/base.ts index 2ae4547a7..15a5e713b 100644 --- a/packages/xc-cfg/src/chains/evm/base.ts +++ b/packages/xc-cfg/src/chains/evm/base.ts @@ -30,6 +30,9 @@ export const base = new EvmChain({ ecosystem: Ecosystem.Ethereum, evmChain: evmChain, explorer: 'https://basescan.org/', + instaBridge: { + address: '0x0000000000000000000000000000000000000000', // TBD + }, rpcs: ['https://stylish-quick-firefly.base-mainnet.quiknode.pro/'], wormhole: { id: 30, diff --git a/packages/xc-cfg/src/configs/evm/base/index.ts b/packages/xc-cfg/src/configs/evm/base/index.ts index d077665eb..39646f010 100644 --- a/packages/xc-cfg/src/configs/evm/base/index.ts +++ b/packages/xc-cfg/src/configs/evm/base/index.ts @@ -2,13 +2,20 @@ import { AssetRoute, ChainRoutes } from '@galacticcouncil/xc-core'; import { eurc, eurc_mwh } from '../../../assets'; import { base } from '../../../chains'; -import { toHydrationViaWormholeTemplate } from './templates'; +import { + toHydrationViaInstaBridgeTemplate, + toHydrationViaWormholeTemplate, +} from './templates'; const toHydrationViaWormhole: AssetRoute[] = [ toHydrationViaWormholeTemplate(eurc, eurc_mwh), ]; +const toHydrationViaInstaBridge: AssetRoute[] = [ + toHydrationViaInstaBridgeTemplate(eurc, eurc_mwh), +]; + export const baseConfig = new ChainRoutes({ chain: base, - routes: [...toHydrationViaWormhole], + routes: [...toHydrationViaWormhole, ...toHydrationViaInstaBridge], }); diff --git a/packages/xc-cfg/src/configs/evm/base/templates.ts b/packages/xc-cfg/src/configs/evm/base/templates.ts index dff24db88..4f2f81ba6 100644 --- a/packages/xc-cfg/src/configs/evm/base/templates.ts +++ b/packages/xc-cfg/src/configs/evm/base/templates.ts @@ -1,10 +1,7 @@ import { Asset, AssetRoute } from '@galacticcouncil/xc-core'; import { eth } from '../../../assets'; -import { - BalanceBuilder, - ContractBuilder, -} from '../../../builders'; +import { BalanceBuilder, ContractBuilder } from '../../../builders'; import { hydration, moonbeam } from '../../../chains'; import { Tag } from '../../../tags'; @@ -41,3 +38,35 @@ export function toHydrationViaWormholeTemplate( tags: [Tag.Mrl, Tag.Wormhole], }); } + +export function toHydrationViaInstaBridgeTemplate( + assetIn: Asset, + assetOut: Asset +): AssetRoute { + return new AssetRoute({ + source: { + asset: assetIn, + balance: BalanceBuilder().evm().erc20(), + fee: { + asset: eth, + balance: BalanceBuilder().evm().native(), + }, + destinationFee: { + asset: assetIn, + balance: BalanceBuilder().evm().erc20(), + }, + }, + destination: { + chain: hydration, + asset: assetOut, + fee: { + amount: 0, + asset: assetOut, + }, + }, + contract: ContractBuilder() + .InstaBridge() + .bridgeViaWormhole({ destChain: moonbeam, destAsset: assetOut }), + tags: [Tag.InstaBridge], + }); +} diff --git a/packages/xc-cfg/src/tags.ts b/packages/xc-cfg/src/tags.ts index f93bf07ec..a6b8ec793 100644 --- a/packages/xc-cfg/src/tags.ts +++ b/packages/xc-cfg/src/tags.ts @@ -1,4 +1,5 @@ export enum Tag { + InstaBridge = 'InstaBridge', Wormhole = 'Wormhole', Relayer = 'Relayer', Snowbridge = 'Snowbridge', diff --git a/packages/xc-core/src/chain/EvmChain.ts b/packages/xc-core/src/chain/EvmChain.ts index 1c1509130..6c779fdba 100644 --- a/packages/xc-core/src/chain/EvmChain.ts +++ b/packages/xc-core/src/chain/EvmChain.ts @@ -11,10 +11,15 @@ import { import { Snowbridge, SnowbridgeDef, Wormhole, WormholeDef } from '../bridge'; import { EvmClient } from '../evm'; +export type InstaBridgeDef = { + address: string; +}; + export interface EvmChainParams extends ChainParams { evmChain: EvmChainDef; id: number; rpcs?: string[]; + instaBridge?: InstaBridgeDef; snowbridge?: SnowbridgeDef; wormhole?: WormholeDef; } @@ -23,6 +28,7 @@ export class EvmChain extends Chain { readonly evmChain: EvmChainDef; readonly id: number; readonly rpcs?: string[]; + readonly instaBridge?: InstaBridgeDef; readonly snowbridge?: Snowbridge; readonly wormhole?: Wormhole; @@ -30,6 +36,7 @@ export class EvmChain extends Chain { evmChain, id, rpcs, + instaBridge, snowbridge, wormhole, ...others @@ -38,10 +45,15 @@ export class EvmChain extends Chain { this.evmChain = evmChain; this.id = id; this.rpcs = rpcs; + this.instaBridge = instaBridge; this.snowbridge = snowbridge && new Snowbridge(snowbridge); this.wormhole = wormhole && new Wormhole(wormhole); } + getInstaBridge(): string | undefined { + return this.instaBridge?.address; + } + get evmClient(): EvmClient { return new EvmClient(this.evmChain, this.rpcs); } diff --git a/packages/xc-core/src/evm/abi/InstaBridge.ts b/packages/xc-core/src/evm/abi/InstaBridge.ts new file mode 100644 index 000000000..fe763a32a --- /dev/null +++ b/packages/xc-core/src/evm/abi/InstaBridge.ts @@ -0,0 +1,32 @@ +export const INSTA_BRIDGE = [ + { + inputs: [ + { internalType: 'address', name: 'asset', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { internalType: 'uint16', name: 'destChain', type: 'uint16' }, + { internalType: 'address', name: 'destAsset', type: 'address' }, + { internalType: 'bytes32', name: 'recipient', type: 'bytes32' }, + ], + name: 'bridgeViaWormhole', + outputs: [ + { internalType: 'uint64', name: 'transferSequence', type: 'uint64' }, + { internalType: 'uint64', name: 'messageSequence', type: 'uint64' }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'vaa', type: 'bytes' }], + name: 'completeTransfer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'quoteFee', + outputs: [{ internalType: 'uint256', name: 'fee', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/packages/xc-core/src/evm/abi/index.ts b/packages/xc-core/src/evm/abi/index.ts index ea9d97f8d..0b8d2995e 100644 --- a/packages/xc-core/src/evm/abi/index.ts +++ b/packages/xc-core/src/evm/abi/index.ts @@ -3,6 +3,7 @@ import type { Abi as TAbi } from 'viem'; import { BATCH } from './Batch'; import { ERC20 } from './Erc20'; import { GMP } from './Gmp'; +import { INSTA_BRIDGE } from './InstaBridge'; import { META } from './Meta'; import { POLKADOT_XCM } from './PolkadotXcm'; import { SNOWBRIDGE } from './Snowbridge'; @@ -13,6 +14,7 @@ export const Abi: Record = { Batch: BATCH, Erc20: ERC20, Gmp: GMP, + InstaBridge: INSTA_BRIDGE, Meta: META, PolkadotXcm: POLKADOT_XCM, Snowbridge: SNOWBRIDGE, From 9d5f9bbed239a202f74b64bd28e30e137b438a59 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 10 Mar 2026 22:23:41 +0100 Subject: [PATCH 03/16] changeset --- .changeset/add-instabridge-support.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .changeset/add-instabridge-support.md diff --git a/.changeset/add-instabridge-support.md b/.changeset/add-instabridge-support.md new file mode 100644 index 000000000..48d67fd53 --- /dev/null +++ b/.changeset/add-instabridge-support.md @@ -0,0 +1,11 @@ +--- +"@galacticcouncil/xc-core": minor +"@galacticcouncil/xc-cfg": minor +--- + +Add InstaBridge support for EURC transfers from Base to Hydration + +- Added InstaBridge ABI and contract builder +- Added InstaBridgeDef type and getInstaBridge() method to EvmChain +- Added toHydrationPrecompile() helper for converting Hydration asset IDs to EVM precompile addresses +- Added InstaBridge route template for Base -> Hydration EURC transfers From 91d662efed8c0043a7a77ff3f5db1120042fc762 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 10 Mar 2026 22:43:40 +0100 Subject: [PATCH 04/16] Revert "using node 23" This reverts commit 2e8caa7da84e5408c80b7cfea5dfcb265fe6f359. --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 409940768..8fdd954df 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -23 +22 \ No newline at end of file From 3389e4e4e2927202abdfa78cfc55abd7664d2320 Mon Sep 17 00:00:00 2001 From: Pavol Noha Date: Tue, 10 Mar 2026 22:58:07 +0100 Subject: [PATCH 05/16] disable cache --- .github/workflows/snapshot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index c10cb0f7c..2a1b52c36 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -19,7 +19,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: '22.21.1' - cache: 'npm' - name: 🔐 Authenticate with NPM run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc From 40cc4afd4ea5af5f241bb097f4aed3940ebdc38a Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 10 Mar 2026 23:14:09 +0100 Subject: [PATCH 06/16] just patch --- .changeset/add-instabridge-support.md | 11 ----------- .changeset/olive-worms-cut.md | 6 ++++++ 2 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 .changeset/add-instabridge-support.md create mode 100644 .changeset/olive-worms-cut.md diff --git a/.changeset/add-instabridge-support.md b/.changeset/add-instabridge-support.md deleted file mode 100644 index 48d67fd53..000000000 --- a/.changeset/add-instabridge-support.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@galacticcouncil/xc-core": minor -"@galacticcouncil/xc-cfg": minor ---- - -Add InstaBridge support for EURC transfers from Base to Hydration - -- Added InstaBridge ABI and contract builder -- Added InstaBridgeDef type and getInstaBridge() method to EvmChain -- Added toHydrationPrecompile() helper for converting Hydration asset IDs to EVM precompile addresses -- Added InstaBridge route template for Base -> Hydration EURC transfers diff --git a/.changeset/olive-worms-cut.md b/.changeset/olive-worms-cut.md new file mode 100644 index 000000000..1b5c626af --- /dev/null +++ b/.changeset/olive-worms-cut.md @@ -0,0 +1,6 @@ +--- +'@galacticcouncil/xc-core': patch +'@galacticcouncil/xc-cfg': patch +--- + +instabridge base eurc From 40a8235a3b7f2dc9b9a8a8b10f352d38f9f614dd Mon Sep 17 00:00:00 2001 From: Pavol Noha Date: Tue, 10 Mar 2026 23:16:04 +0100 Subject: [PATCH 07/16] try re-resolve --- .github/workflows/snapshot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 2a1b52c36..756d0f33d 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -32,6 +32,9 @@ jobs: PR: ${{ github.event.pull_request.number }} COMMIT_SHA: ${{ github.event.pull_request.head.sha }} + - name: 🧩 Re-resolve workspace links + run: npm install --ignore-scripts + - name: 🛠️ Build SDK run: npm run build From 58656271092b11506fc2b3b6bef629a25e1b3461 Mon Sep 17 00:00:00 2001 From: Pavol Noha Date: Tue, 10 Mar 2026 23:21:33 +0100 Subject: [PATCH 08/16] xc-sdk bump --- .changeset/olive-worms-cut.md | 5 +++-- .github/workflows/snapshot.yml | 3 --- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.changeset/olive-worms-cut.md b/.changeset/olive-worms-cut.md index 1b5c626af..d30cbcbc8 100644 --- a/.changeset/olive-worms-cut.md +++ b/.changeset/olive-worms-cut.md @@ -1,6 +1,7 @@ --- -'@galacticcouncil/xc-core': patch -'@galacticcouncil/xc-cfg': patch +'@galacticcouncil/xc-core': minor +'@galacticcouncil/xc-cfg': minor +'@galacticcouncil/xc-sdk': patch --- instabridge base eurc diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 756d0f33d..2a1b52c36 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -32,9 +32,6 @@ jobs: PR: ${{ github.event.pull_request.number }} COMMIT_SHA: ${{ github.event.pull_request.head.sha }} - - name: 🧩 Re-resolve workspace links - run: npm install --ignore-scripts - - name: 🛠️ Build SDK run: npm run build From 9b91595e83ef89730e7d1e845b3f01925dffdc5e Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 11 Mar 2026 15:10:07 +0100 Subject: [PATCH 09/16] deployed instabridge on base --- packages/xc-cfg/src/chains/evm/base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xc-cfg/src/chains/evm/base.ts b/packages/xc-cfg/src/chains/evm/base.ts index 15a5e713b..ed81b30a3 100644 --- a/packages/xc-cfg/src/chains/evm/base.ts +++ b/packages/xc-cfg/src/chains/evm/base.ts @@ -31,7 +31,7 @@ export const base = new EvmChain({ evmChain: evmChain, explorer: 'https://basescan.org/', instaBridge: { - address: '0x0000000000000000000000000000000000000000', // TBD + address: '0x73bab4cec782e1530117932cef8492ebe64e112e', }, rpcs: ['https://stylish-quick-firefly.base-mainnet.quiknode.pro/'], wormhole: { From c9b7cd343890e01c3aef8410ba0a51dd98ecaa2f Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 11 Mar 2026 16:11:36 +0100 Subject: [PATCH 10/16] always using h160 --- packages/xc-cfg/src/builders/contracts/InstaBridge.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts index 1227de41b..bc0092d74 100644 --- a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts +++ b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts @@ -1,5 +1,4 @@ import { - addr, Abi, Asset, ContractConfig, @@ -10,8 +9,9 @@ import { } from '@galacticcouncil/xc-core'; import { parseAssetId } from '../utils'; +import { h160 } from '@galacticcouncil/common'; -const { Ss58Addr } = addr; +const { H160 } = h160; /** * Encode Hydration asset ID to EVM precompile address. @@ -56,7 +56,7 @@ const bridgeViaWormhole = (opts: BridgeViaWormholeOpts): ContractConfigBuilder = amount, rcvWh.getWormholeId(), toHydrationPrecompile(destAssetId as number), - Ss58Addr.getPubKey(address) as `0x${string}`, + H160.fromAccount(address), ], func: 'bridgeViaWormhole', module: 'InstaBridge', From e720946234a5af629a31368a3788387764c012b8 Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 11 Mar 2026 16:31:26 +0100 Subject: [PATCH 11/16] prefix address --- packages/xc-cfg/src/builders/contracts/InstaBridge.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts index bc0092d74..0252d494b 100644 --- a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts +++ b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts @@ -27,6 +27,14 @@ function toHydrationPrecompile(assetId: number): `0x${string}` { return ('0x' + Buffer.from(bytes).toString('hex')) as `0x${string}`; } +/** + * Pad H160 address to bytes32 (left-pad with zeros). + */ +function toBytes32(h160: `0x${string}`): `0x${string}` { + const addr = h160.replace('0x', '').toLowerCase(); + return `0x${'0'.repeat(24)}${addr}` as `0x${string}`; +} + type BridgeViaWormholeOpts = { destChain: EvmParachain; destAsset: Asset; @@ -56,7 +64,7 @@ const bridgeViaWormhole = (opts: BridgeViaWormholeOpts): ContractConfigBuilder = amount, rcvWh.getWormholeId(), toHydrationPrecompile(destAssetId as number), - H160.fromAccount(address), + toBytes32(H160.fromAccount(address) as `0x${string}`), ], func: 'bridgeViaWormhole', module: 'InstaBridge', From 8f53fb05dddf8c1f9052e74dfb181eaa0633c733 Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 31 Mar 2026 03:28:29 +0200 Subject: [PATCH 12/16] applied new deployment --- .../src/builders/contracts/InstaBridge.ts | 32 ++----------------- packages/xc-cfg/src/chains/evm/base.ts | 2 +- .../xc-cfg/src/configs/evm/base/templates.ts | 2 +- packages/xc-core/src/evm/abi/InstaBridge.ts | 2 -- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts index 0252d494b..56ba90b2d 100644 --- a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts +++ b/packages/xc-cfg/src/builders/contracts/InstaBridge.ts @@ -1,11 +1,8 @@ import { Abi, - Asset, ContractConfig, ContractConfigBuilder, EvmChain, - EvmParachain, - Wormhole as Wh, } from '@galacticcouncil/xc-core'; import { parseAssetId } from '../utils'; @@ -13,20 +10,6 @@ import { h160 } from '@galacticcouncil/common'; const { H160 } = h160; -/** - * Encode Hydration asset ID to EVM precompile address. - * Follows HydraErc20Mapping encoding from Hydration runtime. - */ -function toHydrationPrecompile(assetId: number): `0x${string}` { - const bytes = new Uint8Array(20); - bytes[15] = 1; - bytes[16] = (assetId >> 24) & 0xff; - bytes[17] = (assetId >> 16) & 0xff; - bytes[18] = (assetId >> 8) & 0xff; - bytes[19] = assetId & 0xff; - return ('0x' + Buffer.from(bytes).toString('hex')) as `0x${string}`; -} - /** * Pad H160 address to bytes32 (left-pad with zeros). */ @@ -35,21 +18,12 @@ function toBytes32(h160: `0x${string}`): `0x${string}` { return `0x${'0'.repeat(24)}${addr}` as `0x${string}`; } -type BridgeViaWormholeOpts = { - destChain: EvmParachain; - destAsset: Asset; -}; - -const bridgeViaWormhole = (opts: BridgeViaWormholeOpts): ContractConfigBuilder => ({ +const bridgeViaWormhole = (): ContractConfigBuilder => ({ build: async (params) => { - const { address, amount, asset, source, destination } = params; + const { address, amount, asset, source } = params; const ctx = source.chain as EvmChain; - const rcv = destination.chain as EvmParachain; - - const rcvWh = Wh.fromChain(opts.destChain); const assetId = ctx.getAssetId(asset); - const destAssetId = rcv.getAssetId(opts.destAsset); const instaBridgeAddress = ctx.getInstaBridge(); if (!instaBridgeAddress) { @@ -62,8 +36,6 @@ const bridgeViaWormhole = (opts: BridgeViaWormholeOpts): ContractConfigBuilder = args: [ parseAssetId(assetId), amount, - rcvWh.getWormholeId(), - toHydrationPrecompile(destAssetId as number), toBytes32(H160.fromAccount(address) as `0x${string}`), ], func: 'bridgeViaWormhole', diff --git a/packages/xc-cfg/src/chains/evm/base.ts b/packages/xc-cfg/src/chains/evm/base.ts index ed81b30a3..3d8f6b410 100644 --- a/packages/xc-cfg/src/chains/evm/base.ts +++ b/packages/xc-cfg/src/chains/evm/base.ts @@ -31,7 +31,7 @@ export const base = new EvmChain({ evmChain: evmChain, explorer: 'https://basescan.org/', instaBridge: { - address: '0x73bab4cec782e1530117932cef8492ebe64e112e', + address: '0xf5b9334e44f800382cb47fc19669401d694e529b', }, rpcs: ['https://stylish-quick-firefly.base-mainnet.quiknode.pro/'], wormhole: { diff --git a/packages/xc-cfg/src/configs/evm/base/templates.ts b/packages/xc-cfg/src/configs/evm/base/templates.ts index 4f2f81ba6..e0c7806a2 100644 --- a/packages/xc-cfg/src/configs/evm/base/templates.ts +++ b/packages/xc-cfg/src/configs/evm/base/templates.ts @@ -66,7 +66,7 @@ export function toHydrationViaInstaBridgeTemplate( }, contract: ContractBuilder() .InstaBridge() - .bridgeViaWormhole({ destChain: moonbeam, destAsset: assetOut }), + .bridgeViaWormhole(), tags: [Tag.InstaBridge], }); } diff --git a/packages/xc-core/src/evm/abi/InstaBridge.ts b/packages/xc-core/src/evm/abi/InstaBridge.ts index fe763a32a..fa9680bd6 100644 --- a/packages/xc-core/src/evm/abi/InstaBridge.ts +++ b/packages/xc-core/src/evm/abi/InstaBridge.ts @@ -3,8 +3,6 @@ export const INSTA_BRIDGE = [ inputs: [ { internalType: 'address', name: 'asset', type: 'address' }, { internalType: 'uint256', name: 'amount', type: 'uint256' }, - { internalType: 'uint16', name: 'destChain', type: 'uint16' }, - { internalType: 'address', name: 'destAsset', type: 'address' }, { internalType: 'bytes32', name: 'recipient', type: 'bytes32' }, ], name: 'bridgeViaWormhole', From 70257796263ab9e76009d8cbbb2e637cecb6ff2b Mon Sep 17 00:00:00 2001 From: mrq Date: Tue, 31 Mar 2026 03:35:16 +0200 Subject: [PATCH 13/16] basejump --- .changeset/olive-worms-cut.md | 2 +- packages/xc-cfg/src/builders/ContractBuilder.ts | 4 ++-- .../contracts/{InstaBridge.ts => Basejump.ts} | 14 +++++++------- packages/xc-cfg/src/chains/evm/base.ts | 2 +- packages/xc-cfg/src/configs/evm/base/index.ts | 8 ++++---- packages/xc-cfg/src/configs/evm/base/templates.ts | 6 +++--- packages/xc-cfg/src/tags.ts | 2 +- packages/xc-core/src/chain/EvmChain.ts | 14 +++++++------- .../src/evm/abi/{InstaBridge.ts => Basejump.ts} | 2 +- packages/xc-core/src/evm/abi/index.ts | 4 ++-- 10 files changed, 29 insertions(+), 29 deletions(-) rename packages/xc-cfg/src/builders/contracts/{InstaBridge.ts => Basejump.ts} (77%) rename packages/xc-core/src/evm/abi/{InstaBridge.ts => Basejump.ts} (96%) diff --git a/.changeset/olive-worms-cut.md b/.changeset/olive-worms-cut.md index d30cbcbc8..c36e03297 100644 --- a/.changeset/olive-worms-cut.md +++ b/.changeset/olive-worms-cut.md @@ -4,4 +4,4 @@ '@galacticcouncil/xc-sdk': patch --- -instabridge base eurc +basejump base eurc diff --git a/packages/xc-cfg/src/builders/ContractBuilder.ts b/packages/xc-cfg/src/builders/ContractBuilder.ts index 7e6b80c12..200b9b340 100644 --- a/packages/xc-cfg/src/builders/ContractBuilder.ts +++ b/packages/xc-cfg/src/builders/ContractBuilder.ts @@ -1,6 +1,6 @@ import { Batch } from './contracts/Batch'; import { Erc20 } from './contracts/Erc20'; -import { InstaBridge } from './contracts/InstaBridge'; +import { Basejump } from './contracts/Basejump'; import { PolkadotXcm } from './contracts/PolkadotXcm'; import { Snowbridge } from './contracts/Snowbridge'; import { Wormhole } from './contracts/Wormhole'; @@ -9,7 +9,7 @@ export function ContractBuilder() { return { Batch, Erc20, - InstaBridge, + Basejump, PolkadotXcm, Snowbridge, Wormhole, diff --git a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts b/packages/xc-cfg/src/builders/contracts/Basejump.ts similarity index 77% rename from packages/xc-cfg/src/builders/contracts/InstaBridge.ts rename to packages/xc-cfg/src/builders/contracts/Basejump.ts index 56ba90b2d..7daba20c4 100644 --- a/packages/xc-cfg/src/builders/contracts/InstaBridge.ts +++ b/packages/xc-cfg/src/builders/contracts/Basejump.ts @@ -25,26 +25,26 @@ const bridgeViaWormhole = (): ContractConfigBuilder => ({ const assetId = ctx.getAssetId(asset); - const instaBridgeAddress = ctx.getInstaBridge(); - if (!instaBridgeAddress) { - throw new Error(`InstaBridge not configured for ${ctx.name}`); + const basejumpAddress = ctx.getBasejump(); + if (!basejumpAddress) { + throw new Error(`Basejump not configured for ${ctx.name}`); } return new ContractConfig({ - abi: Abi.InstaBridge, - address: instaBridgeAddress, + abi: Abi.Basejump, + address: basejumpAddress, args: [ parseAssetId(assetId), amount, toBytes32(H160.fromAccount(address) as `0x${string}`), ], func: 'bridgeViaWormhole', - module: 'InstaBridge', + module: 'Basejump', }); }, }); -export const InstaBridge = () => { +export const Basejump = () => { return { bridgeViaWormhole, }; diff --git a/packages/xc-cfg/src/chains/evm/base.ts b/packages/xc-cfg/src/chains/evm/base.ts index 3d8f6b410..0e8dae890 100644 --- a/packages/xc-cfg/src/chains/evm/base.ts +++ b/packages/xc-cfg/src/chains/evm/base.ts @@ -30,7 +30,7 @@ export const base = new EvmChain({ ecosystem: Ecosystem.Ethereum, evmChain: evmChain, explorer: 'https://basescan.org/', - instaBridge: { + basejump: { address: '0xf5b9334e44f800382cb47fc19669401d694e529b', }, rpcs: ['https://stylish-quick-firefly.base-mainnet.quiknode.pro/'], diff --git a/packages/xc-cfg/src/configs/evm/base/index.ts b/packages/xc-cfg/src/configs/evm/base/index.ts index 39646f010..30e5ac2a2 100644 --- a/packages/xc-cfg/src/configs/evm/base/index.ts +++ b/packages/xc-cfg/src/configs/evm/base/index.ts @@ -3,7 +3,7 @@ import { AssetRoute, ChainRoutes } from '@galacticcouncil/xc-core'; import { eurc, eurc_mwh } from '../../../assets'; import { base } from '../../../chains'; import { - toHydrationViaInstaBridgeTemplate, + toHydrationViaBasejumpTemplate, toHydrationViaWormholeTemplate, } from './templates'; @@ -11,11 +11,11 @@ const toHydrationViaWormhole: AssetRoute[] = [ toHydrationViaWormholeTemplate(eurc, eurc_mwh), ]; -const toHydrationViaInstaBridge: AssetRoute[] = [ - toHydrationViaInstaBridgeTemplate(eurc, eurc_mwh), +const toHydrationViaBasejump: AssetRoute[] = [ + toHydrationViaBasejumpTemplate(eurc, eurc_mwh), ]; export const baseConfig = new ChainRoutes({ chain: base, - routes: [...toHydrationViaWormhole, ...toHydrationViaInstaBridge], + routes: [...toHydrationViaWormhole, ...toHydrationViaBasejump], }); diff --git a/packages/xc-cfg/src/configs/evm/base/templates.ts b/packages/xc-cfg/src/configs/evm/base/templates.ts index e0c7806a2..ada21948f 100644 --- a/packages/xc-cfg/src/configs/evm/base/templates.ts +++ b/packages/xc-cfg/src/configs/evm/base/templates.ts @@ -39,7 +39,7 @@ export function toHydrationViaWormholeTemplate( }); } -export function toHydrationViaInstaBridgeTemplate( +export function toHydrationViaBasejumpTemplate( assetIn: Asset, assetOut: Asset ): AssetRoute { @@ -65,8 +65,8 @@ export function toHydrationViaInstaBridgeTemplate( }, }, contract: ContractBuilder() - .InstaBridge() + .Basejump() .bridgeViaWormhole(), - tags: [Tag.InstaBridge], + tags: [Tag.Basejump], }); } diff --git a/packages/xc-cfg/src/tags.ts b/packages/xc-cfg/src/tags.ts index a6b8ec793..eca039590 100644 --- a/packages/xc-cfg/src/tags.ts +++ b/packages/xc-cfg/src/tags.ts @@ -1,5 +1,5 @@ export enum Tag { - InstaBridge = 'InstaBridge', + Basejump = 'Basejump', Wormhole = 'Wormhole', Relayer = 'Relayer', Snowbridge = 'Snowbridge', diff --git a/packages/xc-core/src/chain/EvmChain.ts b/packages/xc-core/src/chain/EvmChain.ts index 6c779fdba..ec592317a 100644 --- a/packages/xc-core/src/chain/EvmChain.ts +++ b/packages/xc-core/src/chain/EvmChain.ts @@ -11,7 +11,7 @@ import { import { Snowbridge, SnowbridgeDef, Wormhole, WormholeDef } from '../bridge'; import { EvmClient } from '../evm'; -export type InstaBridgeDef = { +export type BasejumpDef = { address: string; }; @@ -19,7 +19,7 @@ export interface EvmChainParams extends ChainParams { evmChain: EvmChainDef; id: number; rpcs?: string[]; - instaBridge?: InstaBridgeDef; + basejump?: BasejumpDef; snowbridge?: SnowbridgeDef; wormhole?: WormholeDef; } @@ -28,7 +28,7 @@ export class EvmChain extends Chain { readonly evmChain: EvmChainDef; readonly id: number; readonly rpcs?: string[]; - readonly instaBridge?: InstaBridgeDef; + readonly basejump?: BasejumpDef; readonly snowbridge?: Snowbridge; readonly wormhole?: Wormhole; @@ -36,7 +36,7 @@ export class EvmChain extends Chain { evmChain, id, rpcs, - instaBridge, + basejump, snowbridge, wormhole, ...others @@ -45,13 +45,13 @@ export class EvmChain extends Chain { this.evmChain = evmChain; this.id = id; this.rpcs = rpcs; - this.instaBridge = instaBridge; + this.basejump = basejump; this.snowbridge = snowbridge && new Snowbridge(snowbridge); this.wormhole = wormhole && new Wormhole(wormhole); } - getInstaBridge(): string | undefined { - return this.instaBridge?.address; + getBasejump(): string | undefined { + return this.basejump?.address; } get evmClient(): EvmClient { diff --git a/packages/xc-core/src/evm/abi/InstaBridge.ts b/packages/xc-core/src/evm/abi/Basejump.ts similarity index 96% rename from packages/xc-core/src/evm/abi/InstaBridge.ts rename to packages/xc-core/src/evm/abi/Basejump.ts index fa9680bd6..6563c7a15 100644 --- a/packages/xc-core/src/evm/abi/InstaBridge.ts +++ b/packages/xc-core/src/evm/abi/Basejump.ts @@ -1,4 +1,4 @@ -export const INSTA_BRIDGE = [ +export const BASEJUMP = [ { inputs: [ { internalType: 'address', name: 'asset', type: 'address' }, diff --git a/packages/xc-core/src/evm/abi/index.ts b/packages/xc-core/src/evm/abi/index.ts index 0b8d2995e..2d6ab456c 100644 --- a/packages/xc-core/src/evm/abi/index.ts +++ b/packages/xc-core/src/evm/abi/index.ts @@ -3,7 +3,7 @@ import type { Abi as TAbi } from 'viem'; import { BATCH } from './Batch'; import { ERC20 } from './Erc20'; import { GMP } from './Gmp'; -import { INSTA_BRIDGE } from './InstaBridge'; +import { BASEJUMP } from './Basejump'; import { META } from './Meta'; import { POLKADOT_XCM } from './PolkadotXcm'; import { SNOWBRIDGE } from './Snowbridge'; @@ -14,7 +14,7 @@ export const Abi: Record = { Batch: BATCH, Erc20: ERC20, Gmp: GMP, - InstaBridge: INSTA_BRIDGE, + Basejump: BASEJUMP, Meta: META, PolkadotXcm: POLKADOT_XCM, Snowbridge: SNOWBRIDGE, From b15353b233afb3546034a6d2e10ef7bd1fc999f9 Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 1 Apr 2026 04:51:12 +0200 Subject: [PATCH 14/16] fees support --- .../xc-cfg/src/builders/FeeAmountBuilder.ts | 24 +++++++++++++++++++ .../xc-cfg/src/configs/evm/base/templates.ts | 6 ++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/xc-cfg/src/builders/FeeAmountBuilder.ts b/packages/xc-cfg/src/builders/FeeAmountBuilder.ts index 2c4e7e184..4ae3699dc 100644 --- a/packages/xc-cfg/src/builders/FeeAmountBuilder.ts +++ b/packages/xc-cfg/src/builders/FeeAmountBuilder.ts @@ -203,8 +203,32 @@ function XcmPaymentApi() { }; } +function Basejump() { + return { + quoteFee: (): FeeAmountConfigBuilder => ({ + build: async ({ feeAsset, source }) => { + const ctx = source as EvmChain; + const basejumpAddress = ctx.getBasejump(); + if (!basejumpAddress) { + throw new Error(`Basejump not configured for ${ctx.name}`); + } + + const feeAssetId = ctx.getAssetId(feeAsset); + const fee = await ctx.evmClient.getProvider().readContract({ + abi: Abi.Basejump, + address: basejumpAddress as `0x${string}`, + args: [feeAssetId as `0x${string}`], + functionName: 'quoteFee', + }); + return { amount: fee } as FeeAmount; + }, + }), + }; +} + export function FeeAmountBuilder() { return { + Basejump, XcmPaymentApi, Snowbridge, Wormhole, diff --git a/packages/xc-cfg/src/configs/evm/base/templates.ts b/packages/xc-cfg/src/configs/evm/base/templates.ts index ada21948f..d39ba5d48 100644 --- a/packages/xc-cfg/src/configs/evm/base/templates.ts +++ b/packages/xc-cfg/src/configs/evm/base/templates.ts @@ -1,7 +1,7 @@ import { Asset, AssetRoute } from '@galacticcouncil/xc-core'; import { eth } from '../../../assets'; -import { BalanceBuilder, ContractBuilder } from '../../../builders'; +import { BalanceBuilder, ContractBuilder, FeeAmountBuilder } from '../../../builders'; import { hydration, moonbeam } from '../../../chains'; import { Tag } from '../../../tags'; @@ -60,8 +60,8 @@ export function toHydrationViaBasejumpTemplate( chain: hydration, asset: assetOut, fee: { - amount: 0, - asset: assetOut, + amount: FeeAmountBuilder().Basejump().quoteFee(), + asset: assetIn, }, }, contract: ContractBuilder() From 6128c84e036b779063ec49f535c0c3ef40c9894d Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 1 Apr 2026 06:42:07 +0200 Subject: [PATCH 15/16] prefixing evm addresses correctly --- .../src/builders/contracts/Basejump.spec.ts | 72 +++++++++++++++++++ .../xc-cfg/src/builders/contracts/Basejump.ts | 14 ++-- 2 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 packages/xc-cfg/src/builders/contracts/Basejump.spec.ts diff --git a/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts b/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts new file mode 100644 index 000000000..b3cab876d --- /dev/null +++ b/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts @@ -0,0 +1,72 @@ +import { ContractConfigBuilderParams } from '@galacticcouncil/xc-core'; + +import { eurc } from '../../assets'; +import { base, hydration } from '../../chains'; + +import { Basejump } from './Basejump'; + +const buildCtx = (address: string) => { + return { + address, + amount: 1000000n, + asset: eurc, + sender: '0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0', + source: { chain: base }, + destination: { chain: hydration }, + } as ContractConfigBuilderParams; +}; + +describe('Basejump contract builder', () => { + describe('bridgeViaWormhole', () => { + it('should encode EVM H160 address with ETH\\0 prefix', async () => { + const h160 = '0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0'; + const ctx = buildCtx(h160); + const config = await Basejump().bridgeViaWormhole().build(ctx); + + const recipient = config.args[2] as string; + // ETH\0 = 0x45544800, then H160 lowercase, then 16 zero hex chars + expect(recipient.toLowerCase()).toBe( + '0x45544800' + + '71feb8b2849101a6e62e3369eaafdc6154cd0bc0' + + '0000000000000000' + ); + }); + + it('should encode SS58 EVM account with ETH\\0 prefix', async () => { + // This SS58 address is the Hydration mapping of 0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0 + const { h160 } = await import('@galacticcouncil/common'); + const ss58 = h160.H160.toAccount('0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0'); + const ctx = buildCtx(ss58); + const config = await Basejump().bridgeViaWormhole().build(ctx); + + const recipient = config.args[2] as string; + expect(recipient.toLowerCase()).toBe( + '0x45544800' + + '71feb8b2849101a6e62e3369eaafdc6154cd0bc0' + + '0000000000000000' + ); + }); + + it('should encode native SS58 substrate account as raw AccountId32', async () => { + // Alice's well-known AccountId32 + const alice = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; + const ctx = buildCtx(alice); + const config = await Basejump().bridgeViaWormhole().build(ctx); + + const recipient = config.args[2] as string; + // Alice's raw AccountId32 + expect(recipient.toLowerCase()).toBe( + '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' + ); + }); + + it('should produce correct contract config', async () => { + const ctx = buildCtx('0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0'); + const config = await Basejump().bridgeViaWormhole().build(ctx); + + expect(config.func).toBe('bridgeViaWormhole'); + expect(config.module).toBe('Basejump'); + expect(config.args).toHaveLength(3); + }); + }); +}); diff --git a/packages/xc-cfg/src/builders/contracts/Basejump.ts b/packages/xc-cfg/src/builders/contracts/Basejump.ts index 7daba20c4..b2aa8c855 100644 --- a/packages/xc-cfg/src/builders/contracts/Basejump.ts +++ b/packages/xc-cfg/src/builders/contracts/Basejump.ts @@ -7,15 +7,17 @@ import { import { parseAssetId } from '../utils'; import { h160 } from '@galacticcouncil/common'; +import { AccountId } from 'polkadot-api'; +import { toHex } from '@polkadot-api/utils'; -const { H160 } = h160; +const { H160, isEvmAddress } = h160; /** - * Pad H160 address to bytes32 (left-pad with zeros). + * Convert any address (H160 or SS58) to bytes32 AccountId. */ -function toBytes32(h160: `0x${string}`): `0x${string}` { - const addr = h160.replace('0x', '').toLowerCase(); - return `0x${'0'.repeat(24)}${addr}` as `0x${string}`; +function toAccountId32(address: string): `0x${string}` { + const ss58 = isEvmAddress(address) ? H160.toAccount(address) : address; + return toHex(AccountId().enc(ss58)) as `0x${string}`; } const bridgeViaWormhole = (): ContractConfigBuilder => ({ @@ -36,7 +38,7 @@ const bridgeViaWormhole = (): ContractConfigBuilder => ({ args: [ parseAssetId(assetId), amount, - toBytes32(H160.fromAccount(address) as `0x${string}`), + toAccountId32(address), ], func: 'bridgeViaWormhole', module: 'Basejump', From f6c6ae35fab3bb8448eca791e9c1f35107e0aca7 Mon Sep 17 00:00:00 2001 From: mrq Date: Wed, 1 Apr 2026 07:01:24 +0200 Subject: [PATCH 16/16] fixed abi --- .../src/builders/contracts/Basejump.spec.ts | 42 ++++++++++++++++++- packages/xc-core/src/evm/abi/Basejump.ts | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts b/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts index b3cab876d..93c73dbee 100644 --- a/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts +++ b/packages/xc-cfg/src/builders/contracts/Basejump.spec.ts @@ -1,4 +1,4 @@ -import { ContractConfigBuilderParams } from '@galacticcouncil/xc-core'; +import { Abi, ContractConfigBuilderParams } from '@galacticcouncil/xc-core'; import { eurc } from '../../assets'; import { base, hydration } from '../../chains'; @@ -68,5 +68,45 @@ describe('Basejump contract builder', () => { expect(config.module).toBe('Basejump'); expect(config.args).toHaveLength(3); }); + + it('should pass asset address as first arg', async () => { + const ctx = buildCtx('0x71FeB8b2849101a6E62e3369eaAfDc6154CD0Bc0'); + const config = await Basejump().bridgeViaWormhole().build(ctx); + + // First arg is the asset ERC20 address on the source chain + const assetArg = (config.args[0] as string).toLowerCase(); + const expectedAssetId = base.getAssetId(eurc)?.toString().toLowerCase(); + expect(assetArg).toBe(expectedAssetId); + }); + }); + + describe('ABI', () => { + it('quoteFee should accept address param (not uint256)', () => { + const abi = Abi.Basejump as readonly Record[]; + const quoteFee = abi.find( + (e) => e.type === 'function' && e.name === 'quoteFee' + ) as Record | undefined; + + expect(quoteFee).toBeDefined(); + const inputs = quoteFee!.inputs as { type: string; name: string }[]; + expect(inputs).toHaveLength(1); + expect(inputs[0].type).toBe('address'); + expect(inputs[0].name).toBe('asset'); + }); + + it('bridgeViaWormhole should accept (address, uint256, bytes32)', () => { + const abi = Abi.Basejump as readonly Record[]; + const fn = abi.find( + (e) => e.type === 'function' && e.name === 'bridgeViaWormhole' + ) as Record | undefined; + + expect(fn).toBeDefined(); + const inputs = fn!.inputs as { type: string }[]; + expect(inputs.map((i) => i.type)).toEqual([ + 'address', + 'uint256', + 'bytes32', + ]); + }); }); }); diff --git a/packages/xc-core/src/evm/abi/Basejump.ts b/packages/xc-core/src/evm/abi/Basejump.ts index 6563c7a15..5faf5ccd4 100644 --- a/packages/xc-core/src/evm/abi/Basejump.ts +++ b/packages/xc-core/src/evm/abi/Basejump.ts @@ -21,7 +21,7 @@ export const BASEJUMP = [ type: 'function', }, { - inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + inputs: [{ internalType: 'address', name: 'asset', type: 'address' }], name: 'quoteFee', outputs: [{ internalType: 'uint256', name: 'fee', type: 'uint256' }], stateMutability: 'view',