1
- import * as anchor from ' @coral-xyz/anchor' ;
2
- import type { Program } from ' @coral-xyz/anchor' ;
1
+ import * as anchor from " @coral-xyz/anchor" ;
2
+ import type { Program } from " @coral-xyz/anchor" ;
3
3
import {
4
4
ASSOCIATED_TOKEN_PROGRAM_ID ,
5
5
TOKEN_2022_PROGRAM_ID ,
6
6
createAssociatedTokenAccountInstruction ,
7
7
createMintToInstruction ,
8
8
createTransferCheckedWithTransferHookInstruction ,
9
9
getAssociatedTokenAddressSync ,
10
- } from '@solana/spl-token' ;
11
- import { Keypair , Transaction , sendAndConfirmTransaction } from '@solana/web3.js' ;
12
- import type { TransferHook } from '../target/types/transfer_hook' ;
13
-
14
- describe ( 'transfer-hook' , ( ) => {
10
+ } from "@solana/spl-token" ;
11
+ import {
12
+ Keypair ,
13
+ Transaction ,
14
+ sendAndConfirmTransaction ,
15
+ SendTransactionError ,
16
+ } from "@solana/web3.js" ;
17
+ import type { TransferHook } from "../target/types/transfer_hook" ;
18
+ import { expect } from "chai" ;
19
+ import chai from "chai" ;
20
+ import chaiAsPromised from "chai-as-promised" ;
21
+
22
+ chai . use ( chaiAsPromised ) ;
23
+
24
+ describe ( "transfer-hook" , ( ) => {
15
25
// Configure the client to use the local cluster.
16
26
const provider = anchor . AnchorProvider . env ( ) ;
17
27
anchor . setProvider ( provider ) ;
@@ -30,7 +40,7 @@ describe('transfer-hook', () => {
30
40
wallet . publicKey ,
31
41
false ,
32
42
TOKEN_2022_PROGRAM_ID ,
33
- ASSOCIATED_TOKEN_PROGRAM_ID ,
43
+ ASSOCIATED_TOKEN_PROGRAM_ID
34
44
) ;
35
45
36
46
// Recipient token account address
@@ -40,21 +50,21 @@ describe('transfer-hook', () => {
40
50
recipient . publicKey ,
41
51
false ,
42
52
TOKEN_2022_PROGRAM_ID ,
43
- ASSOCIATED_TOKEN_PROGRAM_ID ,
53
+ ASSOCIATED_TOKEN_PROGRAM_ID
44
54
) ;
45
55
46
- it ( ' Create Mint with Transfer Hook Extension' , async ( ) => {
56
+ it ( " Create Mint with Transfer Hook Extension" , async ( ) => {
47
57
const transactionSignature = await program . methods
48
58
. initialize ( decimals )
49
59
. accounts ( { mintAccount : mint . publicKey } )
50
60
. signers ( [ mint ] )
51
61
. rpc ( { skipPreflight : true } ) ;
52
- console . log ( ' Your transaction signature' , transactionSignature ) ;
62
+ console . log ( " Your transaction signature" , transactionSignature ) ;
53
63
} ) ;
54
64
55
65
// Create the two token accounts for the transfer-hook enabled mint
56
66
// Fund the sender token account with 100 tokens
57
- it ( ' Create Token Accounts and Mint Tokens' , async ( ) => {
67
+ it ( " Create Token Accounts and Mint Tokens" , async ( ) => {
58
68
// 100 tokens
59
69
const amount = 100 * 10 ** decimals ;
60
70
@@ -65,61 +75,112 @@ describe('transfer-hook', () => {
65
75
wallet . publicKey ,
66
76
mint . publicKey ,
67
77
TOKEN_2022_PROGRAM_ID ,
68
- ASSOCIATED_TOKEN_PROGRAM_ID ,
78
+ ASSOCIATED_TOKEN_PROGRAM_ID
69
79
) ,
70
80
createAssociatedTokenAccountInstruction (
71
81
wallet . publicKey ,
72
82
destinationTokenAccount ,
73
83
recipient . publicKey ,
74
84
mint . publicKey ,
75
85
TOKEN_2022_PROGRAM_ID ,
76
- ASSOCIATED_TOKEN_PROGRAM_ID ,
86
+ ASSOCIATED_TOKEN_PROGRAM_ID
77
87
) ,
78
- createMintToInstruction ( mint . publicKey , sourceTokenAccount , wallet . publicKey , amount , [ ] , TOKEN_2022_PROGRAM_ID ) ,
88
+ createMintToInstruction (
89
+ mint . publicKey ,
90
+ sourceTokenAccount ,
91
+ wallet . publicKey ,
92
+ amount ,
93
+ [ ] ,
94
+ TOKEN_2022_PROGRAM_ID
95
+ )
79
96
) ;
80
97
81
- const txSig = await sendAndConfirmTransaction ( connection , transaction , [ wallet . payer ] , { skipPreflight : true } ) ;
98
+ const txSig = await sendAndConfirmTransaction (
99
+ connection ,
100
+ transaction ,
101
+ [ wallet . payer ] ,
102
+ { skipPreflight : true }
103
+ ) ;
82
104
83
105
console . log ( `Transaction Signature: ${ txSig } ` ) ;
84
106
} ) ;
85
107
86
108
// Account to store extra accounts required by the transfer hook instruction
87
- it ( ' Create ExtraAccountMetaList Account' , async ( ) => {
109
+ it ( " Create ExtraAccountMetaList Account" , async ( ) => {
88
110
const initializeExtraAccountMetaListInstruction = await program . methods
89
111
. initializeExtraAccountMetaList ( )
90
112
. accounts ( {
91
113
mint : mint . publicKey ,
92
114
} )
93
115
. instruction ( ) ;
94
116
95
- const transaction = new Transaction ( ) . add ( initializeExtraAccountMetaListInstruction ) ;
117
+ const transaction = new Transaction ( ) . add (
118
+ initializeExtraAccountMetaListInstruction
119
+ ) ;
96
120
97
- const txSig = await sendAndConfirmTransaction ( provider . connection , transaction , [ wallet . payer ] , { skipPreflight : true , commitment : 'confirmed' } ) ;
98
- console . log ( 'Transaction Signature:' , txSig ) ;
121
+ const txSig = await sendAndConfirmTransaction (
122
+ provider . connection ,
123
+ transaction ,
124
+ [ wallet . payer ] ,
125
+ { skipPreflight : true , commitment : "confirmed" }
126
+ ) ;
127
+ console . log ( "Transaction Signature:" , txSig ) ;
99
128
} ) ;
100
129
101
- it ( ' Transfer Hook with Extra Account Meta' , async ( ) => {
130
+ it ( " Transfer Hook with Extra Account Meta" , async ( ) => {
102
131
// 1 tokens
103
132
const amount = 1 * 10 ** decimals ;
104
133
const bigIntAmount = BigInt ( amount ) ;
105
134
106
135
// Standard token transfer instruction
107
- const transferInstruction = await createTransferCheckedWithTransferHookInstruction (
136
+ const transferInstruction =
137
+ await createTransferCheckedWithTransferHookInstruction (
138
+ connection ,
139
+ sourceTokenAccount ,
140
+ mint . publicKey ,
141
+ destinationTokenAccount ,
142
+ wallet . publicKey ,
143
+ bigIntAmount ,
144
+ decimals ,
145
+ [ ] ,
146
+ "confirmed" ,
147
+ TOKEN_2022_PROGRAM_ID
148
+ ) ;
149
+
150
+ const transaction = new Transaction ( ) . add ( transferInstruction ) ;
151
+
152
+ const txSig = await sendAndConfirmTransaction (
108
153
connection ,
109
- sourceTokenAccount ,
110
- mint . publicKey ,
111
- destinationTokenAccount ,
112
- wallet . publicKey ,
113
- bigIntAmount ,
114
- decimals ,
115
- [ ] ,
116
- 'confirmed' ,
117
- TOKEN_2022_PROGRAM_ID ,
154
+ transaction ,
155
+ [ wallet . payer ] ,
156
+ { skipPreflight : true }
118
157
) ;
158
+ console . log ( "Transfer Signature:" , txSig ) ;
159
+ } ) ;
119
160
120
- const transaction = new Transaction ( ) . add ( transferInstruction ) ;
161
+ it ( "Try call transfer hook without transfer" , async ( ) => {
162
+ const transferHookIx = await program . methods
163
+ . transferHook ( new anchor . BN ( 1 ) )
164
+ . accounts ( {
165
+ sourceToken : sourceTokenAccount ,
166
+ mint : mint . publicKey ,
167
+ destinationToken : destinationTokenAccount ,
168
+ owner : wallet . publicKey ,
169
+ } )
170
+ . instruction ( ) ;
121
171
122
- const txSig = await sendAndConfirmTransaction ( connection , transaction , [ wallet . payer ] , { skipPreflight : true } ) ;
123
- console . log ( 'Transfer Signature:' , txSig ) ;
172
+ const transaction = new Transaction ( ) . add ( transferHookIx ) ;
173
+
174
+ const sendPromise = sendAndConfirmTransaction (
175
+ connection ,
176
+ transaction ,
177
+ [ wallet . payer ] ,
178
+ { skipPreflight : false }
179
+ ) ;
180
+
181
+ await expect ( sendPromise ) . to . eventually . be . rejectedWith (
182
+ SendTransactionError ,
183
+ program . idl . errors [ 0 ] . msg
184
+ ) ;
124
185
} ) ;
125
186
} ) ;
0 commit comments