From 84343d3fae71c5d27658ffe80b80eed402f96237 Mon Sep 17 00:00:00 2001 From: vovunku Date: Wed, 3 Jan 2024 09:43:32 +0100 Subject: [PATCH 01/22] added base implementation for dock indexer using polkadex --- chainTypes/dockChaintypes.ts | 5 +++ dock.yaml | 64 ++++++++++++++++++++++++++++++++++++ package.json | 2 ++ yarn.lock | 5 +++ 4 files changed, 76 insertions(+) create mode 100644 chainTypes/dockChaintypes.ts create mode 100644 dock.yaml diff --git a/chainTypes/dockChaintypes.ts b/chainTypes/dockChaintypes.ts new file mode 100644 index 00000000..85ddb3fc --- /dev/null +++ b/chainTypes/dockChaintypes.ts @@ -0,0 +1,5 @@ +// Adapted from https://github.com/polkadot-js/apps/blob/master/packages/apps-config/src/api/spec/dock-mainnet.ts + +import { spec } from '@docknetwork/node-types'; + +export default { typesBundle: { spec: spec } }; \ No newline at end of file diff --git a/dock.yaml b/dock.yaml new file mode 100644 index 00000000..7b80b73e --- /dev/null +++ b/dock.yaml @@ -0,0 +1,64 @@ +specVersion: 1.0.0 +name: subquery-nova-dock +version: 1.0.0 +runner: + node: + name: '@subql/node' + version: '*' + query: + name: '@subql/query' + version: v1.5.0 +description: Nova SubQuery project +repository: https://github.com/nova-wallet/subquery-nova +schema: + file: ./schema.graphql +network: + chainId: '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae' + endpoint: >- + wss://mainnet-node.dock.io + chaintypes: + file: ./dist/dockChaintypes.js +dataSources: + - name: main + kind: substrate/Runtime + startBlock: 12885 + mapping: + file: ./dist/index.js + handlers: + - handler: handleHistoryElement + kind: substrate/CallHandler + - handler: handleReward + kind: substrate/EventHandler + filter: + module: staking + method: Reward + - handler: handleRewarded + kind: substrate/EventHandler + filter: + module: staking + method: Rewarded + - handler: handleSlash + kind: substrate/EventHandler + filter: + module: staking + method: Slash + - handler: handleSlashed + kind: substrate/EventHandler + filter: + module: staking + method: Slashed + - handler: handleTransfer + kind: substrate/EventHandler + filter: + module: balances + method: Transfer + - handler: handleNewEra + kind: substrate/EventHandler + filter: + module: staking + method: StakingElection + - handler: handleStakersElected + kind: substrate/EventHandler + filter: + module: staking + method: StakersElected diff --git a/package.json b/package.json index 8ca79f68..2f557dad 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "devDependencies": { "@acala-network/type-definitions": "^4.1.5", "@crustio/type-definitions": "^1.3.0", + "@docknetwork/node-types": "0.16.0", "@equilab/definitions": "^1.4.18", "@interlay/interbtc-types": "^1.5.10", "@kiltprotocol/type-definitions": "^0.1.23", @@ -53,6 +54,7 @@ "alephZeroChaintypes": "./chainTypes/alephZeroChaintypes.ts", "basiliskChaintypes": "./chainTypes/basiliskChaintypes.ts", "centrifugeChaintypes": "./chainTypes/centrifugeChaintypes.ts", + "dockChaintypes": "./chainTypes/dockChaintypes.ts", "encointerChaintypes": "./chainTypes/encointerChaintypes.ts", "frequencyChaintypes": "./chainTypes/frequencyChaintypes.ts", "krestChaintypes": "./chainTypes/krestChaintypes.ts", diff --git a/yarn.lock b/yarn.lock index 7467e70f..250aa6b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -486,6 +486,11 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@docknetwork/node-types@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@docknetwork/node-types/-/node-types-0.16.0.tgz#23570042c823a6320654ee2c5b8c0da5d7c43d21" + integrity sha512-VUZB8guX9161hDIEVn/UKJEUlXjIDE6vH5flx6uDHVc0QOhBy1bq6AGLayG4ZH19dCN39ta2sKGIFq9wLO4H2A== + "@equilab/definitions@^1.4.18": version "1.4.18" resolved "https://registry.yarnpkg.com/@equilab/definitions/-/definitions-1.4.18.tgz#e544951b50278705af3d9fa4ba91e04df53a3d06" From 12afc00107ffe4a3a054b72212a331154ff4b07d Mon Sep 17 00:00:00 2001 From: vovunku Date: Mon, 29 Jan 2024 16:24:19 +0100 Subject: [PATCH 02/22] added manta project using polimec as base --- ipfs-cids/.manta-cid | 1 + manta.yaml | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 ipfs-cids/.manta-cid create mode 100644 manta.yaml diff --git a/ipfs-cids/.manta-cid b/ipfs-cids/.manta-cid new file mode 100644 index 00000000..43b80565 --- /dev/null +++ b/ipfs-cids/.manta-cid @@ -0,0 +1 @@ +QmatFmxu7ZALVnasojm1zqV1xTQeiT9RDAvngC2mAprewV \ No newline at end of file diff --git a/manta.yaml b/manta.yaml new file mode 100644 index 00000000..a0c69b8d --- /dev/null +++ b/manta.yaml @@ -0,0 +1,41 @@ +specVersion: 1.0.0 +name: subquery-nova-manta +version: 1.0.0 +runner: + node: + name: '@subql/node' + version: '*' + query: + name: '@subql/query' + version: v1.5.0 +description: Nova SubQuery project +repository: https://github.com/nova-wallet/subquery-nova +schema: + file: ./schema.graphql +network: + chainId: '0xf3c7ad88f6a80f366c4be216691411ef0622e8b809b1046ea297ef106058d4eb' + endpoint: wss://ws.manta.systems +dataSources: + - name: main + kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - handler: handleHistoryElement + kind: substrate/CallHandler + - handler: handleParachainRewarded + kind: substrate/EventHandler + filter: + module: parachainStaking + method: Rewarded + - handler: handleTransfer + kind: substrate/EventHandler + filter: + module: balances + method: Transfer + - handler: handleAssetTransfer + kind: substrate/EventHandler + filter: + module: assets + method: Transferred From fbd3d9b4d59bf7b6c693bcd80f84cdadbfce3e3e Mon Sep 17 00:00:00 2001 From: valentun Date: Tue, 30 Jan 2024 13:09:52 +0300 Subject: [PATCH 03/22] Hydra swaps --- hydra.yaml | 19 +++-- rococo-assethub.yaml | 2 +- src/index.ts | 1 + src/mappings/HistoryElements.ts | 97 ++++++++++++++++++----- src/mappings/Transfers.ts | 62 +-------------- src/mappings/common.ts | 32 ++++++++ src/mappings/swaps/AssetConversion.ts | 72 +++++++++++++++++ src/mappings/swaps/HydraDx.ts | 106 ++++++++++++++++++++++++++ src/mappings/swaps/index.ts | 4 + statemine.yaml | 2 +- westmint.yaml | 2 +- 11 files changed, 310 insertions(+), 89 deletions(-) create mode 100644 src/mappings/swaps/AssetConversion.ts create mode 100644 src/mappings/swaps/HydraDx.ts create mode 100644 src/mappings/swaps/index.ts diff --git a/hydra.yaml b/hydra.yaml index 4904e9ef..c2bc1dcc 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -14,21 +14,16 @@ schema: file: ./schema.graphql network: chainId: '0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d' - endpoint: wss://rpc-01.hydradx.io + endpoint: wss://rpc.hydradx.cloud dataSources: - name: main kind: substrate/Runtime - startBlock: 1 + startBlock: 4361342 mapping: file: ./dist/index.js handlers: - handler: handleHistoryElement kind: substrate/CallHandler - - handler: handleParachainRewarded - kind: substrate/EventHandler - filter: - module: parachainStaking - method: Rewarded - handler: handleTransfer kind: substrate/EventHandler filter: @@ -49,3 +44,13 @@ dataSources: filter: module: tokens method: Transfer + - handler: handleOmnipoolSwap + kind: substrate/EventHandler + filter: + module: omnipool + method: SellExecuted + - handler: handleOmnipoolSwap + kind: substrate/EventHandler + filter: + module: omnipool + method: BuyExecuted diff --git a/rococo-assethub.yaml b/rococo-assethub.yaml index 57f83e3b..16a8ed8e 100644 --- a/rococo-assethub.yaml +++ b/rococo-assethub.yaml @@ -52,7 +52,7 @@ dataSources: filter: module: tokens method: Transfer - - handler: handleSwap + - handler: handleAssetConversionSwap kind: substrate/EventHandler filter: module: assetConversion diff --git a/src/index.ts b/src/index.ts index 13ba516e..99951a76 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,4 +4,5 @@ export * from './mappings/Rewards' export * from './mappings/PoolRewards' export * from './mappings/Transfers' export * from './mappings/NewEra' +export * from './mappings/swaps' import "@polkadot/api-augment" \ No newline at end of file diff --git a/src/mappings/HistoryElements.ts b/src/mappings/HistoryElements.ts index 3a5806d0..73c76f7b 100644 --- a/src/mappings/HistoryElements.ts +++ b/src/mappings/HistoryElements.ts @@ -19,14 +19,17 @@ import { isNativeTransferAll, isOrmlTransferAll, isEvmTransaction, - isEvmExecutedEvent, + isEvmExecutedEvent, isAssetTxFeePaidEvent, - isEquilibriumTransfer, + isEquilibriumTransfer, isHydraDxBuy, isHydraDxSell, } from "./common"; import {CallBase} from "@polkadot/types/types/calls"; import {AnyTuple} from "@polkadot/types/types/codec"; import {u64} from "@polkadot/types"; import { ethereumEncode } from '@polkadot/util-crypto'; +import {u128, u32} from "@polkadot/types-codec"; +import {convertHydraDxTokenIdToString, findHydraDxFeeTyped} from "./swaps"; +import {Codec} from "@polkadot/types/types"; type TransferData = { isTransferAll: boolean, @@ -162,17 +165,18 @@ function findFailedTransferCalls(extrinsic: SubstrateExtrinsic): Array isAssetTxFeePaidEvent(eventRecordToSubstrateEvent(e))); - if (foundAssetTxFeePaid !== undefined) { - const [who, actual_fee, tip, rawAssetIdFee] = getEventData(eventRecordToSubstrateEvent(foundAssetTxFeePaid)) - if ('interior' in rawAssetIdFee) { - assetIdFee = getAssetIdFromMultilocation(rawAssetIdFee) - fee = actual_fee.toString(); + const assetHubSwapCallback = (path, amountIn, amountOut, receiver) => { + let assetIdFee = "native" + let fee = calculateFeeAsString(extrinsic) + let foundAssetTxFeePaid = extrinsic.block.events.find((e) => isAssetTxFeePaidEvent(eventRecordToSubstrateEvent(e))); + if (foundAssetTxFeePaid !== undefined) { + const [who, actual_fee, tip, rawAssetIdFee] = getEventData(eventRecordToSubstrateEvent(foundAssetTxFeePaid)) + if ('interior' in rawAssetIdFee) { + assetIdFee = getAssetIdFromMultilocation(rawAssetIdFee) + fee = actual_fee.toString(); + } } - } - const swapCallback = (path, amountIn, amountOut, receiver) => { + const assetIdIn = getAssetIdFromMultilocation(path[0], true) const assetIdOut = getAssetIdFromMultilocation(path[path["length"] - 1], true) @@ -199,7 +203,32 @@ function findFailedTransferCalls(extrinsic: SubstrateExtrinsic): Array { + let fee = findHydraDxFeeTyped(extrinsic.events) + + const assetIdIn = convertHydraDxTokenIdToString(assetIn) + const assetIdOut = convertHydraDxTokenIdToString(assetOut) + + const swap: Swap = { + assetIdIn: assetIdIn, + amountIn: amountIn.toString(), + assetIdOut: assetIdOut, + amountOut: amountOut.toString(), + sender: sender.toString(), + receiver: sender.toString(), + assetIdFee: fee.tokenId, + fee: fee.amount, + eventIdx: -1, + success: false + } + + return { + isTransferAll: false, + transfer: swap, + } + } + + let transferCalls = determineTransferCallsArgs(extrinsic.extrinsic.method, transferCallback, assetHubSwapCallback, hydraDxSwapCallback) if (transferCalls.length == 0) { return null; } @@ -207,7 +236,12 @@ function findFailedTransferCalls(extrinsic: SubstrateExtrinsic): Array, transferCallback, swapCallback) : Array { +function determineTransferCallsArgs( + causeCall: CallBase, + transferCallback, + assetHubSwapCallback, + hydraDxSwapCallback +) : Array { if (isNativeTransfer(causeCall)) { return transferCallback(false, ...extractArgsFromTransfer(causeCall)) } else if (isAssetTransfer(causeCall)) { @@ -221,13 +255,17 @@ function determineTransferCallsArgs(causeCall: CallBase, transferCallb } else if (isOrmlTransferAll(causeCall)) { return transferCallback(true, ...extractArgsFromOrmlTransferAll(causeCall)) } else if (isSwapExactTokensForTokens(causeCall)) { - return swapCallback(...extractArgsFromSwapExactTokensForTokens(causeCall)) + return assetHubSwapCallback(...extractArgsFromSwapExactTokensForTokens(causeCall)) } else if (isSwapTokensForExactTokens(causeCall)) { - return swapCallback(...extractArgsFromSwapTokensForExactTokens(causeCall)) + return assetHubSwapCallback(...extractArgsFromSwapTokensForExactTokens(causeCall)) + } else if (isHydraDxBuy(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraDxBuy(causeCall))] + } else if (isHydraDxSell(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraDxSell(causeCall))] } else if (isBatch(causeCall)) { return callsFromBatch(causeCall) .map(call => { - return determineTransferCallsArgs(call, transferCallback, swapCallback) + return determineTransferCallsArgs(call, transferCallback, assetHubSwapCallback, hydraDxSwapCallback) .map((value, index, array) => { return value }) @@ -235,7 +273,7 @@ function determineTransferCallsArgs(causeCall: CallBase, transferCallb .flat() } else if (isProxy(causeCall)) { let proxyCall = callFromProxy(causeCall) - return determineTransferCallsArgs(proxyCall, transferCallback, swapCallback) + return determineTransferCallsArgs(proxyCall, transferCallback, assetHubSwapCallback, hydraDxSwapCallback) } else { return [] } @@ -314,3 +352,26 @@ function extractArgsFromSwapTokensForExactTokens(call: CallBase) { receiver ] } + +function extractArgsFromHydraDxSell(call: CallBase): Codec[] { + const [assetIn, assetOut, amount, minBuyAmount, _] = call.args + + return [ + assetIn, + assetOut, + amount, // amountIn + minBuyAmount // amountOut + ] +} + + +function extractArgsFromHydraDxBuy(call: CallBase): Codec[] { + const [assetOut, assetIn, amount, maxSellAmount, _] = call.args + + return [ + assetIn, + assetOut, + maxSellAmount, // amountIn + amount // amountOut + ] +} \ No newline at end of file diff --git a/src/mappings/Transfers.ts b/src/mappings/Transfers.ts index 9d31ebdd..fcd7be90 100644 --- a/src/mappings/Transfers.ts +++ b/src/mappings/Transfers.ts @@ -27,66 +27,6 @@ type TransferPayload = { assetId?: string; }; -export async function handleSwap(event: SubstrateEvent): Promise { - const [from, to, path, amountIn, amountOut] = getEventData(event); - - let element = await HistoryElement.get(`${eventId(event)}-from`) - - if (element !== undefined) { - // already processed swap previously - return; - } - - let assetIdFee: string - let fee: string - let foundAssetTxFeePaid = event.block.events.find((e) => isAssetTxFeePaidEvent(eventRecordToSubstrateEvent(e))); - let swaps = event.block.events.filter((e) => isSwapExecutedEvent(eventRecordToSubstrateEvent(e))); - if (foundAssetTxFeePaid === undefined) { - assetIdFee = "native" - fee = calculateFeeAsString(event.extrinsic, from.toString()) - } else { - const [who, actualFee, tip, rawAssetIdFee] = getEventData(eventRecordToSubstrateEvent(foundAssetTxFeePaid)) - assetIdFee = getAssetIdFromMultilocation(rawAssetIdFee) - fee = actualFee.toString() - - let { event: { data: [feeFrom, feeTo, feePath, feeAmountIn, feeAmountOut] } } = swaps[0] - - swaps = swaps.slice(1) - if (BigIntFromCodec(actualFee) != BigIntFromCodec(feeAmountIn)) { - let { event: { data: [refundFrom, refundTo, refundPath, refundAmountIn, refundAmountOut] } } = swaps[swaps.length - 1] - - if (BigIntFromCodec(feeAmountIn) == BigIntFromCodec(actualFee) + BigIntFromCodec(refundAmountOut) && - getAssetIdFromMultilocation(feePath[0]) == getAssetIdFromMultilocation(refundPath[refundPath["length"] - 1])) { - swaps = swaps.slice(swaps.length - 1) - // TODO: if fee splitted, than we will process the same block two times - } - } - } - await Promise.all(swaps.map((e) => processSwap(eventRecordToSubstrateEvent(e), assetIdFee, fee))) -} - -async function processSwap(event: SubstrateEvent, assetIdFee: string, fee: string): Promise { - const [from, to, path, amountIn, amountOut] = getEventData(event) - - const swap = { - assetIdIn: getAssetIdFromMultilocation(path[0]), - amountIn: amountIn.toString(), - assetIdOut: getAssetIdFromMultilocation(path[path["length"] - 1]), - amountOut: amountOut.toString(), - sender: from.toString(), - receiver: to.toString(), - assetIdFee: assetIdFee, - fee: fee, - eventIdx: event.idx, - success: true - } - - await createAssetTransmission(event, from.toString(), "-from", {"swap": swap}); - if (from.toString() != to.toString()) { - await createAssetTransmission(event, to.toString(), "-to", {"swap": swap}); - } -} - export async function handleTransfer(event: SubstrateEvent): Promise { const [from, to, amount] = getEventData(event); @@ -221,7 +161,7 @@ async function createTransfer({ await createAssetTransmission(event, address, suffix, data); } -async function createAssetTransmission( +export async function createAssetTransmission( event, address, suffix, diff --git a/src/mappings/common.ts b/src/mappings/common.ts index 80f64e6b..54d17136 100644 --- a/src/mappings/common.ts +++ b/src/mappings/common.ts @@ -6,9 +6,11 @@ import {AnyTuple} from "@polkadot/types/types/codec"; import { Vec, GenericEventData } from '@polkadot/types'; import {Codec} from "@polkadot/types/types"; import {INumber} from "@polkadot/types-codec/types/interfaces"; +import * as events from "events"; const batchCalls = ["batch", "batchAll", "forceBatch"] const transferCalls = ["transfer", "transferKeepAlive"] + const ormlSections = ["currencies", "tokens"] export function distinct(array: Array): Array { @@ -50,6 +52,10 @@ export function isAssetTxFeePaidEvent(event: SubstrateEvent): boolean { return event.event.section === 'assetTxPayment' && event.event.method === "AssetTxFeePaid" } +export function isCurrencyDepositedEvent(event: SubstrateEvent): boolean { + return event.event.section === 'currencies' && event.event.method === "Deposited" +} + export function isSwapExecutedEvent(event: SubstrateEvent): boolean { return event.event.section === 'assetConversion' && event.event.method === "SwapExecuted" } @@ -62,6 +68,14 @@ export function isSwapTokensForExactTokens(call: CallBase) : boolean { return call.section === "assetConversion" && call.method === "swapTokensForExactTokens" } +export function isHydraDxBuy(call: CallBase) : boolean { + return call.section === "omnipool" && call.method == "buy" +} + +export function isHydraDxSell(call: CallBase) : boolean { + return call.section === "omnipool" && call.method == "sell" +} + export function isOrmlTransfer(call: CallBase) : boolean { return ormlSections.includes(call.section) && transferCalls.includes(call.method) } @@ -215,6 +229,24 @@ function exportFeeFromTransactionFeePaidEvent(extrinsic: SubstrateExtrinsic, fro return undefined } +export function extractTransactionPaidFee(events: EventRecord[]): string | undefined { + const eventRecord = events.find((event) => + event.event.method == "TransactionFeePaid" && event.event.section == "transactionPayment" + ) + + if (eventRecord == undefined) return undefined + + const { + event: { + data: [ _, fee, tip ] + } + } = eventRecord + + const fullFee = (fee as Balance).toBigInt() + (tip as Balance).toBigInt() + + return fullFee.toString() +} + function exportFeeFromBalancesDepositEvent(extrinsic: SubstrateExtrinsic): bigint { const eventRecord = extrinsic.events.find((event) => { return event.event.method == "Deposit" && event.event.section == "balances" diff --git a/src/mappings/swaps/AssetConversion.ts b/src/mappings/swaps/AssetConversion.ts new file mode 100644 index 00000000..eb99ea85 --- /dev/null +++ b/src/mappings/swaps/AssetConversion.ts @@ -0,0 +1,72 @@ +import {SubstrateEvent} from "@subql/types"; +import { + BigIntFromCodec, + calculateFeeAsString, + eventId, + eventRecordToSubstrateEvent, getAssetIdFromMultilocation, + getEventData, + isAssetTxFeePaidEvent, + isSwapExecutedEvent +} from "../common"; +import {HistoryElement} from "../../types"; +import {createAssetTransmission} from "../Transfers"; + +export async function handleAssetConversionSwap(event: SubstrateEvent): Promise { + const [from, to, path, amountIn, amountOut] = getEventData(event); + + let element = await HistoryElement.get(`${eventId(event)}-from`) + + if (element !== undefined) { + // already processed swap previously + return; + } + + let assetIdFee: string + let fee: string + let foundAssetTxFeePaid = event.block.events.find((e) => isAssetTxFeePaidEvent(eventRecordToSubstrateEvent(e))); + let swaps = event.block.events.filter((e) => isSwapExecutedEvent(eventRecordToSubstrateEvent(e))); + if (foundAssetTxFeePaid === undefined) { + assetIdFee = "native" + fee = calculateFeeAsString(event.extrinsic, from.toString()) + } else { + const [who, actualFee, tip, rawAssetIdFee] = getEventData(eventRecordToSubstrateEvent(foundAssetTxFeePaid)) + assetIdFee = getAssetIdFromMultilocation(rawAssetIdFee) + fee = actualFee.toString() + + let { event: { data: [feeFrom, feeTo, feePath, feeAmountIn, feeAmountOut] } } = swaps[0] + + swaps = swaps.slice(1) + if (BigIntFromCodec(actualFee) != BigIntFromCodec(feeAmountIn)) { + let { event: { data: [refundFrom, refundTo, refundPath, refundAmountIn, refundAmountOut] } } = swaps[swaps.length - 1] + + if (BigIntFromCodec(feeAmountIn) == BigIntFromCodec(actualFee) + BigIntFromCodec(refundAmountOut) && + getAssetIdFromMultilocation(feePath[0]) == getAssetIdFromMultilocation(refundPath[refundPath["length"] - 1])) { + swaps = swaps.slice(swaps.length - 1) + // TODO: if fee splitted, than we will process the same block two times + } + } + } + await Promise.all(swaps.map((e) => processAssetConversionSwap(eventRecordToSubstrateEvent(e), assetIdFee, fee))) +} + +async function processAssetConversionSwap(event: SubstrateEvent, assetIdFee: string, fee: string): Promise { + const [from, to, path, amountIn, amountOut] = getEventData(event) + + const swap = { + assetIdIn: getAssetIdFromMultilocation(path[0]), + amountIn: amountIn.toString(), + assetIdOut: getAssetIdFromMultilocation(path[path["length"] - 1]), + amountOut: amountOut.toString(), + sender: from.toString(), + receiver: to.toString(), + assetIdFee: assetIdFee, + fee: fee, + eventIdx: event.idx, + success: true + } + + await createAssetTransmission(event, from.toString(), "-from", {"swap": swap}); + if (from.toString() != to.toString()) { + await createAssetTransmission(event, to.toString(), "-to", {"swap": swap}); + } +} \ No newline at end of file diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts new file mode 100644 index 00000000..e324349e --- /dev/null +++ b/src/mappings/swaps/HydraDx.ts @@ -0,0 +1,106 @@ +import {SubstrateEvent, TypedEventRecord} from "@subql/types"; +import { + eventId, + eventRecordToSubstrateEvent, extractTransactionPaidFee, getEventData, + isCurrencyDepositedEvent +} from "../common"; +import {HistoryElement} from "../../types"; +import {createAssetTransmission} from "../Transfers"; +import {AccountId32} from "@polkadot/types/interfaces/runtime"; +import {u128, u32} from "@polkadot/types-codec"; +import {EventRecord} from "@polkadot/types/interfaces"; +import {Codec} from "@polkadot/types/types"; +import {INumber} from "@polkadot/types-codec/types/interfaces"; + +type OmnipoolSwapArgs = [who: AccountId32, assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128, assetFeeAmount: u128, protocolFeeAmount: u128] + +export async function handleOmnipoolSwap(event: SubstrateEvent): Promise { + let element = await HistoryElement.get(`${eventId(event)}-from`) + if (element !== undefined) { + // already processed swap previously + return; + } + if (event.extrinsic == undefined) { + // TODO we dont yet process swap events that were initiated by the system and not by the user + // Example: https://hydradx.subscan.io/block/4361343?tab=event&event=4361343-27 + return; + } + + const fee = findHydraDxFeeTyped(event.extrinsic.events) + const [who, assetIn, assetOut, amountIn, amountOut] = event.event.data + + const swap = { + assetIdIn: convertHydraDxTokenIdToString(assetIn), + amountIn: amountIn.toString(), + assetIdOut: convertHydraDxTokenIdToString(assetOut), + amountOut: amountOut.toString(), + sender: who, + receiver: who, + assetIdFee: fee.tokenId, + fee: fee.amount, + eventIdx: event.idx, + success: true + } + + logger.info(`Constructed swap ${JSON.stringify(swap)}`) + + await createAssetTransmission(event, who.toString(), "-from", {"swap": swap}); +} + +export type Fee = { + tokenId: string + amount: string +} + +export function findHydraDxFeeTyped(events: TypedEventRecord[]): Fee | undefined { + return findHydraDxFee(events as EventRecord[]) +} + +export function findHydraDxFee(events: EventRecord[]): Fee | undefined { + const lastCurrenciesDepositEvent = findLastEvent(events, + (event) => isCurrencyDepositedEvent(eventRecordToSubstrateEvent(event)) + ) + + if (lastCurrenciesDepositEvent == undefined) return findNativeFee(events) + + const { + event: { + data: [currencyId, _, amount] + } + } = lastCurrenciesDepositEvent + + return { + tokenId: convertHydraDxTokenIdToString(currencyId), + amount: (amount as INumber).toString() + } +} + +function findNativeFee(events: EventRecord[]): Fee | undefined { + let foundAssetTxFeePaid = extractTransactionPaidFee(events) + if (foundAssetTxFeePaid == undefined) return undefined + + return { + tokenId: "native", + amount: foundAssetTxFeePaid + } +} + +export function convertHydraDxTokenIdToString(hydraDxTokenId: Codec): string { + const asString = hydraDxTokenId.toString() + + if (asString == "0") { + return "native" + } else { + return hydraDxTokenId.toHex(true) + } +} + +function findLastEvent(events: EventRecord[], expression: (event: EventRecord) => boolean): EventRecord | undefined { + const currenciesDepositedEvents = events.filter((e) => isCurrencyDepositedEvent(eventRecordToSubstrateEvent(e))) + + if (currenciesDepositedEvents.length == 0) { + return undefined + } + + return currenciesDepositedEvents[currenciesDepositedEvents.length - 1] +} \ No newline at end of file diff --git a/src/mappings/swaps/index.ts b/src/mappings/swaps/index.ts new file mode 100644 index 00000000..8f81fbdc --- /dev/null +++ b/src/mappings/swaps/index.ts @@ -0,0 +1,4 @@ +//Exports all handler functions +export * from './AssetConversion' +export * from './HydraDx' +import "@polkadot/api-augment" \ No newline at end of file diff --git a/statemine.yaml b/statemine.yaml index a5bece3a..8902134a 100644 --- a/statemine.yaml +++ b/statemine.yaml @@ -53,7 +53,7 @@ dataSources: filter: module: tokens method: Transfer - - handler: handleSwap + - handler: handleAssetConversionSwap kind: substrate/EventHandler filter: module: assetConversion diff --git a/westmint.yaml b/westmint.yaml index 06611a53..5e327ae0 100644 --- a/westmint.yaml +++ b/westmint.yaml @@ -52,7 +52,7 @@ dataSources: filter: module: tokens method: Transfer - - handler: handleSwap + - handler: handleAssetConversionSwap kind: substrate/EventHandler filter: module: assetConversion From e306c69c53e36e1f6ab461405a8e140ff09c2c94 Mon Sep 17 00:00:00 2001 From: valentun Date: Tue, 30 Jan 2024 13:10:55 +0300 Subject: [PATCH 04/22] Revert block number --- hydra.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hydra.yaml b/hydra.yaml index c2bc1dcc..a5dd3422 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -18,7 +18,7 @@ network: dataSources: - name: main kind: substrate/Runtime - startBlock: 4361342 + startBlock: 1 mapping: file: ./dist/index.js handlers: From 15c82d554842dd1caa432fca19aa05b34b9b7647 Mon Sep 17 00:00:00 2001 From: valentun Date: Wed, 31 Jan 2024 11:58:30 +0300 Subject: [PATCH 05/22] Fix findLastEvent --- src/mappings/swaps/HydraDx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index e324349e..3ee7d935 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -96,7 +96,7 @@ export function convertHydraDxTokenIdToString(hydraDxTokenId: Codec): string { } function findLastEvent(events: EventRecord[], expression: (event: EventRecord) => boolean): EventRecord | undefined { - const currenciesDepositedEvents = events.filter((e) => isCurrencyDepositedEvent(eventRecordToSubstrateEvent(e))) + const currenciesDepositedEvents = events.filter(expression) if (currenciesDepositedEvents.length == 0) { return undefined From d8e522a1de6c810848df4ef24204f87ceee540d3 Mon Sep 17 00:00:00 2001 From: vovunku Date: Sun, 4 Feb 2024 23:01:57 +0100 Subject: [PATCH 06/22] doubled logic for payoutStakersByPage logic --- src/mappings/Rewards.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mappings/Rewards.ts b/src/mappings/Rewards.ts index a675197b..74dacde8 100644 --- a/src/mappings/Rewards.ts +++ b/src/mappings/Rewards.ts @@ -31,6 +31,10 @@ function isPayoutStakers(call: CallBase): boolean { return call.method == "payoutStakers" } +function isPayoutStakersByPage(call: CallBase): boolean { + return call.method == "payoutStakersByPage" +} + function isPayoutValidator(call: CallBase): boolean { return call.method == "payoutValidator" } @@ -41,6 +45,12 @@ function extractArgsFromPayoutStakers(call: CallBase): [string, number return [validatorAddressRaw.toString(), (eraRaw as EraIndex).toNumber()] } +function extractArgsFromPayoutStakersByPage(call: CallBase): [string, number] { + const [validatorAddressRaw, eraRaw, _] = call.args + + return [validatorAddressRaw.toString(), (eraRaw as EraIndex).toNumber()] +} + function extractArgsFromPayoutValidator(call: CallBase, sender: string): [string, number] { const [eraRaw] = call.args @@ -164,6 +174,8 @@ async function handleRewardForTxHistory(rewardEvent: SubstrateEvent): Promise, sender: string) : [string, number][] { if (isPayoutStakers(causeCall)) { return [extractArgsFromPayoutStakers(causeCall)] + } else if (isPayoutStakersByPage(causeCall)) { + return [extractArgsFromPayoutStakersByPage(causeCall)] } else if (isPayoutValidator(causeCall)) { return [extractArgsFromPayoutValidator(causeCall, sender)] } else if (isBatch(causeCall)) { From e5b84027dc818869afa167a71b8c5b8c2ccbc0f3 Mon Sep 17 00:00:00 2001 From: vovunku Date: Mon, 5 Feb 2024 16:44:20 +0100 Subject: [PATCH 07/22] deployed stakers payout paged logic --- ipfs-cids/.westend-cid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipfs-cids/.westend-cid b/ipfs-cids/.westend-cid index 3e6dd2d8..4f024c55 100644 --- a/ipfs-cids/.westend-cid +++ b/ipfs-cids/.westend-cid @@ -1 +1 @@ -QmbpSWKejfPqwxex6E8KSqWD5sxSHedVKyWR5Rfs1AmbmQ \ No newline at end of file +QmWffzTpd4fCa2Ewpm78BBB76guRruF9zbL2uSai8rMTtX \ No newline at end of file From c3b02fc946a167d29af6d597bee6ab094e12ba52 Mon Sep 17 00:00:00 2001 From: vovunku Date: Tue, 6 Feb 2024 12:06:40 +0100 Subject: [PATCH 08/22] updated dock ChainTypes and deployed --- dock.yaml | 12 +----------- ipfs-cids/.dock-cid | 1 + package.json | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) create mode 100644 ipfs-cids/.dock-cid diff --git a/dock.yaml b/dock.yaml index 7b80b73e..8a7d50d4 100644 --- a/dock.yaml +++ b/dock.yaml @@ -21,27 +21,17 @@ network: dataSources: - name: main kind: substrate/Runtime - startBlock: 12885 + startBlock: 1 mapping: file: ./dist/index.js handlers: - handler: handleHistoryElement kind: substrate/CallHandler - - handler: handleReward - kind: substrate/EventHandler - filter: - module: staking - method: Reward - handler: handleRewarded kind: substrate/EventHandler filter: module: staking method: Rewarded - - handler: handleSlash - kind: substrate/EventHandler - filter: - module: staking - method: Slash - handler: handleSlashed kind: substrate/EventHandler filter: diff --git a/ipfs-cids/.dock-cid b/ipfs-cids/.dock-cid new file mode 100644 index 00000000..5c408e59 --- /dev/null +++ b/ipfs-cids/.dock-cid @@ -0,0 +1 @@ +QmSM8Q1xKcU17AXqajJcBcjPtNTyntzVH7yh31gmEz1HYV \ No newline at end of file diff --git a/package.json b/package.json index 56df0010..65d89988 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@acala-network/type-definitions": "^4.1.5", "@crustio/type-definitions": "^1.3.0", - "@docknetwork/node-types": "0.16.0", + "@docknetwork/node-types": "0.17.0", "@equilab/definitions": "^1.4.18", "@interlay/interbtc-types": "^1.5.10", "@kiltprotocol/type-definitions": "^0.1.23", From 81fad3224c581d3990c57a736d53cf7e134621a7 Mon Sep 17 00:00:00 2001 From: "emkil.russel@gmail.com" Date: Wed, 14 Feb 2024 17:38:55 +0100 Subject: [PATCH 09/22] fix history element --- hydra.yaml | 5 +++++ src/mappings/HistoryElements.ts | 38 +++++++++++++++++++++++++++------ src/mappings/common.ts | 12 +++++++++-- src/mappings/swaps/HydraDx.ts | 33 ++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/hydra.yaml b/hydra.yaml index a5dd3422..0c028278 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -54,3 +54,8 @@ dataSources: filter: module: omnipool method: BuyExecuted + - handler: handleHydraRouterSwap + kind: substrate/EventHandler + filter: + module: router + method: Executed \ No newline at end of file diff --git a/src/mappings/HistoryElements.ts b/src/mappings/HistoryElements.ts index 73c76f7b..3e850ed4 100644 --- a/src/mappings/HistoryElements.ts +++ b/src/mappings/HistoryElements.ts @@ -258,10 +258,14 @@ function determineTransferCallsArgs( return assetHubSwapCallback(...extractArgsFromSwapExactTokensForTokens(causeCall)) } else if (isSwapTokensForExactTokens(causeCall)) { return assetHubSwapCallback(...extractArgsFromSwapTokensForExactTokens(causeCall)) - } else if (isHydraDxBuy(causeCall)) { - return [hydraDxSwapCallback(...extractArgsFromHydraDxBuy(causeCall))] - } else if (isHydraDxSell(causeCall)) { - return [hydraDxSwapCallback(...extractArgsFromHydraDxSell(causeCall))] + } else if (isHydraOmnipoolBuy(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraOmnipoolBuy(causeCall))] + } else if (isHydraOmnipoolSell(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraOmnipoolSell(causeCall))] + } else if (isHydraRouterBuy(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraRouterBuy(causeCall))] + } else if (isHydraRouterSell(causeCall)) { + return [hydraDxSwapCallback(...extractArgsFromHydraRouterSell(causeCall))] } else if (isBatch(causeCall)) { return callsFromBatch(causeCall) .map(call => { @@ -353,7 +357,29 @@ function extractArgsFromSwapTokensForExactTokens(call: CallBase) { ] } -function extractArgsFromHydraDxSell(call: CallBase): Codec[] { +function extractArgsFromHydraRouterSell(call: CallBase): Codec[] { + const [assetIn, assetOut, amountIn, minAmountOut, _] = call.args + + return [ + assetIn, + assetOut, + amountIn, + amountOut + ] +} + +function extractArgsFromHydraRouterBuy(call: CallBase): Codec[] { + const [assetIn, assetOut, amountOut, maxAmountIn, _] = call.args + + return [ + assetIn, + assetOut, + maxAmountIn, + amountOut + ] +} + +function extractArgsFromHydraOmnipoolSell(call: CallBase): Codec[] { const [assetIn, assetOut, amount, minBuyAmount, _] = call.args return [ @@ -365,7 +391,7 @@ function extractArgsFromHydraDxSell(call: CallBase): Codec[] { } -function extractArgsFromHydraDxBuy(call: CallBase): Codec[] { +function extractArgsFromHydraOmnipoolBuy(call: CallBase): Codec[] { const [assetOut, assetIn, amount, maxSellAmount, _] = call.args return [ diff --git a/src/mappings/common.ts b/src/mappings/common.ts index 54d17136..a6630255 100644 --- a/src/mappings/common.ts +++ b/src/mappings/common.ts @@ -68,14 +68,22 @@ export function isSwapTokensForExactTokens(call: CallBase) : boolean { return call.section === "assetConversion" && call.method === "swapTokensForExactTokens" } -export function isHydraDxBuy(call: CallBase) : boolean { +export function isHydraOmnipoolBuy(call: CallBase) : boolean { return call.section === "omnipool" && call.method == "buy" } -export function isHydraDxSell(call: CallBase) : boolean { +export function isHydraOmnipoolSell(call: CallBase) : boolean { return call.section === "omnipool" && call.method == "sell" } +export function isHydraRouterBuy(call: CallBase) : boolean { + return call.section === "router" && call.method == "buy" +} + +export function isHydraRouterSell(call: CallBase) : boolean { + return call.section === "router" && call.method == "sell" +} + export function isOrmlTransfer(call: CallBase) : boolean { return ormlSections.includes(call.section) && transferCalls.includes(call.method) } diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index 3ee7d935..2ac14675 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -14,6 +14,8 @@ import {INumber} from "@polkadot/types-codec/types/interfaces"; type OmnipoolSwapArgs = [who: AccountId32, assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128, assetFeeAmount: u128, protocolFeeAmount: u128] +type RouterSwapArgs = [assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128]; + export async function handleOmnipoolSwap(event: SubstrateEvent): Promise { let element = await HistoryElement.get(`${eventId(event)}-from`) if (element !== undefined) { @@ -47,6 +49,37 @@ export async function handleOmnipoolSwap(event: SubstrateEvent await createAssetTransmission(event, who.toString(), "-from", {"swap": swap}); } +export async function handleHydraRouterSwap(event: SubstrateEvent): Promise { + let element = await HistoryElement.get(`${eventId(event)}-from`) + if (element !== undefined) { + return; + } + if (event.extrinsic == undefined) { + return; + } + + const who = event.extrinsic.signer.toString() + const fee = findHydraDxFeeTyped(event.extrinsic.events) + const [assetIn, assetOut, amountIn, amountOut] = event.event.data + + const swap = { + assetIdIn: convertHydraDxTokenIdToString(assetIn), + amountIn: amountIn.toString(), + assetIdOut: convertHydraDxTokenIdToString(assetOut), + amountOut: amountOut.toString(), + sender: who, + receiver: who, + assetIdFee: fee.tokenId, + fee: fee.amount, + eventIdx: event.idx, + success: true + } + + logger.info(`Constructed swap ${JSON.stringify(swap)}`) + + await createAssetTransmission(event, who.toString(), "-from", {"swap": swap}); +} + export type Fee = { tokenId: string amount: string From 1740dda543344e39c16915c432aae91a97a16bf0 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 07:17:17 +0100 Subject: [PATCH 10/22] make common orml currency id --- src/mappings/HistoryElements.ts | 3 ++- src/mappings/Transfers.ts | 5 +++-- src/mappings/common.ts | 4 ++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mappings/HistoryElements.ts b/src/mappings/HistoryElements.ts index 3e850ed4..76949cf2 100644 --- a/src/mappings/HistoryElements.ts +++ b/src/mappings/HistoryElements.ts @@ -22,6 +22,7 @@ import { isEvmExecutedEvent, isAssetTxFeePaidEvent, isEquilibriumTransfer, isHydraDxBuy, isHydraDxSell, + convertOrmlCurrencyIdToString } from "./common"; import {CallBase} from "@polkadot/types/types/calls"; import {AnyTuple} from "@polkadot/types/types/codec"; @@ -331,7 +332,7 @@ function extractArgsFromOrmlTransferAll(call: CallBase): [string, bigi return [ destinationAddress.toString(), BigInt(0), - currencyId.toHex().toString() + convertOrmlCurrencyIdToString(currencyId) ] } diff --git a/src/mappings/Transfers.ts b/src/mappings/Transfers.ts index fcd7be90..335c5d96 100644 --- a/src/mappings/Transfers.ts +++ b/src/mappings/Transfers.ts @@ -14,6 +14,7 @@ import { eventRecordToSubstrateEvent, getAssetIdFromMultilocation, BigIntFromCodec, + convertOrmlCurrencyIdToString } from "./common"; import {INumber} from "@polkadot/types-codec/types/interfaces"; @@ -76,7 +77,7 @@ export async function handleOrmlTransfer(event: SubstrateEvent): Promise { to, suffix: "-from", amount, - assetId: currencyId.toHex().toString(), + assetId: convertOrmlCurrencyIdToString(currencyId), }); await createTransfer({ event, @@ -85,7 +86,7 @@ export async function handleOrmlTransfer(event: SubstrateEvent): Promise { to, suffix: "-to", amount, - assetId: currencyId.toHex().toString(), + assetId: convertOrmlCurrencyIdToString(currencyId), }); } diff --git a/src/mappings/common.ts b/src/mappings/common.ts index a6630255..83c87d11 100644 --- a/src/mappings/common.ts +++ b/src/mappings/common.ts @@ -177,6 +177,10 @@ export function BigIntFromCodec(eventRecord: Codec): bigint { return (eventRecord as unknown as INumber).toBigInt() } +export function convertOrmlCurrencyIdToString(currencyId: Codec): string { + return currencyId.toHex(true) +} + function exportFeeRefund(extrinsic: SubstrateExtrinsic, from: string = ''): bigint { const extrinsicSigner = from || extrinsic.extrinsic.signer.toString() From 017371455ff8d8b89c69069d4e03642b00591854 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 10:04:36 +0100 Subject: [PATCH 11/22] process omnipool swap only if it is not part of router swap --- src/mappings/HistoryElements.ts | 8 ++++++-- src/mappings/swaps/HydraDx.ts | 22 ++++++++++++++++++++-- yarn.lock | 8 ++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/mappings/HistoryElements.ts b/src/mappings/HistoryElements.ts index 76949cf2..b47f58a6 100644 --- a/src/mappings/HistoryElements.ts +++ b/src/mappings/HistoryElements.ts @@ -21,7 +21,11 @@ import { isEvmTransaction, isEvmExecutedEvent, isAssetTxFeePaidEvent, - isEquilibriumTransfer, isHydraDxBuy, isHydraDxSell, + isEquilibriumTransfer, + isHydraOmnipoolBuy, + isHydraOmnipoolSell, + isHydraRouterSell, + isHydraRouterBuy, convertOrmlCurrencyIdToString } from "./common"; import {CallBase} from "@polkadot/types/types/calls"; @@ -365,7 +369,7 @@ function extractArgsFromHydraRouterSell(call: CallBase): Codec[] { assetIn, assetOut, amountIn, - amountOut + minAmountOut ] } diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index 2ac14675..c61f1be2 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -9,7 +9,7 @@ import {createAssetTransmission} from "../Transfers"; import {AccountId32} from "@polkadot/types/interfaces/runtime"; import {u128, u32} from "@polkadot/types-codec"; import {EventRecord} from "@polkadot/types/interfaces"; -import {Codec} from "@polkadot/types/types"; +import {Codec, AnyTuple} from "@polkadot/types/types"; import {INumber} from "@polkadot/types-codec/types/interfaces"; type OmnipoolSwapArgs = [who: AccountId32, assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128, assetFeeAmount: u128, protocolFeeAmount: u128] @@ -17,6 +17,11 @@ type OmnipoolSwapArgs = [who: AccountId32, assetIn: u32, assetOut: u32, amountIn type RouterSwapArgs = [assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128]; export async function handleOmnipoolSwap(event: SubstrateEvent): Promise { + if (isPartOfRouterSwap(event)) { + // TODO: we currently don't support swaps in batch + return; + } + let element = await HistoryElement.get(`${eventId(event)}-from`) if (element !== undefined) { // already processed swap previously @@ -58,7 +63,7 @@ export async function handleHydraRouterSwap(event: SubstrateEvent(event: SubstrateEvent): boolean { + for (const eventRecord of event.extrinsic.events) { + if ( + eventRecord.event.section == "router" && + eventRecord.event.method == "Executed" + ) { + return true + } + } + + return false +} + function findNativeFee(events: EventRecord[]): Fee | undefined { let foundAssetTxFeePaid = extractTransactionPaidFee(events) if (foundAssetTxFeePaid == undefined) return undefined diff --git a/yarn.lock b/yarn.lock index 93f95f5f..76940834 100644 --- a/yarn.lock +++ b/yarn.lock @@ -486,10 +486,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@docknetwork/node-types@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@docknetwork/node-types/-/node-types-0.16.0.tgz#23570042c823a6320654ee2c5b8c0da5d7c43d21" - integrity sha512-VUZB8guX9161hDIEVn/UKJEUlXjIDE6vH5flx6uDHVc0QOhBy1bq6AGLayG4ZH19dCN39ta2sKGIFq9wLO4H2A== +"@docknetwork/node-types@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@docknetwork/node-types/-/node-types-0.17.0.tgz#ca0ddb5b819e012e8f2f112353008325de4f3e33" + integrity sha512-aSRFtCwLhdhcY1wqX3WfhPpY2QXVqaB9kNB3e5+ajCWXtc0wuKJePpnSZEO4RqUEUKV5Y3LcsQ52ZB+aJ1PpFw== "@equilab/definitions@^1.4.18": version "1.4.18" From 881e3c76d20344dac5755b51b4706d7e707359d2 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 11:31:32 +0100 Subject: [PATCH 12/22] fix filter logic --- src/mappings/swaps/HydraDx.ts | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index c61f1be2..bf3a8737 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -17,11 +17,6 @@ type OmnipoolSwapArgs = [who: AccountId32, assetIn: u32, assetOut: u32, amountIn type RouterSwapArgs = [assetIn: u32, assetOut: u32, amountIn: u128, amountOut: u128]; export async function handleOmnipoolSwap(event: SubstrateEvent): Promise { - if (isPartOfRouterSwap(event)) { - // TODO: we currently don't support swaps in batch - return; - } - let element = await HistoryElement.get(`${eventId(event)}-from`) if (element !== undefined) { // already processed swap previously @@ -33,6 +28,11 @@ export async function handleOmnipoolSwap(event: SubstrateEvent return; } + if (isPartOfRouterSwap(event.extrinsic.events)) { + // TODO: we currently don't support swaps in batch + return; + } + const fee = findHydraDxFeeTyped(event.extrinsic.events) const [who, assetIn, assetOut, amountIn, amountOut] = event.event.data @@ -41,15 +41,16 @@ export async function handleOmnipoolSwap(event: SubstrateEvent amountIn: amountIn.toString(), assetIdOut: convertHydraDxTokenIdToString(assetOut), amountOut: amountOut.toString(), - sender: who, - receiver: who, + sender: who.toString(), + receiver: who.toString(), assetIdFee: fee.tokenId, fee: fee.amount, eventIdx: event.idx, success: true } - logger.info(`Constructed swap ${JSON.stringify(swap)}`) + const blockNumber = event.block.block.header.number + logger.info(`Constructed omnipool swap ${JSON.stringify(swap)} for block ${blockNumber.toString()}`) await createAssetTransmission(event, who.toString(), "-from", {"swap": swap}); } @@ -72,15 +73,16 @@ export async function handleHydraRouterSwap(event: SubstrateEvent(event: SubstrateEvent): boolean { - for (const eventRecord of event.extrinsic.events) { +function isPartOfRouterSwap(events: TypedEventRecord[]): boolean { + const eventRecords = events as EventRecord[] + for (const eventRecord of eventRecords) { if ( eventRecord.event.section == "router" && - eventRecord.event.method == "Executed" + eventRecord.event.method == "RouteExecuted" ) { return true } From eb46b30cb33b71ea2574d64951264ee188abc6c1 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 11:56:46 +0100 Subject: [PATCH 13/22] fix currency id representation --- src/mappings/common.ts | 6 +++++- src/mappings/swaps/HydraDx.ts | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mappings/common.ts b/src/mappings/common.ts index 83c87d11..c55b03a2 100644 --- a/src/mappings/common.ts +++ b/src/mappings/common.ts @@ -6,6 +6,7 @@ import {AnyTuple} from "@polkadot/types/types/codec"; import { Vec, GenericEventData } from '@polkadot/types'; import {Codec} from "@polkadot/types/types"; import {INumber} from "@polkadot/types-codec/types/interfaces"; +import { u8aToHex } from "@polkadot/util" import * as events from "events"; const batchCalls = ["batch", "batchAll", "forceBatch"] @@ -178,7 +179,10 @@ export function BigIntFromCodec(eventRecord: Codec): bigint { } export function convertOrmlCurrencyIdToString(currencyId: Codec): string { - return currencyId.toHex(true) + // make sure first we have scale encoded bytes + const bytes = currencyId.toU8a() + + return u8aToHex(bytes).toString() } function exportFeeRefund(extrinsic: SubstrateExtrinsic, from: string = ''): bigint { diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index bf3a8737..19ae2332 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -2,7 +2,8 @@ import {SubstrateEvent, TypedEventRecord} from "@subql/types"; import { eventId, eventRecordToSubstrateEvent, extractTransactionPaidFee, getEventData, - isCurrencyDepositedEvent + isCurrencyDepositedEvent, + convertOrmlCurrencyIdToString } from "../common"; import {HistoryElement} from "../../types"; import {createAssetTransmission} from "../Transfers"; @@ -145,7 +146,7 @@ export function convertHydraDxTokenIdToString(hydraDxTokenId: Codec): string { if (asString == "0") { return "native" } else { - return hydraDxTokenId.toHex(true) + return convertOrmlCurrencyIdToString(hydraDxTokenId) } } From a0b356f8027aa0655c7ffe7962b4f6ab371dfa3e Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 13:32:45 +0100 Subject: [PATCH 14/22] fix naming --- hydra.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hydra.yaml b/hydra.yaml index 0c028278..21c2f646 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -58,4 +58,4 @@ dataSources: kind: substrate/EventHandler filter: module: router - method: Executed \ No newline at end of file + method: RouteExecuted \ No newline at end of file From ce171212e2fb105123e46a90c40731ce58a771a6 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 15 Feb 2024 13:44:44 +0100 Subject: [PATCH 15/22] update deployment --- ipfs-cids/.hydra-cid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipfs-cids/.hydra-cid b/ipfs-cids/.hydra-cid index 97e3d220..0f17415c 100644 --- a/ipfs-cids/.hydra-cid +++ b/ipfs-cids/.hydra-cid @@ -1 +1 @@ -QmYRGPQAZfMYLxSRvcEwn2MHfijykez4tAEm2At8gdwjsK \ No newline at end of file +Qmda4hw8Qz556MKsHDP4QRRXTPgT2NkM3hAsoqhh7fsUXP \ No newline at end of file From 5edb30e7c5f17f8c02b7486e8fdaf69d736a61c0 Mon Sep 17 00:00:00 2001 From: Russel Date: Fri, 16 Feb 2024 04:45:33 +0100 Subject: [PATCH 16/22] fix tokens transfer --- hydra.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hydra.yaml b/hydra.yaml index 21c2f646..19504305 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -34,11 +34,6 @@ dataSources: filter: module: assets method: Transferred - - handler: handleCurrencyTransfer - kind: substrate/EventHandler - filter: - module: currencies - method: Transferred - handler: handleTokenTransfer kind: substrate/EventHandler filter: From a357546ac91e61561c4f76845757e4114b6e509a Mon Sep 17 00:00:00 2001 From: Russel Date: Fri, 16 Feb 2024 05:00:36 +0100 Subject: [PATCH 17/22] fix hydra cid --- ipfs-cids/.hydra-cid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipfs-cids/.hydra-cid b/ipfs-cids/.hydra-cid index 0f17415c..95ac743e 100644 --- a/ipfs-cids/.hydra-cid +++ b/ipfs-cids/.hydra-cid @@ -1 +1 @@ -Qmda4hw8Qz556MKsHDP4QRRXTPgT2NkM3hAsoqhh7fsUXP \ No newline at end of file +QmdayLTysfwzBFATJfR2bConb8EP17rjYSqXVAyzNSwUdc \ No newline at end of file From b2c7e755dfa8d0043fe96410a9e5e6d152ac259c Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 29 Feb 2024 10:01:29 +0100 Subject: [PATCH 18/22] fix router event --- hydra.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hydra.yaml b/hydra.yaml index 19504305..ff1f38a0 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -53,4 +53,4 @@ dataSources: kind: substrate/EventHandler filter: module: router - method: RouteExecuted \ No newline at end of file + method: Executed \ No newline at end of file From 011ae46a2fb35c8490db4052a664091548a06443 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 29 Feb 2024 10:11:57 +0100 Subject: [PATCH 19/22] fix event --- src/mappings/swaps/HydraDx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index 19ae2332..38c41800 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -121,7 +121,7 @@ function isPartOfRouterSwap(events: TypedEventRecord[]): boolean { for (const eventRecord of eventRecords) { if ( eventRecord.event.section == "router" && - eventRecord.event.method == "RouteExecuted" + eventRecord.event.method == "Executed" ) { return true } From 01e85cc7e73549303fc7bffbcfc530cd2ab79244 Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 29 Feb 2024 10:26:48 +0100 Subject: [PATCH 20/22] fix hydra events --- hydra.yaml | 5 +++++ src/mappings/swaps/HydraDx.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hydra.yaml b/hydra.yaml index ff1f38a0..36205203 100644 --- a/hydra.yaml +++ b/hydra.yaml @@ -49,6 +49,11 @@ dataSources: filter: module: omnipool method: BuyExecuted + - handler: handleHydraRouterSwap + kind: substrate/EventHandler + filter: + module: router + method: RouteExecuted - handler: handleHydraRouterSwap kind: substrate/EventHandler filter: diff --git a/src/mappings/swaps/HydraDx.ts b/src/mappings/swaps/HydraDx.ts index 38c41800..c54d5cec 100644 --- a/src/mappings/swaps/HydraDx.ts +++ b/src/mappings/swaps/HydraDx.ts @@ -121,7 +121,7 @@ function isPartOfRouterSwap(events: TypedEventRecord[]): boolean { for (const eventRecord of eventRecords) { if ( eventRecord.event.section == "router" && - eventRecord.event.method == "Executed" + (eventRecord.event.method == "Executed" || eventRecord.event.method == "RouteExecuted") ) { return true } From e8b4e8ad7810c5dc4c962e69409641f417a4574b Mon Sep 17 00:00:00 2001 From: Russel Date: Thu, 29 Feb 2024 10:36:57 +0100 Subject: [PATCH 21/22] deploy cid --- ipfs-cids/.hydra-cid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipfs-cids/.hydra-cid b/ipfs-cids/.hydra-cid index 95ac743e..2e9cee83 100644 --- a/ipfs-cids/.hydra-cid +++ b/ipfs-cids/.hydra-cid @@ -1 +1 @@ -QmdayLTysfwzBFATJfR2bConb8EP17rjYSqXVAyzNSwUdc \ No newline at end of file +QmcLEzaNKuXCvSYe2ss7u64Y5UwKEGoE8TapDjhkqXe4v8 \ No newline at end of file From 078a1acd38adb2cddbf00ad674e9334cabe6b89e Mon Sep 17 00:00:00 2001 From: vovunku Date: Wed, 24 Apr 2024 11:36:37 +0200 Subject: [PATCH 22/22] deployed polkadot+kusama with new reward parsing logic --- ipfs-cids/.kusama-cid | 2 +- ipfs-cids/.polkadot-cid | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ipfs-cids/.kusama-cid b/ipfs-cids/.kusama-cid index 28301091..81fd1d8f 100644 --- a/ipfs-cids/.kusama-cid +++ b/ipfs-cids/.kusama-cid @@ -1 +1 @@ -Qmc2BGBGKe346v5nmt4f8QnA8YdTr8CnufCkgAwe9K6Akg \ No newline at end of file +QmZxCUe4kmXwUzvUNHCQrTqShr5ipcqv3nPGoAz1vTZnj8 \ No newline at end of file diff --git a/ipfs-cids/.polkadot-cid b/ipfs-cids/.polkadot-cid index 6361863b..4d5e5b39 100644 --- a/ipfs-cids/.polkadot-cid +++ b/ipfs-cids/.polkadot-cid @@ -1 +1 @@ -QmUciu8MN6Eiw2xN11XL1sNi3UPWQNoYoZ6LLTmdytv4Fb \ No newline at end of file +QmQcPMkUd63AKSJYki1J8omYREKTQKeq87E3nxTiZe89sF \ No newline at end of file