@theliem/xmarket-sdk 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -9,6 +9,9 @@ interface ProgramIds {
9
9
  questionMarket: PublicKey;
10
10
  hook: PublicKey;
11
11
  clobExchange: PublicKey;
12
+ feeManagement?: PublicKey;
13
+ presale?: PublicKey;
14
+ marketOracle?: PublicKey;
12
15
  }
13
16
  interface CollateralConfig {
14
17
  mint: PublicKey;
@@ -20,6 +23,8 @@ interface NetworkConfig {
20
23
  rpcUrl: string;
21
24
  programIds: ProgramIds;
22
25
  defaultCollateral: CollateralConfig;
26
+ /** Owner of the fee_config PDA — used to auto-derive fee distribution accounts */
27
+ feeConfigOwner?: PublicKey;
23
28
  }
24
29
  type NetworkName = string;
25
30
 
@@ -93,6 +98,7 @@ interface QuestionMarketConfig {
93
98
  questionCount: number;
94
99
  approvedCount: number;
95
100
  rejectedCount: number;
101
+ presaleCount: number;
96
102
  whitelist: PublicKey[];
97
103
  whitelistLen: number;
98
104
  isPaused: boolean;
@@ -160,6 +166,15 @@ interface OrderStatus {
160
166
  isCancelled: boolean;
161
167
  bump: number;
162
168
  }
169
+ /** Per-question fee rates, all out of FEE_DENOMINATOR (1_000_000). E.g. 2_000 = 0.2% */
170
+ interface QuestionFee {
171
+ conditionId: Uint8Array;
172
+ mergeFee: BN;
173
+ redeemFee: BN;
174
+ swapFee: BN;
175
+ bump: number;
176
+ }
177
+ declare const FEE_DENOMINATOR = 1000000;
163
178
  /**
164
179
  * Off-chain order struct passed as instruction data.
165
180
  * Operator validates + submits matched order pairs on-chain.
@@ -448,14 +463,114 @@ declare class MarketClient {
448
463
  yes: Position | null;
449
464
  no: Position | null;
450
465
  }>;
466
+ /**
467
+ * Any user creates a presale + initial buy (question-market::create_presale).
468
+ * Reads agents_rev / company_rev from fee_config.
469
+ *
470
+ * @param feeConfig fee_management fee_config PDA (owner = feeConfigOwner)
471
+ * @param currencyMint collateral token (e.g. USDC)
472
+ * @param presaleIndex config.presale_count — fetch config first or pass 0 for first presale
473
+ */
474
+ createPresale(params: {
475
+ price: anchor.BN;
476
+ startTime: anchor.BN;
477
+ endTime: anchor.BN;
478
+ initialBuyAmount: anchor.BN;
479
+ }, feeConfig: PublicKey, currencyMint: PublicKey, presaleIndex: anchor.BN, creator?: PublicKey, payer?: PublicKey): Promise<{
480
+ tx: Transaction;
481
+ presalePda: PublicKey;
482
+ qtMint: PublicKey;
483
+ }>;
484
+ /**
485
+ * Whitelist-only: approve presale → creates question + CTF condition + market_oracle in one tx.
486
+ *
487
+ * @param presalePda the presale account
488
+ * @param contentHash 32-byte hash for question content
489
+ * @param hookProgram token-2022 transfer hook program
490
+ * @param authorizedClob clob program allowed to do CTF transfers
491
+ * @param expirationTime Unix seconds
492
+ * @param creator presale creator pubkey (stored in question)
493
+ * @param currencyMint collateral mint
494
+ */
495
+ approvePresale(presalePda: PublicKey, contentHash: Uint8Array, hookProgram: PublicKey, authorizedClob: PublicKey, expirationTime: anchor.BN, creator: PublicKey, currencyMint: PublicKey, caller?: PublicKey, payer?: PublicKey): Promise<{
496
+ tx: Transaction;
497
+ questionPda: PublicKey;
498
+ conditionPda: PublicKey;
499
+ marketOraclePda: PublicKey;
500
+ marketOracleVault: PublicKey;
501
+ }>;
502
+ /**
503
+ * Whitelist-only: reject presale so users can refund.
504
+ */
505
+ rejectPresale(presalePda: PublicKey, caller?: PublicKey): Promise<Transaction>;
506
+ /**
507
+ * Whitelist-only: distribute presale vault funds → agents_rev% + company_rev% + rest to creator.
508
+ * Must be called after approvePresale.
509
+ */
510
+ collectPresaleRevenue(presalePda: PublicKey, currencyMint: PublicKey, referralAddress: PublicKey, companyAddress: PublicKey, caller?: PublicKey): Promise<Transaction>;
511
+ /**
512
+ * Whitelist-only: snapshot MST supply so holders can claim trading fees.
513
+ * Call after oracle resolves the question.
514
+ */
515
+ collectTradingFee(marketOraclePda: PublicKey, qtMint: PublicKey, caller?: PublicKey): Promise<Transaction>;
451
516
  }
452
517
 
453
- declare class ClobClient {
518
+ declare class FeeManagementClient {
454
519
  private readonly program;
455
520
  private readonly provider;
456
521
  private readonly programIds;
457
522
  constructor(program: anchor.Program, provider: anchor.AnchorProvider, programIds: ProgramIds);
523
+ initFeeConfig(admin: PublicKey, companyAddress: PublicKey, referralAddress: PublicKey, presaleRevenueAddress: PublicKey, investorsMarketRev: number, companyMarketRev: number, agentsPresaleRev: number, companyPresaleRev: number, authority: PublicKey, payer: PublicKey): Promise<TxResult>;
524
+ fetchFeeConfig(owner: PublicKey): Promise<any | null>;
525
+ /**
526
+ * Fetch per-question fees for a condition.
527
+ * Returns null if no fees have been set yet.
528
+ */
529
+ fetchQuestionFee(conditionPda: PublicKey): Promise<QuestionFee | null>;
530
+ /**
531
+ * Set per-question fees for a condition.
532
+ * @param conditionPda - condition PDA from the question
533
+ * @param mergeFee - fee out of FEE_DENOMINATOR (1_000_000), e.g. 2_000 = 0.2%
534
+ * @param redeemFee - fee out of FEE_DENOMINATOR
535
+ * @param swapFee - trading fee out of FEE_DENOMINATOR
536
+ * @param feeConfigOwner - pubkey that owns the fee_config PDA (usually market deployer)
537
+ * @param authority - signer authorized in fee_config whitelist / admin / owner
538
+ * @param payer - rent + tx fee payer
539
+ */
540
+ updateFeeConfig(companyAddress: PublicKey, referralAddress: PublicKey, presaleRevenueAddress: PublicKey, investorsMarketRev: number, companyMarketRev: number, agentsPresaleRev: number, companyPresaleRev: number, authority: PublicKey, payer: PublicKey): Promise<TxResult>;
541
+ setMarketFeeOverride(conditionPda: PublicKey, investors: number, company: number, isAdmin: boolean, feeConfigOwner: PublicKey, authority: PublicKey, payer: PublicKey): Promise<TxResult>;
542
+ buildDistributeFeeIx(conditionPda: PublicKey, amount: BN, feeConfigOwner: PublicKey, sourceAta: PublicKey, companyAta: PublicKey, marketOracleVault: PublicKey, authority: PublicKey): Promise<TransactionInstruction>;
543
+ distributeFee(conditionPda: PublicKey, amount: BN, feeConfigOwner: PublicKey, sourceAta: PublicKey, companyAta: PublicKey, marketOracleVault: PublicKey, authority: PublicKey): Promise<TxResult>;
544
+ setQuestionFee(conditionPda: PublicKey, mergeFee: BN, redeemFee: BN, swapFee: BN, feeConfigOwner: PublicKey, authority: PublicKey, payer: PublicKey): Promise<TxResult>;
545
+ }
546
+
547
+ declare class ClobClient {
548
+ private readonly program;
549
+ private readonly provider;
550
+ private readonly programIds;
551
+ private readonly networkConfig;
552
+ /** Injected by XMarketSDK after construction — enables auto fee distribution */
553
+ feeClient?: FeeManagementClient;
554
+ feeConfigOwner?: PublicKey;
555
+ /** Cached company_address from fee_config to avoid repeated RPC calls */
556
+ private _companyAddress?;
557
+ /** ALT cache: condition.toBase58() → loaded ALT account */
558
+ private _altCache;
559
+ constructor(program: anchor.Program, provider: anchor.AnchorProvider, programIds: ProgramIds, networkConfig: {
560
+ defaultCollateral: {
561
+ mint: PublicKey;
562
+ };
563
+ });
564
+ private companyAddress;
458
565
  get walletPubkey(): PublicKey;
566
+ /**
567
+ * Get or create an ALT for a condition.
568
+ * First call: creates + extends ALT on-chain, waits for activation (~2s).
569
+ * Subsequent calls for same condition: returns cached ALT instantly.
570
+ * BE devs never interact with this — called automatically by matchOrders.
571
+ */
572
+ ensureAlt(condition: PublicKey, collateralMint: PublicKey, buyerPubkey: PublicKey, buyerNonce: anchor.BN, makers: SignedOrder[]): Promise<AddressLookupTableAccount>;
573
+ private _sendLegacyTx;
459
574
  /**
460
575
  * Send a match transaction as versioned (v0).
461
576
  * Pass a pre-built AddressLookupTableAccount to compress account keys and
@@ -465,7 +580,7 @@ declare class ClobClient {
465
580
  * If `whitelistedWallet` is provided and differs from `this.provider.wallet`,
466
581
  * both wallets sign the transaction (whitelisted operator + payer).
467
582
  */
468
- private _sendMatchTx;
583
+ sendMatchTx(instructions: TransactionInstruction[], lookupTable?: AddressLookupTableAccount, whitelistedWallet?: anchor.Wallet): Promise<string>;
469
584
  /** PDA for a CLOB whitelist entry. */
470
585
  whitelistEntryPda(address: PublicKey): PublicKey;
471
586
  configPda(): PublicKey;
@@ -496,6 +611,15 @@ declare class ClobClient {
496
611
  *
497
612
  * remaining_accounts: [hook×3] [seller×5 × N]
498
613
  */
614
+ /** Build Ed25519 + matchComplementary instructions without sending.
615
+ *
616
+ * If `buySigned.order.fee > 0` and `feeClient` + `feeConfigOwner` are wired in,
617
+ * automatically appends 5 fee_management remaining_accounts so the program CPIs
618
+ * to distribute_fee internally. No manual `feeDistribute` param needed.
619
+ */
620
+ buildMatchComplementaryIxs(buySigned: SignedOrder, makersSigned: SignedOrder[], collateralMint: PublicKey, feeRecipient: PublicKey, whitelisted: PublicKey, opts?: {
621
+ marketOracleVault?: PublicKey;
622
+ }): Promise<TransactionInstruction[]>;
499
623
  private matchComplementary;
500
624
  /**
501
625
  * MINT match: 1 YES buyer (taker) + N NO buyers (makers).
@@ -530,7 +654,19 @@ declare class ClobClient {
530
654
  *
531
655
  * All makers must have the same tokenId and side as makers[0].
532
656
  */
533
- matchOrders(taker: SignedOrder, makers: SignedOrder[], collateralMint: PublicKey, feeRecipient: PublicKey, whitelistedWallet: anchor.Wallet, lookupTable?: AddressLookupTableAccount): Promise<TxResult>;
657
+ /**
658
+ * Auto-detect match type and execute in a single transaction.
659
+ * ALT is managed automatically (created on first call per condition, cached thereafter).
660
+ * feeRecipient and collateralMint are derived from on-chain config.
661
+ * Fee distribution (distribute_fee CPI) fires automatically when order.fee > 0.
662
+ *
663
+ * @param opts.marketOracleVault Required for presale markets (is_admin=false).
664
+ * Pass the ATA of the market_oracle PDA so 50% of fee goes there.
665
+ * For admin markets (is_admin=true) omit — payer is used as placeholder (no transfer).
666
+ */
667
+ matchOrders(taker: SignedOrder, makers: SignedOrder[], opts?: {
668
+ marketOracleVault?: PublicKey;
669
+ }): Promise<TxResult>;
534
670
  /** Add an address to the CLOB whitelist (owner only). */
535
671
  addToWhitelist(address: PublicKey): Promise<TxResult>;
536
672
  /** Batch-add addresses to the CLOB whitelist (owner only). All PDAs created in one tx. */
@@ -548,6 +684,97 @@ declare class ClobClient {
548
684
  isOrderCancelled(maker: PublicKey, nonce: anchor.BN): Promise<boolean>;
549
685
  }
550
686
 
687
+ interface PresaleInfo {
688
+ version: number;
689
+ questionMarketConfig: PublicKey;
690
+ presaleIndex: anchor.BN;
691
+ creator: PublicKey;
692
+ currencyMint: PublicKey;
693
+ qtMint: PublicKey;
694
+ price: anchor.BN;
695
+ startTime: anchor.BN;
696
+ endTime: anchor.BN;
697
+ status: "pending" | "approved" | "rejected";
698
+ soldTokenAmount: anchor.BN;
699
+ initialTokenAmountCreator: anchor.BN;
700
+ agentsRev: number;
701
+ companyRev: number;
702
+ referralAddress: PublicKey;
703
+ companyAddress: PublicKey;
704
+ isDistributeRevenue: boolean;
705
+ creatorClaimableRevenue: anchor.BN;
706
+ bump: number;
707
+ }
708
+ interface UserBuyRecord {
709
+ user: PublicKey;
710
+ presale: PublicKey;
711
+ currencyAmount: anchor.BN;
712
+ bump: number;
713
+ }
714
+ declare class PresaleClient {
715
+ private readonly program;
716
+ private readonly provider;
717
+ private readonly programIds;
718
+ constructor(program: anchor.Program, provider: anchor.AnchorProvider, programIds: ProgramIds);
719
+ get walletPubkey(): PublicKey;
720
+ presalePda(questionMarketConfig: PublicKey, presaleIndex: anchor.BN): PublicKey;
721
+ qtMintPda(presalePda: PublicKey): PublicKey;
722
+ qtAuthorityPda(presalePda: PublicKey): PublicKey;
723
+ userBuyRecordPda(presalePda: PublicKey, user: PublicKey): PublicKey;
724
+ /**
725
+ * Buy MST tokens during presale.
726
+ * qtAmount: amount of MST to receive (9 decimals).
727
+ * USDC cost = qtAmount * price / 1e9.
728
+ */
729
+ buy(presalePda: PublicKey, qtAmount: anchor.BN, buyer?: PublicKey, payer?: PublicKey, signers?: Keypair[]): Promise<TxResult>;
730
+ /**
731
+ * Refund: burn user's MST and return USDC.
732
+ * Only callable when presale status = Rejected.
733
+ */
734
+ refund(presalePda: PublicKey, user?: PublicKey, signers?: Keypair[]): Promise<TxResult>;
735
+ /**
736
+ * Creator claims their share of presale revenue after distribute_presale_revenue.
737
+ */
738
+ claimRevenue(presalePda: PublicKey, creator?: PublicKey, signers?: Keypair[]): Promise<TxResult>;
739
+ fetchPresale(presalePda: PublicKey): Promise<PresaleInfo | null>;
740
+ fetchUserBuyRecord(presalePda: PublicKey, user: PublicKey): Promise<UserBuyRecord | null>;
741
+ }
742
+
743
+ interface MarketOracleInfo {
744
+ version: number;
745
+ question: PublicKey;
746
+ questionMarketConfig: PublicKey;
747
+ currencyMint: PublicKey;
748
+ creator: PublicKey;
749
+ qtMint: PublicKey;
750
+ feesDistributed: boolean;
751
+ qtTotalSupply: anchor.BN;
752
+ totalClaimed: anchor.BN;
753
+ bump: number;
754
+ }
755
+ interface UserClaimRecord {
756
+ user: PublicKey;
757
+ marketOracle: PublicKey;
758
+ hasClaimed: boolean;
759
+ bump: number;
760
+ }
761
+ declare class MarketOracleClient {
762
+ private readonly program;
763
+ private readonly provider;
764
+ private readonly programIds;
765
+ constructor(program: anchor.Program, provider: anchor.AnchorProvider, programIds: ProgramIds);
766
+ get walletPubkey(): PublicKey;
767
+ marketOraclePda(questionPda: PublicKey): PublicKey;
768
+ userClaimRecordPda(marketOraclePda: PublicKey, user: PublicKey): PublicKey;
769
+ /**
770
+ * User burns their MST and claims proportional share of oracle vault USDC.
771
+ * Call after market.collectTradingFee snapshotted qt supply.
772
+ */
773
+ claimFeesShare(marketOraclePda: PublicKey, user?: PublicKey, payer?: PublicKey, signers?: Keypair[]): Promise<TxResult>;
774
+ fetchMarketOracle(marketOraclePda: PublicKey): Promise<MarketOracleInfo | null>;
775
+ fetchUserClaimRecord(marketOraclePda: PublicKey, user: PublicKey): Promise<UserClaimRecord | null>;
776
+ }
777
+
551
778
  declare class XMarketSDK {
552
779
  readonly provider: anchor.AnchorProvider;
553
780
  readonly networkConfig: NetworkConfig;
@@ -558,6 +785,9 @@ declare class XMarketSDK {
558
785
  private _market?;
559
786
  private _ctf?;
560
787
  private _clob?;
788
+ private _fee?;
789
+ private _presale?;
790
+ private _marketOracle?;
561
791
  constructor(config: NetworkConfig, wallet: anchor.Wallet, marketOwner?: PublicKey);
562
792
  private _withAddress;
563
793
  get oracle(): OracleClient;
@@ -565,6 +795,9 @@ declare class XMarketSDK {
565
795
  get market(): MarketClient;
566
796
  get ctf(): CtfClient;
567
797
  get clob(): ClobClient;
798
+ get fee(): FeeManagementClient;
799
+ get presale(): PresaleClient;
800
+ get marketOracle(): MarketOracleClient;
568
801
  }
569
802
 
570
803
  declare const SEEDS: {
@@ -584,6 +817,15 @@ declare const SEEDS: {
584
817
  readonly extraAccountMetas: Buffer<ArrayBuffer>;
585
818
  readonly clobConfig: Buffer<ArrayBuffer>;
586
819
  readonly order: Buffer<ArrayBuffer>;
820
+ readonly feeConfig: Buffer<ArrayBuffer>;
821
+ readonly questionFee: Buffer<ArrayBuffer>;
822
+ readonly marketFee: Buffer<ArrayBuffer>;
823
+ readonly presale: Buffer<ArrayBuffer>;
824
+ readonly qtMint: Buffer<ArrayBuffer>;
825
+ readonly qtAuthority: Buffer<ArrayBuffer>;
826
+ readonly userBuy: Buffer<ArrayBuffer>;
827
+ readonly marketOracle: Buffer<ArrayBuffer>;
828
+ readonly userClaim: Buffer<ArrayBuffer>;
587
829
  };
588
830
  declare class PDA {
589
831
  static questionMarketConfig(owner: PublicKey, programIds: Pick<ProgramIds, "questionMarket">): [PublicKey, number];
@@ -603,6 +845,15 @@ declare class PDA {
603
845
  static extraAccountMetaList(mint: PublicKey, programIds: Pick<ProgramIds, "hook">): [PublicKey, number];
604
846
  static clobConfig(programIds: Pick<ProgramIds, "clobExchange">): [PublicKey, number];
605
847
  static orderStatus(maker: PublicKey, nonce: BN, programIds: Pick<ProgramIds, "clobExchange">): [PublicKey, number];
848
+ static feeConfig(owner: PublicKey, programIds: Pick<ProgramIds, "feeManagement">): [PublicKey, number];
849
+ static questionFee(conditionPda: PublicKey, programIds: Pick<ProgramIds, "feeManagement">): [PublicKey, number];
850
+ static marketFeeOverride(conditionPda: PublicKey, programIds: Pick<ProgramIds, "feeManagement">): [PublicKey, number];
851
+ static presale(questionMarketConfig: PublicKey, presaleIndex: BN, programIds: Pick<ProgramIds, "presale">): [PublicKey, number];
852
+ static qtMint(presalePda: PublicKey, programIds: Pick<ProgramIds, "presale">): [PublicKey, number];
853
+ static qtAuthority(presalePda: PublicKey, programIds: Pick<ProgramIds, "presale">): [PublicKey, number];
854
+ static userBuyRecord(presalePda: PublicKey, user: PublicKey, programIds: Pick<ProgramIds, "presale">): [PublicKey, number];
855
+ static marketOraclePda(questionPda: PublicKey, programIds: Pick<ProgramIds, "marketOracle">): [PublicKey, number];
856
+ static userClaimRecord(marketOraclePda: PublicKey, user: PublicKey, programIds: Pick<ProgramIds, "marketOracle">): [PublicKey, number];
606
857
  }
607
858
  /** Unique 32-byte question ID: SHA-256(content + timestamp). Different each call. */
608
859
  declare function generateQuestionId(content: string, salt?: number): Uint8Array;
@@ -736,4 +987,4 @@ declare function buildApproveCollateralTx(collateralMint: PublicKey, signer: Pub
736
987
  */
737
988
  declare function buildApproveAllOutcomeTokensTx(condition: PublicKey, signer: PublicKey, payer: PublicKey, delegate: PublicKey, programIds: ProgramIds, amount?: BN): Transaction;
738
989
 
739
- export { AccountNotFoundError, ClobClient, type ClobConfig, type ClobWhitelistEntry, type CollateralConfig, type CollateralVault, type Condition, type CreateQuestionParams, CtfClient, type CtfConfig, HookClient, type HookConfig, IX_SYSVAR, InvalidParamError, MAX_APPROVE_AMOUNT, MarketClient, type MatchType, type NetworkConfig, type NetworkName, OracleClient, type OracleConfig, type Order, type OrderStatus, PDA, type Position, type ProgramIds, type Question, type QuestionMarketConfig, type QuestionResult, QuestionStatus, SEEDS, type SignedOrder, type TxResult, UnauthorizedError, XMarketError, XMarketSDK, buildApproveAllOutcomeTokensTx, buildApproveCollateralTx, buildBatchedEd25519Instruction, buildOrder, deserializeSignedOrder, detectMatchType, generateContentHash, generateQuestionId, getOrderSignBytes, serializeOrderToBytes, serializeSignedOrder, signOrder, signOrderWithKeypair, verifySignedOrder };
990
+ export { AccountNotFoundError, ClobClient, type ClobConfig, type ClobWhitelistEntry, type CollateralConfig, type CollateralVault, type Condition, type CreateQuestionParams, CtfClient, type CtfConfig, FEE_DENOMINATOR, FeeManagementClient, HookClient, type HookConfig, IX_SYSVAR, InvalidParamError, MAX_APPROVE_AMOUNT, MarketClient, MarketOracleClient, type MarketOracleInfo, type MatchType, type NetworkConfig, type NetworkName, OracleClient, type OracleConfig, type Order, type OrderStatus, PDA, type Position, PresaleClient, type PresaleInfo, type ProgramIds, type Question, type QuestionFee, type QuestionMarketConfig, type QuestionResult, QuestionStatus, SEEDS, type SignedOrder, type TxResult, UnauthorizedError, type UserBuyRecord, type UserClaimRecord, XMarketError, XMarketSDK, buildApproveAllOutcomeTokensTx, buildApproveCollateralTx, buildBatchedEd25519Instruction, buildOrder, deserializeSignedOrder, detectMatchType, generateContentHash, generateQuestionId, getOrderSignBytes, serializeOrderToBytes, serializeSignedOrder, signOrder, signOrderWithKeypair, verifySignedOrder };