Skip to content

Commit 102f0b4

Browse files
committed
solana/sdk: support transfer hook
1 parent 277b3e7 commit 102f0b4

File tree

2 files changed

+267
-33
lines changed

2 files changed

+267
-33
lines changed

solana/tests/example-native-token-transfer.ts

+103-19
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ import {
1616
serializePayload,
1717
deserializePayload,
1818
} from "@wormhole-foundation/sdk-definitions";
19-
import { NttMessage, postVaa, NTT, nttMessageLayout } from "../ts/sdk";
19+
import { postVaa, NTT, nttMessageLayout } from "../ts/sdk";
20+
import { WormholeTransceiverMessage } from "../ts/sdk/nttLayout";
21+
2022
import {
21-
NativeTokenTransfer,
22-
TransceiverMessage,
23-
WormholeTransceiverMessage,
24-
nativeTokenTransferLayout,
25-
nttManagerMessageLayout,
26-
} from "../ts/sdk/nttLayout";
23+
PublicKey,
24+
SystemProgram,
25+
Transaction,
26+
sendAndConfirmTransaction,
27+
} from "@solana/web3.js";
28+
29+
import { DummyTransferHook } from "../target/types/dummy_transfer_hook";
2730

2831
export const GUARDIAN_KEY =
2932
"cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
@@ -48,25 +51,78 @@ describe("example-native-token-transfers", () => {
4851
const user = anchor.web3.Keypair.generate();
4952
let tokenAccount: anchor.web3.PublicKey;
5053

51-
let mint: anchor.web3.PublicKey;
54+
const mint = anchor.web3.Keypair.generate();
55+
56+
const dummyTransferHook = anchor.workspace
57+
.DummyTransferHook as anchor.Program<DummyTransferHook>;
58+
59+
const [extraAccountMetaListPDA] = PublicKey.findProgramAddressSync(
60+
[Buffer.from("extra-account-metas"), mint.publicKey.toBuffer()],
61+
dummyTransferHook.programId
62+
);
63+
64+
const [counterPDA] = PublicKey.findProgramAddressSync(
65+
[Buffer.from("counter")],
66+
dummyTransferHook.programId
67+
);
68+
69+
async function counterValue(): Promise<anchor.BN> {
70+
const counter = await dummyTransferHook.account.counter.fetch(counterPDA);
71+
return counter.count
72+
}
73+
74+
it("Initialize mint", async () => {
75+
const extensions = [spl.ExtensionType.TransferHook];
76+
const mintLen = spl.getMintLen(extensions);
77+
const lamports = await connection.getMinimumBalanceForRentExemption(
78+
mintLen
79+
);
80+
81+
const transaction = new Transaction().add(
82+
SystemProgram.createAccount({
83+
fromPubkey: payer.publicKey,
84+
newAccountPubkey: mint.publicKey,
85+
space: mintLen,
86+
lamports,
87+
programId: spl.TOKEN_2022_PROGRAM_ID,
88+
}),
89+
spl.createInitializeTransferHookInstruction(
90+
mint.publicKey,
91+
owner.publicKey,
92+
dummyTransferHook.programId,
93+
spl.TOKEN_2022_PROGRAM_ID
94+
),
95+
spl.createInitializeMintInstruction(
96+
mint.publicKey,
97+
9,
98+
owner.publicKey,
99+
null,
100+
spl.TOKEN_2022_PROGRAM_ID
101+
)
102+
);
52103

53-
before(async () => {
54-
// airdrop some tokens to payer
55-
mint = await spl.createMint(connection, payer, owner.publicKey, null, 9);
104+
await sendAndConfirmTransaction(connection, transaction, [payer, mint]);
56105

57106
tokenAccount = await spl.createAssociatedTokenAccount(
58107
connection,
59108
payer,
60-
mint,
61-
user.publicKey
109+
mint.publicKey,
110+
user.publicKey,
111+
undefined,
112+
spl.TOKEN_2022_PROGRAM_ID,
113+
spl.ASSOCIATED_TOKEN_PROGRAM_ID
62114
);
115+
63116
await spl.mintTo(
64117
connection,
65118
payer,
66-
mint,
119+
mint.publicKey,
67120
tokenAccount,
68121
owner,
69-
BigInt(10000000)
122+
BigInt(10000000),
123+
undefined,
124+
undefined,
125+
spl.TOKEN_2022_PROGRAM_ID
70126
);
71127
});
72128

@@ -75,22 +131,47 @@ describe("example-native-token-transfers", () => {
75131
expect(version).to.equal("1.0.0");
76132
});
77133

134+
it("Create ExtraAccountMetaList Account", async () => {
135+
const initializeExtraAccountMetaListInstruction =
136+
await dummyTransferHook.methods
137+
.initializeExtraAccountMetaList()
138+
.accountsStrict({
139+
payer: payer.publicKey,
140+
mint: mint.publicKey,
141+
counter: counterPDA,
142+
extraAccountMetaList: extraAccountMetaListPDA,
143+
tokenProgram: spl.TOKEN_2022_PROGRAM_ID,
144+
associatedTokenProgram: spl.ASSOCIATED_TOKEN_PROGRAM_ID,
145+
systemProgram: SystemProgram.programId,
146+
})
147+
.instruction();
148+
149+
const transaction = new Transaction().add(
150+
initializeExtraAccountMetaListInstruction
151+
);
152+
153+
await sendAndConfirmTransaction(connection, transaction, [payer]);
154+
});
155+
78156
describe("Locking", () => {
79157
before(async () => {
80158
await spl.setAuthority(
81159
connection,
82160
payer,
83-
mint,
161+
mint.publicKey,
84162
owner,
85-
0, // mint
86-
ntt.tokenAuthorityAddress()
163+
spl.AuthorityType.MintTokens,
164+
ntt.tokenAuthorityAddress(),
165+
[],
166+
undefined,
167+
spl.TOKEN_2022_PROGRAM_ID
87168
);
88169

89170
await ntt.initialize({
90171
payer,
91172
owner: payer,
92173
chain: "solana",
93-
mint,
174+
mint: mint.publicKey,
94175
outboundLimit: new BN(1000000),
95176
mode: "locking",
96177
});
@@ -173,6 +254,7 @@ describe("example-native-token-transfers", () => {
173254

174255
// TODO: assert other stuff in the message
175256
// console.log(nttManagerMessage);
257+
expect((await counterValue()).toString()).to.be.eq("1")
176258
});
177259

178260
it("Can receive tokens", async () => {
@@ -230,6 +312,8 @@ describe("example-native-token-transfers", () => {
230312
});
231313

232314
expect(released).to.equal(true);
315+
316+
expect((await counterValue()).toString()).to.be.eq("2")
233317
});
234318
});
235319

0 commit comments

Comments
 (0)