@theliem/xmarket-sdk 3.19.0 → 3.21.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/dist/index.mjs CHANGED
@@ -354,7 +354,7 @@ var OracleClient = class {
354
354
  owner: acc.owner,
355
355
  admin: acc.admin,
356
356
  questionCount: acc.questionCount.toNumber(),
357
- whitelist: acc.whitelist,
357
+ whitelist: acc.whitelist.slice(0, acc.whitelistLen),
358
358
  whitelistLen: acc.whitelistLen,
359
359
  isPaused: acc.isPaused,
360
360
  bump: acc.bump
@@ -407,6 +407,23 @@ var HookClient = class {
407
407
  }).rpc();
408
408
  return { signature: sig };
409
409
  }
410
+ /**
411
+ * Returns initializeExtraAccountMetaList instruction if the account doesn't exist yet, else null.
412
+ * Used by ClobClient to auto-prepend when extraAccountMetaList is missing.
413
+ */
414
+ async buildInitHookIxIfNeeded(mint, payer) {
415
+ const [extraAccountMetaList] = PDA.extraAccountMetaList(mint, this.programIds);
416
+ const existing = await this.provider.connection.getAccountInfo(extraAccountMetaList);
417
+ if (existing) return null;
418
+ return this.program.methods.initializeExtraAccountMetaList().accounts({
419
+ payer,
420
+ extraAccountMetaList,
421
+ mint,
422
+ hookConfig: this.configPda(),
423
+ tokenProgram: TOKEN_2022_PROGRAM_ID,
424
+ systemProgram: SystemProgram.programId
425
+ }).instruction();
426
+ }
410
427
  /**
411
428
  * Register extra account metas for a Token-2022 YES/NO mint.
412
429
  * Must be called once per mint after CTF creates it.
@@ -481,7 +498,7 @@ var HookClient = class {
481
498
  const acc = await this.program.account.hookConfig.fetch(this.configPda());
482
499
  return {
483
500
  owner: acc.owner,
484
- whitelist: acc.whitelist,
501
+ whitelist: acc.whitelist.slice(0, acc.whitelistLen),
485
502
  whitelistLen: acc.whitelistLen,
486
503
  isFrozen: acc.isFrozen,
487
504
  bump: acc.bump
@@ -571,7 +588,10 @@ var MarketClient = class {
571
588
  const [mintAuthority] = PDA.mintAuthority(conditionPda, this.programIds);
572
589
  const [collateralVault] = PDA.collateralVault(params.collateralMint, this.programIds);
573
590
  if (!this.programIds.feeManagement) throw new Error("feeManagement program ID not configured");
591
+ if (!this.feeConfigOwner) throw new Error("feeConfigOwner not configured");
574
592
  const [questionFeePda] = PDA.questionFee(conditionPda, this.programIds);
593
+ const [feeConfigPda] = PDA.feeConfig(this.feeConfigOwner, this.programIds);
594
+ const [marketFeeOverride] = PDA.marketFeeOverride(conditionPda, this.programIds);
575
595
  const tx = await this.program.methods.createQuestionAdmin({
576
596
  questionId: Array.from(questionId),
577
597
  contentHash: Array.from(contentHash),
@@ -592,6 +612,8 @@ var MarketClient = class {
592
612
  collateralVault,
593
613
  conditionalTokensProgram: this.programIds.conditionalTokens,
594
614
  questionFee: questionFeePda,
615
+ feeConfig: feeConfigPda,
616
+ marketFeeOverride,
595
617
  feeManagementProgram: this.programIds.feeManagement,
596
618
  tokenProgram: TOKEN_2022_PROGRAM_ID,
597
619
  systemProgram: SystemProgram.programId,
@@ -663,6 +685,9 @@ var MarketClient = class {
663
685
  systemProgram: SystemProgram.programId
664
686
  }).transaction();
665
687
  }
688
+ async bumpPresaleCount(count, authority) {
689
+ return this.program.methods.bumpPresaleCount(new anchor5.BN(count)).accounts({ authority, config: this.configPda }).transaction();
690
+ }
666
691
  // ─── Queries ─────────────────────────────────────────────────────────────────
667
692
  async fetchConfig() {
668
693
  try {
@@ -676,7 +701,7 @@ var MarketClient = class {
676
701
  approvedCount: acc.approvedCount.toNumber(),
677
702
  rejectedCount: acc.rejectedCount.toNumber(),
678
703
  presaleCount: acc.presaleCount.toNumber(),
679
- whitelist: acc.whitelist,
704
+ whitelist: acc.whitelist.slice(0, acc.whitelistLen),
680
705
  whitelistLen: acc.whitelistLen,
681
706
  isPaused: acc.isPaused,
682
707
  bump: acc.bump
@@ -829,6 +854,9 @@ var MarketClient = class {
829
854
  const [adminConfig] = PDA.adminConfig(adminOwner, this.programIds);
830
855
  const adminVault = getAssociatedTokenAddressSync(currencyMint, adminConfig, true);
831
856
  const [claimRecord] = PDA.claimRecord(conditionPda.toBytes(), this.programIds);
857
+ const feeConfigOwner = this.feeConfigOwner ?? adminOwner;
858
+ const [feeConfigPda] = PDA.feeConfig(feeConfigOwner, this.programIds);
859
+ const [marketFeeOverride] = PDA.marketFeeOverride(conditionPda, this.programIds);
832
860
  const builder = this.program.methods.approvePresale({
833
861
  contentHash: Array.from(contentHash),
834
862
  hookProgram,
@@ -857,6 +885,8 @@ var MarketClient = class {
857
885
  adminConfig,
858
886
  claimRecord,
859
887
  questionFee: questionFeePda,
888
+ feeConfig: feeConfigPda,
889
+ marketFeeOverride,
860
890
  feeManagementProgram: this.programIds.feeManagement,
861
891
  conditionalTokensProgram: this.programIds.conditionalTokens,
862
892
  presaleProgram: this.programIds.presale,
@@ -1520,6 +1550,8 @@ function _detectMatchType(a, b) {
1520
1550
  // src/programs/clob.ts
1521
1551
  var ClobClient = class {
1522
1552
  constructor(program, provider, programIds, networkConfig) {
1553
+ /** Cache: conditionPda.toBase58() → marketOracleVault ATA */
1554
+ this._marketOracleVaultCache = /* @__PURE__ */ new Map();
1523
1555
  /** ALT cache: condition.toBase58() → loaded ALT account */
