Add test
This commit is contained in:
parent
61283100be
commit
1cead33153
|
@ -125,7 +125,7 @@
|
|||
},
|
||||
"wormchain": {
|
||||
"network": "mainnet",
|
||||
"rpcs": ["https://wormchain-rpc.quickapi.com"]
|
||||
"rpcs": ["https://tncnt-eu-wormchain-main-01.rpc.p2p.world"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,12 @@ export * from "./evm/PollEvm";
|
|||
export * from "./evm/types";
|
||||
export * from "./solana/GetSolanaTransactions";
|
||||
export * from "./solana/PollSolanaTransactions";
|
||||
export * from "./wormchain/HandleWormchainLogs";
|
||||
export * from "./wormchain/GetWormchainLogs";
|
||||
export * from "./wormchain/PollWormchain";
|
||||
export * from "./aptos/GetAptosTransactions";
|
||||
export * from "./aptos/GetAptosTransactionsByEvents";
|
||||
export * from "./aptos/HandleAptosTransactions";
|
||||
export * from "./aptos/PollAptos";
|
||||
export * from "./RunPollingJob";
|
||||
export * from "./StartJobs";
|
||||
|
|
|
@ -39,7 +39,7 @@ export class GetWormchainLogs {
|
|||
}
|
||||
|
||||
private populateLog(opts: GetWormchainOpts, fromBlock: bigint, toBlock: bigint): string {
|
||||
return `[addresses:${opts.addresses}][topics:${opts.topics}][blocks:${fromBlock} - ${toBlock}]`;
|
||||
return `[addresses:${opts.addresses}][blocks:${fromBlock} - ${toBlock}]`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -216,9 +216,9 @@ export class PollWormchainLogsConfig {
|
|||
return this.props.chainId;
|
||||
}
|
||||
|
||||
static fromBlock(chain: string, fromBlock: bigint) {
|
||||
static fromBlock(fromBlock: bigint) {
|
||||
return new PollWormchainLogsConfig({
|
||||
chain,
|
||||
chain: "wormchain",
|
||||
fromBlock,
|
||||
addresses: [],
|
||||
topics: [],
|
||||
|
|
|
@ -2,20 +2,19 @@ import { LogFoundEvent, LogMessagePublished } from "../../../domain/entities";
|
|||
import { WormchainLog } from "../../../domain/entities/wormchain";
|
||||
import winston from "winston";
|
||||
|
||||
const CHAIN_ID_WORMCHAIN = 22;
|
||||
const CHAIN_ID_WORMCHAIN = 3104;
|
||||
const CORE_ADDRESS = "wormhole1ufs3tlq4umljk0qfe8k5ya0x6hpavn897u2cnf9k0en9jr7qarqqaqfk2j";
|
||||
|
||||
let logger: winston.Logger = winston.child({ module: "wormchainLogMessagePublishedMapper" });
|
||||
|
||||
export const wormchainLogMessagePublishedMapper = (
|
||||
log: WormchainLog,
|
||||
parsedArgs: ReadonlyArray<any>
|
||||
log: WormchainLog
|
||||
): LogFoundEvent<LogMessagePublished> | undefined => {
|
||||
const { coreContract, sequence, emitter, hash } = transactionAttibutes(log);
|
||||
const { coreContract, sequence, payload, emitter, nonce, hash } = transactionAttibutes(log);
|
||||
|
||||
if (coreContract && sequence && emitter && hash) {
|
||||
if (coreContract && sequence && payload && emitter && payload && nonce && hash) {
|
||||
logger.info(
|
||||
`[wormchain] Source event info: [tx: ][emitterChain: ${CHAIN_ID_WORMCHAIN}][sender: }}][sequence: ]`
|
||||
`[wormchain] Source event info: [tx: ${hash}][emitterChain: ${CHAIN_ID_WORMCHAIN}][sender: ${emitter} }}][sequence: ${sequence} ]`
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -28,9 +27,9 @@ export const wormchainLogMessagePublishedMapper = (
|
|||
attributes: {
|
||||
sender: emitter,
|
||||
sequence: sequence,
|
||||
payload: parsedArgs[3],
|
||||
nonce: parsedArgs[2],
|
||||
consistencyLevel: parsedArgs[4],
|
||||
payload: payload,
|
||||
nonce: nonce,
|
||||
consistencyLevel: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -39,7 +38,9 @@ export const wormchainLogMessagePublishedMapper = (
|
|||
function transactionAttibutes(log: WormchainLog): TransactionAttributes {
|
||||
let coreContract;
|
||||
let sequence;
|
||||
let payload;
|
||||
let emitter;
|
||||
let nonce;
|
||||
let hash;
|
||||
|
||||
log.transactions?.forEach((tx) => {
|
||||
|
@ -50,11 +51,18 @@ function transactionAttibutes(log: WormchainLog): TransactionAttributes {
|
|||
const value = Buffer.from(attr.value, "base64").toString().toLowerCase();
|
||||
|
||||
switch (key) {
|
||||
case "message.sequence":
|
||||
console.log(key, value);
|
||||
sequence = Number(value);
|
||||
break;
|
||||
case "message.message":
|
||||
payload = value;
|
||||
break;
|
||||
case "message.sender":
|
||||
emitter = value;
|
||||
break;
|
||||
case "message.sequence":
|
||||
sequence = Number(value);
|
||||
case "message.nonce":
|
||||
nonce = Number(value);
|
||||
break;
|
||||
case "_contract_address":
|
||||
case "contract_address":
|
||||
|
@ -69,7 +77,9 @@ function transactionAttibutes(log: WormchainLog): TransactionAttributes {
|
|||
return {
|
||||
coreContract,
|
||||
sequence,
|
||||
payload,
|
||||
emitter,
|
||||
nonce,
|
||||
hash,
|
||||
};
|
||||
}
|
||||
|
@ -77,6 +87,8 @@ function transactionAttibutes(log: WormchainLog): TransactionAttributes {
|
|||
type TransactionAttributes = {
|
||||
coreContract: boolean | undefined;
|
||||
sequence: number | undefined;
|
||||
payload: string | undefined;
|
||||
emitter: string | undefined;
|
||||
nonce: number | undefined;
|
||||
hash: string | undefined;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
import { afterEach, describe, it, expect, jest } from "@jest/globals";
|
||||
import {
|
||||
PollEvmLogsConfig,
|
||||
PollWormchain,
|
||||
PollWormchainLogsConfig,
|
||||
PollWormchainLogsMetadata,
|
||||
} from "../../../../src/domain/actions";
|
||||
import {
|
||||
MetadataRepository,
|
||||
StatRepository,
|
||||
WormchainRepository,
|
||||
} from "../../../../src/domain/repositories";
|
||||
import { EvmBlock, EvmLog, ReceiptTransaction } from "../../../../src/domain/entities";
|
||||
import { thenWaitForAssertion } from "../../../wait-assertion";
|
||||
|
||||
let cfg = PollWormchainLogsConfig.fromBlock(7626734n);
|
||||
|
||||
let getBlockHeightSpy: jest.SpiedFunction<WormchainRepository["getBlockHeight"]>;
|
||||
let getBlockLogsSpy: jest.SpiedFunction<WormchainRepository["getBlockLogs"]>;
|
||||
let handlerSpy: jest.SpiedFunction<(logs: EvmLog[]) => Promise<void>>;
|
||||
let metadataSaveSpy: jest.SpiedFunction<MetadataRepository<PollWormchainLogsMetadata>["save"]>;
|
||||
|
||||
let metadataRepo: MetadataRepository<PollWormchainLogsMetadata>;
|
||||
let wormchainBlockRepo: WormchainRepository;
|
||||
let statsRepo: StatRepository;
|
||||
|
||||
let handlers = {
|
||||
working: (logs: EvmLog[]) => Promise.resolve(),
|
||||
failing: (logs: EvmLog[]) => Promise.reject(),
|
||||
};
|
||||
let pollWormchain: PollWormchain;
|
||||
|
||||
describe("PollWormchain", () => {
|
||||
afterEach(async () => {
|
||||
await pollWormchain.stop();
|
||||
});
|
||||
|
||||
it("should be able to read logs from latest block when no fromBlock is configured", async () => {
|
||||
const currentHeight = 10n;
|
||||
|
||||
const logs = {
|
||||
transactions: [
|
||||
{
|
||||
hash: "0x47a54890a16ea9d924c32a1fa6fd1cf39176be532c8ba454d33f628d89be3388",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxNGhqMnRhdnE4ZnBlc2R3eHhjdTQ0cnR5M2hoOTB2aHVqcnZjbXN0bDR6cjN0eG1mdnc5c3JyZzQ2NQ==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "YWN0aW9u", value: "c3VibWl0X29ic2VydmF0aW9ucw==", index: true },
|
||||
{
|
||||
key: "b3duZXI=",
|
||||
value: "d29ybWhvbGUxOHl3NmY4OHA3Znc2bTk5eDlrbnJmejNwMHk2OTNoaDBhaDh5Mm0=",
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
hash: "0x56e974e33c5c7403d23a5fe7fa414d9f1d6dd4f1b67601342100093c604b5d70",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxNGhqMnRhdnE4ZnBlc2R3eHhjdTQ0cnR5M2hoOTB2aHVqcnZjbXN0bDR6cjN0eG1mdnc5c3JyZzQ2NQ==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "YWN0aW9u", value: "c3VibWl0X29ic2VydmF0aW9ucw==", index: true },
|
||||
{
|
||||
key: "b3duZXI=",
|
||||
value: "d29ybWhvbGUxYWNxYTV2bDJudW5oc250djBldGpzNnllZTN2NnZjOGw5bTRxOGU=",
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
blockHeight: "7626735",
|
||||
timestamp: 1711143216257,
|
||||
};
|
||||
givenEvmBlockRepository(currentHeight, logs);
|
||||
givenMetadataRepository();
|
||||
givenStatsRepository();
|
||||
givenPollWormchainLogs();
|
||||
|
||||
await whenPollWormchainLogsStarts();
|
||||
|
||||
await thenWaitForAssertion(
|
||||
() => expect(getBlockHeightSpy).toHaveReturnedTimes(1),
|
||||
() => expect(getBlockLogsSpy).toHaveBeenCalledWith(currentHeight)
|
||||
);
|
||||
});
|
||||
|
||||
it("should be return an empty array because to block is more greater than from block", async () => {
|
||||
const currentHeight = 10n;
|
||||
|
||||
givenEvmBlockRepository(currentHeight);
|
||||
givenMetadataRepository({ lastBlock: 15n });
|
||||
givenStatsRepository();
|
||||
givenPollWormchainLogs();
|
||||
|
||||
await whenPollWormchainLogsStarts();
|
||||
|
||||
await thenWaitForAssertion(() => expect(getBlockHeightSpy).toHaveReturnedTimes(1));
|
||||
});
|
||||
});
|
||||
|
||||
const givenEvmBlockRepository = (height?: bigint, logs: any = []) => {
|
||||
wormchainBlockRepo = {
|
||||
getBlockHeight: () => Promise.resolve(height),
|
||||
getBlockLogs: () => Promise.resolve(logs),
|
||||
};
|
||||
|
||||
getBlockHeightSpy = jest.spyOn(wormchainBlockRepo, "getBlockHeight");
|
||||
getBlockLogsSpy = jest.spyOn(wormchainBlockRepo, "getBlockLogs");
|
||||
handlerSpy = jest.spyOn(handlers, "working");
|
||||
};
|
||||
|
||||
const givenMetadataRepository = (data?: PollWormchainLogsMetadata) => {
|
||||
metadataRepo = {
|
||||
get: () => Promise.resolve(data),
|
||||
save: () => Promise.resolve(),
|
||||
};
|
||||
metadataSaveSpy = jest.spyOn(metadataRepo, "save");
|
||||
};
|
||||
|
||||
const givenStatsRepository = () => {
|
||||
statsRepo = {
|
||||
count: () => {},
|
||||
measure: () => {},
|
||||
report: () => Promise.resolve(""),
|
||||
};
|
||||
};
|
||||
|
||||
const givenPollWormchainLogs = (from?: bigint) => {
|
||||
cfg.setFromBlock(from);
|
||||
pollWormchain = new PollWormchain(
|
||||
wormchainBlockRepo,
|
||||
metadataRepo,
|
||||
statsRepo,
|
||||
cfg,
|
||||
"GetWormchainLogs"
|
||||
);
|
||||
};
|
||||
|
||||
const whenPollWormchainLogsStarts = async () => {
|
||||
pollWormchain.run([handlers.working]);
|
||||
};
|
|
@ -0,0 +1,171 @@
|
|||
import { wormchainLogMessagePublishedMapper } from "../../../../src/infrastructure/mappers/wormchain/wormchainLogMessagePublishedMapper";
|
||||
import { describe, it, expect } from "@jest/globals";
|
||||
import { WormchainLog } from "../../../../src/domain/entities/wormchain";
|
||||
|
||||
describe("wormchainLogMessagePublishedMapper", () => {
|
||||
it("should be able to map log to aptosLogMessagePublishedMapper", async () => {
|
||||
// When
|
||||
const result = wormchainLogMessagePublishedMapper(log);
|
||||
|
||||
if (result) {
|
||||
// Then
|
||||
expect(result.name).toBe("log-message-published");
|
||||
expect(result.chainId).toBe(3104);
|
||||
expect(result.txHash).toBe(
|
||||
"0xa08b0ac6ee67e21d3dd89f48f60cc907fc867288f4439bcf72731b0884d8aff2"
|
||||
);
|
||||
expect(result.address).toBe(
|
||||
"wormhole1ufs3tlq4umljk0qfe8k5ya0x6hpavn897u2cnf9k0en9jr7qarqqaqfk2j"
|
||||
);
|
||||
expect(result.attributes.consistencyLevel).toBe(0);
|
||||
expect(result.attributes.nonce).toBe(7671);
|
||||
expect(result.attributes.payload).toBe(
|
||||
"0100000000000000000000000000000000000000000000000000000000555643a3f5edec8471c75624ebc4079a634326d96a689e6157d79abe8f5a6f94472853bc00018622b98735cb870ae0cb22bd4ea58cfb512bd4002247ccd0b250eb6d0c5032fc00010000000000000000000000000000000000000000000000000000000000000000"
|
||||
);
|
||||
expect(result.attributes.sender).toBe(
|
||||
"aeb534c45c3049d380b9d9b966f9895f53abd4301bfaff407fa09dea8ae7a924"
|
||||
);
|
||||
expect(result.attributes.sequence).toBe(28603);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const log: WormchainLog = {
|
||||
transactions: [
|
||||
{
|
||||
hash: "0x987e77d2d8cf8b9c0b3998dc62dc94fad9de47c4e3b50ad9bfd3083d7ab958ff",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxNGhqMnRhdnE4ZnBlc2R3eHhjdTQ0cnR5M2hoOTB2aHVqcnZjbXN0bDR6cjN0eG1mdnc5c3JyZzQ2NQ==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "YWN0aW9u", value: "c3VibWl0X29ic2VydmF0aW9ucw==", index: true },
|
||||
{
|
||||
key: "b3duZXI=",
|
||||
value: "d29ybWhvbGUxODc4a3h6M3VnZXN2YTRoNGtmeng2Y3F0ZHk5NmN3d2RqajBwaHc=",
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
hash: "0xa08b0ac6ee67e21d3dd89f48f60cc907fc867288f4439bcf72731b0884d8aff2",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxajYydGt5cWhqeWpscXN5MzB1bnVhcW5uZDhkdDV3cXFucndqemYwZms3bnc0dzdkeHBzcWhheWFuZw==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "YWN0aW9u", value: "aW5jcmVhc2VfYWxsb3dhbmNl", index: true },
|
||||
{ key: "YW1vdW50", value: "MTQzMTcxNjc3MQ==", index: true },
|
||||
{
|
||||
key: "b3duZXI=",
|
||||
value:
|
||||
"d29ybWhvbGUxNGVqcWp5cTh1bTRwM3hmcWo3NHlsZDV3YXFsamY4OGZ6MjV5eG5tYTBjbmdzcHhlM2xlczAwZnBqeA==",
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
key: "c3BlbmRlcg==",
|
||||
value:
|
||||
"d29ybWhvbGUxNDY2bmYzenV4cHlhOHE5ZW14dWtkN3ZmdGFmNmg0cHNyMGEwN3NybDV6dzc0emg4NHlqcTRseWptaA==",
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
hash: "0xa08b0ac6ee67e21d3dd89f48f60cc907fc867288f4439bcf72731b0884d8aff2",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxNDY2bmYzenV4cHlhOHE5ZW14dWtkN3ZmdGFmNmg0cHNyMGEwN3NybDV6dzc0emg4NHlqcTRseWptaA==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "dHJhbnNmZXIuYW1vdW50", value: "MTQzMTcxNjc3MQ==", index: true },
|
||||
{ key: "dHJhbnNmZXIuYmxvY2tfdGltZQ==", value: "MTcxMTE0MzIyMg==", index: true },
|
||||
{ key: "dHJhbnNmZXIubm9uY2U=", value: "NzY3MQ==", index: true },
|
||||
{
|
||||
key: "dHJhbnNmZXIucmVjaXBpZW50",
|
||||
value:
|
||||
"ODYyMmI5ODczNWNiODcwYWUwY2IyMmJkNGVhNThjZmI1MTJiZDQwMDIyNDdjY2QwYjI1MGViNmQwYzUwMzJmYw==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "dHJhbnNmZXIucmVjaXBpZW50X2NoYWlu", value: "MQ==", index: true },
|
||||
{
|
||||
key: "dHJhbnNmZXIuc2VuZGVy",
|
||||
value:
|
||||
"YWU2NDA5MTAwN2U2ZWExODk5MjA5N2FhNGZiNjhlZTgzZjI0OWNlOTEyYTg0MzRmN2Q3ZTI2ODgwNGQ5OGZmMw==",
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
key: "dHJhbnNmZXIudG9rZW4=",
|
||||
value:
|
||||
"ZjVlZGVjODQ3MWM3NTYyNGViYzQwNzlhNjM0MzI2ZDk2YTY4OWU2MTU3ZDc5YWJlOGY1YTZmOTQ0NzI4NTNiYw==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "dHJhbnNmZXIudG9rZW5fY2hhaW4=", value: "MQ==", index: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
hash: "0xa08b0ac6ee67e21d3dd89f48f60cc907fc867288f4439bcf72731b0884d8aff2",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxajYydGt5cWhqeWpscXN5MzB1bnVhcW5uZDhkdDV3cXFucndqemYwZms3bnc0dzdkeHBzcWhheWFuZw==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "YWN0aW9u", value: "YnVybl9mcm9t", index: true },
|
||||
{ key: "YW1vdW50", value: "MTQzMTcxNjc3MQ==", index: true },
|
||||
{
|
||||
key: "Ynk=",
|
||||
value:
|
||||
"d29ybWhvbGUxNDY2bmYzenV4cHlhOHE5ZW14dWtkN3ZmdGFmNmg0cHNyMGEwN3NybDV6dzc0emg4NHlqcTRseWptaA==",
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
key: "ZnJvbQ==",
|
||||
value:
|
||||
"d29ybWhvbGUxNGVqcWp5cTh1bTRwM3hmcWo3NHlsZDV3YXFsamY4OGZ6MjV5eG5tYTBjbmdzcHhlM2xlczAwZnBqeA==",
|
||||
index: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
hash: "0xa08b0ac6ee67e21d3dd89f48f60cc907fc867288f4439bcf72731b0884d8aff2",
|
||||
type: "wasm",
|
||||
attributes: [
|
||||
{
|
||||
key: "X2NvbnRyYWN0X2FkZHJlc3M=",
|
||||
value:
|
||||
"d29ybWhvbGUxdWZzM3RscTR1bWxqazBxZmU4azV5YTB4NmhwYXZuODk3dTJjbmY5azBlbjlqcjdxYXJxcWFxZmsyag==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "bWVzc2FnZS5ibG9ja190aW1l", value: "MTcxMTE0MzIyMg==", index: true },
|
||||
{ key: "bWVzc2FnZS5jaGFpbl9pZA==", value: "MzEwNA==", index: true },
|
||||
{
|
||||
key: "bWVzc2FnZS5tZXNzYWdl",
|
||||
value:
|
||||
"MDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDU1NTY0M2EzZjVlZGVjODQ3MWM3NTYyNGViYzQwNzlhNjM0MzI2ZDk2YTY4OWU2MTU3ZDc5YWJlOGY1YTZmOTQ0NzI4NTNiYzAwMDE4NjIyYjk4NzM1Y2I4NzBhZTBjYjIyYmQ0ZWE1OGNmYjUxMmJkNDAwMjI0N2NjZDBiMjUwZWI2ZDBjNTAzMmZjMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA=",
|
||||
index: true,
|
||||
},
|
||||
{ key: "bWVzc2FnZS5ub25jZQ==", value: "NzY3MQ==", index: true },
|
||||
{
|
||||
key: "bWVzc2FnZS5zZW5kZXI=",
|
||||
value:
|
||||
"YWViNTM0YzQ1YzMwNDlkMzgwYjlkOWI5NjZmOTg5NWY1M2FiZDQzMDFiZmFmZjQwN2ZhMDlkZWE4YWU3YTkyNA==",
|
||||
index: true,
|
||||
},
|
||||
{ key: "bWVzc2FnZS5zZXF1ZW5jZQ==", value: "Mjg2MDM=", index: true },
|
||||
],
|
||||
},
|
||||
],
|
||||
blockHeight: 7626736n,
|
||||
timestamp: 1711143222043,
|
||||
};
|
Loading…
Reference in New Issue