@gabox-labs/sdk 0.7.1 → 0.9.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 +62 -0
- package/README.md +85 -23
- package/dist/{gabox-DGTCh34U.js → gabox-CuyJYmrS.js} +669 -309
- package/dist/gabox-CuyJYmrS.js.map +1 -0
- package/dist/generated/index.d.ts +458 -92
- package/dist/generated/index.js +214 -54
- package/dist/generated/index.js.map +1 -1
- package/dist/{index-CA0m7AKk.d.ts → index-CQcBMEah.d.ts} +189 -4
- package/dist/index.d.ts +226 -30
- package/dist/index.js +182 -40
- package/dist/index.js.map +1 -1
- package/dist/raydium/index.d.ts +2 -2
- package/dist/raydium/index.js +2 -2
- package/dist/{raydium-CU-tZzIk.js → raydium-DXUJ-g1p.js} +835 -105
- package/dist/raydium-DXUJ-g1p.js.map +1 -0
- package/llms.txt +4 -0
- package/package.json +1 -1
- package/skills/gabox-sdk/SKILL.md +21 -13
- package/skills/gabox-sdk/references/api.md +47 -18
- package/dist/gabox-DGTCh34U.js.map +0 -1
- package/dist/raydium-CU-tZzIk.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
-
import {
|
|
3
|
-
import { AccountRole, Endian, addEncoderSizePrefix, appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables, createTransactionMessage, fetchEncodedAccount, fixDecoderSize, getAddressDecoder, getAddressEncoder, getBase58Decoder, getBase64Encoder, getBooleanDecoder, getBytesDecoder, getBytesEncoder, getProgramDerivedAddress, getStructDecoder, getStructEncoder, getTransactionEncoder, getU16Decoder, getU16Encoder, getU32Encoder, getU64Decoder, getU64Encoder, getU8Decoder, getU8Encoder, getUtf8Encoder, pipe, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash } from "@solana/kit";
|
|
2
|
+
import { $t as getPoolSize, At as findDrawPda, Ht as getWalletActivitySize, Nt as decodeWalletActivity, Ot as findPoolPda, Ut as POOL_DISCRIMINATOR, Wt as decodePool, en as DRAW_DISCRIMINATOR, jt as findActivityPda, kt as findIdentityPda, t as GABOX_PROGRAM_ADDRESS, tn as decodeDraw, un as getDrawSize } from "./gabox-CuyJYmrS.js";
|
|
3
|
+
import { AccountRole, Endian, addEncoderSizePrefix, appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables, createTransactionMessage, fetchEncodedAccount, fixDecoderSize, getAddressDecoder, getAddressEncoder, getBase58Decoder, getBase64Encoder, getBooleanDecoder, getBytesDecoder, getBytesEncoder, getProgramDerivedAddress, getStructDecoder, getStructEncoder, getTransactionEncoder, getU128Decoder, getU16Decoder, getU16Encoder, getU32Encoder, getU64Decoder, getU64Encoder, getU8Decoder, getU8Encoder, getUtf8Encoder, pipe, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash } from "@solana/kit";
|
|
4
4
|
import { getCloseAccountInstruction, getCreateAssociatedTokenIdempotentInstruction } from "@solana-program/token";
|
|
5
5
|
//#region src/raydium/abi.ts
|
|
6
6
|
const RAYDIUM_MAINNET_IDS = {
|
|
@@ -603,6 +603,69 @@ const LAUNCHLAB_CLAIM_CREATOR_FEE = {
|
|
|
603
603
|
]
|
|
604
604
|
};
|
|
605
605
|
/**
|
|
606
|
+
* `claim_platform_fee_from_vault` on `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` — not in interfaces.json (the program never builds it).
|
|
607
|
+
*/
|
|
608
|
+
const LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT = {
|
|
609
|
+
name: "claim_platform_fee_from_vault",
|
|
610
|
+
discriminator: new Uint8Array([
|
|
611
|
+
117,
|
|
612
|
+
241,
|
|
613
|
+
198,
|
|
614
|
+
168,
|
|
615
|
+
248,
|
|
616
|
+
218,
|
|
617
|
+
80,
|
|
618
|
+
29
|
|
619
|
+
]),
|
|
620
|
+
accounts: [
|
|
621
|
+
{
|
|
622
|
+
name: "platform_fee_wallet",
|
|
623
|
+
writable: true,
|
|
624
|
+
signer: true
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
name: "fee_vault_authority",
|
|
628
|
+
writable: false,
|
|
629
|
+
signer: false
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
name: "platform_config",
|
|
633
|
+
writable: false,
|
|
634
|
+
signer: false
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
name: "platform_fee_vault",
|
|
638
|
+
writable: true,
|
|
639
|
+
signer: false
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
name: "recipient_token_account",
|
|
643
|
+
writable: true,
|
|
644
|
+
signer: false
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "quote_mint",
|
|
648
|
+
writable: false,
|
|
649
|
+
signer: false
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: "token_program",
|
|
653
|
+
writable: false,
|
|
654
|
+
signer: false
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
name: "system_program",
|
|
658
|
+
writable: false,
|
|
659
|
+
signer: false
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
name: "associated_token_program",
|
|
663
|
+
writable: false,
|
|
664
|
+
signer: false
|
|
665
|
+
}
|
|
666
|
+
]
|
|
667
|
+
};
|
|
668
|
+
/**
|
|
606
669
|
* `swap_base_output` on `CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` — cross-checked against interfaces.json.
|
|
607
670
|
*/
|
|
608
671
|
const CPMM_SWAP_BASE_OUTPUT = {
|
|
@@ -878,6 +941,14 @@ const CPMM_COLLECT_CREATOR_FEE = {
|
|
|
878
941
|
* `test/raydium-pdas.test.ts` derives each PDA again and compares.
|
|
879
942
|
*/
|
|
880
943
|
const ADDRESS_ENCODER = getAddressEncoder();
|
|
944
|
+
const LOCK_MAINNET_IDS = {
|
|
945
|
+
lock: "LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE",
|
|
946
|
+
lockAuthority: "3f7GcQFG397GAaEnv51zR6tsTVihYRydnydDD1cXekxH"
|
|
947
|
+
};
|
|
948
|
+
const LOCK_DEVNET_IDS = {
|
|
949
|
+
lock: "DRay25Usp3YJAi7beckgpGUC7mGJ2cR1AVPxhYfwVCUX",
|
|
950
|
+
lockAuthority: "7qWVV8UY2bRJfDLP4s37YzBPKUkVB46DStYJBpYbQzu3"
|
|
951
|
+
};
|
|
881
952
|
/**
|
|
882
953
|
* The decimals every Gabox coin is launched with. `venue/launch.rs` refuses any other value, and
|
|
883
954
|
* `tokens.rs` refuses a pool mint that does not have exactly this many.
|
|
@@ -891,9 +962,18 @@ const LAUNCH_DECIMALS = 6;
|
|
|
891
962
|
* feature is what swaps them. Pass your own ids to a builder if your validator clones devnet.
|
|
892
963
|
*/
|
|
893
964
|
const RAYDIUM_IDS = {
|
|
894
|
-
"mainnet-beta":
|
|
895
|
-
|
|
896
|
-
|
|
965
|
+
"mainnet-beta": {
|
|
966
|
+
...RAYDIUM_MAINNET_IDS,
|
|
967
|
+
...LOCK_MAINNET_IDS
|
|
968
|
+
},
|
|
969
|
+
devnet: {
|
|
970
|
+
...RAYDIUM_DEVNET_IDS,
|
|
971
|
+
...LOCK_DEVNET_IDS
|
|
972
|
+
},
|
|
973
|
+
localnet: {
|
|
974
|
+
...RAYDIUM_MAINNET_IDS,
|
|
975
|
+
...LOCK_MAINNET_IDS
|
|
976
|
+
}
|
|
897
977
|
};
|
|
898
978
|
/** The Raydium deployment one cluster trades on. Throws for a cluster this SDK does not know. */
|
|
899
979
|
function raydiumIds(cluster) {
|
|
@@ -916,7 +996,9 @@ const LAUNCHLAB_SEEDS = {
|
|
|
916
996
|
/** `["pool_vault", pool_state, mint]`. */
|
|
917
997
|
vault: "pool_vault",
|
|
918
998
|
/** `["creator_fee_vault_auth_seed"]`, the authority over every creator fee vault. */
|
|
919
|
-
creatorFeeVaultAuthority: "creator_fee_vault_auth_seed"
|
|
999
|
+
creatorFeeVaultAuthority: "creator_fee_vault_auth_seed",
|
|
1000
|
+
/** `["platform_fee_vault_auth_seed"]`, the authority over every platform fee vault. */
|
|
1001
|
+
platformFeeVaultAuthority: "platform_fee_vault_auth_seed"
|
|
920
1002
|
};
|
|
921
1003
|
/** CPMM's PDA seeds. */
|
|
922
1004
|
const CPMM_SEEDS = {
|
|
@@ -931,6 +1013,15 @@ const CPMM_SEEDS = {
|
|
|
931
1013
|
/** `["creator_fee_share", creator, amm_config]`. */
|
|
932
1014
|
creatorFeeShare: "creator_fee_share"
|
|
933
1015
|
};
|
|
1016
|
+
/** The SPL Memo program. The lock program's `collect_cp_fees` lists it and never writes to it. */
|
|
1017
|
+
const MEMO_PROGRAM_ADDRESS = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
|
|
1018
|
+
/** The lock program's PDA seeds. */
|
|
1019
|
+
const LOCK_SEEDS = {
|
|
1020
|
+
/** `["lock_cp_authority_seed"]`. */
|
|
1021
|
+
authority: "lock_cp_authority_seed",
|
|
1022
|
+
/** `["locked_liquidity", fee_nft_mint]`. One record per locked position. */
|
|
1023
|
+
lockedLiquidity: "locked_liquidity"
|
|
1024
|
+
};
|
|
934
1025
|
/** Metaplex's metadata PDA seed: `["metadata", metaplex, mint]`. */
|
|
935
1026
|
const METADATA_SEED = "metadata";
|
|
936
1027
|
/**
|
|
@@ -973,43 +1064,6 @@ function compareAddresses(a, b) {
|
|
|
973
1064
|
return 0;
|
|
974
1065
|
}
|
|
975
1066
|
//#endregion
|
|
976
|
-
//#region src/ids.ts
|
|
977
|
-
/** `declare_id!` in `programs/gabox/src/lib.rs`. */
|
|
978
|
-
const GABOX_PROGRAM_ID = GABOX_PROGRAM_ADDRESS;
|
|
979
|
-
/** MagicBlock's ephemeral VRF program. `vrf.rs` pins it and refuses any other. */
|
|
980
|
-
const VRF_PROGRAM_ADDRESS = "Vrf1RNUjXmQGjmQrQLvJHs9SNkvDJEsRVFPkfSQUwGz";
|
|
981
|
-
/**
|
|
982
|
-
* MagicBlock's default oracle queue. The program pins this one address, so a pool creator cannot
|
|
983
|
-
* point a draw at an oracle they control.
|
|
984
|
-
*/
|
|
985
|
-
const VRF_DEFAULT_QUEUE = "Cuj97ggrhhidhbu39TijNVqE74xvKJ69gDervRUXAxGh";
|
|
986
|
-
/** The seed of both identity PDAs. See `pdas.ts` — there are two, under different programs. */
|
|
987
|
-
const IDENTITY_SEED = new Uint8Array([
|
|
988
|
-
105,
|
|
989
|
-
100,
|
|
990
|
-
101,
|
|
991
|
-
110,
|
|
992
|
-
116,
|
|
993
|
-
105,
|
|
994
|
-
116,
|
|
995
|
-
121
|
|
996
|
-
]);
|
|
997
|
-
const SLOT_HASHES_SYSVAR = "SysvarS1otHashes111111111111111111111111111";
|
|
998
|
-
const INSTRUCTIONS_SYSVAR = "Sysvar1nstructions1111111111111111111111111";
|
|
999
|
-
/** `constants.rs`. A retry may not run sooner than this after the last attempt. */
|
|
1000
|
-
const RETRY_SLOTS = 300n;
|
|
1001
|
-
/** `constants.rs`. After this many slots from the purchase, anyone may expire the draw. */
|
|
1002
|
-
const TIMEOUT_SLOTS = 216000n;
|
|
1003
|
-
/** `constants.rs`. Three requests in total, counting the one `buy_pack` makes. */
|
|
1004
|
-
const MAX_ATTEMPTS = 3;
|
|
1005
|
-
/**
|
|
1006
|
-
* `constants.rs`. Tokens in one pack, in base units: 1,000,000 tokens at the fixed 6 decimals, or
|
|
1007
|
-
* 0.1% of the 1,000,000,000 supply. Every pool sells packs of this size. The venue decides what a
|
|
1008
|
-
* pack costs, so the pack price follows the coin. Read `pool.packTokens` rather than this when a
|
|
1009
|
-
* pool is at hand: a later program version may change the constant.
|
|
1010
|
-
*/
|
|
1011
|
-
const PACK_TOKENS = 1000000n * 1000000n;
|
|
1012
|
-
//#endregion
|
|
1013
1067
|
//#region src/math.ts
|
|
1014
1068
|
/**
|
|
1015
1069
|
* A bigint port of `programs/gabox/src/math.rs`.
|
|
@@ -1038,6 +1092,12 @@ const MAX_MULTIPLIER_BPS = 2e5;
|
|
|
1038
1092
|
const TICKETS = 65536;
|
|
1039
1093
|
/** The prize table has exactly this many slots. Unused slots are all-zero. */
|
|
1040
1094
|
const TIERS = 8;
|
|
1095
|
+
/**
|
|
1096
|
+
* `constants::MAX_BATCH_SIZE`. The most packs one `buy_packs` call opens. A limit per purchase,
|
|
1097
|
+
* not on pending packs: any number of buyers and overlapping purchases are fine, because every
|
|
1098
|
+
* pending draw carries its own reservation.
|
|
1099
|
+
*/
|
|
1100
|
+
const MAX_BATCH_SIZE = 5;
|
|
1041
1101
|
/** Thrown by every function here. `code` matches a `GaboxError` variant name. */
|
|
1042
1102
|
var GaboxMathError = class extends Error {
|
|
1043
1103
|
code;
|
|
@@ -1242,6 +1302,124 @@ function choose(prizes, ticket) {
|
|
|
1242
1302
|
}
|
|
1243
1303
|
return 0n;
|
|
1244
1304
|
}
|
|
1305
|
+
/** A ticket is a `u16`: the first two bytes of the pack's hash, little-endian. */
|
|
1306
|
+
function checkedTicket(ticket) {
|
|
1307
|
+
if (!Number.isInteger(ticket) || ticket < 0 || ticket >= 65536) throw new GaboxMathError("Arithmetic", `a ticket is an integer from 0 to 65535`);
|
|
1308
|
+
return ticket;
|
|
1309
|
+
}
|
|
1310
|
+
/** `count` is a `u8` the program bounds at `MAX_BATCH_SIZE`. Zero is refused before any trade. */
|
|
1311
|
+
function checkedCount(count) {
|
|
1312
|
+
if (!Number.isInteger(count) || count < 1) throw new GaboxMathError("ZeroAmount", "a purchase opens at least one pack");
|
|
1313
|
+
if (count > 5) throw new GaboxMathError("TooManyPacks", `a purchase opens at most 5 packs`);
|
|
1314
|
+
return count;
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* `math::uncapped`. Every tier's award for this base before any inventory cap, `0n` on an unused
|
|
1318
|
+
* row. A ticketed tier that would pay nothing is refused, the same as in `quote`.
|
|
1319
|
+
*/
|
|
1320
|
+
function uncappedAmounts(base, tiers) {
|
|
1321
|
+
validateTiers(tiers);
|
|
1322
|
+
return tiers.map((tier, i) => {
|
|
1323
|
+
if (tier.tickets === 0) return 0n;
|
|
1324
|
+
const amount = tierAmount(base, tier.multiplierBps);
|
|
1325
|
+
if (amount === 0n) throw new GaboxMathError("PackTooSmall", `tier ${i} rounds to zero tokens at this pack size`);
|
|
1326
|
+
return amount;
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
/** `math::min_tier`. The ticketed tier with the smallest award. Expiry pays it for every pack. */
|
|
1330
|
+
function minTier(uncapped, tiers) {
|
|
1331
|
+
let best = null;
|
|
1332
|
+
for (const [i, tier] of tiers.entries()) {
|
|
1333
|
+
if (tier.tickets === 0) continue;
|
|
1334
|
+
if (best === null || uncapped[i] < uncapped[best]) best = i;
|
|
1335
|
+
}
|
|
1336
|
+
return best ?? 0;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* `math::choose_index`. Which tier a 16-bit ticket lands on: the rows are consecutive ranges in
|
|
1340
|
+
* table order. Exactly 65,536 tickets, so there is no modulo and no bias.
|
|
1341
|
+
*/
|
|
1342
|
+
function chooseIndex(tiers, ticket) {
|
|
1343
|
+
checkedTicket(ticket);
|
|
1344
|
+
let end = 0;
|
|
1345
|
+
let last = 0;
|
|
1346
|
+
for (const [i, tier] of tiers.entries()) {
|
|
1347
|
+
if (tier.tickets === 0) continue;
|
|
1348
|
+
last = i;
|
|
1349
|
+
end += tier.tickets;
|
|
1350
|
+
if (ticket < end) return i;
|
|
1351
|
+
}
|
|
1352
|
+
return last;
|
|
1353
|
+
}
|
|
1354
|
+
/**
|
|
1355
|
+
* `math::reserve_for`. What a purchase of `count` packs adds to `pool.reserved`:
|
|
1356
|
+
* `min(count * uncappedMax, free + count * packTokens)`. Settlement in order can never pay more
|
|
1357
|
+
* than either bound, so this is the least reservation that keeps the vault solvent whatever the
|
|
1358
|
+
* outcomes. With `count = 1` it is exactly the single pack's capped maximum.
|
|
1359
|
+
*/
|
|
1360
|
+
function reserveFor(count, packTokens, uncappedMax, free) {
|
|
1361
|
+
checkedCount(count);
|
|
1362
|
+
const byPrizes = checkedU64(uncappedMax * BigInt(count), "reservation");
|
|
1363
|
+
const byVault = checkedU64(free + packTokens * BigInt(count), "reservation");
|
|
1364
|
+
return byPrizes < byVault ? byPrizes : byVault;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* `math::settle_with`. Settle a batch in order from explicit tickets.
|
|
1368
|
+
*
|
|
1369
|
+
* Pack k's table caps every tier at what the vault can pay after packs 1..k-1 paid out, counting
|
|
1370
|
+
* the batch's own tokens as they arrive: pack 1 sees `freeSnapshot + packTokens`, and every later
|
|
1371
|
+
* pack sees the remainder plus one more pack. So no pack can lose its own base to an earlier pack,
|
|
1372
|
+
* and the total never exceeds `reserveFor(...)`.
|
|
1373
|
+
*
|
|
1374
|
+
* With `timedOut` every pack pays its smallest tier, and `tickets` is ignored.
|
|
1375
|
+
*/
|
|
1376
|
+
function settleWith(tiers, packTokens, freeSnapshot, count, tickets, timedOut = false) {
|
|
1377
|
+
checkedCount(count);
|
|
1378
|
+
const uncapped = uncappedAmounts(packTokens, tiers);
|
|
1379
|
+
const fallback = minTier(uncapped, tiers);
|
|
1380
|
+
let avail = checkedU64(freeSnapshot + packTokens, "available inventory");
|
|
1381
|
+
let total = 0n;
|
|
1382
|
+
const results = [];
|
|
1383
|
+
for (let k = 0; k < count; k++) {
|
|
1384
|
+
let tier;
|
|
1385
|
+
if (timedOut) tier = fallback;
|
|
1386
|
+
else {
|
|
1387
|
+
const ticket = tickets[k];
|
|
1388
|
+
if (ticket === void 0) throw new GaboxMathError("Arithmetic", `no ticket for pack ${k} of ${count}`);
|
|
1389
|
+
tier = chooseIndex(tiers, ticket);
|
|
1390
|
+
}
|
|
1391
|
+
const cap = uncapped[tier];
|
|
1392
|
+
const amount = cap < avail ? cap : avail;
|
|
1393
|
+
results.push({
|
|
1394
|
+
tier,
|
|
1395
|
+
amount
|
|
1396
|
+
});
|
|
1397
|
+
total = checkedU64(total + amount, "settlement total");
|
|
1398
|
+
avail = checkedU64(avail - amount + packTokens, "available inventory");
|
|
1399
|
+
}
|
|
1400
|
+
return {
|
|
1401
|
+
total,
|
|
1402
|
+
results
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* The top prize each pack of a purchase can still win if every pack before it won its own top
|
|
1407
|
+
* prize: the worst case for the later packs, which is what a buyer should see next to the first
|
|
1408
|
+
* pack's table. `caps[0]` is the first pack's capped maximum; on a deep vault every entry is the
|
|
1409
|
+
* uncapped jackpot, on a thin one the later entries fall towards one pack.
|
|
1410
|
+
*/
|
|
1411
|
+
function perPackCaps(tiers, packTokens, freeSnapshot, count) {
|
|
1412
|
+
checkedCount(count);
|
|
1413
|
+
const uncapped = uncappedMaximum(packTokens, tiers);
|
|
1414
|
+
let avail = checkedU64(freeSnapshot + packTokens, "available inventory");
|
|
1415
|
+
const caps = [];
|
|
1416
|
+
for (let k = 0; k < count; k++) {
|
|
1417
|
+
const cap = uncapped < avail ? uncapped : avail;
|
|
1418
|
+
caps.push(cap);
|
|
1419
|
+
avail = checkedU64(avail - cap + packTokens, "available inventory");
|
|
1420
|
+
}
|
|
1421
|
+
return caps;
|
|
1422
|
+
}
|
|
1245
1423
|
/** `math::resolve_reservation`. Release the unwon part of a maximum, keep the award reserved. */
|
|
1246
1424
|
function resolveReservation(reserved, maximum, award) {
|
|
1247
1425
|
if (award > maximum) throw new GaboxMathError("InsolventInventory", "the award exceeds the reserved maximum");
|
|
@@ -1274,6 +1452,43 @@ function averageMultiplierBps(tiers) {
|
|
|
1274
1452
|
return Number(weighted / BigInt(TICKETS));
|
|
1275
1453
|
}
|
|
1276
1454
|
//#endregion
|
|
1455
|
+
//#region src/ids.ts
|
|
1456
|
+
/** `declare_id!` in `programs/gabox/src/lib.rs`. */
|
|
1457
|
+
const GABOX_PROGRAM_ID = GABOX_PROGRAM_ADDRESS;
|
|
1458
|
+
/** MagicBlock's ephemeral VRF program. `vrf.rs` pins it and refuses any other. */
|
|
1459
|
+
const VRF_PROGRAM_ADDRESS = "Vrf1RNUjXmQGjmQrQLvJHs9SNkvDJEsRVFPkfSQUwGz";
|
|
1460
|
+
/**
|
|
1461
|
+
* MagicBlock's default oracle queue. The program pins this one address, so a pool creator cannot
|
|
1462
|
+
* point a draw at an oracle they control.
|
|
1463
|
+
*/
|
|
1464
|
+
const VRF_DEFAULT_QUEUE = "Cuj97ggrhhidhbu39TijNVqE74xvKJ69gDervRUXAxGh";
|
|
1465
|
+
/** The seed of both identity PDAs. See `pdas.ts` — there are two, under different programs. */
|
|
1466
|
+
const IDENTITY_SEED = new Uint8Array([
|
|
1467
|
+
105,
|
|
1468
|
+
100,
|
|
1469
|
+
101,
|
|
1470
|
+
110,
|
|
1471
|
+
116,
|
|
1472
|
+
105,
|
|
1473
|
+
116,
|
|
1474
|
+
121
|
|
1475
|
+
]);
|
|
1476
|
+
const SLOT_HASHES_SYSVAR = "SysvarS1otHashes111111111111111111111111111";
|
|
1477
|
+
const INSTRUCTIONS_SYSVAR = "Sysvar1nstructions1111111111111111111111111";
|
|
1478
|
+
/** `constants.rs`. A retry may not run sooner than this after the last attempt. */
|
|
1479
|
+
const RETRY_SLOTS = 300n;
|
|
1480
|
+
/** `constants.rs`. After this many slots from the purchase, anyone may expire the draw. */
|
|
1481
|
+
const TIMEOUT_SLOTS = 216000n;
|
|
1482
|
+
/** `constants.rs`. Three requests in total, counting the one `buy_packs` makes. */
|
|
1483
|
+
const MAX_ATTEMPTS = 3;
|
|
1484
|
+
/**
|
|
1485
|
+
* `constants.rs`. Tokens in one pack, in base units: 1,000,000 tokens at the fixed 6 decimals, or
|
|
1486
|
+
* 0.1% of the 1,000,000,000 supply. Every pool sells packs of this size. The venue decides what a
|
|
1487
|
+
* pack costs, so the pack price follows the coin. Read `pool.packTokens` rather than this when a
|
|
1488
|
+
* pool is at hand: a later program version may change the constant.
|
|
1489
|
+
*/
|
|
1490
|
+
const PACK_TOKENS = 1000000n * 1000000n;
|
|
1491
|
+
//#endregion
|
|
1277
1492
|
//#region src/raydium/pdas.ts
|
|
1278
1493
|
/**
|
|
1279
1494
|
* Every Raydium address a Gabox transaction derives.
|
|
@@ -1337,6 +1552,11 @@ const platformFeeVaultAddress = async (launchlab, platformConfig, quoteMint) =>
|
|
|
1337
1552
|
const creatorFeeVaultAddress = async (launchlab, creator, quoteMint) => await derive(launchlab, [address$1.encode(creator), address$1.encode(quoteMint)]);
|
|
1338
1553
|
/** `["creator_fee_vault_auth_seed"]`. The authority `claim_creator_fee` signs the payout with. */
|
|
1339
1554
|
const creatorFeeVaultAuthority = async (launchlab) => await derive(launchlab, [utf8.encode(LAUNCHLAB_SEEDS.creatorFeeVaultAuthority)]);
|
|
1555
|
+
/**
|
|
1556
|
+
* `["platform_fee_vault_auth_seed"]`. The authority `claim_platform_fee_from_vault` signs the
|
|
1557
|
+
* payout with.
|
|
1558
|
+
*/
|
|
1559
|
+
const platformFeeVaultAuthority = async (launchlab) => await derive(launchlab, [utf8.encode(LAUNCHLAB_SEEDS.platformFeeVaultAuthority)]);
|
|
1340
1560
|
/** `["metadata", metaplex, mint]` under Metaplex. LaunchLab's create instruction writes it. */
|
|
1341
1561
|
const metadataAddress = async (mint) => await derive(METAPLEX_PROGRAM_ADDRESS, [
|
|
1342
1562
|
utf8.encode(METADATA_SEED),
|
|
@@ -1379,6 +1599,13 @@ const cpmmCreatorFeeShare = async (cpmm, creator, ammConfig) => await derive(cpm
|
|
|
1379
1599
|
address$1.encode(creator),
|
|
1380
1600
|
address$1.encode(ammConfig)
|
|
1381
1601
|
]);
|
|
1602
|
+
/** `["lock_cp_authority_seed"]`. The lock program's authority, which owns every locked LP vault. */
|
|
1603
|
+
const lockAuthority = async (lock) => await derive(lock, [utf8.encode(LOCK_SEEDS.authority)]);
|
|
1604
|
+
/**
|
|
1605
|
+
* `["locked_liquidity", fee_nft_mint]`. The record of one locked position: which pool, how much LP,
|
|
1606
|
+
* and the checkpoint the next fee harvest is measured from.
|
|
1607
|
+
*/
|
|
1608
|
+
const lockedLiquidityAddress = async (lock, feeNftMint) => await derive(lock, [utf8.encode(LOCK_SEEDS.lockedLiquidity), address$1.encode(feeNftMint)]);
|
|
1382
1609
|
/** An associated token account. Off-curve owners are allowed: pool PDAs are all off-curve. */
|
|
1383
1610
|
const ata = async (owner, mint, tokenProgram = TOKEN_PROGRAM_ADDRESS) => await derive(ASSOCIATED_TOKEN_PROGRAM_ADDRESS, [
|
|
1384
1611
|
address$1.encode(owner),
|
|
@@ -1398,12 +1625,30 @@ const ata = async (owner, mint, tokenProgram = TOKEN_PROGRAM_ADDRESS) => await d
|
|
|
1398
1625
|
*/
|
|
1399
1626
|
/** `["pool", mint]`. One pool per coin. */
|
|
1400
1627
|
const poolAddress = async (mint) => (await findPoolPda({ mint }))[0];
|
|
1401
|
-
/**
|
|
1402
|
-
|
|
1628
|
+
/**
|
|
1629
|
+
* `["draw", pool, purchaser, nonce]`, with the nonce as eight little-endian bytes. The buyer's
|
|
1630
|
+
* client picks the nonce, so two buyers, or two purchases of one buyer, never name the same draw.
|
|
1631
|
+
* The pool's sequence counter is not in the address any more; the program assigns `seqStart`
|
|
1632
|
+
* when the purchase executes.
|
|
1633
|
+
*/
|
|
1634
|
+
const drawAddress = async (pool, purchaser, nonce) => (await findDrawPda({
|
|
1403
1635
|
pool,
|
|
1404
|
-
|
|
1636
|
+
purchaser,
|
|
1637
|
+
nonce
|
|
1405
1638
|
}))[0];
|
|
1406
|
-
/**
|
|
1639
|
+
/**
|
|
1640
|
+
* A random `u64` nonce for one purchase. `buyPacks` draws one per build. A nonce that is still in
|
|
1641
|
+
* use fails the purchase at the program; one whose draw already closed names a new draw, so a
|
|
1642
|
+
* rebuilt transaction must never reuse the nonce of a purchase that may have landed.
|
|
1643
|
+
*/
|
|
1644
|
+
function randomNonce() {
|
|
1645
|
+
const bytes = /* @__PURE__ */ new Uint8Array(8);
|
|
1646
|
+
crypto.getRandomValues(bytes);
|
|
1647
|
+
let nonce = 0n;
|
|
1648
|
+
for (let i = 7; i >= 0; i--) nonce = nonce << 8n | BigInt(bytes[i]);
|
|
1649
|
+
return nonce;
|
|
1650
|
+
}
|
|
1651
|
+
/** The per-wallet `WalletActivity` PDA. `buy_packs` derives it from the purchaser automatically. */
|
|
1407
1652
|
const activityAddress = async (wallet) => (await findActivityPda({ purchaser: wallet }))[0];
|
|
1408
1653
|
/** `["identity"]` under Gabox. The PDA the program signs its randomness request with. */
|
|
1409
1654
|
const vrfIdentityAddress = async () => (await findIdentityPda())[0];
|
|
@@ -1440,7 +1685,8 @@ const vaultAddress = async (mint) => await associatedTokenAddress(await poolAddr
|
|
|
1440
1685
|
const DISCRIMINATOR$1 = 8;
|
|
1441
1686
|
const u8 = getU8Decoder();
|
|
1442
1687
|
const u16 = getU16Decoder();
|
|
1443
|
-
const u64$
|
|
1688
|
+
const u64$2 = getU64Decoder();
|
|
1689
|
+
const u128 = getU128Decoder();
|
|
1444
1690
|
const addressAt = getAddressDecoder();
|
|
1445
1691
|
const bool = getBooleanDecoder();
|
|
1446
1692
|
/** Refuse an account that is too short or carries another type's discriminator. */
|
|
@@ -1462,7 +1708,7 @@ function atLeast(data, size, what) {
|
|
|
1462
1708
|
*/
|
|
1463
1709
|
function tokenAccountAmount(data) {
|
|
1464
1710
|
if (data.length < 72) throw new Error("not a token account: fewer than 72 bytes");
|
|
1465
|
-
return u64$
|
|
1711
|
+
return u64$2.decode(data, 64);
|
|
1466
1712
|
}
|
|
1467
1713
|
/** The `mint` and `owner` of an SPL token account: bytes 0 to 32 and 32 to 64. */
|
|
1468
1714
|
function tokenAccountOwnerAndMint(data) {
|
|
@@ -1542,27 +1788,27 @@ function token2022Symbol(data) {
|
|
|
1542
1788
|
}
|
|
1543
1789
|
/** Offsets follow the `PoolState` field list in `idl/raydium_launchpad.json`. */
|
|
1544
1790
|
const LAUNCHLAB_POOL_HEAD = getStructDecoder([
|
|
1545
|
-
["epoch", u64$
|
|
1791
|
+
["epoch", u64$2],
|
|
1546
1792
|
["authBump", u8],
|
|
1547
1793
|
["status", u8],
|
|
1548
1794
|
["baseDecimals", u8],
|
|
1549
1795
|
["quoteDecimals", u8],
|
|
1550
1796
|
["migrateType", u8],
|
|
1551
|
-
["supply", u64$
|
|
1552
|
-
["totalBaseSell", u64$
|
|
1553
|
-
["virtualBase", u64$
|
|
1554
|
-
["virtualQuote", u64$
|
|
1555
|
-
["realBase", u64$
|
|
1556
|
-
["realQuote", u64$
|
|
1557
|
-
["totalQuoteFundRaising", u64$
|
|
1558
|
-
["quoteProtocolFee", u64$
|
|
1559
|
-
["platformFee", u64$
|
|
1560
|
-
["migrateFee", u64$
|
|
1561
|
-
["vestingTotalLockedAmount", u64$
|
|
1562
|
-
["vestingCliffPeriod", u64$
|
|
1563
|
-
["vestingUnlockPeriod", u64$
|
|
1564
|
-
["vestingStartTime", u64$
|
|
1565
|
-
["vestingAllocatedShareAmount", u64$
|
|
1797
|
+
["supply", u64$2],
|
|
1798
|
+
["totalBaseSell", u64$2],
|
|
1799
|
+
["virtualBase", u64$2],
|
|
1800
|
+
["virtualQuote", u64$2],
|
|
1801
|
+
["realBase", u64$2],
|
|
1802
|
+
["realQuote", u64$2],
|
|
1803
|
+
["totalQuoteFundRaising", u64$2],
|
|
1804
|
+
["quoteProtocolFee", u64$2],
|
|
1805
|
+
["platformFee", u64$2],
|
|
1806
|
+
["migrateFee", u64$2],
|
|
1807
|
+
["vestingTotalLockedAmount", u64$2],
|
|
1808
|
+
["vestingCliffPeriod", u64$2],
|
|
1809
|
+
["vestingUnlockPeriod", u64$2],
|
|
1810
|
+
["vestingStartTime", u64$2],
|
|
1811
|
+
["vestingAllocatedShareAmount", u64$2],
|
|
1566
1812
|
["globalConfig", addressAt],
|
|
1567
1813
|
["platformConfig", addressAt],
|
|
1568
1814
|
["baseMint", addressAt],
|
|
@@ -1603,17 +1849,17 @@ function decodeLaunchlabPool(data) {
|
|
|
1603
1849
|
};
|
|
1604
1850
|
}
|
|
1605
1851
|
const LAUNCHLAB_GLOBAL_CONFIG_HEAD = getStructDecoder([
|
|
1606
|
-
["epoch", u64$
|
|
1852
|
+
["epoch", u64$2],
|
|
1607
1853
|
["curveType", u8],
|
|
1608
1854
|
["index", u16],
|
|
1609
|
-
["migrateFee", u64$
|
|
1610
|
-
["tradeFeeRate", u64$
|
|
1611
|
-
["maxShareFeeRate", u64$
|
|
1612
|
-
["minBaseSupply", u64$
|
|
1613
|
-
["maxLockRate", u64$
|
|
1614
|
-
["minBaseSellRate", u64$
|
|
1615
|
-
["minBaseMigrateRate", u64$
|
|
1616
|
-
["minQuoteFundRaising", u64$
|
|
1855
|
+
["migrateFee", u64$2],
|
|
1856
|
+
["tradeFeeRate", u64$2],
|
|
1857
|
+
["maxShareFeeRate", u64$2],
|
|
1858
|
+
["minBaseSupply", u64$2],
|
|
1859
|
+
["maxLockRate", u64$2],
|
|
1860
|
+
["minBaseSellRate", u64$2],
|
|
1861
|
+
["minBaseMigrateRate", u64$2],
|
|
1862
|
+
["minQuoteFundRaising", u64$2],
|
|
1617
1863
|
["quoteMint", addressAt]
|
|
1618
1864
|
]);
|
|
1619
1865
|
const LAUNCHLAB_GLOBAL_CONFIG_HEAD_SIZE = 115;
|
|
@@ -1635,13 +1881,13 @@ function decodeLaunchlabGlobalConfig(data) {
|
|
|
1635
1881
|
* are fixed byte arrays, so this is the same length for every platform.
|
|
1636
1882
|
*/
|
|
1637
1883
|
const LAUNCHLAB_PLATFORM_CONFIG_HEAD = getStructDecoder([
|
|
1638
|
-
["epoch", u64$
|
|
1884
|
+
["epoch", u64$2],
|
|
1639
1885
|
["platformFeeWallet", addressAt],
|
|
1640
1886
|
["platformNftWallet", addressAt],
|
|
1641
|
-
["platformScale", u64$
|
|
1642
|
-
["creatorScale", u64$
|
|
1643
|
-
["burnScale", u64$
|
|
1644
|
-
["feeRate", u64$
|
|
1887
|
+
["platformScale", u64$2],
|
|
1888
|
+
["creatorScale", u64$2],
|
|
1889
|
+
["burnScale", u64$2],
|
|
1890
|
+
["feeRate", u64$2]
|
|
1645
1891
|
]);
|
|
1646
1892
|
const PLATFORM_CPSWAP_CONFIG_OFFSET = 688;
|
|
1647
1893
|
const PLATFORM_CREATOR_FEE_RATE_OFFSET = 720;
|
|
@@ -1655,7 +1901,7 @@ function decodeLaunchlabPlatformConfig(data) {
|
|
|
1655
1901
|
return {
|
|
1656
1902
|
platformFeeWallet: head.platformFeeWallet,
|
|
1657
1903
|
feeRate: head.feeRate,
|
|
1658
|
-
creatorFeeRate: u64$
|
|
1904
|
+
creatorFeeRate: u64$2.decode(data, PLATFORM_CREATOR_FEE_RATE_OFFSET),
|
|
1659
1905
|
cpswapConfig: addressAt.decode(data, PLATFORM_CPSWAP_CONFIG_OFFSET),
|
|
1660
1906
|
platformCpCreator: addressAt.decode(data, PLATFORM_CP_CREATOR_OFFSET)
|
|
1661
1907
|
};
|
|
@@ -1676,18 +1922,18 @@ const CPMM_POOL_HEAD = getStructDecoder([
|
|
|
1676
1922
|
["lpMintDecimals", u8],
|
|
1677
1923
|
["mint0Decimals", u8],
|
|
1678
1924
|
["mint1Decimals", u8],
|
|
1679
|
-
["lpSupply", u64$
|
|
1680
|
-
["protocolFeesToken0", u64$
|
|
1681
|
-
["protocolFeesToken1", u64$
|
|
1682
|
-
["fundFeesToken0", u64$
|
|
1683
|
-
["fundFeesToken1", u64$
|
|
1684
|
-
["openTime", u64$
|
|
1685
|
-
["recentEpoch", u64$
|
|
1925
|
+
["lpSupply", u64$2],
|
|
1926
|
+
["protocolFeesToken0", u64$2],
|
|
1927
|
+
["protocolFeesToken1", u64$2],
|
|
1928
|
+
["fundFeesToken0", u64$2],
|
|
1929
|
+
["fundFeesToken1", u64$2],
|
|
1930
|
+
["openTime", u64$2],
|
|
1931
|
+
["recentEpoch", u64$2],
|
|
1686
1932
|
["creatorFeeOn", u8],
|
|
1687
1933
|
["enableCreatorFee", bool],
|
|
1688
1934
|
["padding1", fixDecoderSize(getBytesDecoder(), 6)],
|
|
1689
|
-
["creatorFeesToken0", u64$
|
|
1690
|
-
["creatorFeesToken1", u64$
|
|
1935
|
+
["creatorFeesToken0", u64$2],
|
|
1936
|
+
["creatorFeesToken1", u64$2]
|
|
1691
1937
|
]);
|
|
1692
1938
|
const CPMM_POOL_STATE_HEAD_SIZE = 413;
|
|
1693
1939
|
/**
|
|
@@ -1715,12 +1961,14 @@ function decodeCpmmPool(data) {
|
|
|
1715
1961
|
poolCreator: head.poolCreator,
|
|
1716
1962
|
token0Vault: head.token0Vault,
|
|
1717
1963
|
token1Vault: head.token1Vault,
|
|
1964
|
+
lpMint: head.lpMint,
|
|
1718
1965
|
token0Mint: head.token0Mint,
|
|
1719
1966
|
token1Mint: head.token1Mint,
|
|
1720
1967
|
token0Program: head.token0Program,
|
|
1721
1968
|
token1Program: head.token1Program,
|
|
1722
1969
|
observationKey: head.observationKey,
|
|
1723
1970
|
status: head.status,
|
|
1971
|
+
lpSupply: head.lpSupply,
|
|
1724
1972
|
mint0Decimals: head.mint0Decimals,
|
|
1725
1973
|
mint1Decimals: head.mint1Decimals,
|
|
1726
1974
|
protocolFeesToken0: head.protocolFeesToken0,
|
|
@@ -1738,13 +1986,13 @@ const CPMM_AMM_CONFIG_HEAD = getStructDecoder([
|
|
|
1738
1986
|
["bump", u8],
|
|
1739
1987
|
["disableCreatePool", bool],
|
|
1740
1988
|
["index", u16],
|
|
1741
|
-
["tradeFeeRate", u64$
|
|
1742
|
-
["protocolFeeRate", u64$
|
|
1743
|
-
["fundFeeRate", u64$
|
|
1744
|
-
["createPoolFee", u64$
|
|
1989
|
+
["tradeFeeRate", u64$2],
|
|
1990
|
+
["protocolFeeRate", u64$2],
|
|
1991
|
+
["fundFeeRate", u64$2],
|
|
1992
|
+
["createPoolFee", u64$2],
|
|
1745
1993
|
["protocolOwner", addressAt],
|
|
1746
1994
|
["fundOwner", addressAt],
|
|
1747
|
-
["creatorFeeRate", u64$
|
|
1995
|
+
["creatorFeeRate", u64$2]
|
|
1748
1996
|
]);
|
|
1749
1997
|
const CPMM_AMM_CONFIG_HEAD_SIZE = 116;
|
|
1750
1998
|
function decodeCpmmAmmConfig(data) {
|
|
@@ -1760,12 +2008,48 @@ function decodeCpmmAmmConfig(data) {
|
|
|
1760
2008
|
creatorFeeRate: head.creatorFeeRate
|
|
1761
2009
|
};
|
|
1762
2010
|
}
|
|
2011
|
+
/** `sha256("account:LockedCpLiquidityState")[0..8]`. */
|
|
2012
|
+
const LOCKED_CP_LIQUIDITY_DISCRIMINATOR = new Uint8Array([
|
|
2013
|
+
25,
|
|
2014
|
+
10,
|
|
2015
|
+
238,
|
|
2016
|
+
197,
|
|
2017
|
+
207,
|
|
2018
|
+
234,
|
|
2019
|
+
73,
|
|
2020
|
+
22
|
|
2021
|
+
]);
|
|
2022
|
+
const LOCKED_CP_LIQUIDITY = getStructDecoder([
|
|
2023
|
+
["lockedLpAmount", u64$2],
|
|
2024
|
+
["claimedLpAmount", u64$2],
|
|
2025
|
+
["unclaimedLpAmount", u64$2],
|
|
2026
|
+
["lastLp", u64$2],
|
|
2027
|
+
["lastK", u128],
|
|
2028
|
+
["recentEpoch", u64$2],
|
|
2029
|
+
["poolId", addressAt],
|
|
2030
|
+
["feeNftMint", addressAt],
|
|
2031
|
+
["lockedOwner", addressAt],
|
|
2032
|
+
["lockedLpMint", addressAt]
|
|
2033
|
+
]);
|
|
2034
|
+
/** Six numbers and four addresses after the discriminator. The account itself is 256 bytes. */
|
|
2035
|
+
const LOCKED_CP_LIQUIDITY_HEAD_SIZE = 192;
|
|
2036
|
+
function decodeLockedCpLiquidity(data) {
|
|
2037
|
+
checked(data, LOCKED_CP_LIQUIDITY_DISCRIMINATOR, "locked liquidity record");
|
|
2038
|
+
atLeast(data, 192, "locked liquidity record");
|
|
2039
|
+
return LOCKED_CP_LIQUIDITY.decode(data, DISCRIMINATOR$1);
|
|
2040
|
+
}
|
|
1763
2041
|
//#endregion
|
|
1764
2042
|
//#region src/accounts.ts
|
|
1765
2043
|
/** Account readers and bounded discovery scans. Old pool layouts are intentionally unsupported. */
|
|
1766
2044
|
const DISCRIMINATOR = 8;
|
|
1767
2045
|
const DRAW_POOL_OFFSET = DISCRIMINATOR;
|
|
1768
2046
|
const DRAW_PURCHASER_OFFSET = 40;
|
|
2047
|
+
/**
|
|
2048
|
+
* The `settled` byte: after pool, purchaser, nonce, bump, seq_start, count, two slots, attempts,
|
|
2049
|
+
* eight tiers, pack_tokens, free_snapshot and reserved. `test/surface.test.ts` pins it against the
|
|
2050
|
+
* generated encoder.
|
|
2051
|
+
*/
|
|
2052
|
+
const DRAW_SETTLED_OFFSET = 195;
|
|
1769
2053
|
const POOL_CREATOR_OFFSET = DISCRIMINATOR;
|
|
1770
2054
|
const POOL_MINT_OFFSET = 40;
|
|
1771
2055
|
const base58 = getBase58Decoder();
|
|
@@ -1811,7 +2095,7 @@ function decodeCurrentWalletActivity(account) {
|
|
|
1811
2095
|
}
|
|
1812
2096
|
/**
|
|
1813
2097
|
* A wallet's lifetime pack-buying activity, or `null` before it has bought its first pack.
|
|
1814
|
-
* `
|
|
2098
|
+
* `buy_packs` creates this account `init_if_needed`, so a fresh wallet has none yet.
|
|
1815
2099
|
*/
|
|
1816
2100
|
async function fetchWalletActivity(client, wallet) {
|
|
1817
2101
|
return decodeCurrentWalletActivity(await fetchEncodedAccount(client.rpc, await activityAddress(wallet), { commitment: "confirmed" }));
|
|
@@ -1840,6 +2124,23 @@ async function listDraws(client, query = {}) {
|
|
|
1840
2124
|
}
|
|
1841
2125
|
const listDrawsByPool = async (client, pool) => await listDraws(client, { pool });
|
|
1842
2126
|
const listDrawsByPurchaser = async (client, purchaser) => await listDraws(client, { purchaser });
|
|
2127
|
+
/**
|
|
2128
|
+
* A purchaser's draws that settled without paying: the callback could not use the purchaser's coin
|
|
2129
|
+
* account, so the tokens wait in the vault as `owed` until `claimPrize` or `claimPrizeTo` pays
|
|
2130
|
+
* them. A pending draw is not in this list, and a paid one no longer exists.
|
|
2131
|
+
*/
|
|
2132
|
+
async function fetchOwedDraws(client, purchaser) {
|
|
2133
|
+
const filters = [
|
|
2134
|
+
memcmp$1(0, asBase58(DRAW_DISCRIMINATOR)),
|
|
2135
|
+
{ dataSize: BigInt(getDrawSize()) },
|
|
2136
|
+
memcmp$1(40, purchaser),
|
|
2137
|
+
memcmp$1(195, asBase58(new Uint8Array([1])))
|
|
2138
|
+
];
|
|
2139
|
+
return (await scan(client.rpc, filters, (address, data) => ({
|
|
2140
|
+
address,
|
|
2141
|
+
data: decodeDraw(encoded(address, data)).data
|
|
2142
|
+
}))).filter((row) => row.data.settled && row.data.owed > 0n);
|
|
2143
|
+
}
|
|
1843
2144
|
async function fetchVaultBalance(client, mint) {
|
|
1844
2145
|
const vault = await vaultAddress(mint);
|
|
1845
2146
|
const { value } = await client.rpc.getAccountInfo(vault, {
|
|
@@ -1923,9 +2224,18 @@ const CREATE_MACHINE_COMPUTE_UNITS = 35e4;
|
|
|
1923
2224
|
* Measured at `178,690`, `163,686` and `157,692` on the curve, and `113,891`, `110,922` and
|
|
1924
2225
|
* `106,387` on CPMM. The curve buy is dearer because a coin's first trade also creates the platform
|
|
1925
2226
|
* and creator fee vaults.
|
|
2227
|
+
*
|
|
2228
|
+
* One figure for every `count` from 1 to `MAX_BATCH_SIZE`: a purchase of five packs is still one
|
|
2229
|
+
* trade, one draw and one request. The per-pack work runs in the oracle's callback, on the oracle's
|
|
2230
|
+
* own budget. The devnet end-to-end test re-measures count 1 and 5.
|
|
1926
2231
|
*/
|
|
1927
2232
|
const BUY_PACK_COMPUTE_UNITS = 235e3;
|
|
1928
2233
|
/**
|
|
2234
|
+
* `claim_prize`: create the purchaser's ATA when it is missing, one transfer, close the draw. An
|
|
2235
|
+
* estimate until the devnet run measures it; a caller may override it.
|
|
2236
|
+
*/
|
|
2237
|
+
const CLAIM_PRIZE_COMPUTE_UNITS = 8e4;
|
|
2238
|
+
/**
|
|
1929
2239
|
* A WSOL wrap, a venue sale, and the WSOL close. Measured at `94,246`, `86,745` and `88,246` on the
|
|
1930
2240
|
* curve, and `61,545`, `55,576` and `57,046` on CPMM.
|
|
1931
2241
|
*/
|
|
@@ -1936,6 +2246,15 @@ const REDEEM_COMPUTE_UNITS = 125e3;
|
|
|
1936
2246
|
* on a pool quoted in another token is cheaper, `17,635`, because nothing has to be unwrapped.
|
|
1937
2247
|
*/
|
|
1938
2248
|
const CLAIM_COMPUTE_UNITS = 55e3;
|
|
2249
|
+
/**
|
|
2250
|
+
* A harvest of one locked CPMM position: `collect_cp_fees` on the lock program, which withdraws
|
|
2251
|
+
* LP through CPMM and pays both sides out.
|
|
2252
|
+
*
|
|
2253
|
+
* Measured at `102,221` on devnet on 2026-09-19 (tx `5s7xvy23…`), with both token accounts
|
|
2254
|
+
* created in the same transaction and the WSOL one closed again. `82,697` of that is the lock
|
|
2255
|
+
* program itself.
|
|
2256
|
+
*/
|
|
2257
|
+
const HARVEST_COMPUTE_UNITS = 15e4;
|
|
1939
2258
|
/** `ComputeBudgetInstruction`'s discriminants. Positional and append-only upstream. */
|
|
1940
2259
|
const SET_COMPUTE_UNIT_LIMIT = 2;
|
|
1941
2260
|
const SET_COMPUTE_UNIT_PRICE = 3;
|
|
@@ -2894,7 +3213,7 @@ async function getLaunchInstruction(input, ids) {
|
|
|
2894
3213
|
* WSOL into SOL, so it only belongs on a WSOL claim: closing a USDC account would throw the payout
|
|
2895
3214
|
* away.
|
|
2896
3215
|
*/
|
|
2897
|
-
async function wrapAround(creator, quote, middle) {
|
|
3216
|
+
async function wrapAround$1(creator, quote, middle) {
|
|
2898
3217
|
const account = await ata(creator.address, quote.mint, quote.tokenProgram);
|
|
2899
3218
|
const create = getCreateAssociatedTokenIdempotentInstruction({
|
|
2900
3219
|
payer: creator,
|
|
@@ -2915,7 +3234,7 @@ async function wrapAround(creator, quote, middle) {
|
|
|
2915
3234
|
];
|
|
2916
3235
|
}
|
|
2917
3236
|
/** Attach a signer to the one slot the ABI marks as signing. Roles never change here. */
|
|
2918
|
-
function withSigner(accounts, signer) {
|
|
3237
|
+
function withSigner$1(accounts, signer) {
|
|
2919
3238
|
return accounts.map((meta) => (meta.role === AccountRole.READONLY_SIGNER || meta.role === AccountRole.WRITABLE_SIGNER) && meta.address === signer.address ? {
|
|
2920
3239
|
...meta,
|
|
2921
3240
|
signer
|
|
@@ -2930,9 +3249,9 @@ function withSigner(accounts, signer) {
|
|
|
2930
3249
|
* two quote assets claims once per asset.
|
|
2931
3250
|
*/
|
|
2932
3251
|
async function getClaimCreatorFeeInstructions(creator, ids, quote) {
|
|
2933
|
-
return await wrapAround(creator, quote, [{
|
|
3252
|
+
return await wrapAround$1(creator, quote, [{
|
|
2934
3253
|
programAddress: ids.launchlab,
|
|
2935
|
-
accounts: withSigner(order(LAUNCHLAB_CLAIM_CREATOR_FEE, {
|
|
3254
|
+
accounts: withSigner$1(order(LAUNCHLAB_CLAIM_CREATOR_FEE, {
|
|
2936
3255
|
creator: creator.address,
|
|
2937
3256
|
fee_vault_authority: await creatorFeeVaultAuthority(ids.launchlab),
|
|
2938
3257
|
creator_fee_vault: await creatorFeeVaultAddress(ids.launchlab, creator.address, quote.mint),
|
|
@@ -2953,7 +3272,7 @@ async function getClaimCreatorFeeInstructions(creator, ids, quote) {
|
|
|
2953
3272
|
*/
|
|
2954
3273
|
async function claimCreatorFee(client, input) {
|
|
2955
3274
|
const ids = raydiumIds(client.cluster);
|
|
2956
|
-
const quote = await quoteOf(client, input.quoteMint ?? "So11111111111111111111111111111111111111112");
|
|
3275
|
+
const quote = await quoteOf$1(client, input.quoteMint ?? "So11111111111111111111111111111111111111112");
|
|
2957
3276
|
const instructions = await getClaimCreatorFeeInstructions(input.creator, ids, quote);
|
|
2958
3277
|
return await buildMessage(client, input.creator, instructions, {
|
|
2959
3278
|
addressLookupTables: input.addressLookupTables,
|
|
@@ -2965,7 +3284,7 @@ async function claimCreatorFee(client, input) {
|
|
|
2965
3284
|
* The token program a quote mint lives under. WSOL is always classic SPL Token, so that one needs
|
|
2966
3285
|
* no read at all.
|
|
2967
3286
|
*/
|
|
2968
|
-
async function quoteOf(client, mint) {
|
|
3287
|
+
async function quoteOf$1(client, mint) {
|
|
2969
3288
|
if (mint === "So11111111111111111111111111111111111111112") return {
|
|
2970
3289
|
mint,
|
|
2971
3290
|
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
@@ -2996,7 +3315,7 @@ async function getCollectCreatorFeeInstructions(client, input, ids = raydiumIds(
|
|
|
2996
3315
|
});
|
|
2997
3316
|
const collect = {
|
|
2998
3317
|
programAddress: ids.cpmm,
|
|
2999
|
-
accounts: withSigner(order(CPMM_COLLECT_CREATOR_FEE, {
|
|
3318
|
+
accounts: withSigner$1(order(CPMM_COLLECT_CREATOR_FEE, {
|
|
3000
3319
|
creator: creator.address,
|
|
3001
3320
|
authority: ids.cpmmAuthority,
|
|
3002
3321
|
pool_state: poolState,
|
|
@@ -3015,7 +3334,7 @@ async function getCollectCreatorFeeInstructions(client, input, ids = raydiumIds(
|
|
|
3015
3334
|
}), creator),
|
|
3016
3335
|
data: new Uint8Array(CPMM_COLLECT_CREATOR_FEE.discriminator)
|
|
3017
3336
|
};
|
|
3018
|
-
return await wrapAround(creator, {
|
|
3337
|
+
return await wrapAround$1(creator, {
|
|
3019
3338
|
mint: quote.mint,
|
|
3020
3339
|
tokenProgram: quote.tokenProgram
|
|
3021
3340
|
}, [collect]);
|
|
@@ -3086,6 +3405,400 @@ async function fetchCreatorFees(client, input) {
|
|
|
3086
3405
|
}
|
|
3087
3406
|
}
|
|
3088
3407
|
//#endregion
|
|
3408
|
+
//#region src/raydium/platform.ts
|
|
3409
|
+
/**
|
|
3410
|
+
* Collecting the platform's share of trading.
|
|
3411
|
+
*
|
|
3412
|
+
* Gabox charges no fee of its own. The platform's income is the share Raydium pays out of its own
|
|
3413
|
+
* revenue, and it sits in two different places depending on where a coin trades:
|
|
3414
|
+
*
|
|
3415
|
+
* - **On the curve.** LaunchLab pays 0.5% of every trade into `[platform_config, quote_mint]`
|
|
3416
|
+
* under LaunchLab. One vault per quote asset for the whole platform, not one per coin, so a
|
|
3417
|
+
* single `claim_platform_fee_from_vault` sweeps every coin on that quote. Only the wallet the
|
|
3418
|
+
* platform config names as `platform_fee_wallet` can sign it.
|
|
3419
|
+
* - **After graduation.** LaunchLab moves the whole pool into a CPMM pool and locks 100% of the
|
|
3420
|
+
* LP under Raydium's lock program. The lock mints one fee NFT to the platform NFT wallet. The
|
|
3421
|
+
* LP earns the pool's trade fee, and `collect_cp_fees` on the lock program pays the NFT holder
|
|
3422
|
+
* that growth. One position per graduated coin, so it takes one call per coin.
|
|
3423
|
+
*
|
|
3424
|
+
* Both flows pay into the signer's associated token account. When a side is WSOL, the builders
|
|
3425
|
+
* close that account afterwards, so the wallet ends up with plain SOL. Any other token is created if
|
|
3426
|
+
* missing and left alone, because closing it would throw away a real balance.
|
|
3427
|
+
*
|
|
3428
|
+
* **Closing unwraps everything.** If the wallet already held WSOL in that account, closing turns it
|
|
3429
|
+
* into SOL too. Nothing is lost, but the balance moves.
|
|
3430
|
+
*/
|
|
3431
|
+
const u64$1 = getU64Encoder();
|
|
3432
|
+
/**
|
|
3433
|
+
* Create the signer's token account for one mint, if it is missing, and close it again when the
|
|
3434
|
+
* mint is WSOL. The close is what turns WSOL into SOL, so it only belongs on a WSOL side.
|
|
3435
|
+
*/
|
|
3436
|
+
async function wrapAround(signer, sides, middle) {
|
|
3437
|
+
const before = [];
|
|
3438
|
+
const after = [];
|
|
3439
|
+
for (const side of sides) {
|
|
3440
|
+
const account = await ata(signer.address, side.mint, side.tokenProgram);
|
|
3441
|
+
before.push(getCreateAssociatedTokenIdempotentInstruction({
|
|
3442
|
+
payer: signer,
|
|
3443
|
+
ata: account,
|
|
3444
|
+
owner: signer.address,
|
|
3445
|
+
mint: side.mint,
|
|
3446
|
+
tokenProgram: side.tokenProgram
|
|
3447
|
+
}));
|
|
3448
|
+
if (side.mint === "So11111111111111111111111111111111111111112") after.push(getCloseAccountInstruction({
|
|
3449
|
+
account,
|
|
3450
|
+
destination: signer.address,
|
|
3451
|
+
owner: signer
|
|
3452
|
+
}));
|
|
3453
|
+
}
|
|
3454
|
+
return [
|
|
3455
|
+
...before,
|
|
3456
|
+
...middle,
|
|
3457
|
+
...after
|
|
3458
|
+
];
|
|
3459
|
+
}
|
|
3460
|
+
/** Attach a signer to the one slot the ABI marks as signing. Roles never change here. */
|
|
3461
|
+
function withSigner(accounts, signer) {
|
|
3462
|
+
return accounts.map((meta) => (meta.role === AccountRole.READONLY_SIGNER || meta.role === AccountRole.WRITABLE_SIGNER) && meta.address === signer.address ? {
|
|
3463
|
+
...meta,
|
|
3464
|
+
signer
|
|
3465
|
+
} : meta);
|
|
3466
|
+
}
|
|
3467
|
+
/**
|
|
3468
|
+
* The token program a quote mint lives under. WSOL is always classic SPL Token, so that one needs
|
|
3469
|
+
* no read at all.
|
|
3470
|
+
*/
|
|
3471
|
+
async function quoteOf(client, mint) {
|
|
3472
|
+
if (mint === "So11111111111111111111111111111111111111112") return {
|
|
3473
|
+
mint,
|
|
3474
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
3475
|
+
};
|
|
3476
|
+
return {
|
|
3477
|
+
mint,
|
|
3478
|
+
tokenProgram: (await fetchQuoteDisplay(client, mint)).tokenProgram
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
/**
|
|
3482
|
+
* The instructions of a platform fee claim, for one quote asset: create the quote account, claim,
|
|
3483
|
+
* and close it again when the quote is WSOL.
|
|
3484
|
+
*
|
|
3485
|
+
* This sweeps **every** coin launched against that quote, because LaunchLab keeps one platform
|
|
3486
|
+
* vault per quote asset. `feeWallet` must be the wallet the platform config names, or LaunchLab
|
|
3487
|
+
* refuses the claim.
|
|
3488
|
+
*/
|
|
3489
|
+
async function getClaimPlatformFeeInstructions(feeWallet, ids, quote) {
|
|
3490
|
+
const claim = {
|
|
3491
|
+
programAddress: ids.launchlab,
|
|
3492
|
+
accounts: withSigner(order(LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT, {
|
|
3493
|
+
platform_fee_wallet: feeWallet.address,
|
|
3494
|
+
fee_vault_authority: await platformFeeVaultAuthority(ids.launchlab),
|
|
3495
|
+
platform_config: ids.gaboxPlatform,
|
|
3496
|
+
platform_fee_vault: await platformFeeVaultAddress(ids.launchlab, ids.gaboxPlatform, quote.mint),
|
|
3497
|
+
recipient_token_account: await ata(feeWallet.address, quote.mint, quote.tokenProgram),
|
|
3498
|
+
quote_mint: quote.mint,
|
|
3499
|
+
token_program: quote.tokenProgram,
|
|
3500
|
+
system_program: SYSTEM_PROGRAM_ADDRESS,
|
|
3501
|
+
associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ADDRESS
|
|
3502
|
+
}), feeWallet),
|
|
3503
|
+
data: new Uint8Array(LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT.discriminator)
|
|
3504
|
+
};
|
|
3505
|
+
return await wrapAround(feeWallet, [quote], [claim]);
|
|
3506
|
+
}
|
|
3507
|
+
/**
|
|
3508
|
+
* Claim the curve platform fee for one quote asset.
|
|
3509
|
+
*
|
|
3510
|
+
* A WSOL claim arrives as SOL, because the builder closes the WSOL account. Any other quote arrives
|
|
3511
|
+
* as that token, in the fee wallet's own account.
|
|
3512
|
+
*/
|
|
3513
|
+
async function claimPlatformFee(client, input) {
|
|
3514
|
+
const ids = raydiumIds(client.cluster);
|
|
3515
|
+
const quote = await quoteOf(client, input.quoteMint ?? "So11111111111111111111111111111111111111112");
|
|
3516
|
+
const instructions = await getClaimPlatformFeeInstructions(input.feeWallet, ids, quote);
|
|
3517
|
+
return await buildMessage(client, input.feeWallet, instructions, {
|
|
3518
|
+
addressLookupTables: input.addressLookupTables,
|
|
3519
|
+
computeUnitLimit: input.computeUnitLimit ?? 55e3,
|
|
3520
|
+
...input.computeUnitPrice === void 0 ? {} : { computeUnitPrice: input.computeUnitPrice }
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3523
|
+
/**
|
|
3524
|
+
* What the platform can claim from the curve right now, for one quote asset, in base units.
|
|
3525
|
+
*
|
|
3526
|
+
* `quoteMint` defaults to wrapped SOL. One vault per quote asset, so a platform with coins on two
|
|
3527
|
+
* quotes reads this twice. A vault that does not exist yet reads as zero.
|
|
3528
|
+
*/
|
|
3529
|
+
async function fetchPlatformFees(client, input = {}) {
|
|
3530
|
+
const ids = raydiumIds(client.cluster);
|
|
3531
|
+
const quoteMint = input.quoteMint ?? "So11111111111111111111111111111111111111112";
|
|
3532
|
+
const vault = await platformFeeVaultAddress(ids.launchlab, ids.gaboxPlatform, quoteMint);
|
|
3533
|
+
const [account] = await readAccounts(client.rpc, [vault]);
|
|
3534
|
+
return {
|
|
3535
|
+
quoteMint,
|
|
3536
|
+
curveQuote: account ? tokenAccountAmount(account.data) : 0n
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3539
|
+
/**
|
|
3540
|
+
* `collect_cp_fees` on the lock program. There is no public IDL for it. The account list and the
|
|
3541
|
+
* discriminator come from Raydium's own SDK and from the `pinocchio-raydium-locking-program`
|
|
3542
|
+
* client crate, and the devnet harvest in `test/devnet.e2e.test.ts` runs it.
|
|
3543
|
+
*/
|
|
3544
|
+
const LOCK_COLLECT_CP_FEES = {
|
|
3545
|
+
name: "collect_cp_fees",
|
|
3546
|
+
discriminator: new Uint8Array([
|
|
3547
|
+
8,
|
|
3548
|
+
30,
|
|
3549
|
+
51,
|
|
3550
|
+
199,
|
|
3551
|
+
209,
|
|
3552
|
+
184,
|
|
3553
|
+
247,
|
|
3554
|
+
133
|
|
3555
|
+
]),
|
|
3556
|
+
accounts: [
|
|
3557
|
+
{
|
|
3558
|
+
name: "authority",
|
|
3559
|
+
writable: false,
|
|
3560
|
+
signer: false
|
|
3561
|
+
},
|
|
3562
|
+
{
|
|
3563
|
+
name: "fee_nft_owner",
|
|
3564
|
+
writable: false,
|
|
3565
|
+
signer: true
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
name: "fee_nft_account",
|
|
3569
|
+
writable: false,
|
|
3570
|
+
signer: false
|
|
3571
|
+
},
|
|
3572
|
+
{
|
|
3573
|
+
name: "locked_liquidity",
|
|
3574
|
+
writable: true,
|
|
3575
|
+
signer: false
|
|
3576
|
+
},
|
|
3577
|
+
{
|
|
3578
|
+
name: "cpmm_program",
|
|
3579
|
+
writable: false,
|
|
3580
|
+
signer: false
|
|
3581
|
+
},
|
|
3582
|
+
{
|
|
3583
|
+
name: "cp_authority",
|
|
3584
|
+
writable: false,
|
|
3585
|
+
signer: false
|
|
3586
|
+
},
|
|
3587
|
+
{
|
|
3588
|
+
name: "pool_state",
|
|
3589
|
+
writable: true,
|
|
3590
|
+
signer: false
|
|
3591
|
+
},
|
|
3592
|
+
{
|
|
3593
|
+
name: "lp_mint",
|
|
3594
|
+
writable: true,
|
|
3595
|
+
signer: false
|
|
3596
|
+
},
|
|
3597
|
+
{
|
|
3598
|
+
name: "recipient_token_0_account",
|
|
3599
|
+
writable: true,
|
|
3600
|
+
signer: false
|
|
3601
|
+
},
|
|
3602
|
+
{
|
|
3603
|
+
name: "recipient_token_1_account",
|
|
3604
|
+
writable: true,
|
|
3605
|
+
signer: false
|
|
3606
|
+
},
|
|
3607
|
+
{
|
|
3608
|
+
name: "token_0_vault",
|
|
3609
|
+
writable: true,
|
|
3610
|
+
signer: false
|
|
3611
|
+
},
|
|
3612
|
+
{
|
|
3613
|
+
name: "token_1_vault",
|
|
3614
|
+
writable: true,
|
|
3615
|
+
signer: false
|
|
3616
|
+
},
|
|
3617
|
+
{
|
|
3618
|
+
name: "vault_0_mint",
|
|
3619
|
+
writable: false,
|
|
3620
|
+
signer: false
|
|
3621
|
+
},
|
|
3622
|
+
{
|
|
3623
|
+
name: "vault_1_mint",
|
|
3624
|
+
writable: false,
|
|
3625
|
+
signer: false
|
|
3626
|
+
},
|
|
3627
|
+
{
|
|
3628
|
+
name: "locked_lp_vault",
|
|
3629
|
+
writable: true,
|
|
3630
|
+
signer: false
|
|
3631
|
+
},
|
|
3632
|
+
{
|
|
3633
|
+
name: "token_program",
|
|
3634
|
+
writable: false,
|
|
3635
|
+
signer: false
|
|
3636
|
+
},
|
|
3637
|
+
{
|
|
3638
|
+
name: "token_program_2022",
|
|
3639
|
+
writable: false,
|
|
3640
|
+
signer: false
|
|
3641
|
+
},
|
|
3642
|
+
{
|
|
3643
|
+
name: "memo_program",
|
|
3644
|
+
writable: false,
|
|
3645
|
+
signer: false
|
|
3646
|
+
}
|
|
3647
|
+
]
|
|
3648
|
+
};
|
|
3649
|
+
/** Integer square root, rounded down. */
|
|
3650
|
+
function isqrt(value) {
|
|
3651
|
+
if (value < 0n) throw new Error("isqrt of a negative number");
|
|
3652
|
+
if (value < 2n) return value;
|
|
3653
|
+
let x = BigInt(Math.floor(Math.sqrt(Number(value))));
|
|
3654
|
+
for (;;) {
|
|
3655
|
+
const y = x + value / x >> 1n;
|
|
3656
|
+
if (y >= x) break;
|
|
3657
|
+
x = y;
|
|
3658
|
+
}
|
|
3659
|
+
while (x * x > value) x -= 1n;
|
|
3660
|
+
while ((x + 1n) * (x + 1n) <= value) x += 1n;
|
|
3661
|
+
return x;
|
|
3662
|
+
}
|
|
3663
|
+
/**
|
|
3664
|
+
* The LP tokens a locked position may withdraw as fees.
|
|
3665
|
+
*
|
|
3666
|
+
* Every swap leaves its fee in the vaults, so one LP token buys a little more of the pool after
|
|
3667
|
+
* each trade than before it. The record keeps the pool's `x * y` and LP supply from its last
|
|
3668
|
+
* checkpoint. The LP tokens that still hold exactly the checkpoint's liquidity are
|
|
3669
|
+
* `locked * sqrt(last_k) / last_lp * supply / sqrt(k)`; everything above that is fee growth.
|
|
3670
|
+
*
|
|
3671
|
+
* The division rounds the kept part up, so the answer never claims a unit the pool does not owe.
|
|
3672
|
+
*/
|
|
3673
|
+
function lockedFeeLp(lock, pool) {
|
|
3674
|
+
if (lock.lockedLpAmount === 0n || lock.lastLp === 0n || pool.lpSupply === 0n) return 0n;
|
|
3675
|
+
const rootNow = isqrt(pool.vault0 * pool.vault1);
|
|
3676
|
+
if (rootNow === 0n) return 0n;
|
|
3677
|
+
const numerator = lock.lockedLpAmount * isqrt(lock.lastK) * pool.lpSupply;
|
|
3678
|
+
const denominator = lock.lastLp * rootNow;
|
|
3679
|
+
const keep = (numerator + denominator - 1n) / denominator;
|
|
3680
|
+
return keep >= lock.lockedLpAmount ? 0n : lock.lockedLpAmount - keep;
|
|
3681
|
+
}
|
|
3682
|
+
/**
|
|
3683
|
+
* Every locked CPMM position `owner` holds a fee NFT for, with what each one can harvest.
|
|
3684
|
+
*
|
|
3685
|
+
* Three reads: the wallet's token accounts, then the lock record behind every NFT-shaped one, then
|
|
3686
|
+
* the pool and the two vaults of every record found. A token account of one unit and zero decimals
|
|
3687
|
+
* is not always a lock NFT, so the record decides: no record, not a position.
|
|
3688
|
+
*/
|
|
3689
|
+
async function fetchLockedPositions(client, owner, ids = raydiumIds(client.cluster)) {
|
|
3690
|
+
const { value: accounts } = await client.rpc.getTokenAccountsByOwner(owner, { programId: TOKEN_PROGRAM_ADDRESS }, {
|
|
3691
|
+
encoding: "jsonParsed",
|
|
3692
|
+
commitment: "confirmed"
|
|
3693
|
+
}).send();
|
|
3694
|
+
const nftMints = [];
|
|
3695
|
+
for (const { account } of accounts) {
|
|
3696
|
+
const info = account.data.parsed.info;
|
|
3697
|
+
if (info.tokenAmount.decimals === 0 && info.tokenAmount.amount === "1") nftMints.push(info.mint);
|
|
3698
|
+
}
|
|
3699
|
+
if (nftMints.length === 0) return [];
|
|
3700
|
+
const records = await Promise.all(nftMints.map((mint) => lockedLiquidityAddress(ids.lock, mint)));
|
|
3701
|
+
const found = [];
|
|
3702
|
+
for (const [index, account] of (await readAccounts(client.rpc, records)).entries()) {
|
|
3703
|
+
if (!account || account.owner !== ids.lock) continue;
|
|
3704
|
+
const lock = decodeLockedCpLiquidity(account.data);
|
|
3705
|
+
if (lock.feeNftMint !== nftMints[index]) continue;
|
|
3706
|
+
found.push({
|
|
3707
|
+
feeNftMint: nftMints[index],
|
|
3708
|
+
record: records[index],
|
|
3709
|
+
lock
|
|
3710
|
+
});
|
|
3711
|
+
}
|
|
3712
|
+
if (found.length === 0) return [];
|
|
3713
|
+
const decoded = (await readAccounts(client.rpc, found.map((entry) => entry.lock.poolId))).map((account) => account && account.owner === ids.cpmm ? decodeCpmmPool(account.data) : null);
|
|
3714
|
+
const vaults = await readAccounts(client.rpc, decoded.flatMap((pool) => pool ? [pool.token0Vault, pool.token1Vault] : []));
|
|
3715
|
+
const positions = [];
|
|
3716
|
+
let cursor = 0;
|
|
3717
|
+
for (const [index, entry] of found.entries()) {
|
|
3718
|
+
const pool = decoded[index];
|
|
3719
|
+
if (!pool) continue;
|
|
3720
|
+
const raw0 = vaults[cursor];
|
|
3721
|
+
const raw1 = vaults[cursor + 1];
|
|
3722
|
+
cursor += 2;
|
|
3723
|
+
if (!raw0 || !raw1 || pool.lpMint !== entry.lock.lockedLpMint) continue;
|
|
3724
|
+
const vault0 = tokenAccountAmount(raw0.data) - pool.protocolFeesToken0 - pool.fundFeesToken0 - pool.creatorFeesToken0;
|
|
3725
|
+
const vault1 = tokenAccountAmount(raw1.data) - pool.protocolFeesToken1 - pool.fundFeesToken1 - pool.creatorFeesToken1;
|
|
3726
|
+
const claimableLp = lockedFeeLp(entry.lock, {
|
|
3727
|
+
vault0,
|
|
3728
|
+
vault1,
|
|
3729
|
+
lpSupply: pool.lpSupply
|
|
3730
|
+
});
|
|
3731
|
+
positions.push({
|
|
3732
|
+
...entry,
|
|
3733
|
+
poolAddress: entry.lock.poolId,
|
|
3734
|
+
pool,
|
|
3735
|
+
vault0,
|
|
3736
|
+
vault1,
|
|
3737
|
+
claimableLp,
|
|
3738
|
+
claimableToken0: pool.lpSupply === 0n ? 0n : claimableLp * vault0 / pool.lpSupply,
|
|
3739
|
+
claimableToken1: pool.lpSupply === 0n ? 0n : claimableLp * vault1 / pool.lpSupply
|
|
3740
|
+
});
|
|
3741
|
+
}
|
|
3742
|
+
return positions;
|
|
3743
|
+
}
|
|
3744
|
+
/**
|
|
3745
|
+
* The instructions of one harvest: create the two token accounts, collect, and close the WSOL one
|
|
3746
|
+
* when a side is WSOL.
|
|
3747
|
+
*
|
|
3748
|
+
* `feeLp` defaults to everything the position can withdraw now. The lock program refuses more than
|
|
3749
|
+
* that, so a caller that passes its own number keeps it at or below `position.claimableLp`.
|
|
3750
|
+
*/
|
|
3751
|
+
async function getHarvestLockedFeesInstructions(owner, ids, position, feeLp = position.claimableLp) {
|
|
3752
|
+
if (feeLp <= 0n) throw new Error("nothing to harvest: the position has earned no fee LP yet");
|
|
3753
|
+
const { pool } = position;
|
|
3754
|
+
const collect = {
|
|
3755
|
+
programAddress: ids.lock,
|
|
3756
|
+
accounts: withSigner(order(LOCK_COLLECT_CP_FEES, {
|
|
3757
|
+
authority: ids.lockAuthority,
|
|
3758
|
+
fee_nft_owner: owner.address,
|
|
3759
|
+
fee_nft_account: await ata(owner.address, position.feeNftMint, TOKEN_PROGRAM_ADDRESS),
|
|
3760
|
+
locked_liquidity: position.record,
|
|
3761
|
+
cpmm_program: ids.cpmm,
|
|
3762
|
+
cp_authority: ids.cpmmAuthority,
|
|
3763
|
+
pool_state: position.poolAddress,
|
|
3764
|
+
lp_mint: pool.lpMint,
|
|
3765
|
+
recipient_token_0_account: await ata(owner.address, pool.token0Mint, pool.token0Program),
|
|
3766
|
+
recipient_token_1_account: await ata(owner.address, pool.token1Mint, pool.token1Program),
|
|
3767
|
+
token_0_vault: pool.token0Vault,
|
|
3768
|
+
token_1_vault: pool.token1Vault,
|
|
3769
|
+
vault_0_mint: pool.token0Mint,
|
|
3770
|
+
vault_1_mint: pool.token1Mint,
|
|
3771
|
+
locked_lp_vault: await ata(ids.lockAuthority, pool.lpMint, TOKEN_PROGRAM_ADDRESS),
|
|
3772
|
+
token_program: TOKEN_PROGRAM_ADDRESS,
|
|
3773
|
+
token_program_2022: TOKEN_2022_PROGRAM_ADDRESS,
|
|
3774
|
+
memo_program: MEMO_PROGRAM_ADDRESS
|
|
3775
|
+
}), owner),
|
|
3776
|
+
data: new Uint8Array([...LOCK_COLLECT_CP_FEES.discriminator, ...u64$1.encode(feeLp)])
|
|
3777
|
+
};
|
|
3778
|
+
return await wrapAround(owner, [{
|
|
3779
|
+
mint: pool.token0Mint,
|
|
3780
|
+
tokenProgram: pool.token0Program
|
|
3781
|
+
}, {
|
|
3782
|
+
mint: pool.token1Mint,
|
|
3783
|
+
tokenProgram: pool.token1Program
|
|
3784
|
+
}], [collect]);
|
|
3785
|
+
}
|
|
3786
|
+
/**
|
|
3787
|
+
* Harvest one locked position's fees.
|
|
3788
|
+
*
|
|
3789
|
+
* A pool with WSOL on one side pays that side out as SOL, because the builder closes the WSOL
|
|
3790
|
+
* account. The other side arrives as that token, in the owner's own account.
|
|
3791
|
+
*/
|
|
3792
|
+
async function harvestLockedFees(client, input) {
|
|
3793
|
+
const ids = raydiumIds(client.cluster);
|
|
3794
|
+
const instructions = await getHarvestLockedFeesInstructions(input.owner, ids, input.position, input.feeLp);
|
|
3795
|
+
return await buildMessage(client, input.owner, instructions, {
|
|
3796
|
+
addressLookupTables: input.addressLookupTables,
|
|
3797
|
+
computeUnitLimit: input.computeUnitLimit ?? 15e4,
|
|
3798
|
+
...input.computeUnitPrice === void 0 ? {} : { computeUnitPrice: input.computeUnitPrice }
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3801
|
+
//#endregion
|
|
3089
3802
|
//#region src/raydium/trade.ts
|
|
3090
3803
|
/**
|
|
3091
3804
|
* A venue trade a wallet sends on its own, outside any Gabox instruction.
|
|
@@ -3176,6 +3889,7 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3176
3889
|
LAUNCHLAB_BUY_EXACT_IN: () => LAUNCHLAB_BUY_EXACT_IN,
|
|
3177
3890
|
LAUNCHLAB_BUY_EXACT_OUT: () => LAUNCHLAB_BUY_EXACT_OUT,
|
|
3178
3891
|
LAUNCHLAB_CLAIM_CREATOR_FEE: () => LAUNCHLAB_CLAIM_CREATOR_FEE,
|
|
3892
|
+
LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT: () => LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT,
|
|
3179
3893
|
LAUNCHLAB_GLOBAL_CONFIG_DISCRIMINATOR: () => LAUNCHLAB_GLOBAL_CONFIG_DISCRIMINATOR,
|
|
3180
3894
|
LAUNCHLAB_GLOBAL_CONFIG_HEAD_SIZE: () => 115,
|
|
3181
3895
|
LAUNCHLAB_INITIALIZE: () => LAUNCHLAB_INITIALIZE,
|
|
@@ -3191,6 +3905,11 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3191
3905
|
LAUNCH_DECIMALS: () => 6,
|
|
3192
3906
|
LAUNCH_SUPPLY: () => LAUNCH_SUPPLY,
|
|
3193
3907
|
LAUNCH_TOTAL_BASE_SELL: () => LAUNCH_TOTAL_BASE_SELL,
|
|
3908
|
+
LOCKED_CP_LIQUIDITY_DISCRIMINATOR: () => LOCKED_CP_LIQUIDITY_DISCRIMINATOR,
|
|
3909
|
+
LOCKED_CP_LIQUIDITY_HEAD_SIZE: () => 192,
|
|
3910
|
+
LOCK_COLLECT_CP_FEES: () => LOCK_COLLECT_CP_FEES,
|
|
3911
|
+
LOCK_SEEDS: () => LOCK_SEEDS,
|
|
3912
|
+
MEMO_PROGRAM_ADDRESS: () => MEMO_PROGRAM_ADDRESS,
|
|
3194
3913
|
METADATA_LIMITS: () => METADATA_LIMITS,
|
|
3195
3914
|
METADATA_SEED: () => METADATA_SEED,
|
|
3196
3915
|
METAPLEX_PROGRAM_ADDRESS: () => METAPLEX_PROGRAM_ADDRESS,
|
|
@@ -3210,6 +3929,7 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3210
3929
|
ceilDiv: () => ceilDiv,
|
|
3211
3930
|
ceilDivRate: () => ceilDivRate,
|
|
3212
3931
|
claimCreatorFee: () => claimCreatorFee,
|
|
3932
|
+
claimPlatformFee: () => claimPlatformFee,
|
|
3213
3933
|
collectCreatorFee: () => collectCreatorFee,
|
|
3214
3934
|
compareAddresses: () => compareAddresses,
|
|
3215
3935
|
cpmmAuthority: () => cpmmAuthority,
|
|
@@ -3233,17 +3953,23 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3233
3953
|
decodeLaunchlabGlobalConfig: () => decodeLaunchlabGlobalConfig,
|
|
3234
3954
|
decodeLaunchlabPlatformConfig: () => decodeLaunchlabPlatformConfig,
|
|
3235
3955
|
decodeLaunchlabPool: () => decodeLaunchlabPool,
|
|
3956
|
+
decodeLockedCpLiquidity: () => decodeLockedCpLiquidity,
|
|
3236
3957
|
fetchCreatorFees: () => fetchCreatorFees,
|
|
3237
3958
|
fetchCurveSettings: () => fetchCurveSettings,
|
|
3959
|
+
fetchLockedPositions: () => fetchLockedPositions,
|
|
3960
|
+
fetchPlatformFees: () => fetchPlatformFees,
|
|
3238
3961
|
fetchQuoteAsset: () => fetchQuoteAsset,
|
|
3239
3962
|
fetchQuoteBinding: () => fetchQuoteBinding,
|
|
3240
3963
|
fetchQuoteConfig: () => fetchQuoteConfig,
|
|
3241
3964
|
fetchQuoteDisplay: () => fetchQuoteDisplay,
|
|
3242
3965
|
findCpmmPool: () => findCpmmPool,
|
|
3243
3966
|
getClaimCreatorFeeInstructions: () => getClaimCreatorFeeInstructions,
|
|
3967
|
+
getClaimPlatformFeeInstructions: () => getClaimPlatformFeeInstructions,
|
|
3244
3968
|
getCollectCreatorFeeInstructions: () => getCollectCreatorFeeInstructions,
|
|
3245
3969
|
getCurveBuyExactInInstruction: () => getCurveBuyExactInInstruction,
|
|
3970
|
+
getHarvestLockedFeesInstructions: () => getHarvestLockedFeesInstructions,
|
|
3246
3971
|
getLaunchInstruction: () => getLaunchInstruction,
|
|
3972
|
+
harvestLockedFees: () => harvestLockedFees,
|
|
3247
3973
|
initialCurve: () => initialCurve,
|
|
3248
3974
|
isQuoteSupported: () => isQuoteSupported,
|
|
3249
3975
|
launchlabAuthority: () => launchlabAuthority,
|
|
@@ -3255,6 +3981,9 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3255
3981
|
launchlabPoolAddress: () => launchlabPoolAddress,
|
|
3256
3982
|
launchlabSellAccounts: () => launchlabSellAccounts,
|
|
3257
3983
|
launchlabVaultAddress: () => launchlabVaultAddress,
|
|
3984
|
+
lockAuthority: () => lockAuthority,
|
|
3985
|
+
lockedFeeLp: () => lockedFeeLp,
|
|
3986
|
+
lockedLiquidityAddress: () => lockedLiquidityAddress,
|
|
3258
3987
|
metadataAddress: () => metadataAddress,
|
|
3259
3988
|
metaplexSymbol: () => metaplexSymbol,
|
|
3260
3989
|
mintDecimals: () => mintDecimals,
|
|
@@ -3262,6 +3991,7 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3262
3991
|
newCurveReserves: () => newCurveReserves,
|
|
3263
3992
|
order: () => order,
|
|
3264
3993
|
platformFeeVaultAddress: () => platformFeeVaultAddress,
|
|
3994
|
+
platformFeeVaultAuthority: () => platformFeeVaultAuthority,
|
|
3265
3995
|
preFeeAmount: () => preFeeAmount,
|
|
3266
3996
|
quoteAccountFor: () => quoteAccountFor,
|
|
3267
3997
|
raydiumIds: () => raydiumIds,
|
|
@@ -3277,6 +4007,6 @@ var raydium_exports = /* @__PURE__ */ __exportAll({
|
|
|
3277
4007
|
wsolAccountFor: () => wsolAccountFor
|
|
3278
4008
|
});
|
|
3279
4009
|
//#endregion
|
|
3280
|
-
export {
|
|
4010
|
+
export { readAccounts as $, uncappedMaximum as $n, poolAddress as $t, wsolAccountFor as A, VRF_PROGRAM_ADDRESS as An, LAUNCHLAB_CLAIM_PLATFORM_FEE_FROM_VAULT as Ar, CPMM_AMM_CONFIG_HEAD_SIZE as At, remainingBase as B, checkedCount as Bn, RAYDIUM_DEVNET_IDS as Br, decodeCpmmPool as Bt, fetchQuoteBinding as C, INSTRUCTIONS_SYSVAR as Cn, CPMM_COLLECT_CREATOR_FEE as Cr, fetchWalletActivity as Ct, quoteAccountFor as D, SLOT_HASHES_SYSVAR as Dn, LAUNCHLAB_BUY_EXACT_IN as Dr, listPools as Dt, newCurveReserves as E, RETRY_SLOTS as En, CPMM_SWAP_BASE_OUTPUT as Er, listDrawsByPurchaser as Et, curveBuyExactIn as F, MAX_MULTIPLIER_BPS as Fn, LAUNCHLAB_SELL_EXACT_IN as Fr, LAUNCHLAB_PLATFORM_CONFIG_HEAD_SIZE as Ft, launchlabBuyExactInAccounts as G, perPackCaps as Gn, TOKEN_PROGRAM_ADDRESS as Gr, metaplexSymbol as Gt, cpmmBuyAccounts as H, chooseIndex as Hn, RENT_SYSVAR_ADDRESS as Hr, decodeLaunchlabPlatformConfig as Ht, curveBuyExactOut as I, MIN_SEED_MULTIPLIER_BPS as In, LAUNCH_SUPPLY as Ir, LAUNCHLAB_POOL_STATE_HEAD_SIZE as It, fetchQuoteAsset as J, resolveReservation as Jn, tokenAccountAmount as Jt, launchlabSellAccounts as K, quote as Kn, WSOL_MINT as Kr, mintDecimals as Kt, curveSellExactIn as L, TICKETS as Ln, LAUNCH_TOTAL_BASE_SELL as Lr, LOCKED_CP_LIQUIDITY_DISCRIMINATOR as Lt, ceilDivRate as M, DEFAULT_TIERS as Mn, LAUNCHLAB_INITIALIZE as Mr, CPMM_POOL_STATE_HEAD_SIZE as Mt, cpmmSwapBaseInput as N, GaboxMathError as Nn, LAUNCHLAB_PLATFORM_CONFIG_DISCRIMINATOR as Nr, CPMM_POOL_STATE_SIZE as Nt, resolveVenue as O, TIMEOUT_SLOTS as On, LAUNCHLAB_BUY_EXACT_OUT as Or, quotePool as Ot, cpmmSwapBaseOutput as P, MAX_BATCH_SIZE as Pn, LAUNCHLAB_POOL_STATE_DISCRIMINATOR as Pr, LAUNCHLAB_GLOBAL_CONFIG_HEAD_SIZE as Pt, decodeBase64 as Q, uncappedAmounts as Qn, drawAddress as Qt, initialCurve as R, TIERS as Rn, METAPLEX_PROGRAM_ADDRESS as Rr, LOCKED_CP_LIQUIDITY_HEAD_SIZE as Rt, fetchCurveSettings as S, IDENTITY_SEED as Sn, CPMM_AMM_CONFIG_DISCRIMINATOR as Sr, fetchVaultBalance as St, newCurveBuyCost as T, PACK_TOKENS as Tn, CPMM_SWAP_BASE_INPUT as Tr, listDrawsByPool as Tt, cpmmSellAccounts as U, maxMultiplierBps as Un, SYSTEM_PROGRAM_ADDRESS as Ur, decodeLaunchlabPool as Ut, totalCurveFeeRate as V, choose as Vn, RAYDIUM_MAINNET_IDS as Vr, decodeLaunchlabGlobalConfig as Vt, launchlabBuyAccounts as W, minTier as Wn, TOKEN_2022_PROGRAM_ADDRESS as Wr, decodeLockedCpLiquidity as Wt, fetchQuoteDisplay as X, settleWith as Xn, activityAddress as Xt, fetchQuoteConfig as Y, seedTokens as Yn, tokenAccountOwnerAndMint as Yt, isQuoteSupported as Z, tierAmount as Zn, associatedTokenAddress as Zt, buildMessage as _, lockedLiquidityAddress as _n, SHARE_FEE_RATE as _r, fetchDraw as _t, fetchLockedPositions as a, cpmmAuthority as an, LAUNCHLAB_SEEDS as ar, DEFAULT_COMPUTE_UNIT_LIMIT as at, creatorFeeOnInput as b, platformFeeVaultAuthority as bn, sortedMints as br, fetchPoolByMint as bt, getHarvestLockedFeesInstructions as c, creatorFeeVaultAddress as cn, LAUNCHLAB_STATUS_TRADE as cr, REDEEM_COMPUTE_UNITS as ct, claimCreatorFee as d, launchlabEventAuthority as dn, MEMO_PROGRAM_ADDRESS as dr, getSetComputeUnitPriceInstruction as dt, randomNonce as en, validatePack as er, BUY_PACK_COMPUTE_UNITS as et, collectCreatorFee as f, launchlabGlobalConfig as fn, METADATA_LIMITS as fr, DRAW_POOL_OFFSET as ft, getLaunchInstruction as g, lockAuthority as gn, RAYDIUM_IDS as gr, POOL_MINT_OFFSET as gt, getCollectCreatorFeeInstructions as h, launchlabVaultAddress as hn, RATE_DENOMINATOR as hr, POOL_CREATOR_OFFSET as ht, claimPlatformFee as i, ata as in, CREATOR_FEE_ON_QUOTE as ir, CREATE_MACHINE_COMPUTE_UNITS as it, ceilDiv as j, BPS as jn, LAUNCHLAB_GLOBAL_CONFIG_DISCRIMINATOR as jr, CPMM_POOL_OFFSETS as jt, sellQuote as k, VRF_DEFAULT_QUEUE as kn, LAUNCHLAB_CLAIM_CREATOR_FEE as kr, tiersOf as kt, harvestLockedFees as l, creatorFeeVaultAuthority as ln, LAUNCH_DECIMALS as lr, computeBudgetInstructions as lt, getClaimCreatorFeeInstructions as m, launchlabPoolAddress as mn, MIGRATE_TO_CPMM as mr, DRAW_SETTLED_OFFSET as mt, getCurveBuyExactInInstruction as n, vaultAddress as nn, CONSTANT_CURVE_TAG as nr, CLAIM_PRIZE_COMPUTE_UNITS as nt, fetchPlatformFees as o, cpmmCreatorFeeShare as on, LAUNCHLAB_STATUS_FUND as or, HARVEST_COMPUTE_UNITS as ot, fetchCreatorFees as p, launchlabPlatformConfig as pn, METADATA_SEED as pr, DRAW_PURCHASER_OFFSET as pt, order as q, reserveFor as qn, token2022Symbol as qt, LOCK_COLLECT_CP_FEES as r, vrfIdentityAddress as rn, CPMM_SEEDS as rr, COMPUTE_BUDGET_PROGRAM_ADDRESS as rt, getClaimPlatformFeeInstructions as s, cpmmPoolAddress as sn, LAUNCHLAB_STATUS_MIGRATE as sr, MAX_COMPUTE_UNIT_LIMIT as st, raydium_exports as t, scopedVrfIdentityAddress as tn, validateTiers as tr, CLAIM_COMPUTE_UNITS as tt, lockedFeeLp as u, launchlabAuthority as un, LOCK_SEEDS as ur, getSetComputeUnitLimitInstruction as ut, withRemainingAccounts as v, metadataAddress as vn, compareAddresses as vr, fetchOwedDraws as vt, findCpmmPool as w, MAX_ATTEMPTS as wn, CPMM_POOL_STATE_DISCRIMINATOR as wr, listDraws as wt, curveQuote as x, GABOX_PROGRAM_ID as xn, ASSOCIATED_TOKEN_PROGRAM_ADDRESS as xr, fetchPoolInventory as xt, cpmmPoolMatches as y, platformFeeVaultAddress as yn, raydiumIds as yr, fetchPoolAt as yt, preFeeAmount as z, averageMultiplierBps as zn, PLATFORM_ADMIN as zr, decodeCpmmAmmConfig as zt };
|
|
3281
4011
|
|
|
3282
|
-
//# sourceMappingURL=raydium-
|
|
4012
|
+
//# sourceMappingURL=raydium-DXUJ-g1p.js.map
|