1524
1556
  this._altCache = /* @__PURE__ */ new Map();
1525
1557
  this.program = program;
@@ -1542,6 +1574,24 @@ var ClobClient = class {
1542
1574
  await this.companyAddress();
1543
1575
  return this._referralVault;
1544
1576
  }
1577
+ /**
1578
+ * Derive marketOracleVault ATA for a condition, cached per condition.
1579
+ * Works for presale markets (market_oracle initialized by approvePresale).
1580
+ * Returns undefined if ctfClient/qmConfigPda not injected or marketOracle not configured.
1581
+ */
1582
+ async getMarketOracleVault(condition, collateralMint) {
1583
+ if (!this.ctfClient || !this.qmConfigPda || !this.programIds.marketOracle) return void 0;
1584
+ const key = condition.toBase58();
1585
+ const cached = this._marketOracleVaultCache.get(key);
1586
+ if (cached) return cached;
1587
+ const cond = await this.ctfClient.fetchCondition(condition);
1588
+ if (!cond) return void 0;
1589
+ const [questionPda] = PDA.question(this.qmConfigPda, cond.questionId, this.programIds);
1590
+ const [marketOraclePda] = PDA.marketOraclePda(questionPda, this.programIds);
1591
+ const vault = getAssociatedTokenAddressSync(collateralMint, marketOraclePda, true);
1592
+ this._marketOracleVaultCache.set(key, vault);
1593
+ return vault;
1594
+ }
1545
1595
  get walletPubkey() {
1546
1596
  return this.provider.wallet.publicKey;
1547
1597
  }
@@ -1641,11 +1691,11 @@ var ClobClient = class {
1641
1691
  if (companyAddr) {
1642
1692
  addresses.push(getAssociatedTokenAddressSync(collateralMint, companyAddr));
1643
1693
  }
1644
- addresses.push(payer);
1694
+ const oracleVaultForAlt = await this.getMarketOracleVault(condition, collateralMint) ?? payer;
1695
+ addresses.push(oracleVaultForAlt);
1645
1696
  if (refVault) {
1646
1697
  addresses.push(refVault);
1647
1698
  }
1648
- addresses.push(TOKEN_PROGRAM_ID);
1649
1699
  }
1650
1700
  const slot = await connection.getSlot("finalized");
