@theliem/xmarket-sdk 3.0.0 → 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/{clob_exchange-ATSH42KC.json → clob_exchange-MQF4NI27.json} +2 -46
- package/dist/fee_management-VGF77YXG.json +1337 -0
- package/dist/index.d.mts +259 -8
- package/dist/index.d.ts +259 -8
- package/dist/index.js +853 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +849 -48
- package/dist/index.mjs.map +1 -1
- package/dist/market_oracle-E6UUARGR.json +699 -0
- package/dist/{oracle-FZJJIJGI.json → oracle-A5VOIMGM.json} +5 -0
- package/dist/presale-ZZJXXQS3.json +1792 -0
- package/dist/{question_market-CB6ZUZ5E.json → question_market-77YI4LRP.json} +965 -32
- package/package.json +7 -17
- package/src/idls/clob_exchange.json +2 -46
- package/src/idls/fee_management.json +1337 -0
- package/src/idls/market_oracle.json +699 -0
- package/src/idls/oracle.json +5 -0
- package/src/idls/presale.json +1792 -0
- package/src/idls/question_market.json +965 -32
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import * as anchor4 from '@coral-xyz/anchor';
|
|
2
|
-
import { SYSVAR_INSTRUCTIONS_PUBKEY, PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, TransactionInstruction, Ed25519Program, TransactionMessage, VersionedTransaction, Connection, Transaction } from '@solana/web3.js';
|
|
2
|
+
import { SYSVAR_INSTRUCTIONS_PUBKEY, PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, TransactionInstruction, Ed25519Program, AddressLookupTableProgram, TransactionMessage, VersionedTransaction, Connection, Transaction } from '@solana/web3.js';
|
|
3
3
|
import { createHash } from 'crypto';
|
|
4
|
-
import { TOKEN_2022_PROGRAM_ID,
|
|
5
|
-
import oracleIdl from './oracle-
|
|
4
|
+
import { TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, createApproveInstruction } from '@solana/spl-token';
|
|
5
|
+
import oracleIdl from './oracle-A5VOIMGM.json';
|
|
6
6
|
import hookIdl from './hook-THBRGUM6.json';
|
|
7
|
-
import questionMarketIdl from './question_market-
|
|
7
|
+
import questionMarketIdl from './question_market-77YI4LRP.json';
|
|
8
8
|
import conditionalTokensIdl from './conditional_tokens-3O5V46N5.json';
|
|
9
|
-
import clobExchangeIdl from './clob_exchange-
|
|
9
|
+
import clobExchangeIdl from './clob_exchange-MQF4NI27.json';
|
|
10
|
+
import feeManagementIdl from './fee_management-VGF77YXG.json';
|
|
11
|
+
import presaleIdl from './presale-ZZJXXQS3.json';
|
|
12
|
+
import marketOracleIdl from './market_oracle-E6UUARGR.json';
|
|
10
13
|
import BN4 from 'bn.js';
|
|
11
14
|
import * as nacl from 'tweetnacl';
|
|
12
15
|
|
|
@@ -27,7 +30,18 @@ var SEEDS = {
|
|
|
27
30
|
hookConfig: Buffer.from("hook_config"),
|
|
28
31
|
extraAccountMetas: Buffer.from("extra-account-metas"),
|
|
29
32
|
clobConfig: Buffer.from("clob_config"),
|
|
30
|
-
order: Buffer.from("order")
|
|
33
|
+
order: Buffer.from("order"),
|
|
34
|
+
feeConfig: Buffer.from("fee_config"),
|
|
35
|
+
questionFee: Buffer.from("question_fee"),
|
|
36
|
+
marketFee: Buffer.from("market_fee"),
|
|
37
|
+
// Presale
|
|
38
|
+
presale: Buffer.from("presale"),
|
|
39
|
+
qtMint: Buffer.from("qt_mint"),
|
|
40
|
+
qtAuthority: Buffer.from("qt_authority"),
|
|
41
|
+
userBuy: Buffer.from("user_buy"),
|
|
42
|
+
// Market Oracle
|
|
43
|
+
marketOracle: Buffer.from("market_oracle"),
|
|
44
|
+
userClaim: Buffer.from("user_claim")
|
|
31
45
|
};
|
|
32
46
|
var PDA = class {
|
|
33
47
|
// ─── Question Market ────────────────────────────────────────────────────────
|
|
@@ -139,6 +153,74 @@ var PDA = class {
|
|
|
139
153
|
programIds.clobExchange
|
|
140
154
|
);
|
|
141
155
|
}
|
|
156
|
+
// ─── Fee Management ─────────────────────────────────────────────────────────
|
|
157
|
+
static feeConfig(owner, programIds) {
|
|
158
|
+
if (!programIds.feeManagement) throw new Error("feeManagement program ID not configured");
|
|
159
|
+
return PublicKey.findProgramAddressSync(
|
|
160
|
+
[SEEDS.feeConfig, owner.toBuffer()],
|
|
161
|
+
programIds.feeManagement
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
static questionFee(conditionPda, programIds) {
|
|
165
|
+
if (!programIds.feeManagement) throw new Error("feeManagement program ID not configured");
|
|
166
|
+
return PublicKey.findProgramAddressSync(
|
|
167
|
+
[SEEDS.questionFee, conditionPda.toBuffer()],
|
|
168
|
+
programIds.feeManagement
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
static marketFeeOverride(conditionPda, programIds) {
|
|
172
|
+
if (!programIds.feeManagement) throw new Error("feeManagement program ID not configured");
|
|
173
|
+
return PublicKey.findProgramAddressSync(
|
|
174
|
+
[SEEDS.marketFee, conditionPda.toBuffer()],
|
|
175
|
+
programIds.feeManagement
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
// ─── Presale ─────────────────────────────────────────────────────────────────
|
|
179
|
+
static presale(questionMarketConfig, presaleIndex, programIds) {
|
|
180
|
+
if (!programIds.presale) throw new Error("presale program ID not configured");
|
|
181
|
+
const idxBuf = Buffer.alloc(8);
|
|
182
|
+
idxBuf.writeBigUInt64LE(BigInt(presaleIndex.toString()));
|
|
183
|
+
return PublicKey.findProgramAddressSync(
|
|
184
|
+
[SEEDS.presale, questionMarketConfig.toBuffer(), idxBuf],
|
|
185
|
+
programIds.presale
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
static qtMint(presalePda, programIds) {
|
|
189
|
+
if (!programIds.presale) throw new Error("presale program ID not configured");
|
|
190
|
+
return PublicKey.findProgramAddressSync(
|
|
191
|
+
[SEEDS.qtMint, presalePda.toBuffer()],
|
|
192
|
+
programIds.presale
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
static qtAuthority(presalePda, programIds) {
|
|
196
|
+
if (!programIds.presale) throw new Error("presale program ID not configured");
|
|
197
|
+
return PublicKey.findProgramAddressSync(
|
|
198
|
+
[SEEDS.qtAuthority, presalePda.toBuffer()],
|
|
199
|
+
programIds.presale
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
static userBuyRecord(presalePda, user, programIds) {
|
|
203
|
+
if (!programIds.presale) throw new Error("presale program ID not configured");
|
|
204
|
+
return PublicKey.findProgramAddressSync(
|
|
205
|
+
[SEEDS.userBuy, presalePda.toBuffer(), user.toBuffer()],
|
|
206
|
+
programIds.presale
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
// ─── Market Oracle ────────────────────────────────────────────────────────────
|
|
210
|
+
static marketOraclePda(questionPda, programIds) {
|
|
211
|
+
if (!programIds.marketOracle) throw new Error("marketOracle program ID not configured");
|
|
212
|
+
return PublicKey.findProgramAddressSync(
|
|
213
|
+
[SEEDS.marketOracle, questionPda.toBuffer()],
|
|
214
|
+
programIds.marketOracle
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
static userClaimRecord(marketOraclePda, user, programIds) {
|
|
218
|
+
if (!programIds.marketOracle) throw new Error("marketOracle program ID not configured");
|
|
219
|
+
return PublicKey.findProgramAddressSync(
|
|
220
|
+
[SEEDS.userClaim, marketOraclePda.toBuffer(), user.toBuffer()],
|
|
221
|
+
programIds.marketOracle
|
|
222
|
+
);
|
|
223
|
+
}
|
|
142
224
|
};
|
|
143
225
|
function generateQuestionId(content, salt) {
|
|
144
226
|
const input = content + (salt ?? Date.now());
|
|
@@ -218,6 +300,7 @@ var OracleClient = class {
|
|
|
218
300
|
async updateAdmin(newAdmin, ownerPubkey) {
|
|
219
301
|
const sig = await this.program.methods.updateAdmin(newAdmin).accounts({
|
|
220
302
|
owner: this.walletPubkey,
|
|
303
|
+
payer: this.walletPubkey,
|
|
221
304
|
oracleConfig: this.configPda(ownerPubkey)
|
|
222
305
|
}).rpc();
|
|
223
306
|
return { signature: sig };
|
|
@@ -399,6 +482,7 @@ var QuestionStatus = /* @__PURE__ */ ((QuestionStatus2) => {
|
|
|
399
482
|
QuestionStatus2["Resolved"] = "resolved";
|
|
400
483
|
return QuestionStatus2;
|
|
401
484
|
})(QuestionStatus || {});
|
|
485
|
+
var FEE_DENOMINATOR = 1e6;
|
|
402
486
|
var XMarketError = class extends Error {
|
|
403
487
|
constructor(message, code) {
|
|
404
488
|
super(message);
|
|
@@ -453,7 +537,7 @@ var MarketClient = class {
|
|
|
453
537
|
* @param payer - Pays rent for all new accounts (can differ from creator)
|
|
454
538
|
* @param creator - Identity of the question creator (signs but does not pay)
|
|
455
539
|
*/
|
|
456
|
-
async createQuestion(params, oracle, creator = this.walletPubkey, payer =
|
|
540
|
+
async createQuestion(params, oracle, creator = this.walletPubkey, payer = this.walletPubkey) {
|
|
457
541
|
const questionId = params.questionId ?? generateQuestionId(params.content);
|
|
458
542
|
const contentHash = params.contentHash ?? generateContentHash(params.content);
|
|
459
543
|
const [questionPda] = PDA.question(this.configPda, questionId, this.programIds);
|
|
@@ -492,7 +576,7 @@ var MarketClient = class {
|
|
|
492
576
|
* @param creator - Whitelisted creator (must be in whitelist or be admin/owner)
|
|
493
577
|
* @param payer - Fee payer (pays rent; can differ from creator)
|
|
494
578
|
*/
|
|
495
|
-
async createQuestionAdmin(params, oracle, creator = this.walletPubkey, payer =
|
|
579
|
+
async createQuestionAdmin(params, oracle, creator = this.walletPubkey, payer = this.walletPubkey) {
|
|
496
580
|
const questionId = params.questionId ?? generateQuestionId(params.content);
|
|
497
581
|
const contentHash = params.contentHash ?? generateContentHash(params.content);
|
|
498
582
|
const [questionPda] = PDA.question(this.configPda, questionId, this.programIds);
|
|
@@ -586,6 +670,7 @@ var MarketClient = class {
|
|
|
586
670
|
questionCount: acc.questionCount.toNumber(),
|
|
587
671
|
approvedCount: acc.approvedCount.toNumber(),
|
|
588
672
|
rejectedCount: acc.rejectedCount.toNumber(),
|
|
673
|
+
presaleCount: acc.presaleCount.toNumber(),
|
|
589
674
|
whitelist: acc.whitelist,
|
|
590
675
|
whitelistLen: acc.whitelistLen,
|
|
591
676
|
isPaused: acc.isPaused,
|
|
@@ -637,6 +722,157 @@ var MarketClient = class {
|
|
|
637
722
|
if (!q || !q.condition) return { yes: null, no: null };
|
|
638
723
|
return this.ctfClient.fetchBothPositions(q.condition, owner);
|
|
639
724
|
}
|
|
725
|
+
// ─── Presale instructions ────────────────────────────────────────────────────
|
|
726
|
+
/**
|
|
727
|
+
* Any user creates a presale + initial buy (question-market::create_presale).
|
|
728
|
+
* Reads agents_rev / company_rev from fee_config.
|
|
729
|
+
*
|
|
730
|
+
* @param feeConfig fee_management fee_config PDA (owner = feeConfigOwner)
|
|
731
|
+
* @param currencyMint collateral token (e.g. USDC)
|
|
732
|
+
* @param presaleIndex config.presale_count — fetch config first or pass 0 for first presale
|
|
733
|
+
*/
|
|
734
|
+
async createPresale(params, feeConfig, currencyMint, presaleIndex, creator = this.walletPubkey, payer = creator) {
|
|
735
|
+
if (!this.programIds.presale) throw new Error("presale program ID not configured");
|
|
736
|
+
const [presalePda] = PDA.presale(this.configPda, presaleIndex, this.programIds);
|
|
737
|
+
const [qtMint] = PDA.qtMint(presalePda, this.programIds);
|
|
738
|
+
const [qtAuthority] = PDA.qtAuthority(presalePda, this.programIds);
|
|
739
|
+
const [userBuyRecord] = PDA.userBuyRecord(presalePda, creator, this.programIds);
|
|
740
|
+
const presaleVault = getAssociatedTokenAddressSync(currencyMint, presalePda, true);
|
|
741
|
+
const creatorQtAta = getAssociatedTokenAddressSync(qtMint, creator);
|
|
742
|
+
const creatorCurrencyAta = getAssociatedTokenAddressSync(currencyMint, creator);
|
|
743
|
+
const tx = await this.program.methods.createPresale({
|
|
744
|
+
price: params.price,
|
|
745
|
+
startTime: params.startTime,
|
|
746
|
+
endTime: params.endTime,
|
|
747
|
+
initialBuyAmount: params.initialBuyAmount
|
|
748
|
+
}).accounts({
|
|
749
|
+
creator,
|
|
750
|
+
payer,
|
|
751
|
+
config: this.configPda,
|
|
752
|
+
feeConfig,
|
|
753
|
+
presale: presalePda,
|
|
754
|
+
qtMint,
|
|
755
|
+
qtAuthority,
|
|
756
|
+
currencyMint,
|
|
757
|
+
presaleVault,
|
|
758
|
+
creatorCurrencyAta,
|
|
759
|
+
creatorQtAta,
|
|
760
|
+
userBuyRecord,
|
|
761
|
+
presaleProgram: this.programIds.presale,
|
|
762
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
763
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
764
|
+
systemProgram: SystemProgram.programId,
|
|
765
|
+
rent: SYSVAR_RENT_PUBKEY
|
|
766
|
+
}).transaction();
|
|
767
|
+
return { tx, presalePda, qtMint };
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Whitelist-only: approve presale → creates question + CTF condition + market_oracle in one tx.
|
|
771
|
+
*
|
|
772
|
+
* @param presalePda the presale account
|
|
773
|
+
* @param contentHash 32-byte hash for question content
|
|
774
|
+
* @param hookProgram token-2022 transfer hook program
|
|
775
|
+
* @param authorizedClob clob program allowed to do CTF transfers
|
|
776
|
+
* @param expirationTime Unix seconds
|
|
777
|
+
* @param creator presale creator pubkey (stored in question)
|
|
778
|
+
* @param currencyMint collateral mint
|
|
779
|
+
*/
|
|
780
|
+
async approvePresale(presalePda, contentHash, hookProgram, authorizedClob, expirationTime, creator, currencyMint, caller = this.walletPubkey, payer = caller) {
|
|
781
|
+
if (!this.programIds.presale) throw new Error("presale program ID not configured");
|
|
782
|
+
if (!this.programIds.marketOracle) throw new Error("marketOracle program ID not configured");
|
|
783
|
+
const questionId = presalePda.toBytes();
|
|
784
|
+
const [questionPda] = PDA.question(this.configPda, questionId, this.programIds);
|
|
785
|
+
const marketConfig = await this.fetchConfig();
|
|
786
|
+
if (!marketConfig) throw new Error("QuestionMarketConfig not found");
|
|
787
|
+
const oraclePubkey = marketConfig.oracle;
|
|
788
|
+
const [conditionPda] = PDA.condition(oraclePubkey, questionId, this.programIds);
|
|
789
|
+
const [yesMint] = PDA.yesMint(conditionPda, this.programIds);
|
|
790
|
+
const [noMint] = PDA.noMint(conditionPda, this.programIds);
|
|
791
|
+
const [mintAuthority] = PDA.mintAuthority(conditionPda, this.programIds);
|
|
792
|
+
const [collateralVault] = PDA.collateralVault(currencyMint, this.programIds);
|
|
793
|
+
const [marketOraclePda] = PDA.marketOraclePda(questionPda, this.programIds);
|
|
794
|
+
const marketOracleVault = getAssociatedTokenAddressSync(currencyMint, marketOraclePda, true);
|
|
795
|
+
const tx = await this.program.methods.approvePresale({
|
|
796
|
+
contentHash: Array.from(contentHash),
|
|
797
|
+
hookProgram,
|
|
798
|
+
authorizedClob,
|
|
799
|
+
expirationTime,
|
|
800
|
+
creator
|
|
801
|
+
}).accounts({
|
|
802
|
+
caller,
|
|
803
|
+
payer,
|
|
804
|
+
config: this.configPda,
|
|
805
|
+
presale: presalePda,
|
|
806
|
+
question: questionPda,
|
|
807
|
+
currencyMint,
|
|
808
|
+
oracle: oraclePubkey,
|
|
809
|
+
condition: conditionPda,
|
|
810
|
+
yesMint,
|
|
811
|
+
noMint,
|
|
812
|
+
mintAuthority,
|
|
813
|
+
collateralVault,
|
|
814
|
+
marketOracle: marketOraclePda,
|
|
815
|
+
marketOracleVault,
|
|
816
|
+
conditionalTokensProgram: this.programIds.conditionalTokens,
|
|
817
|
+
presaleProgram: this.programIds.presale,
|
|
818
|
+
marketOracleProgram: this.programIds.marketOracle,
|
|
819
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
820
|
+
token2022Program: TOKEN_2022_PROGRAM_ID,
|
|
821
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
822
|
+
systemProgram: SystemProgram.programId,
|
|
823
|
+
rent: SYSVAR_RENT_PUBKEY
|
|
824
|
+
}).transaction();
|
|
825
|
+
return { tx, questionPda, conditionPda, marketOraclePda, marketOracleVault };
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Whitelist-only: reject presale so users can refund.
|
|
829
|
+
*/
|
|
830
|
+
async rejectPresale(presalePda, caller = this.walletPubkey) {
|
|
831
|
+
if (!this.programIds.presale) throw new Error("presale program ID not configured");
|
|
832
|
+
return this.program.methods.rejectPresale().accounts({
|
|
833
|
+
caller,
|
|
834
|
+
config: this.configPda,
|
|
835
|
+
presale: presalePda,
|
|
836
|
+
presaleProgram: this.programIds.presale
|
|
837
|
+
}).transaction();
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Whitelist-only: distribute presale vault funds → agents_rev% + company_rev% + rest to creator.
|
|
841
|
+
* Must be called after approvePresale.
|
|
842
|
+
*/
|
|
843
|
+
async collectPresaleRevenue(presalePda, currencyMint, referralAddress, companyAddress, caller = this.walletPubkey) {
|
|
844
|
+
if (!this.programIds.presale) throw new Error("presale program ID not configured");
|
|
845
|
+
const presaleVault = getAssociatedTokenAddressSync(currencyMint, presalePda, true);
|
|
846
|
+
const referralTokenAccount = getAssociatedTokenAddressSync(currencyMint, referralAddress);
|
|
847
|
+
const companyTokenAccount = getAssociatedTokenAddressSync(currencyMint, companyAddress);
|
|
848
|
+
return this.program.methods.collectPresaleRevenue().accounts({
|
|
849
|
+
caller,
|
|
850
|
+
config: this.configPda,
|
|
851
|
+
presale: presalePda,
|
|
852
|
+
presaleVault,
|
|
853
|
+
currencyMint,
|
|
854
|
+
referralTokenAccount,
|
|
855
|
+
companyTokenAccount,
|
|
856
|
+
presaleProgram: this.programIds.presale,
|
|
857
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
858
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
859
|
+
systemProgram: SystemProgram.programId
|
|
860
|
+
}).transaction();
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Whitelist-only: snapshot MST supply so holders can claim trading fees.
|
|
864
|
+
* Call after oracle resolves the question.
|
|
865
|
+
*/
|
|
866
|
+
async collectTradingFee(marketOraclePda, qtMint, caller = this.walletPubkey) {
|
|
867
|
+
if (!this.programIds.marketOracle) throw new Error("marketOracle program ID not configured");
|
|
868
|
+
return this.program.methods.collectTradingFee().accounts({
|
|
869
|
+
caller,
|
|
870
|
+
config: this.configPda,
|
|
871
|
+
marketOracle: marketOraclePda,
|
|
872
|
+
qtMint,
|
|
873
|
+
marketOracleProgram: this.programIds.marketOracle
|
|
874
|
+
}).transaction();
|
|
875
|
+
}
|
|
640
876
|
};
|
|
641
877
|
var CtfClient = class {
|
|
642
878
|
constructor(program, provider, programIds) {
|
|
@@ -1046,14 +1282,138 @@ var IX_SYSVAR = SYSVAR_INSTRUCTIONS_PUBKEY;
|
|
|
1046
1282
|
// src/programs/clob.ts
|
|
1047
1283
|
var CLOB_WHITELIST_SEED = Buffer.from("clob_whitelist");
|
|
1048
1284
|
var ClobClient = class {
|
|
1049
|
-
constructor(program, provider, programIds) {
|
|
1285
|
+
constructor(program, provider, programIds, networkConfig) {
|
|
1286
|
+
/** ALT cache: condition.toBase58() → loaded ALT account */
|
|
1287
|
+
this._altCache = /* @__PURE__ */ new Map();
|
|
1050
1288
|
this.program = program;
|
|
1051
1289
|
this.provider = provider;
|
|
1052
1290
|
this.programIds = programIds;
|
|
1291
|
+
this.networkConfig = networkConfig;
|
|
1292
|
+
}
|
|
1293
|
+
async companyAddress() {
|
|
1294
|
+
if (!this.feeClient || !this.feeConfigOwner) return void 0;
|
|
1295
|
+
if (!this._companyAddress) {
|
|
1296
|
+
const cfg = await this.feeClient.fetchFeeConfig(this.feeConfigOwner);
|
|
1297
|
+
if (cfg) this._companyAddress = cfg.companyAddress;
|
|
1298
|
+
}
|
|
1299
|
+
return this._companyAddress;
|
|
1053
1300
|
}
|
|
1054
1301
|
get walletPubkey() {
|
|
1055
1302
|
return this.provider.wallet.publicKey;
|
|
1056
1303
|
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Get or create an ALT for a condition.
|
|
1306
|
+
* First call: creates + extends ALT on-chain, waits for activation (~2s).
|
|
1307
|
+
* Subsequent calls for same condition: returns cached ALT instantly.
|
|
1308
|
+
* BE devs never interact with this — called automatically by matchOrders.
|
|
1309
|
+
*/
|
|
1310
|
+
async ensureAlt(condition, collateralMint, buyerPubkey, buyerNonce, makers) {
|
|
1311
|
+
const cacheKey = condition.toBase58();
|
|
1312
|
+
if (this._altCache.has(cacheKey)) {
|
|
1313
|
+
return this._altCache.get(cacheKey);
|
|
1314
|
+
}
|
|
1315
|
+
const { connection } = this.provider;
|
|
1316
|
+
const payer = this.walletPubkey;
|
|
1317
|
+
const [yesMint] = PDA.yesMint(condition, this.programIds);
|
|
1318
|
+
const [extraAccountMeta] = PDA.extraAccountMetaList(yesMint, this.programIds);
|
|
1319
|
+
const [hookConfig] = PDA.hookConfig(this.programIds);
|
|
1320
|
+
const [buyOrderStatus] = PDA.orderStatus(buyerPubkey, buyerNonce, this.programIds);
|
|
1321
|
+
const [buyerPosition] = PDA.position(condition, 1, buyerPubkey, this.programIds);
|
|
1322
|
+
const clobConfigPda = this.configPda();
|
|
1323
|
+
const feeRecipientAddr = (await this.fetchConfig())?.feeRecipient;
|
|
1324
|
+
const addresses = [
|
|
1325
|
+
// instruction program IDs — must be in ALT to keep static keys minimal
|
|
1326
|
+
Ed25519Program.programId,
|
|
1327
|
+
this.programIds.clobExchange,
|
|
1328
|
+
// other programs
|
|
1329
|
+
this.programIds.conditionalTokens,
|
|
1330
|
+
this.programIds.hook,
|
|
1331
|
+
TOKEN_PROGRAM_ID,
|
|
1332
|
+
TOKEN_2022_PROGRAM_ID,
|
|
1333
|
+
SystemProgram.programId,
|
|
1334
|
+
SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
1335
|
+
// config PDAs
|
|
1336
|
+
clobConfigPda,
|
|
1337
|
+
hookConfig,
|
|
1338
|
+
this.whitelistEntryPda(payer),
|
|
1339
|
+
// condition PDAs
|
|
1340
|
+
condition,
|
|
1341
|
+
yesMint,
|
|
1342
|
+
extraAccountMeta,
|
|
1343
|
+
// buyer pubkey + ATAs + PDAs
|
|
1344
|
+
buyerPubkey,
|
|
1345
|
+
getAssociatedTokenAddressSync(collateralMint, buyerPubkey),
|
|
1346
|
+
getAssociatedTokenAddressSync(yesMint, buyerPubkey, false, TOKEN_2022_PROGRAM_ID),
|
|
1347
|
+
buyerPosition,
|
|
1348
|
+
buyOrderStatus
|
|
1349
|
+
];
|
|
1350
|
+
if (feeRecipientAddr) addresses.push(feeRecipientAddr);
|
|
1351
|
+
for (const m of makers) {
|
|
1352
|
+
const seller = m.order.maker;
|
|
1353
|
+
const [sellerPos] = PDA.position(condition, 1, seller, this.programIds);
|
|
1354
|
+
const [sellerStatus] = PDA.orderStatus(seller, m.order.nonce, this.programIds);
|
|
1355
|
+
addresses.push(
|
|
1356
|
+
seller,
|
|
1357
|
+
getAssociatedTokenAddressSync(yesMint, seller, false, TOKEN_2022_PROGRAM_ID),
|
|
1358
|
+
getAssociatedTokenAddressSync(collateralMint, seller),
|
|
1359
|
+
sellerPos,
|
|
1360
|
+
sellerStatus
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
if (this.programIds.feeManagement && this.feeConfigOwner) {
|
|
1364
|
+
const companyAddr = await this.companyAddress();
|
|
1365
|
+
addresses.push(
|
|
1366
|
+
this.programIds.feeManagement,
|
|
1367
|
+
PDA.feeConfig(this.feeConfigOwner, this.programIds)[0],
|
|
1368
|
+
PDA.marketFeeOverride(condition, this.programIds)[0]
|
|
1369
|
+
);
|
|
1370
|
+
if (companyAddr) {
|
|
1371
|
+
addresses.push(getAssociatedTokenAddressSync(collateralMint, companyAddr));
|
|
1372
|
+
}
|
|
1373
|
+
addresses.push(payer);
|
|
1374
|
+
}
|
|
1375
|
+
const slot = await connection.getSlot("finalized");
|
|
1376
|
+
const [createIx, altAddress] = AddressLookupTableProgram.createLookupTable({
|
|
1377
|
+
authority: payer,
|
|
1378
|
+
payer,
|
|
1379
|
+
recentSlot: slot
|
|
1380
|
+
});
|
|
1381
|
+
const BATCH = 30;
|
|
1382
|
+
const extendIxs = [];
|
|
1383
|
+
for (let i = 0; i < addresses.length; i += BATCH) {
|
|
1384
|
+
extendIxs.push(AddressLookupTableProgram.extendLookupTable({
|
|
1385
|
+
payer,
|
|
1386
|
+
authority: payer,
|
|
1387
|
+
lookupTable: altAddress,
|
|
1388
|
+
addresses: addresses.slice(i, i + BATCH)
|
|
1389
|
+
}));
|
|
1390
|
+
}
|
|
1391
|
+
await this._sendLegacyTx([createIx, extendIxs[0]]);
|
|
1392
|
+
for (let i = 1; i < extendIxs.length; i++) {
|
|
1393
|
+
await this._sendLegacyTx([extendIxs[i]]);
|
|
1394
|
+
}
|
|
1395
|
+
for (let attempt = 0; attempt < 30; attempt++) {
|
|
1396
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
1397
|
+
const res = await connection.getAddressLookupTable(altAddress);
|
|
1398
|
+
if (res.value && res.value.state.addresses.length === addresses.length) {
|
|
1399
|
+
this._altCache.set(cacheKey, res.value);
|
|
1400
|
+
return res.value;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
throw new Error(`ALT ${altAddress.toBase58()} not active after 30s`);
|
|
1404
|
+
}
|
|
1405
|
+
async _sendLegacyTx(instructions) {
|
|
1406
|
+
const { connection } = this.provider;
|
|
1407
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
1408
|
+
const { Transaction: Transaction3 } = await import('@solana/web3.js');
|
|
1409
|
+
const tx = new Transaction3();
|
|
1410
|
+
tx.recentBlockhash = blockhash;
|
|
1411
|
+
tx.feePayer = this.walletPubkey;
|
|
1412
|
+
tx.add(...instructions);
|
|
1413
|
+
const signed = await this.provider.wallet.signTransaction(tx);
|
|
1414
|
+
const sig = await connection.sendRawTransaction(signed.serialize());
|
|
1415
|
+
await connection.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, "confirmed");
|
|
1416
|
+
}
|
|
1057
1417
|
/**
|
|
1058
1418
|
* Send a match transaction as versioned (v0).
|
|
1059
1419
|
* Pass a pre-built AddressLookupTableAccount to compress account keys and
|
|
@@ -1063,7 +1423,7 @@ var ClobClient = class {
|
|
|
1063
1423
|
* If `whitelistedWallet` is provided and differs from `this.provider.wallet`,
|
|
1064
1424
|
* both wallets sign the transaction (whitelisted operator + payer).
|
|
1065
1425
|
*/
|
|
1066
|
-
async
|
|
1426
|
+
async sendMatchTx(instructions, lookupTable, whitelistedWallet) {
|
|
1067
1427
|
const { connection } = this.provider;
|
|
1068
1428
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
1069
1429
|
const message = new TransactionMessage({
|
|
@@ -1172,7 +1532,13 @@ var ClobClient = class {
|
|
|
1172
1532
|
*
|
|
1173
1533
|
* remaining_accounts: [hook×3] [seller×5 × N]
|
|
1174
1534
|
*/
|
|
1175
|
-
|
|
1535
|
+
/** Build Ed25519 + matchComplementary instructions without sending.
|
|
1536
|
+
*
|
|
1537
|
+
* If `buySigned.order.fee > 0` and `feeClient` + `feeConfigOwner` are wired in,
|
|
1538
|
+
* automatically appends 5 fee_management remaining_accounts so the program CPIs
|
|
1539
|
+
* to distribute_fee internally. No manual `feeDistribute` param needed.
|
|
1540
|
+
*/
|
|
1541
|
+
async buildMatchComplementaryIxs(buySigned, makersSigned, collateralMint, feeRecipient, whitelisted, opts) {
|
|
1176
1542
|
const condition = buySigned.order.condition;
|
|
1177
1543
|
const tokenId = buySigned.order.tokenId;
|
|
1178
1544
|
const [outcomeMint] = tokenId === 1 ? PDA.yesMint(condition, this.programIds) : PDA.noMint(condition, this.programIds);
|
|
@@ -1202,12 +1568,23 @@ var ClobClient = class {
|
|
|
1202
1568
|
{ pubkey: sellOrderStatus, isSigner: false, isWritable: true }
|
|
1203
1569
|
];
|
|
1204
1570
|
});
|
|
1205
|
-
|
|
1571
|
+
let feeAccounts = [];
|
|
1572
|
+
if (buySigned.order.fee.gtn(0) && this.programIds.feeManagement && this.feeConfigOwner) {
|
|
1573
|
+
const companyAddr = await this.companyAddress();
|
|
1574
|
+
if (companyAddr) {
|
|
1575
|
+
const oracleVault = opts?.marketOracleVault ?? this.walletPubkey;
|
|
1576
|
+
feeAccounts = [
|
|
1577
|
+
{ pubkey: this.programIds.feeManagement, isSigner: false, isWritable: false },
|
|
1578
|
+
{ pubkey: PDA.feeConfig(this.feeConfigOwner, this.programIds)[0], isSigner: false, isWritable: false },
|
|
1579
|
+
{ pubkey: PDA.marketFeeOverride(condition, this.programIds)[0], isSigner: false, isWritable: false },
|
|
1580
|
+
{ pubkey: getAssociatedTokenAddressSync(collateralMint, companyAddr), isSigner: false, isWritable: true },
|
|
1581
|
+
{ pubkey: oracleVault, isSigner: false, isWritable: true }
|
|
1582
|
+
];
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1206
1585
|
const whitelistEntry = this.whitelistEntryPda(whitelisted);
|
|
1207
1586
|
const makerNonces = makersSigned.map((m) => m.order.nonce);
|
|
1208
|
-
const
|
|
1209
|
-
buildBatchedEd25519Instruction([buySigned, ...makersSigned])
|
|
1210
|
-
];
|
|
1587
|
+
const ed25519Ix = buildBatchedEd25519Instruction([buySigned, ...makersSigned]);
|
|
1211
1588
|
const matchIx = await this.program.methods.matchComplementary(buySigned.order.nonce, makerNonces).accounts({
|
|
1212
1589
|
whitelisted,
|
|
1213
1590
|
payer: this.walletPubkey,
|
|
@@ -1226,12 +1603,19 @@ var ClobClient = class {
|
|
|
1226
1603
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
1227
1604
|
token2022Program: TOKEN_2022_PROGRAM_ID,
|
|
1228
1605
|
systemProgram: SystemProgram.programId
|
|
1229
|
-
}).remainingAccounts([...hookAccounts, ...makerAccounts]).instruction();
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1606
|
+
}).remainingAccounts([...hookAccounts, ...makerAccounts, ...feeAccounts]).instruction();
|
|
1607
|
+
return [ed25519Ix, matchIx];
|
|
1608
|
+
}
|
|
1609
|
+
async matchComplementary(buySigned, makersSigned, collateralMint, feeRecipient, whitelistedWallet, lookupTable, opts) {
|
|
1610
|
+
const ixs = await this.buildMatchComplementaryIxs(
|
|
1611
|
+
buySigned,
|
|
1612
|
+
makersSigned,
|
|
1613
|
+
collateralMint,
|
|
1614
|
+
feeRecipient,
|
|
1615
|
+
whitelistedWallet.publicKey,
|
|
1616
|
+
opts
|
|
1234
1617
|
);
|
|
1618
|
+
const sig = await this.sendMatchTx(ixs, lookupTable, whitelistedWallet);
|
|
1235
1619
|
return { signature: sig };
|
|
1236
1620
|
}
|
|
1237
1621
|
/**
|
|
@@ -1244,14 +1628,13 @@ var ClobClient = class {
|
|
|
1244
1628
|
*
|
|
1245
1629
|
* remaining_accounts: [maker×5 × N] (no hook accounts — mint_to doesn't fire hook)
|
|
1246
1630
|
*/
|
|
1247
|
-
async matchMintOrders(yesSigned, makersSigned, collateralMint, whitelistedWallet, lookupTable) {
|
|
1631
|
+
async matchMintOrders(yesSigned, makersSigned, collateralMint, feeRecipient, whitelistedWallet, lookupTable) {
|
|
1248
1632
|
const condition = yesSigned.order.condition;
|
|
1249
1633
|
const [yesMint] = PDA.yesMint(condition, this.programIds);
|
|
1250
1634
|
const [noMint] = PDA.noMint(condition, this.programIds);
|
|
1251
1635
|
const [mintAuthority] = PDA.mintAuthority(condition, this.programIds);
|
|
1252
1636
|
const [collateralVault] = PDA.collateralVault(collateralMint, this.programIds);
|
|
1253
1637
|
const [vaultTokenAccount] = PDA.vaultToken(collateralMint, this.programIds);
|
|
1254
|
-
const [clobAuthority] = PDA.clobConfig(this.programIds);
|
|
1255
1638
|
const buyerYes = yesSigned.order.maker;
|
|
1256
1639
|
const buyerYesCollateral = getAssociatedTokenAddressSync(collateralMint, buyerYes);
|
|
1257
1640
|
const buyerYesTokenAccount = getAssociatedTokenAddressSync(yesMint, buyerYes, false, TOKEN_2022_PROGRAM_ID);
|
|
@@ -1294,13 +1677,20 @@ var ClobClient = class {
|
|
|
1294
1677
|
yesMint,
|
|
1295
1678
|
noMint,
|
|
1296
1679
|
mintAuthority,
|
|
1297
|
-
|
|
1680
|
+
feeRecipient,
|
|
1298
1681
|
conditionalTokensProgram: this.programIds.conditionalTokens,
|
|
1299
1682
|
collateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
1300
1683
|
token2022Program: TOKEN_2022_PROGRAM_ID,
|
|
1301
1684
|
systemProgram: SystemProgram.programId
|
|
1302
1685
|
}).remainingAccounts(makerAccounts).instruction();
|
|
1303
|
-
const
|
|
1686
|
+
const frKey = feeRecipient.toBase58();
|
|
1687
|
+
for (const k of matchIx.keys) {
|
|
1688
|
+
if (k.pubkey.toBase58() === frKey) {
|
|
1689
|
+
k.isWritable = true;
|
|
1690
|
+
break;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
const sig = await this.sendMatchTx(
|
|
1304
1694
|
[...ed25519Ixs, matchIx],
|
|
1305
1695
|
lookupTable,
|
|
1306
1696
|
whitelistedWallet
|
|
@@ -1317,13 +1707,12 @@ var ClobClient = class {
|
|
|
1317
1707
|
*
|
|
1318
1708
|
* remaining_accounts: [maker×5 × N] (no hook accounts — burn doesn't fire hook)
|
|
1319
1709
|
*/
|
|
1320
|
-
async matchMergeOrders(yesSigned, makersSigned, collateralMint, whitelistedWallet, lookupTable) {
|
|
1710
|
+
async matchMergeOrders(yesSigned, makersSigned, collateralMint, feeRecipient, whitelistedWallet, lookupTable) {
|
|
1321
1711
|
const condition = yesSigned.order.condition;
|
|
1322
1712
|
const [yesMint] = PDA.yesMint(condition, this.programIds);
|
|
1323
1713
|
const [noMint] = PDA.noMint(condition, this.programIds);
|
|
1324
1714
|
const [collateralVault] = PDA.collateralVault(collateralMint, this.programIds);
|
|
1325
1715
|
const [vaultTokenAccount] = PDA.vaultToken(collateralMint, this.programIds);
|
|
1326
|
-
const [clobAuthority] = PDA.clobConfig(this.programIds);
|
|
1327
1716
|
const sellerYes = yesSigned.order.maker;
|
|
1328
1717
|
const sellerYesTokenAccount = getAssociatedTokenAddressSync(yesMint, sellerYes, false, TOKEN_2022_PROGRAM_ID);
|
|
1329
1718
|
const [sellerYesPosition] = PDA.position(condition, 1, sellerYes, this.programIds);
|
|
@@ -1365,13 +1754,20 @@ var ClobClient = class {
|
|
|
1365
1754
|
vaultTokenAccount,
|
|
1366
1755
|
yesMint,
|
|
1367
1756
|
noMint,
|
|
1368
|
-
|
|
1757
|
+
feeRecipient,
|
|
1369
1758
|
conditionalTokensProgram: this.programIds.conditionalTokens,
|
|
1370
1759
|
collateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
1371
1760
|
token2022Program: TOKEN_2022_PROGRAM_ID,
|
|
1372
1761
|
systemProgram: SystemProgram.programId
|
|
1373
1762
|
}).remainingAccounts(makerAccounts).instruction();
|
|
1374
|
-
const
|
|
1763
|
+
const frKeyM = feeRecipient.toBase58();
|
|
1764
|
+
for (const k of matchIx.keys) {
|
|
1765
|
+
if (k.pubkey.toBase58() === frKeyM) {
|
|
1766
|
+
k.isWritable = true;
|
|
1767
|
+
break;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
const sig = await this.sendMatchTx(
|
|
1375
1771
|
[...ed25519Ixs, matchIx],
|
|
1376
1772
|
lookupTable,
|
|
1377
1773
|
whitelistedWallet
|
|
@@ -1389,15 +1785,37 @@ var ClobClient = class {
|
|
|
1389
1785
|
*
|
|
1390
1786
|
* All makers must have the same tokenId and side as makers[0].
|
|
1391
1787
|
*/
|
|
1392
|
-
|
|
1788
|
+
/**
|
|
1789
|
+
* Auto-detect match type and execute in a single transaction.
|
|
1790
|
+
* ALT is managed automatically (created on first call per condition, cached thereafter).
|
|
1791
|
+
* feeRecipient and collateralMint are derived from on-chain config.
|
|
1792
|
+
* Fee distribution (distribute_fee CPI) fires automatically when order.fee > 0.
|
|
1793
|
+
*
|
|
1794
|
+
* @param opts.marketOracleVault Required for presale markets (is_admin=false).
|
|
1795
|
+
* Pass the ATA of the market_oracle PDA so 50% of fee goes there.
|
|
1796
|
+
* For admin markets (is_admin=true) omit — payer is used as placeholder (no transfer).
|
|
1797
|
+
*/
|
|
1798
|
+
async matchOrders(taker, makers, opts) {
|
|
1393
1799
|
if (makers.length === 0) throw new InvalidParamError("At least 1 maker required");
|
|
1800
|
+
const collateralMint = this.networkConfig.defaultCollateral.mint;
|
|
1801
|
+
const cfg = await this.fetchConfig();
|
|
1802
|
+
if (!cfg) throw new InvalidParamError("CLOB config not found on-chain");
|
|
1803
|
+
const feeRecipient = cfg.feeRecipient;
|
|
1804
|
+
const whitelistedWallet = this.provider.wallet;
|
|
1805
|
+
const alt = await this.ensureAlt(
|
|
1806
|
+
taker.order.condition,
|
|
1807
|
+
collateralMint,
|
|
1808
|
+
taker.order.maker,
|
|
1809
|
+
taker.order.nonce,
|
|
1810
|
+
makers
|
|
1811
|
+
);
|
|
1394
1812
|
const t = taker.order;
|
|
1395
1813
|
const m0 = makers[0].order;
|
|
1396
|
-
const SIDE_BUY =
|
|
1397
|
-
const SIDE_SELL =
|
|
1814
|
+
const SIDE_BUY = 0;
|
|
1815
|
+
const SIDE_SELL = 1;
|
|
1398
1816
|
if (t.tokenId === m0.tokenId) {
|
|
1399
1817
|
if (t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_SELL)) {
|
|
1400
|
-
return this.matchComplementary(taker, makers, collateralMint, feeRecipient, whitelistedWallet,
|
|
1818
|
+
return this.matchComplementary(taker, makers, collateralMint, feeRecipient, whitelistedWallet, alt, opts);
|
|
1401
1819
|
}
|
|
1402
1820
|
if (t.side === SIDE_SELL && makers.every((m) => m.order.side === SIDE_BUY)) {
|
|
1403
1821
|
throw new InvalidParamError("COMPLEMENTARY N-maker: taker must be the BUY side");
|
|
@@ -1406,19 +1824,11 @@ var ClobClient = class {
|
|
|
1406
1824
|
}
|
|
1407
1825
|
const allBuy = t.side === SIDE_BUY && makers.every((m) => m.order.side === SIDE_BUY);
|
|
1408
1826
|
const allSell = t.side === SIDE_SELL && makers.every((m) => m.order.side === SIDE_SELL);
|
|
1409
|
-
if (!allBuy && !allSell)
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
if (
|
|
1413
|
-
|
|
1414
|
-
}
|
|
1415
|
-
if (!makers.every((m) => m.order.tokenId === 0)) {
|
|
1416
|
-
throw new InvalidParamError("MINT/MERGE: all makers must be the NO side (tokenId=0)");
|
|
1417
|
-
}
|
|
1418
|
-
if (allBuy) {
|
|
1419
|
-
return this.matchMintOrders(taker, makers, collateralMint, whitelistedWallet, lookupTable);
|
|
1420
|
-
}
|
|
1421
|
-
return this.matchMergeOrders(taker, makers, collateralMint, whitelistedWallet, lookupTable);
|
|
1827
|
+
if (!allBuy && !allSell) throw new InvalidParamError("MINT/MERGE: all orders must be same side");
|
|
1828
|
+
if (t.tokenId !== 1) throw new InvalidParamError("MINT/MERGE: taker must be YES (tokenId=1)");
|
|
1829
|
+
if (!makers.every((m) => m.order.tokenId === 0)) throw new InvalidParamError("MINT/MERGE: makers must be NO (tokenId=0)");
|
|
1830
|
+
if (allBuy) return this.matchMintOrders(taker, makers, collateralMint, feeRecipient, whitelistedWallet, alt);
|
|
1831
|
+
return this.matchMergeOrders(taker, makers, collateralMint, feeRecipient, whitelistedWallet, alt);
|
|
1422
1832
|
}
|
|
1423
1833
|
// ─── Whitelist admin ─────────────────────────────────────────────────────────
|
|
1424
1834
|
/** Add an address to the CLOB whitelist (owner only). */
|
|
@@ -1517,6 +1927,369 @@ var ClobClient = class {
|
|
|
1517
1927
|
return status?.isCancelled === true;
|
|
1518
1928
|
}
|
|
1519
1929
|
};
|
|
1930
|
+
var FeeManagementClient = class {
|
|
1931
|
+
constructor(program, provider, programIds) {
|
|
1932
|
+
this.program = program;
|
|
1933
|
+
this.provider = provider;
|
|
1934
|
+
this.programIds = programIds;
|
|
1935
|
+
}
|
|
1936
|
+
async initFeeConfig(admin, companyAddress, referralAddress, presaleRevenueAddress, investorsMarketRev, companyMarketRev, agentsPresaleRev, companyPresaleRev, authority, payer) {
|
|
1937
|
+
const [feeConfigPda] = PDA.feeConfig(authority, this.programIds);
|
|
1938
|
+
const sig = await this.program.methods.initialize({
|
|
1939
|
+
admin,
|
|
1940
|
+
companyAddress,
|
|
1941
|
+
referralAddress,
|
|
1942
|
+
presaleRevenueAddress,
|
|
1943
|
+
investorsMarketRev,
|
|
1944
|
+
companyMarketRev,
|
|
1945
|
+
agentsPresaleRev,
|
|
1946
|
+
companyPresaleRev
|
|
1947
|
+
}).accounts({
|
|
1948
|
+
authority,
|
|
1949
|
+
payer,
|
|
1950
|
+
feeConfig: feeConfigPda,
|
|
1951
|
+
systemProgram: SystemProgram.programId
|
|
1952
|
+
}).signers([]).rpc();
|
|
1953
|
+
return { signature: sig };
|
|
1954
|
+
}
|
|
1955
|
+
async fetchFeeConfig(owner) {
|
|
1956
|
+
try {
|
|
1957
|
+
const [pda] = PDA.feeConfig(owner, this.programIds);
|
|
1958
|
+
return await this.program.account.feeConfig.fetch(pda);
|
|
1959
|
+
} catch {
|
|
1960
|
+
return null;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Fetch per-question fees for a condition.
|
|
1965
|
+
* Returns null if no fees have been set yet.
|
|
1966
|
+
*/
|
|
1967
|
+
async fetchQuestionFee(conditionPda) {
|
|
1968
|
+
try {
|
|
1969
|
+
const [pda] = PDA.questionFee(conditionPda, this.programIds);
|
|
1970
|
+
const acc = await this.program.account.questionFee.fetch(pda);
|
|
1971
|
+
return {
|
|
1972
|
+
conditionId: new Uint8Array(acc.conditionId),
|
|
1973
|
+
mergeFee: acc.mergeFee,
|
|
1974
|
+
redeemFee: acc.redeemFee,
|
|
1975
|
+
swapFee: acc.swapFee,
|
|
1976
|
+
bump: acc.bump
|
|
1977
|
+
};
|
|
1978
|
+
} catch {
|
|
1979
|
+
return null;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
/**
|
|
1983
|
+
* Set per-question fees for a condition.
|
|
1984
|
+
* @param conditionPda - condition PDA from the question
|
|
1985
|
+
* @param mergeFee - fee out of FEE_DENOMINATOR (1_000_000), e.g. 2_000 = 0.2%
|
|
1986
|
+
* @param redeemFee - fee out of FEE_DENOMINATOR
|
|
1987
|
+
* @param swapFee - trading fee out of FEE_DENOMINATOR
|
|
1988
|
+
* @param feeConfigOwner - pubkey that owns the fee_config PDA (usually market deployer)
|
|
1989
|
+
* @param authority - signer authorized in fee_config whitelist / admin / owner
|
|
1990
|
+
* @param payer - rent + tx fee payer
|
|
1991
|
+
*/
|
|
1992
|
+
async updateFeeConfig(companyAddress, referralAddress, presaleRevenueAddress, investorsMarketRev, companyMarketRev, agentsPresaleRev, companyPresaleRev, authority, payer) {
|
|
1993
|
+
const [feeConfigPda] = PDA.feeConfig(authority, this.programIds);
|
|
1994
|
+
const sig = await this.program.methods.updateConfig({
|
|
1995
|
+
companyAddress,
|
|
1996
|
+
referralAddress,
|
|
1997
|
+
presaleRevenueAddress,
|
|
1998
|
+
investorsMarketRev,
|
|
1999
|
+
companyMarketRev,
|
|
2000
|
+
agentsPresaleRev,
|
|
2001
|
+
companyPresaleRev
|
|
2002
|
+
}).accounts({
|
|
2003
|
+
authority,
|
|
2004
|
+
payer,
|
|
2005
|
+
feeConfig: feeConfigPda
|
|
2006
|
+
}).signers([]).rpc();
|
|
2007
|
+
return { signature: sig };
|
|
2008
|
+
}
|
|
2009
|
+
async setMarketFeeOverride(conditionPda, investors, company, isAdmin, feeConfigOwner, authority, payer) {
|
|
2010
|
+
const [feeConfigPda] = PDA.feeConfig(feeConfigOwner, this.programIds);
|
|
2011
|
+
const [marketFeeOverridePda] = PDA.marketFeeOverride(conditionPda, this.programIds);
|
|
2012
|
+
const sig = await this.program.methods.setMarketFeeOverride(conditionPda, investors, company, isAdmin).accounts({
|
|
2013
|
+
authority,
|
|
2014
|
+
payer,
|
|
2015
|
+
feeConfig: feeConfigPda,
|
|
2016
|
+
marketFeeOverride: marketFeeOverridePda,
|
|
2017
|
+
systemProgram: SystemProgram.programId
|
|
2018
|
+
}).signers([]).rpc();
|
|
2019
|
+
return { signature: sig };
|
|
2020
|
+
}
|
|
2021
|
+
async buildDistributeFeeIx(conditionPda, amount, feeConfigOwner, sourceAta, companyAta, marketOracleVault, authority) {
|
|
2022
|
+
const [feeConfigPda] = PDA.feeConfig(feeConfigOwner, this.programIds);
|
|
2023
|
+
const [marketFeeOverridePda] = PDA.marketFeeOverride(conditionPda, this.programIds);
|
|
2024
|
+
return this.program.methods.distributeFee(conditionPda, amount).accounts({
|
|
2025
|
+
feeConfig: feeConfigPda,
|
|
2026
|
+
marketFeeOverride: marketFeeOverridePda,
|
|
2027
|
+
authority,
|
|
2028
|
+
sourceAta,
|
|
2029
|
+
companyAta,
|
|
2030
|
+
marketOracleVault,
|
|
2031
|
+
tokenProgram: new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
|
2032
|
+
}).instruction();
|
|
2033
|
+
}
|
|
2034
|
+
async distributeFee(conditionPda, amount, feeConfigOwner, sourceAta, companyAta, marketOracleVault, authority) {
|
|
2035
|
+
const [feeConfigPda] = PDA.feeConfig(feeConfigOwner, this.programIds);
|
|
2036
|
+
const [marketFeeOverridePda] = PDA.marketFeeOverride(conditionPda, this.programIds);
|
|
2037
|
+
const sig = await this.program.methods.distributeFee(conditionPda, amount).accounts({
|
|
2038
|
+
feeConfig: feeConfigPda,
|
|
2039
|
+
marketFeeOverride: marketFeeOverridePda,
|
|
2040
|
+
authority,
|
|
2041
|
+
sourceAta,
|
|
2042
|
+
companyAta,
|
|
2043
|
+
marketOracleVault,
|
|
2044
|
+
tokenProgram: new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
|
|
2045
|
+
}).signers([]).rpc();
|
|
2046
|
+
return { signature: sig };
|
|
2047
|
+
}
|
|
2048
|
+
async setQuestionFee(conditionPda, mergeFee, redeemFee, swapFee, feeConfigOwner, authority, payer) {
|
|
2049
|
+
const [feeConfigPda] = PDA.feeConfig(feeConfigOwner, this.programIds);
|
|
2050
|
+
const [questionFeePda] = PDA.questionFee(conditionPda, this.programIds);
|
|
2051
|
+
const sig = await this.program.methods.setQuestionFee(
|
|
2052
|
+
Array.from(conditionPda.toBytes()),
|
|
2053
|
+
mergeFee,
|
|
2054
|
+
redeemFee,
|
|
2055
|
+
swapFee
|
|
2056
|
+
).accounts({
|
|
2057
|
+
authority,
|
|
2058
|
+
payer,
|
|
2059
|
+
feeConfig: feeConfigPda,
|
|
2060
|
+
questionFee: questionFeePda,
|
|
2061
|
+
systemProgram: SystemProgram.programId
|
|
2062
|
+
}).signers([]).rpc();
|
|
2063
|
+
return { signature: sig };
|
|
2064
|
+
}
|
|
2065
|
+
};
|
|
2066
|
+
var PresaleClient = class {
|
|
2067
|
+
constructor(program, provider, programIds) {
|
|
2068
|
+
this.program = program;
|
|
2069
|
+
this.provider = provider;
|
|
2070
|
+
this.programIds = programIds;
|
|
2071
|
+
}
|
|
2072
|
+
get walletPubkey() {
|
|
2073
|
+
return this.provider.wallet.publicKey;
|
|
2074
|
+
}
|
|
2075
|
+
presalePda(questionMarketConfig, presaleIndex) {
|
|
2076
|
+
return PDA.presale(questionMarketConfig, presaleIndex, this.programIds)[0];
|
|
2077
|
+
}
|
|
2078
|
+
qtMintPda(presalePda) {
|
|
2079
|
+
return PDA.qtMint(presalePda, this.programIds)[0];
|
|
2080
|
+
}
|
|
2081
|
+
qtAuthorityPda(presalePda) {
|
|
2082
|
+
return PDA.qtAuthority(presalePda, this.programIds)[0];
|
|
2083
|
+
}
|
|
2084
|
+
userBuyRecordPda(presalePda, user) {
|
|
2085
|
+
return PDA.userBuyRecord(presalePda, user, this.programIds)[0];
|
|
2086
|
+
}
|
|
2087
|
+
/**
|
|
2088
|
+
* Buy MST tokens during presale.
|
|
2089
|
+
* qtAmount: amount of MST to receive (9 decimals).
|
|
2090
|
+
* USDC cost = qtAmount * price / 1e9.
|
|
2091
|
+
*/
|
|
2092
|
+
async buy(presalePda, qtAmount, buyer = this.walletPubkey, payer = this.walletPubkey, signers = []) {
|
|
2093
|
+
const presale = await this.fetchPresale(presalePda);
|
|
2094
|
+
if (!presale) throw new Error(`Presale not found: ${presalePda.toBase58()}`);
|
|
2095
|
+
const qtMint = presale.qtMint;
|
|
2096
|
+
const currencyMint = presale.currencyMint;
|
|
2097
|
+
const qtAuthority = this.qtAuthorityPda(presalePda);
|
|
2098
|
+
const userBuyRecord = this.userBuyRecordPda(presalePda, buyer);
|
|
2099
|
+
const buyerQtAta = getAssociatedTokenAddressSync(qtMint, buyer);
|
|
2100
|
+
const buyerCurrencyAta = getAssociatedTokenAddressSync(currencyMint, buyer);
|
|
2101
|
+
const presaleVault = getAssociatedTokenAddressSync(currencyMint, presalePda, true);
|
|
2102
|
+
const sig = await this.program.methods.buy(qtAmount).accounts({
|
|
2103
|
+
buyer,
|
|
2104
|
+
payer,
|
|
2105
|
+
presale: presalePda,
|
|
2106
|
+
qtMint,
|
|
2107
|
+
qtAuthority,
|
|
2108
|
+
buyerQtAta,
|
|
2109
|
+
buyerCurrencyAta,
|
|
2110
|
+
presaleVault,
|
|
2111
|
+
currencyMint,
|
|
2112
|
+
userBuyRecord,
|
|
2113
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2114
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
2115
|
+
systemProgram: SystemProgram.programId
|
|
2116
|
+
}).signers(signers).rpc();
|
|
2117
|
+
return { signature: sig };
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Refund: burn user's MST and return USDC.
|
|
2121
|
+
* Only callable when presale status = Rejected.
|
|
2122
|
+
*/
|
|
2123
|
+
async refund(presalePda, user = this.walletPubkey, signers = []) {
|
|
2124
|
+
const presale = await this.fetchPresale(presalePda);
|
|
2125
|
+
if (!presale) throw new Error(`Presale not found: ${presalePda.toBase58()}`);
|
|
2126
|
+
const qtMint = presale.qtMint;
|
|
2127
|
+
const currencyMint = presale.currencyMint;
|
|
2128
|
+
const userBuyRecord = this.userBuyRecordPda(presalePda, user);
|
|
2129
|
+
const userQtAta = getAssociatedTokenAddressSync(qtMint, user);
|
|
2130
|
+
const userCurrencyAta = getAssociatedTokenAddressSync(currencyMint, user);
|
|
2131
|
+
const presaleVault = getAssociatedTokenAddressSync(currencyMint, presalePda, true);
|
|
2132
|
+
const sig = await this.program.methods.refund().accounts({
|
|
2133
|
+
user,
|
|
2134
|
+
presale: presalePda,
|
|
2135
|
+
qtMint,
|
|
2136
|
+
userQtAta,
|
|
2137
|
+
userCurrencyAta,
|
|
2138
|
+
presaleVault,
|
|
2139
|
+
currencyMint,
|
|
2140
|
+
userBuyRecord,
|
|
2141
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2142
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
2143
|
+
systemProgram: SystemProgram.programId
|
|
2144
|
+
}).signers(signers).rpc();
|
|
2145
|
+
return { signature: sig };
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Creator claims their share of presale revenue after distribute_presale_revenue.
|
|
2149
|
+
*/
|
|
2150
|
+
async claimRevenue(presalePda, creator = this.walletPubkey, signers = []) {
|
|
2151
|
+
const presale = await this.fetchPresale(presalePda);
|
|
2152
|
+
if (!presale) throw new Error(`Presale not found: ${presalePda.toBase58()}`);
|
|
2153
|
+
const currencyMint = presale.currencyMint;
|
|
2154
|
+
const presaleVault = getAssociatedTokenAddressSync(currencyMint, presalePda, true);
|
|
2155
|
+
const creatorCurrencyAta = getAssociatedTokenAddressSync(currencyMint, creator);
|
|
2156
|
+
const sig = await this.program.methods.claimRevenue().accounts({
|
|
2157
|
+
creator,
|
|
2158
|
+
presale: presalePda,
|
|
2159
|
+
presaleVault,
|
|
2160
|
+
creatorCurrencyAta,
|
|
2161
|
+
currencyMint,
|
|
2162
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2163
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
2164
|
+
systemProgram: SystemProgram.programId
|
|
2165
|
+
}).signers(signers).rpc();
|
|
2166
|
+
return { signature: sig };
|
|
2167
|
+
}
|
|
2168
|
+
// ─── Queries ─────────────────────────────────────────────────────────────────
|
|
2169
|
+
async fetchPresale(presalePda) {
|
|
2170
|
+
try {
|
|
2171
|
+
const acc = await this.program.account.presaleAccount.fetch(presalePda);
|
|
2172
|
+
const rawStatus = acc.status;
|
|
2173
|
+
const status = rawStatus.approved !== void 0 ? "approved" : rawStatus.rejected !== void 0 ? "rejected" : "pending";
|
|
2174
|
+
return {
|
|
2175
|
+
version: acc.version,
|
|
2176
|
+
questionMarketConfig: acc.questionMarketConfig,
|
|
2177
|
+
presaleIndex: acc.presaleIndex,
|
|
2178
|
+
creator: acc.creator,
|
|
2179
|
+
currencyMint: acc.currencyMint,
|
|
2180
|
+
qtMint: acc.qtMint,
|
|
2181
|
+
price: acc.price,
|
|
2182
|
+
startTime: acc.startTime,
|
|
2183
|
+
endTime: acc.endTime,
|
|
2184
|
+
status,
|
|
2185
|
+
soldTokenAmount: acc.soldTokenAmount,
|
|
2186
|
+
initialTokenAmountCreator: acc.initialTokenAmountCreator,
|
|
2187
|
+
agentsRev: acc.agentsRev,
|
|
2188
|
+
companyRev: acc.companyRev,
|
|
2189
|
+
referralAddress: acc.referralAddress,
|
|
2190
|
+
companyAddress: acc.companyAddress,
|
|
2191
|
+
isDistributeRevenue: acc.isDistributeRevenue,
|
|
2192
|
+
creatorClaimableRevenue: acc.creatorClaimableRevenue,
|
|
2193
|
+
bump: acc.bump
|
|
2194
|
+
};
|
|
2195
|
+
} catch {
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
async fetchUserBuyRecord(presalePda, user) {
|
|
2200
|
+
try {
|
|
2201
|
+
const pda = this.userBuyRecordPda(presalePda, user);
|
|
2202
|
+
const acc = await this.program.account.userBuyRecord.fetch(pda);
|
|
2203
|
+
return {
|
|
2204
|
+
user: acc.user,
|
|
2205
|
+
presale: acc.presale,
|
|
2206
|
+
currencyAmount: acc.currencyAmount,
|
|
2207
|
+
bump: acc.bump
|
|
2208
|
+
};
|
|
2209
|
+
} catch {
|
|
2210
|
+
return null;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
var MarketOracleClient = class {
|
|
2215
|
+
constructor(program, provider, programIds) {
|
|
2216
|
+
this.program = program;
|
|
2217
|
+
this.provider = provider;
|
|
2218
|
+
this.programIds = programIds;
|
|
2219
|
+
}
|
|
2220
|
+
get walletPubkey() {
|
|
2221
|
+
return this.provider.wallet.publicKey;
|
|
2222
|
+
}
|
|
2223
|
+
marketOraclePda(questionPda) {
|
|
2224
|
+
return PDA.marketOraclePda(questionPda, this.programIds)[0];
|
|
2225
|
+
}
|
|
2226
|
+
userClaimRecordPda(marketOraclePda, user) {
|
|
2227
|
+
return PDA.userClaimRecord(marketOraclePda, user, this.programIds)[0];
|
|
2228
|
+
}
|
|
2229
|
+
/**
|
|
2230
|
+
* User burns their MST and claims proportional share of oracle vault USDC.
|
|
2231
|
+
* Call after market.collectTradingFee snapshotted qt supply.
|
|
2232
|
+
*/
|
|
2233
|
+
async claimFeesShare(marketOraclePda, user = this.walletPubkey, payer = this.walletPubkey, signers = []) {
|
|
2234
|
+
const oracle = await this.fetchMarketOracle(marketOraclePda);
|
|
2235
|
+
if (!oracle) throw new Error(`MarketOracle not found: ${marketOraclePda.toBase58()}`);
|
|
2236
|
+
const currencyMint = oracle.currencyMint;
|
|
2237
|
+
const qtMint = oracle.qtMint;
|
|
2238
|
+
const marketOracleVault = getAssociatedTokenAddressSync(currencyMint, marketOraclePda, true);
|
|
2239
|
+
const userQtAta = getAssociatedTokenAddressSync(qtMint, user);
|
|
2240
|
+
const userCurrencyAta = getAssociatedTokenAddressSync(currencyMint, user);
|
|
2241
|
+
const userClaimRecord = this.userClaimRecordPda(marketOraclePda, user);
|
|
2242
|
+
const sig = await this.program.methods.claimFeesShare().accounts({
|
|
2243
|
+
user,
|
|
2244
|
+
payer,
|
|
2245
|
+
marketOracle: marketOraclePda,
|
|
2246
|
+
marketOracleVault,
|
|
2247
|
+
currencyMint,
|
|
2248
|
+
qtMint,
|
|
2249
|
+
userQtAta,
|
|
2250
|
+
userCurrencyAta,
|
|
2251
|
+
userClaimRecord,
|
|
2252
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2253
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
2254
|
+
systemProgram: SystemProgram.programId
|
|
2255
|
+
}).signers(signers).rpc();
|
|
2256
|
+
return { signature: sig };
|
|
2257
|
+
}
|
|
2258
|
+
// ─── Queries ─────────────────────────────────────────────────────────────────
|
|
2259
|
+
async fetchMarketOracle(marketOraclePda) {
|
|
2260
|
+
try {
|
|
2261
|
+
const acc = await this.program.account.marketOracleAccount.fetch(marketOraclePda);
|
|
2262
|
+
return {
|
|
2263
|
+
version: acc.version,
|
|
2264
|
+
question: acc.question,
|
|
2265
|
+
questionMarketConfig: acc.questionMarketConfig,
|
|
2266
|
+
currencyMint: acc.currencyMint,
|
|
2267
|
+
creator: acc.creator,
|
|
2268
|
+
qtMint: acc.qtMint,
|
|
2269
|
+
feesDistributed: acc.feesDistributed,
|
|
2270
|
+
qtTotalSupply: acc.qtTotalSupply,
|
|
2271
|
+
totalClaimed: acc.totalClaimed,
|
|
2272
|
+
bump: acc.bump
|
|
2273
|
+
};
|
|
2274
|
+
} catch {
|
|
2275
|
+
return null;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
async fetchUserClaimRecord(marketOraclePda, user) {
|
|
2279
|
+
try {
|
|
2280
|
+
const pda = this.userClaimRecordPda(marketOraclePda, user);
|
|
2281
|
+
const acc = await this.program.account.userClaimRecord.fetch(pda);
|
|
2282
|
+
return {
|
|
2283
|
+
user: acc.user,
|
|
2284
|
+
marketOracle: acc.marketOracle,
|
|
2285
|
+
hasClaimed: acc.hasClaimed,
|
|
2286
|
+
bump: acc.bump
|
|
2287
|
+
};
|
|
2288
|
+
} catch {
|
|
2289
|
+
return null;
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
};
|
|
1520
2293
|
var XMarketSDK = class {
|
|
1521
2294
|
constructor(config, wallet, marketOwner) {
|
|
1522
2295
|
this.networkConfig = config;
|
|
@@ -1564,10 +2337,38 @@ var XMarketSDK = class {
|
|
|
1564
2337
|
get clob() {
|
|
1565
2338
|
if (!this._clob) {
|
|
1566
2339
|
const program = new anchor4.Program(this._withAddress(clobExchangeIdl, this._programIds.clobExchange), this.provider);
|
|
1567
|
-
this._clob = new ClobClient(program, this.provider, this._programIds);
|
|
2340
|
+
this._clob = new ClobClient(program, this.provider, this._programIds, this.networkConfig);
|
|
2341
|
+
if (this.networkConfig.feeConfigOwner && this._programIds.feeManagement) {
|
|
2342
|
+
this._clob.feeConfigOwner = this.networkConfig.feeConfigOwner;
|
|
2343
|
+
this._clob.feeClient = this.fee;
|
|
2344
|
+
}
|
|
1568
2345
|
}
|
|
1569
2346
|
return this._clob;
|
|
1570
2347
|
}
|
|
2348
|
+
get fee() {
|
|
2349
|
+
if (!this._fee) {
|
|
2350
|
+
if (!this._programIds.feeManagement) throw new Error("feeManagement program ID not configured in NetworkConfig");
|
|
2351
|
+
const program = new anchor4.Program(this._withAddress(feeManagementIdl, this._programIds.feeManagement), this.provider);
|
|
2352
|
+
this._fee = new FeeManagementClient(program, this.provider, this._programIds);
|
|
2353
|
+
}
|
|
2354
|
+
return this._fee;
|
|
2355
|
+
}
|
|
2356
|
+
get presale() {
|
|
2357
|
+
if (!this._presale) {
|
|
2358
|
+
if (!this._programIds.presale) throw new Error("presale program ID not configured in NetworkConfig");
|
|
2359
|
+
const program = new anchor4.Program(this._withAddress(presaleIdl, this._programIds.presale), this.provider);
|
|
2360
|
+
this._presale = new PresaleClient(program, this.provider, this._programIds);
|
|
2361
|
+
}
|
|
2362
|
+
return this._presale;
|
|
2363
|
+
}
|
|
2364
|
+
get marketOracle() {
|
|
2365
|
+
if (!this._marketOracle) {
|
|
2366
|
+
if (!this._programIds.marketOracle) throw new Error("marketOracle program ID not configured in NetworkConfig");
|
|
2367
|
+
const program = new anchor4.Program(this._withAddress(marketOracleIdl, this._programIds.marketOracle), this.provider);
|
|
2368
|
+
this._marketOracle = new MarketOracleClient(program, this.provider, this._programIds);
|
|
2369
|
+
}
|
|
2370
|
+
return this._marketOracle;
|
|
2371
|
+
}
|
|
1571
2372
|
};
|
|
1572
2373
|
function buildOrder(params) {
|
|
1573
2374
|
return {
|
|
@@ -1636,7 +2437,7 @@ function detectMatchType(a, b) {
|
|
|
1636
2437
|
return _detectMatchType(_a, _b);
|
|
1637
2438
|
}
|
|
1638
2439
|
function _detectMatchType(a, b) {
|
|
1639
|
-
const SIDE_BUY =
|
|
2440
|
+
const SIDE_BUY = 0;
|
|
1640
2441
|
if (a.tokenId === b.tokenId) {
|
|
1641
2442
|
const aBuy2 = a.side === SIDE_BUY;
|
|
1642
2443
|
const bBuy2 = b.side === SIDE_BUY;
|
|
@@ -1697,6 +2498,6 @@ function buildApproveAllOutcomeTokensTx(condition, signer, payer, delegate, prog
|
|
|
1697
2498
|
return tx;
|
|
1698
2499
|
}
|
|
1699
2500
|
|
|
1700
|
-
export { AccountNotFoundError, ClobClient, CtfClient, HookClient, IX_SYSVAR, InvalidParamError, MAX_APPROVE_AMOUNT, MarketClient, OracleClient, PDA, QuestionStatus, SEEDS, UnauthorizedError, XMarketError, XMarketSDK, buildApproveAllOutcomeTokensTx, buildApproveCollateralTx, buildBatchedEd25519Instruction, buildOrder, deserializeSignedOrder, detectMatchType, generateContentHash, generateQuestionId, getOrderSignBytes, serializeOrderToBytes, serializeSignedOrder, signOrder, signOrderWithKeypair, verifySignedOrder };
|
|
2501
|
+
export { AccountNotFoundError, ClobClient, CtfClient, FEE_DENOMINATOR, FeeManagementClient, HookClient, IX_SYSVAR, InvalidParamError, MAX_APPROVE_AMOUNT, MarketClient, MarketOracleClient, OracleClient, PDA, PresaleClient, QuestionStatus, SEEDS, UnauthorizedError, XMarketError, XMarketSDK, buildApproveAllOutcomeTokensTx, buildApproveCollateralTx, buildBatchedEd25519Instruction, buildOrder, deserializeSignedOrder, detectMatchType, generateContentHash, generateQuestionId, getOrderSignBytes, serializeOrderToBytes, serializeSignedOrder, signOrder, signOrderWithKeypair, verifySignedOrder };
|
|
1701
2502
|
//# sourceMappingURL=index.mjs.map
|
|
1702
2503
|
//# sourceMappingURL=index.mjs.map
|