Skip to content

Commit

Permalink
V3 next xcm payment api (#354)
Browse files Browse the repository at this point in the history
* Apply XcmPaymentApi fees in transactions to Moonbeam / Moonriver / Moonbase-Alpha (#351)

* -wip- initial commit and initial configs

* -wip- extract common code

* -wip- fix some types

* -wip- TODOs and refactoring

* -wip- group all in a single function

* -wip- apply to all Acala and Hydration routes

* -wip- apply to manta routes

* apply xcmv4 and solution for registered asset id for ERC20s

* sort assets, handle different palletInstances and apply to several configs

* remove unused property

* remove logs

* remove deleted routes from snapshots

* apply new configuration to Kusama chains

* add changeset

* remove assetTypeUnitsPerSecond function since it is not used now

* remove assetTypeUnitsPerSecond function since it is not used now

* apply PR reviews

* Version Packages (#352)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* update snapshots

* add asset ordering param to ibtc and kbtc

* fix linting and spell checking

* add changeset for xcm-utils (#353)

* Version Packages (#355)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix linting and spell checking

* fix linting error

* move palletInstance validation

* fix TEER configuration in Integritee (#356)

* Version Packages (#357)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* change native asset checking and builder interface

* fix error

* Fix Asset Hub memecoings asset ordering in fee calculation (#359)

* Version Packages (#360)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix lint

* change property name

* rename properties

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 2, 2024
1 parent b46e429 commit 66ae4fb
Show file tree
Hide file tree
Showing 71 changed files with 868 additions and 217 deletions.
32 changes: 16 additions & 16 deletions examples/sdk-simple/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { dot, moonbeam, polkadot } from "@moonbeam-network/xcm-config";
import { Sdk, type TransferData } from "@moonbeam-network/xcm-sdk";
import { Keyring } from "@polkadot/api";
import { cryptoWaitReady } from "@polkadot/util-crypto";
import { http, type Address, createWalletClient } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { dot, moonbeam, polkadot } from '@moonbeam-network/xcm-config';
import { Sdk, type TransferData } from '@moonbeam-network/xcm-sdk';
import { Keyring } from '@polkadot/api';
import { cryptoWaitReady } from '@polkadot/util-crypto';
import { http, type Address, createWalletClient } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

// Moonbeam Signer ===========================================================

const moonbeamPrivateKey = "";
const moonbeamPrivateKey = '';
const account = privateKeyToAccount(moonbeamPrivateKey as Address);
const walletClient = createWalletClient({
account,
Expand All @@ -17,12 +17,12 @@ const walletClient = createWalletClient({

// Polkadot Signer ===========================================================

const polkadotPrivateKey = "";
const polkadotPrivateKey = '';

await cryptoWaitReady();
const keyring = new Keyring({
ss58Format: polkadot.ss58Format,
type: "sr25519",
type: 'sr25519',
});
const pair = keyring.createFromUri(polkadotPrivateKey);

Expand All @@ -32,14 +32,14 @@ export function logBalances(data: TransferData): void {
console.log(
`Balance on ${data.source.chain.name} ${data.source.balance.toDecimal()} ${
data.source.balance.symbol
}`
}`,
);
console.log(
`Balance on ${
data.destination.chain.name
} ${data.destination.balance.toDecimal()} ${
data.destination.balance.symbol
}`
}`,
);
}

Expand All @@ -57,12 +57,12 @@ export function logTxDetails(data: TransferData): void {
data.source.chain.name
} and ${data.destination.fee.toDecimal()} ${
data.destination.fee.symbol
} fee on ${data.destination.chain.name}.`
} fee on ${data.destination.chain.name}.`,
);
}

export async function fromPolkadot() {
console.log("\nTransfer from Polkadot to Moonbeam\n");
console.log('\nTransfer from Polkadot to Moonbeam\n');

const data = await Sdk().getTransferData({
destinationAddress: account.address,
Expand All @@ -86,7 +86,7 @@ export async function fromPolkadot() {
}

export async function fromMoonbeam() {
console.log("\nTransfer from Moonbeam to Polkadot\n");
console.log('\nTransfer from Moonbeam to Polkadot\n');

const data = await Sdk()
.assets()
Expand Down Expand Up @@ -118,12 +118,12 @@ async function main() {
console.log(`Polkadot address: ${pair.address}.`);

await fromPolkadot();
console.log("\nWaiting 30 seconds...");
console.log('\nWaiting 30 seconds...');
await setTimeout(30000);
await fromMoonbeam();
}

main()
.then(() => console.log("done!"))
.then(() => console.log('done!'))
.catch(console.error)
.finally(() => process.exit());
4 changes: 3 additions & 1 deletion mkdocs/docs/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ export const polkadotAssetHubConfig = new ChainConfig({
balance: BalanceBuilder().substrate().assets().account(),
destination: moonbeam,
destinationFee: {
amount: FeeBuilder().assetManager().assetTypeUnitsPerSecond(),
amount: FeeBuilder()
.xcmPaymentApi()
.xcmPaymentFee({ isAssetReserveChain: false }),
asset: usdt,
balance: BalanceBuilder().substrate().assets().account(),
},
Expand Down
12 changes: 9 additions & 3 deletions mkdocs/docs/reference/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,9 @@ Defines a chain's configurations, including information for each chain's support
balance: BalanceBuilder().substrate().assets().account(),
destination: moonbeam,
destinationFee: {
amount: FeeBuilder().assetManager().assetTypeUnitsPerSecond(),
amount: FeeBuilder()
.xcmPaymentApi()
.xcmPaymentFee({ isAssetReserveChain: false }),
asset: usdt,
balance: BalanceBuilder().substrate().assets().account(),
},
Expand Down Expand Up @@ -761,7 +763,9 @@ Defines an asset's configurations for a source chain and includes information ab
balance: BalanceBuilder().substrate().assets().account(),
destination: moonbeam,
destinationFee: {
amount: FeeBuilder().assetManager().assetTypeUnitsPerSecond(),
amount: FeeBuilder()
.xcmPaymentApi()
.xcmPaymentFee({ isAssetReserveChain: false }),
asset: usdt,
balance: BalanceBuilder().substrate().assets().account(),
},
Expand Down Expand Up @@ -831,7 +835,9 @@ Defines the fees for a particular asset on the destination chain.
{
asset: dot,
balance: BalanceBuilder().substrate().system().account(),
amount: FeeBuilder().assetManager().assetTypeUnitsPerSecond(),
amount: amount: FeeBuilder()
.xcmPaymentApi()
.xcmPaymentFee({ isAssetReserveChain: false }),
}
```

Expand Down
19 changes: 19 additions & 0 deletions packages/builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# @moonbeam-network/xcm-builder

## 2.5.1

### Patch Changes

- Updated dependencies [[`4be5659`](https://github.com/moonbeam-foundation/xcm-sdk/commit/4be5659c05fe2487dd6f440c833fdf7cdc369917)]:
- @moonbeam-network/xcm-utils@2.2.0
- @moonbeam-network/xcm-types@2.4.1

## 2.5.0

### Minor Changes

- [#351](https://github.com/moonbeam-foundation/xcm-sdk/pull/351) [`2a7ed04`](https://github.com/moonbeam-foundation/xcm-sdk/commit/2a7ed04887ee41e5a6c010f213265028a953a769) Thanks [@mmaurello](https://github.com/mmaurello)! - Implement XcmPaymentApi to calculate fees for routes going to Moonbeam / Moonriver / Moonbase-Alpha

### Patch Changes

- Updated dependencies [[`2a7ed04`](https://github.com/moonbeam-foundation/xcm-sdk/commit/2a7ed04887ee41e5a6c010f213265028a953a769)]:
- @moonbeam-network/xcm-types@2.4.0

## 2.4.7

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/builder/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@moonbeam-network/xcm-builder",
"version": "2.4.7",
"version": "2.5.1",
"description": "Moonbeam XCM builder",
"scripts": {
"build": "tsup",
Expand Down
20 changes: 18 additions & 2 deletions packages/builder/src/fee/FeeBuilder.interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { ChainAssetId } from '@moonbeam-network/xcm-types';
import type { AnyParachain, ChainAsset } from '@moonbeam-network/xcm-types';
import type { ApiPromise } from '@polkadot/api';
import type { Enum } from '@polkadot/types';
import type { StagingXcmV3MultiLocation } from '@polkadot/types/lookup';
import type { ConfigBuilder } from '../builder.interfaces';
import type { SubstrateCallConfig } from '../types/substrate/SubstrateCallConfig';

Expand All @@ -9,6 +11,20 @@ export type FeeConfigBuilder = ConfigBuilder<
>;

export interface FeeConfigBuilderPrams {
asset: ChainAssetId;
address: string;
api: ApiPromise;
asset: ChainAsset;
destination: AnyParachain;
feeAsset: ChainAsset;
}

export interface XcmPaymentFeeProps {
isAssetReserveChain: boolean;
shouldTransferAssetPrecedeFeeAsset?: boolean;
}

export interface MoonbeamRuntimeXcmConfigAssetType extends Enum {
readonly isXcm: boolean;
readonly asXcm: StagingXcmV3MultiLocation;
readonly type: 'Xcm';
}
79 changes: 59 additions & 20 deletions packages/builder/src/fee/FeeBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,77 @@
import type { Option, u128 } from '@polkadot/types';
/* eslint-disable sort-keys */
/* eslint-disable @typescript-eslint/no-use-before-define */

import { SubstrateCallConfig } from '../types/substrate/SubstrateCallConfig';
import type { FeeConfigBuilder } from './FeeBuilder.interfaces';
import type {
FeeConfigBuilder,
FeeConfigBuilderPrams,
XcmPaymentFeeProps,
} from './FeeBuilder.interfaces';
import {
getBuyExecutionInstruction,
getClearOriginInstruction,
getDepositAssetInstruction,
getFeeForXcmInstructionsAndAsset,
getReserveAssetDepositedInstruction,
getSetTopicInstruction,
getVersionedAssetId,
getWithdrawAssetInstruction,
} from './FeeBuilder.utils';

export function FeeBuilder() {
return {
assetManager,
xcmPaymentApi,
};
}

function assetManager() {
function xcmPaymentApi() {
return {
assetTypeUnitsPerSecond: (weight = 1_000_000_000): FeeConfigBuilder => ({
build: ({ api, asset }) =>
xcmPaymentFee: ({
isAssetReserveChain,
shouldTransferAssetPrecedeFeeAsset = false,
}: XcmPaymentFeeProps): FeeConfigBuilder => ({
build: ({
address,
api,
asset,
destination,
feeAsset,
}: FeeConfigBuilderPrams) =>
new SubstrateCallConfig({
api,
call: async (): Promise<bigint> => {
const type = (await api.query.assetManager.assetIdType(
const versionedFeeAssetId = await getVersionedAssetId(
api,
feeAsset,
destination,
);
const versionedTransferAssetId = await getVersionedAssetId(
api,
asset,
// biome-ignore lint/suspicious/noExplicitAny: not sure how to fix this
)) as unknown as Option<any>;

if (type.isNone) {
throw new Error(`No asset type found for asset ${asset}`);
}

const unwrappedType = type.unwrap();
destination,
);
const versionedAssets = shouldTransferAssetPrecedeFeeAsset
? [versionedTransferAssetId, versionedFeeAssetId]
: [versionedFeeAssetId, versionedTransferAssetId];

const res = (await api.query.assetManager.assetTypeUnitsPerSecond(
unwrappedType,
)) as unknown as Option<u128>;
const assets =
feeAsset === asset ? [versionedFeeAssetId] : versionedAssets;

const unitsPerSecond = res.unwrapOrDefault().toBigInt();
const instructions = [
isAssetReserveChain
? getWithdrawAssetInstruction(assets)
: getReserveAssetDepositedInstruction(assets),
getClearOriginInstruction(),
getBuyExecutionInstruction(versionedFeeAssetId),
getDepositAssetInstruction(address, assets),
getSetTopicInstruction(),
];

return (BigInt(weight) * unitsPerSecond) / BigInt(10 ** 12);
return getFeeForXcmInstructionsAndAsset(
api,
instructions,
versionedFeeAssetId,
);
},
}),
}),
Expand Down
Loading

0 comments on commit 66ae4fb

Please sign in to comment.