sol-trade-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +390 -0
- package/dist/chunk-MMQAMIKR.mjs +3735 -0
- package/dist/chunk-NEZDFAYA.mjs +7744 -0
- package/dist/clients-VITWK7B6.mjs +1370 -0
- package/dist/index-1BK_FXsW.d.mts +2327 -0
- package/dist/index-1BK_FXsW.d.ts +2327 -0
- package/dist/index.d.mts +2659 -0
- package/dist/index.d.ts +2659 -0
- package/dist/index.js +13265 -0
- package/dist/index.mjs +562 -0
- package/dist/perf/index.d.mts +2 -0
- package/dist/perf/index.d.ts +2 -0
- package/dist/perf/index.js +3742 -0
- package/dist/perf/index.mjs +214 -0
- package/package.json +101 -0
- package/src/__tests__/complete_sdk.test.ts +354 -0
- package/src/__tests__/hotpath.test.ts +486 -0
- package/src/__tests__/nonce.test.ts +45 -0
- package/src/__tests__/sdk.test.ts +425 -0
- package/src/address-lookup/index.ts +197 -0
- package/src/cache/cache.ts +308 -0
- package/src/calc/index.ts +1058 -0
- package/src/calc/pumpfun.ts +124 -0
- package/src/common/bonding_curve.ts +272 -0
- package/src/common/compute-budget.ts +148 -0
- package/src/common/confirm-any-signature.ts +184 -0
- package/src/common/fast-timing.ts +481 -0
- package/src/common/fast_fn.ts +150 -0
- package/src/common/gas-fee-strategy.ts +253 -0
- package/src/common/map-pool.ts +23 -0
- package/src/common/nonce.ts +40 -0
- package/src/common/sdk-log.ts +460 -0
- package/src/common/seed.ts +381 -0
- package/src/common/spl-token.ts +578 -0
- package/src/common/subscription-handle.ts +644 -0
- package/src/common/trading-utils.ts +239 -0
- package/src/common/wsol-manager.ts +325 -0
- package/src/compute/compute_budget_manager.ts +187 -0
- package/src/compute/index.ts +21 -0
- package/src/constants/index.ts +96 -0
- package/src/execution/execution.ts +532 -0
- package/src/execution/index.ts +42 -0
- package/src/hotpath/executor.ts +464 -0
- package/src/hotpath/index.ts +64 -0
- package/src/hotpath/state.ts +435 -0
- package/src/index.ts +2117 -0
- package/src/instruction/bonk_builder.ts +730 -0
- package/src/instruction/index.ts +24 -0
- package/src/instruction/meteora_damm_v2_builder.ts +509 -0
- package/src/instruction/pumpfun_builder.ts +1183 -0
- package/src/instruction/pumpswap.ts +1123 -0
- package/src/instruction/raydium_amm_v4_builder.ts +692 -0
- package/src/instruction/raydium_cpmm_builder.ts +795 -0
- package/src/middleware/traits.ts +407 -0
- package/src/params/index.ts +483 -0
- package/src/perf/compiler-optimization.ts +529 -0
- package/src/perf/hardware.ts +631 -0
- package/src/perf/index.ts +9 -0
- package/src/perf/kernel-bypass.ts +656 -0
- package/src/perf/protocol.ts +682 -0
- package/src/perf/realtime.ts +592 -0
- package/src/perf/simd.ts +668 -0
- package/src/perf/syscall-bypass.ts +331 -0
- package/src/perf/ultra-low-latency.ts +505 -0
- package/src/perf/zero-copy.ts +589 -0
- package/src/pool/pool.ts +294 -0
- package/src/rpc/client.ts +345 -0
- package/src/sdk-errors.ts +13 -0
- package/src/security/index.ts +26 -0
- package/src/security/secure-key.ts +303 -0
- package/src/security/validators.ts +281 -0
- package/src/seed/pda.ts +262 -0
- package/src/serialization/index.ts +28 -0
- package/src/serialization/serialization.ts +288 -0
- package/src/swqos/clients.ts +1754 -0
- package/src/swqos/index.ts +50 -0
- package/src/swqos/providers.ts +1707 -0
- package/src/trading/core/async-executor.ts +702 -0
- package/src/trading/core/confirmation-monitor.ts +711 -0
- package/src/trading/core/index.ts +82 -0
- package/src/trading/core/retry-handler.ts +683 -0
- package/src/trading/core/transaction-pool.ts +780 -0
- package/src/trading/executor.ts +385 -0
- package/src/trading/factory.ts +282 -0
- package/src/trading/index.ts +30 -0
- package/src/types.ts +8 -0
- package/src/utils/index.ts +155 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPL Token utilities for Sol Trade SDK
|
|
3
|
+
* Provides token account management, mint operations, and instruction building.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
PublicKey,
|
|
8
|
+
TransactionInstruction,
|
|
9
|
+
SystemProgram,
|
|
10
|
+
SYSVAR_RENT_PUBKEY,
|
|
11
|
+
} from '@solana/web3.js';
|
|
12
|
+
|
|
13
|
+
// ===== Token Program IDs =====
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* SPL Token Program ID
|
|
17
|
+
*/
|
|
18
|
+
export const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* SPL Token 2022 Program ID
|
|
22
|
+
*/
|
|
23
|
+
export const TOKEN_2022_PROGRAM_ID = new PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Associated Token Account Program ID
|
|
27
|
+
*/
|
|
28
|
+
export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
|
|
29
|
+
|
|
30
|
+
// ===== Token Account Types =====
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Token account state
|
|
34
|
+
*/
|
|
35
|
+
export enum AccountState {
|
|
36
|
+
Uninitialized = 0,
|
|
37
|
+
Initialized = 1,
|
|
38
|
+
Frozen = 2,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Token account information
|
|
43
|
+
*/
|
|
44
|
+
export interface TokenAccount {
|
|
45
|
+
address: PublicKey;
|
|
46
|
+
mint: PublicKey;
|
|
47
|
+
owner: PublicKey;
|
|
48
|
+
amount: bigint;
|
|
49
|
+
delegate?: PublicKey;
|
|
50
|
+
state: AccountState;
|
|
51
|
+
isNative?: bigint;
|
|
52
|
+
delegatedAmount: bigint;
|
|
53
|
+
closeAuthority?: PublicKey;
|
|
54
|
+
tokenProgram: PublicKey;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Mint account information
|
|
59
|
+
*/
|
|
60
|
+
export interface Mint {
|
|
61
|
+
address: PublicKey;
|
|
62
|
+
mintAuthority?: PublicKey;
|
|
63
|
+
supply: bigint;
|
|
64
|
+
decimals: number;
|
|
65
|
+
isInitialized: boolean;
|
|
66
|
+
freezeAuthority?: PublicKey;
|
|
67
|
+
tokenProgram: PublicKey;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Token account layout sizes
|
|
72
|
+
*/
|
|
73
|
+
export const TOKEN_ACCOUNT_SIZE = 165;
|
|
74
|
+
export const MINT_SIZE = 82;
|
|
75
|
+
export const MULTISIG_SIZE = 355;
|
|
76
|
+
|
|
77
|
+
// ===== Token Instruction Builder =====
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Instruction types for SPL Token program
|
|
81
|
+
*/
|
|
82
|
+
export enum TokenInstruction {
|
|
83
|
+
InitializeMint = 0,
|
|
84
|
+
InitializeAccount = 1,
|
|
85
|
+
InitializeMultisig = 2,
|
|
86
|
+
Transfer = 3,
|
|
87
|
+
Approve = 4,
|
|
88
|
+
Revoke = 5,
|
|
89
|
+
SetAuthority = 6,
|
|
90
|
+
MintTo = 7,
|
|
91
|
+
Burn = 8,
|
|
92
|
+
CloseAccount = 9,
|
|
93
|
+
FreezeAccount = 10,
|
|
94
|
+
ThawAccount = 11,
|
|
95
|
+
TransferChecked = 12,
|
|
96
|
+
ApproveChecked = 13,
|
|
97
|
+
MintToChecked = 14,
|
|
98
|
+
BurnChecked = 15,
|
|
99
|
+
InitializeAccount2 = 16,
|
|
100
|
+
SyncNative = 17,
|
|
101
|
+
InitializeAccount3 = 18,
|
|
102
|
+
InitializeMultisig2 = 19,
|
|
103
|
+
InitializeMint2 = 20,
|
|
104
|
+
GetAccountDataSize = 21,
|
|
105
|
+
InitializeImmutableOwner = 22,
|
|
106
|
+
AmountToUiAmount = 23,
|
|
107
|
+
UiAmountToAmount = 24,
|
|
108
|
+
InitializeMintCloseAuthority = 25,
|
|
109
|
+
CreateNativeMint = 29,
|
|
110
|
+
InitializeNonTransferableMint = 27,
|
|
111
|
+
InitializePermanentDelegate = 35,
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Authority types for SetAuthority instruction
|
|
116
|
+
*/
|
|
117
|
+
export enum AuthorityType {
|
|
118
|
+
MintTokens = 0,
|
|
119
|
+
FreezeAccount = 1,
|
|
120
|
+
AccountOwner = 2,
|
|
121
|
+
CloseAccount = 3,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Builder for SPL Token instructions
|
|
126
|
+
*/
|
|
127
|
+
export class TokenInstructionBuilder {
|
|
128
|
+
/**
|
|
129
|
+
* Create InitializeMint instruction
|
|
130
|
+
*/
|
|
131
|
+
static initializeMint(
|
|
132
|
+
mint: PublicKey,
|
|
133
|
+
decimals: number,
|
|
134
|
+
mintAuthority: PublicKey,
|
|
135
|
+
freezeAuthority: PublicKey | null,
|
|
136
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
137
|
+
): TransactionInstruction {
|
|
138
|
+
const keys = [
|
|
139
|
+
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
140
|
+
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
const data = Buffer.alloc(67);
|
|
144
|
+
data.writeUInt8(TokenInstruction.InitializeMint, 0);
|
|
145
|
+
data.writeUInt8(decimals, 1);
|
|
146
|
+
data.writeUInt8(1, 2); // Mint authority option
|
|
147
|
+
data.set(mintAuthority.toBytes(), 3);
|
|
148
|
+
data.writeUInt8(freezeAuthority ? 1 : 0, 35);
|
|
149
|
+
if (freezeAuthority) {
|
|
150
|
+
data.set(freezeAuthority.toBytes(), 36);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return new TransactionInstruction({
|
|
154
|
+
keys,
|
|
155
|
+
programId: tokenProgram,
|
|
156
|
+
data,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Create InitializeAccount instruction
|
|
162
|
+
*/
|
|
163
|
+
static initializeAccount(
|
|
164
|
+
account: PublicKey,
|
|
165
|
+
mint: PublicKey,
|
|
166
|
+
owner: PublicKey,
|
|
167
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
168
|
+
): TransactionInstruction {
|
|
169
|
+
const keys = [
|
|
170
|
+
{ pubkey: account, isSigner: false, isWritable: true },
|
|
171
|
+
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
172
|
+
{ pubkey: owner, isSigner: false, isWritable: false },
|
|
173
|
+
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
const data = Buffer.from([TokenInstruction.InitializeAccount]);
|
|
177
|
+
|
|
178
|
+
return new TransactionInstruction({
|
|
179
|
+
keys,
|
|
180
|
+
programId: tokenProgram,
|
|
181
|
+
data,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Create Transfer instruction
|
|
187
|
+
*/
|
|
188
|
+
static transfer(
|
|
189
|
+
source: PublicKey,
|
|
190
|
+
destination: PublicKey,
|
|
191
|
+
owner: PublicKey,
|
|
192
|
+
amount: bigint,
|
|
193
|
+
multiSigners: PublicKey[] = [],
|
|
194
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
195
|
+
): TransactionInstruction {
|
|
196
|
+
const keys = [
|
|
197
|
+
{ pubkey: source, isSigner: false, isWritable: true },
|
|
198
|
+
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
199
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
200
|
+
...multiSigners.map((signer) => ({
|
|
201
|
+
pubkey: signer,
|
|
202
|
+
isSigner: true,
|
|
203
|
+
isWritable: false,
|
|
204
|
+
})),
|
|
205
|
+
];
|
|
206
|
+
|
|
207
|
+
const data = Buffer.alloc(9);
|
|
208
|
+
data.writeUInt8(TokenInstruction.Transfer, 0);
|
|
209
|
+
data.writeBigUInt64LE(amount, 1);
|
|
210
|
+
|
|
211
|
+
return new TransactionInstruction({
|
|
212
|
+
keys,
|
|
213
|
+
programId: tokenProgram,
|
|
214
|
+
data,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Create TransferChecked instruction
|
|
220
|
+
*/
|
|
221
|
+
static transferChecked(
|
|
222
|
+
source: PublicKey,
|
|
223
|
+
mint: PublicKey,
|
|
224
|
+
destination: PublicKey,
|
|
225
|
+
owner: PublicKey,
|
|
226
|
+
amount: bigint,
|
|
227
|
+
decimals: number,
|
|
228
|
+
multiSigners: PublicKey[] = [],
|
|
229
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
230
|
+
): TransactionInstruction {
|
|
231
|
+
const keys = [
|
|
232
|
+
{ pubkey: source, isSigner: false, isWritable: true },
|
|
233
|
+
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
234
|
+
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
235
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
236
|
+
...multiSigners.map((signer) => ({
|
|
237
|
+
pubkey: signer,
|
|
238
|
+
isSigner: true,
|
|
239
|
+
isWritable: false,
|
|
240
|
+
})),
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
const data = Buffer.alloc(10);
|
|
244
|
+
data.writeUInt8(TokenInstruction.TransferChecked, 0);
|
|
245
|
+
data.writeBigUInt64LE(amount, 1);
|
|
246
|
+
data.writeUInt8(decimals, 9);
|
|
247
|
+
|
|
248
|
+
return new TransactionInstruction({
|
|
249
|
+
keys,
|
|
250
|
+
programId: tokenProgram,
|
|
251
|
+
data,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Create MintTo instruction
|
|
257
|
+
*/
|
|
258
|
+
static mintTo(
|
|
259
|
+
mint: PublicKey,
|
|
260
|
+
destination: PublicKey,
|
|
261
|
+
authority: PublicKey,
|
|
262
|
+
amount: bigint,
|
|
263
|
+
multiSigners: PublicKey[] = [],
|
|
264
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
265
|
+
): TransactionInstruction {
|
|
266
|
+
const keys = [
|
|
267
|
+
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
268
|
+
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
269
|
+
{ pubkey: authority, isSigner: multiSigners.length === 0, isWritable: false },
|
|
270
|
+
...multiSigners.map((signer) => ({
|
|
271
|
+
pubkey: signer,
|
|
272
|
+
isSigner: true,
|
|
273
|
+
isWritable: false,
|
|
274
|
+
})),
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
const data = Buffer.alloc(9);
|
|
278
|
+
data.writeUInt8(TokenInstruction.MintTo, 0);
|
|
279
|
+
data.writeBigUInt64LE(amount, 1);
|
|
280
|
+
|
|
281
|
+
return new TransactionInstruction({
|
|
282
|
+
keys,
|
|
283
|
+
programId: tokenProgram,
|
|
284
|
+
data,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Create Burn instruction
|
|
290
|
+
*/
|
|
291
|
+
static burn(
|
|
292
|
+
account: PublicKey,
|
|
293
|
+
mint: PublicKey,
|
|
294
|
+
owner: PublicKey,
|
|
295
|
+
amount: bigint,
|
|
296
|
+
multiSigners: PublicKey[] = [],
|
|
297
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
298
|
+
): TransactionInstruction {
|
|
299
|
+
const keys = [
|
|
300
|
+
{ pubkey: account, isSigner: false, isWritable: true },
|
|
301
|
+
{ pubkey: mint, isSigner: false, isWritable: true },
|
|
302
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
303
|
+
...multiSigners.map((signer) => ({
|
|
304
|
+
pubkey: signer,
|
|
305
|
+
isSigner: true,
|
|
306
|
+
isWritable: false,
|
|
307
|
+
})),
|
|
308
|
+
];
|
|
309
|
+
|
|
310
|
+
const data = Buffer.alloc(9);
|
|
311
|
+
data.writeUInt8(TokenInstruction.Burn, 0);
|
|
312
|
+
data.writeBigUInt64LE(amount, 1);
|
|
313
|
+
|
|
314
|
+
return new TransactionInstruction({
|
|
315
|
+
keys,
|
|
316
|
+
programId: tokenProgram,
|
|
317
|
+
data,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Create Approve instruction
|
|
323
|
+
*/
|
|
324
|
+
static approve(
|
|
325
|
+
account: PublicKey,
|
|
326
|
+
delegate: PublicKey,
|
|
327
|
+
owner: PublicKey,
|
|
328
|
+
amount: bigint,
|
|
329
|
+
multiSigners: PublicKey[] = [],
|
|
330
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
331
|
+
): TransactionInstruction {
|
|
332
|
+
const keys = [
|
|
333
|
+
{ pubkey: account, isSigner: false, isWritable: true },
|
|
334
|
+
{ pubkey: delegate, isSigner: false, isWritable: false },
|
|
335
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
336
|
+
...multiSigners.map((signer) => ({
|
|
337
|
+
pubkey: signer,
|
|
338
|
+
isSigner: true,
|
|
339
|
+
isWritable: false,
|
|
340
|
+
})),
|
|
341
|
+
];
|
|
342
|
+
|
|
343
|
+
const data = Buffer.alloc(9);
|
|
344
|
+
data.writeUInt8(TokenInstruction.Approve, 0);
|
|
345
|
+
data.writeBigUInt64LE(amount, 1);
|
|
346
|
+
|
|
347
|
+
return new TransactionInstruction({
|
|
348
|
+
keys,
|
|
349
|
+
programId: tokenProgram,
|
|
350
|
+
data,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Create Revoke instruction
|
|
356
|
+
*/
|
|
357
|
+
static revoke(
|
|
358
|
+
account: PublicKey,
|
|
359
|
+
owner: PublicKey,
|
|
360
|
+
multiSigners: PublicKey[] = [],
|
|
361
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
362
|
+
): TransactionInstruction {
|
|
363
|
+
const keys = [
|
|
364
|
+
{ pubkey: account, isSigner: false, isWritable: true },
|
|
365
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
366
|
+
...multiSigners.map((signer) => ({
|
|
367
|
+
pubkey: signer,
|
|
368
|
+
isSigner: true,
|
|
369
|
+
isWritable: false,
|
|
370
|
+
})),
|
|
371
|
+
];
|
|
372
|
+
|
|
373
|
+
const data = Buffer.from([TokenInstruction.Revoke]);
|
|
374
|
+
|
|
375
|
+
return new TransactionInstruction({
|
|
376
|
+
keys,
|
|
377
|
+
programId: tokenProgram,
|
|
378
|
+
data,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Create CloseAccount instruction
|
|
384
|
+
*/
|
|
385
|
+
static closeAccount(
|
|
386
|
+
account: PublicKey,
|
|
387
|
+
destination: PublicKey,
|
|
388
|
+
owner: PublicKey,
|
|
389
|
+
multiSigners: PublicKey[] = [],
|
|
390
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
391
|
+
): TransactionInstruction {
|
|
392
|
+
const keys = [
|
|
393
|
+
{ pubkey: account, isSigner: false, isWritable: true },
|
|
394
|
+
{ pubkey: destination, isSigner: false, isWritable: true },
|
|
395
|
+
{ pubkey: owner, isSigner: multiSigners.length === 0, isWritable: false },
|
|
396
|
+
...multiSigners.map((signer) => ({
|
|
397
|
+
pubkey: signer,
|
|
398
|
+
isSigner: true,
|
|
399
|
+
isWritable: false,
|
|
400
|
+
})),
|
|
401
|
+
];
|
|
402
|
+
|
|
403
|
+
const data = Buffer.from([TokenInstruction.CloseAccount]);
|
|
404
|
+
|
|
405
|
+
return new TransactionInstruction({
|
|
406
|
+
keys,
|
|
407
|
+
programId: tokenProgram,
|
|
408
|
+
data,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Create SyncNative instruction (for WSOL accounts)
|
|
414
|
+
*/
|
|
415
|
+
static syncNative(
|
|
416
|
+
nativeAccount: PublicKey,
|
|
417
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID
|
|
418
|
+
): TransactionInstruction {
|
|
419
|
+
const keys = [{ pubkey: nativeAccount, isSigner: false, isWritable: true }];
|
|
420
|
+
|
|
421
|
+
const data = Buffer.from([TokenInstruction.SyncNative]);
|
|
422
|
+
|
|
423
|
+
return new TransactionInstruction({
|
|
424
|
+
keys,
|
|
425
|
+
programId: tokenProgram,
|
|
426
|
+
data,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ===== Token Utilities =====
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Token utility functions
|
|
435
|
+
*/
|
|
436
|
+
export class TokenUtil {
|
|
437
|
+
/**
|
|
438
|
+
* Calculate associated token account address
|
|
439
|
+
*/
|
|
440
|
+
static async getAssociatedTokenAddress(
|
|
441
|
+
mint: PublicKey,
|
|
442
|
+
owner: PublicKey,
|
|
443
|
+
_allowOwnerOffCurve: boolean = false,
|
|
444
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID,
|
|
445
|
+
associatedTokenProgram: PublicKey = ASSOCIATED_TOKEN_PROGRAM_ID
|
|
446
|
+
): Promise<PublicKey> {
|
|
447
|
+
const [address] = await PublicKey.findProgramAddress(
|
|
448
|
+
[owner.toBuffer(), tokenProgram.toBuffer(), mint.toBuffer()],
|
|
449
|
+
associatedTokenProgram
|
|
450
|
+
);
|
|
451
|
+
return address;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Create associated token account idempotent instruction
|
|
456
|
+
*/
|
|
457
|
+
static createAssociatedTokenAccountIdempotentInstruction(
|
|
458
|
+
payer: PublicKey,
|
|
459
|
+
associatedToken: PublicKey,
|
|
460
|
+
owner: PublicKey,
|
|
461
|
+
mint: PublicKey,
|
|
462
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID,
|
|
463
|
+
associatedTokenProgram: PublicKey = ASSOCIATED_TOKEN_PROGRAM_ID
|
|
464
|
+
): TransactionInstruction {
|
|
465
|
+
const keys = [
|
|
466
|
+
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
467
|
+
{ pubkey: associatedToken, isSigner: false, isWritable: true },
|
|
468
|
+
{ pubkey: owner, isSigner: false, isWritable: false },
|
|
469
|
+
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
470
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
471
|
+
{ pubkey: tokenProgram, isSigner: false, isWritable: false },
|
|
472
|
+
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
|
|
473
|
+
];
|
|
474
|
+
|
|
475
|
+
// Instruction data: 1 = CreateIdempotent
|
|
476
|
+
const data = Buffer.from([1]);
|
|
477
|
+
|
|
478
|
+
return new TransactionInstruction({
|
|
479
|
+
keys,
|
|
480
|
+
programId: associatedTokenProgram,
|
|
481
|
+
data,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Create associated token account instruction
|
|
487
|
+
*/
|
|
488
|
+
static createAssociatedTokenAccountInstruction(
|
|
489
|
+
payer: PublicKey,
|
|
490
|
+
associatedToken: PublicKey,
|
|
491
|
+
owner: PublicKey,
|
|
492
|
+
mint: PublicKey,
|
|
493
|
+
tokenProgram: PublicKey = TOKEN_PROGRAM_ID,
|
|
494
|
+
associatedTokenProgram: PublicKey = ASSOCIATED_TOKEN_PROGRAM_ID
|
|
495
|
+
): TransactionInstruction {
|
|
496
|
+
const keys = [
|
|
497
|
+
{ pubkey: payer, isSigner: true, isWritable: true },
|
|
498
|
+
{ pubkey: associatedToken, isSigner: false, isWritable: true },
|
|
499
|
+
{ pubkey: owner, isSigner: false, isWritable: false },
|
|
500
|
+
{ pubkey: mint, isSigner: false, isWritable: false },
|
|
501
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
502
|
+
{ pubkey: tokenProgram, isSigner: false, isWritable: false },
|
|
503
|
+
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
|
|
504
|
+
];
|
|
505
|
+
|
|
506
|
+
// Instruction data: 0 = Create
|
|
507
|
+
const data = Buffer.from([0]);
|
|
508
|
+
|
|
509
|
+
return new TransactionInstruction({
|
|
510
|
+
keys,
|
|
511
|
+
programId: associatedTokenProgram,
|
|
512
|
+
data,
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Check if a token is a wrapped SOL (WSOL) token
|
|
518
|
+
*/
|
|
519
|
+
static isWrappedSol(mint: PublicKey): boolean {
|
|
520
|
+
return mint.equals(WSOL_MINT);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Convert token amount to UI amount (with decimals)
|
|
525
|
+
*/
|
|
526
|
+
static toUiAmount(amount: bigint, decimals: number): number {
|
|
527
|
+
return Number(amount) / Math.pow(10, decimals);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Convert UI amount to token amount (with decimals)
|
|
532
|
+
*/
|
|
533
|
+
static fromUiAmount(uiAmount: number, decimals: number): bigint {
|
|
534
|
+
return BigInt(Math.floor(uiAmount * Math.pow(10, decimals)));
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Format token amount for display
|
|
539
|
+
*/
|
|
540
|
+
static formatAmount(amount: bigint, decimals: number, maxDecimals: number = 6): string {
|
|
541
|
+
const uiAmount = this.toUiAmount(amount, decimals);
|
|
542
|
+
return uiAmount.toLocaleString('en-US', {
|
|
543
|
+
maximumFractionDigits: maxDecimals,
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// ===== Common Token Mints =====
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Wrapped SOL mint
|
|
552
|
+
*/
|
|
553
|
+
export const WSOL_MINT = new PublicKey('So11111111111111111111111111111111111111112');
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Native SOL mint (for Token-2022)
|
|
557
|
+
*/
|
|
558
|
+
export const NATIVE_MINT = new PublicKey('So11111111111111111111111111111111111111111');
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* USDC mint
|
|
562
|
+
*/
|
|
563
|
+
export const USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* USDT mint
|
|
567
|
+
*/
|
|
568
|
+
export const USDT_MINT = new PublicKey('Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB');
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Common token decimals
|
|
572
|
+
*/
|
|
573
|
+
export const TOKEN_DECIMALS = {
|
|
574
|
+
SOL: 9,
|
|
575
|
+
WSOL: 9,
|
|
576
|
+
USDC: 6,
|
|
577
|
+
USDT: 6,
|
|
578
|
+
} as const;
|