1651
1701
  const [createIx, altAddress] = AddressLookupTableProgram.createLookupTable({
@@ -1908,7 +1958,7 @@ ${logs.join("\n")}`);
1908
1958
  const feeOverridePda = PDA.marketFeeOverride(condition, this.programIds)[0];
1909
1959
  const feeOverrideExists = await this.provider.connection.getAccountInfo(feeOverridePda);
1910
1960
  if (feeOverrideExists) {
1911
- const oracleVault = opts?.marketOracleVault ?? this.walletPubkey;
1961
+ const oracleVault = opts?.marketOracleVault ?? await this.getMarketOracleVault(condition, collateralMint) ?? this.walletPubkey;
1912
1962
  feeAccounts = [
1913
1963
  { pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
1914
1964
  { pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
@@ -2164,15 +2214,14 @@ ${logs.join("\n")}`);
2164
2214
  const feeOverridePda = PDA.marketFeeOverride(condition, this.programIds)[0];
2165
2215
  const feeOverrideExists = await this.provider.connection.getAccountInfo(feeOverridePda);
2166
2216
  if (feeOverrideExists) {
2167
- const oracleVault = opts?.marketOracleVault ?? payer;
2217
+ const oracleVault = opts?.marketOracleVault ?? await this.getMarketOracleVault(condition, collateralMint) ?? payer;
2168
2218
  remainingAccounts.push(
2169
2219
  { pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
2170
2220
  { pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
2171
2221
  { pubkey: feeOverridePda, isSigner: false, isWritable: false },
2172
2222
  { pubkey: getAssociatedTokenAddressSync(collateralMint, companyAddr), isSigner: false, isWritable: true },
2173
2223
  { pubkey: oracleVault, isSigner: false, isWritable: true },
2174
- { pubkey: refVault, isSigner: false, isWritable: true },
2175
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }
2224
+ { pubkey: refVault, isSigner: false, isWritable: true }
2176
2225
  );
2177
2226
  }
2178
2227
  }
@@ -2373,6 +2422,18 @@ ${logs.join("\n")}`);
2373
2422
  const m0 = makers[0].order;
2374
2423
  const SIDE_BUY = 0;
2375
2424
  const SIDE_SELL = 1;
2425
+ const hookInitIxs = [];
2426
+ if (this.hookClient) {
2427
+ const condition0 = t.condition;
2428
+ const [ym] = PDA.yesMint(condition0, this.programIds);
2429
+ const [nm] = PDA.noMint(condition0, this.programIds);
2430
+ const [yIx, nIx] = await Promise.all([
2431
+ this.hookClient.buildInitHookIxIfNeeded(ym, payer),
2432
+ this.hookClient.buildInitHookIxIfNeeded(nm, payer)
2433
+ ]);
2434
+ if (yIx) hookInitIxs.push(yIx);
2435
+ if (nIx) hookInitIxs.push(nIx);
2436
+ }
2376
2437
  if (t.tokenId === m0.tokenId) {
2377
2438
  let buySignedOrder, sellCandidates;
2378
2439
  if (t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_SELL)) {
@@ -2392,7 +2453,7 @@ ${logs.join("\n")}`);
2392
2453
  opts,
2393
2454
  false
2394
2455
  );
2395
- return this._buildUnsignedVtx(ixs3, alt, payer);
2456
+ return this._buildUnsignedVtx([...hookInitIxs, ...ixs3], alt, payer);
2396
2457
  } else {
2397
2458
  throw new InvalidParamError("COMPLEMENTARY requires one BUY and one or more SELLs on same tokenId");
2398
2459
  }
@@ -2408,7 +2469,7 @@ ${logs.join("\n")}`);
2408
2469
  operator,
2409
2470
  opts
2410
2471
  );
2411
- return this._buildUnsignedVtx(ixs2, alt, payer);
2472
+ return this._buildUnsignedVtx([...hookInitIxs, ...ixs2], alt, payer);
2412
2473
  }
2413
2474
  const allBuy = t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_BUY);
2414
2475
  const allSell = t.side === SIDE_SELL && makers.every((m) => m.order.side === SIDE_SELL);
@@ -2429,7 +2490,7 @@ ${logs.join("\n")}`);
2429
2490
  ]);
2430
2491
  await this._ensureClobOutcomeAtas(yesMint, noMint, clobConfig, clobYesAta, clobNoAta);
2431
2492
  const ix = allBuy ? await this._buildMintIx(taker, makers, collateralMint, operator, payer) : await this._buildMergeIx(taker, makers, collateralMint, operator, payer, opts);
2432
- return this._buildUnsignedVtx([ix], alt, payer);
2493
+ return this._buildUnsignedVtx([...hookInitIxs, ix], alt, payer);
2433
2494
  }
