diff --git a/src/handlers/EventHandler.ts b/src/handlers/EventHandler.ts index 7c96935..c8cf99d 100644 --- a/src/handlers/EventHandler.ts +++ b/src/handlers/EventHandler.ts @@ -1,8 +1,8 @@ -import { BlockData, DataHandlerContext, Log } from '@subsquid/evm-processor'; import { Store } from '@subsquid/typeorm-store'; import { Application, ApplicationFactory, + Chain, Erc1155Deposit, Erc20Deposit, Erc721Deposit, @@ -11,6 +11,7 @@ import { NFT, Token, } from '../model'; +import { BlockData, Log, ProcessorContext } from '../processor'; import ApplicationCreated from './ApplicationCreated'; import Handler from './Handler'; import InputAdded from './InputAdded'; @@ -26,6 +27,7 @@ export default class EventHandler { private readonly erc721Deposits: Map; private readonly multiTokens: Map; private readonly erc1155Deposits: Map; + private readonly chains: Map; private readonly applicationCreated: Handler; private readonly inputAdded: Handler; private readonly ownershipTransferred: Handler; @@ -40,9 +42,11 @@ export default class EventHandler { this.erc721Deposits = new Map(); this.multiTokens = new Map(); this.erc1155Deposits = new Map(); + this.chains = new Map(); this.applicationCreated = new ApplicationCreated( this.factories, this.applications, + this.chains, ); this.inputAdded = new InputAdded( @@ -54,12 +58,16 @@ export default class EventHandler { this.erc721Deposits, this.multiTokens, this.erc1155Deposits, + this.chains, ); - this.ownershipTransferred = new OwnershipTransferred(this.applications); + this.ownershipTransferred = new OwnershipTransferred( + this.applications, + this.chains, + ); } - async handle(log: Log, block: BlockData, ctx: DataHandlerContext) { + async handle(log: Log, block: BlockData, ctx: ProcessorContext) { await this.applicationCreated.handle(log, block, ctx); await this.inputAdded.handle(log, block, ctx); await this.ownershipTransferred.handle(log, block, ctx); @@ -77,6 +85,7 @@ export default class EventHandler { erc721Deposits: this.erc721Deposits, multiTokens: this.multiTokens, erc1155Deposits: this.erc1155Deposits, + chains: this.chains, }; } diff --git a/src/handlers/Handler.ts b/src/handlers/Handler.ts index c9d7bb5..1049909 100644 --- a/src/handlers/Handler.ts +++ b/src/handlers/Handler.ts @@ -1,5 +1,6 @@ -import { BlockData, DataHandlerContext, Log } from '@subsquid/evm-processor'; +import { DataHandlerContext } from '@subsquid/evm-processor'; import { Store } from '@subsquid/typeorm-store'; +import { BlockData, Log } from '../processor'; export default interface Handler { handle( diff --git a/src/handlers/InputAdded.ts b/src/handlers/InputAdded.ts index cdad3f9..b48d1f4 100644 --- a/src/handlers/InputAdded.ts +++ b/src/handlers/InputAdded.ts @@ -1,4 +1,4 @@ -import { BlockData, DataHandlerContext, Log } from '@subsquid/evm-processor'; +import { DataHandlerContext } from '@subsquid/evm-processor'; import { Store } from '@subsquid/typeorm-store'; import { AbiCoder, dataSlice, getUint } from 'ethers'; import { Contract as ERC20 } from '../abi/ERC20'; @@ -13,6 +13,7 @@ import { } from '../config'; import { Application, + Chain, Erc1155Deposit, Erc1155Transfer, Erc20Deposit, @@ -22,6 +23,9 @@ import { NFT, Token, } from '../model'; +import { BlockData, Log } from '../processor'; + +import { generateIDFrom } from '../utils'; import Handler from './Handler'; const logErrorAndReturnNull = @@ -31,14 +35,15 @@ const logErrorAndReturnNull = }; export default class InputAdded implements Handler { constructor( - private tokenStorage: Map, - private depositStorage: Map, - private applicationStorage: Map, - private inputStorage: Map, - private nftStorage: Map, - private erc721DepositStorage: Map, - private multiTokenStorage: Map, - private erc1155DepositStorage: Map, + private tokenStorage: Map, + private depositStorage: Map, + private applicationStorage: Map, + private inputStorage: Map, + private nftStorage: Map, + private erc721DepositStorage: Map, + private multiTokenStorage: Map, + private erc1155DepositStorage: Map, + private chainStorage: Map, ) {} private async prepareErc20Deposit( @@ -47,30 +52,42 @@ export default class InputAdded implements Handler { ctx: DataHandlerContext, opts: { inputId: string; + chain: Chain; }, ) { if (input.msgSender !== ERC20PortalAddress) return undefined; + const chain = opts.chain; + // first byte is a boolean and it is not used here at the moment const tokenAddress = dataSlice(input.payload, 1, 21).toLowerCase(); // 20 bytes for address const from = dataSlice(input.payload, 21, 41).toLowerCase(); // 20 bytes for address const amount = getUint(dataSlice(input.payload, 41, 73)); // 32 bytes for uint256 + const tokenId = generateIDFrom([chain.id, tokenAddress]); - let token = this.tokenStorage.get(tokenAddress) as Token; + let token = this.tokenStorage.get(tokenId) as Token; if (!token) { const contract = new ERC20(ctx, block.header, tokenAddress); const name = await contract.name(); const symbol = await contract.symbol(); const decimals = await contract.decimals(); - token = new Token({ id: tokenAddress, name, symbol, decimals }); - this.tokenStorage.set(tokenAddress, token); - ctx.log.info(`${tokenAddress} (Token) stored`); + token = new Token({ + id: tokenId, + name, + symbol, + decimals, + chain: chain, + address: tokenAddress, + }); + this.tokenStorage.set(tokenId, token); + ctx.log.info(`${tokenId} (Token) stored`); } const deposit = new Erc20Deposit({ id: input.id, amount, from, token, + chain: opts.chain, }); this.depositStorage.set(opts.inputId, deposit); @@ -84,16 +101,20 @@ export default class InputAdded implements Handler { block: BlockData, ctx: DataHandlerContext, opts: { - inputId: String; + inputId: string; + chain: Chain; }, ) { if (input.msgSender !== ERC721PortalAddress) return undefined; + const chain = opts.chain; + const tokenAddress = dataSlice(input.payload, 0, 20).toLowerCase(); // 20 bytes for address const from = dataSlice(input.payload, 20, 40).toLowerCase(); // 20 bytes for address const tokenIndex = getUint(dataSlice(input.payload, 40, 72)); // 32 bytes for uint256 + const tokenId = generateIDFrom([chain.id, tokenAddress]); - let nft = this.nftStorage.get(tokenAddress); + let nft = this.nftStorage.get(tokenId); if (!nft) { const contract = new ERC721(ctx, block.header, tokenAddress); const name = await contract @@ -102,9 +123,15 @@ export default class InputAdded implements Handler { const symbol = await contract .symbol() .catch(logErrorAndReturnNull(ctx)); - nft = new NFT({ id: tokenAddress, name, symbol }); - this.nftStorage.set(tokenAddress, nft); - ctx.log.info(`${tokenAddress} (NFT) stored`); + nft = new NFT({ + id: tokenId, + name, + symbol, + chain, + address: tokenAddress, + }); + this.nftStorage.set(tokenId, nft); + ctx.log.info(`${tokenId} (NFT) stored`); } const deposit = new Erc721Deposit({ @@ -112,6 +139,7 @@ export default class InputAdded implements Handler { from, token: nft, tokenIndex, + chain, }); this.erc721DepositStorage.set(opts.inputId, deposit); @@ -122,10 +150,11 @@ export default class InputAdded implements Handler { private async prepareErc1155Deposit( input: Input, - block: BlockData, + _block: BlockData, ctx: DataHandlerContext, opts: { - inputId: String; + inputId: string; + chain: Chain; }, ) { if ( @@ -134,8 +163,11 @@ export default class InputAdded implements Handler { ) return undefined; + const chain = opts.chain; + const tokenAddress = dataSlice(input.payload, 0, 20).toLowerCase(); // 20 bytes for token address const from = dataSlice(input.payload, 20, 40).toLowerCase(); // 20 bytes for from address + const tokenId = generateIDFrom([chain.id, tokenAddress]); let transfers: Erc1155Transfer[] = []; if (input.msgSender === ERC1155BatchPortalAddress) { @@ -156,12 +188,16 @@ export default class InputAdded implements Handler { transfers = [new Erc1155Transfer({ tokenIndex, amount })]; } - let token = this.multiTokenStorage.get(tokenAddress); + let token = this.multiTokenStorage.get(tokenId); if (!token) { - token = new MultiToken({ id: tokenAddress }); - this.multiTokenStorage.set(tokenAddress, token); - ctx.log.info(`${tokenAddress} (ERC-1155) contract stored.`); + token = new MultiToken({ + id: tokenId, + chain, + address: tokenAddress, + }); + this.multiTokenStorage.set(tokenId, token); + ctx.log.info(`${tokenId} (ERC-1155) contract stored.`); } const deposit = new Erc1155Deposit({ @@ -169,6 +205,7 @@ export default class InputAdded implements Handler { from, token, transfers, + chain, }); this.erc1155DepositStorage.set(input.id, deposit); @@ -182,9 +219,22 @@ export default class InputAdded implements Handler { log.address === InputBoxAddress && log.topics[0] === events.InputAdded.topic ) { + if (!log.transaction?.chainId) + throw new Error( + 'Chain id is required to save InputAdded events and related data!', + ); + + const chain = new Chain({ + id: log.transaction.chainId.toString(), + }); + + // Storing Chain + this.chainStorage.set(chain.id, chain); + const timestamp = BigInt(log.block.timestamp); const event = events.InputAdded.decode(log); - const dappId = event.dapp.toLowerCase(); + const dappAddress = event.dapp.toLowerCase(); + const dappId = generateIDFrom([chain.id, dappAddress]); const timestampInSeconds = timestamp / 1000n; let application = @@ -195,12 +245,15 @@ export default class InputAdded implements Handler { application = new Application({ id: dappId, timestamp: timestampInSeconds, + chain: chain, + address: dappAddress, }); this.applicationStorage.set(dappId, application); ctx.log.info(`${dappId} (Application) stored`); } - const inputId = `${dappId}-${event.inboxInputIndex}`; + const inputId = generateIDFrom([dappId, event.inboxInputIndex]); + const input = new Input({ id: inputId, application, @@ -211,9 +264,10 @@ export default class InputAdded implements Handler { blockNumber: BigInt(log.block.height), blockHash: log.block.hash, transactionHash: log.transaction?.hash, + chain: chain, }); - const params = [input, block, ctx, { inputId }] as const; + const params = [input, block, ctx, { inputId, chain }] as const; input.erc20Deposit = await this.prepareErc20Deposit(...params); diff --git a/tests/handlers/InputAdded.test.ts b/tests/handlers/InputAdded.test.ts index 87c10de..ca99417 100644 --- a/tests/handlers/InputAdded.test.ts +++ b/tests/handlers/InputAdded.test.ts @@ -1,10 +1,12 @@ import { afterEach } from 'node:test'; +import { sepolia } from 'viem/chains'; import { beforeEach, describe, expect, test, vi } from 'vitest'; import { Contract as ERC20 } from '../../src/abi/ERC20'; import { Contract as ERC721 } from '../../src/abi/ERC721'; import InputAdded from '../../src/handlers/InputAdded'; import { Application, + Chain, Erc1155Deposit, Erc1155Transfer, Erc20Deposit, @@ -23,6 +25,7 @@ import { logErc721Transfer, logs, } from '../stubs/params'; +import { mockModelImplementation } from '../stubs/utils'; vi.mock('../../src/abi/ERC20'); @@ -38,6 +41,7 @@ vi.mock('../../src/model/', async () => { const Erc1155Deposit = vi.fn(); const MultiToken = vi.fn(); const Erc1155Transfer = vi.fn(); + const Chain = vi.fn(); return { Application, @@ -49,20 +53,22 @@ vi.mock('../../src/model/', async () => { MultiToken, Erc1155Deposit, Erc1155Transfer, + Chain, }; }); -const ApplicationMock = vi.mocked(Application); -const InputMock = vi.mocked(Input); -const NFTStub = vi.mocked(NFT); +const ApplicationMock = mockModelImplementation(Application); +const InputMock = mockModelImplementation(Input); +const NFTStub = mockModelImplementation(NFT); const ERC721Mock = vi.mocked(ERC721, true); -const ERC721DepositStub = vi.mocked(Erc721Deposit); +const ERC721DepositStub = mockModelImplementation(Erc721Deposit); const ERC20Mock = vi.mocked(ERC20, true); -const ERC20DepositStub = vi.mocked(Erc20Deposit); -const TokenStub = vi.mocked(Token); -const MultiTokenStub = vi.mocked(MultiToken); -const ERC1155DepositStub = vi.mocked(Erc1155Deposit); -const ERC1155TransferStub = vi.mocked(Erc1155Transfer); +const ERC20DepositStub = mockModelImplementation(Erc20Deposit); +const TokenStub = mockModelImplementation(Token); +const MultiTokenStub = mockModelImplementation(MultiToken); +const ERC1155DepositStub = mockModelImplementation(Erc1155Deposit); +const ERC1155TransferStub = mockModelImplementation(Erc1155Transfer); +const ChainStub = mockModelImplementation(Chain); describe('InputAdded', () => { let inputAdded: InputAdded; @@ -74,6 +80,8 @@ describe('InputAdded', () => { const mockErc721DepositStorage = new Map(); const mockMultiTokenStorage = new Map(); const mockErc1155DepositStorage = new Map(); + const mockChainStorage = new Map(); + const expectedChain = { id: sepolia.id.toString() }; beforeEach(() => { inputAdded = new InputAdded( @@ -85,6 +93,7 @@ describe('InputAdded', () => { mockErc721DepositStorage, mockMultiTokenStorage, mockErc1155DepositStorage, + mockChainStorage, ); mockTokenStorage.clear(); @@ -102,51 +111,52 @@ describe('InputAdded', () => { }); describe('handle', async () => { - test('wrong contract address', async () => { + test('should ignore events other than InputAdded', async () => { await inputAdded.handle(logs[1], block, ctx); expect(mockInputStorage.size).toBe(0); expect(mockApplicationStorage.size).toBe(0); expect(mockDepositStorage.size).toBe(0); }); - test('correct contract address', async () => { + test('should handle event type InputAdded', async () => { await inputAdded.handle(logs[0], block, ctx); expect(mockApplicationStorage.size).toBe(1); expect(mockInputStorage.size).toBe(1); }); test('when creating a non-existing app it should also set the timestamp in seconds', async () => { - const expectedParams = vi.fn(); - - ApplicationMock.mockImplementationOnce((args) => { - expectedParams(args); - return new Application(args); - }); - await inputAdded.handle(logs[0], block, ctx); const timestamp = BigInt(logs[0].block.timestamp) / 1000n; - expect(expectedParams).toHaveBeenCalledWith({ - id: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54', + const [application] = mockApplicationStorage.values(); + expect(application).toEqual({ + id: `${sepolia.id}-0x0be010fa7e70d74fa8b6729fe1ae268787298f54`, + address: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54', timestamp, + chain: expectedChain, }); }); + test('should throw error when chain-id information is not available in the Log ', async () => { + try { + const clonedLog = structuredClone(logErc20Transfer); + delete clonedLog.transaction?.chainId; + await inputAdded.handle(clonedLog, block, ctx); + expect(true).toEqual('Should not reach that expectation.'); + } catch (error) { + expect(error.message).toEqual( + 'Chain id is required to save InputAdded events and related data!', + ); + } + }); + describe('ERC-20 deposit', () => { const name = 'Wrapped Ether'; const symbol = 'WETH'; const decimals = 18; beforeEach(() => { - InputMock.mockImplementationOnce((args) => { - return { ...args } as Input; - }); - TokenStub.mockImplementation((args) => ({ ...args } as Token)); - ERC20DepositStub.mockImplementation( - (args) => ({ ...args } as Erc20Deposit), - ); - // some default returns for the ERC20 contract calls ERC20Mock.prototype.name.mockResolvedValue(name); ERC20Mock.prototype.symbol.mockResolvedValue(symbol); @@ -160,28 +170,36 @@ describe('InputAdded', () => { test('Should store the token information', async () => { await inputAdded.handle(logErc20Transfer, block, ctx); expect(mockTokenStorage.size).toBe(1); - const token = mockTokenStorage.values().next().value; - - expect(token.name).toEqual(name); - expect(token.symbol).toEqual(symbol); - expect(token.decimals).toEqual(decimals); + const [token] = mockTokenStorage.values(); + + expect(token).toEqual({ + chain: expectedChain, + decimals: decimals, + id: `${sepolia.id}-0x813ae0539daf858599a1b2a7083380542a7b1bb5`, + address: '0x813ae0539daf858599a1b2a7083380542a7b1bb5', + name: name, + symbol: symbol, + }); }); test('should store the deposit information', async () => { await inputAdded.handle(logErc20Transfer, block, ctx); expect(mockDepositStorage.size).toBe(1); - const deposit = mockDepositStorage.values().next().value; + const [deposit] = mockDepositStorage.values(); expect(deposit).toEqual({ - id: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1', + chain: expectedChain, + id: `${sepolia.id}-0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1`, amount: 111000000000000000n, from: '0xf9e958241c1ca380cfcd50170ec43974bded0bff', token: { - id: '0x813ae0539daf858599a1b2a7083380542a7b1bb5', + id: `${sepolia.id.toString()}-0x813ae0539daf858599a1b2a7083380542a7b1bb5`, + address: '0x813ae0539daf858599a1b2a7083380542a7b1bb5', decimals: 18, name: 'Wrapped Ether', symbol: 'WETH', + chain: expectedChain, }, }); }); @@ -190,17 +208,21 @@ describe('InputAdded', () => { await inputAdded.handle(logErc20Transfer, block, ctx); expect(mockInputStorage.size).toEqual(1); - const input = mockInputStorage.values().next().value as Input; + const [input] = + mockInputStorage.values() as IterableIterator; expect(input.erc20Deposit).toEqual({ + chain: expectedChain, amount: 111000000000000000n, from: '0xf9e958241c1ca380cfcd50170ec43974bded0bff', - id: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1', + id: `${sepolia.id}-0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1`, token: { decimals: 18, - id: '0x813ae0539daf858599a1b2a7083380542a7b1bb5', + id: `${sepolia.id}-0x813ae0539daf858599a1b2a7083380542a7b1bb5`, + address: '0x813ae0539daf858599a1b2a7083380542a7b1bb5', name: 'Wrapped Ether', symbol: 'WETH', + chain: expectedChain, }, }); @@ -215,19 +237,6 @@ describe('InputAdded', () => { beforeEach(() => { ERC721Mock.prototype.name.mockResolvedValue(name); ERC721Mock.prototype.symbol.mockResolvedValue(symbol); - - // Returning simple object as the Class type for assertion - InputMock.mockImplementationOnce((args) => { - return { ...args } as Input; - }); - - NFTStub.mockImplementationOnce((args) => { - return { ...args } as NFT; - }); - - ERC721DepositStub.mockImplementationOnce((args) => { - return { ...args } as Erc721Deposit; - }); }); afterEach(() => { @@ -238,27 +247,37 @@ describe('InputAdded', () => { await inputAdded.handle(logErc721Transfer, block, ctx); expect(mockNftStorage.size).toBe(1); - const token = mockNftStorage.values().next().value; - expect(token.name).toEqual(name); - expect(token.symbol).toEqual(symbol); + const [token] = + mockNftStorage.values() as IterableIterator; + + expect(token).toEqual({ + chain: expectedChain, + id: `${sepolia.id}-0x7a3cc9c0408887a030a0354330c36a9cd681aa7e`, + address: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', + name, + symbol, + }); }); test('should store the deposit information', async () => { await inputAdded.handle(logErc721Transfer, block, ctx); expect(mockErc721DepositStorage.size).toBe(1); - const deposit = mockErc721DepositStorage.values().next().value; - expect(deposit.id).toEqual( - '0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1', - ); - expect(deposit.from).toEqual( - logErc721Transfer.transaction.from, - ); - expect(deposit.tokenIndex).toEqual(1n); - expect(deposit.token).toEqual({ - id: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', - name, - symbol, + const [deposit] = + mockErc721DepositStorage.values() as IterableIterator; + + expect(deposit).toEqual({ + chain: expectedChain, + id: `${sepolia.id}-0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1`, + from: logErc721Transfer.transaction?.from, + token: { + chain: expectedChain, + id: `${sepolia.id}-0x7a3cc9c0408887a030a0354330c36a9cd681aa7e`, + address: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', + name, + symbol, + }, + tokenIndex: 1n, }); }); @@ -266,12 +285,17 @@ describe('InputAdded', () => { await inputAdded.handle(logErc721Transfer, block, ctx); expect(mockInputStorage.size).toBe(1); - const input = mockInputStorage.values().next().value; + const [input] = + mockInputStorage.values() as IterableIterator; + expect(input.erc721Deposit).toEqual({ + chain: expectedChain, from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', - id: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1', + id: `${sepolia.id}-0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1`, token: { - id: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', + chain: expectedChain, + id: `${sepolia.id}-0x7a3cc9c0408887a030a0354330c36a9cd681aa7e`, + address: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', name, symbol, }, @@ -290,41 +314,20 @@ describe('InputAdded', () => { await inputAdded.handle(logErc721Transfer, block, ctx); expect(mockInputStorage.size).toBe(1); - const input = mockInputStorage.values().next().value; - expect(input.erc721Deposit).toEqual({ - from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', - id: '0x0be010fa7e70d74fa8b6729fe1ae268787298f54-1', - token: { - id: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', - name: null, - symbol: null, - }, - tokenIndex: 1n, + const [input] = + mockInputStorage.values() as IterableIterator; + expect(input.erc721Deposit?.token).toEqual({ + id: `${sepolia.id}-0x7a3cc9c0408887a030a0354330c36a9cd681aa7e`, + address: '0x7a3cc9c0408887a030a0354330c36a9cd681aa7e', + name: null, + symbol: null, + chain: expectedChain, }); }); }); describe('ERC-1155 deposits', () => { - const tokenAddress = '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e'; - - beforeEach(() => { - // Returning simple object as the Class type for assertion - InputMock.mockImplementationOnce((args) => { - return { ...args } as Input; - }); - - MultiTokenStub.mockImplementationOnce((args) => { - return { ...args } as MultiToken; - }); - - ERC1155TransferStub.mockImplementation((args) => { - return { ...args } as Erc1155Transfer; - }); - - ERC1155DepositStub.mockImplementationOnce((args) => { - return { ...args } as Erc1155Deposit; - }); - }); + const tokenAddress = `${sepolia.id}-0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e`; afterEach(() => { vi.clearAllMocks(); @@ -338,11 +341,14 @@ describe('InputAdded', () => { expect(mockMultiTokenStorage.size).toBe(1); const token = mockMultiTokenStorage.get(tokenAddress); expect(token?.id).toEqual(tokenAddress); + expect(token?.address).toEqual( + '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e', + ); + expect(token?.chain).toEqual({ id: '11155111' }); }); test('should store the deposit information for single transfer', async () => { - const inputId = - '0x4ca2f6935200b9a782a78f408f640f17b29809d8-783'; + const inputId = `${sepolia.id}-0x4ca2f6935200b9a782a78f408f640f17b29809d8-783`; expect(mockErc1155DepositStorage.size).toBe(0); await inputAdded.handle(logErc1155SingleTransfer, block, ctx); @@ -353,8 +359,11 @@ describe('InputAdded', () => { expect(deposit).toEqual({ from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', id: inputId, + chain: expectedChain, token: { - id: '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e', + id: `${sepolia.id}-0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e`, + address: '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e', + chain: expectedChain, }, transfers: [ { @@ -366,8 +375,7 @@ describe('InputAdded', () => { }); test('should store the deposit information for batch transfer', async () => { - const inputId = - '0x4ca2f6935200b9a782a78f408f640f17b29809d8-784'; + const inputId = `${sepolia.id}-0x4ca2f6935200b9a782a78f408f640f17b29809d8-784`; expect(mockErc1155DepositStorage.size).toBe(0); await inputAdded.handle(logErc1155BatchTransfer, block, ctx); @@ -378,8 +386,11 @@ describe('InputAdded', () => { expect(deposit).toEqual({ from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', id: inputId, + chain: expectedChain, token: { - id: '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e', + id: `${sepolia.id}-0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e`, + address: '0x2960f4db2b0993ae5b59bc4a0f5ec7a1767e905e', + chain: expectedChain, }, transfers: [ { diff --git a/tests/stubs/params.ts b/tests/stubs/params.ts index 4cb3e42..502cdfa 100644 --- a/tests/stubs/params.ts +++ b/tests/stubs/params.ts @@ -68,7 +68,7 @@ export const input = { '0x6a3d76983453c0f74188bd89e01576c35f9d9b02daecdd49f7171aeb2bd3dc78', } satisfies Input; -export const logErc721Transfer = { +export const logErc721Transfer: Log = { id: '0004867730-000035-2c78f', address: InputBoxAddress, logIndex: 35, @@ -79,6 +79,7 @@ export const logErc721Transfer = { '0x0000000000000000000000000000000000000000000000000000000000000001', ], data: '0x000000000000000000000000237f8dd094c0e47f4236f12b4fa01d6dae89fb87000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c87a3cc9c0408887a030a0354330c36a9cd681aa7ea074683b5be015f053b5dceb064c41fc9d11b6e500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -94,7 +95,8 @@ export const logErc721Transfer = { from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', to: '0x237f8dd094c0e47f4236f12b4fa01d6dae89fb87', hash: '0x47c53eeddc2f927ef2a7a3dd9a95bfd70ecfda2c4efdf10a16c48ca98c86b881', - value: 0, + value: 0n, + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -106,7 +108,7 @@ export const logErc721Transfer = { }, }; -export const logErc1155SingleTransfer = { +export const logErc1155SingleTransfer: Log = { id: '0004867730-000035-2c78f', address: InputBoxAddress, logIndex: 35, @@ -117,6 +119,7 @@ export const logErc1155SingleTransfer = { encodeAbiParameters([{ type: 'uint256' }], [783n]), ], data: '0x0000000000000000000000007cfb0193ca87eb6e48056885e026552c3a941fc4000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001282960f4db2b0993ae5b59bc4a0f5ec7a1767e905ea074683b5be015f053b5dceb064c41fc9d11b6e500000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000989680000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -132,7 +135,8 @@ export const logErc1155SingleTransfer = { from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', to: '0x7CFB0193Ca87eB6e48056885E026552c3A941FC4', hash: '0x47c53eeddc2f927ef2a7a3dd9a95bfd70ecfda2c4efdf10a16c48ca98c86b881', - value: 0, + value: 0n, + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -144,7 +148,7 @@ export const logErc1155SingleTransfer = { }, }; -export const logErc1155BatchTransfer = { +export const logErc1155BatchTransfer: Log = { id: '0004867730-000035-2c78f', address: InputBoxAddress, logIndex: 35, @@ -155,6 +159,7 @@ export const logErc1155BatchTransfer = { encodeAbiParameters([{ type: 'uint256' }], [784n]), ], data: '0x000000000000000000000000edb53860a6b52bbb7561ad596416ee9965b055aa000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002282960f4db2b0993ae5b59bc4a0f5ec7a1767e905ea074683b5be015f053b5dceb064c41fc9d11b6e500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -170,7 +175,8 @@ export const logErc1155BatchTransfer = { from: '0xa074683b5be015f053b5dceb064c41fc9d11b6e5', to: '0xedB53860A6B52bbb7561Ad596416ee9965B055Aa', hash: '0x47c53eeddc2f927ef2a7a3dd9a95bfd70ecfda2c4efdf10a16c48ca98c86b881', - value: 0, + value: 0n, + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -182,7 +188,7 @@ export const logErc1155BatchTransfer = { }, }; -export const logErc20Transfer = { +export const logErc20Transfer: Log = { id: '0004867730-000035-2c78f', address: InputBoxAddress, logIndex: 31, @@ -193,6 +199,7 @@ export const logErc20Transfer = { '0x0000000000000000000000000000000000000000000000000000000000000001', ], data: '0x0000000000000000000000009c21aeb2093c32ddbc53eef24b873bdcd1ada1db0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004a01813ae0539daf858599a1b2a7083380542a7b1bb5f9e958241c1ca380cfcd50170ec43974bded0bff000000000000000000000000000000000000000000000000018a59e9721180000000000000000000000000000000000000000000000000', + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730, @@ -208,7 +215,8 @@ export const logErc20Transfer = { from: '0xF9e958241c1cA380cFcD50170Ec43974bDeD0BfF', to: '0xA1C977656F68e1eE2733FF43B83529aF2a5aE7c9', hash: '0x47c53eeddc2f927ef2a7a3dd9a95bfd70ecfda2c4efdf10a16c48ca98c86b881', - value: 0, + value: 0n, + // @ts-ignore block: { id: '0004867730-2c78f', height: 4867730,