@gabox-labs/sdk 0.2.0 → 0.7.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/CHANGELOG.md +310 -0
- package/README.md +173 -438
- package/dist/{gaboxV2-CV2XltqC.js → gabox-DGTCh34U.js} +575 -1584
- package/dist/gabox-DGTCh34U.js.map +1 -0
- package/dist/generated/index.d.ts +384 -752
- package/dist/generated/index.js +116 -338
- package/dist/generated/index.js.map +1 -1
- package/dist/index-C4at2cZ_.d.ts +1184 -0
- package/dist/index.d.ts +474 -432
- package/dist/index.js +1186 -1374
- package/dist/index.js.map +1 -1
- package/dist/raydium/index.d.ts +2 -0
- package/dist/raydium/index.js +2 -0
- package/dist/raydium-CU-tZzIk.js +3282 -0
- package/dist/raydium-CU-tZzIk.js.map +1 -0
- package/llms.txt +7 -3
- package/package.json +11 -16
- package/skills/gabox-sdk/SKILL.md +57 -146
- package/skills/gabox-sdk/references/api.md +155 -145
- package/dist/gaboxV2-CV2XltqC.js.map +0 -1
- package/dist/index-BxvSkzCO.d.ts +0 -471
- package/dist/pump/index.d.ts +0 -2
- package/dist/pump/index.js +0 -2
- package/dist/pump-D0K_0uiC.js +0 -1531
- package/dist/pump-D0K_0uiC.js.map +0 -1
package/dist/pump-D0K_0uiC.js
DELETED
|
@@ -1,1531 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import { t as GABOX_V2_PROGRAM_ADDRESS } from "./gaboxV2-CV2XltqC.js";
|
|
3
|
-
import { AccountRole, addEncoderSizePrefix, address, getAddressEncoder, getBase64Encoder, getBooleanEncoder, getStructEncoder, getU32Encoder, getU64Decoder, getU64Encoder, getUtf8Encoder } from "@solana/kit";
|
|
4
|
-
import { GLOBAL_PDA, GLOBAL_VOLUME_ACCUMULATOR_PDA, PUMP_EVENT_AUTHORITY_PDA, PUMP_FEE_CONFIG_PDA, PUMP_SDK, bondingCurvePda, creatorVaultPda, feeSharingConfigPda, getBuySolAmountFromTokenAmount, getGlobalParamsPda, getMayhemStatePda, getSellSolAmountFromTokenAmount, getSolVaultPda, getTokenVaultPda, userVolumeAccumulatorPda } from "@pump-fun/pump-sdk";
|
|
5
|
-
import { GLOBAL_CONFIG_PDA, GLOBAL_VOLUME_ACCUMULATOR_PDA as GLOBAL_VOLUME_ACCUMULATOR_PDA$1, PUMP_AMM_EVENT_AUTHORITY_PDA, PUMP_AMM_FEE_CONFIG_PDA, PUMP_AMM_SDK, buyBaseInput, canonicalPumpPoolPda, coinCreatorVaultAtaPda, coinCreatorVaultAuthorityPda, sellBaseInput, userVolumeAccumulatorPda as userVolumeAccumulatorPda$1 } from "@pump-fun/pump-swap-sdk";
|
|
6
|
-
import { getAssociatedTokenAddressSync, unpackMint } from "@solana/spl-token";
|
|
7
|
-
import { PublicKey } from "@solana/web3.js";
|
|
8
|
-
import BN from "bn.js";
|
|
9
|
-
import { Buffer } from "buffer";
|
|
10
|
-
//#region src/pump/abi.ts
|
|
11
|
-
/**
|
|
12
|
-
* Program addresses, taken from the two IDLs rather than typed here. `fee_program` and
|
|
13
|
-
* `mayhem_program_id` are `address` constraints on accounts, so the IDL states them exactly.
|
|
14
|
-
*/
|
|
15
|
-
const PUMP_PROGRAM_ADDRESS = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
|
|
16
|
-
const PUMP_SWAP_PROGRAM_ADDRESS = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
|
|
17
|
-
const PUMP_FEE_PROGRAM_ADDRESS = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
|
|
18
|
-
const MAYHEM_PROGRAM_ADDRESS = "MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e";
|
|
19
|
-
/** Pump `create_v2` always mints Token-2022. The IDL pins the program on the account. */
|
|
20
|
-
const PUMP_CREATE_TOKEN_PROGRAM_ADDRESS = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
21
|
-
const ASSOCIATED_TOKEN_PROGRAM_ADDRESS = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
22
|
-
const SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
23
|
-
/** `create_v2` on `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` — not in interfaces.json (create only, the program reads two slots of it). */
|
|
24
|
-
const PUMP_CREATE_V2 = {
|
|
25
|
-
name: "create_v2",
|
|
26
|
-
discriminator: new Uint8Array([
|
|
27
|
-
214,
|
|
28
|
-
144,
|
|
29
|
-
76,
|
|
30
|
-
236,
|
|
31
|
-
95,
|
|
32
|
-
139,
|
|
33
|
-
49,
|
|
34
|
-
180
|
|
35
|
-
]),
|
|
36
|
-
accounts: [
|
|
37
|
-
{
|
|
38
|
-
name: "mint",
|
|
39
|
-
writable: true,
|
|
40
|
-
signer: true
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "mint_authority",
|
|
44
|
-
writable: false,
|
|
45
|
-
signer: false
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: "bonding_curve",
|
|
49
|
-
writable: true,
|
|
50
|
-
signer: false
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: "associated_bonding_curve",
|
|
54
|
-
writable: true,
|
|
55
|
-
signer: false
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: "global",
|
|
59
|
-
writable: false,
|
|
60
|
-
signer: false
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: "user",
|
|
64
|
-
writable: true,
|
|
65
|
-
signer: true
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: "system_program",
|
|
69
|
-
writable: false,
|
|
70
|
-
signer: false
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: "token_program",
|
|
74
|
-
writable: false,
|
|
75
|
-
signer: false
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: "associated_token_program",
|
|
79
|
-
writable: false,
|
|
80
|
-
signer: false
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
name: "mayhem_program_id",
|
|
84
|
-
writable: true,
|
|
85
|
-
signer: false
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "global_params",
|
|
89
|
-
writable: false,
|
|
90
|
-
signer: false
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
name: "sol_vault",
|
|
94
|
-
writable: true,
|
|
95
|
-
signer: false
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
name: "mayhem_state",
|
|
99
|
-
writable: true,
|
|
100
|
-
signer: false
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: "mayhem_token_vault",
|
|
104
|
-
writable: true,
|
|
105
|
-
signer: false
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
name: "event_authority",
|
|
109
|
-
writable: false,
|
|
110
|
-
signer: false
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: "program",
|
|
114
|
-
writable: false,
|
|
115
|
-
signer: false
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
};
|
|
119
|
-
/** `buy_v2` on `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` — cross-checked against interfaces.json. */
|
|
120
|
-
const PUMP_BUY = {
|
|
121
|
-
name: "buy_v2",
|
|
122
|
-
discriminator: new Uint8Array([
|
|
123
|
-
184,
|
|
124
|
-
23,
|
|
125
|
-
238,
|
|
126
|
-
97,
|
|
127
|
-
103,
|
|
128
|
-
197,
|
|
129
|
-
211,
|
|
130
|
-
61
|
|
131
|
-
]),
|
|
132
|
-
accounts: [
|
|
133
|
-
{
|
|
134
|
-
name: "global",
|
|
135
|
-
writable: false,
|
|
136
|
-
signer: false
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: "base_mint",
|
|
140
|
-
writable: false,
|
|
141
|
-
signer: false
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: "quote_mint",
|
|
145
|
-
writable: false,
|
|
146
|
-
signer: false
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
name: "base_token_program",
|
|
150
|
-
writable: false,
|
|
151
|
-
signer: false
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
name: "quote_token_program",
|
|
155
|
-
writable: false,
|
|
156
|
-
signer: false
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
name: "associated_token_program",
|
|
160
|
-
writable: false,
|
|
161
|
-
signer: false
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
name: "fee_recipient",
|
|
165
|
-
writable: true,
|
|
166
|
-
signer: false
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
name: "associated_quote_fee_recipient",
|
|
170
|
-
writable: true,
|
|
171
|
-
signer: false
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
name: "buyback_fee_recipient",
|
|
175
|
-
writable: true,
|
|
176
|
-
signer: false
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
name: "associated_quote_buyback_fee_recipient",
|
|
180
|
-
writable: true,
|
|
181
|
-
signer: false
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
name: "bonding_curve",
|
|
185
|
-
writable: true,
|
|
186
|
-
signer: false
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
name: "associated_base_bonding_curve",
|
|
190
|
-
writable: true,
|
|
191
|
-
signer: false
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
name: "associated_quote_bonding_curve",
|
|
195
|
-
writable: true,
|
|
196
|
-
signer: false
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: "user",
|
|
200
|
-
writable: true,
|
|
201
|
-
signer: true
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: "associated_base_user",
|
|
205
|
-
writable: true,
|
|
206
|
-
signer: false
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
name: "associated_quote_user",
|
|
210
|
-
writable: true,
|
|
211
|
-
signer: false
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
name: "creator_vault",
|
|
215
|
-
writable: true,
|
|
216
|
-
signer: false
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
name: "associated_creator_vault",
|
|
220
|
-
writable: true,
|
|
221
|
-
signer: false
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
name: "sharing_config",
|
|
225
|
-
writable: false,
|
|
226
|
-
signer: false
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
name: "global_volume_accumulator",
|
|
230
|
-
writable: false,
|
|
231
|
-
signer: false
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
name: "user_volume_accumulator",
|
|
235
|
-
writable: true,
|
|
236
|
-
signer: false
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
name: "associated_user_volume_accumulator",
|
|
240
|
-
writable: true,
|
|
241
|
-
signer: false
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
name: "fee_config",
|
|
245
|
-
writable: false,
|
|
246
|
-
signer: false
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
name: "fee_program",
|
|
250
|
-
writable: false,
|
|
251
|
-
signer: false
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
name: "system_program",
|
|
255
|
-
writable: false,
|
|
256
|
-
signer: false
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: "event_authority",
|
|
260
|
-
writable: false,
|
|
261
|
-
signer: false
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
name: "program",
|
|
265
|
-
writable: false,
|
|
266
|
-
signer: false
|
|
267
|
-
}
|
|
268
|
-
]
|
|
269
|
-
};
|
|
270
|
-
/** `sell_v2` on `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P` — cross-checked against interfaces.json. */
|
|
271
|
-
const PUMP_SELL = {
|
|
272
|
-
name: "sell_v2",
|
|
273
|
-
discriminator: new Uint8Array([
|
|
274
|
-
93,
|
|
275
|
-
246,
|
|
276
|
-
130,
|
|
277
|
-
60,
|
|
278
|
-
231,
|
|
279
|
-
233,
|
|
280
|
-
64,
|
|
281
|
-
178
|
|
282
|
-
]),
|
|
283
|
-
accounts: [
|
|
284
|
-
{
|
|
285
|
-
name: "global",
|
|
286
|
-
writable: false,
|
|
287
|
-
signer: false
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
name: "base_mint",
|
|
291
|
-
writable: false,
|
|
292
|
-
signer: false
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
name: "quote_mint",
|
|
296
|
-
writable: false,
|
|
297
|
-
signer: false
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
name: "base_token_program",
|
|
301
|
-
writable: false,
|
|
302
|
-
signer: false
|
|
303
|
-
},
|
|
304
|
-
{
|
|
305
|
-
name: "quote_token_program",
|
|
306
|
-
writable: false,
|
|
307
|
-
signer: false
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
name: "associated_token_program",
|
|
311
|
-
writable: false,
|
|
312
|
-
signer: false
|
|
313
|
-
},
|
|
314
|
-
{
|
|
315
|
-
name: "fee_recipient",
|
|
316
|
-
writable: true,
|
|
317
|
-
signer: false
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
name: "associated_quote_fee_recipient",
|
|
321
|
-
writable: true,
|
|
322
|
-
signer: false
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
name: "buyback_fee_recipient",
|
|
326
|
-
writable: true,
|
|
327
|
-
signer: false
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
name: "associated_quote_buyback_fee_recipient",
|
|
331
|
-
writable: true,
|
|
332
|
-
signer: false
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
name: "bonding_curve",
|
|
336
|
-
writable: true,
|
|
337
|
-
signer: false
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
name: "associated_base_bonding_curve",
|
|
341
|
-
writable: true,
|
|
342
|
-
signer: false
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
name: "associated_quote_bonding_curve",
|
|
346
|
-
writable: true,
|
|
347
|
-
signer: false
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
name: "user",
|
|
351
|
-
writable: true,
|
|
352
|
-
signer: true
|
|
353
|
-
},
|
|
354
|
-
{
|
|
355
|
-
name: "associated_base_user",
|
|
356
|
-
writable: true,
|
|
357
|
-
signer: false
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
name: "associated_quote_user",
|
|
361
|
-
writable: true,
|
|
362
|
-
signer: false
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
name: "creator_vault",
|
|
366
|
-
writable: true,
|
|
367
|
-
signer: false
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
name: "associated_creator_vault",
|
|
371
|
-
writable: true,
|
|
372
|
-
signer: false
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
name: "sharing_config",
|
|
376
|
-
writable: false,
|
|
377
|
-
signer: false
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
name: "user_volume_accumulator",
|
|
381
|
-
writable: true,
|
|
382
|
-
signer: false
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
name: "associated_user_volume_accumulator",
|
|
386
|
-
writable: true,
|
|
387
|
-
signer: false
|
|
388
|
-
},
|
|
389
|
-
{
|
|
390
|
-
name: "fee_config",
|
|
391
|
-
writable: false,
|
|
392
|
-
signer: false
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
name: "fee_program",
|
|
396
|
-
writable: false,
|
|
397
|
-
signer: false
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
name: "system_program",
|
|
401
|
-
writable: false,
|
|
402
|
-
signer: false
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
name: "event_authority",
|
|
406
|
-
writable: false,
|
|
407
|
-
signer: false
|
|
408
|
-
},
|
|
409
|
-
{
|
|
410
|
-
name: "program",
|
|
411
|
-
writable: false,
|
|
412
|
-
signer: false
|
|
413
|
-
}
|
|
414
|
-
]
|
|
415
|
-
};
|
|
416
|
-
/** `buy` on `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` — cross-checked against interfaces.json. */
|
|
417
|
-
const SWAP_BUY = {
|
|
418
|
-
name: "buy",
|
|
419
|
-
discriminator: new Uint8Array([
|
|
420
|
-
102,
|
|
421
|
-
6,
|
|
422
|
-
61,
|
|
423
|
-
18,
|
|
424
|
-
1,
|
|
425
|
-
218,
|
|
426
|
-
235,
|
|
427
|
-
234
|
|
428
|
-
]),
|
|
429
|
-
accounts: [
|
|
430
|
-
{
|
|
431
|
-
name: "pool",
|
|
432
|
-
writable: true,
|
|
433
|
-
signer: false
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
name: "user",
|
|
437
|
-
writable: true,
|
|
438
|
-
signer: true
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
name: "global_config",
|
|
442
|
-
writable: false,
|
|
443
|
-
signer: false
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
name: "base_mint",
|
|
447
|
-
writable: false,
|
|
448
|
-
signer: false
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
name: "quote_mint",
|
|
452
|
-
writable: false,
|
|
453
|
-
signer: false
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
name: "user_base_token_account",
|
|
457
|
-
writable: true,
|
|
458
|
-
signer: false
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
name: "user_quote_token_account",
|
|
462
|
-
writable: true,
|
|
463
|
-
signer: false
|
|
464
|
-
},
|
|
465
|
-
{
|
|
466
|
-
name: "pool_base_token_account",
|
|
467
|
-
writable: true,
|
|
468
|
-
signer: false
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
name: "pool_quote_token_account",
|
|
472
|
-
writable: true,
|
|
473
|
-
signer: false
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
name: "protocol_fee_recipient",
|
|
477
|
-
writable: false,
|
|
478
|
-
signer: false
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
name: "protocol_fee_recipient_token_account",
|
|
482
|
-
writable: true,
|
|
483
|
-
signer: false
|
|
484
|
-
},
|
|
485
|
-
{
|
|
486
|
-
name: "base_token_program",
|
|
487
|
-
writable: false,
|
|
488
|
-
signer: false
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
name: "quote_token_program",
|
|
492
|
-
writable: false,
|
|
493
|
-
signer: false
|
|
494
|
-
},
|
|
495
|
-
{
|
|
496
|
-
name: "system_program",
|
|
497
|
-
writable: false,
|
|
498
|
-
signer: false
|
|
499
|
-
},
|
|
500
|
-
{
|
|
501
|
-
name: "associated_token_program",
|
|
502
|
-
writable: false,
|
|
503
|
-
signer: false
|
|
504
|
-
},
|
|
505
|
-
{
|
|
506
|
-
name: "event_authority",
|
|
507
|
-
writable: false,
|
|
508
|
-
signer: false
|
|
509
|
-
},
|
|
510
|
-
{
|
|
511
|
-
name: "program",
|
|
512
|
-
writable: false,
|
|
513
|
-
signer: false
|
|
514
|
-
},
|
|
515
|
-
{
|
|
516
|
-
name: "coin_creator_vault_ata",
|
|
517
|
-
writable: true,
|
|
518
|
-
signer: false
|
|
519
|
-
},
|
|
520
|
-
{
|
|
521
|
-
name: "coin_creator_vault_authority",
|
|
522
|
-
writable: false,
|
|
523
|
-
signer: false
|
|
524
|
-
},
|
|
525
|
-
{
|
|
526
|
-
name: "global_volume_accumulator",
|
|
527
|
-
writable: false,
|
|
528
|
-
signer: false
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
name: "user_volume_accumulator",
|
|
532
|
-
writable: true,
|
|
533
|
-
signer: false
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
name: "fee_config",
|
|
537
|
-
writable: false,
|
|
538
|
-
signer: false
|
|
539
|
-
},
|
|
540
|
-
{
|
|
541
|
-
name: "fee_program",
|
|
542
|
-
writable: false,
|
|
543
|
-
signer: false
|
|
544
|
-
}
|
|
545
|
-
]
|
|
546
|
-
};
|
|
547
|
-
/** `sell` on `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` — cross-checked against interfaces.json. */
|
|
548
|
-
const SWAP_SELL = {
|
|
549
|
-
name: "sell",
|
|
550
|
-
discriminator: new Uint8Array([
|
|
551
|
-
51,
|
|
552
|
-
230,
|
|
553
|
-
133,
|
|
554
|
-
164,
|
|
555
|
-
1,
|
|
556
|
-
127,
|
|
557
|
-
131,
|
|
558
|
-
173
|
|
559
|
-
]),
|
|
560
|
-
accounts: [
|
|
561
|
-
{
|
|
562
|
-
name: "pool",
|
|
563
|
-
writable: true,
|
|
564
|
-
signer: false
|
|
565
|
-
},
|
|
566
|
-
{
|
|
567
|
-
name: "user",
|
|
568
|
-
writable: true,
|
|
569
|
-
signer: true
|
|
570
|
-
},
|
|
571
|
-
{
|
|
572
|
-
name: "global_config",
|
|
573
|
-
writable: false,
|
|
574
|
-
signer: false
|
|
575
|
-
},
|
|
576
|
-
{
|
|
577
|
-
name: "base_mint",
|
|
578
|
-
writable: false,
|
|
579
|
-
signer: false
|
|
580
|
-
},
|
|
581
|
-
{
|
|
582
|
-
name: "quote_mint",
|
|
583
|
-
writable: false,
|
|
584
|
-
signer: false
|
|
585
|
-
},
|
|
586
|
-
{
|
|
587
|
-
name: "user_base_token_account",
|
|
588
|
-
writable: true,
|
|
589
|
-
signer: false
|
|
590
|
-
},
|
|
591
|
-
{
|
|
592
|
-
name: "user_quote_token_account",
|
|
593
|
-
writable: true,
|
|
594
|
-
signer: false
|
|
595
|
-
},
|
|
596
|
-
{
|
|
597
|
-
name: "pool_base_token_account",
|
|
598
|
-
writable: true,
|
|
599
|
-
signer: false
|
|
600
|
-
},
|
|
601
|
-
{
|
|
602
|
-
name: "pool_quote_token_account",
|
|
603
|
-
writable: true,
|
|
604
|
-
signer: false
|
|
605
|
-
},
|
|
606
|
-
{
|
|
607
|
-
name: "protocol_fee_recipient",
|
|
608
|
-
writable: false,
|
|
609
|
-
signer: false
|
|
610
|
-
},
|
|
611
|
-
{
|
|
612
|
-
name: "protocol_fee_recipient_token_account",
|
|
613
|
-
writable: true,
|
|
614
|
-
signer: false
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
name: "base_token_program",
|
|
618
|
-
writable: false,
|
|
619
|
-
signer: false
|
|
620
|
-
},
|
|
621
|
-
{
|
|
622
|
-
name: "quote_token_program",
|
|
623
|
-
writable: false,
|
|
624
|
-
signer: false
|
|
625
|
-
},
|
|
626
|
-
{
|
|
627
|
-
name: "system_program",
|
|
628
|
-
writable: false,
|
|
629
|
-
signer: false
|
|
630
|
-
},
|
|
631
|
-
{
|
|
632
|
-
name: "associated_token_program",
|
|
633
|
-
writable: false,
|
|
634
|
-
signer: false
|
|
635
|
-
},
|
|
636
|
-
{
|
|
637
|
-
name: "event_authority",
|
|
638
|
-
writable: false,
|
|
639
|
-
signer: false
|
|
640
|
-
},
|
|
641
|
-
{
|
|
642
|
-
name: "program",
|
|
643
|
-
writable: false,
|
|
644
|
-
signer: false
|
|
645
|
-
},
|
|
646
|
-
{
|
|
647
|
-
name: "coin_creator_vault_ata",
|
|
648
|
-
writable: true,
|
|
649
|
-
signer: false
|
|
650
|
-
},
|
|
651
|
-
{
|
|
652
|
-
name: "coin_creator_vault_authority",
|
|
653
|
-
writable: false,
|
|
654
|
-
signer: false
|
|
655
|
-
},
|
|
656
|
-
{
|
|
657
|
-
name: "fee_config",
|
|
658
|
-
writable: false,
|
|
659
|
-
signer: false
|
|
660
|
-
},
|
|
661
|
-
{
|
|
662
|
-
name: "fee_program",
|
|
663
|
-
writable: false,
|
|
664
|
-
signer: false
|
|
665
|
-
}
|
|
666
|
-
]
|
|
667
|
-
};
|
|
668
|
-
//#endregion
|
|
669
|
-
//#region src/ids.ts
|
|
670
|
-
/** `declare_id!` in `programs/gabox-v2/src/lib.rs`. */
|
|
671
|
-
const GABOX_PROGRAM_ID = GABOX_V2_PROGRAM_ADDRESS;
|
|
672
|
-
/** Classic SPL Token. The quote side of every Pump trade uses it, because the quote is WSOL. */
|
|
673
|
-
const TOKEN_PROGRAM_ADDRESS = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
674
|
-
/**
|
|
675
|
-
* Token-2022. Pump `create_v2` mints here, so every coin a machine is built on is a Token-2022
|
|
676
|
-
* mint and the pool vault ATA lives under this program.
|
|
677
|
-
*/
|
|
678
|
-
const TOKEN_2022_PROGRAM_ADDRESS = PUMP_CREATE_TOKEN_PROGRAM_ADDRESS;
|
|
679
|
-
/** Wrapped SOL. The quote mint on both venues. */
|
|
680
|
-
const WSOL_MINT = "So11111111111111111111111111111111111111112";
|
|
681
|
-
/** MagicBlock's ephemeral VRF program. `vrf.rs` pins it and refuses any other. */
|
|
682
|
-
const VRF_PROGRAM_ADDRESS = "Vrf1RNUjXmQGjmQrQLvJHs9SNkvDJEsRVFPkfSQUwGz";
|
|
683
|
-
/**
|
|
684
|
-
* MagicBlock's default oracle queue. The program pins this one address, so a pool creator cannot
|
|
685
|
-
* point a draw at an oracle they control.
|
|
686
|
-
*/
|
|
687
|
-
const VRF_DEFAULT_QUEUE = "Cuj97ggrhhidhbu39TijNVqE74xvKJ69gDervRUXAxGh";
|
|
688
|
-
/** The seed of both identity PDAs. See `pdas.ts` — there are two, under different programs. */
|
|
689
|
-
const IDENTITY_SEED = new Uint8Array([
|
|
690
|
-
105,
|
|
691
|
-
100,
|
|
692
|
-
101,
|
|
693
|
-
110,
|
|
694
|
-
116,
|
|
695
|
-
105,
|
|
696
|
-
116,
|
|
697
|
-
121
|
|
698
|
-
]);
|
|
699
|
-
const SLOT_HASHES_SYSVAR = "SysvarS1otHashes111111111111111111111111111";
|
|
700
|
-
const INSTRUCTIONS_SYSVAR = "Sysvar1nstructions1111111111111111111111111";
|
|
701
|
-
/** `state.rs`. A retry may not run sooner than this after the last attempt. */
|
|
702
|
-
const RETRY_SLOTS = 300n;
|
|
703
|
-
/** `state.rs`. After this many slots from the purchase, anyone may expire the draw. */
|
|
704
|
-
const TIMEOUT_SLOTS = 216000n;
|
|
705
|
-
/** `state.rs`. Three requests in total, counting the one `buy_pack` makes. */
|
|
706
|
-
const MAX_ATTEMPTS = 3;
|
|
707
|
-
/**
|
|
708
|
-
* `state.rs`. Tokens in one pack, in base units: 1,000,000 tokens at Pump's fixed 6 decimals, or
|
|
709
|
-
* 0.1% of the 1,000,000,000 supply. Every pool sells packs of this size. The venue decides what a
|
|
710
|
-
* pack costs, so the pack price follows the coin. Read `pool.packTokens` rather than this when a
|
|
711
|
-
* pool is at hand: a later program version may change the constant.
|
|
712
|
-
*/
|
|
713
|
-
const PACK_TOKENS = 1000000n * 1000000n;
|
|
714
|
-
/** `state.rs`. The creator's per-pack fee, in bps of what the venue charged, may not exceed this. */
|
|
715
|
-
const MAX_FEE_BPS = 100;
|
|
716
|
-
/** Referral reward: 1% of the creator fee, deducted from that fee. */
|
|
717
|
-
const REFERRAL_FEE_BPS = 100n;
|
|
718
|
-
/** `state.rs`. The protocol's share of every pack's venue cost and of every sale's proceeds, in bps. */
|
|
719
|
-
const PROTOCOL_FEE_BPS = 100n;
|
|
720
|
-
/**
|
|
721
|
-
* `PROTOCOL_FEE_COLLECTOR` in `state.rs`. Every pack pays 1% of its venue cost here, on top of
|
|
722
|
-
* that cost. Every sale through the program pays 1% of its proceeds here: SOL on Pump, WSOL (into the
|
|
723
|
-
* collector's WSOL ATA) on PumpSwap. The same key holds the program's upgrade authority.
|
|
724
|
-
*
|
|
725
|
-
* The generated instructions pin it as an `address` constraint, and `test/instruction-data.test.ts`
|
|
726
|
-
* checks this copy against the IDL.
|
|
727
|
-
*/
|
|
728
|
-
const PROTOCOL_FEE_COLLECTOR = "5WcPTEQ59UqpQzjZUPbU8QRGCbj7NeQNLDa7DbsLkLKT";
|
|
729
|
-
//#endregion
|
|
730
|
-
//#region src/pump/adapter.ts
|
|
731
|
-
/**
|
|
732
|
-
* The boundary with Pump's official SDKs.
|
|
733
|
-
*
|
|
734
|
-
* # Why this file exists, and why it is the only one like it
|
|
735
|
-
*
|
|
736
|
-
* `@pump-fun/pump-sdk` and `@pump-fun/pump-swap-sdk` are the maintained clients Pump publishes.
|
|
737
|
-
* They carry two things worth having and expensive to reproduce: the exact seeds of every PDA a
|
|
738
|
-
* trade touches, and the fee-tier and curve math that says how many tokens a given spend buys.
|
|
739
|
-
* Getting either one slightly wrong shows a buyer a price the venue will not honour.
|
|
740
|
-
*
|
|
741
|
-
* Both packages are built on `@solana/web3.js` v1 and `bn.js`. This SDK and the app are on
|
|
742
|
-
* `@solana/kit`. So the conversion happens here and nowhere else: `PublicKey` and `BN` do not
|
|
743
|
-
* appear in any other file, and nothing this module exports carries them. Addresses go out as kit
|
|
744
|
-
* `Address`, amounts as `bigint`.
|
|
745
|
-
*
|
|
746
|
-
* Pinned versions are in `sdk/package.json` and repeated in `sdk/README.md`. They are exact, not
|
|
747
|
-
* ranges: a fee-math change in a patch release changes what a buyer is shown.
|
|
748
|
-
*
|
|
749
|
-
* # What this file does NOT do
|
|
750
|
-
*
|
|
751
|
-
* It does not build instructions. Both packages build their trades around `@solana/web3.js`
|
|
752
|
-
* transactions, and `market.rs` takes the venue's account list as `remaining_accounts` instead.
|
|
753
|
-
* So `accounts.ts` assembles the account lists from the generated `abi.ts` table, using the
|
|
754
|
-
* addresses this file derives.
|
|
755
|
-
*/
|
|
756
|
-
const toAddress = (key) => address(key.toBase58());
|
|
757
|
-
const toPublicKey = (a) => new PublicKey(a);
|
|
758
|
-
const brand = (value) => value;
|
|
759
|
-
const unbrand = (value) => value;
|
|
760
|
-
const toBigint = (n) => BigInt(n.toString());
|
|
761
|
-
const toBn = (n) => new BN(n.toString());
|
|
762
|
-
/**
|
|
763
|
-
* An `AccountInfo<Buffer>` shaped just enough for the packages' decoders. They read `.data` and
|
|
764
|
-
* nothing else, so the rest is filler rather than a claim about the account.
|
|
765
|
-
*/
|
|
766
|
-
function accountInfo(data, owner = PublicKey.default) {
|
|
767
|
-
return {
|
|
768
|
-
data: Buffer.from(data),
|
|
769
|
-
executable: false,
|
|
770
|
-
lamports: 0,
|
|
771
|
-
owner
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
/** `["global"]` under Pump. Holds the fee recipient lists and the curve's initial reserves. */
|
|
775
|
-
const PUMP_GLOBAL = toAddress(GLOBAL_PDA);
|
|
776
|
-
const PUMP_EVENT_AUTHORITY = toAddress(PUMP_EVENT_AUTHORITY_PDA);
|
|
777
|
-
/** `["fee_config", pump_program_id]` under the Pump fee program. */
|
|
778
|
-
const PUMP_FEE_CONFIG = toAddress(PUMP_FEE_CONFIG_PDA);
|
|
779
|
-
const PUMP_GLOBAL_VOLUME_ACCUMULATOR = toAddress(GLOBAL_VOLUME_ACCUMULATOR_PDA);
|
|
780
|
-
/**
|
|
781
|
-
* Mayhem mode is off for every gabox coin, but `create_v2` still takes all four accounts.
|
|
782
|
-
*
|
|
783
|
-
* The four mayhem accounts are derived under the **mayhem** program
|
|
784
|
-
* (`MAyhSmzXzV1pTf7LsNkrNwkWKTo4ougAJ1PPg47MD4e`), not under Pump. Pump's IDL states the seeds but
|
|
785
|
-
* omits the program on `global_params`, `sol_vault` and `mayhem_state`, so read literally it would
|
|
786
|
-
* put all three under Pump and every `create_v2` would fail. `@pump-fun/pump-sdk`'s own
|
|
787
|
-
* `createV2Instruction` derives them under the mayhem program, and that is what these follow.
|
|
788
|
-
* Confirmed by a successful seeded machine creation on devnet on 2026-09-10.
|
|
789
|
-
*/
|
|
790
|
-
const MAYHEM_GLOBAL_PARAMS = toAddress(getGlobalParamsPda());
|
|
791
|
-
const MAYHEM_SOL_VAULT = toAddress(getSolVaultPda());
|
|
792
|
-
const pumpBondingCurve = (mint) => toAddress(bondingCurvePda(toPublicKey(mint)));
|
|
793
|
-
const pumpCreatorVault = (creator) => toAddress(creatorVaultPda(toPublicKey(creator)));
|
|
794
|
-
const pumpSharingConfig = (mint) => toAddress(feeSharingConfigPda(toPublicKey(mint)));
|
|
795
|
-
const pumpUserVolumeAccumulator = (user) => toAddress(userVolumeAccumulatorPda(toPublicKey(user)));
|
|
796
|
-
const pumpMayhemState = (mint) => toAddress(getMayhemStatePda(toPublicKey(mint)));
|
|
797
|
-
const pumpMayhemTokenVault = (mint) => toAddress(getTokenVaultPda(toPublicKey(mint)));
|
|
798
|
-
/**
|
|
799
|
-
* `["mint-authority"]` under Pump.
|
|
800
|
-
*
|
|
801
|
-
* The one address here that comes from the IDL rather than the package: `pda.ts` has no helper for
|
|
802
|
-
* it. The seed is in `create_v2`'s own `pda` metadata, so it is not a guess.
|
|
803
|
-
*/
|
|
804
|
-
const PUMP_MINT_AUTHORITY = toAddress(PublicKey.findProgramAddressSync([Buffer.from("mint-authority")], new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"))[0]);
|
|
805
|
-
const AMM_GLOBAL_CONFIG = toAddress(GLOBAL_CONFIG_PDA);
|
|
806
|
-
const AMM_EVENT_AUTHORITY = toAddress(PUMP_AMM_EVENT_AUTHORITY_PDA);
|
|
807
|
-
const AMM_FEE_CONFIG = toAddress(PUMP_AMM_FEE_CONFIG_PDA);
|
|
808
|
-
const AMM_GLOBAL_VOLUME_ACCUMULATOR = toAddress(GLOBAL_VOLUME_ACCUMULATOR_PDA$1);
|
|
809
|
-
/**
|
|
810
|
-
* The canonical PumpSwap pool for a graduated Pump coin: index 0, owned by the coin's
|
|
811
|
-
* `["pool-authority", mint]` PDA, quoted in WSOL. A coin can have other pools; the program lets the
|
|
812
|
-
* user sign whichever pool they pass, and a client should pick this one.
|
|
813
|
-
*/
|
|
814
|
-
const ammCanonicalPool = (mint) => toAddress(canonicalPumpPoolPda(toPublicKey(mint)));
|
|
815
|
-
const ammUserVolumeAccumulator = (user) => toAddress(userVolumeAccumulatorPda$1(toPublicKey(user)));
|
|
816
|
-
const ammCoinCreatorVaultAuthority = (coinCreator) => toAddress(coinCreatorVaultAuthorityPda(toPublicKey(coinCreator)));
|
|
817
|
-
const ammCoinCreatorVaultAta = (vaultAuthority, quoteMint, quoteTokenProgram) => toAddress(coinCreatorVaultAtaPda(toPublicKey(vaultAuthority), toPublicKey(quoteMint), toPublicKey(quoteTokenProgram)));
|
|
818
|
-
/** An ATA, off-curve owners allowed. Pool PDAs and vault authorities are all off-curve. */
|
|
819
|
-
const ata = (owner, mint, tokenProgram) => toAddress(getAssociatedTokenAddressSync(toPublicKey(mint), toPublicKey(owner), true, toPublicKey(tokenProgram)));
|
|
820
|
-
function decodePumpGlobal(data) {
|
|
821
|
-
const g = PUMP_SDK.decodeGlobal(accountInfo(data));
|
|
822
|
-
return {
|
|
823
|
-
feeRecipient: toAddress(g.feeRecipient),
|
|
824
|
-
feeRecipients: g.feeRecipients.map(toAddress),
|
|
825
|
-
buybackFeeRecipients: (g.buybackFeeRecipients ?? []).map(toAddress),
|
|
826
|
-
reservedFeeRecipient: toAddress(g.reservedFeeRecipient),
|
|
827
|
-
reservedFeeRecipients: (g.reservedFeeRecipients ?? []).map(toAddress),
|
|
828
|
-
createV2Enabled: g.createV2Enabled,
|
|
829
|
-
mayhemModeEnabled: g.mayhemModeEnabled,
|
|
830
|
-
isCashbackEnabled: g.isCashbackEnabled,
|
|
831
|
-
feeBasisPoints: toBigint(g.feeBasisPoints),
|
|
832
|
-
creatorFeeBasisPoints: toBigint(g.creatorFeeBasisPoints),
|
|
833
|
-
tokenTotalSupply: toBigint(g.tokenTotalSupply),
|
|
834
|
-
initialVirtualTokenReserves: toBigint(g.initialVirtualTokenReserves),
|
|
835
|
-
initialVirtualSolReserves: toBigint(g.initialVirtualSolReserves),
|
|
836
|
-
initialRealTokenReserves: toBigint(g.initialRealTokenReserves),
|
|
837
|
-
raw: brand(g)
|
|
838
|
-
};
|
|
839
|
-
}
|
|
840
|
-
function decodeBondingCurve(data) {
|
|
841
|
-
const c = PUMP_SDK.decodeBondingCurve(accountInfo(data));
|
|
842
|
-
return {
|
|
843
|
-
virtualTokenReserves: toBigint(c.virtualTokenReserves),
|
|
844
|
-
virtualQuoteReserves: toBigint(c.virtualQuoteReserves),
|
|
845
|
-
realTokenReserves: toBigint(c.realTokenReserves),
|
|
846
|
-
realQuoteReserves: toBigint(c.realQuoteReserves),
|
|
847
|
-
tokenTotalSupply: toBigint(c.tokenTotalSupply),
|
|
848
|
-
complete: c.complete,
|
|
849
|
-
creator: toAddress(c.creator),
|
|
850
|
-
isMayhemMode: c.isMayhemMode,
|
|
851
|
-
isCashbackCoin: c.isCashbackCoin,
|
|
852
|
-
quoteMint: toAddress(c.quoteMint),
|
|
853
|
-
raw: brand(c)
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
function decodePumpFeeConfig(data) {
|
|
857
|
-
return brand(PUMP_SDK.decodeFeeConfig(accountInfo(data)));
|
|
858
|
-
}
|
|
859
|
-
function decodeAmmPool(data) {
|
|
860
|
-
const p = PUMP_AMM_SDK.decodePool(accountInfo(data));
|
|
861
|
-
return {
|
|
862
|
-
index: p.index,
|
|
863
|
-
creator: toAddress(p.creator),
|
|
864
|
-
baseMint: toAddress(p.baseMint),
|
|
865
|
-
quoteMint: toAddress(p.quoteMint),
|
|
866
|
-
poolBaseTokenAccount: toAddress(p.poolBaseTokenAccount),
|
|
867
|
-
poolQuoteTokenAccount: toAddress(p.poolQuoteTokenAccount),
|
|
868
|
-
coinCreator: toAddress(p.coinCreator),
|
|
869
|
-
virtualQuoteReserves: toBigint(p.virtualQuoteReserves ?? new BN(0)),
|
|
870
|
-
raw: brand(p)
|
|
871
|
-
};
|
|
872
|
-
}
|
|
873
|
-
function decodeAmmGlobalConfig(data) {
|
|
874
|
-
const g = PUMP_AMM_SDK.decodeGlobalConfig(accountInfo(data));
|
|
875
|
-
return {
|
|
876
|
-
protocolFeeRecipients: g.protocolFeeRecipients.map(toAddress),
|
|
877
|
-
raw: brand(g)
|
|
878
|
-
};
|
|
879
|
-
}
|
|
880
|
-
function decodeAmmFeeConfig(data) {
|
|
881
|
-
return brand(PUMP_AMM_SDK.decodeFeeConfig(accountInfo(data)));
|
|
882
|
-
}
|
|
883
|
-
/** Total supply of an SPL or Token-2022 mint. The AMM fee tiers are a function of it. */
|
|
884
|
-
function decodeMintSupply(data, mint, owner) {
|
|
885
|
-
const program = toPublicKey(owner);
|
|
886
|
-
return unpackMint(toPublicKey(mint), accountInfo(data, program), program).supply;
|
|
887
|
-
}
|
|
888
|
-
/**
|
|
889
|
-
* Lamports an exact-tokens-out buy of `tokens` costs on the Pump curve, fees included.
|
|
890
|
-
*
|
|
891
|
-
* This is the same function the Pump front end uses. The result is the whole debit — the curve's
|
|
892
|
-
* price plus the venue's protocol and creator fees — which is what `buy_v2`'s `max_sol_cost` has
|
|
893
|
-
* to cover, and what `buy_pack`'s `max_quote_in` caps.
|
|
894
|
-
*/
|
|
895
|
-
function curveBuyCost({ global, bondingCurve, feeConfig, mintSupply, tokens, quoteMint }) {
|
|
896
|
-
return toBigint(getBuySolAmountFromTokenAmount({
|
|
897
|
-
global: unbrand(global.raw),
|
|
898
|
-
feeConfig: feeConfig === null ? null : unbrand(feeConfig),
|
|
899
|
-
mintSupply: mintSupply === null ? null : toBn(mintSupply),
|
|
900
|
-
bondingCurve: bondingCurve ? unbrand(bondingCurve.raw) : null,
|
|
901
|
-
amount: toBn(tokens),
|
|
902
|
-
quoteMint: toPublicKey(quoteMint)
|
|
903
|
-
}));
|
|
904
|
-
}
|
|
905
|
-
/** Lamports a curve sale of `tokens` returns, net of fees. */
|
|
906
|
-
function curveSellQuote({ global, bondingCurve, feeConfig, mintSupply, tokens }) {
|
|
907
|
-
return toBigint(getSellSolAmountFromTokenAmount({
|
|
908
|
-
global: unbrand(global.raw),
|
|
909
|
-
feeConfig: feeConfig === null ? null : unbrand(feeConfig),
|
|
910
|
-
mintSupply: toBn(mintSupply),
|
|
911
|
-
bondingCurve: unbrand(bondingCurve.raw),
|
|
912
|
-
amount: toBn(tokens)
|
|
913
|
-
}));
|
|
914
|
-
}
|
|
915
|
-
/** WSOL a PumpSwap exact-base-out buy of `tokens` costs, LP and protocol fees included. */
|
|
916
|
-
function ammBuyCost({ pool, globalConfig, feeConfig, baseReserve, quoteReserve, baseMintSupply, tokens }) {
|
|
917
|
-
const result = buyBaseInput({
|
|
918
|
-
base: toBn(tokens),
|
|
919
|
-
slippage: 0,
|
|
920
|
-
baseReserve: toBn(baseReserve),
|
|
921
|
-
quoteReserve: toBn(quoteReserve),
|
|
922
|
-
virtualQuoteReserves: toBn(pool.virtualQuoteReserves),
|
|
923
|
-
globalConfig: unbrand(globalConfig.raw),
|
|
924
|
-
baseMintAccount: { supply: baseMintSupply },
|
|
925
|
-
baseMint: toPublicKey(pool.baseMint),
|
|
926
|
-
coinCreator: toPublicKey(pool.coinCreator),
|
|
927
|
-
creator: toPublicKey(pool.creator),
|
|
928
|
-
feeConfig: feeConfig === null ? null : unbrand(feeConfig)
|
|
929
|
-
});
|
|
930
|
-
return toBigint(result.uiQuote);
|
|
931
|
-
}
|
|
932
|
-
/** WSOL a PumpSwap sale of `tokens` returns, net of fees. */
|
|
933
|
-
function ammSellQuote({ pool, globalConfig, feeConfig, baseReserve, quoteReserve, baseMintSupply, tokens }) {
|
|
934
|
-
const result = sellBaseInput({
|
|
935
|
-
base: toBn(tokens),
|
|
936
|
-
slippage: 0,
|
|
937
|
-
baseReserve: toBn(baseReserve),
|
|
938
|
-
quoteReserve: toBn(quoteReserve),
|
|
939
|
-
virtualQuoteReserves: toBn(pool.virtualQuoteReserves),
|
|
940
|
-
globalConfig: unbrand(globalConfig.raw),
|
|
941
|
-
baseMintAccount: { supply: baseMintSupply },
|
|
942
|
-
baseMint: toPublicKey(pool.baseMint),
|
|
943
|
-
coinCreator: toPublicKey(pool.coinCreator),
|
|
944
|
-
creator: toPublicKey(pool.creator),
|
|
945
|
-
feeConfig: feeConfig === null ? null : unbrand(feeConfig)
|
|
946
|
-
});
|
|
947
|
-
return toBigint(result.uiQuote);
|
|
948
|
-
}
|
|
949
|
-
//#endregion
|
|
950
|
-
//#region src/pump/accounts.ts
|
|
951
|
-
/**
|
|
952
|
-
* The ordered account list of every Pump and PumpSwap instruction this SDK builds.
|
|
953
|
-
*
|
|
954
|
-
* # Why these are built here and not by the official SDK
|
|
955
|
-
*
|
|
956
|
-
* `market.rs` accepts four trade instructions and no others: Pump's `buy_v2` and `sell_v2`,
|
|
957
|
-
* PumpSwap's `buy` and `sell`. The official packages build these around `@solana/web3.js`
|
|
958
|
-
* transactions, and the program wants a bare account list as `remainingAccounts`. So the lists are
|
|
959
|
-
* assembled here, from `abi.ts`, which `scripts/codegen.mjs` generated from the same IDLs the
|
|
960
|
-
* program's `market_abi.rs` came from.
|
|
961
|
-
*
|
|
962
|
-
* Every address still comes from `adapter.ts`, which means from the official packages. Nothing here
|
|
963
|
-
* invents a derivation.
|
|
964
|
-
*
|
|
965
|
-
* # How to read the output
|
|
966
|
-
*
|
|
967
|
-
* Each function returns `AccountMeta[]` in ABI order, with the `role` each slot's own ABI gives it.
|
|
968
|
-
* That list goes into `buy_pack` (or `initialize_pool`, or `sell_prize`) as `remainingAccounts`,
|
|
969
|
-
* unchanged. `market.rs` walks it position by position: a writable slot must be writable in the
|
|
970
|
-
* outer transaction, and the one signer slot must be the purchaser and must sign.
|
|
971
|
-
*
|
|
972
|
-
* # The three addresses that need a chain read
|
|
973
|
-
*
|
|
974
|
-
* `fee_recipient` and `buyback_fee_recipient` on Pump, and `protocol_fee_recipient` on PumpSwap.
|
|
975
|
-
* Each is one of a list held in an on-chain account, and the venue accepts any member. `state.ts`
|
|
976
|
-
* reads those accounts and passes the choice in.
|
|
977
|
-
*/
|
|
978
|
-
/**
|
|
979
|
-
* Turn `{name -> address}` into the ABI's ordered `AccountMeta[]`.
|
|
980
|
-
*
|
|
981
|
-
* The map is keyed by the IDL's own account names, so a missing entry names the slot it belongs to
|
|
982
|
-
* rather than failing as an off-by-one further down. The role comes from the ABI table alone —
|
|
983
|
-
* never from the caller — which is what keeps this list in step with `market_abi.rs`.
|
|
984
|
-
*/
|
|
985
|
-
function order(abi, byName) {
|
|
986
|
-
return abi.accounts.map((spec) => {
|
|
987
|
-
const address = byName[spec.name];
|
|
988
|
-
if (address === void 0) throw new Error(`${abi.name}: no address given for the "${spec.name}" account`);
|
|
989
|
-
return {
|
|
990
|
-
address,
|
|
991
|
-
role: spec.signer ? spec.writable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER : spec.writable ? AccountRole.WRITABLE : AccountRole.READONLY
|
|
992
|
-
};
|
|
993
|
-
});
|
|
994
|
-
}
|
|
995
|
-
/**
|
|
996
|
-
* `create_v2` on Pump. The mint is a fresh keypair and signs; the user pays.
|
|
997
|
-
*
|
|
998
|
-
* The four mayhem accounts are always present even with mayhem mode off. `create_v2` takes them
|
|
999
|
-
* unconditionally, so a client cannot skip them.
|
|
1000
|
-
*/
|
|
1001
|
-
function pumpCreateV2Accounts(input) {
|
|
1002
|
-
const { mint, user, tokenProgram } = input;
|
|
1003
|
-
return order(PUMP_CREATE_V2, {
|
|
1004
|
-
mint,
|
|
1005
|
-
mint_authority: PUMP_MINT_AUTHORITY,
|
|
1006
|
-
bonding_curve: pumpBondingCurve(mint),
|
|
1007
|
-
associated_bonding_curve: ata(pumpBondingCurve(mint), mint, tokenProgram),
|
|
1008
|
-
global: PUMP_GLOBAL,
|
|
1009
|
-
user,
|
|
1010
|
-
system_program: SYSTEM_PROGRAM_ADDRESS,
|
|
1011
|
-
token_program: tokenProgram,
|
|
1012
|
-
associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
1013
|
-
mayhem_program_id: MAYHEM_PROGRAM_ADDRESS,
|
|
1014
|
-
global_params: MAYHEM_GLOBAL_PARAMS,
|
|
1015
|
-
sol_vault: MAYHEM_SOL_VAULT,
|
|
1016
|
-
mayhem_state: pumpMayhemState(mint),
|
|
1017
|
-
mayhem_token_vault: pumpMayhemTokenVault(mint),
|
|
1018
|
-
event_authority: PUMP_EVENT_AUTHORITY,
|
|
1019
|
-
program: PUMP_PROGRAM_ADDRESS
|
|
1020
|
-
});
|
|
1021
|
-
}
|
|
1022
|
-
function pumpTradeAccounts(abi, input) {
|
|
1023
|
-
const { mint, user, tokenProgram, creator, feeRecipient, buybackFeeRecipient, quoteMint = WSOL_MINT, quoteTokenProgram = TOKEN_PROGRAM_ADDRESS } = input;
|
|
1024
|
-
const curve = pumpBondingCurve(mint);
|
|
1025
|
-
const creatorVault = pumpCreatorVault(creator);
|
|
1026
|
-
const volume = pumpUserVolumeAccumulator(user);
|
|
1027
|
-
return order(abi, {
|
|
1028
|
-
global: PUMP_GLOBAL,
|
|
1029
|
-
base_mint: mint,
|
|
1030
|
-
quote_mint: quoteMint,
|
|
1031
|
-
base_token_program: tokenProgram,
|
|
1032
|
-
quote_token_program: quoteTokenProgram,
|
|
1033
|
-
associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
1034
|
-
fee_recipient: feeRecipient,
|
|
1035
|
-
associated_quote_fee_recipient: ata(feeRecipient, quoteMint, quoteTokenProgram),
|
|
1036
|
-
buyback_fee_recipient: buybackFeeRecipient,
|
|
1037
|
-
associated_quote_buyback_fee_recipient: ata(buybackFeeRecipient, quoteMint, quoteTokenProgram),
|
|
1038
|
-
bonding_curve: curve,
|
|
1039
|
-
associated_base_bonding_curve: ata(curve, mint, tokenProgram),
|
|
1040
|
-
associated_quote_bonding_curve: ata(curve, quoteMint, quoteTokenProgram),
|
|
1041
|
-
user,
|
|
1042
|
-
associated_base_user: ata(user, mint, tokenProgram),
|
|
1043
|
-
associated_quote_user: ata(user, quoteMint, quoteTokenProgram),
|
|
1044
|
-
creator_vault: creatorVault,
|
|
1045
|
-
associated_creator_vault: ata(creatorVault, quoteMint, quoteTokenProgram),
|
|
1046
|
-
sharing_config: pumpSharingConfig(mint),
|
|
1047
|
-
global_volume_accumulator: PUMP_GLOBAL_VOLUME_ACCUMULATOR,
|
|
1048
|
-
user_volume_accumulator: volume,
|
|
1049
|
-
associated_user_volume_accumulator: ata(volume, quoteMint, quoteTokenProgram),
|
|
1050
|
-
fee_config: PUMP_FEE_CONFIG,
|
|
1051
|
-
fee_program: PUMP_FEE_PROGRAM_ADDRESS,
|
|
1052
|
-
system_program: SYSTEM_PROGRAM_ADDRESS,
|
|
1053
|
-
event_authority: PUMP_EVENT_AUTHORITY,
|
|
1054
|
-
program: PUMP_PROGRAM_ADDRESS
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
/** `buy_v2`. The first argument is tokens to receive; the second is the most SOL to pay. */
|
|
1058
|
-
const pumpBuyAccounts = (input) => pumpTradeAccounts(PUMP_BUY, input);
|
|
1059
|
-
/** `sell_v2`. One account shorter than the buy: it has no `global_volume_accumulator`. */
|
|
1060
|
-
const pumpSellAccounts = (input) => pumpTradeAccounts(PUMP_SELL, input);
|
|
1061
|
-
function swapTradeAccounts(abi, input) {
|
|
1062
|
-
const { pool, mint, user, tokenProgram, poolBaseTokenAccount, poolQuoteTokenAccount, coinCreator, protocolFeeRecipient, quoteMint = WSOL_MINT, quoteTokenProgram = TOKEN_PROGRAM_ADDRESS } = input;
|
|
1063
|
-
const vaultAuthority = ammCoinCreatorVaultAuthority(coinCreator);
|
|
1064
|
-
return order(abi, {
|
|
1065
|
-
pool,
|
|
1066
|
-
user,
|
|
1067
|
-
global_config: AMM_GLOBAL_CONFIG,
|
|
1068
|
-
base_mint: mint,
|
|
1069
|
-
quote_mint: quoteMint,
|
|
1070
|
-
user_base_token_account: ata(user, mint, tokenProgram),
|
|
1071
|
-
user_quote_token_account: ata(user, quoteMint, quoteTokenProgram),
|
|
1072
|
-
pool_base_token_account: poolBaseTokenAccount,
|
|
1073
|
-
pool_quote_token_account: poolQuoteTokenAccount,
|
|
1074
|
-
protocol_fee_recipient: protocolFeeRecipient,
|
|
1075
|
-
protocol_fee_recipient_token_account: ata(protocolFeeRecipient, quoteMint, quoteTokenProgram),
|
|
1076
|
-
base_token_program: tokenProgram,
|
|
1077
|
-
quote_token_program: quoteTokenProgram,
|
|
1078
|
-
system_program: SYSTEM_PROGRAM_ADDRESS,
|
|
1079
|
-
associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
1080
|
-
event_authority: AMM_EVENT_AUTHORITY,
|
|
1081
|
-
program: PUMP_SWAP_PROGRAM_ADDRESS,
|
|
1082
|
-
coin_creator_vault_ata: ammCoinCreatorVaultAta(vaultAuthority, quoteMint, quoteTokenProgram),
|
|
1083
|
-
coin_creator_vault_authority: vaultAuthority,
|
|
1084
|
-
global_volume_accumulator: AMM_GLOBAL_VOLUME_ACCUMULATOR,
|
|
1085
|
-
user_volume_accumulator: ammUserVolumeAccumulator(user),
|
|
1086
|
-
fee_config: AMM_FEE_CONFIG,
|
|
1087
|
-
fee_program: PUMP_FEE_PROGRAM_ADDRESS
|
|
1088
|
-
});
|
|
1089
|
-
}
|
|
1090
|
-
/** `buy` on PumpSwap. The spend is WSOL, so fund the user's WSOL ATA with `max_quote_in` first. */
|
|
1091
|
-
const swapBuyAccounts = (input) => swapTradeAccounts(SWAP_BUY, input);
|
|
1092
|
-
/** `sell` on PumpSwap. Proceeds land in the user's WSOL ATA; unwrap separately if wanted. */
|
|
1093
|
-
const swapSellAccounts = (input) => swapTradeAccounts(SWAP_SELL, input);
|
|
1094
|
-
/**
|
|
1095
|
-
* PumpSwap's optional cashback account, appended after the ABI list.
|
|
1096
|
-
*
|
|
1097
|
-
* `market.rs` allows exactly one extra account past the end of a PumpSwap list, and checks it is
|
|
1098
|
-
* this address and that it is writable. It is the WSOL ATA of the user's own volume accumulator.
|
|
1099
|
-
* Append it only when the coin is a cashback coin; otherwise leave the list at its ABI length.
|
|
1100
|
-
*/
|
|
1101
|
-
function swapCashbackAccount(user) {
|
|
1102
|
-
const volume = ammUserVolumeAccumulator(user);
|
|
1103
|
-
return {
|
|
1104
|
-
address: ata(volume, WSOL_MINT, TOKEN_PROGRAM_ADDRESS),
|
|
1105
|
-
role: AccountRole.WRITABLE
|
|
1106
|
-
};
|
|
1107
|
-
}
|
|
1108
|
-
//#endregion
|
|
1109
|
-
//#region src/pump/venue.ts
|
|
1110
|
-
/**
|
|
1111
|
-
* Reading the venue: which one a coin trades on right now, what a pack costs there, and the
|
|
1112
|
-
* account list for the trade.
|
|
1113
|
-
*
|
|
1114
|
-
* One round trip does the whole job. `resolveVenue` reads every account the answer depends on,
|
|
1115
|
-
* decodes them through `adapter.ts`, and hands back a plain object whose methods are pure. A caller
|
|
1116
|
-
* that wants to re-price a different token count calls `quoteBuy` again with no further reads.
|
|
1117
|
-
*
|
|
1118
|
-
* # Choosing the venue
|
|
1119
|
-
*
|
|
1120
|
-
* The bonding curve's `complete` flag is the whole rule. `false` means the coin is still on the
|
|
1121
|
-
* curve, so trade Pump. `true` means it graduated, so trade the canonical PumpSwap pool. A caller
|
|
1122
|
-
* can force either one; forcing PumpSwap for a coin still on the curve simply fails on chain.
|
|
1123
|
-
*
|
|
1124
|
-
* A coin can graduate between the read and the send. `buy_pack` then fails and no draw is created,
|
|
1125
|
-
* which is the intended outcome — refresh and retry.
|
|
1126
|
-
*/
|
|
1127
|
-
const base64 = getBase64Encoder();
|
|
1128
|
-
const u64$1 = getU64Decoder();
|
|
1129
|
-
async function readAccounts(rpc, addresses) {
|
|
1130
|
-
const { value } = await rpc.getMultipleAccounts(addresses, {
|
|
1131
|
-
encoding: "base64",
|
|
1132
|
-
commitment: "confirmed"
|
|
1133
|
-
}).send();
|
|
1134
|
-
return value.map((account) => {
|
|
1135
|
-
if (!account) return null;
|
|
1136
|
-
const [encoded] = account.data;
|
|
1137
|
-
return {
|
|
1138
|
-
data: new Uint8Array(base64.encode(encoded)),
|
|
1139
|
-
owner: account.owner
|
|
1140
|
-
};
|
|
1141
|
-
});
|
|
1142
|
-
}
|
|
1143
|
-
/**
|
|
1144
|
-
* The `amount` field of an SPL or Token-2022 token account: bytes 64..72, little-endian.
|
|
1145
|
-
*
|
|
1146
|
-
* Both layouts share their first 165 bytes, so one reader covers both. Token-2022 extensions live
|
|
1147
|
-
* past that and do not move this field.
|
|
1148
|
-
*/
|
|
1149
|
-
function tokenAccountAmount(data) {
|
|
1150
|
-
if (data.length < 72) throw new Error("not a token account: fewer than 72 bytes");
|
|
1151
|
-
return u64$1.decode(data, 64);
|
|
1152
|
-
}
|
|
1153
|
-
function pick(list, index, what) {
|
|
1154
|
-
if (list.length === 0) throw new Error(`the chain holds no ${what}`);
|
|
1155
|
-
const i = index ?? Math.floor(Math.random() * list.length);
|
|
1156
|
-
const chosen = list[i];
|
|
1157
|
-
if (chosen === void 0) throw new Error(`${what} index ${i} is out of range (${list.length})`);
|
|
1158
|
-
return chosen;
|
|
1159
|
-
}
|
|
1160
|
-
async function resolveVenue(client, options) {
|
|
1161
|
-
const { mint, user } = options;
|
|
1162
|
-
const curveAddress = pumpBondingCurve(mint);
|
|
1163
|
-
const poolAddress = ammCanonicalPool(mint);
|
|
1164
|
-
const [mintAccount, globalAccount, feeConfigAccount, curveAccount, poolAccount, ammConfigAccount, ammFeeAccount] = await readAccounts(client.rpc, [
|
|
1165
|
-
mint,
|
|
1166
|
-
PUMP_GLOBAL,
|
|
1167
|
-
PUMP_FEE_CONFIG,
|
|
1168
|
-
curveAddress,
|
|
1169
|
-
poolAddress,
|
|
1170
|
-
AMM_GLOBAL_CONFIG,
|
|
1171
|
-
AMM_FEE_CONFIG
|
|
1172
|
-
]);
|
|
1173
|
-
if (!mintAccount) throw new Error(`no mint account at ${mint}`);
|
|
1174
|
-
if (!globalAccount) throw new Error(`Pump's Global account is missing at ${PUMP_GLOBAL}`);
|
|
1175
|
-
const tokenProgram = mintAccount.owner;
|
|
1176
|
-
const mintSupply = decodeMintSupply(mintAccount.data, mint, tokenProgram);
|
|
1177
|
-
const global = decodePumpGlobal(globalAccount.data);
|
|
1178
|
-
const pumpFeeConfig = feeConfigAccount ? decodePumpFeeConfig(feeConfigAccount.data) : null;
|
|
1179
|
-
const curve = curveAccount ? decodeBondingCurve(curveAccount.data) : null;
|
|
1180
|
-
const kind = options.venue ?? (curve?.complete === true ? "pumpswap" : "pump");
|
|
1181
|
-
if (kind === "pump") {
|
|
1182
|
-
if (!curve) throw new Error(`no bonding curve at ${curveAddress}. The coin does not exist on Pump, or it was not created with \`create_v2\`.`);
|
|
1183
|
-
const feeRecipient = pick([global.feeRecipient, ...global.feeRecipients], options.feeRecipientIndex, "Pump fee recipient");
|
|
1184
|
-
const buybackFeeRecipient = pick(global.buybackFeeRecipients, options.buybackRecipientIndex, "Pump buyback fee recipient");
|
|
1185
|
-
const shared = {
|
|
1186
|
-
mint,
|
|
1187
|
-
user,
|
|
1188
|
-
tokenProgram,
|
|
1189
|
-
creator: curve.creator,
|
|
1190
|
-
feeRecipient,
|
|
1191
|
-
buybackFeeRecipient
|
|
1192
|
-
};
|
|
1193
|
-
return {
|
|
1194
|
-
kind,
|
|
1195
|
-
program: PUMP_PROGRAM_ADDRESS,
|
|
1196
|
-
mint,
|
|
1197
|
-
tokenProgram,
|
|
1198
|
-
complete: curve.complete,
|
|
1199
|
-
creator: curve.creator,
|
|
1200
|
-
buyAccounts: pumpBuyAccounts(shared),
|
|
1201
|
-
sellAccounts: pumpSellAccounts(shared),
|
|
1202
|
-
quoteBuy: (tokens) => curveBuyCost({
|
|
1203
|
-
global,
|
|
1204
|
-
bondingCurve: curve,
|
|
1205
|
-
feeConfig: pumpFeeConfig,
|
|
1206
|
-
mintSupply,
|
|
1207
|
-
tokens,
|
|
1208
|
-
quoteMint: WSOL_MINT
|
|
1209
|
-
}),
|
|
1210
|
-
quoteSell: (tokens) => curveSellQuote({
|
|
1211
|
-
global,
|
|
1212
|
-
bondingCurve: curve,
|
|
1213
|
-
feeConfig: pumpFeeConfig,
|
|
1214
|
-
mintSupply,
|
|
1215
|
-
tokens
|
|
1216
|
-
})
|
|
1217
|
-
};
|
|
1218
|
-
}
|
|
1219
|
-
if (!poolAccount) throw new Error(`no canonical PumpSwap pool at ${poolAddress}. The coin has not graduated, or its pool is not the canonical one.`);
|
|
1220
|
-
if (!ammConfigAccount) throw new Error(`PumpSwap's GlobalConfig is missing at ${AMM_GLOBAL_CONFIG}`);
|
|
1221
|
-
const pool = decodeAmmPool(poolAccount.data);
|
|
1222
|
-
const ammConfig = decodeAmmGlobalConfig(ammConfigAccount.data);
|
|
1223
|
-
const ammFeeConfig = ammFeeAccount ? decodeAmmFeeConfig(ammFeeAccount.data) : null;
|
|
1224
|
-
const [baseVault, quoteVault] = await readAccounts(client.rpc, [pool.poolBaseTokenAccount, pool.poolQuoteTokenAccount]);
|
|
1225
|
-
if (!baseVault || !quoteVault) throw new Error("the PumpSwap pool has no reserve accounts");
|
|
1226
|
-
const baseReserve = tokenAccountAmount(baseVault.data);
|
|
1227
|
-
const quoteReserve = tokenAccountAmount(quoteVault.data);
|
|
1228
|
-
const protocolFeeRecipient = pick(ammConfig.protocolFeeRecipients, options.feeRecipientIndex, "PumpSwap protocol fee recipient");
|
|
1229
|
-
const shared = {
|
|
1230
|
-
pool: poolAddress,
|
|
1231
|
-
mint,
|
|
1232
|
-
user,
|
|
1233
|
-
tokenProgram,
|
|
1234
|
-
poolBaseTokenAccount: pool.poolBaseTokenAccount,
|
|
1235
|
-
poolQuoteTokenAccount: pool.poolQuoteTokenAccount,
|
|
1236
|
-
coinCreator: pool.coinCreator,
|
|
1237
|
-
protocolFeeRecipient,
|
|
1238
|
-
quoteMint: WSOL_MINT,
|
|
1239
|
-
quoteTokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
1240
|
-
};
|
|
1241
|
-
return {
|
|
1242
|
-
kind,
|
|
1243
|
-
program: PUMP_SWAP_PROGRAM_ADDRESS,
|
|
1244
|
-
mint,
|
|
1245
|
-
tokenProgram,
|
|
1246
|
-
complete: true,
|
|
1247
|
-
creator: curve?.creator ?? pool.coinCreator,
|
|
1248
|
-
buyAccounts: swapBuyAccounts(shared),
|
|
1249
|
-
sellAccounts: swapSellAccounts(shared),
|
|
1250
|
-
quoteBuy: (tokens) => ammBuyCost({
|
|
1251
|
-
pool,
|
|
1252
|
-
globalConfig: ammConfig,
|
|
1253
|
-
feeConfig: ammFeeConfig,
|
|
1254
|
-
baseReserve,
|
|
1255
|
-
quoteReserve,
|
|
1256
|
-
baseMintSupply: mintSupply,
|
|
1257
|
-
tokens
|
|
1258
|
-
}),
|
|
1259
|
-
quoteSell: (tokens) => ammSellQuote({
|
|
1260
|
-
pool,
|
|
1261
|
-
globalConfig: ammConfig,
|
|
1262
|
-
feeConfig: ammFeeConfig,
|
|
1263
|
-
baseReserve,
|
|
1264
|
-
quoteReserve,
|
|
1265
|
-
baseMintSupply: mintSupply,
|
|
1266
|
-
tokens
|
|
1267
|
-
})
|
|
1268
|
-
};
|
|
1269
|
-
}
|
|
1270
|
-
/**
|
|
1271
|
-
* Lamports an exact-tokens-out buy of `tokens` costs right now, on whichever venue the coin trades.
|
|
1272
|
-
* Pass `pool.packTokens` for the pack price.
|
|
1273
|
-
*
|
|
1274
|
-
* One read and one number. Use `resolveVenue` when you also need the account list, which every
|
|
1275
|
-
* transaction builder does — this is for a price display.
|
|
1276
|
-
*/
|
|
1277
|
-
async function curveQuote(client, mint, tokens, options = {}) {
|
|
1278
|
-
return (await resolveVenue(client, {
|
|
1279
|
-
mint,
|
|
1280
|
-
user: options.user ?? mint,
|
|
1281
|
-
...options.venue ? { venue: options.venue } : {},
|
|
1282
|
-
feeRecipientIndex: 0,
|
|
1283
|
-
buybackRecipientIndex: 0
|
|
1284
|
-
})).quoteBuy(tokens);
|
|
1285
|
-
}
|
|
1286
|
-
/**
|
|
1287
|
-
* Lamports an exact-tokens-out buy of `tokens` would cost on a curve that does not exist yet,
|
|
1288
|
-
* fees included. This is what the seed costs: `initialize_pool` buys it in the same transaction
|
|
1289
|
-
* that creates the coin, so the curve is Pump's default new curve at that moment.
|
|
1290
|
-
*/
|
|
1291
|
-
async function newCurveBuyCost(client, tokens) {
|
|
1292
|
-
const [globalAccount, feeConfigAccount] = await readAccounts(client.rpc, [PUMP_GLOBAL, PUMP_FEE_CONFIG]);
|
|
1293
|
-
if (!globalAccount) throw new Error(`Pump's Global account is missing at ${PUMP_GLOBAL}`);
|
|
1294
|
-
return curveBuyCost({
|
|
1295
|
-
global: decodePumpGlobal(globalAccount.data),
|
|
1296
|
-
bondingCurve: null,
|
|
1297
|
-
feeConfig: feeConfigAccount ? decodePumpFeeConfig(feeConfigAccount.data) : null,
|
|
1298
|
-
mintSupply: null,
|
|
1299
|
-
tokens,
|
|
1300
|
-
quoteMint: WSOL_MINT
|
|
1301
|
-
});
|
|
1302
|
-
}
|
|
1303
|
-
/** Lamports a sale of `tokens` returns right now, net of the venue's fees. */
|
|
1304
|
-
async function sellQuote(client, mint, tokens, options = {}) {
|
|
1305
|
-
return (await resolveVenue(client, {
|
|
1306
|
-
mint,
|
|
1307
|
-
user: options.user ?? mint,
|
|
1308
|
-
...options.venue ? { venue: options.venue } : {},
|
|
1309
|
-
feeRecipientIndex: 0,
|
|
1310
|
-
buybackRecipientIndex: 0
|
|
1311
|
-
})).quoteSell(tokens);
|
|
1312
|
-
}
|
|
1313
|
-
/**
|
|
1314
|
-
* The user's WSOL associated token account. PumpSwap spends WSOL rather than native SOL, so this
|
|
1315
|
-
* account must exist and hold enough before a pack is bought on a graduated coin.
|
|
1316
|
-
*/
|
|
1317
|
-
function wsolAccountFor(user) {
|
|
1318
|
-
return ata(user, WSOL_MINT, TOKEN_PROGRAM_ADDRESS);
|
|
1319
|
-
}
|
|
1320
|
-
//#endregion
|
|
1321
|
-
//#region src/pump/create.ts
|
|
1322
|
-
/**
|
|
1323
|
-
* Pump's `create_v2`, built by hand.
|
|
1324
|
-
*
|
|
1325
|
-
* `@pump-fun/pump-sdk` has a `createV2Instruction`, but it returns a web3.js v1
|
|
1326
|
-
* `TransactionInstruction` built through Anchor. Converting that back into a kit instruction means
|
|
1327
|
-
* unpacking its account metas and re-deriving each role, which is more moving parts than encoding
|
|
1328
|
-
* six arguments. So the arguments are encoded here with kit codecs, and the account list still
|
|
1329
|
-
* comes from `accounts.ts`, which comes from the IDL.
|
|
1330
|
-
*
|
|
1331
|
-
* # The argument layout
|
|
1332
|
-
*
|
|
1333
|
-
* Borsh, in IDL order: three length-prefixed UTF-8 strings, a pubkey, a bool, and `OptionBool`.
|
|
1334
|
-
*
|
|
1335
|
-
* `OptionBool` is the one that catches people. It is **not** `Option<bool>`, which would be one or
|
|
1336
|
-
* two bytes depending on the tag. The IDL declares it as a struct with a single unnamed `bool`
|
|
1337
|
-
* field, so it is exactly one byte, always. `market.rs` hits the same thing on PumpSwap's buy and
|
|
1338
|
-
* says so in a comment.
|
|
1339
|
-
*/
|
|
1340
|
-
const ARGS_ENCODER = getStructEncoder([
|
|
1341
|
-
["name", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],
|
|
1342
|
-
["symbol", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],
|
|
1343
|
-
["uri", addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],
|
|
1344
|
-
["creator", getAddressEncoder()],
|
|
1345
|
-
["isMayhemMode", getBooleanEncoder()],
|
|
1346
|
-
["isCashbackEnabled", getBooleanEncoder()]
|
|
1347
|
-
]);
|
|
1348
|
-
/**
|
|
1349
|
-
* `create_v2`. Put it **before** `initialize_pool` in the transaction.
|
|
1350
|
-
*
|
|
1351
|
-
* `market::require_created_here` reads the Instructions sysvar and looks for this instruction by
|
|
1352
|
-
* discriminator, checking that account 0 is the mint and that account 5 — the `user` slot — is the
|
|
1353
|
-
* gabox creator and signs. The order matters for a second reason too: the mint account has to exist
|
|
1354
|
-
* and deserialize before `initialize_pool`'s own account validation runs.
|
|
1355
|
-
*/
|
|
1356
|
-
function getPumpCreateV2Instruction(input) {
|
|
1357
|
-
const { mint, user, name, symbol, uri, creator = user.address, mayhemMode = false, cashback = false } = input;
|
|
1358
|
-
const metas = pumpCreateV2Accounts({
|
|
1359
|
-
mint: mint.address,
|
|
1360
|
-
user: user.address,
|
|
1361
|
-
tokenProgram: PUMP_CREATE_TOKEN_PROGRAM_ADDRESS
|
|
1362
|
-
});
|
|
1363
|
-
const signerFor = /* @__PURE__ */ new Map([[mint.address, mint], [user.address, user]]);
|
|
1364
|
-
const accounts = metas.map((meta) => {
|
|
1365
|
-
const signer = signerFor.get(meta.address);
|
|
1366
|
-
const isSigner = meta.role === 2 || meta.role === 3;
|
|
1367
|
-
return signer && isSigner ? {
|
|
1368
|
-
...meta,
|
|
1369
|
-
signer
|
|
1370
|
-
} : meta;
|
|
1371
|
-
});
|
|
1372
|
-
const data = new Uint8Array([...PUMP_CREATE_V2.discriminator, ...ARGS_ENCODER.encode({
|
|
1373
|
-
name,
|
|
1374
|
-
symbol,
|
|
1375
|
-
uri,
|
|
1376
|
-
creator,
|
|
1377
|
-
isMayhemMode: mayhemMode,
|
|
1378
|
-
isCashbackEnabled: cashback
|
|
1379
|
-
})]);
|
|
1380
|
-
return {
|
|
1381
|
-
programAddress: PUMP_PROGRAM_ADDRESS,
|
|
1382
|
-
accounts,
|
|
1383
|
-
data
|
|
1384
|
-
};
|
|
1385
|
-
}
|
|
1386
|
-
//#endregion
|
|
1387
|
-
//#region src/pump/trade.ts
|
|
1388
|
-
/**
|
|
1389
|
-
* A venue trade the caller sends on its own, outside a gabox instruction.
|
|
1390
|
-
*
|
|
1391
|
-
* `buy_pack`, `sell_tokens` and the legacy `sell_prize` take the venue's account list as
|
|
1392
|
-
* `remainingAccounts` and the program does the CPI. Standalone trades are used when funding with
|
|
1393
|
-
* SOL. A sale of a delivered prize goes through `sell_tokens` (see `tx/redeem.ts`) so that it pays
|
|
1394
|
-
* the protocol fee; `venueSellInstruction` stays for coins that have no pool.
|
|
1395
|
-
*
|
|
1396
|
-
* # The argument layout
|
|
1397
|
-
*
|
|
1398
|
-
* `market.rs` says it in one sentence: "Every supported venue instruction starts with the same two
|
|
1399
|
-
* u64 args." A buy is `(amount_out, max_quote_in)` — the caller fixes the token count and the
|
|
1400
|
-
* venue decides the cost. PumpSwap's buy carries one extra byte, `track_volume`, which is an
|
|
1401
|
-
* `OptionBool`: a one-field tuple struct, so exactly one byte, never `Option<bool>`'s one-or-two.
|
|
1402
|
-
*
|
|
1403
|
-
* The account list and the discriminator both come from `abi.ts`, which codegen took from the two
|
|
1404
|
-
* official Pump IDLs. Nothing here retypes either.
|
|
1405
|
-
*/
|
|
1406
|
-
const u64 = getU64Encoder();
|
|
1407
|
-
/** `track_volume` on PumpSwap's buy. Off: a donation is not a volume-accruing trade for the funder. */
|
|
1408
|
-
const TRACK_VOLUME_OFF = 0;
|
|
1409
|
-
/**
|
|
1410
|
-
* Buy tokens at the venue, as a standalone instruction.
|
|
1411
|
-
*
|
|
1412
|
-
* The signer is attached to the one slot the ABI marks as a signer, and only when its address
|
|
1413
|
-
* matches — the same rule `create.ts` follows. Passing a `user` that is not in the account list is
|
|
1414
|
-
* a mistake this catches here rather than on chain.
|
|
1415
|
-
*/
|
|
1416
|
-
function venueBuyInstruction(input) {
|
|
1417
|
-
const { venue, user, tokens, maxQuoteIn } = input;
|
|
1418
|
-
if (tokens <= 0n) throw new Error("tokens must be positive");
|
|
1419
|
-
if (maxQuoteIn <= 0n) throw new Error("maxQuoteIn must be positive");
|
|
1420
|
-
const abi = venue.kind === "pump" ? PUMP_BUY : SWAP_BUY;
|
|
1421
|
-
const accounts = attachSigner(venue.buyAccounts, user);
|
|
1422
|
-
const data = new Uint8Array([
|
|
1423
|
-
...abi.discriminator,
|
|
1424
|
-
...u64.encode(tokens),
|
|
1425
|
-
...u64.encode(maxQuoteIn),
|
|
1426
|
-
...venue.kind === "pumpswap" ? [TRACK_VOLUME_OFF] : []
|
|
1427
|
-
]);
|
|
1428
|
-
return {
|
|
1429
|
-
programAddress: venue.program,
|
|
1430
|
-
accounts,
|
|
1431
|
-
data
|
|
1432
|
-
};
|
|
1433
|
-
}
|
|
1434
|
-
/** Sell tokens the wallet already holds, as a standalone venue instruction. */
|
|
1435
|
-
function venueSellInstruction(input) {
|
|
1436
|
-
const { venue, user, amount, minQuoteOutput } = input;
|
|
1437
|
-
if (amount <= 0n) throw new Error("amount must be positive");
|
|
1438
|
-
if (minQuoteOutput <= 0n) throw new Error("minQuoteOutput must be positive");
|
|
1439
|
-
const abi = venue.kind === "pump" ? PUMP_SELL : SWAP_SELL;
|
|
1440
|
-
return {
|
|
1441
|
-
programAddress: venue.program,
|
|
1442
|
-
accounts: attachSigner(venue.sellAccounts, user),
|
|
1443
|
-
data: new Uint8Array([
|
|
1444
|
-
...abi.discriminator,
|
|
1445
|
-
...u64.encode(amount),
|
|
1446
|
-
...u64.encode(minQuoteOutput)
|
|
1447
|
-
])
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
/** Give the signer to the slots the ABI already marks as signing. Roles never change here. */
|
|
1451
|
-
function attachSigner(accounts, signer) {
|
|
1452
|
-
let matched = false;
|
|
1453
|
-
const withSigner = accounts.map((meta) => {
|
|
1454
|
-
if (!(meta.role === 2 || meta.role === 3) || meta.address !== signer.address) return meta;
|
|
1455
|
-
matched = true;
|
|
1456
|
-
return {
|
|
1457
|
-
...meta,
|
|
1458
|
-
signer
|
|
1459
|
-
};
|
|
1460
|
-
});
|
|
1461
|
-
if (!matched) throw new Error(`${signer.address} is not the signing account of this venue trade. Resolve the venue with the same wallet you are going to sign with.`);
|
|
1462
|
-
return withSigner;
|
|
1463
|
-
}
|
|
1464
|
-
//#endregion
|
|
1465
|
-
//#region src/pump/index.ts
|
|
1466
|
-
var pump_exports = /* @__PURE__ */ __exportAll({
|
|
1467
|
-
AMM_EVENT_AUTHORITY: () => AMM_EVENT_AUTHORITY,
|
|
1468
|
-
AMM_FEE_CONFIG: () => AMM_FEE_CONFIG,
|
|
1469
|
-
AMM_GLOBAL_CONFIG: () => AMM_GLOBAL_CONFIG,
|
|
1470
|
-
AMM_GLOBAL_VOLUME_ACCUMULATOR: () => AMM_GLOBAL_VOLUME_ACCUMULATOR,
|
|
1471
|
-
ASSOCIATED_TOKEN_PROGRAM_ADDRESS: () => ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
1472
|
-
MAYHEM_GLOBAL_PARAMS: () => MAYHEM_GLOBAL_PARAMS,
|
|
1473
|
-
MAYHEM_PROGRAM_ADDRESS: () => MAYHEM_PROGRAM_ADDRESS,
|
|
1474
|
-
MAYHEM_SOL_VAULT: () => MAYHEM_SOL_VAULT,
|
|
1475
|
-
PUMP_BUY: () => PUMP_BUY,
|
|
1476
|
-
PUMP_CREATE_TOKEN_PROGRAM_ADDRESS: () => PUMP_CREATE_TOKEN_PROGRAM_ADDRESS,
|
|
1477
|
-
PUMP_CREATE_V2: () => PUMP_CREATE_V2,
|
|
1478
|
-
PUMP_EVENT_AUTHORITY: () => PUMP_EVENT_AUTHORITY,
|
|
1479
|
-
PUMP_FEE_CONFIG: () => PUMP_FEE_CONFIG,
|
|
1480
|
-
PUMP_FEE_PROGRAM_ADDRESS: () => PUMP_FEE_PROGRAM_ADDRESS,
|
|
1481
|
-
PUMP_GLOBAL: () => PUMP_GLOBAL,
|
|
1482
|
-
PUMP_GLOBAL_VOLUME_ACCUMULATOR: () => PUMP_GLOBAL_VOLUME_ACCUMULATOR,
|
|
1483
|
-
PUMP_MINT_AUTHORITY: () => PUMP_MINT_AUTHORITY,
|
|
1484
|
-
PUMP_PROGRAM_ADDRESS: () => PUMP_PROGRAM_ADDRESS,
|
|
1485
|
-
PUMP_SELL: () => PUMP_SELL,
|
|
1486
|
-
PUMP_SWAP_PROGRAM_ADDRESS: () => PUMP_SWAP_PROGRAM_ADDRESS,
|
|
1487
|
-
SWAP_BUY: () => SWAP_BUY,
|
|
1488
|
-
SWAP_SELL: () => SWAP_SELL,
|
|
1489
|
-
SYSTEM_PROGRAM_ADDRESS: () => SYSTEM_PROGRAM_ADDRESS,
|
|
1490
|
-
ammBuyCost: () => ammBuyCost,
|
|
1491
|
-
ammCanonicalPool: () => ammCanonicalPool,
|
|
1492
|
-
ammCoinCreatorVaultAta: () => ammCoinCreatorVaultAta,
|
|
1493
|
-
ammCoinCreatorVaultAuthority: () => ammCoinCreatorVaultAuthority,
|
|
1494
|
-
ammSellQuote: () => ammSellQuote,
|
|
1495
|
-
ammUserVolumeAccumulator: () => ammUserVolumeAccumulator,
|
|
1496
|
-
ata: () => ata,
|
|
1497
|
-
curveBuyCost: () => curveBuyCost,
|
|
1498
|
-
curveQuote: () => curveQuote,
|
|
1499
|
-
curveSellQuote: () => curveSellQuote,
|
|
1500
|
-
decodeAmmFeeConfig: () => decodeAmmFeeConfig,
|
|
1501
|
-
decodeAmmGlobalConfig: () => decodeAmmGlobalConfig,
|
|
1502
|
-
decodeAmmPool: () => decodeAmmPool,
|
|
1503
|
-
decodeBondingCurve: () => decodeBondingCurve,
|
|
1504
|
-
decodeMintSupply: () => decodeMintSupply,
|
|
1505
|
-
decodePumpFeeConfig: () => decodePumpFeeConfig,
|
|
1506
|
-
decodePumpGlobal: () => decodePumpGlobal,
|
|
1507
|
-
getPumpCreateV2Instruction: () => getPumpCreateV2Instruction,
|
|
1508
|
-
newCurveBuyCost: () => newCurveBuyCost,
|
|
1509
|
-
pumpBondingCurve: () => pumpBondingCurve,
|
|
1510
|
-
pumpBuyAccounts: () => pumpBuyAccounts,
|
|
1511
|
-
pumpCreateV2Accounts: () => pumpCreateV2Accounts,
|
|
1512
|
-
pumpCreatorVault: () => pumpCreatorVault,
|
|
1513
|
-
pumpMayhemState: () => pumpMayhemState,
|
|
1514
|
-
pumpMayhemTokenVault: () => pumpMayhemTokenVault,
|
|
1515
|
-
pumpSellAccounts: () => pumpSellAccounts,
|
|
1516
|
-
pumpSharingConfig: () => pumpSharingConfig,
|
|
1517
|
-
pumpUserVolumeAccumulator: () => pumpUserVolumeAccumulator,
|
|
1518
|
-
resolveVenue: () => resolveVenue,
|
|
1519
|
-
sellQuote: () => sellQuote,
|
|
1520
|
-
swapBuyAccounts: () => swapBuyAccounts,
|
|
1521
|
-
swapCashbackAccount: () => swapCashbackAccount,
|
|
1522
|
-
swapSellAccounts: () => swapSellAccounts,
|
|
1523
|
-
tokenAccountAmount: () => tokenAccountAmount,
|
|
1524
|
-
venueBuyInstruction: () => venueBuyInstruction,
|
|
1525
|
-
venueSellInstruction: () => venueSellInstruction,
|
|
1526
|
-
wsolAccountFor: () => wsolAccountFor
|
|
1527
|
-
});
|
|
1528
|
-
//#endregion
|
|
1529
|
-
export { MAX_ATTEMPTS as $, ammCoinCreatorVaultAta as A, decodeBondingCurve as B, PUMP_EVENT_AUTHORITY as C, SWAP_SELL as Ct, PUMP_MINT_AUTHORITY as D, PUMP_GLOBAL_VOLUME_ACCUMULATOR as E, curveBuyCost as F, pumpCreatorVault as G, decodePumpFeeConfig as H, curveSellQuote as I, pumpSharingConfig as J, pumpMayhemState as K, decodeAmmFeeConfig as L, ammSellQuote as M, ammUserVolumeAccumulator as N, ammBuyCost as O, ata as P, INSTRUCTIONS_SYSVAR as Q, decodeAmmGlobalConfig as R, MAYHEM_SOL_VAULT as S, SWAP_BUY as St, PUMP_GLOBAL as T, decodePumpGlobal as U, decodeMintSupply as V, pumpBondingCurve as W, GABOX_PROGRAM_ID as X, pumpUserVolumeAccumulator as Y, IDENTITY_SEED as Z, AMM_EVENT_AUTHORITY as _, PUMP_CREATE_V2 as _t, curveQuote as a, RETRY_SLOTS as at, AMM_GLOBAL_VOLUME_ACCUMULATOR as b, PUMP_SELL as bt, sellQuote as c, TOKEN_2022_PROGRAM_ADDRESS as ct, pumpBuyAccounts as d, VRF_PROGRAM_ADDRESS as dt, MAX_FEE_BPS as et, pumpCreateV2Accounts as f, WSOL_MINT as ft, swapSellAccounts as g, PUMP_CREATE_TOKEN_PROGRAM_ADDRESS as gt, swapCashbackAccount as h, PUMP_BUY as ht, getPumpCreateV2Instruction as i, REFERRAL_FEE_BPS as it, ammCoinCreatorVaultAuthority as j, ammCanonicalPool as k, tokenAccountAmount as l, TOKEN_PROGRAM_ADDRESS as lt, swapBuyAccounts as m, MAYHEM_PROGRAM_ADDRESS as mt, venueBuyInstruction as n, PROTOCOL_FEE_BPS as nt, newCurveBuyCost as o, SLOT_HASHES_SYSVAR as ot, pumpSellAccounts as p, ASSOCIATED_TOKEN_PROGRAM_ADDRESS as pt, pumpMayhemTokenVault as q, venueSellInstruction as r, PROTOCOL_FEE_COLLECTOR as rt, resolveVenue as s, TIMEOUT_SLOTS as st, pump_exports as t, PACK_TOKENS as tt, wsolAccountFor as u, VRF_DEFAULT_QUEUE as ut, AMM_FEE_CONFIG as v, PUMP_FEE_PROGRAM_ADDRESS as vt, PUMP_FEE_CONFIG as w, SYSTEM_PROGRAM_ADDRESS as wt, MAYHEM_GLOBAL_PARAMS as x, PUMP_SWAP_PROGRAM_ADDRESS as xt, AMM_GLOBAL_CONFIG as y, PUMP_PROGRAM_ADDRESS as yt, decodeAmmPool as z };
|
|
1530
|
-
|
|
1531
|
-
//# sourceMappingURL=pump-D0K_0uiC.js.map
|