Skip to content

Commit

Permalink
✅ WETH integration test (#432)
Browse files Browse the repository at this point in the history
## What?

Add initial Snowbridge WETH integration tests.
  • Loading branch information
lrazovic authored Mar 5, 2025
2 parents b1c86f6 + e22194d commit 3e4eb81
Show file tree
Hide file tree
Showing 35 changed files with 2,649 additions and 430 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.0-autogenerated.575737038775881951",
"version": "0.1.0-autogenerated.14907376514540113357",
"name": "@polkadot-api/descriptors",
"files": [
"dist"
Expand Down
Binary file modified integration-tests/chopsticks/.papi/metadata/polimec.scale
Binary file not shown.
11 changes: 7 additions & 4 deletions integration-tests/chopsticks/.papi/polkadot-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
"descriptorPath": ".papi/descriptors",
"entries": {
"polimec": {
"wsUrl": "ws://127.0.0.1:8000",
"metadata": ".papi/metadata/polimec.scale"
},
"polkadot": {
"wsUrl": "ws://localhost:8002",
"wsUrl": "wss://rpc.ibp.network/polkadot",
"metadata": ".papi/metadata/polkadot.scale"
},
"pah": {
"wsUrl": "ws://localhost:8001",
"wsUrl": "wss://sys.ibp.network/statemint",
"metadata": ".papi/metadata/pah.scale"
},
"bridge": {
"wsUrl": "wss://sys.ibp.network/bridgehub-polkadot",
"metadata": ".papi/metadata/bridge.scale"
}
}
}
}
17 changes: 17 additions & 0 deletions integration-tests/chopsticks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ To install dependencies:
bun install
```

```bash
bun papi
```

> [!NOTE]
> Sometimes you need to regenerate the Polimec descriptors. To do that, run:
>
> ```bash
> bun papi add polimec --wasm ../../target/release/wbuild/polimec-runtime/polimec_runtime.compact.compressed.wasm
> ```
To start the chains:
```bash
Expand All @@ -18,3 +29,9 @@ To run the tests:
bun run test
```


> [!IMPORTANT]
> TODO: Add:
> - [ ] Polimec SA on AH: Add WETH balance to it in the Chopstick ovveride
> - [ ] Polimec to Asset Hub: WETH transfer. This is a "normal" transfer_asset call.
> - [ ] Polimec to Ethereum: WETH transfer. This is a bit more complex, example extrinsic: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fhydration.ibp.network#/extrinsics/decode/0x6b0d04010100a10f040801000007464a69c7e002020907040300c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200130000e8890423c78a0204010002040816040d01000001010088ca48e3e1d0f1c50bd6b504e1312d21f5bd45ed147e3c30c77eb5e4d63bdc6310010102020907040300c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000201090704081300010300c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20004000d010204000103001501c1413e4178c38567ada8945a80351f7b849600
1,084 changes: 1,084 additions & 0 deletions integration-tests/chopsticks/bun.lock

Large diffs are not rendered by default.

Binary file removed integration-tests/chopsticks/bun.lockb
Binary file not shown.
18 changes: 18 additions & 0 deletions integration-tests/chopsticks/overrides/bridge-hub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { INITIAL_BALANCES } from '@/constants';
import { Accounts } from '@/types';

export const bridge_storage = {
System: {
Account: [
[
[Accounts.ALICE],
{
providers: 1,
data: {
free: INITIAL_BALANCES.DOT,
},
},
],
],
},
} as const;
3 changes: 2 additions & 1 deletion integration-tests/chopsticks/overrides/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { bridge_storage } from '@/bridge-hub';
import { POLIMEC_WASM, polimec_storage } from '@/polimec';
import { polkadot_storage } from '@/polkadot';
import { polkadot_hub_storage } from '@/polkadot-hub';

export { polkadot_storage, polkadot_hub_storage, POLIMEC_WASM, polimec_storage };
export { polkadot_storage, polkadot_hub_storage, POLIMEC_WASM, polimec_storage, bridge_storage };
72 changes: 67 additions & 5 deletions integration-tests/chopsticks/overrides/polimec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
import { INITIAL_BALANCES } from '@/constants';
import { Accounts, Assets } from '@/types';
import { INITIAL_BALANCES, WETH_ADDRESS } from '@/constants';
import { Accounts } from '@/types';

export const POLIMEC_WASM =
'../../target/release/wbuild/polimec-runtime/polimec_runtime.compact.compressed.wasm';

const usdc_location = {
parents: 1,
interior: {
x3: [{ parachain: 1000 }, { palletInstance: 50 }, { generalIndex: 1337 }],
},
};
const usdt_location = {
parents: 1,
interior: {
x3: [{ parachain: 1000 }, { palletInstance: 50 }, { generalIndex: 1984 }],
},
};
const dot_location = {
parents: 1,
interior: {
here: undefined,
},
};

export const weth_location = {
parents: 2,
interior: {
x2: [
{
globalConsensus: {
ethereum: {
chainId: 1n,
},
},
},
{
accountKey20: {
key: WETH_ADDRESS,
},
},
],
},
};

export const polimec_storage = {
System: {
Account: [
Expand All @@ -21,23 +60,46 @@ export const polimec_storage = {
ForeignAssets: {
Account: [
[
[Assets.USDC, Accounts.BOB],
[usdc_location, Accounts.BOB],
{
balance: INITIAL_BALANCES.USDC,
},
],
[
[Assets.USDT, Accounts.BOB],
[usdt_location, Accounts.BOB],
{
balance: INITIAL_BALANCES.USDT,
},
],
[
[Assets.DOT, Accounts.BOB],
[dot_location, Accounts.BOB],
{
balance: INITIAL_BALANCES.DOT,
},
],
],
// Note: We can remove Asset and Metadata from the storage override as soon we set them on-chain.
Asset: [
[
[weth_location],
{
owner: Accounts.ALICE,
issuer: Accounts.ALICE,
admin: Accounts.ALICE,
freezer: Accounts.ALICE,
supply: 100n * INITIAL_BALANCES.WETH,
deposit: 0n,
min_balance: 15000000000000n,
is_sufficient: true,
accounts: 1,
sufficients: 1,
approvals: 0,
status: 'Live',
},
],
],
Metadata: [
[[weth_location], { symbol: 'Wrapped Ether', name: 'WETH', decimals: 18, isFrozen: false }],
],
},
} as const;
16 changes: 10 additions & 6 deletions integration-tests/chopsticks/overrides/polkadot-hub.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { INITIAL_BALANCES } from '@/constants';
import { Accounts, Assets } from '@/types';
import { Accounts, Asset } from '@/types';
import { weth_location } from './polimec';

export const polkadot_hub_storage = {
System: {
Expand All @@ -18,24 +19,27 @@ export const polkadot_hub_storage = {
Assets: {
Account: [
[
[Assets.USDT, Accounts.ALICE],
[Asset.USDT, Accounts.ALICE],
{
balance: INITIAL_BALANCES.USDT,
},
],
[
[Assets.USDC, Accounts.ALICE],
[Asset.USDC, Accounts.ALICE],
{
balance: INITIAL_BALANCES.USDC,
},
],
],
},
ForeignAssets: {
Account: [
[
[Assets.UNKNOWN, Accounts.ALICE],
[weth_location, Accounts.POLIMEC],
{
balance: INITIAL_BALANCES.USDT,
balance: INITIAL_BALANCES.WETH,
},
],
],
},
// TODO: Add the foreignAssets storage to give to ALICE WETH = INITIAL_BALANCES.WETH
} as const;
11 changes: 5 additions & 6 deletions integration-tests/chopsticks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@
"type": "module",
"scripts": {
"lint": "biome check --write src overrides",
"test": "env LOG_LEVEL=error bun test --timeout 25000"
"test": "env LOG_LEVEL=error bun test"
},
"devDependencies": {
"@acala-network/chopsticks": "1.0.1",
"@acala-network/chopsticks": "1.0.2",
"@biomejs/biome": "1.9.4",
"@polkadot-labs/hdkd": "0.0.10",
"@polkadot-labs/hdkd": "0.0.11",
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
"typescript": "^5.7.3"
},
"dependencies": {
"@polkadot-api/descriptors": "file:.papi/descriptors",
"@polkadot/keyring": "13.2.3",
"polkadot-api": "^1.7.7"
"polkadot-api": "^1.9.0"
}
}
8 changes: 7 additions & 1 deletion integration-tests/chopsticks/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Accounts } from '@/types';
import { FixedSizeBinary } from 'polkadot-api';

export const INITIAL_BALANCES = {
USDT: 52000n * 10n ** 6n,
Expand All @@ -17,4 +18,9 @@ export const TRANSFER_AMOUNTS = {
export const DERIVE_PATHS = {
[Accounts.ALICE]: '//Alice',
[Accounts.BOB]: '//Bob',
};
} as const;

export const WETH_ADDRESS = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
export const DEFAULT_TOPIC = FixedSizeBinary.fromArray(Array(32).fill(1));
export const FEE_AMOUNT = 40_000_000_000n;
export const WETH_AMOUNT = 15_000_000_000_000n;
33 changes: 22 additions & 11 deletions integration-tests/chopsticks/src/managers/BaseManager.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { DERIVE_PATHS } from '@/constants';
import type { Accounts, ChainClient, ChainToDefinition, Chains } from '@/types';
import type {
Accounts,
Asset,
AssetSourceRelation,
ChainClient,
ChainToDefinition,
Chains,
} from '@/types';
import { sr25519CreateDerive } from '@polkadot-labs/hdkd';
import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy } from '@polkadot-labs/hdkd-helpers';
import type { PolkadotSigner, TypedApi } from 'polkadot-api';
import type { PolkadotClient, PolkadotSigner, TypedApi } from 'polkadot-api';
import { getPolkadotSigner } from 'polkadot-api/signer';
import { filter, firstValueFrom, take } from 'rxjs';

Expand Down Expand Up @@ -34,13 +41,19 @@ export abstract class BaseChainManager {
return client.api as TypedApi<ChainToDefinition[T]>;
}

getClient<T extends Chains>(chain: T): PolkadotClient {
const client = this.clients.get(chain);
if (!client) throw new Error(`Chain ${chain} not initialized`);
return client.client;
}

getSigner(account: Accounts) {
const signer = this.signers.get(account);
if (!signer) throw new Error(`Signer for ${account} not found`);
return signer;
}

async waitForNextBlock(currentBlock: number) {
waitForNextBlock(currentBlock: number) {
const api = this.getApi(this.getChainType());
return firstValueFrom(
api.query.System.Number.watchValue().pipe(
Expand All @@ -53,10 +66,12 @@ export abstract class BaseChainManager {
async getBlockNumber() {
const chain = this.getChainType();
const api = this.getApi(chain);
// Note: Not sure why this is needed, but without it we cannot retrieve the block number.
await api.compatibilityToken;
return api.query.System.Number.getValue();
}

async getMessageQueueEvents() {
getMessageQueueEvents() {
const api = this.getApi(this.getChainType());
return api.event.MessageQueue.Processed.pull();
}
Expand All @@ -67,19 +82,15 @@ export abstract class BaseChainManager {
return events[0]?.payload.actual_fee || 0n;
}

async getNativeBalanceOf(account: Accounts) {
const api = this.getApi(this.getChainType());
const balance = await api.query.System.Account.getValue(account);
return balance.data.free;
}
abstract getAssetSourceRelation(asset: Asset): AssetSourceRelation;

abstract getAssetBalanceOf(account: Accounts, asset: Asset): Promise<bigint>;

// @ts-expect-error - TODO: Not sure which is the correct type for this
abstract getXcmPallet();

abstract getChainType(): Chains;

abstract getAssetBalanceOf(account: Accounts, asset: number): Promise<bigint>;

abstract connect(): void;

abstract disconnect(): void;
Expand Down
Loading

0 comments on commit 3e4eb81

Please sign in to comment.