@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.
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { Dt as POOL_DISCRIMINATOR, Et as getWalletActivitySize, Jt as getDrawSize, Lt as getPoolSize, Ot as decodePool, Rt as DRAW_DISCRIMINATOR, _t as decodeWalletActivity, ft as findPoolPda, ht as findActivityPda, mt as findDrawPda, pt as findIdentityPda, t as GABOX_PROGRAM_ADDRESS, zt as decodeDraw } from "./gabox-DGTCh34U.js";
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": RAYDIUM_MAINNET_IDS,
895
- devnet: RAYDIUM_DEVNET_IDS,
896
- localnet: RAYDIUM_MAINNET_IDS
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
- /** `["draw", pool, seq]`, with the sequence as eight little-endian bytes. */
1402
- const drawAddress = async (pool, seq) => (await findDrawPda({
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
- seq
1636
+ purchaser,
1637
+ nonce
1405
1638
  }))[0];
1406
- /** The per-wallet `WalletActivity` PDA. `buy_pack` derives it from the purchaser automatically. */
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$1 = getU64Decoder();
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$1.decode(data, 64);
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$1],
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$1],
1552
- ["totalBaseSell", u64$1],
1553
- ["virtualBase", u64$1],
1554
- ["virtualQuote", u64$1],
1555
- ["realBase", u64$1],
1556
- ["realQuote", u64$1],
1557
- ["totalQuoteFundRaising", u64$1],
1558
- ["quoteProtocolFee", u64$1],
1559
- ["platformFee", u64$1],
1560
- ["migrateFee", u64$1],
1561
- ["vestingTotalLockedAmount", u64$1],
1562
- ["vestingCliffPeriod", u64$1],
1563
- ["vestingUnlockPeriod", u64$1],
1564
- ["vestingStartTime", u64$1],
1565
- ["vestingAllocatedShareAmount", u64$1],
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$1],
1852
+ ["epoch", u64$2],
1607
1853
  ["curveType", u8],
1608
1854
  ["index", u16],
1609
- ["migrateFee", u64$1],
1610
- ["tradeFeeRate", u64$1],
1611
- ["maxShareFeeRate", u64$1],
1612
- ["minBaseSupply", u64$1],
1613
- ["maxLockRate", u64$1],
1614
- ["minBaseSellRate", u64$1],
1615
- ["minBaseMigrateRate", u64$1],
1616
- ["minQuoteFundRaising", u64$1],
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$1],
1884
+ ["epoch", u64$2],
1639
1885
  ["platformFeeWallet", addressAt],
1640
1886
  ["platformNftWallet", addressAt],
