From 4204de75520599479a0fedd492db6bd9f558e651 Mon Sep 17 00:00:00 2001 From: anastasiarods Date: Fri, 20 Sep 2024 15:12:24 +0200 Subject: [PATCH] Add default interpreter for transfers (#105) * Upd interpreter * Add default interpreter for transfers * Move transfer interpreter to fallback * Add changeset --- .changeset/unlucky-rats-hammer.md | 5 +++ .../interpreters/fallback.ts | 26 +++++++++-- .../interpreters/index.ts | 7 ++- .../interpreters/moxie.ts | 6 +-- .../interpreters/transfer.ts | 43 +++++++++++++++++++ packages/transaction-interpreter/src/types.ts | 6 ++- 6 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 .changeset/unlucky-rats-hammer.md create mode 100644 packages/transaction-interpreter/interpreters/transfer.ts diff --git a/.changeset/unlucky-rats-hammer.md b/.changeset/unlucky-rats-hammer.md new file mode 100644 index 0000000..713d9a3 --- /dev/null +++ b/.changeset/unlucky-rats-hammer.md @@ -0,0 +1,5 @@ +--- +'@3loop/transaction-interpreter': minor +--- + +Add transfer interpretations to fallback interpreter diff --git a/packages/transaction-interpreter/interpreters/fallback.ts b/packages/transaction-interpreter/interpreters/fallback.ts index c13f7f0..0c8e84a 100644 --- a/packages/transaction-interpreter/interpreters/fallback.ts +++ b/packages/transaction-interpreter/interpreters/fallback.ts @@ -1,17 +1,35 @@ import type { InterpretedTransaction } from '@/types.js' import type { DecodedTx } from '@3loop/transaction-decoder' -import { assetsReceived, assetsSent } from './std.js' +import { assetsReceived, assetsSent, displayAsset, NULL_ADDRESS } from './std.js' export function transformEvent(event: DecodedTx): InterpretedTransaction { const methodName = event.methodCall.name - return { - type: 'unknown', - action: `Called method '${methodName}'`, + const newEvent: Omit = { chain: event.chainID, txHash: event.txHash, user: { address: event.fromAddress, name: null }, method: methodName, + } + + const transfers = event.transfers.filter((t) => t.from !== NULL_ADDRESS && t.to !== NULL_ADDRESS) + + if (transfers.length === 1) { + const fromAddress = transfers[0].from + const assetSent = assetsSent(transfers, fromAddress) + return { + type: 'unknown', + action: `Sent ${displayAsset(assetSent[0])}`, + ...newEvent, + assetsReceived: [], + assetsSent: assetSent, + } + } + + return { + type: 'unknown', + action: `Called method '${methodName}'`, + ...newEvent, assetsSent: assetsSent(event.transfers, event.fromAddress), assetsReceived: assetsReceived(event.transfers, event.fromAddress), } diff --git a/packages/transaction-interpreter/interpreters/index.ts b/packages/transaction-interpreter/interpreters/index.ts index 6982b5f..7fc788e 100644 --- a/packages/transaction-interpreter/interpreters/index.ts +++ b/packages/transaction-interpreter/interpreters/index.ts @@ -41,11 +41,10 @@ function getInterpreter(tx: DecodedTx): string | undefined { return `${standardLibrary}\n${interpretations[eventInterpreter]}` } - //if there is a contract type mapping, return the contract type interpreter - const contractTypes = ['ERC20', 'ERC721', 'ERC1155'] - if (contractTypes.includes(contractType)) { + // Check for contract type mapping and return the corresponding interpreter + if (contractType && contractTypeToName[contractType.toLowerCase()]) { const typeId = contractTypeToName[contractType.toLowerCase()] - return `${standardLibrary} \n ${interpretations[typeId]}` + return `${standardLibrary}\n${interpretations[typeId]}` } return undefined diff --git a/packages/transaction-interpreter/interpreters/moxie.ts b/packages/transaction-interpreter/interpreters/moxie.ts index 4ac63a6..b445731 100644 --- a/packages/transaction-interpreter/interpreters/moxie.ts +++ b/packages/transaction-interpreter/interpreters/moxie.ts @@ -45,7 +45,7 @@ export function transformEvent(event: DecodedTx): InterpretedTransaction { if (eventType === 'buy' && isSwap) { return { type: 'swap', - action: `Bought ${formatNumber(received[0].amount)} shares of ${received[0].asset?.name} for ${displayAsset( + action: `Bought ${formatNumber(received[0].amount)} Fan Tokens of ${received[0].asset?.name} for ${displayAsset( sent[0], )}`, ...newEvent, @@ -57,7 +57,7 @@ export function transformEvent(event: DecodedTx): InterpretedTransaction { if (eventType === 'sell' && isSwap) { return { type: 'swap', - action: `Sold ${formatNumber(sent[0].amount)} shares of ${sent[0].asset?.name} for ${displayAsset( + action: `Sold ${formatNumber(sent[0].amount)} Fan Tokens of ${sent[0].asset?.name} for ${displayAsset( received[0], )}`, ...newEvent, @@ -72,7 +72,7 @@ export function transformEvent(event: DecodedTx): InterpretedTransaction { return { type: 'burn', - action: `Burned ${displayAsset(sent[0])} for ${buyTokenMetadata?.contractName} fan holders`, + action: `Burned ${displayAsset(sent[0])} for ${buyTokenMetadata?.contractName} Fan Tokens holders`, ...newEvent, assetsSent: sent, assetsReceived: [], diff --git a/packages/transaction-interpreter/interpreters/transfer.ts b/packages/transaction-interpreter/interpreters/transfer.ts new file mode 100644 index 0000000..a412269 --- /dev/null +++ b/packages/transaction-interpreter/interpreters/transfer.ts @@ -0,0 +1,43 @@ +import { assetsReceived, assetsSent, displayAsset, NULL_ADDRESS } from './std.js' +import type { InterpretedTransaction } from '@/types.js' +import type { DecodedTx } from '@3loop/transaction-decoder' + +/** + * Fallback interpretator to display transfers. + */ +export function transformEvent(event: DecodedTx): InterpretedTransaction { + const methodName = event.methodCall.name + + const newEvent: Omit = { + chain: event.chainID, + txHash: event.txHash, + user: { address: event.fromAddress, name: null }, + method: methodName, + } + + const transfers = event.transfers.filter((t) => t.from !== NULL_ADDRESS && t.to !== NULL_ADDRESS) + + if (transfers.length === 1) { + const fromAddress = transfers[0].from + const assetSent = assetsSent(transfers, fromAddress) + return { + type: 'transfer-token', + action: `Sent ${displayAsset(assetSent[0])}`, + ...newEvent, + assetsReceived: [], + assetsSent: assetSent, + } + } + + // TODO: handle multiple transfers + + return { + type: 'unknown', + action: `Called method '${methodName}'`, + ...newEvent, + assetsReceived: assetsReceived(transfers, event.fromAddress), + assetsSent: assetsSent(transfers, event.fromAddress), + } +} + +export const contractType = 'transfer' diff --git a/packages/transaction-interpreter/src/types.ts b/packages/transaction-interpreter/src/types.ts index e480121..b1582ce 100644 --- a/packages/transaction-interpreter/src/types.ts +++ b/packages/transaction-interpreter/src/types.ts @@ -9,8 +9,9 @@ interface Address { address: string name: string | null } +type StringWithAutocompleteOptions = (string & Record) | TOptions -type TransactionType = +type TransactionType = StringWithAutocompleteOptions< | 'repay-loan' | 'deposit-collateral' | 'borrow' @@ -27,8 +28,9 @@ type TransactionType = | 'account-abstraction' | 'stake-token' | 'unstake-token' + | 'burn' | 'unknown' - | string +> export interface Asset { address: string