From 6d8dbacb7b8833ef5980a4579d7302078d54ed0f Mon Sep 17 00:00:00 2001 From: Erno Date: Wed, 22 Mar 2023 04:13:01 +0800 Subject: [PATCH] feat: add internal transactions --- .changeset/soft-oranges-relate.md | 6 + .../EvmInternalTransaction.test.ts | 109 +++++++++++ .../EvmInternalTransaction.ts | 169 ++++++++++++++++++ .../dataTypes/EvmInternalTransaction/index.ts | 2 + .../dataTypes/EvmInternalTransaction/types.ts | 57 ++++++ .../EvmTransaction/EvmTransaction.ts | 16 ++ .../src/dataTypes/EvmTransaction/types.ts | 3 + .../common/evmUtils/src/dataTypes/index.ts | 1 + .../block/getBlockOperation.test.ts | 1 + .../src/operations/block/getBlockOperation.ts | 22 ++- .../common/evmUtils/src/operations/openapi.ts | 98 ++++++++++ .../evmUtils/src/operations/operations.ts | 7 +- .../getInternalTransactionsOperation.test.ts | 30 ++++ .../getInternalTransactionsOperation.ts | 103 +++++++++++ .../getTransactionOperation.test.ts | 1 + .../transaction/getTransactionOperation.ts | 28 ++- .../getWalletTransactionsOperation.test.ts | 1 + .../getWalletTransactionsOperation.ts | 41 ++++- .../src/operations/transaction/index.ts | 1 + .../endpoints/getInternalTransactions.ts | 56 ++++++ .../evmApi/integration/mocks/mockServer.ts | 2 + .../test/getInternalTransactions.test.ts | 37 ++++ packages/evmApi/src/generated/ClientEvmApi.ts | 31 ++-- 23 files changed, 792 insertions(+), 30 deletions(-) create mode 100644 .changeset/soft-oranges-relate.md create mode 100644 packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.test.ts create mode 100644 packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.ts create mode 100644 packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/index.ts create mode 100644 packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/types.ts create mode 100644 packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.test.ts create mode 100644 packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.ts create mode 100644 packages/evmApi/integration/mocks/endpoints/getInternalTransactions.ts create mode 100644 packages/evmApi/integration/test/getInternalTransactions.test.ts diff --git a/.changeset/soft-oranges-relate.md b/.changeset/soft-oranges-relate.md new file mode 100644 index 0000000000..ea5a128685 --- /dev/null +++ b/.changeset/soft-oranges-relate.md @@ -0,0 +1,6 @@ +--- +'@moralisweb3/common-evm-utils': minor +'@moralisweb3/evm-api': minor +--- + +Add internal transactions param to several operations and `Moralis.Evm.transaction.getInternalTransactions()` diff --git a/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.test.ts b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.test.ts new file mode 100644 index 0000000000..9c896e86d1 --- /dev/null +++ b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.test.ts @@ -0,0 +1,109 @@ +import { Core } from '@moralisweb3/common-core'; +import { EvmInternalTransaction } from './EvmInternalTransaction'; +import { setupEvmUtils } from '../../test/setup'; +import { EvmInternalTransactionInput } from './types'; + +const exampleInput: EvmInternalTransactionInput = { + chain: '0x1', + transactionHash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + blockNumber: 16876143, + blockHash: '0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e', + type: 'STATICCALL', + from: '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', + to: '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85', + value: '100000', + gas: '263200', + gasUsed: '2569', + input: '0x96e494e8d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa', + output: '0x0000000000000000000000000000000000000000000000000000000000000001', +}; + +describe('EvmInternalTransaction', () => { + let core: Core; + + beforeAll(() => { + core = setupEvmUtils(); + }); + + beforeEach(() => { + core.config.reset(); + }); + + /** + * Creation + */ + it('should create a new EvmInternalTransaction', () => { + const transaction = EvmInternalTransaction.create(exampleInput); + + expect(transaction.chain.hex).toBe('0x1'); + expect(transaction.transactionHash).toBe('0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d'); + expect(transaction.blockNumber.toString()).toBe('16876143'); + expect(transaction.blockHash).toBe('0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e'); + expect(transaction.type).toBe('STATICCALL'); + expect(transaction.from.lowercase).toBe('0x283af0b28c62c092c9727f1ee09c02ca627eb7f5'); + expect(transaction.to.lowercase).toBe('0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85'); + expect(transaction.value.toString()).toBe('100000'); + expect(transaction.gas.toString()).toBe('263200'); + expect(transaction.gasUsed.toString()).toBe('2569'); + expect(transaction.input).toBe('0x96e494e8d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa'); + expect(transaction.output).toBe('0x0000000000000000000000000000000000000000000000000000000000000001'); + }); + + /** + * Formatting + */ + it('should return formatting in json', () => { + const transaction = EvmInternalTransaction.create(exampleInput); + + const value = transaction.toJSON(); + + expect(value).toStrictEqual({ + chain: '0x1', + from: '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', + to: '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85', + transactionHash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + gas: '263200', + gasUsed: '2569', + blockNumber: '16876143', + blockHash: '0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e', + input: '0x96e494e8d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa', + output: '0x0000000000000000000000000000000000000000000000000000000000000001', + value: '100000', + type: 'STATICCALL', + }); + }); + + /** + * Methods + */ + it('should check equality of 2 transactions of the same value', () => { + const transactionA = EvmInternalTransaction.create(exampleInput); + const transactionB = EvmInternalTransaction.create(exampleInput); + + expect(transactionA.equals(transactionB)).toBeTruthy(); + }); + + it('should check equality of 2 transactions of the same value via a static method', () => { + const transactionA = EvmInternalTransaction.create(exampleInput); + const transactionB = EvmInternalTransaction.create(exampleInput); + + expect(EvmInternalTransaction.equals(transactionA, transactionB)).toBeTruthy(); + }); + + it('should check inequality when chain is different', () => { + const transactionA = EvmInternalTransaction.create(exampleInput); + const transactionB = EvmInternalTransaction.create({ ...exampleInput, chain: '0x2' }); + + expect(transactionA.equals(transactionB)).toBeFalsy(); + }); + + it('should check inequality when transactionHash is different', () => { + const transactionA = EvmInternalTransaction.create(exampleInput); + const transactionB = EvmInternalTransaction.create({ + ...exampleInput, + transactionHash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7xxxxxxxx', + }); + + expect(transactionA.equals(transactionB)).toBeFalsy(); + }); +}); diff --git a/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.ts b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.ts new file mode 100644 index 0000000000..da09112db7 --- /dev/null +++ b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/EvmInternalTransaction.ts @@ -0,0 +1,169 @@ +import Core, { MoralisDataObject, BigNumber, CoreProvider } from '@moralisweb3/common-core'; +import { EvmAddress } from '../EvmAddress'; +import { EvmChain } from '../EvmChain'; +import { EvmInternalTransactionInput, EvmInternalTransactionData } from './types'; + +/** + * Valid input for a new EvmInternalTransaction instance. + * This can be an existing {@link EvmInternalTransaction} or a valid {@link EvmInternalTransactionInput} object + */ +export type EvmInternalTransactionish = EvmInternalTransactionInput | EvmInternalTransaction; + +/** + * The EvmTranaction is a representation of a published transaction. + * + * Use this class any time you work with a transaction. + * + * @category DataType + */ +export class EvmInternalTransaction implements MoralisDataObject { + /** + * Create a new instance of EvmInternalTransaction from any valid transaction input + * @param data - the EvmInternalTransactionish type + * @example + * ``` + * const transaction = EvmInternalTransaction.create(data); + *``` + */ + static create(data: EvmInternalTransactionish, core?: Core) { + if (data instanceof EvmInternalTransaction) { + return data; + } + const finalCore = core ?? CoreProvider.getDefault(); + return new EvmInternalTransaction(data, finalCore); + } + + private _data: EvmInternalTransactionData; + + constructor(data: EvmInternalTransactionInput, core: Core) { + this._data = EvmInternalTransaction.parse(data, core); + } + + static parse = (data: EvmInternalTransactionInput, core: Core): EvmInternalTransactionData => ({ + chain: EvmChain.create(data.chain), + from: EvmAddress.create(data.from, core), + to: EvmAddress.create(data.to, core), + transactionHash: data.transactionHash, + gas: BigNumber.create(data.gas), + gasUsed: BigNumber.create(data.gasUsed), + blockNumber: BigNumber.create(data.blockNumber), + blockHash: data.blockHash, + input: data.input, + output: data.output, + value: BigNumber.create(data.value), + type: data.type, + }); + + /** + * Check the equality between two Evm internal transactions + * @param dataA - The first transaction + * @param dataB - The second transaction + * @example + * ```ts + * EvmInternalTransaction.equals(dataA, dataB) + * ``` + */ + static equals(dataA: EvmInternalTransactionish, dataB: EvmInternalTransactionish) { + const transactionA = EvmInternalTransaction.create(dataA); + const transactionB = EvmInternalTransaction.create(dataB); + + if (!transactionA._data.chain.equals(transactionB._data.chain)) { + return false; + } + + if (transactionA._data.transactionHash !== transactionB._data.transactionHash) { + return false; + } + + return true; + } + + /** + * Checks the equality of the current transaction with another evm transaction + * @param data - the transaction to compare with + * @example + * ```ts + * transaction.equals(data) + * ``` + */ + equals(data: EvmInternalTransactionish): boolean { + return EvmInternalTransaction.equals(this, data); + } + + toJSON() { + const data = this._data; + return { + ...data, + to: data.to?.format(), + from: data.from?.format(), + gas: data.gas?.toString(), + gasUsed: data.gasUsed?.toString(), + value: data.value?.toString(), + chain: data.chain?.format(), + blockNumber: data.blockNumber?.toString(), + }; + } + + /** + * @returns a JSON represention of the transaction. + * @example + * ``` + * transaction.format() + * ``` + */ + format() { + return this.toJSON(); + } + + get result() { + return this._data; + } + + get chain() { + return this._data.chain; + } + + get transactionHash() { + return this._data.transactionHash; + } + + get blockNumber() { + return this._data.blockNumber; + } + + get blockHash() { + return this._data.blockHash; + } + + get type() { + return this._data.type; + } + + get from() { + return this._data.from; + } + + get to() { + return this._data.to; + } + + get value() { + return this._data.value; + } + + get gas() { + return this._data.gas; + } + + get gasUsed() { + return this._data.gasUsed; + } + + get input() { + return this._data.input; + } + + get output() { + return this._data.output; + } +} diff --git a/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/index.ts b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/index.ts new file mode 100644 index 0000000000..42212eefa9 --- /dev/null +++ b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/index.ts @@ -0,0 +1,2 @@ +export * from './EvmInternalTransaction'; +export * from './types'; diff --git a/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/types.ts b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/types.ts new file mode 100644 index 0000000000..2a4841a11f --- /dev/null +++ b/packages/common/evmUtils/src/dataTypes/EvmInternalTransaction/types.ts @@ -0,0 +1,57 @@ +import { BigNumber, BigNumberish } from '@moralisweb3/common-core'; +import { EvmAddressish, EvmAddress } from '../EvmAddress'; +import { EvmChain, EvmChainish } from '../EvmChain'; + +/** + * Valid EvmInternalTransactionLog input. + * + * @example + * ```ts + * const input = { + * "chain": "0x1", + * "transactionHash": "0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d", + * "block_number": 16876143, + * "block_hash": "0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e", + * "type": "STATICCALL", + * "from": "0x283af0b28c62c092c9727f1ee09c02ca627eb7f5", + * "to": "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85", + * "value": "0", + * "gas": "263200", + * "gas_used": "2569", + * "input": "0x96e494e8d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa", + * "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + * } + * ``` + */ +export interface EvmInternalTransactionInput { + chain: EvmChainish; + transactionHash: string; + blockNumber: BigNumberish; + blockHash: string; + type: string; + from: EvmAddressish; + to: EvmAddressish; + value: BigNumberish; + gas: BigNumberish; + gasUsed: BigNumberish; + input: string; + output: string; +} + +/** + * Represents a processed internal transaction log. + */ +export interface EvmInternalTransactionData { + chain: EvmChain; + transactionHash: string; + blockNumber: BigNumber; + blockHash: string; + type: string; + from: EvmAddress; + to: EvmAddress; + value: BigNumber; + gas: BigNumber; + gasUsed: BigNumber; + input: string; + output: string; +} diff --git a/packages/common/evmUtils/src/dataTypes/EvmTransaction/EvmTransaction.ts b/packages/common/evmUtils/src/dataTypes/EvmTransaction/EvmTransaction.ts index f1006ae05f..764b1bb76f 100644 --- a/packages/common/evmUtils/src/dataTypes/EvmTransaction/EvmTransaction.ts +++ b/packages/common/evmUtils/src/dataTypes/EvmTransaction/EvmTransaction.ts @@ -5,6 +5,7 @@ import { EvmNative } from '../EvmNative'; import { EvmTransactionLog } from '../EvmTransactionLog'; import { EvmSignature } from '../EvmSignature/EvmSignature'; import { EvmTransactionInput, EvmTransactionData } from './types'; +import { EvmInternalTransaction } from '../EvmInternalTransaction'; /** * Valid input for a new EvmTransaction instance. @@ -69,6 +70,9 @@ export class EvmTransaction implements MoralisDataObject { receiptStatus: maybe(data.receiptStatus, (status) => +status), logs: (data.logs ?? []).map((log) => EvmTransactionLog.create(log)), + internalTransactions: (data.internalTransactions ?? []).map((transaction) => + EvmInternalTransaction.create(transaction), + ), signature: maybe(data.signature, EvmSignature.create), }); @@ -124,6 +128,7 @@ export class EvmTransaction implements MoralisDataObject { chain: data.chain?.format(), contractAddress: data.contractAddress?.format(), logs: data.logs.map((log) => log.toJSON()), + internalTransactions: data.internalTransactions.map((transaction) => transaction.toJSON()), signature: data.signature?.toJSON(), blockNumber: data.blockNumber?.toString(), blockTimestamp: data.blockTimestamp.toString(), @@ -273,6 +278,17 @@ export class EvmTransaction implements MoralisDataObject { return this._data.contractAddress; } + /** + * @returns the internal transactions + * @example + * ``` + * transaction.logs // EvmInternalTransaction[] + * ``` + */ + get internalTransactions() { + return this._data.internalTransactions; + } + /** * @returns the transaction logs * @example diff --git a/packages/common/evmUtils/src/dataTypes/EvmTransaction/types.ts b/packages/common/evmUtils/src/dataTypes/EvmTransaction/types.ts index 3760395d1c..e305a70f20 100644 --- a/packages/common/evmUtils/src/dataTypes/EvmTransaction/types.ts +++ b/packages/common/evmUtils/src/dataTypes/EvmTransaction/types.ts @@ -4,6 +4,7 @@ import { EvmChain, EvmChainish } from '../EvmChain'; import { EvmNativeish, EvmNative } from '../EvmNative'; import { EvmTransactionLogish, EvmTransactionLog } from '../EvmTransactionLog'; import { EvmSignature, EvmSignatureish } from '../EvmSignature/EvmSignature'; +import { EvmInternalTransaction, EvmInternalTransactionish } from '../EvmInternalTransaction'; /** * This can be any object with valid transaction data. @@ -64,6 +65,7 @@ export interface EvmTransactionInput { receiptStatus?: null | string | number; logs?: EvmTransactionLogish[]; + internalTransactions?: EvmInternalTransactionish[]; signature?: EvmSignatureish; } @@ -99,6 +101,7 @@ export interface EvmTransactionData { receiptStatus?: number; logs: EvmTransactionLog[]; + internalTransactions: EvmInternalTransaction[]; signature?: EvmSignature; } diff --git a/packages/common/evmUtils/src/dataTypes/index.ts b/packages/common/evmUtils/src/dataTypes/index.ts index 259e33b2f0..d575359dd5 100644 --- a/packages/common/evmUtils/src/dataTypes/index.ts +++ b/packages/common/evmUtils/src/dataTypes/index.ts @@ -8,6 +8,7 @@ export * from './EvmBlock'; export * from './EvmBlockDate'; export * from './EvmChain'; export * from './EvmEvent'; +export * from './EvmInternalTransaction'; export * from './EvmNative'; export * from './EvmNft'; export * from './EvmNftCollection'; diff --git a/packages/common/evmUtils/src/operations/block/getBlockOperation.test.ts b/packages/common/evmUtils/src/operations/block/getBlockOperation.test.ts index a719d5c7dc..c89ae1c86b 100644 --- a/packages/common/evmUtils/src/operations/block/getBlockOperation.test.ts +++ b/packages/common/evmUtils/src/operations/block/getBlockOperation.test.ts @@ -15,6 +15,7 @@ describe('getBlockOperation', () => { const request: Required = { blockNumberOrHash: '0x123', chain: EvmChain.create(chain, core), + include: 'internal_transactions', }; const serializedRequest = getBlockOperation.serializeRequest(request, core); diff --git a/packages/common/evmUtils/src/operations/block/getBlockOperation.ts b/packages/common/evmUtils/src/operations/block/getBlockOperation.ts index a46f9f6da7..c6791b529d 100644 --- a/packages/common/evmUtils/src/operations/block/getBlockOperation.ts +++ b/packages/common/evmUtils/src/operations/block/getBlockOperation.ts @@ -1,5 +1,13 @@ import { Core, Camelize, Operation, toCamelCase, ResponseAdapter } from '@moralisweb3/common-core'; -import { EvmBlock, EvmChain, EvmChainish, EvmTransaction, EvmTransactionLog, LogTopic } from '../../dataTypes'; +import { + EvmBlock, + EvmChain, + EvmChainish, + EvmInternalTransaction, + EvmTransaction, + EvmTransactionLog, + LogTopic, +} from '../../dataTypes'; import { EvmChainResolver } from '../../EvmChainResolver'; import { operations } from '../openapi'; @@ -39,7 +47,7 @@ export const getBlockOperation: Operation< isNullable: true, urlPathPattern: '/block/{blockNumberOrHash}', urlPathParamNames: ['blockNumberOrHash'], - urlSearchParamNames: ['chain'], + urlSearchParamNames: ['chain', 'include'], getRequestUrlParams, serializeRequest, @@ -53,6 +61,7 @@ function getRequestUrlParams(request: GetBlockRequest, core: Core) { return { chain: EvmChainResolver.resolve(request.chain, core).apiHex, blockNumberOrHash: request.blockNumberOrHash, + include: request.include, }; } @@ -103,6 +112,13 @@ function deserializeResponse(jsonResponse: GetBlockJSONResponse, request: GetBlo transactionIndex: +log.transactionIndex, }); }), + internalTransactions: (transaction.internalTransactions ?? []).map((jsonInternalTransaction) => { + const internalTransaction = toCamelCase(jsonInternalTransaction); + return EvmInternalTransaction.create({ + chain, + ...internalTransaction, + }); + }), }, core, ), @@ -116,6 +132,7 @@ function serializeRequest(request: GetBlockRequest, core: Core) { return { chain: EvmChainResolver.resolve(request.chain, core).apiHex, blockNumberOrHash: request.blockNumberOrHash, + include: request.include, }; } @@ -123,5 +140,6 @@ function deserializeRequest(jsonRequest: GetBlockJSONRequest, core: Core): GetBl return { chain: EvmChain.create(jsonRequest.chain, core), blockNumberOrHash: jsonRequest.blockNumberOrHash, + include: jsonRequest.include, }; } diff --git a/packages/common/evmUtils/src/operations/openapi.ts b/packages/common/evmUtils/src/operations/openapi.ts index 8a3c603d23..c6cb94562c 100644 --- a/packages/common/evmUtils/src/operations/openapi.ts +++ b/packages/common/evmUtils/src/operations/openapi.ts @@ -156,6 +156,10 @@ export interface paths { /** Get native transactions and logs ordered by block number in descending order. */ get: operations["getWalletTransactionsVerbose"]; }; + "/transaction/{transaction_hash}/internal-transactions": { + /** Get the contents of a internal transaction by transaction hash. */ + get: operations["getInternalTransactions"]; + }; "/transaction/{transaction_hash}": { /** Get the contents of a transaction by the given transaction hash. */ get: operations["getTransaction"]; @@ -472,6 +476,8 @@ export interface components { block_hash: string; /** @description The logs of the transaction */ logs?: components["schemas"]["log"][]; + /** @description The internal transactions of the transaction */ + internal_transactions?: components["schemas"]["internalTransaction"][]; }; block: { /** @@ -741,6 +747,65 @@ export interface components { * @example 0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86 */ block_hash: string; + /** @description The internal transaction */ + internal_transactions?: components["schemas"]["internalTransaction"][]; + }; + internalTransaction: { + /** + * @description The hash of the transaction + * @example 0x057Ec652A4F150f7FF94f089A38008f49a0DF88e + */ + transaction_hash: string; + /** + * @description The block number + * @example 12526958 + */ + block_number: string; + /** + * @description The block hash + * @example 0x0372c302e3c52e8f2e15d155e2c545e6d802e479236564af052759253b20fd86 + */ + block_hash: string; + /** + * @description Call type + * @example CALL + */ + type: string; + /** + * @description The sender + * @example 0xd4a3BebD824189481FC45363602b83C9c7e9cbDf + */ + from: string; + /** + * @description The recipient + * @example 0xa71db868318f0a0bae9411347cd4a6fa23d8d4ef + */ + to: string; + /** + * @description The value that was transfered (in wei) + * @example 650000000000000000 + */ + value: string; + /** + * @description The gas of the transaction + * @example 6721975 + */ + gas: string; + /** + * @description The used gas + * @example 6721975 + */ + gas_used: string; + /** + * @description The input + * @example 0x + */ + input: string; + /** + * @description The output + * @example 0x + */ + output: string; }; erc20Allowance: { /** @description The allowance */ @@ -862,6 +927,12 @@ export interface components { page_size?: number; result?: components["schemas"]["trade"][]; }; + /** + * @default + * @example internal_transactions + * @enum {string} + */ + includeList: "internal_transactions"; /** * @default eth * @example eth @@ -2783,6 +2854,8 @@ export interface operations { limit?: number; /** If the result should skip returning the total count (Improves performance). */ disable_total?: boolean; + /** If the result should contain the internal transactions. */ + include?: components["schemas"]["includeList"]; }; path: { /** The address of the wallet */ @@ -2849,12 +2922,35 @@ export interface operations { }; }; }; + /** Get the contents of a internal transaction by transaction hash. */ + getInternalTransactions: { + parameters: { + query: { + /** The chain to query */ + chain?: components["schemas"]["chainList"]; + }; + path: { + /** The transaction hash */ + transaction_hash: string; + }; + }; + responses: { + /** Internal Transaction details by transaction hash */ + 200: { + content: { + "application/json": components["schemas"]["internalTransaction"][]; + }; + }; + }; + }; /** Get the contents of a transaction by the given transaction hash. */ getTransaction: { parameters: { query: { /** The chain to query */ chain?: components["schemas"]["chainList"]; + /** If the result should contain the internal transactions. */ + include?: components["schemas"]["includeList"]; }; path: { /** The transaction hash */ @@ -2876,6 +2972,8 @@ export interface operations { query: { /** The chain to query */ chain?: components["schemas"]["chainList"]; + /** If the result should contain the internal transactions. */ + include?: components["schemas"]["includeList"]; }; path: { /** The block number or block hash */ diff --git a/packages/common/evmUtils/src/operations/operations.ts b/packages/common/evmUtils/src/operations/operations.ts index 9fa462ce71..4d3be2afde 100644 --- a/packages/common/evmUtils/src/operations/operations.ts +++ b/packages/common/evmUtils/src/operations/operations.ts @@ -32,15 +32,15 @@ import { getTokenTransfersOperation, getWalletTokenBalancesOperation, getErc20MintsOperation, + getWalletTokenTransfersOperation, } from './token'; -import { getWalletTokenTransfersOperation } from './token/getWalletTokenTransfersOperation'; import { getTransactionOperation, getWalletTransactionsOperation, getWalletTransactionsVerboseOperation, + getInternalTransactionsOperation, } from './transaction'; -import { endpointWeightsOperation, web3ApiVersionOperation } from './utils'; -import { runContractFunctionOperation } from './utils/runContractFunctionOperation'; +import { endpointWeightsOperation, web3ApiVersionOperation, runContractFunctionOperation } from './utils'; export const operations = [ endpointWeightsOperation, @@ -50,6 +50,7 @@ export const operations = [ getContractNFTsOperation, getDateToBlockOperation, getErc20MintsOperation, + getInternalTransactionsOperation, getMultipleNFTsOperation, getNativeBalanceOperation, getNativeBalancesForAddressesOperation, diff --git a/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.test.ts b/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.test.ts new file mode 100644 index 0000000000..7be0b20968 --- /dev/null +++ b/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.test.ts @@ -0,0 +1,30 @@ +import MoralisCore from '@moralisweb3/common-core'; +import { EvmChain } from '../../dataTypes'; +import { getInternalTransactionsOperation, GetInternalTransactionsRequest } from './getInternalTransactionsOperation'; + +describe('getInternalTransactionsOperation', () => { + let core: MoralisCore; + + beforeAll(() => { + core = MoralisCore.create(); + }); + + it('serializeRequest() serializes correctly and deserializeRequest() deserializes correctly', () => { + const chain = '0x10'; + + const request: Required = { + chain: EvmChain.create(chain, core), + transactionHash: '0x9857d679ab331210161427d36d08c3b00e6d28c03366e9b891832ad9b5d478f7z', + }; + + const serializedRequest = getInternalTransactionsOperation.serializeRequest(request, core); + + expect(serializedRequest.chain).toBe(chain); + expect(serializedRequest.transactionHash).toBe(request.transactionHash); + + const deserializedRequest = getInternalTransactionsOperation.deserializeRequest(serializedRequest, core); + + expect((deserializedRequest.chain as EvmChain).apiHex).toBe(chain); + expect(deserializedRequest.transactionHash).toBe(request.transactionHash); + }); +}); diff --git a/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.ts b/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.ts new file mode 100644 index 0000000000..6cee57451d --- /dev/null +++ b/packages/common/evmUtils/src/operations/transaction/getInternalTransactionsOperation.ts @@ -0,0 +1,103 @@ +import { Core, Camelize, Operation, ResponseAdapter } from '@moralisweb3/common-core'; +import { EvmChain, EvmChainish, EvmInternalTransaction } from '../../dataTypes'; +import { EvmChainResolver } from '../../EvmChainResolver'; +import { operations } from '../openapi'; + +type OperationId = 'getInternalTransactions'; + +type PathParams = operations[OperationId]['parameters']['path']; + +type QueryParams = operations[OperationId]['parameters']['query']; + +type RequestParams = PathParams & QueryParams; + +type SuccessResponse = operations[OperationId]['responses']['200']['content']['application/json']; + +// Exports + +export interface GetInternalTransactionsRequest extends Camelize> { + chain?: EvmChainish; +} + +export type GetInternalTransactionsJSONRequest = ReturnType; + +export type GetInternalTransactionsJSONResponse = SuccessResponse; + +export type GetInternalTransactionsResponse = ReturnType; + +export interface GetInternalTransactionsResponseAdapter + extends ResponseAdapter {} + +/** Get native transactions ordered by block number in descending order. */ +export const getInternalTransactionsOperation: Operation< + GetInternalTransactionsRequest, + GetInternalTransactionsJSONRequest, + GetInternalTransactionsResponse, + GetInternalTransactionsJSONResponse +> = { + method: 'GET', + name: 'getInternalTransactions', + id: 'getInternalTransactions', + groupName: 'transaction', + urlPathPattern: '/transaction/{transactionHash}/internal-transactions', + urlPathParamNames: ['transactionHash'], + urlSearchParamNames: ['chain'], + + getRequestUrlParams, + serializeRequest, + deserializeRequest, + deserializeResponse, +}; + +// Methods + +function getRequestUrlParams(request: GetInternalTransactionsRequest, core: Core) { + return { + chain: EvmChainResolver.resolve(request.chain, core).apiHex, + transactionHash: request.transactionHash, + }; +} + +function serializeRequest(request: GetInternalTransactionsRequest, core: Core) { + return { + chain: EvmChainResolver.resolve(request.chain, core).apiHex, + transactionHash: request.transactionHash, + }; +} + +function deserializeRequest( + jsonRequest: GetInternalTransactionsJSONRequest, + core: Core, +): GetInternalTransactionsRequest { + return { + chain: EvmChain.create(jsonRequest.chain, core), + transactionHash: jsonRequest.transactionHash, + }; +} + +function deserializeResponse( + jsonResponse: GetInternalTransactionsJSONResponse, + request: GetInternalTransactionsJSONRequest, + core: Core, +) { + return (jsonResponse ?? []).map((transaction) => { + const chain = EvmChainResolver.resolve(request.chain, core); + return EvmInternalTransaction.create( + { + chain, + blockHash: transaction.block_hash, + blockNumber: transaction.block_number, + from: transaction.from, + gas: transaction.gas, + gasUsed: transaction.gas_used, + input: transaction.input, + output: transaction.output, + to: transaction.to, + transactionHash: transaction.transaction_hash, + type: transaction.type, + value: transaction.value, + }, + core, + ); + }); +} diff --git a/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.test.ts b/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.test.ts index 60fe0d0601..99acd1749a 100644 --- a/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.test.ts +++ b/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.test.ts @@ -15,6 +15,7 @@ describe('getTransactionOperation', () => { const request: Required = { chain: EvmChain.create(chain, core), transactionHash: '0x9857d679ab331210161427d36d08c3b00e6d28c03366e9b891832ad9b5d478f7z', + include: 'internal_transactions', }; const serializedRequest = getTransactionOperation.serializeRequest(request, core); diff --git a/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.ts b/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.ts index 286d4945b9..15ed410d9b 100644 --- a/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.ts +++ b/packages/common/evmUtils/src/operations/transaction/getTransactionOperation.ts @@ -1,5 +1,12 @@ -import { Core, Camelize, Operation, ResponseAdapter } from '@moralisweb3/common-core'; -import { EvmChain, EvmChainish, EvmTransaction, EvmTransactionLog, LogTopic } from '../../dataTypes'; +import { Core, Camelize, Operation, ResponseAdapter, toCamelCase } from '@moralisweb3/common-core'; +import { + EvmChain, + EvmChainish, + EvmInternalTransaction, + EvmTransaction, + EvmTransactionLog, + LogTopic, +} from '../../dataTypes'; import { EvmChainResolver } from '../../EvmChainResolver'; import { operations } from '../openapi'; @@ -40,7 +47,7 @@ export const getTransactionOperation: Operation< isNullable: true, urlPathPattern: '/transaction/{transactionHash}', urlPathParamNames: ['transactionHash'], - urlSearchParamNames: ['chain'], + urlSearchParamNames: ['chain', 'include'], getRequestUrlParams, serializeRequest, @@ -52,6 +59,7 @@ function getRequestUrlParams(request: GetTransactionRequest, core: Core) { return { chain: EvmChainResolver.resolve(request.chain, core).apiHex, transactionHash: request.transactionHash, + include: request.include, }; } @@ -59,6 +67,7 @@ function serializeRequest(request: GetTransactionRequest, core: Core) { return { chain: EvmChainResolver.resolve(request.chain, core).apiHex, transactionHash: request.transactionHash, + include: request.include, }; } @@ -66,10 +75,12 @@ function deserializeRequest(jsonRequest: GetTransactionJSONRequest, core: Core): return { chain: EvmChain.create(jsonRequest.chain, core), transactionHash: jsonRequest.transactionHash, + include: jsonRequest.include, }; } //TODO: I noticed that the docs comes with a type of "string | unknown" which automatically resolves to "unknown". I think we should fix this in the api, casting for now function deserializeResponse(jsonResponse: GetTransactionJSONResponse, request: GetTransactionJSONRequest, core: Core) { + const chain = EvmChainResolver.resolve(request.chain, core); return EvmTransaction.create( { from: jsonResponse.from_address, @@ -83,7 +94,7 @@ function deserializeResponse(jsonResponse: GetTransactionJSONResponse, request: blockNumber: jsonResponse.block_number, blockTimestamp: jsonResponse.block_timestamp, index: jsonResponse.transaction_index, - chain: EvmChainResolver.resolve(request.chain, core), + chain, hash: jsonResponse.hash, gas: jsonResponse.gas, cumulativeGasUsed: jsonResponse.receipt_cumulative_gas_used, @@ -101,11 +112,18 @@ function deserializeResponse(jsonResponse: GetTransactionJSONResponse, request: blockTimestamp: log.block_timestamp, logIndex: +log.log_index, transactionIndex: +log.transaction_index, - chain: EvmChainResolver.resolve(request.chain, core), + chain, }, core, ), ), + internalTransactions: (jsonResponse.internal_transactions ?? []).map((jsonInternalTransaction) => { + const internalTransaction = toCamelCase(jsonInternalTransaction); + return EvmInternalTransaction.create({ + chain, + ...internalTransaction, + }); + }), receiptRoot: jsonResponse.receipt_root as string, receiptStatus: jsonResponse.receipt_status, }, diff --git a/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.test.ts b/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.test.ts index ce70f6b0b8..357f3561c5 100644 --- a/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.test.ts +++ b/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.test.ts @@ -25,6 +25,7 @@ describe('getWalletTransactionsOperation', () => { cursor: 'CURSOR1', limit: 333, disableTotal: true, + include: 'internal_transactions', }; const serializedRequest = getWalletTransactionsOperation.serializeRequest(request, core); diff --git a/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.ts b/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.ts index ba9b726e6b..828240b98d 100644 --- a/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.ts +++ b/packages/common/evmUtils/src/operations/transaction/getWalletTransactionsOperation.ts @@ -6,8 +6,16 @@ import { BigNumber, DateInput, PaginatedResponseAdapter, + toCamelCase, } from '@moralisweb3/common-core'; -import { EvmChain, EvmChainish, EvmAddress, EvmAddressish, EvmTransaction } from '../../dataTypes'; +import { + EvmChain, + EvmChainish, + EvmAddress, + EvmAddressish, + EvmTransaction, + EvmInternalTransaction, +} from '../../dataTypes'; import { EvmChainResolver } from '../../EvmChainResolver'; import { operations } from '../openapi'; @@ -53,7 +61,17 @@ export const getWalletTransactionsOperation: PaginatedOperation< groupName: 'transaction', urlPathPattern: '/{address}', urlPathParamNames: ['address'], - urlSearchParamNames: ['chain', 'fromBlock', 'toBlock', 'fromDate', 'toDate', 'cursor', 'limit', 'disableTotal'], + urlSearchParamNames: [ + 'chain', + 'fromBlock', + 'toBlock', + 'fromDate', + 'toDate', + 'cursor', + 'limit', + 'disableTotal', + 'include', + ], firstPageIndex: 0, getRequestUrlParams, @@ -75,6 +93,7 @@ function getRequestUrlParams(request: GetWalletTransactionsRequest, core: Core) limit: maybe(request.limit, String), address: EvmAddress.create(request.address, core).lowercase, disable_total: request.disableTotal, + include: request.include, }; } @@ -89,6 +108,7 @@ function serializeRequest(request: GetWalletTransactionsRequest, core: Core) { limit: request.limit, address: EvmAddress.create(request.address, core).checksum, disableTotal: request.disableTotal, + include: request.include, }; } @@ -103,6 +123,7 @@ function deserializeRequest(jsonRequest: GetWalletTransactionsJSONRequest, core: limit: jsonRequest.limit, address: EvmAddress.create(jsonRequest.address, core), disableTotal: jsonRequest.disableTotal, + include: jsonRequest.include, }; } @@ -111,8 +132,9 @@ function deserializeResponse( request: GetWalletTransactionsJSONRequest, core: Core, ) { - return (jsonResponse.result ?? []).map((transfer) => - EvmTransaction.create( + return (jsonResponse.result ?? []).map((transfer) => { + const chain = EvmChainResolver.resolve(request.chain, core); + return EvmTransaction.create( { cumulativeGasUsed: transfer.receipt_cumulative_gas_used, gasPrice: transfer.gas_price, @@ -132,8 +154,15 @@ function deserializeResponse( blockTimestamp: new Date(transfer.block_timestamp), gas: transfer.gas ? BigNumber.create(transfer.gas as string) : null, to: transfer.to_address ? (transfer.to_address as string) : null, + internalTransactions: (transfer.internal_transactions ?? []).map((jsonInternalTransaction) => { + const internalTransaction = toCamelCase(jsonInternalTransaction); + return EvmInternalTransaction.create({ + chain, + ...internalTransaction, + }); + }), }, core, - ), - ); + ); + }); } diff --git a/packages/common/evmUtils/src/operations/transaction/index.ts b/packages/common/evmUtils/src/operations/transaction/index.ts index 402239cf4f..647fef0aca 100644 --- a/packages/common/evmUtils/src/operations/transaction/index.ts +++ b/packages/common/evmUtils/src/operations/transaction/index.ts @@ -1,3 +1,4 @@ export * from './getTransactionOperation'; export * from './getWalletTransactionsOperation'; export * from './getWalletTransactionsVerboseOperation'; +export * from './getInternalTransactionsOperation'; diff --git a/packages/evmApi/integration/mocks/endpoints/getInternalTransactions.ts b/packages/evmApi/integration/mocks/endpoints/getInternalTransactions.ts new file mode 100644 index 0000000000..578f196052 --- /dev/null +++ b/packages/evmApi/integration/mocks/endpoints/getInternalTransactions.ts @@ -0,0 +1,56 @@ +import { MockScenarios } from '@moralisweb3/test-utils'; + +export const mockGetInternalTransaction = MockScenarios.create( + { + method: 'get', + name: 'mockGetInternalTransaction', + url: '/transaction/:transactionHash/internal-transactions', + getParams: ({ req }) => ({ + transactionHash: req.params.transactionHash, + chain: req.url.searchParams.get('chain'), + }), + }, + [ + { + condition: { + transactionHash: '0xb796997765a2274d26df7ded20536e5fb9d53e56562d3cb0fbe867d695e3f2ff', + chain: '0x1', + }, + response: [], + }, + { + condition: { + transactionHash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + chain: '0x1', + }, + response: [ + { + transaction_hash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + block_number: 16876143, + block_hash: '0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e', + type: 'STATICCALL', + from: '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', + to: '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85', + value: '0', + gas: '263200', + gas_used: '2569', + input: '0x96e494e8d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa', + output: '0x0000000000000000000000000000000000000000000000000000000000000001', + }, + { + transaction_hash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + block_number: 16876143, + block_hash: '0xc8d7592122307a771c5172af09699b5a2d36fa540d0fbc656f3d52c619c7536e', + type: 'STATICCALL', + from: '0x283af0b28c62c092c9727f1ee09c02ca627eb7f5', + to: '0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85', + value: '0', + gas: '254917', + gas_used: '523', + input: '0xd6e4fa86d40a37cd10c71cb3896d1b05b6c707e29cb5aeff0278c6fc7e5e5b31623a1baa', + output: '0x0000000000000000000000000000000000000000000000000000000000000000', + }, + ], + }, + ], +); diff --git a/packages/evmApi/integration/mocks/mockServer.ts b/packages/evmApi/integration/mocks/mockServer.ts index e1e79f17a1..41e8661b72 100644 --- a/packages/evmApi/integration/mocks/mockServer.ts +++ b/packages/evmApi/integration/mocks/mockServer.ts @@ -43,10 +43,12 @@ import { mockSearchNFTs } from './endpoints/searchNFTs'; import { mockSyncNFTContract } from './endpoints/syncNFTContract'; import { mockGetMultipleNFTs } from './endpoints/getMultipleNFTs'; import { mockGetErc20Mints } from './endpoints/getErc20Mints'; +import { mockGetInternalTransaction } from './endpoints/getInternalTransactions'; const handler = [ mockGetDateToBlock, mockGetNFTContractTransfers, + mockGetInternalTransaction, mockGetTransaction, mockGetWalletTransactionsVerbose, mockGetWalletTransactions, diff --git a/packages/evmApi/integration/test/getInternalTransactions.test.ts b/packages/evmApi/integration/test/getInternalTransactions.test.ts new file mode 100644 index 0000000000..01a439fbf2 --- /dev/null +++ b/packages/evmApi/integration/test/getInternalTransactions.test.ts @@ -0,0 +1,37 @@ +import { EvmApi } from '../../src/EvmApi'; +import { cleanEvmApi, setupEvmApi } from '../setup'; + +describe('getInternalTransactions', () => { + let evmApi: EvmApi; + + beforeAll(() => { + evmApi = setupEvmApi(); + }); + + afterAll(() => { + cleanEvmApi(); + }); + + it('handles empty response', async () => { + const { result } = await evmApi.transaction.getInternalTransactions({ + transactionHash: '0xb796997765a2274d26df7ded20536e5fb9d53e56562d3cb0fbe867d695e3f2ff', + }); + + expect(result).toStrictEqual([]); + }); + + it('returns properly internal transaction', async () => { + const { result } = await evmApi.transaction.getInternalTransactions({ + transactionHash: '0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d', + }); + + expect(result).toBeDefined(); + const [transaction] = result; + + expect(transaction).toBeDefined(); + expect(transaction.transactionHash).toEqual('0x2ac6283fb30fe33499416b0388ff27145a0eeb6aa8b37bca40af87d7f1c74e2d'); + expect(transaction.type).toEqual('STATICCALL'); + expect(transaction.gas?.toString()).toEqual('263200'); + expect(transaction.gasUsed?.toString()).toEqual('2569'); + }); +}); diff --git a/packages/evmApi/src/generated/ClientEvmApi.ts b/packages/evmApi/src/generated/ClientEvmApi.ts index d96e93f708..5841a8566f 100644 --- a/packages/evmApi/src/generated/ClientEvmApi.ts +++ b/packages/evmApi/src/generated/ClientEvmApi.ts @@ -1,6 +1,6 @@ // CAUTION: This file is automatically generated. Do not edit it manually! -import { endpointWeightsOperation, EndpointWeightsResponseAdapter, runContractFunctionOperation, RunContractFunctionRequest, RunContractFunctionResponseAdapter, web3ApiVersionOperation, Web3ApiVersionResponseAdapter, getBlockOperation, GetBlockRequest, GetBlockResponseAdapter, getDateToBlockOperation, GetDateToBlockRequest, GetDateToBlockResponseAdapter, getContractEventsOperation, GetContractEventsRequest, GetContractEventsResponseAdapter, getContractLogsOperation, GetContractLogsRequest, GetContractLogsResponseAdapter, getContractNFTsOperation, GetContractNFTsRequest, GetContractNFTsResponseAdapter, getMultipleNFTsOperation, GetMultipleNFTsRequest, GetMultipleNFTsResponseAdapter, getNFTContractMetadataOperation, GetNFTContractMetadataRequest, GetNFTContractMetadataResponseAdapter, getNFTContractTransfersOperation, GetNFTContractTransfersRequest, GetNFTContractTransfersResponseAdapter, getNFTLowestPriceOperation, GetNFTLowestPriceRequest, GetNFTLowestPriceResponseAdapter, getNFTMetadataOperation, GetNFTMetadataRequest, GetNFTMetadataResponseAdapter, getNFTOwnersOperation, GetNFTOwnersRequest, GetNFTOwnersResponseAdapter, getNFTTokenIdOwnersOperation, GetNFTTokenIdOwnersRequest, GetNFTTokenIdOwnersResponseAdapter, getNFTTradesOperation, GetNFTTradesRequest, GetNFTTradesResponseAdapter, getNFTTransfersByBlockOperation, GetNFTTransfersByBlockRequest, GetNFTTransfersByBlockResponseAdapter, getNFTTransfersFromToBlockOperation, GetNFTTransfersFromToBlockRequest, GetNFTTransfersFromToBlockResponseAdapter, getNFTTransfersOperation, GetNFTTransfersRequest, GetNFTTransfersResponseAdapter, getWalletNFTCollectionsOperation, GetWalletNFTCollectionsRequest, GetWalletNFTCollectionsResponseAdapter, getWalletNFTsOperation, GetWalletNFTsRequest, GetWalletNFTsResponseAdapter, getWalletNFTTransfersOperation, GetWalletNFTTransfersRequest, GetWalletNFTTransfersResponseAdapter, reSyncMetadataOperation, ReSyncMetadataRequest, ReSyncMetadataResponseAdapter, searchNFTsOperation, SearchNFTsRequest, SearchNFTsResponseAdapter, syncNFTContractOperation, SyncNFTContractRequest, SyncNFTContractResponseAdapter, getErc20MintsOperation, GetErc20MintsRequest, GetErc20MintsResponseAdapter, getTokenAllowanceOperation, GetTokenAllowanceRequest, GetTokenAllowanceResponseAdapter, getTokenMetadataBySymbolOperation, GetTokenMetadataBySymbolRequest, GetTokenMetadataBySymbolResponseAdapter, getTokenMetadataOperation, GetTokenMetadataRequest, GetTokenMetadataResponseAdapter, getTokenPriceOperation, GetTokenPriceRequest, GetTokenPriceResponseAdapter, getTokenTransfersOperation, GetTokenTransfersRequest, GetTokenTransfersResponseAdapter, getWalletTokenBalancesOperation, GetWalletTokenBalancesRequest, GetWalletTokenBalancesResponseAdapter, getWalletTokenTransfersOperation, GetWalletTokenTransfersRequest, GetWalletTokenTransfersResponseAdapter, getNativeBalanceOperation, GetNativeBalanceRequest, GetNativeBalanceResponseAdapter, getNativeBalancesForAddressesOperation, GetNativeBalancesForAddressesRequest, GetNativeBalancesForAddressesResponseAdapter, getPairAddressOperation, GetPairAddressRequest, GetPairAddressResponseAdapter, getPairReservesOperation, GetPairReservesRequest, GetPairReservesResponseAdapter, getTransactionOperation, GetTransactionRequest, GetTransactionResponseAdapter, getWalletTransactionsOperation, GetWalletTransactionsRequest, GetWalletTransactionsResponseAdapter, getWalletTransactionsVerboseOperation, GetWalletTransactionsVerboseRequest, GetWalletTransactionsVerboseResponseAdapter, resolveAddressOperation, ResolveAddressRequest, ResolveAddressResponseAdapter, resolveDomainOperation, ResolveDomainRequest, ResolveDomainResponseAdapter, uploadFolderOperation, UploadFolderRequest, UploadFolderResponseAdapter } from '@moralisweb3/common-evm-utils'; +import { endpointWeightsOperation, EndpointWeightsResponseAdapter, runContractFunctionOperation, RunContractFunctionRequest, RunContractFunctionResponseAdapter, web3ApiVersionOperation, Web3ApiVersionResponseAdapter, getBlockOperation, GetBlockRequest, GetBlockResponseAdapter, getDateToBlockOperation, GetDateToBlockRequest, GetDateToBlockResponseAdapter, getContractEventsOperation, GetContractEventsRequest, GetContractEventsResponseAdapter, getContractLogsOperation, GetContractLogsRequest, GetContractLogsResponseAdapter, getContractNFTsOperation, GetContractNFTsRequest, GetContractNFTsResponseAdapter, getMultipleNFTsOperation, GetMultipleNFTsRequest, GetMultipleNFTsResponseAdapter, getNFTContractMetadataOperation, GetNFTContractMetadataRequest, GetNFTContractMetadataResponseAdapter, getNFTContractTransfersOperation, GetNFTContractTransfersRequest, GetNFTContractTransfersResponseAdapter, getNFTLowestPriceOperation, GetNFTLowestPriceRequest, GetNFTLowestPriceResponseAdapter, getNFTMetadataOperation, GetNFTMetadataRequest, GetNFTMetadataResponseAdapter, getNFTOwnersOperation, GetNFTOwnersRequest, GetNFTOwnersResponseAdapter, getNFTTokenIdOwnersOperation, GetNFTTokenIdOwnersRequest, GetNFTTokenIdOwnersResponseAdapter, getNFTTradesOperation, GetNFTTradesRequest, GetNFTTradesResponseAdapter, getNFTTransfersByBlockOperation, GetNFTTransfersByBlockRequest, GetNFTTransfersByBlockResponseAdapter, getNFTTransfersFromToBlockOperation, GetNFTTransfersFromToBlockRequest, GetNFTTransfersFromToBlockResponseAdapter, getNFTTransfersOperation, GetNFTTransfersRequest, GetNFTTransfersResponseAdapter, getWalletNFTCollectionsOperation, GetWalletNFTCollectionsRequest, GetWalletNFTCollectionsResponseAdapter, getWalletNFTsOperation, GetWalletNFTsRequest, GetWalletNFTsResponseAdapter, getWalletNFTTransfersOperation, GetWalletNFTTransfersRequest, GetWalletNFTTransfersResponseAdapter, reSyncMetadataOperation, ReSyncMetadataRequest, ReSyncMetadataResponseAdapter, searchNFTsOperation, SearchNFTsRequest, SearchNFTsResponseAdapter, syncNFTContractOperation, SyncNFTContractRequest, SyncNFTContractResponseAdapter, getErc20MintsOperation, GetErc20MintsRequest, GetErc20MintsResponseAdapter, getTokenAllowanceOperation, GetTokenAllowanceRequest, GetTokenAllowanceResponseAdapter, getTokenMetadataBySymbolOperation, GetTokenMetadataBySymbolRequest, GetTokenMetadataBySymbolResponseAdapter, getTokenMetadataOperation, GetTokenMetadataRequest, GetTokenMetadataResponseAdapter, getTokenPriceOperation, GetTokenPriceRequest, GetTokenPriceResponseAdapter, getTokenTransfersOperation, GetTokenTransfersRequest, GetTokenTransfersResponseAdapter, getWalletTokenBalancesOperation, GetWalletTokenBalancesRequest, GetWalletTokenBalancesResponseAdapter, getWalletTokenTransfersOperation, GetWalletTokenTransfersRequest, GetWalletTokenTransfersResponseAdapter, getInternalTransactionsOperation, GetInternalTransactionsRequest, GetInternalTransactionsResponseAdapter, getTransactionOperation, GetTransactionRequest, GetTransactionResponseAdapter, getWalletTransactionsOperation, GetWalletTransactionsRequest, GetWalletTransactionsResponseAdapter, getWalletTransactionsVerboseOperation, GetWalletTransactionsVerboseRequest, GetWalletTransactionsVerboseResponseAdapter, getNativeBalanceOperation, GetNativeBalanceRequest, GetNativeBalanceResponseAdapter, getNativeBalancesForAddressesOperation, GetNativeBalancesForAddressesRequest, GetNativeBalancesForAddressesResponseAdapter, getPairAddressOperation, GetPairAddressRequest, GetPairAddressResponseAdapter, getPairReservesOperation, GetPairReservesRequest, GetPairReservesResponseAdapter, resolveAddressOperation, ResolveAddressRequest, ResolveAddressResponseAdapter, resolveDomainOperation, ResolveDomainRequest, ResolveDomainResponseAdapter, uploadFolderOperation, UploadFolderRequest, UploadFolderResponseAdapter } from '@moralisweb3/common-evm-utils'; import { OperationResolver, NullableOperationResolver, PaginatedOperationResolver } from '@moralisweb3/api-utils'; import { ApiModule, } from '@moralisweb3/common-core'; export abstract class ClientEvmApi extends ApiModule { @@ -124,6 +124,22 @@ export abstract class ClientEvmApi extends ApiModule { }; + public readonly transaction = { + getInternalTransactions: (request: GetInternalTransactionsRequest): Promise => { + return new OperationResolver(getInternalTransactionsOperation, this.baseUrl, this.core).fetch(request); + }, + getTransaction: (request: GetTransactionRequest): Promise => { + return new NullableOperationResolver(getTransactionOperation, this.baseUrl, this.core).fetch(request); + }, + getWalletTransactions: (request: GetWalletTransactionsRequest): Promise => { + return new PaginatedOperationResolver(getWalletTransactionsOperation, this.baseUrl, this.core).fetch(request); + }, + getWalletTransactionsVerbose: (request: GetWalletTransactionsVerboseRequest): Promise => { + return new PaginatedOperationResolver(getWalletTransactionsVerboseOperation, this.baseUrl, this.core).fetch(request); + }, + + }; + public readonly balance = { getNativeBalance: (request: GetNativeBalanceRequest): Promise => { return new OperationResolver(getNativeBalanceOperation, this.baseUrl, this.core).fetch(request); @@ -144,19 +160,6 @@ export abstract class ClientEvmApi extends ApiModule { }; - public readonly transaction = { - getTransaction: (request: GetTransactionRequest): Promise => { - return new NullableOperationResolver(getTransactionOperation, this.baseUrl, this.core).fetch(request); - }, - getWalletTransactions: (request: GetWalletTransactionsRequest): Promise => { - return new PaginatedOperationResolver(getWalletTransactionsOperation, this.baseUrl, this.core).fetch(request); - }, - getWalletTransactionsVerbose: (request: GetWalletTransactionsVerboseRequest): Promise => { - return new PaginatedOperationResolver(getWalletTransactionsVerboseOperation, this.baseUrl, this.core).fetch(request); - }, - - }; - public readonly resolve = { resolveAddress: (request: ResolveAddressRequest): Promise => { return new NullableOperationResolver(resolveAddressOperation, this.baseUrl, this.core).fetch(request);