Skip to content

Commit

Permalink
-wip- initial commit get sovereign account balances and validate tran…
Browse files Browse the repository at this point in the history
…sfer amount
  • Loading branch information
mmaurello committed Sep 2, 2024
1 parent 04145d8 commit 569447d
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 19 deletions.
3 changes: 2 additions & 1 deletion packages/config/src/configs/moonbeam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,9 @@ export const moonbeamConfig = new ChainConfig({
destination: polkadotAssetHub,
destinationFee: {
amount: 0.2,
asset: usdt,
asset: dot,
balance: BalanceBuilder().substrate().assets().account(),
destinationBalance: BalanceBuilder().substrate().system().account(),
},
fee: {
asset: glmr,
Expand Down
1 change: 1 addition & 0 deletions packages/config/src/types/AssetConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface AssetConfigConstructorParams {

export interface DestinationFeeConfig extends FeeAssetConfig {
amount: number | FeeConfigBuilder;
destinationBalance?: BalanceConfigBuilder;
}

export interface FeeAssetConfig {
Expand Down
63 changes: 61 additions & 2 deletions packages/sdk/src/getTransferData/getDestinationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import { FeeConfigBuilder } from '@moonbeam-network/xcm-builder';
import { TransferConfig } from '@moonbeam-network/xcm-config';
import { AssetAmount } from '@moonbeam-network/xcm-types';
import { toBigInt } from '@moonbeam-network/xcm-utils';
import {
getSovereignAccountAddresses,
toBigInt,
} from '@moonbeam-network/xcm-utils';
import { PolkadotService } from '../polkadot';
import { DestinationChainTransferData } from '../sdk.interfaces';
import { getBalance, getDecimals, getMin } from './getTransferData.utils';
Expand Down Expand Up @@ -35,11 +38,13 @@ export async function getDestinationData({

const balance = await getBalance({
address: destinationAddress,
asset: config.asset,
balanceBuilder: config.balance,
chain,
config,
decimals: zeroAmount.decimals,
polkadot,
});

const min = await getMin(config, polkadot);

const balanceAmount = zeroAmount.copyWith({ amount: balance });
Expand All @@ -51,12 +56,18 @@ export async function getDestinationData({
polkadot,
});
const minAmount = zeroAmount.copyWith({ amount: min });

return {
balance: balanceAmount,
chain,
existentialDeposit,
fee: feeAmount,
min: minAmount,
sovereignAccountBalances: await getSovereignAccountBalances({
decimals: zeroAmount.decimals,
polkadot,
transferConfig,
}),
};
}

Expand Down Expand Up @@ -93,3 +104,51 @@ export async function getFee({
amount: await cfg.call(),
});
}

interface GetSovereignAccountBalancesProps {
transferConfig: TransferConfig;
decimals: number;
polkadot: PolkadotService;
}

async function getSovereignAccountBalances({
transferConfig,
decimals,
polkadot,
}: GetSovereignAccountBalancesProps) {
const {
destination: { chain, config },
source: { config: sourceConfig },
} = transferConfig;
const sovereignAccountAddresses = getSovereignAccountAddresses(
transferConfig.source.chain.parachainId,
);
// console.log('sovereignAccountAddresses', sovereignAccountAddresses);

const destinationFeeAssetBalance =
sourceConfig.destinationFee?.destinationBalance;

const sovereignAccountBalance = await getBalance({
address: sovereignAccountAddresses.generic,
asset: config.asset,
balanceBuilder: config.balance,
chain,
decimals,
polkadot,
});

const sovereignAccountFeeAssetBalance = destinationFeeAssetBalance
? await getBalance({
address: sovereignAccountAddresses.generic,
asset: sourceConfig.destinationFee.asset,
balanceBuilder: destinationFeeAssetBalance,
chain,
decimals, // TODO this is not correct but it doesn't affect us
polkadot,
})
: undefined;
return {
feeAssetBalance: sovereignAccountFeeAssetBalance,
transferAssetBalance: sovereignAccountBalance,
};
}
13 changes: 8 additions & 5 deletions packages/sdk/src/getTransferData/getSourceData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
import { PolkadotService } from '../polkadot';
import { EvmSigner, SourceChainTransferData } from '../sdk.interfaces';
import {
GetBalancesParams,
BaseParams,
getBalance,
getDecimals,
getMin,
Expand Down Expand Up @@ -112,8 +112,9 @@ export async function getSourceData({

const balance = await getBalance({
address: sourceAddress,
asset: config.asset,
balanceBuilder: config.balance,
chain,
config,
decimals: zeroAmount.decimals,
polkadot,
});
Expand Down Expand Up @@ -206,10 +207,11 @@ export async function getSourceData({
};
}

export interface GetFeeBalanceParams
extends Omit<GetBalancesParams, 'config' | 'evmSigner'> {
// TODO mjm review this
export interface GetFeeBalanceParams extends BaseParams {
balance: bigint;
feeConfig: FeeAssetConfig | undefined;
decimals: number;
}

export async function getFeeBalance({
Expand Down Expand Up @@ -456,8 +458,9 @@ export async function getAssetsBalances({
// eslint-disable-next-line no-await-in-loop
const balance = await getBalance({
address,
asset: asset.asset,
balanceBuilder: asset.balance,
chain,
config: asset,
decimals,
polkadot,
});
Expand Down
9 changes: 9 additions & 0 deletions packages/sdk/src/getTransferData/getTransferData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '../sdk.interfaces';
import { getDestinationData } from './getDestinationData';
import { getSourceData } from './getSourceData';
import { validateSovereignAccountBalances } from './getTransferData.utils';

export interface GetTransferDataParams extends Partial<Signers> {
configService: IConfigService;
Expand Down Expand Up @@ -53,13 +54,15 @@ export async function getTransferData({
sourceAddress,
transferConfig,
});
// console.log('destination', destination);

return {
destination,
getEstimate(amount: number | string) {
const bigAmount = Big(
toBigInt(amount, source.balance.decimals).toString(),
);

const result = bigAmount.minus(
source.balance.isSame(destinationFee) ? destinationFee.toBig() : Big(0),
);
Expand Down Expand Up @@ -93,6 +96,12 @@ export async function getTransferData({
},
async transfer(amount): Promise<string> {
const bigintAmount = toBigInt(amount, source.balance.decimals);
validateSovereignAccountBalances({
amount: bigintAmount,
destination,
source,
});

const {
asset,
source: { chain, config },
Expand Down
62 changes: 52 additions & 10 deletions packages/sdk/src/getTransferData/getTransferData.utils.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,53 @@
import {
BalanceConfigBuilder,
CallType,
ContractConfig,
SubstrateQueryConfig,
} from '@moonbeam-network/xcm-builder';
import { AssetConfig } from '@moonbeam-network/xcm-config';
import { AssetConfig, FeeAssetConfig } from '@moonbeam-network/xcm-config';
import { AnyChain, Asset, EvmParachain } from '@moonbeam-network/xcm-types';
import { convertDecimals, toBigInt } from '@moonbeam-network/xcm-utils';
import {
BalanceContractInterface,
createContractWithoutSigner,
} from '../contract';
import { PolkadotService } from '../polkadot';
import {
DestinationChainTransferData,
SourceChainTransferData,
} from '../sdk.interfaces';

export interface GetBalancesParams {
export interface BaseParams {
address: string;
asset?: Asset;
chain: AnyChain;
config: AssetConfig;
decimals: number;
polkadot: PolkadotService;
}

export type GetDecimalsParams = Omit<GetBalancesParams, 'decimals'> & {
export interface GetBalancesParams extends BaseParams {
asset: Asset;
balanceBuilder: BalanceConfigBuilder;
decimals: number;
}

export interface GetDecimalsParams extends BaseParams {
asset?: Asset;
config: AssetConfig | FeeAssetConfig;
assetBuiltConfig?: SubstrateQueryConfig | ContractConfig;
};
}

export async function getBalance({
address,
chain,
config,
balanceBuilder,
asset,
decimals,
polkadot,
}: GetBalancesParams) {
const cfg = config.balance.build({
const cfg = balanceBuilder.build({
address,
asset: polkadot.chain.getBalanceAssetId(config.asset),
asset: polkadot.chain.getBalanceAssetId(asset),
});
// console.log('cfg', cfg);
if (cfg.type === CallType.Substrate) {
const balance = await polkadot.query(cfg as SubstrateQueryConfig);
return chain.usesChainDecimals
Expand Down Expand Up @@ -97,3 +109,33 @@ export async function getMin(config: AssetConfig, polkadot: PolkadotService) {

return 0n;
}

interface ValidateSovereignAccountBalancesProps {
amount: bigint;
destination: DestinationChainTransferData;
source: SourceChainTransferData;
}

export function validateSovereignAccountBalances({
amount,
source,
destination,
}: ValidateSovereignAccountBalancesProps): void {
const { sovereignAccountBalances } = destination;
if (!sovereignAccountBalances) return;
// console.log('validating', destination.sovereignAccountBalances);
if (amount > sovereignAccountBalances.transferAssetBalance) {
throw new Error(
'Moonbeam Sovereign account in Polkadot Asset Hub does not have enough balance for this transaction',
);
}
if (
sovereignAccountBalances.feeAssetBalance &&
source.destinationFeeBalance.amount >
sovereignAccountBalances.feeAssetBalance
) {
throw new Error(
'Moonbeam Sovereign account in Polkadot Asset Hub does not have enough balance to pay for fees for this transaction',
);
}
}
9 changes: 8 additions & 1 deletion packages/sdk/src/sdk.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ export interface SourceChainTransferData extends ChainTransferData {
max: AssetAmount;
}

export interface DestinationChainTransferData extends ChainTransferData {}
export interface SovereignAccountBalance {
feeAssetBalance: bigint | undefined;
transferAssetBalance: bigint;
}

export interface DestinationChainTransferData extends ChainTransferData {
sovereignAccountBalances: SovereignAccountBalance;
}

export interface ChainTransferData {
balance: AssetAmount;
Expand Down

0 comments on commit 569447d

Please sign in to comment.