1641
- ["platformScale", u64$1],
1642
- ["creatorScale", u64$1],
1643
- ["burnScale", u64$1],
1644
- ["feeRate", u64$1]
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$1.decode(data, PLATFORM_CREATOR_FEE_RATE_OFFSET),
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$1],
1680
- ["protocolFeesToken0", u64$1],
1681
- ["protocolFeesToken1", u64$1],
1682
- ["fundFeesToken0", u64$1],
1683
- ["fundFeesToken1", u64$1],
1684
- ["openTime", u64$1],
1685
- ["recentEpoch", u64$1],
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$1],
1690
- ["creatorFeesToken1", u64$1]
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$1],
1742
- ["protocolFeeRate", u64$1],
1743
- ["fundFeeRate", u64$1],
1744
- ["createPoolFee", u64$1],
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$1]
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
- * `buy_pack` creates this account `init_if_needed`, so a fresh wallet has none yet.
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 { computeBudgetInstructions as $, LAUNCHLAB_BUY_EXACT_OUT as $n, launchlabVaultAddress as $t, initialCurve as A, CPMM_SEEDS as An, metaplexSymbol as At, fetchQuoteAsset as B, RATE_DENOMINATOR as Bn, vaultAddress as Bt, ceilDiv as C, PACK_TOKENS as Cn, LAUNCHLAB_PLATFORM_CONFIG_HEAD_SIZE as Ct, curveBuyExactIn as D, VRF_DEFAULT_QUEUE as Dn, decodeLaunchlabGlobalConfig as Dt, cpmmSwapBaseOutput as E, TIMEOUT_SLOTS as En, decodeCpmmPool as Et, cpmmSellAccounts as F, LAUNCHLAB_STATUS_TRADE as Fn, activityAddress as Ft, readAccounts as G, sortedMints as Gn, cpmmPoolAddress as Gt, fetchQuoteDisplay as H, SHARE_FEE_RATE as Hn, ata as Ht, launchlabBuyAccounts as I, LAUNCH_DECIMALS as In, associatedTokenAddress as It, COMPUTE_BUDGET_PROGRAM_ADDRESS as J, CPMM_COLLECT_CREATOR_FEE as Jn, launchlabAuthority as Jt, BUY_PACK_COMPUTE_UNITS as K, ASSOCIATED_TOKEN_PROGRAM_ADDRESS as Kn, creatorFeeVaultAddress as Kt, launchlabBuyExactInAccounts as L, METADATA_LIMITS as Ln, drawAddress as Lt, remainingBase as M, LAUNCHLAB_SEEDS as Mn, token2022Symbol as Mt, totalCurveFeeRate as N, LAUNCHLAB_STATUS_FUND as Nn, tokenAccountAmount as Nt, curveBuyExactOut as O, VRF_PROGRAM_ADDRESS as On, decodeLaunchlabPlatformConfig as Ot, cpmmBuyAccounts as P, LAUNCHLAB_STATUS_MIGRATE as Pn, tokenAccountOwnerAndMint as Pt, REDEEM_COMPUTE_UNITS as Q, LAUNCHLAB_BUY_EXACT_IN as Qn, launchlabPoolAddress as Qt, launchlabSellAccounts as R, METADATA_SEED as Rn, poolAddress as Rt, wsolAccountFor as S, MAX_ATTEMPTS as Sn, LAUNCHLAB_GLOBAL_CONFIG_HEAD_SIZE as St, cpmmSwapBaseInput as T, SLOT_HASHES_SYSVAR as Tn, decodeCpmmAmmConfig as Tt, isQuoteSupported as U, compareAddresses as Un, cpmmAuthority as Ut, fetchQuoteConfig as V, RAYDIUM_IDS as Vn, vrfIdentityAddress as Vt, decodeBase64 as W, raydiumIds as Wn, cpmmCreatorFeeShare as Wt, DEFAULT_COMPUTE_UNIT_LIMIT as X, CPMM_SWAP_BASE_INPUT as Xn, launchlabGlobalConfig as Xt, CREATE_MACHINE_COMPUTE_UNITS as Y, CPMM_POOL_STATE_DISCRIMINATOR as Yn, launchlabEventAuthority as Yt, MAX_COMPUTE_UNIT_LIMIT as Z, CPMM_SWAP_BASE_OUTPUT as Zn, launchlabPlatformConfig as Zt, newCurveBuyCost as _, validatePack as _n, tiersOf as _t, fetchCreatorFees as a, MAX_MULTIPLIER_BPS as an, LAUNCHLAB_SELL_EXACT_IN as ar, POOL_MINT_OFFSET as at, resolveVenue as b, IDENTITY_SEED as bn, CPMM_POOL_STATE_HEAD_SIZE as bt, getLaunchInstruction as c, TIERS as cn, METAPLEX_PROGRAM_ADDRESS as cr, fetchPoolByMint as ct, cpmmPoolMatches as d, maxMultiplierBps as dn, RAYDIUM_MAINNET_IDS as dr, fetchWalletActivity as dt, metadataAddress as en, LAUNCHLAB_CLAIM_CREATOR_FEE as er, getSetComputeUnitLimitInstruction as et, creatorFeeOnInput as f, quote as fn, RENT_SYSVAR_ADDRESS as fr, listDraws as ft, findCpmmPool as g, uncappedMaximum as gn, WSOL_MINT as gr, quotePool as gt, fetchQuoteBinding as h, tierAmount as hn, TOKEN_PROGRAM_ADDRESS as hr, listPools as ht, collectCreatorFee as i, GaboxMathError as in, LAUNCHLAB_POOL_STATE_DISCRIMINATOR as ir, POOL_CREATOR_OFFSET as it, preFeeAmount as j, CREATOR_FEE_ON_QUOTE as jn, mintDecimals as jt, curveSellExactIn as k, CONSTANT_CURVE_TAG as kn, decodeLaunchlabPool as kt, buildMessage as l, averageMultiplierBps as ln, PLATFORM_ADMIN as lr, fetchPoolInventory as lt, fetchCurveSettings as m, seedTokens as mn, TOKEN_2022_PROGRAM_ADDRESS as mr, listDrawsByPurchaser as mt, getCurveBuyExactInInstruction as n, BPS as nn, LAUNCHLAB_INITIALIZE as nr, DRAW_POOL_OFFSET as nt, getClaimCreatorFeeInstructions as o, MIN_SEED_MULTIPLIER_BPS as on, LAUNCH_SUPPLY as or, fetchDraw as ot, curveQuote as p, resolveReservation as pn, SYSTEM_PROGRAM_ADDRESS as pr, listDrawsByPool as pt, CLAIM_COMPUTE_UNITS as q, CPMM_AMM_CONFIG_DISCRIMINATOR as qn, creatorFeeVaultAuthority as qt, claimCreatorFee as r, DEFAULT_TIERS as rn, LAUNCHLAB_PLATFORM_CONFIG_DISCRIMINATOR as rr, DRAW_PURCHASER_OFFSET as rt, getCollectCreatorFeeInstructions as s, TICKETS as sn, LAUNCH_TOTAL_BASE_SELL as sr, fetchPoolAt as st, raydium_exports as t, platformFeeVaultAddress as tn, LAUNCHLAB_GLOBAL_CONFIG_DISCRIMINATOR as tr, getSetComputeUnitPriceInstruction as tt, withRemainingAccounts as u, choose as un, RAYDIUM_DEVNET_IDS as ur, fetchVaultBalance as ut, newCurveReserves as v, validateTiers as vn, CPMM_AMM_CONFIG_HEAD_SIZE as vt, ceilDivRate as w, RETRY_SLOTS as wn, LAUNCHLAB_POOL_STATE_HEAD_SIZE as wt, sellQuote as x, INSTRUCTIONS_SYSVAR as xn, CPMM_POOL_STATE_SIZE as xt, quoteAccountFor as y, GABOX_PROGRAM_ID as yn, CPMM_POOL_OFFSETS as yt, order as z, MIGRATE_TO_CPMM as zn, scopedVrfIdentityAddress as zt };
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-CU-tZzIk.js.map
4012
+ //# sourceMappingURL=raydium-DXUJ-g1p.js.map