diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..1841652 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "useTabs": false, + "trailingComma": "all", + "printWidth": 150 +} diff --git a/packages/adapter/src/chains/mangata.ts b/packages/adapter/src/chains/mangata.ts index 7515984..61af5ed 100644 --- a/packages/adapter/src/chains/mangata.ts +++ b/packages/adapter/src/chains/mangata.ts @@ -1,18 +1,14 @@ import _ from "lodash"; import BN from "bn.js"; import type { SubmittableExtrinsic, AddressOrPair } from "@polkadot/api/types"; -import type { u32, u64, u128, Option } from "@polkadot/types"; +import type { u32, u128, Option } from "@polkadot/types"; import type { WeightV2 } from "@polkadot/types/interfaces"; import type { HexString } from "@polkadot/util/types"; import type { KeyringPair } from "@polkadot/keyring/types"; import { Weight } from "@oak-network/config"; import { ChainAdapter } from "./chainAdapter"; -import { - convertAbsoluteLocationToRelative, - getDerivativeAccountV2, - sendExtrinsic, -} from "../util"; -import { WEIGHT_REF_TIME_PER_SECOND } from "../constants"; +import { getDerivativeAccountV2, sendExtrinsic } from "../util"; +import { WEIGHT_REF_TIME_PER_NANOS, WEIGHT_REF_TIME_PER_SECOND, WEIGHT_PROOF_SIZE_PER_MB } from "../constants"; import { SendExtrinsicResult } from "../types"; // MangataAdapter implements ChainAdapter @@ -31,12 +27,8 @@ export class MangataAdapter extends ChainAdapter { * @returns Extrinsic weight */ // eslint-disable-next-line class-methods-use-this - async getExtrinsicWeight( - extrinsic: SubmittableExtrinsic<"promise">, - account: AddressOrPair, - ): Promise { - const { refTime, proofSize } = (await extrinsic.paymentInfo(account)) - .weight as unknown as WeightV2; + async getExtrinsicWeight(extrinsic: SubmittableExtrinsic<"promise">, account: AddressOrPair): Promise { + const { refTime, proofSize } = (await extrinsic.paymentInfo(account)).weight as unknown as WeightV2; return new Weight(new BN(refTime.unwrap()), new BN(proofSize.unwrap())); } @@ -46,15 +38,10 @@ export class MangataAdapter extends ChainAdapter { * @param instructionCount The number of XCM instructions * @returns XCM overall weight */ - async calculateXcmOverallWeight( - transactCallWeight: Weight, - instructionCount: number, - ): Promise { + async calculateXcmOverallWeight(transactCallWeight: Weight, instructionCount: number): Promise { const { xcm } = this.chainConfig; if (_.isUndefined(xcm)) throw new Error("chainConfig.xcm not set"); - const overallWeight = transactCallWeight.add( - xcm.instructionWeight.muln(instructionCount), - ); + const overallWeight = transactCallWeight.add(xcm.instructionWeight.muln(instructionCount)); return overallWeight; } @@ -66,24 +53,24 @@ export class MangataAdapter extends ChainAdapter { */ async weightToFee(weight: Weight, assetLocation: any): Promise { const [defaultAsset] = this.chainConfig.assets; - if (_.isUndefined(defaultAsset)) - throw new Error("chainConfig.defaultAsset not set"); + if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set"); const api = this.getApi(); if (_.isEqual(defaultAsset.location, assetLocation)) { - const fee = (await api.call.transactionPaymentApi.queryWeightToFee( - weight, - )) as u64; - return fee; + const unit = new BN(10).pow(new BN(defaultAsset.decimals)); + // ExtrinsicBaseWeight benchmark value: 114756 nano seconds + const extrinsicBaseWeight = WEIGHT_REF_TIME_PER_NANOS.mul(new BN(114756)); + const feePerSecond = WEIGHT_REF_TIME_PER_SECOND.div(extrinsicBaseWeight).mul(unit); + const refTimeFee = weight.refTime.mul(feePerSecond).div(WEIGHT_REF_TIME_PER_SECOND); + const proofSizeFee = weight.proofSize.mul(feePerSecond).div(WEIGHT_PROOF_SIZE_PER_MB); + return refTimeFee.add(proofSizeFee); } - const storageValue = - await api.query.assetRegistry.locationToAssetId(assetLocation); + const storageValue = await api.query.assetRegistry.locationToAssetId(assetLocation); const item = storageValue as unknown as Option; if (item.isNone) throw new Error("AssetTypeUnitsPerSecond is null"); const assetId = item.unwrap(); - const metadataStorageValue = - await api.query.assetRegistry.metadata(assetId); + const metadataStorageValue = await api.query.assetRegistry.metadata(assetId); const metadataItem = metadataStorageValue as unknown as Option; if (metadataItem.isNone) throw new Error("Metadata is null"); @@ -137,25 +124,18 @@ export class MangataAdapter extends ChainAdapter { const { key } = this.chainConfig; if (_.isUndefined(key)) throw new Error("chainConfig.key not set"); - const transferAssetLocation = this.isNativeAsset(assetLocation) - ? convertAbsoluteLocationToRelative(assetLocation) - : assetLocation; - const api = this.getApi(); const extrinsic = api.tx.xTokens.transferMultiasset( { V3: { fun: { Fungible: assetAmount }, - id: { Concrete: transferAssetLocation }, + id: { Concrete: assetLocation }, }, }, { V3: { interior: { - X2: [ - destination.interior.X1, - { AccountId32: { id: recipient, network: null } }, - ], + X2: [destination.interior.X1, { AccountId32: { id: recipient, network: null } }], }, parents: 1, }, diff --git a/packages/adapter/src/chains/moonbeam.ts b/packages/adapter/src/chains/moonbeam.ts index 6ea993d..5da6d2c 100644 --- a/packages/adapter/src/chains/moonbeam.ts +++ b/packages/adapter/src/chains/moonbeam.ts @@ -7,11 +7,7 @@ import type { HexString } from "@polkadot/util/types"; import type { KeyringPair } from "@polkadot/keyring/types"; import { Weight } from "@oak-network/config"; import { ChainAdapter, TaskScheduler } from "./chainAdapter"; -import { - convertAbsoluteLocationToRelative, - getDerivativeAccountV3, - sendExtrinsic, -} from "../util"; +import { convertAbsoluteLocationToRelative, getDerivativeAccountV3, sendExtrinsic } from "../util"; import { AccountType, SendExtrinsicResult } from "../types"; import { WEIGHT_REF_TIME_PER_SECOND } from "../constants"; @@ -25,11 +21,11 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { async initialize() { // As of 12/02/2023, api.consts and api.query both return {} from all Moonriver endpoints. // Maybe additional calls are required prior to fetch api.consts - + // await this.fetchAndUpdateConfigs(); - this.chainConfig.ss58Prefix = 1285; - this.chainConfig.paraId = 2023; + this.chainConfig.ss58Prefix = 1285; + this.chainConfig.paraId = 2023; } /** @@ -74,12 +70,8 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { * @returns Extrinsic weight */ // eslint-disable-next-line class-methods-use-this - async getExtrinsicWeight( - extrinsic: SubmittableExtrinsic<"promise">, - account: AddressOrPair, - ): Promise { - const { refTime, proofSize } = (await extrinsic.paymentInfo(account)) - .weight as unknown as WeightV2; + async getExtrinsicWeight(extrinsic: SubmittableExtrinsic<"promise">, account: AddressOrPair): Promise { + const { refTime, proofSize } = (await extrinsic.paymentInfo(account)).weight as unknown as WeightV2; return new Weight(new BN(refTime.unwrap()), new BN(proofSize.unwrap())); } @@ -89,15 +81,10 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { * @param instructionCount * @returns XCM overall weight */ - async calculateXcmOverallWeight( - transactCallWeight: Weight, - instructionCount: number, - ): Promise { + async calculateXcmOverallWeight(transactCallWeight: Weight, instructionCount: number): Promise { const { xcm } = this.chainConfig; if (_.isUndefined(xcm)) throw new Error("chainConfig.xcm not set"); - const overallWeight = transactCallWeight.add( - xcm.instructionWeight.muln(instructionCount), - ); + const overallWeight = transactCallWeight.add(xcm.instructionWeight.muln(instructionCount)); return overallWeight; } @@ -109,13 +96,10 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { */ async weightToFee(weight: Weight, assetLocation: any): Promise { const [defaultAsset] = this.chainConfig.assets; - if (_.isUndefined(defaultAsset)) - throw new Error("chainConfig.defaultAsset not set"); + if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set"); const api = this.getApi(); if (_.isEqual(defaultAsset.location, assetLocation)) { - const fee = (await api.call.transactionPaymentApi.queryWeightToFee( - weight, - )) as u64; + const fee = (await api.call.transactionPaymentApi.queryWeightToFee(weight)) as u64; return fee; } const storageValue = await api.query.assetManager.assetTypeUnitsPerSecond({ @@ -159,11 +143,8 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { if (_.isUndefined(key)) throw new Error("chainConfig.key not set"); const [defaultAsset] = this.chainConfig.assets; - if (_.isUndefined(defaultAsset)) - throw new Error("chainConfig.defaultAsset not set"); - const currency = _.isEqual(feeLocation, defaultAsset.location) - ? { AsCurrencyId: "SelfReserve" } - : { AsMultiLocation: { V3: feeLocation } }; + if (_.isUndefined(defaultAsset)) throw new Error("chainConfig.defaultAsset not set"); + const currency = _.isEqual(feeLocation, defaultAsset.location) ? { AsCurrencyId: "SelfReserve" } : { AsMultiLocation: { V3: feeLocation } }; const extrinsic = this.getApi().tx.xcmTransactor.transactThroughSigned( { V3: destination }, { currency, feeAmount }, @@ -172,10 +153,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { false, ); - console.log( - `Send extrinsic from ${key} to schedule task. extrinsic:`, - extrinsic.method.toHex(), - ); + console.log(`Send extrinsic from ${key} to schedule task. extrinsic:`, extrinsic.method.toHex()); const result = await sendExtrinsic(api, extrinsic, keyringPair); return result; } @@ -221,9 +199,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { const { key } = this.chainConfig; if (_.isUndefined(key)) throw new Error("chainConfig.key not set"); - const transferAssetLocation = this.isNativeAsset(assetLocation) - ? convertAbsoluteLocationToRelative(assetLocation) - : assetLocation; + const transferAssetLocation = this.isNativeAsset(assetLocation) ? convertAbsoluteLocationToRelative(assetLocation) : assetLocation; const api = this.getApi(); const extrinsic = api.tx.xTokens.transferMultiasset( @@ -236,10 +212,7 @@ export class MoonbeamAdapter extends ChainAdapter implements TaskScheduler { { V3: { interior: { - X2: [ - destination.interior.X1, - { AccountId32: { id: recipient, network: null } }, - ], + X2: [destination.interior.X1, { AccountId32: { id: recipient, network: null } }], }, parents: 1, }, diff --git a/packages/adapter/src/chains/oak.ts b/packages/adapter/src/chains/oak.ts index 1ca5356..ec12f2c 100644 --- a/packages/adapter/src/chains/oak.ts +++ b/packages/adapter/src/chains/oak.ts @@ -14,6 +14,16 @@ import { AccountType, SendExtrinsicResult } from "../types"; import { WEIGHT_REF_TIME_PER_SECOND } from "../constants"; import { InvalidAddress } from "../errors"; +export interface AutomationPriceTriggerParams { + chain: string; + exchange: string; + asset1: string; + asset2: string; + submittedAt: number; + triggerFunction: "lt" | "gt"; + triggerParam: number[]; +} + export enum OakAdapterTransactType { PayThroughRemoteDerivativeAccount, PayThroughSoverignAccount, @@ -235,6 +245,53 @@ export class OakAdapter extends ChainAdapter { return result; } + /** + * Schedule XCMP task + * @param destination The location of the destination chain + * @param schedule Schedule setting + * @param scheduleFee Schedule fee + * @param executionFee Execution fee + * @param encodedCall Encoded call + * @param encodedCallWeight The encoded call weight weight of the XCM instructions + * @param overallWeight The overall weight of the XCM instructions + * @param keyringPair Operator's keyring pair + * @returns SendExtrinsicResult + */ + async scheduleXcmpPriceTask( + automationPriceTriggerParams: AutomationPriceTriggerParams, + destination: any, + scheduleFee: any, + executionFee: any, + encodedCall: HexString, + encodedCallWeight: Weight, + overallWeight: Weight, + keyringPair: KeyringPair, + ): Promise { + const api = this.getApi(); + const { key } = this.chainConfig; + if (_.isUndefined(key)) throw new Error("chainData.key not set"); + + const extrinsic = api.tx.automationPrice.scheduleXcmpTask( + automationPriceTriggerParams.chain, + automationPriceTriggerParams.exchange, + automationPriceTriggerParams.asset1, + automationPriceTriggerParams.asset2, + automationPriceTriggerParams.submittedAt, + automationPriceTriggerParams.triggerFunction, + automationPriceTriggerParams.triggerParam, + destination, + scheduleFee, + executionFee, + encodedCall, + encodedCallWeight, + overallWeight, + ); + + console.log(`Send extrinsic from ${key} to schedule price task. extrinsic:`, extrinsic.method.toHex()); + const result = await sendExtrinsic(api, extrinsic, keyringPair); + return result; + } + /** * Calculate the derivative account ID of a certain account ID * @param accountId diff --git a/packages/adapter/src/constants.ts b/packages/adapter/src/constants.ts index b0523e9..168c918 100644 --- a/packages/adapter/src/constants.ts +++ b/packages/adapter/src/constants.ts @@ -1,4 +1,5 @@ import BN from "bn.js"; +export const WEIGHT_REF_TIME_PER_NANOS = new BN(1000); export const WEIGHT_REF_TIME_PER_SECOND = new BN(1000000000000); export const WEIGHT_PROOF_SIZE_PER_MB = new BN(1024 * 1024); diff --git a/packages/adapter/src/errors.ts b/packages/adapter/src/errors.ts index fa314a5..0b6265c 100644 --- a/packages/adapter/src/errors.ts +++ b/packages/adapter/src/errors.ts @@ -1,77 +1,77 @@ /* eslint-disable max-classes-per-file */ export class RouterConfigNotFound extends Error { - constructor(token: string, destChain: string, network: string) { - super(); + constructor(token: string, destChain: string, network: string) { + super(); - this.message = `can't find ${token} to ${destChain} router in ${network} network`; - this.name = "RouterConfigNotFound"; - } + this.message = `can't find ${token} to ${destChain} router in ${network} network`; + this.name = "RouterConfigNotFound"; + } } export class AdapterNotFound extends Error { - constructor(network: string) { - super(); + constructor(network: string) { + super(); - this.message = `${network} adapter not find`; - this.name = "AdapterNotFound"; - } + this.message = `${network} adapter not find`; + this.name = "AdapterNotFound"; + } } export class ApiNotFound extends Error { - constructor(network: string) { - super(); + constructor(network: string) { + super(); - this.message = `Api not set for ${network} adapter`; - this.name = "ApiNotFound"; - } + this.message = `Api not set for ${network} adapter`; + this.name = "ApiNotFound"; + } } export class TokenNotFound extends Error { - constructor(token: string, network?: string) { - super(); + constructor(token: string, network?: string) { + super(); - if (network) { - this.message = `can't find ${token} in ${network}`; - } else { - this.message = `can't find ${token} in current network`; - } + if (network) { + this.message = `can't find ${token} in ${network}`; + } else { + this.message = `can't find ${token} in current network`; + } - this.name = "TokenNotFound"; - } + this.name = "TokenNotFound"; + } } export class NoCrossChainAdapterFound extends Error { - constructor(name: string) { - super(); + constructor(name: string) { + super(); - this.message = `Can't find ${name} adapter, please registed it first before use.`; - this.name = "NoCrossChainAdapterFound"; - } + this.message = `Can't find ${name} adapter, please registed it first before use.`; + this.name = "NoCrossChainAdapterFound"; + } } export class DestinationWeightNotFound extends Error { - constructor(source: string, destination: string, token: string) { - super(); + constructor(source: string, destination: string, token: string) { + super(); - this.message = `Can't find ${source} addapter's destination weight for ${destination} destination sending ${token} token.`; - this.name = "DestinationWeightNotFound"; - } + this.message = `Can't find ${source} addapter's destination weight for ${destination} destination sending ${token} token.`; + this.name = "DestinationWeightNotFound"; + } } export class InvalidAddress extends Error { - constructor(address: string) { - super(); + constructor(address: string) { + super(); - this.message = `Address ${address} is invalid.`; - this.name = "InvalidAddress"; - } + this.message = `Address ${address} is invalid.`; + this.name = "InvalidAddress"; + } } export class ModuleNotFound extends Error { - constructor(module: string) { - super(); + constructor(module: string) { + super(); - this.message = `${module} module not found`; - this.name = "ModuleNotFound"; - } + this.message = `${module} module not found`; + this.name = "ModuleNotFound"; + } } diff --git a/packages/config/src/tokens/dev.ts b/packages/config/src/tokens/dev.ts index e9ad6f4..df4c971 100644 --- a/packages/config/src/tokens/dev.ts +++ b/packages/config/src/tokens/dev.ts @@ -1,8 +1,40 @@ import { createToken } from "./types/Token"; -const tur = createToken({ key: "tur", symbol: "TUR", decimals: 10, network: "moonbase", parachainId: 2114 }); -const sby = createToken({ key: "shibuya", symbol: "SBY", decimals: 18, network: "moonbase", parachainId: 2000 }); -const moonbaseLocal = createToken({ key: "unit", symbol: "UNIT", decimals: 18, network: "moonbase", parachainId: 1000, palletInstance: 3 }); -const mgr = createToken({ key: "mgr", symbol: "MGR", decimals: 18, network: "mangata", parachainId: 2110 }); +const tur = createToken({ + decimals: 10, + key: "tur", + network: "moonbase", + parachainId: 2114, + symbol: "TUR", +}); +const sby = createToken({ + decimals: 18, + key: "shibuya", + network: "moonbase", + parachainId: 2000, + symbol: "SBY", +}); +const moonbaseLocal = createToken({ + decimals: 18, + interior: { palletInstance: 3 }, + key: "unit", + network: "moonbase", + parachainId: 1000, + symbol: "UNIT", +}); +const mgr = createToken({ + decimals: 18, + interior: { + GeneralKey: { + data: "0x0000000000000000000000000000000000000000000000000000000000000000", + length: 4, + }, + }, + key: "mgr", + network: "mangata", + parachainId: 2110, + symbol: "MGR", +}); -export default { tur, sby, moonbaseLocal, mgr }; +// eslint-disable-next-line import/no-default-export +export default { mgr, moonbaseLocal, sby, tur }; diff --git a/packages/config/src/tokens/index.ts b/packages/config/src/tokens/index.ts index 53b9ece..f1509e2 100644 --- a/packages/config/src/tokens/index.ts +++ b/packages/config/src/tokens/index.ts @@ -5,11 +5,4 @@ import RococoTokens from "./rococo"; import KusamaTokens from "./kusama"; import PolkadotTokens from "./polkadot"; -export { - XToken, - DevTokens, - MoonbaseTokens, - RococoTokens, - KusamaTokens, - PolkadotTokens, -}; +export { XToken, DevTokens, MoonbaseTokens, RococoTokens, KusamaTokens, PolkadotTokens }; diff --git a/packages/config/src/tokens/kusama.ts b/packages/config/src/tokens/kusama.ts index 23ba736..13ed086 100644 --- a/packages/config/src/tokens/kusama.ts +++ b/packages/config/src/tokens/kusama.ts @@ -1,12 +1,49 @@ import { createToken } from "./types/Token"; -const tur = createToken({ decimals: 10, key: "tur", network: "kusama", parachainId: 2114, symbol: "TUR" }); -const xcTur = createToken({ decimals: 10, key: "xcTur", network: "kusama", parachainId: 2114, symbol: "xcTUR" }); +const tur = createToken({ + decimals: 10, + key: "tur", + network: "kusama", + parachainId: 2114, + symbol: "TUR", +}); +const xcTur = createToken({ + decimals: 10, + key: "xcTur", + network: "kusama", + parachainId: 2114, + symbol: "xcTUR", +}); // TODO: movr is not defined in the original file; need to double check its value -const movr = createToken({ decimals: 18, key: "movr", network: "kusama", palletInstance: 10, parachainId: 2023, symbol: "MOVR" }); -const sdn = createToken({ decimals: 18, key: "shiden", network: "kusama", parachainId: 2007, symbol: "SDN" }); -const mgx = createToken({ decimals: 18, key: "mangata", network: "kusama", parachainId: 2110, symbol: "MGX" }); +const movr = createToken({ + decimals: 18, + interior: { palletInstance: 10 }, + key: "movr", + network: "kusama", + parachainId: 2023, + symbol: "MOVR", +}); +const sdn = createToken({ + decimals: 18, + key: "shiden", + network: "kusama", + parachainId: 2007, + symbol: "SDN", +}); +const mgx = createToken({ + decimals: 18, + interior: { + GeneralKey: { + data: "0x0000000000000000000000000000000000000000000000000000000000000000", + length: 4, + }, + }, + key: "mangata", + network: "kusama", + parachainId: 2110, + symbol: "MGX", +}); // eslint-disable-next-line import/no-default-export export default { mgx, movr, sdn, tur, xcTur }; diff --git a/packages/config/src/tokens/moonbase.ts b/packages/config/src/tokens/moonbase.ts index 76635ff..6e73e87 100644 --- a/packages/config/src/tokens/moonbase.ts +++ b/packages/config/src/tokens/moonbase.ts @@ -1,6 +1,21 @@ import { createToken } from "./types/Token"; -const tur = createToken({ key: "tur", symbol: "TUR", decimals: 10, network: "moonbase", parachainId: 2114 }); -const dev = createToken({ key: "dev", symbol: "DEV", decimals: 10, network: "moonbase", parachainId: 1000, palletInstance: 3 }); +const tur = createToken({ + decimals: 10, + key: "tur", + network: "moonbase", + parachainId: 2114, + symbol: "TUR", +}); -export default { tur, dev }; +const dev = createToken({ + decimals: 10, + interior: { palletInstance: 3 }, + key: "dev", + network: "moonbase", + parachainId: 1000, + symbol: "DEV", +}); + +// eslint-disable-next-line import/no-default-export +export default { dev, tur }; diff --git a/packages/config/src/tokens/polkadot.ts b/packages/config/src/tokens/polkadot.ts index 0988846..bf1693c 100644 --- a/packages/config/src/tokens/polkadot.ts +++ b/packages/config/src/tokens/polkadot.ts @@ -1,5 +1,13 @@ import { createToken } from "./types/Token"; -const glmr = createToken({ key: "glmr", symbol: "GLMR", decimals: 10, network: "kusama", parachainId: 2023, palletInstance: 10 }); +const glmr = createToken({ + decimals: 10, + interior: { palletInstance: 10 }, + key: "glmr", + network: "kusama", + parachainId: 2023, + symbol: "GLMR", +}); +// eslint-disable-next-line import/no-default-export export default { glmr }; diff --git a/packages/config/src/tokens/rococo.ts b/packages/config/src/tokens/rococo.ts index d3b15b3..a27c6b1 100644 --- a/packages/config/src/tokens/rococo.ts +++ b/packages/config/src/tokens/rococo.ts @@ -1,8 +1,33 @@ import { createToken } from "./types/Token"; // You can now create assets without repeating the same structure over and over. -const tur = createToken({ key: "tur", symbol: "TUR", decimals: 10, network: "rococo", parachainId: 2114 }); -const rstr = createToken({ key: "rocstar", symbol: "RSTR", decimals: 18, network: "rococo", parachainId: 2006 }); -const mgr = createToken({ key: "mangata-rococo", symbol: "MGR", decimals: 18, network: "rococo", parachainId: 2110 }); +const tur = createToken({ + decimals: 10, + key: "tur", + network: "rococo", + parachainId: 2114, + symbol: "TUR", +}); +const rstr = createToken({ + decimals: 18, + key: "rocstar", + network: "rococo", + parachainId: 2006, + symbol: "RSTR", +}); +const mgr = createToken({ + decimals: 18, + interior: { + GeneralKey: { + data: "0x0000000000000000000000000000000000000000000000000000000000000000", + length: 4, + }, + }, + key: "mangata-rococo", + network: "rococo", + parachainId: 2110, + symbol: "MGR", +}); -export default { tur, rstr, mgr }; +// eslint-disable-next-line import/no-default-export +export default { mgr, rstr, tur }; diff --git a/packages/config/src/tokens/types/Token.ts b/packages/config/src/tokens/types/Token.ts index f0f237b..653099b 100644 --- a/packages/config/src/tokens/types/Token.ts +++ b/packages/config/src/tokens/types/Token.ts @@ -2,60 +2,64 @@ * This file defines the original Tokens */ interface Location { - parents: number; - interior: Record; + parents: number; + interior: Record; } interface TokenConstructorParams { - key: string; - symbol: string; - decimals: number; - location: any; - network: string; + key: string; + symbol: string; + decimals: number; + location: any; + network: string; } class Token { - public key: string; - public symbol: string; - public decimals: number; - public location: any; // Consider using a more specific type. - public network: string; - - constructor(params: TokenConstructorParams) { - this.key = params.key; - this.symbol = params.symbol; - this.decimals = params.decimals; - this.location = params.location; - this.network = params.network; - } + public key: string; + + public symbol: string; + + public decimals: number; + + public location: any; // Consider using a more specific type. + + public network: string; + + constructor(params: TokenConstructorParams) { + this.key = params.key; + this.symbol = params.symbol; + this.decimals = params.decimals; + this.location = params.location; + this.network = params.network; } +} - /** Below defines createToken for simple creation of Token */ +/** Below defines createToken for simple creation of Token */ interface TokenParams { - key: string; - symbol: string; - decimals: number; - network: string; - parachainId: number; - palletInstance?: number; + key: string; + symbol: string; + decimals: number; + network: string; + parachainId: number; + interior?: any; } // Function to construct the 'location' object based on the parameters. -function constructLocation(parachainId: number, palletInstance?: number): Location { - let interior = palletInstance ? { X2: [{ Parachain: parachainId }, { PalletInstance: palletInstance }] } : { X1: { Parachain: parachainId } }; +function constructLocation(parachainId: number, interior?: any): Location { + const interiorObj = interior ? { X2: [{ Parachain: parachainId }, interior] } : { X1: { Parachain: parachainId } }; - return { - parents: 1, - interior, - }; + return { + interior: interiorObj, + parents: 1, + }; } // Simplify the asset creation function. function createToken(params: TokenParams): Token { - const { key, symbol, decimals, network, parachainId, palletInstance } = params; - const location = constructLocation(parachainId, palletInstance); + const { key, symbol, decimals, network, parachainId, interior } = params; + const location = constructLocation(parachainId, interior); - return new Token({key, symbol, decimals, location, network}); + return new Token({ decimals, key, location, network, symbol }); } export { createToken, Token, TokenConstructorParams }; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index f3c1cb6..360eee9 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -11,74 +11,29 @@ import { TaskSchedulerChainAdapter, SendExtrinsicResult, OakAdapterTransactType, + AutomationPriceTriggerParams, } from "@oak-network/adapter"; import { Weight } from "@oak-network/config"; -interface ScheduleXcmpTaskWithPayThroughSoverignAccountFlowParams { +interface ScheduleXcmpTaskParams { oakAdapter: OakAdapter; - destinationChainAdapter: ChainAdapter; - taskPayloadExtrinsic: SubmittableExtrinsic<"promise">; - schedule: any; - keyringPair: KeyringPair; - xcmOptions?: { - instructionCount?: number; - overallWeight?: Weight; - executionFeeAmount?: BN; - }; -} - -interface ScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams { - oakAdapter: OakAdapter; - destinationChainAdapter: TaskSchedulerChainAdapter; taskPayloadExtrinsic: SubmittableExtrinsic<"promise">; scheduleFeeLocation: any; executionFeeLocation: any; - schedule: any; - scheduleAs: HexString; - keyringPair: KeyringPair; xcmOptions?: { instructionCount?: number; overallWeight?: Weight; executionFeeAmount?: BN; }; + keyringPair: KeyringPair; } -interface AutomationPriceTriggerParams { - chain: string; - exchange: string; - asset1: string; - asset2: string; - submittedAt: number; - triggerFunction: "lt" | "gt"; - triggerParam: number[]; -} - -interface ScheduleXcmpPriceTaskWithPayThroughRemoteDerivativeAccountFlowParams { - oakAdapter: OakAdapter; - destinationChainAdapter: TaskSchedulerChainAdapter; - taskPayloadExtrinsic: SubmittableExtrinsic<"promise">; - scheduleFeeLocation: any; - executionFeeLocation: any; - automationPriceTriggerParams: AutomationPriceTriggerParams; - scheduleAs: HexString; - keyringPair: KeyringPair; +interface ScheduleXcmpTaskWithPayThroughSoverignAccountFlowParams extends ScheduleXcmpTaskParams { + destinationChainAdapter: ChainAdapter; } -interface CommonScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams { - oakAdapter: OakAdapter; +interface ScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams extends ScheduleXcmpTaskParams { destinationChainAdapter: TaskSchedulerChainAdapter; - taskPayloadExtrinsic: SubmittableExtrinsic<"promise">; - createTaskFunc: ( - params: CreateTaskFuncParams, - ) => SubmittableExtrinsic<"promise">; - scheduleFeeLocation: any; - executionFeeLocation: any; - keyringPair: KeyringPair; - xcmOptions?: { - instructionCount?: number; - overallWeight?: Weight; - executionFeeAmount?: BN; - }; } interface CreateTaskFuncParams { @@ -96,17 +51,11 @@ interface CreateTaskFuncParams { * @returns */ const scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow = async ( - params: CommonScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams, + params: ScheduleXcmpTaskParams, + destinationChainAdapter: TaskSchedulerChainAdapter, + createTaskFunc: (params: CreateTaskFuncParams) => SubmittableExtrinsic<"promise">, ): Promise => { - const { - oakAdapter, - destinationChainAdapter, - taskPayloadExtrinsic, - createTaskFunc, - executionFeeLocation, - keyringPair, - xcmOptions, - } = params; + const { oakAdapter, taskPayloadExtrinsic, executionFeeLocation, keyringPair, xcmOptions } = params; const [defaultAsset] = oakAdapter.getChainConfig().assets; if (_.isUndefined(defaultAsset)) { @@ -125,38 +74,20 @@ const scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow = async ( const destination = { V3: destinationChainAdapter.getLocation() }; const encodedCall = taskPayloadExtrinsic.method.toHex(); const oakTransactXcmInstructionCount = - xcmOptions?.instructionCount || - oakAdapter.getTransactXcmInstructionCount( - OakAdapterTransactType.PayThroughRemoteDerivativeAccount, - ); - const taskPayloadEncodedCallWeight = - await destinationChainAdapter.getExtrinsicWeight( - taskPayloadExtrinsic, - keyringPair, - ); + xcmOptions?.instructionCount || oakAdapter.getTransactXcmInstructionCount(OakAdapterTransactType.PayThroughRemoteDerivativeAccount); + const taskPayloadEncodedCallWeight = await destinationChainAdapter.getExtrinsicWeight(taskPayloadExtrinsic, keyringPair); const taskPayloadOverallWeight = xcmOptions?.overallWeight || - (await destinationChainAdapter.calculateXcmOverallWeight( - taskPayloadEncodedCallWeight, - oakTransactXcmInstructionCount, - )); + (await destinationChainAdapter.calculateXcmOverallWeight(taskPayloadEncodedCallWeight, oakTransactXcmInstructionCount)); const executionFeeAmout = - xcmOptions?.executionFeeAmount || - (await destinationChainAdapter.weightToFee( - taskPayloadOverallWeight, - executionFeeLocation, - )); + xcmOptions?.executionFeeAmount || (await destinationChainAdapter.weightToFee(taskPayloadOverallWeight, executionFeeLocation)); const executionFee = { amount: executionFeeAmout, assetLocation: { V3: executionFeeLocation }, }; // Calculate derive account on Turing/OAK - const deriveAccountId = oakAdapter.getDerivativeAccount( - u8aToHex(keyringPair.addressRaw), - paraId, - xcm.instructionNetworkType, - ); + const deriveAccountId = oakAdapter.getDerivativeAccount(u8aToHex(keyringPair.addressRaw), paraId, xcm.instructionNetworkType); // Create task extrinsic const taskExtrinsic = createTaskFunc({ @@ -170,31 +101,20 @@ const scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow = async ( // Schedule task through XCM const taskEncodedCall = taskExtrinsic.method.toHex(); - const destinationTransactXcmInstructionCount = - destinationChainAdapter.getTransactXcmInstructionCount(); - const taskEncodedCallWeight = await oakAdapter.getExtrinsicWeight( - taskExtrinsic, - deriveAccountId, - ); - const taskOverallWeight = await oakAdapter.calculateXcmOverallWeight( + const destinationTransactXcmInstructionCount = destinationChainAdapter.getTransactXcmInstructionCount(); + const taskEncodedCallWeight = await oakAdapter.getExtrinsicWeight(taskExtrinsic, deriveAccountId); + const taskOverallWeight = await oakAdapter.calculateXcmOverallWeight(taskEncodedCallWeight, destinationTransactXcmInstructionCount); + const taskExecutionFee = await oakAdapter.weightToFee(taskOverallWeight, executionFeeLocation); + const oakLocation = oakAdapter.getLocation(); + const sendExtrinsicResult = await destinationChainAdapter.scheduleTaskThroughXcm( + oakLocation, + taskEncodedCall, + executionFeeLocation, + taskExecutionFee, taskEncodedCallWeight, - destinationTransactXcmInstructionCount, - ); - const taskExecutionFee = await oakAdapter.weightToFee( taskOverallWeight, - executionFeeLocation, + keyringPair, ); - const oakLocation = oakAdapter.getLocation(); - const sendExtrinsicResult = - await destinationChainAdapter.scheduleTaskThroughXcm( - oakLocation, - taskEncodedCall, - executionFeeLocation, - taskExecutionFee, - taskEncodedCallWeight, - taskOverallWeight, - keyringPair, - ); return sendExtrinsicResult; }; @@ -206,58 +126,85 @@ export function Sdk() { * @returns */ scheduleXcmpPriceTaskWithPayThroughRemoteDerivativeAccountFlow: async ( - params: ScheduleXcmpPriceTaskWithPayThroughRemoteDerivativeAccountFlowParams, + params: ScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams, + automationPriceTriggerParams: AutomationPriceTriggerParams, ): Promise => { - const { - oakAdapter, - destinationChainAdapter, - taskPayloadExtrinsic, - scheduleFeeLocation, - executionFeeLocation, - automationPriceTriggerParams, - scheduleAs, - keyringPair, - } = params; - const createTaskFunc = ( - funcParams: CreateTaskFuncParams, - ): SubmittableExtrinsic<"promise"> => { - const { - oakApi, + const { oakAdapter, destinationChainAdapter, taskPayloadExtrinsic, scheduleFeeLocation, executionFeeLocation, keyringPair, xcmOptions } = + params; + const createTaskFunc = (funcParams: CreateTaskFuncParams): SubmittableExtrinsic<"promise"> => { + const { oakApi, destination, executionFee, encodedCall, encodedCallWeight, overallWeight } = funcParams; + const taskExtrinsic = oakApi.tx.automationPrice.scheduleXcmpTaskThroughProxy( + automationPriceTriggerParams.chain, + automationPriceTriggerParams.exchange, + automationPriceTriggerParams.asset1, + automationPriceTriggerParams.asset2, + automationPriceTriggerParams.submittedAt, + automationPriceTriggerParams.triggerFunction, + automationPriceTriggerParams.triggerParam, destination, + { V3: scheduleFeeLocation }, executionFee, encodedCall, encodedCallWeight, overallWeight, - } = funcParams; - const taskExtrinsic = - oakApi.tx.automationPrice.scheduleXcmpTaskThroughProxy( - automationPriceTriggerParams.chain, - automationPriceTriggerParams.exchange, - automationPriceTriggerParams.asset1, - automationPriceTriggerParams.asset2, - automationPriceTriggerParams.submittedAt, - automationPriceTriggerParams.triggerFunction, - automationPriceTriggerParams.triggerParam, - destination, - { V3: scheduleFeeLocation }, - executionFee, - encodedCall, - encodedCallWeight, - overallWeight, - scheduleAs, - ); + u8aToHex(keyringPair.addressRaw), + ); return taskExtrinsic; }; - const sendExtrinsicResult = - scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow({ - createTaskFunc, - destinationChainAdapter, + const sendExtrinsicResult = scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow( + { executionFeeLocation, keyringPair, oakAdapter, scheduleFeeLocation, taskPayloadExtrinsic, - }); + xcmOptions, + }, + destinationChainAdapter, + createTaskFunc, + ); + return sendExtrinsicResult; + }, + + scheduleXcmpPriceTaskWithPayThroughSoverignAccountFlow: async ( + params: ScheduleXcmpTaskWithPayThroughSoverignAccountFlowParams, + automationPriceTriggerParams: AutomationPriceTriggerParams, + ): Promise => { + const { oakAdapter, destinationChainAdapter, taskPayloadExtrinsic, scheduleFeeLocation, executionFeeLocation, keyringPair, xcmOptions } = + params; + const [defaultAsset] = oakAdapter.getChainConfig().assets; + if (_.isUndefined(defaultAsset)) { + throw new Error("chainConfig.defaultAsset not set"); + } + + // Caluculate weight and fee for task + const destination = { V3: destinationChainAdapter.getLocation() }; + const encodedCall = taskPayloadExtrinsic.method.toHex(); + const oakTransactXcmInstructionCount = + xcmOptions?.instructionCount || oakAdapter.getTransactXcmInstructionCount(OakAdapterTransactType.PayThroughSoverignAccount); + const taskPayloadEncodedCallWeight = await destinationChainAdapter.getExtrinsicWeight(taskPayloadExtrinsic, keyringPair); + const taskPayloadOverallWeight = + xcmOptions?.overallWeight || + (await destinationChainAdapter.calculateXcmOverallWeight(taskPayloadEncodedCallWeight, oakTransactXcmInstructionCount)); + const executionFeeAmout = + xcmOptions?.executionFeeAmount || (await destinationChainAdapter.weightToFee(taskPayloadOverallWeight, executionFeeLocation)); + const executionFee = { + amount: executionFeeAmout, + assetLocation: { V3: executionFeeLocation }, + }; + + // Schedule XCMP task + const sendExtrinsicResult = oakAdapter.scheduleXcmpPriceTask( + automationPriceTriggerParams, + destination, + { V3: scheduleFeeLocation }, + executionFee, + encodedCall, + taskPayloadEncodedCallWeight, + taskPayloadOverallWeight, + keyringPair, + ); + return sendExtrinsicResult; }, @@ -266,54 +213,39 @@ export function Sdk() { * @param params Operation params * @returns */ - scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow: async ( - params: ScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams, + scheduleXcmpTimeTaskWithPayThroughRemoteDerivativeAccountFlow: async ( + scheduleXcmpTaskParams: ScheduleXcmpTaskParams, + destinationChainAdapter: TaskSchedulerChainAdapter, + schedule: any, ): Promise => { - const { - oakAdapter, - destinationChainAdapter, - taskPayloadExtrinsic, - scheduleFeeLocation, - executionFeeLocation, - schedule, - scheduleAs, - keyringPair, - } = params; - const createTaskFunc = ( - funcParams: CreateTaskFuncParams, - ): SubmittableExtrinsic<"promise"> => { - const { - oakApi, + const { oakAdapter, taskPayloadExtrinsic, scheduleFeeLocation, executionFeeLocation, keyringPair, xcmOptions } = scheduleXcmpTaskParams; + const createTaskFunc = (funcParams: CreateTaskFuncParams): SubmittableExtrinsic<"promise"> => { + const { oakApi, destination, executionFee, encodedCall, encodedCallWeight, overallWeight } = funcParams; + console.log("scheduleFeeLocation: ", scheduleFeeLocation); + const taskExtrinsic = oakApi.tx.automationTime.scheduleXcmpTaskThroughProxy( + schedule, destination, + { V3: scheduleFeeLocation }, executionFee, encodedCall, encodedCallWeight, overallWeight, - } = funcParams; - console.log("scheduleFeeLocation: ", scheduleFeeLocation); - const taskExtrinsic = - oakApi.tx.automationTime.scheduleXcmpTaskThroughProxy( - schedule, - destination, - { V3: scheduleFeeLocation }, - executionFee, - encodedCall, - encodedCallWeight, - overallWeight, - scheduleAs, - ); + u8aToHex(keyringPair.addressRaw), + ); return taskExtrinsic; }; - const sendExtrinsicResult = - scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow({ - createTaskFunc, - destinationChainAdapter, + const sendExtrinsicResult = scheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlow( + { executionFeeLocation, keyringPair, oakAdapter, scheduleFeeLocation, taskPayloadExtrinsic, - }); + xcmOptions, + }, + destinationChainAdapter, + createTaskFunc, + ); return sendExtrinsicResult; }, @@ -322,58 +254,38 @@ export function Sdk() { * @param params Operation params * @returns */ - scheduleXcmpTaskWithPayThroughSoverignAccountFlow: async ( - params: ScheduleXcmpTaskWithPayThroughSoverignAccountFlowParams, + scheduleXcmpTimeTaskWithPayThroughSoverignAccountFlow: async ( + scheduleXcmpTaskParams: ScheduleXcmpTaskWithPayThroughRemoteDerivativeAccountFlowParams, + schedule: any, ): Promise => { - const { - oakAdapter, - destinationChainAdapter, - taskPayloadExtrinsic, - schedule, - keyringPair, - xcmOptions, - } = params; + const { oakAdapter, destinationChainAdapter, taskPayloadExtrinsic, scheduleFeeLocation, executionFeeLocation, keyringPair, xcmOptions } = + scheduleXcmpTaskParams; const [defaultAsset] = oakAdapter.getChainConfig().assets; if (_.isUndefined(defaultAsset)) { - throw new Error("chainConfig.defaultAsset not set"); + throw new Error("chainData.defaultAsset not set"); } // Caluculate weight and fee for task const destination = { V3: destinationChainAdapter.getLocation() }; const encodedCall = taskPayloadExtrinsic.method.toHex(); const oakTransactXcmInstructionCount = - xcmOptions?.instructionCount || - oakAdapter.getTransactXcmInstructionCount( - OakAdapterTransactType.PayThroughSoverignAccount, - ); - const taskPayloadEncodedCallWeight = - await destinationChainAdapter.getExtrinsicWeight( - taskPayloadExtrinsic, - keyringPair, - ); + xcmOptions?.instructionCount || oakAdapter.getTransactXcmInstructionCount(OakAdapterTransactType.PayThroughSoverignAccount); + const taskPayloadEncodedCallWeight = await destinationChainAdapter.getExtrinsicWeight(taskPayloadExtrinsic, keyringPair); const taskPayloadOverallWeight = xcmOptions?.overallWeight || - (await destinationChainAdapter.calculateXcmOverallWeight( - taskPayloadEncodedCallWeight, - oakTransactXcmInstructionCount, - )); - const scheduleFee = { V3: defaultAsset.location }; + (await destinationChainAdapter.calculateXcmOverallWeight(taskPayloadEncodedCallWeight, oakTransactXcmInstructionCount)); const executionFeeAmout = - xcmOptions?.executionFeeAmount || - (await destinationChainAdapter.weightToFee( - taskPayloadOverallWeight, - defaultAsset.location, - )); + xcmOptions?.executionFeeAmount || (await destinationChainAdapter.weightToFee(taskPayloadOverallWeight, executionFeeLocation)); const executionFee = { amount: executionFeeAmout, - assetLocation: { V3: defaultAsset.location }, + assetLocation: { V3: executionFeeLocation }, }; // Schedule XCMP task const sendExtrinsicResult = oakAdapter.scheduleXcmpTask( destination, schedule, - scheduleFee, + { V3: scheduleFeeLocation }, executionFee, encodedCall, taskPayloadEncodedCallWeight,