2434
2495
  await Promise.all([
2435
2496
  this.registerOrderIfNeeded(taker),
@@ -2441,7 +2502,7 @@ ${logs.join("\n")}`);
2441
2502
  const ix = allBuy ? await this._buildMintIx(yesMaker, [taker], collateralMint, operator, payer) : await this._buildMergeIx(yesMaker, [taker], collateralMint, operator, payer, opts);
2442
2503
  ixs.push(ix);
2443
2504
  }
2444
- return this._buildUnsignedVtx(ixs, alt, payer);
2505
+ return this._buildUnsignedVtx([...hookInitIxs, ...ixs], alt, payer);
2445
2506
  }
2446
2507
  // ─── batchCollectRedeemEarly ─────────────────────────────────────────────────
2447
2508
  /**
@@ -2498,7 +2559,7 @@ ${logs.join("\n")}`);
2498
2559
  const feeOverridePda = PDA.marketFeeOverride(condition, this.programIds)[0];
2499
2560
  const feeOverrideExists = await this.provider.connection.getAccountInfo(feeOverridePda);
2500
2561
  if (feeOverrideExists) {
2501
- const oracleVault = opts?.marketOracleVault ?? payer;
2562
+ const oracleVault = opts?.marketOracleVault ?? await this.getMarketOracleVault(condition, collateralMint) ?? payer;
2502
2563
  feeAccounts = [
2503
2564
  { pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
2504
2565
  { pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
@@ -2511,10 +2572,16 @@ ${logs.join("\n")}`);
2511
2572
  }
2512
2573
  }
2513
2574
  await this._ensureClobOutcomeAtas(yesMint, noMint, clobConfig, clobYesAta, clobNoAta);
2575
+ const hookInitIxs = [];
2576
+ if (this.hookClient) {
2577
+ const ix = await this.hookClient.buildInitHookIxIfNeeded(outcomeMint, payer);
2578
+ if (ix) hookInitIxs.push(ix);
2579
+ }
2514
2580
  const ed25519Ix = buildBatchedCollectFeeEd25519Instruction(signedOrders);
2581
+ const ed25519IxIndex = 2 + hookInitIxs.length;
2515
2582
  const collectIx = await this.program.methods.batchCollectRedeemEarly(
2516
- 2,
2517
- // ix_index: Ed25519 ix is ix[2] (cuLimit=0, heapFrame=1, ed25519=2)
2583
+ ed25519IxIndex,
2584
+ // ix_index: adjusted for any prepended hook init ixs
2518
2585
  signedOrders.length,
2519
2586
  outcomeIndex
2520
2587
  ).accounts({
@@ -2538,7 +2605,7 @@ ${logs.join("\n")}`);
2538
2605
  systemProgram: SystemProgram.programId
2539
2606
  }).remainingAccounts([...userAccounts, ...hookAccounts, ...feeAccounts]).instruction();
2540
2607
  const cachedAlt = this._altCache.get(condition.toBase58());
2541
- return this._buildUnsignedVtx([ed25519Ix, collectIx], cachedAlt, payer);
2608
+ return this._buildUnsignedVtx([...hookInitIxs, ed25519Ix, collectIx], cachedAlt, payer);
2542
2609
  }
2543
2610
  // ─── Queries ─────────────────────────────────────────────────────────────────
2544
2611
  async fetchConfig() {
@@ -4636,6 +4703,20 @@ var question_market_default = {
4636
4703
  ],
4637
4704
  writable: true
4638
4705
  },
4706
+ {
4707
+ name: "fee_config",
4708
+ docs: [
4709
+ "FeeConfig PDA \u2014 passed to set_market_fee_override CPI."
4710
+ ],
4711
+ writable: true
4712
+ },
4713
+ {
4714
+ name: "market_fee_override",
4715
+ docs: [
4716
+ "MarketFeeOverride PDA \u2014 auto-init with is_admin=false and fee_config defaults."
4717
+ ],
4718
+ writable: true
4719
+ },
4639
4720
  {
4640
4721
  name: "fee_management_program",
4641
4722
  address: "DuYyXguB5PVSKg6E2p4XPrrXZSCJnuBhoGpkGCBN5bBb"
@@ -4741,6 +4822,55 @@ var question_market_default = {
4741
4822
  ],
4742
4823
  args: []
4743
4824
  },
4825
+ {
4826
+ name: "bump_presale_count",
4827
+ discriminator: [
4828
+ 42,
4829
+ 84,
4830
+ 98,
4831
+ 9,
4832
+ 208,
4833
+ 168,
4834
+ 38,
4835
+ 55
4836
+ ],
4837
+ accounts: [
4838
+ {
4839
+ name: "authority",
4840
+ signer: true
4841
+ },
4842
+ {
4843
+ name: "config",
4844
+ writable: true,
4845
+ pda: {
4846
+ seeds: [
4847
+ {
4848
+ kind: "const",
4849
+ value: [
4850
+ 99,
4851
+ 111,
4852
+ 110,
4853
+ 102,
4854
+ 105,
4855
+ 103
4856
+ ]
4857
+ },
4858
+ {
4859
+ kind: "account",
4860
+ path: "config.owner",
4861
+ account: "QuestionMarketConfig"
4862
+ }
4863
+ ]
4864
+ }
4865
+ }
4866
+ ],
4867
+ args: [
4868
+ {
4869
+ name: "count",
4870
+ type: "u64"
4871
+ }
4872
+ ]
4873
+ },
4744
4874
  {
4745
4875
  name: "collect_presale_revenue",
4746
4876
  discriminator: [
@@ -5297,39 +5427,23 @@ var question_market_default = {
5297
5427
  {
5298
5428
  name: "question_fee",
5299
5429
  docs: [
5300
- "QuestionFee PDA \u2014 initialized with default fees via CPI to fee-management.",
5301
- "Seed uses condition.key() bytes (consistent with existing set_question_fee SDK convention)."
5430
+ "QuestionFee PDA \u2014 initialized with default fees via CPI to fee-management."
5302
5431
  ],
5303
- writable: true,
5304
- pda: {
5305
- seeds: [
5306
- {
5307
- kind: "const",
5308
- value: [
5309
- 113,
5310
- 117,
5311
- 101,
5312
- 115,
5313
- 116,
5314
- 105,
5315
- 111,
5316
- 110,
5317
- 95,
5318
- 102,
5319
- 101,
5320
- 101
5321
- ]
5322
- },
5323
- {
5324
- kind: "account",
5325
- path: "condition"
5326
- }
5327
- ],
5328
- program: {
5329
- kind: "account",
5330
- path: "fee_management_program"
5331
- }
5332
- }
5432
+ writable: true
5433
+ },
5434
+ {
5435
+ name: "fee_config",
5436
+ docs: [
5437
+ "FeeConfig PDA \u2014 passed to set_market_fee_override CPI as authority validator."
5438
+ ],
5439
+ writable: true
5440
+ },
5441
+ {
5442
+ name: "market_fee_override",
5443
+ docs: [
5444
+ "MarketFeeOverride PDA \u2014 init'd by set_market_fee_override CPI (is_admin=true)."
5445
+ ],
5446
+ writable: true
5333
5447
  },
5334
5448
  {
5335
5449
  name: "fee_management_program",
@@ -6895,7 +7009,7 @@ var question_market_default = {
6895
7009
  type: {
6896
7010
  array: [
6897
7011
  "pubkey",
6898
- 30
7012
+ 20
6899
7013
  ]
6900
7014
  }
6901
7015
  },
@@ -6935,7 +7049,7 @@ var question_market_default = {
6935
7049
  type: {
6936
7050
  array: [
6937
7051
  "u8",
6938
- 120
7052
+ 440
6939
7053
  ]
6940
7054
  }
6941
7055
  }
@@ -16286,6 +16400,7 @@ var XMarketSDK = class {
16286
16400
  const program = new anchor5.Program(this._withAddress(question_market_default, this._programIds.questionMarket), this.provider);
16287
16401
  this._market = new MarketClient(program, this.provider, this._programIds, this._marketOwner);
16288
16402
  this._market.ctfClient = this.ctf;
16403
+ this._market.feeConfigOwner = this.networkConfig.feeConfigOwner ?? this._marketOwner;
16289
16404
  }
16290
16405
  return this._market;
16291
16406
  }
@@ -16304,6 +16419,9 @@ var XMarketSDK = class {
16304
16419
  this._clob.feeConfigOwner = this.networkConfig.feeConfigOwner;
16305
16420
  this._clob.feeClient = this.fee;
16306
16421
  }
16422
+ this._clob.ctfClient = this.ctf;
16423
+ this._clob.qmConfigPda = this.market.configPda;
16424
+ this._clob.hookClient = this.hook;
16307
16425
  }
16308
16426
  return this._clob;
16309
16427
  }