@baozi.bet/mcp-server 4.0.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/README.md +294 -0
- package/dist/__tests__/full-test.d.ts +1 -0
- package/dist/__tests__/full-test.js +291 -0
- package/dist/builders/affiliate-transaction.d.ts +41 -0
- package/dist/builders/affiliate-transaction.js +123 -0
- package/dist/builders/bet-transaction.d.ts +70 -0
- package/dist/builders/bet-transaction.js +323 -0
- package/dist/builders/claim-transaction.d.ts +57 -0
- package/dist/builders/claim-transaction.js +196 -0
- package/dist/builders/creator-transaction.d.ts +49 -0
- package/dist/builders/creator-transaction.js +177 -0
- package/dist/builders/dispute-transaction.d.ts +81 -0
- package/dist/builders/dispute-transaction.js +215 -0
- package/dist/builders/index.d.ts +14 -0
- package/dist/builders/index.js +15 -0
- package/dist/builders/market-creation-tx.d.ts +65 -0
- package/dist/builders/market-creation-tx.js +362 -0
- package/dist/builders/market-management-transaction.d.ts +85 -0
- package/dist/builders/market-management-transaction.js +239 -0
- package/dist/builders/race-transaction.d.ts +67 -0
- package/dist/builders/race-transaction.js +242 -0
- package/dist/builders/resolution-transaction.d.ts +108 -0
- package/dist/builders/resolution-transaction.js +250 -0
- package/dist/builders/whitelist-transaction.d.ts +72 -0
- package/dist/builders/whitelist-transaction.js +179 -0
- package/dist/config.d.ts +138 -0
- package/dist/config.js +307 -0
- package/dist/handlers/agent-network.d.ts +81 -0
- package/dist/handlers/agent-network.js +332 -0
- package/dist/handlers/claims.d.ts +47 -0
- package/dist/handlers/claims.js +218 -0
- package/dist/handlers/market-creation.d.ts +154 -0
- package/dist/handlers/market-creation.js +290 -0
- package/dist/handlers/markets.d.ts +41 -0
- package/dist/handlers/markets.js +319 -0
- package/dist/handlers/positions.d.ts +40 -0
- package/dist/handlers/positions.js +244 -0
- package/dist/handlers/quote.d.ts +33 -0
- package/dist/handlers/quote.js +144 -0
- package/dist/handlers/race-markets.d.ts +54 -0
- package/dist/handlers/race-markets.js +308 -0
- package/dist/handlers/resolution.d.ts +43 -0
- package/dist/handlers/resolution.js +194 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +109 -0
- package/dist/resources.d.ts +13 -0
- package/dist/resources.js +336 -0
- package/dist/tools.d.ts +3109 -0
- package/dist/tools.js +1956 -0
- package/dist/validation/bet-rules.d.ts +82 -0
- package/dist/validation/bet-rules.js +276 -0
- package/dist/validation/creation-rules.d.ts +69 -0
- package/dist/validation/creation-rules.js +302 -0
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.js +7 -0
- package/dist/validation/market-rules.d.ts +60 -0
- package/dist/validation/market-rules.js +237 -0
- package/dist/validation/parimutuel-rules.d.ts +117 -0
- package/dist/validation/parimutuel-rules.js +270 -0
- package/package.json +52 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claims Handler - Winnings, Refunds, Affiliate & Creator Claims
|
|
3
|
+
*/
|
|
4
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
5
|
+
import bs58 from 'bs58';
|
|
6
|
+
import { PROGRAM_ID, RPC_ENDPOINT, DISCRIMINATORS, lamportsToSol, SEEDS, } from '../config.js';
|
|
7
|
+
import { getMarket } from './markets.js';
|
|
8
|
+
import { getPositions } from './positions.js';
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// HELPERS
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Derive market PDA from market_id
|
|
14
|
+
*/
|
|
15
|
+
function deriveMarketPda(marketId) {
|
|
16
|
+
const marketIdBigInt = BigInt(marketId);
|
|
17
|
+
const marketIdBuffer = Buffer.alloc(8);
|
|
18
|
+
marketIdBuffer.writeBigUInt64LE(marketIdBigInt);
|
|
19
|
+
const [pda] = PublicKey.findProgramAddressSync([Buffer.from('market'), marketIdBuffer], PROGRAM_ID);
|
|
20
|
+
return pda.toBase58();
|
|
21
|
+
}
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// CLAIMABLE POSITIONS
|
|
24
|
+
// =============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Get all claimable positions for a wallet
|
|
27
|
+
* Checks which positions can be claimed (winnings or refunds)
|
|
28
|
+
*/
|
|
29
|
+
export async function getClaimablePositions(walletAddress) {
|
|
30
|
+
const positions = await getPositions(walletAddress);
|
|
31
|
+
const claimable = [];
|
|
32
|
+
let winningsTotal = 0;
|
|
33
|
+
let refundsTotal = 0;
|
|
34
|
+
let alreadyClaimed = 0;
|
|
35
|
+
for (const position of positions) {
|
|
36
|
+
if (position.claimed) {
|
|
37
|
+
alreadyClaimed++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Derive market PDA from market_id
|
|
41
|
+
const marketPda = deriveMarketPda(position.marketId);
|
|
42
|
+
// Fetch market to check status
|
|
43
|
+
const market = await getMarket(marketPda);
|
|
44
|
+
if (!market)
|
|
45
|
+
continue;
|
|
46
|
+
// Get the bet amount for the winning side
|
|
47
|
+
const yesAmount = position.yesAmountSol;
|
|
48
|
+
const noAmount = position.noAmountSol;
|
|
49
|
+
const totalBet = yesAmount + noAmount;
|
|
50
|
+
let claimType = null;
|
|
51
|
+
let estimatedPayout = 0;
|
|
52
|
+
let winningSide = null;
|
|
53
|
+
if (market.status === 'Resolved') {
|
|
54
|
+
// Check if user bet on the winning side
|
|
55
|
+
if (market.winningOutcome === 'Yes' && yesAmount > 0) {
|
|
56
|
+
winningSide = 'Yes';
|
|
57
|
+
claimType = 'winnings';
|
|
58
|
+
const totalPool = market.yesPoolSol + market.noPoolSol;
|
|
59
|
+
if (market.yesPoolSol > 0) {
|
|
60
|
+
const share = yesAmount / market.yesPoolSol;
|
|
61
|
+
const grossPayout = share * totalPool;
|
|
62
|
+
const profit = grossPayout - yesAmount;
|
|
63
|
+
const fee = profit > 0 ? (profit * market.platformFeeBps) / 10000 : 0;
|
|
64
|
+
estimatedPayout = grossPayout - fee;
|
|
65
|
+
}
|
|
66
|
+
winningsTotal += estimatedPayout;
|
|
67
|
+
}
|
|
68
|
+
else if (market.winningOutcome === 'No' && noAmount > 0) {
|
|
69
|
+
winningSide = 'No';
|
|
70
|
+
claimType = 'winnings';
|
|
71
|
+
const totalPool = market.yesPoolSol + market.noPoolSol;
|
|
72
|
+
if (market.noPoolSol > 0) {
|
|
73
|
+
const share = noAmount / market.noPoolSol;
|
|
74
|
+
const grossPayout = share * totalPool;
|
|
75
|
+
const profit = grossPayout - noAmount;
|
|
76
|
+
const fee = profit > 0 ? (profit * market.platformFeeBps) / 10000 : 0;
|
|
77
|
+
estimatedPayout = grossPayout - fee;
|
|
78
|
+
}
|
|
79
|
+
winningsTotal += estimatedPayout;
|
|
80
|
+
}
|
|
81
|
+
else if (market.winningOutcome === null) {
|
|
82
|
+
// Invalid/Draw - refund all bets
|
|
83
|
+
claimType = 'refund';
|
|
84
|
+
estimatedPayout = totalBet;
|
|
85
|
+
winningSide = yesAmount > noAmount ? 'Yes' : 'No';
|
|
86
|
+
refundsTotal += estimatedPayout;
|
|
87
|
+
}
|
|
88
|
+
// Loser - nothing to claim
|
|
89
|
+
}
|
|
90
|
+
else if (market.status === 'Cancelled') {
|
|
91
|
+
// Cancelled - full refund of all bets
|
|
92
|
+
claimType = 'cancelled';
|
|
93
|
+
estimatedPayout = totalBet;
|
|
94
|
+
winningSide = yesAmount > noAmount ? 'Yes' : 'No';
|
|
95
|
+
refundsTotal += estimatedPayout;
|
|
96
|
+
}
|
|
97
|
+
if (claimType && winningSide) {
|
|
98
|
+
claimable.push({
|
|
99
|
+
positionPda: position.publicKey,
|
|
100
|
+
marketPda,
|
|
101
|
+
marketQuestion: market.question,
|
|
102
|
+
side: winningSide,
|
|
103
|
+
betAmountSol: winningSide === 'Yes' ? yesAmount : noAmount,
|
|
104
|
+
claimType,
|
|
105
|
+
estimatedPayoutSol: round4(estimatedPayout),
|
|
106
|
+
marketStatus: market.status,
|
|
107
|
+
marketOutcome: market.winningOutcome,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
wallet: walletAddress,
|
|
113
|
+
totalClaimableSol: round4(winningsTotal + refundsTotal),
|
|
114
|
+
winningsClaimableSol: round4(winningsTotal),
|
|
115
|
+
refundsClaimableSol: round4(refundsTotal),
|
|
116
|
+
claimablePositions: claimable,
|
|
117
|
+
alreadyClaimedCount: alreadyClaimed,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// =============================================================================
|
|
121
|
+
// AFFILIATE INFO
|
|
122
|
+
// =============================================================================
|
|
123
|
+
/**
|
|
124
|
+
* Decode Affiliate account
|
|
125
|
+
* Affiliate struct:
|
|
126
|
+
* - discriminator (8)
|
|
127
|
+
* - owner (Pubkey, 32)
|
|
128
|
+
* - code (String: 4 + len)
|
|
129
|
+
* - total_earned (u64, 8)
|
|
130
|
+
* - total_claimed (u64, 8)
|
|
131
|
+
* - referral_count (u64, 8)
|
|
132
|
+
* - is_active (bool, 1)
|
|
133
|
+
* - bump (u8, 1)
|
|
134
|
+
*/
|
|
135
|
+
function decodeAffiliate(data, pubkey) {
|
|
136
|
+
try {
|
|
137
|
+
let offset = 8; // Skip discriminator
|
|
138
|
+
const owner = new PublicKey(data.slice(offset, offset + 32));
|
|
139
|
+
offset += 32;
|
|
140
|
+
const codeLen = data.readUInt32LE(offset);
|
|
141
|
+
offset += 4;
|
|
142
|
+
const code = data.slice(offset, offset + codeLen).toString('utf8');
|
|
143
|
+
offset += codeLen;
|
|
144
|
+
const totalEarned = data.readBigUInt64LE(offset);
|
|
145
|
+
offset += 8;
|
|
146
|
+
const totalClaimed = data.readBigUInt64LE(offset);
|
|
147
|
+
offset += 8;
|
|
148
|
+
const referralCount = data.readBigUInt64LE(offset);
|
|
149
|
+
offset += 8;
|
|
150
|
+
const isActive = data.readUInt8(offset) === 1;
|
|
151
|
+
return {
|
|
152
|
+
affiliatePda: pubkey.toBase58(),
|
|
153
|
+
owner: owner.toBase58(),
|
|
154
|
+
code,
|
|
155
|
+
totalEarnedSol: round4(lamportsToSol(totalEarned)),
|
|
156
|
+
unclaimedSol: round4(lamportsToSol(totalEarned - totalClaimed)),
|
|
157
|
+
referralCount: Number(referralCount),
|
|
158
|
+
isActive,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get affiliate info by code
|
|
167
|
+
*/
|
|
168
|
+
export async function getAffiliateByCode(code) {
|
|
169
|
+
const connection = new Connection(RPC_ENDPOINT, 'confirmed');
|
|
170
|
+
// Derive affiliate PDA from code
|
|
171
|
+
const [affiliatePda] = PublicKey.findProgramAddressSync([SEEDS.AFFILIATE, Buffer.from(code)], PROGRAM_ID);
|
|
172
|
+
try {
|
|
173
|
+
const account = await connection.getAccountInfo(affiliatePda);
|
|
174
|
+
if (!account)
|
|
175
|
+
return null;
|
|
176
|
+
return decodeAffiliate(account.data, affiliatePda);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get affiliate info by owner wallet
|
|
184
|
+
*/
|
|
185
|
+
export async function getAffiliateByOwner(walletAddress) {
|
|
186
|
+
const connection = new Connection(RPC_ENDPOINT, 'confirmed');
|
|
187
|
+
const accounts = await connection.getProgramAccounts(PROGRAM_ID, {
|
|
188
|
+
filters: [
|
|
189
|
+
{
|
|
190
|
+
memcmp: {
|
|
191
|
+
offset: 0,
|
|
192
|
+
bytes: bs58.encode(DISCRIMINATORS.AFFILIATE),
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
memcmp: {
|
|
197
|
+
offset: 8, // After discriminator
|
|
198
|
+
bytes: walletAddress,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
});
|
|
203
|
+
const affiliates = [];
|
|
204
|
+
for (const { account, pubkey } of accounts) {
|
|
205
|
+
const affiliate = decodeAffiliate(account.data, pubkey);
|
|
206
|
+
if (affiliate) {
|
|
207
|
+
affiliates.push(affiliate);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return affiliates;
|
|
211
|
+
}
|
|
212
|
+
// =============================================================================
|
|
213
|
+
// HELPERS
|
|
214
|
+
// =============================================================================
|
|
215
|
+
function round4(n) {
|
|
216
|
+
return Math.round(n * 10000) / 10000;
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhaW1zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hhbmRsZXJzL2NsYWltcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFDTCxVQUFVLEVBQ1YsWUFBWSxFQUNaLGNBQWMsRUFDZCxhQUFhLEVBQ2IsS0FBSyxHQUNOLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxjQUFjLENBQUM7QUFDakQsT0FBTyxFQUFFLFlBQVksRUFBWSxNQUFNLGdCQUFnQixDQUFDO0FBNEN4RCxnRkFBZ0Y7QUFDaEYsVUFBVTtBQUNWLGdGQUFnRjtBQUVoRjs7R0FFRztBQUNILFNBQVMsZUFBZSxDQUFDLFFBQWdCO0lBQ3ZDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4QyxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNoRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLHNCQUFzQixDQUM1QyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQ3ZDLFVBQVUsQ0FDWCxDQUFDO0lBQ0YsT0FBTyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVELGdGQUFnRjtBQUNoRixzQkFBc0I7QUFDdEIsZ0ZBQWdGO0FBRWhGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUscUJBQXFCLENBQUMsYUFBcUI7SUFDL0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxZQUFZLENBQUMsYUFBYSxD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SGFuZGxlciAtIFdpbm5pbmdzLCBSZWZ1bmRzLCBBZmZpbGlhdGUgJiBDcmVhdG9yIENsYWltc1xuICovXG5pbXBvcnQgeyBDb25uZWN0aW9uLCBQdWJsaWNLZXkgfSBmcm9tICdAc29sYW5hL3dlYjMuanMnO1xuaW1wb3J0IGJzNTggZnJvbSAnYnM1OCc7XG5pbXBvcnQge1xuICBQUk9HUkFNX0lELFxuICBSUENfRU5EUE9JTlQsXG4gIERJU0NSSU1JTkFUT1JTLFxuICBsYW1wb3J0c1RvU29sLFxuICBTRUVEUyxcbn0gZnJvbSAnLi4vY29uZmlnLmpzJztcbmltcG9ydCB7IGdldE1hcmtldCwgTWFya2V0IH0gZnJvbSAnLi9tYXJrZXRzLmpzJztcbmltcG9ydCB7IGdldFBvc2l0aW9ucywgUG9zaXRpb24gfSBmcm9tICcuL3Bvc2l0aW9ucy5qcyc7XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBDbGFpbWFibGVQb3NpdGlvbiB7XG4gIHBvc2l0aW9uUGRhOiBzdHJpbmc7XG4gIG1hcmtldFBkYTogc3RyaW5nO1xuICBtYXJrZXRRdWVzdGlvbjogc3RyaW5nO1xuICBzaWRlOiAnWWVzJyB8ICdObyc7XG4gIGJldEFtb3VudFNvbDogbnVtYmVyO1xuICBjbGFpbVR5cGU6ICd3aW5uaW5ncycgfCAncmVmdW5kJyB8ICdjYW5jZWxsZWQnO1xuICBlc3RpbWF0ZWRQYXlvdXRTb2w6IG51bWJlcjtcbiAgbWFya2V0U3RhdHVzOiBzdHJpbmc7XG4gIG1hcmtldE91dGNvbWU6IHN0cmluZyB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xhaW1TdW1tYXJ5IHtcbiAgd2FsbGV0OiBzdHJpbmc7XG4gIHRvdGFsQ2xhaW1hYmxlU29sOiBudW1iZXI7XG4gIHdpbm5pbmdzQ2xhaW1hYmxlU29sOiBudW1iZXI7XG4gIHJlZnVuZHNDbGFpbWFibGVTb2w6IG51bWJlcjtcbiAgY2xhaW1hYmxlUG9zaXRpb25zOiBDbGFpbWFibGVQb3NpdGlvbltdO1xuICBhbHJlYWR5Q2xhaW1lZENvdW50OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWZmaWxpYXRlSW5mbyB7XG4gIGFmZmlsaWF0ZVBkYTogc3RyaW5nO1xuICBvd25lcjogc3RyaW5nO1xuICBjb2RlOiBzdHJpbmc7XG4gIHRvdGFsRWFybmVkU29sOiBudW1iZXI7XG4gIHVuY2xhaW1lZFNvbDogbnVtYmVyO1xuICByZWZlcnJhbENvdW50OiBudW1iZXI7XG4gIGlzQWN0aXZlOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0b3JFYXJuaW5ncyB7XG4gIHdhbGxldDogc3RyaW5nO1xuICB0b3RhbENyZWF0b3JGZWVzU29sOiBudW1iZXI7XG4gIHVuY2xhaW1lZFNvbDogbnVtYmVyO1xuICBtYXJrZXRzQ3JlYXRlZDogbnVtYmVyO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEVMUEVSU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBEZXJpdmUgbWFya2V0IFBEQSBmcm9tIG1hcmtldF9pZFxuICovXG5mdW5jdGlvbiBkZXJpdmVNYXJrZXRQZGEobWFya2V0SWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG1hcmtldElkQmlnSW50ID0gQmlnSW50KG1hcmtldElkKTtcbiAgY29uc3QgbWFya2V0SWRCdWZmZXIgPSBCdWZmZXIuYWxsb2MoOCk7XG4gIG1hcmtldElkQnVmZmVyLndyaXRlQmlnVUludDY0TEUobWFya2V0SWRCaWdJbnQpO1xuICBjb25zdCBbcGRhXSA9IFB1YmxpY0tleS5maW5kUHJvZ3JhbUFkZHJlc3NTeW5jKFxuICAgIFtCdWZmZXIuZnJvbSgnbWFya2V0JyksIG1hcmtldElkQnVmZmVyXSxcbiAgICBQUk9HUkFNX0lEXG4gICk7XG4gIHJldHVybiBwZGEudG9CYXNlNTgoKTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENMQUlNQUJMRSBQT1NJVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogR2V0IGFsbCBjbGFpbWFibGUgcG9zaXRpb25zIGZvciBhIHdhbGxldFxuICogQ2hlY2tzIHdoaWNoIHBvc2l0aW9ucyBjYW4gYmUgY2xhaW1lZCAod2lubmluZ3Mgb3IgcmVmdW5kcylcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldENsYWltYWJsZVBvc2l0aW9ucyh3YWxsZXRBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPENsYWltU3VtbWFyeT4ge1xuICBjb25zdCBwb3NpdGlvbnMgPSBhd2FpdCBnZXRQb3NpdGlvbnMod2FsbGV0QWRkcmVzcyk7XG5cbiAgY29uc3QgY2xhaW1hYmxlOiBDbGFpbWFibGVQb3NpdGlvbltdID0gW107XG4gIGxldCB3aW5uaW5nc1RvdGFsID0gMDtcbiAgbGV0IHJlZnVuZHNUb3RhbCA9IDA7XG4gIGxldCBhbHJlYWR5Q2xhaW1lZCA9IDA7XG5cbiAgZm9yIChjb25zdCBwb3NpdGlvbiBvZiBwb3NpdGlvbnMpIHtcbiAgICBpZiAocG9zaXRpb24uY2xhaW1lZCkge1xuICAgICAgYWxyZWFkeUNsYWltZWQrKztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIERlcml2ZSBtYXJrZXQgUERBIGZyb20gbWFya2V0X2lkXG4gICAgY29uc3QgbWFya2V0UGRhID0gZGVyaXZlTWFya2V0UGRhKHBvc2l0aW9uLm1hcmtldElkKTtcblxuICAgIC8vIEZldGNoIG1hcmtldCB0byBjaGVjayBzdGF0dXNcbiAgICBjb25zdCBtYXJrZXQgPSBhd2FpdCBnZXRNYXJrZXQobWFya2V0UGRhKTtcbiAgICBpZiAoIW1hcmtldCkgY29udGludWU7XG5cbiAgICAvLyBHZXQgdGhlIGJldCBhbW91bnQgZm9yIHRoZSB3aW5uaW5nIHNpZGVcbiAgICBjb25zdCB5ZXNBbW91bnQgPSBwb3NpdGlvbi55ZXNBbW91bnRTb2w7XG4gICAgY29uc3Qgbm9BbW91bnQgPSBwb3NpdGlvbi5ub0Ftb3VudFNvbDtcbiAgICBjb25zdCB0b3RhbEJldCA9IHllc0Ftb3VudCArIG5vQW1vdW50O1xuXG4gICAgbGV0IGNsYWltVHlwZTogJ3dpbm5pbmdzJyB8ICdyZWZ1bmQnIHwgJ2NhbmNlbGxlZCcgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZXN0aW1hdGVkUGF5b3V0ID0gMDtcbiAgICBsZXQgd2lubmluZ1NpZGU6ICdZZXMnIHwgJ05vJyB8IG51bGwgPSBudWxsO1xuXG4gICAgaWYgKG1hcmtldC5zdGF0dXMgPT09ICdSZXNvbHZlZCcpIHtcbiAgICAgIC8vIENoZWNrIGlmIHVzZXIgYmV0IG9uIHRoZSB3aW5uaW5nIHNpZGVcbiAgICAgIGlmIChtYXJrZXQud2lubmluZ091dGNvbWUgPT09ICdZZXMnICYmIHllc0Ftb3VudCA+IDApIHtcbiAgICAgICAgd2lubmluZ1NpZGUgPSAnWWVzJztcbiAgICAgICAgY2xhaW1UeXBlID0gJ3dpbm5pbmdzJztcbiAgICAgICAgY29uc3QgdG90YWxQb29sID0gbWFya2V0Lnllc1Bvb2xTb2wgKyBtYXJrZXQubm9Qb29sU29sO1xuICAgICAgICBpZiAobWFya2V0Lnllc1Bvb2xTb2wgPiAwKSB7XG4gICAgICAgICAgY29uc3Qgc2hhcmUgPSB5ZXNBbW91bnQgLyBtYXJrZXQueWVzUG9vbFNvbDtcbiAgICAgICAgICBjb25zdCBncm9zc1BheW91dCA9IHNoYXJlICogdG90YWxQb29sO1xuICAgICAgICAgIGNvbnN0IHByb2ZpdCA9IGdyb3NzUGF5b3V0IC0geWVzQW1vdW50O1xuICAgICAgICAgIGNvbnN0IGZlZSA9IHByb2ZpdCA+IDAgPyAocHJvZml0ICogbWFya2V0LnBsYXRmb3JtRmVlQnBzKSAvIDEwMDAwIDogMDtcbiAgICAgICAgICBlc3RpbWF0ZWRQYXlvdXQgPSBncm9zc1BheW91dCAtIGZlZTtcbiAgICAgICAgfVxuICAgICAgICB3aW5uaW5nc1RvdGFsICs9IGVzdGltYXRlZFBheW91dDtcbiAgICAgIH0gZWxzZSBpZiAobWFya2V0Lndpbm5pbmdPdXRjb21lID09PSAnTm8nICYmIG5vQW1vdW50ID4gMCkge1xuICAgICAgICB3aW5uaW5nU2lkZSA9ICdObyc7XG4gICAgICAgIGNsYWltVHlwZSA9ICd3aW5uaW5ncyc7XG4gICAgICAgIGNvbnN0IHRvdGFsUG9vbCA9IG1hcmtldC55ZXNQb29sU29sICsgbWFya2V0Lm5vUG9vbFNvbDtcbiAgICAgICAgaWYgKG1hcmtldC5ub1Bvb2xTb2wgPiAwKSB7XG4gICAgICAgICAgY29uc3Qgc2hhcmUgPSBub0Ftb3VudCAvIG1hcmtldC5ub1Bvb2xTb2w7XG4gICAgICAgICAgY29uc3QgZ3Jvc3NQYXlvdXQgPSBzaGFyZSAqIHRvdGFsUG9vbDtcbiAgICAgICAgICBjb25zdCBwcm9maXQgPSBncm9zc1BheW91dCAtIG5vQW1vdW50O1xuICAgICAgICAgIGNvbnN0IGZlZSA9IHByb2ZpdCA+IDAgPyAocHJvZml0ICogbWFya2V0LnBsYXRmb3JtRmVlQnBzKSAvIDEwMDAwIDogMDtcbiAgICAgICAgICBlc3RpbWF0ZWRQYXlvdXQgPSBncm9zc1BheW91dCAtIGZlZTtcbiAgICAgICAgfVxuICAgICAgICB3aW5uaW5nc1RvdGFsICs9IGVzdGltYXRlZFBheW91dDtcbiAgICAgIH0gZWxzZSBpZiAobWFya2V0Lndpbm5pbmdPdXRjb21lID09PSBudWxsKSB7XG4gICAgICAgIC8vIEludmFsaWQvRHJhdyAtIHJlZnVuZCBhbGwgYmV0c1xuICAgICAgICBjbGFpbVR5cGUgPSAncmVmdW5kJztcbiAgICAgICAgZXN0aW1hdGVkUGF5b3V0ID0gdG90YWxCZXQ7XG4gICAgICAgIHdpbm5pbmdTaWRlID0geWVzQW1vdW50ID4gbm9BbW91bnQgPyAnWWVzJyA6ICdObyc7XG4gICAgICAgIHJlZnVuZHNUb3RhbCArPSBlc3RpbWF0ZWRQYXlvdXQ7XG4gICAgICB9XG4gICAgICAvLyBMb3NlciAtIG5vdGhpbmcgdG8gY2xhaW1cbiAgICB9IGVsc2UgaWYgKG1hcmtldC5zdGF0dXMgPT09ICdDYW5jZWxsZWQnKSB7XG4gICAgICAvLyBDYW5jZWxsZWQgLSBmdWxsIHJlZnVuZCBvZiBhbGwgYmV0c1xuICAgICAgY2xhaW1UeXBlID0gJ2NhbmNlbGxlZCc7XG4gICAgICBlc3RpbWF0ZWRQYXlvdXQgPSB0b3RhbEJldDtcbiAgICAgIHdpbm5pbmdTaWRlID0geWVzQW1vdW50ID4gbm9BbW91bnQgPyAnWWVzJyA6ICdObyc7XG4gICAgICByZWZ1bmRzVG90YWwgKz0gZXN0aW1hdGVkUGF5b3V0O1xuICAgIH1cblxuICAgIGlmIChjbGFpbVR5cGUgJiYgd2lubmluZ1NpZGUpIHtcbiAgICAgIGNsYWltYWJsZS5wdXNoKHtcbiAgICAgICAgcG9zaXRpb25QZGE6IHBvc2l0aW9uLnB1YmxpY0tleSxcbiAgICAgICAgbWFya2V0UGRhLFxuICAgICAgICBtYXJrZXRRdWVzdGlvbjogbWFya2V0LnF1ZXN0aW9uLFxuICAgICAgICBzaWRlOiB3aW5uaW5nU2lkZSxcbiAgICAgICAgYmV0QW1vdW50U29sOiB3aW5uaW5nU2lkZSA9PT0gJ1llcycgPyB5ZXNBbW91bnQgOiBub0Ftb3VudCxcbiAgICAgICAgY2xhaW1UeXBlLFxuICAgICAgICBlc3RpbWF0ZWRQYXlvdXRTb2w6IHJvdW5kNChlc3RpbWF0ZWRQYXlvdXQpLFxuICAgICAgICBtYXJrZXRTdGF0dXM6IG1hcmtldC5zdGF0dXMsXG4gICAgICAgIG1hcmtldE91dGNvbWU6IG1hcmtldC53aW5uaW5nT3V0Y29tZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2FsbGV0OiB3YWxsZXRBZGRyZXNzLFxuICAgIHRvdGFsQ2xhaW1hYmxlU29sOiByb3VuZDQod2lubmluZ3NUb3RhbCArIHJlZnVuZHNUb3RhbCksXG4gICAgd2lubmluZ3NDbGFpbWFibGVTb2w6IHJvdW5kNCh3aW5uaW5nc1RvdGFsKSxcbiAgICByZWZ1bmRzQ2xhaW1hYmxlU29sOiByb3VuZDQocmVmdW5kc1RvdGFsKSxcbiAgICBjbGFpbWFibGVQb3NpdGlvbnM6IGNsYWltYWJsZSxcbiAgICBhbHJlYWR5Q2xhaW1lZENvdW50OiBhbHJlYWR5Q2xhaW1lZCxcbiAgfTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEFGRklMSUFURSBJTkZPXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIERlY29kZSBBZmZpbGlhdGUgYWNjb3VudFxuICogQWZmaWxpYXRlIHN0cnVjdDpcbiAqIC0gZGlzY3JpbWluYXRvciAoOClcbiAqIC0gb3duZXIgKFB1YmtleSwgMzIpXG4gKiAtIGNvZGUgKFN0cmluZzogNCArIGxlbilcbiAqIC0gdG90YWxfZWFybmVkICh1NjQsIDgpXG4gKiAtIHRvdGFsX2NsYWltZWQgKHU2NCwgOClcbiAqIC0gcmVmZXJyYWxfY291bnQgKHU2NCwgOClcbiAqIC0gaXNfYWN0aXZlIChib29sLCAxKVxuICogLSBidW1wICh1OCwgMSlcbiAqL1xuZnVuY3Rpb24gZGVjb2RlQWZmaWxpYXRlKGRhdGE6IEJ1ZmZlciwgcHVia2V5OiBQdWJsaWNLZXkpOiBBZmZpbGlhdGVJbmZvIHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgbGV0IG9mZnNldCA9IDg7IC8vIFNraXAgZGlzY3JpbWluYXRvclxuXG4gICAgY29uc3Qgb3duZXIgPSBuZXcgUHVibGljS2V5KGRhdGEuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyAzMikpO1xuICAgIG9mZnNldCArPSAzMjtcblxuICAgIGNvbnN0IGNvZGVMZW4gPSBkYXRhLnJlYWRVSW50MzJMRShvZmZzZXQpO1xuICAgIG9mZnNldCArPSA0O1xuICAgIGNvbnN0IGNvZGUgPSBkYXRhLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgY29kZUxlbikudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICBvZmZzZXQgKz0gY29kZUxlbjtcblxuICAgIGNvbnN0IHRvdGFsRWFybmVkID0gZGF0YS5yZWFkQmlnVUludDY0TEUob2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gODtcblxuICAgIGNvbnN0IHRvdGFsQ2xhaW1lZCA9IGRhdGEucmVhZEJpZ1VJbnQ2NExFKG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IDg7XG5cbiAgICBjb25zdCByZWZlcnJhbENvdW50ID0gZGF0YS5yZWFkQmlnVUludDY0TEUob2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gODtcblxuICAgIGNvbnN0IGlzQWN0aXZlID0gZGF0YS5yZWFkVUludDgob2Zmc2V0KSA9PT0gMTtcblxuICAgIHJldHVybiB7XG4gICAgICBhZmZpbGlhdGVQZGE6IHB1YmtleS50b0Jhc2U1OCgpLFxuICAgICAgb3duZXI6IG93bmVyLnRvQmFzZTU4KCksXG4gICAgICBjb2RlLFxuICAgICAgdG90YWxFYXJuZWRTb2w6IHJvdW5kNChsYW1wb3J0c1RvU29sKHRvdGFsRWFybmVkKSksXG4gICAgICB1bmNsYWltZWRTb2w6IHJvdW5kNChsYW1wb3J0c1RvU29sKHRvdGFsRWFybmVkIC0gdG90YWxDbGFpbWVkKSksXG4gICAgICByZWZlcnJhbENvdW50OiBOdW1iZXIocmVmZXJyYWxDb3VudCksXG4gICAgICBpc0FjdGl2ZSxcbiAgICB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBhZmZpbGlhdGUgaW5mbyBieSBjb2RlXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRBZmZpbGlhdGVCeUNvZGUoY29kZTogc3RyaW5nKTogUHJvbWlzZTxBZmZpbGlhdGVJbmZvIHwgbnVsbD4ge1xuICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24oUlBDX0VORFBPSU5ULCAnY29uZmlybWVkJyk7XG5cbiAgLy8gRGVyaXZlIGFmZmlsaWF0ZSBQREEgZnJvbSBjb2RlXG4gIGNvbnN0IFthZmZpbGlhdGVQZGFdID0gUHVibGljS2V5LmZpbmRQcm9ncmFtQWRkcmVzc1N5bmMoXG4gICAgW1NFRURTLkFGRklMSUFURSwgQnVmZmVyLmZyb20oY29kZSldLFxuICAgIFBST0dSQU1fSURcbiAgKTtcblxuICB0cnkge1xuICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBjb25uZWN0aW9uLmdldEFjY291bnRJbmZvKGFmZmlsaWF0ZVBkYSk7XG4gICAgaWYgKCFhY2NvdW50KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gZGVjb2RlQWZmaWxpYXRlKGFjY291bnQuZGF0YSBhcyBCdWZmZXIsIGFmZmlsaWF0ZVBkYSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogR2V0IGFmZmlsaWF0ZSBpbmZvIGJ5IG93bmVyIHdhbGxldFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0QWZmaWxpYXRlQnlPd25lcih3YWxsZXRBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPEFmZmlsaWF0ZUluZm9bXT4ge1xuICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24oUlBDX0VORFBPSU5ULCAnY29uZmlybWVkJyk7XG5cbiAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBjb25uZWN0aW9uLmdldFByb2dyYW1BY2NvdW50cyhQUk9HUkFNX0lELCB7XG4gICAgZmlsdGVyczogW1xuICAgICAge1xuICAgICAgICBtZW1jbXA6IHtcbiAgICAgICAgICBvZmZzZXQ6IDAsXG4gICAgICAgICAgYnl0ZXM6IGJzNTguZW5jb2RlKERJU0NSSU1JTkFUT1JTLkFGRklMSUFURSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBtZW1jbXA6IHtcbiAgICAgICAgICBvZmZzZXQ6IDgsIC8vIEFmdGVyIGRpc2NyaW1pbmF0b3JcbiAgICAgICAgICBieXRlczogd2FsbGV0QWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSk7XG5cbiAgY29uc3QgYWZmaWxpYXRlczogQWZmaWxpYXRlSW5mb1tdID0gW107XG4gIGZvciAoY29uc3QgeyBhY2NvdW50LCBwdWJrZXkgfSBvZiBhY2NvdW50cykge1xuICAgIGNvbnN0IGFmZmlsaWF0ZSA9IGRlY29kZUFmZmlsaWF0ZShhY2NvdW50LmRhdGEgYXMgQnVmZmVyLCBwdWJrZXkpO1xuICAgIGlmIChhZmZpbGlhdGUpIHtcbiAgICAgIGFmZmlsaWF0ZXMucHVzaChhZmZpbGlhdGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBhZmZpbGlhdGVzO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gSEVMUEVSU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gcm91bmQ0KG46IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJvdW5kKG4gKiAxMDAwMCkgLyAxMDAwMDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Market Creation Handler
|
|
3
|
+
*
|
|
4
|
+
* Provides high-level functions for creating markets:
|
|
5
|
+
* - Validation against v6.2 rules
|
|
6
|
+
* - Fee calculation
|
|
7
|
+
* - Transaction building
|
|
8
|
+
* - PDA derivation helpers
|
|
9
|
+
*/
|
|
10
|
+
import { Connection } from '@solana/web3.js';
|
|
11
|
+
import { CreationValidationResult } from '../validation/creation-rules.js';
|
|
12
|
+
export interface MarketCreationPreview {
|
|
13
|
+
validation: CreationValidationResult;
|
|
14
|
+
marketPda?: string;
|
|
15
|
+
marketId?: string;
|
|
16
|
+
creationFeeSol: number;
|
|
17
|
+
platformFeeBps: number;
|
|
18
|
+
estimatedRentSol: number;
|
|
19
|
+
totalCostSol: number;
|
|
20
|
+
recommendedTiming?: {
|
|
21
|
+
closingTime: string;
|
|
22
|
+
resolutionTime: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface CreateMarketRequest {
|
|
26
|
+
question: string;
|
|
27
|
+
layer: 'lab' | 'private';
|
|
28
|
+
closingTime: string;
|
|
29
|
+
resolutionTime?: string;
|
|
30
|
+
marketType?: 'event' | 'measurement';
|
|
31
|
+
eventTime?: string;
|
|
32
|
+
measurementStart?: string;
|
|
33
|
+
measurementEnd?: string;
|
|
34
|
+
inviteHash?: string;
|
|
35
|
+
creatorWallet: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CreateRaceMarketRequest {
|
|
38
|
+
question: string;
|
|
39
|
+
outcomes: string[];
|
|
40
|
+
closingTime: string;
|
|
41
|
+
resolutionTime?: string;
|
|
42
|
+
creatorWallet: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Preview market creation - validates and returns costs without building tx
|
|
46
|
+
*/
|
|
47
|
+
export declare function previewMarketCreation(params: CreateMarketRequest, connection?: Connection): Promise<MarketCreationPreview>;
|
|
48
|
+
/**
|
|
49
|
+
* Preview race market creation
|
|
50
|
+
*/
|
|
51
|
+
export declare function previewRaceMarketCreation(params: CreateRaceMarketRequest, connection?: Connection): Promise<MarketCreationPreview>;
|
|
52
|
+
/**
|
|
53
|
+
* Build lab market creation transaction with full validation
|
|
54
|
+
*/
|
|
55
|
+
export declare function createLabMarket(params: CreateMarketRequest, connection?: Connection): Promise<{
|
|
56
|
+
success: boolean;
|
|
57
|
+
error?: string;
|
|
58
|
+
validation: CreationValidationResult;
|
|
59
|
+
transaction?: {
|
|
60
|
+
serialized: string;
|
|
61
|
+
marketPda: string;
|
|
62
|
+
marketId: string;
|
|
63
|
+
};
|
|
64
|
+
simulation?: {
|
|
65
|
+
success: boolean;
|
|
66
|
+
error?: string;
|
|
67
|
+
unitsConsumed?: number;
|
|
68
|
+
};
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Build private market creation transaction
|
|
72
|
+
*/
|
|
73
|
+
export declare function createPrivateMarket(params: CreateMarketRequest, connection?: Connection): Promise<{
|
|
74
|
+
success: boolean;
|
|
75
|
+
error?: string;
|
|
76
|
+
validation: CreationValidationResult;
|
|
77
|
+
transaction?: {
|
|
78
|
+
serialized: string;
|
|
79
|
+
marketPda: string;
|
|
80
|
+
marketId: string;
|
|
81
|
+
};
|
|
82
|
+
simulation?: {
|
|
83
|
+
success: boolean;
|
|
84
|
+
error?: string;
|
|
85
|
+
};
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Build race market creation transaction
|
|
89
|
+
*/
|
|
90
|
+
export declare function createRaceMarket(params: CreateRaceMarketRequest, connection?: Connection): Promise<{
|
|
91
|
+
success: boolean;
|
|
92
|
+
error?: string;
|
|
93
|
+
validation: CreationValidationResult;
|
|
94
|
+
transaction?: {
|
|
95
|
+
serialized: string;
|
|
96
|
+
raceMarketPda: string;
|
|
97
|
+
marketId: string;
|
|
98
|
+
};
|
|
99
|
+
simulation?: {
|
|
100
|
+
success: boolean;
|
|
101
|
+
error?: string;
|
|
102
|
+
};
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Get creation fees for all layers
|
|
106
|
+
*/
|
|
107
|
+
export declare function getAllCreationFees(): {
|
|
108
|
+
official: {
|
|
109
|
+
sol: number;
|
|
110
|
+
lamports: number;
|
|
111
|
+
};
|
|
112
|
+
lab: {
|
|
113
|
+
sol: number;
|
|
114
|
+
lamports: number;
|
|
115
|
+
};
|
|
116
|
+
private: {
|
|
117
|
+
sol: number;
|
|
118
|
+
lamports: number;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Get platform fees for all layers
|
|
123
|
+
*/
|
|
124
|
+
export declare function getAllPlatformFees(): {
|
|
125
|
+
official: {
|
|
126
|
+
bps: number;
|
|
127
|
+
percent: string;
|
|
128
|
+
};
|
|
129
|
+
lab: {
|
|
130
|
+
bps: number;
|
|
131
|
+
percent: string;
|
|
132
|
+
};
|
|
133
|
+
private: {
|
|
134
|
+
bps: number;
|
|
135
|
+
percent: string;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Get timing constraints
|
|
140
|
+
*/
|
|
141
|
+
export declare function getTimingConstraints(): {
|
|
142
|
+
minEventBufferHours: number;
|
|
143
|
+
recommendedEventBufferHours: number;
|
|
144
|
+
bettingFreezeSeconds: number;
|
|
145
|
+
maxMarketDurationDays: number;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Generate invite hash for private market
|
|
149
|
+
*/
|
|
150
|
+
export declare function generateInviteHash(): string;
|
|
151
|
+
/**
|
|
152
|
+
* Derive invite link from hash
|
|
153
|
+
*/
|
|
154
|
+
export declare function getInviteLink(marketPda: string, inviteHash: string): string;
|