wormhole-explorer/blockchain-watcher/test/infrastructure/mappers/solana/solanaTransferRedeemedMappe...

357 lines
14 KiB
TypeScript

import { expect, describe, it, jest } from "@jest/globals";
import { solana } from "../../../../src/domain/entities";
import { solanaTransferRedeemedMapper } from "../../../../src/infrastructure/mappers";
import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
jest.mock("@certusone/wormhole-sdk/lib/cjs/solana/wormhole");
describe("solanaTransferRedeemedMapper", () => {
it("should map a token bridge tx to a transfer-redeemed event", async () => {
const mockGetPostedMessage = getPostedMessage as jest.MockedFunction<typeof getPostedMessage>;
mockGetPostedMessage.mockResolvedValueOnce({
message: {
emitterChain: 2,
sequence: 1500n,
emitterAddress: Buffer.from(
"0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
"hex"
),
submissionTime: 1700571923,
nonce: 0,
consistencyLevel: 1,
payload: Buffer.from("41QVZTrdrRxb", "base64"),
} as any,
});
const programId = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb";
const tx = {
blockTime: 1701724272,
meta: {
innerInstructions: [
{
index: 0,
instructions: [
{
accounts: [0, 3],
data: "3Bxs49175da2o1zw",
programIdIndex: 4,
stackHeight: 2,
},
{
accounts: [3],
data: "9krTCzbLfv4BRBcj",
programIdIndex: 4,
stackHeight: 2,
},
{
accounts: [3],
data: "SYXsBvR59hMYH7jGFg8pjr13roqCKDy5t1HFBVKFNWZ1FPp7",
programIdIndex: 4,
stackHeight: 2,
},
{
accounts: [2, 1, 6],
data: "6jFrQ56LiKZ1",
programIdIndex: 11,
stackHeight: 2,
},
{
accounts: [2, 1, 6],
data: "6AjePwYNteRu",
programIdIndex: 11,
stackHeight: 2,
},
],
},
],
logMessages: [
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: MintTo",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 136305 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: MintTo",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4589 of 125187 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb consumed 80797 of 200000 compute units",
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb success",
],
status: {
Ok: null,
},
},
slot: 234015120,
transaction: {
message: {
header: {
numReadonlySignedAccounts: 0,
numReadonlyUnsignedAccounts: 10,
numRequiredSignatures: 1,
},
accountKeys: [
"7dm9am6Qx7cH64RB99Mzf7ZsLbEfmXM7ihXXCvMiT2X1",
"4RrFMkY3A5zWdizT61Px222qmSTJqnVszDeBZZNSoAH6",
"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs",
"HkpTbh5td45g3SfFsKmjukX2YZUKfEHZG5HfRrw6Tkyi",
"11111111111111111111111111111111",
"2gQuwC9GMUCVcXw9VffeCswhKbPeyzHH9ZPEnRBw4K9w",
"BCD75RNBHrJJpW4dXVagL5mPjzRLnVZq4YirJdjEYMV7",
"CvYA8s1SnSzQzCv71rjt7Sc9iEVNjz2exRpoucyH2RCE",
"DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx",
"DujfLgMKW71CT2W8pxknf42FT86VbcK5PjQ6LsutjWKC",
"SysvarRent111111111111111111111111111111111",
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
"wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb",
],
recentBlockhash: "H9bDwcfav3nq9wvzJi9sEPCm4oHxqS59nZU81mncD6AU",
instructions: [
{
accounts: [0, 8, 7, 3, 9, 1, 1, 2, 5, 6, 10, 4, 11, 12],
data: "4",
programIdIndex: 13,
stackHeight: null,
},
],
indexToProgramIds: {},
compiledInstructions: [
{
programIdIndex: 13,
accountKeyIndexes: [0, 8, 7, 3, 9, 1, 1, 2, 5, 6, 10, 4, 11, 12],
data: new Uint8Array([3]),
},
],
},
signatures: [
"3FySmshUgVCM2N158oNYbeTfZt2typEU32c9ZxdAXiXURFHuTmeJHhc7cSUtqHdwAsbVWWvEsEddWNAKzkjVPSg2",
],
},
version: "legacy",
} as any as solana.Transaction;
const events = await solanaTransferRedeemedMapper(tx, { programId });
expect(events).toHaveLength(1);
expect(events[0].name).toBe("transfer-redeemed");
expect(events[0].address).toBe(programId);
expect(events[0].chainId).toBe(1);
expect(events[0].txHash).toBe(tx.transaction.signatures[0]);
expect(events[0].blockHeight).toBe(BigInt(tx.slot));
expect(events[0].blockTime).toBe(tx.blockTime);
});
it("should map a tx involving token bridge relayer (aka connect) to a transfer-redeemed event", async () => {
const mockGetPostedMessage = getPostedMessage as jest.MockedFunction<typeof getPostedMessage>;
mockGetPostedMessage.mockResolvedValueOnce({
message: {
emitterChain: 4,
sequence: 5185,
emitterAddress: Buffer.from(
"0000000000000000000000009dcf9d205c9de35334d646bee44b2d2859712a09",
"hex"
),
submissionTime: 1700571923,
nonce: 0,
consistencyLevel: 1,
payload: Buffer.from("41QVZTrdrRxb", "base64"),
} as any,
});
const programId = "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe";
const tx = {
blockTime: 1701701948,
meta: {
innerInstructions: [
{
index: 0,
instructions: [
{
accounts: [0, 1],
data: "11119os1e9qSs2u7TsThXqkBSRVFxhmYaFKFZ1waB2X7armDmvK3p5GmLdUxYdg3h7QSrL",
programIdIndex: 7,
stackHeight: 2,
},
{
accounts: [1, 4],
data: "6NejZzEkDLeuHiYpvQR3Ck46Sw6FQeXFmX5TGWpBSLgJ1",
programIdIndex: 22,
stackHeight: 2,
},
{
accounts: [0, 15, 8, 5, 16, 1, 9, 1, 4, 12, 20, 21, 7, 11, 22],
data: "B",
programIdIndex: 18,
stackHeight: 2,
},
{
accounts: [0, 5],
data: "11112ncWAFpbecrgZiGiLpaHnEYkj7ECUfBBRHr4H5tFCq9bHFXWRyWUjj586frtFc19oa",
programIdIndex: 7,
stackHeight: 3,
},
{
accounts: [4, 1, 20],
data: "6j1A9VR8zuFm",
programIdIndex: 22,
stackHeight: 3,
},
{
accounts: [1, 2, 9],
data: "3tMLEJ9BQpG7",
programIdIndex: 22,
stackHeight: 2,
},
{
accounts: [1, 6, 9],
data: "3qeniiQUmAqm",
programIdIndex: 22,
stackHeight: 2,
},
{
accounts: [1, 0, 9],
data: "A",
programIdIndex: 22,
stackHeight: 2,
},
],
},
],
loadedAddresses: {
readonly: [],
writable: [],
},
logMessages: [
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg invoke [1]",
"Program log: Instruction: CompleteWrappedTransferWithRelay",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: InitializeAccount3",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4214 of 223786 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe invoke [2]",
"Program log: Instruction: LegacyCompleteTransferWithPayloadWrapped",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
"Program log: Instruction: MintTo",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4492 of 128286 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe consumed 50570 of 173121 compute units",
"Program DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: Transfer",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 119156 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: Transfer",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 111686 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: CloseAccount",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3015 of 104235 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg consumed 150503 of 250000 compute units",
"Program 3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
],
status: {
Ok: null,
},
},
slot: 262968784,
transaction: {
message: {
header: {
numReadonlySignedAccounts: 0,
numReadonlyUnsignedAccounts: 16,
numRequiredSignatures: 1,
},
accountKeys: [
"hiUN9rS9VTPVGYc71Vf2d6iyFLvsQaSsqWhxydqdaZf",
"14UpGeFGK9iEhVTgMbdd7RHZmBKb8BYxBpAYGtBWigeT",
"3pjtJPtu7Z9NzQinCaaRyUsZPwSrNjGxYi7RMwkigk47",
"8DW7zrpEe9EVxbD8PBfmEKNkCwXPFTVVukHXirrcE9iV",
"BaGfF51MQ3a61papTRDYaNefBgTQ9ywnVne5fCff4bxT",
"bMDMKEYXfWM2h5AyJL4kzBXLr8Wms29NSWeGQGLgEad",
"EGdE1V4GLFyZH5FFDtsxZaRkw84WhwPWJkCV4yT2L6F4",
"11111111111111111111111111111111",
"2EqgRpRxi1MR8QLycFDcMKws1Kv56dQcwSmXKkFJZgnW",
"2X2u43DR3odTT4jQKFqsG5f4SCfbEmz4pAHR2EVd3Xs3",
"3bPRWXqtSfUaCw3S4wdgvypQtsSzcmvDeaqSqPDkncrg",
"3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
"5rmBUDWruRcWU4S4JyjPLZhcYJARYw4FeU9brEo4nUzo",
"7pFgBNscwYBfKs1Bsi7wgyibmtNCmK4442pgL4xiJcTr",
"8huuoQHYxWGs3oYoKXJBsBgPousVa9XfkPyHWrpPH1B8",
"8PFZNjn19BBYVHNp4H31bEW7eAmu78Yf2RKV8EeA461K",
"9A7Z7kJw7hPsBJQDSeFU63DsgZGhSTjXmGLYS81yCHBN",
"ComputeBudget111111111111111111111111111111",
"DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe",
"HeMY4WFgEA8zkbp7HMCma5mswLArPzPe53EkYcXDJTUV",
"rRsXLHe7sBHdyKU3KY3wbcgWvoT1Ntqudf6e9PKusgb",
"SysvarRent111111111111111111111111111111111",
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
],
recentBlockhash: "KVvqcsFkfd4mgWjqjsEATKvciAwCwUgdeVHeRh4LqyT",
instructions: [
{
accounts: [0, 9, 2, 19, 4, 6, 3, 13, 14, 1, 12, 15, 8, 5, 16, 20, 11, 18, 7, 22, 21],
data: "9ewcWKkpwjKSXZao88ZRqjejhWC1Bf6cFzdxHbDN4taHHCL3zM9P3xi",
programIdIndex: 10,
stackHeight: null,
},
{
accounts: [],
data: "HnkkG7",
programIdIndex: 17,
stackHeight: null,
},
],
indexToProgramIds: {},
compiledInstructions: [
{
programIdIndex: 10,
accountKeyIndexes: [
0, 9, 2, 19, 4, 6, 3, 13, 14, 1, 12, 15, 8, 5, 16, 20, 11, 18, 7, 22, 21,
],
data: new Uint8Array([
174, 44, 4, 91, 81, 201, 235, 255, 59, 128, 71, 194, 194, 46, 49, 88, 200, 5, 254,
175, 217, 196, 30, 63, 1, 233, 245, 96, 162, 12, 73, 62, 205, 171, 142, 159, 18, 6,
57, 151,
]),
},
{
programIdIndex: 17,
accountKeyIndexes: [],
data: new Uint8Array([2, 144, 208, 3, 0]),
},
],
},
signatures: [
"5Cu3tD15AtcQ5NGK6PFT9UMVmqh94ARz8FXpFts5G1nNzQnXXaugP3ELa79P9xCwESC5Kw7FtGHUgh7vz8DuP8tM",
],
},
version: "legacy",
} as any as solana.Transaction;
const events = await solanaTransferRedeemedMapper(tx, { programId });
expect(events).toHaveLength(1);
expect(events[0].name).toBe("transfer-redeemed");
expect(events[0].address).toBe(programId);
expect(events[0].chainId).toBe(1);
expect(events[0].txHash).toBe(tx.transaction.signatures[0]);
expect(events[0].blockHeight).toBe(BigInt(tx.slot));
expect(events[0].blockTime).toBe(tx.blockTime);
});
});