@ab-org/predicate-market-sdk 2.0.0 → 2.1.1-beta.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 +42 -7
- package/dist/account-F5Z2SMJE.js +213 -0
- package/dist/api-DyQAYQ0i.d.ts +156 -0
- package/dist/auth.d.ts +8 -0
- package/dist/auth.js +1 -0
- package/dist/autoReconnect-IFPVI2XU.js +33 -0
- package/dist/chunk-6YQEHB6P.js +14 -0
- package/dist/chunk-F2UPP3YC.js +88 -0
- package/dist/chunk-IUBVUCWJ.js +419 -0
- package/dist/chunk-JFRRJXOJ.js +149 -0
- package/dist/chunk-LOJTP47I.js +6 -0
- package/dist/chunk-SHLNBZBY.js +72 -0
- package/dist/chunk-SZYGIQT3.js +3192 -0
- package/dist/chunk-TPMI3XWV.js +114 -0
- package/dist/chunk-UAXKA6QC.js +17 -0
- package/dist/chunk-WHTI52FI.js +10 -0
- package/dist/chunk-XB2DFS2W.js +50 -0
- package/dist/chunk-YX56ZGDB.js +274 -0
- package/dist/core.d.ts +63 -0
- package/dist/core.js +6 -0
- package/dist/dist-Q2PDXT2F.js +81 -0
- package/dist/index.d.ts +12 -706
- package/dist/index.js +12 -43009
- package/dist/merchant.d.ts +206 -0
- package/dist/merchant.js +4 -0
- package/dist/react.d.ts +197 -0
- package/dist/react.js +7 -0
- package/dist/signInTypes-DESvmgWG.d.ts +41 -0
- package/dist/types-BFidNjd9.d.ts +64 -0
- package/package.json +23 -11
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { getChainInfo, getFundingTokenAddress, DEFAULT_FUNDING_CHAIN_ID } from './chunk-F2UPP3YC.js';
|
|
2
|
+
import { getChains, createOrder } from './chunk-TPMI3XWV.js';
|
|
3
|
+
import { getEnv } from './chunk-SHLNBZBY.js';
|
|
4
|
+
import { sessionStore, createSessionCapabilityPolicy } from '@ab-org/sdk-core';
|
|
5
|
+
import { formatUnits } from 'viem';
|
|
6
|
+
|
|
7
|
+
function requireSession() {
|
|
8
|
+
const session = sessionStore.getState().session;
|
|
9
|
+
if (!session) throw new Error("Login required");
|
|
10
|
+
return session;
|
|
11
|
+
}
|
|
12
|
+
var createDepositController = (custody, marketData) => {
|
|
13
|
+
let status = { phase: "idle" };
|
|
14
|
+
const notify = (next, cb) => {
|
|
15
|
+
status = next;
|
|
16
|
+
cb?.(status);
|
|
17
|
+
};
|
|
18
|
+
const open = async (config) => {
|
|
19
|
+
const session = requireSession();
|
|
20
|
+
const chain = config?.preferredChain ?? session.chainContext?.settlementChain ?? session.chain ?? "AB_CORE";
|
|
21
|
+
const token = config?.preferredToken || getEnv("FUNDING_TOKEN_SYMBOL") || "USDT";
|
|
22
|
+
try {
|
|
23
|
+
const { address } = await marketData.getDepositAddress(token, chain);
|
|
24
|
+
const depositId = `${chain}:${token}:${Date.now()}`;
|
|
25
|
+
notify({ phase: "address-issued", depositId, address }, config?.onStatusChange);
|
|
26
|
+
notify({ phase: "confirming", depositId }, config?.onStatusChange);
|
|
27
|
+
const { status: finalStatus, txHash } = await custody.getDepositStatus(depositId);
|
|
28
|
+
notify(
|
|
29
|
+
finalStatus === "SETTLED" ? { phase: "settled", depositId, txHash } : { phase: "failed", reason: finalStatus },
|
|
30
|
+
config?.onStatusChange
|
|
31
|
+
);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
notify({ phase: "failed", reason: error.message }, config?.onStatusChange);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
get status() {
|
|
38
|
+
return status;
|
|
39
|
+
},
|
|
40
|
+
open,
|
|
41
|
+
fetchTokens() {
|
|
42
|
+
requireSession();
|
|
43
|
+
return marketData.getSupportedTokens("deposit");
|
|
44
|
+
},
|
|
45
|
+
fetchChains(token) {
|
|
46
|
+
requireSession();
|
|
47
|
+
return marketData.getSupportedChains(token, "deposit");
|
|
48
|
+
},
|
|
49
|
+
fetchQuote(token, chain, amount) {
|
|
50
|
+
requireSession();
|
|
51
|
+
return marketData.getQuote({ token, chain, amount, direction: "deposit" });
|
|
52
|
+
},
|
|
53
|
+
fetchDepositAddress(token, chain) {
|
|
54
|
+
requireSession();
|
|
55
|
+
return marketData.getDepositAddress(token, chain);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
function requireSession2() {
|
|
60
|
+
const session = sessionStore.getState().session;
|
|
61
|
+
if (!session) throw new Error("Login required");
|
|
62
|
+
return session;
|
|
63
|
+
}
|
|
64
|
+
var createWithdrawController = (custody, marketData) => {
|
|
65
|
+
let status = { phase: "idle" };
|
|
66
|
+
const update = (next, cb) => {
|
|
67
|
+
status = next;
|
|
68
|
+
cb?.(status);
|
|
69
|
+
};
|
|
70
|
+
const open = async (config) => {
|
|
71
|
+
const session = requireSession2();
|
|
72
|
+
const token = config?.defaultToken || getEnv("FUNDING_TOKEN_SYMBOL") || "USDT";
|
|
73
|
+
const chain = config?.defaultChain ?? session.chainContext?.settlementChain ?? session.chain ?? "AB_CORE";
|
|
74
|
+
const targetAddress = config?.targetAddress;
|
|
75
|
+
if (!targetAddress) throw new Error("targetAddress required for withdraw");
|
|
76
|
+
try {
|
|
77
|
+
const { requestId } = await custody.requestWithdraw({
|
|
78
|
+
amount: config?.defaultAmount ?? "0",
|
|
79
|
+
token,
|
|
80
|
+
chain,
|
|
81
|
+
targetAddress
|
|
82
|
+
});
|
|
83
|
+
update({ phase: "requested", requestId }, config?.onStatusChange);
|
|
84
|
+
update({ phase: "processing", requestId }, config?.onStatusChange);
|
|
85
|
+
const { status: finalStatus, txHash } = await custody.getWithdrawStatus(requestId);
|
|
86
|
+
update(
|
|
87
|
+
finalStatus === "SETTLED" ? { phase: "settled", requestId, txHash } : { phase: "failed", reason: finalStatus },
|
|
88
|
+
config?.onStatusChange
|
|
89
|
+
);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
update({ phase: "failed", reason: error.message }, config?.onStatusChange);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
get status() {
|
|
96
|
+
return status;
|
|
97
|
+
},
|
|
98
|
+
open,
|
|
99
|
+
fetchTokens() {
|
|
100
|
+
requireSession2();
|
|
101
|
+
return marketData.getSupportedTokens("withdraw");
|
|
102
|
+
},
|
|
103
|
+
fetchChains(token) {
|
|
104
|
+
requireSession2();
|
|
105
|
+
return marketData.getSupportedChains(token, "withdraw");
|
|
106
|
+
},
|
|
107
|
+
fetchQuote(token, chain, amount) {
|
|
108
|
+
requireSession2();
|
|
109
|
+
return marketData.getQuote({ token, chain, amount, direction: "withdraw" });
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
var cachedChains = null;
|
|
114
|
+
async function fetchChainsFromApi() {
|
|
115
|
+
if (cachedChains) return cachedChains;
|
|
116
|
+
try {
|
|
117
|
+
const { chains } = await getChains();
|
|
118
|
+
if (chains.length > 0) {
|
|
119
|
+
cachedChains = chains;
|
|
120
|
+
return chains;
|
|
121
|
+
}
|
|
122
|
+
return [];
|
|
123
|
+
} catch {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function chainToChainInfo(chain) {
|
|
128
|
+
return {
|
|
129
|
+
id: chain.chain_id,
|
|
130
|
+
name: chain.network
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function findTokenInChains(chains, chainId, tokenSymbol) {
|
|
134
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
135
|
+
return chain?.tokens.find((t) => t.symbol === tokenSymbol);
|
|
136
|
+
}
|
|
137
|
+
function formatMinimumDepositDisplay(token, tokenSymbol) {
|
|
138
|
+
const raw = token.minimum_deposit?.trim();
|
|
139
|
+
if (raw == null || raw === "") return void 0;
|
|
140
|
+
try {
|
|
141
|
+
return `${formatUnits(BigInt(raw), token.decimals)} ${tokenSymbol}`;
|
|
142
|
+
} catch {
|
|
143
|
+
return `${raw} ${tokenSymbol}`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function deriveTokensFromChains(chains) {
|
|
147
|
+
const bySymbol = /* @__PURE__ */ new Map();
|
|
148
|
+
for (const chain of chains) {
|
|
149
|
+
for (const t of chain.tokens) {
|
|
150
|
+
if (!bySymbol.has(t.symbol)) {
|
|
151
|
+
bySymbol.set(t.symbol, {
|
|
152
|
+
symbol: t.symbol,
|
|
153
|
+
name: t.symbol,
|
|
154
|
+
decimals: t.decimals
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return Array.from(bySymbol.values());
|
|
160
|
+
}
|
|
161
|
+
function computeDefaultQuote(request) {
|
|
162
|
+
const isStable = ["USDT", "USDC", "USD1"].includes(request.token);
|
|
163
|
+
const slippage = isStable ? "0.3" : "1.0";
|
|
164
|
+
const feeRate = request.direction === "withdraw" ? 1e-3 : 0;
|
|
165
|
+
const amount = Number(request.amount) || 0;
|
|
166
|
+
const fee = (amount * feeRate).toFixed(2);
|
|
167
|
+
const estimatedAmount = (amount - Number(fee)).toFixed(6);
|
|
168
|
+
return {
|
|
169
|
+
quoteId: `quote-${Date.now()}`,
|
|
170
|
+
estimatedAmount: amount > 0 ? estimatedAmount : "0",
|
|
171
|
+
slippage,
|
|
172
|
+
fee,
|
|
173
|
+
feeToken: request.token,
|
|
174
|
+
exchangeRate: "1.0",
|
|
175
|
+
expiresAt: Date.now() + 3e4
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function createMarketDataProvider() {
|
|
179
|
+
return {
|
|
180
|
+
async getSupportedTokens(_direction) {
|
|
181
|
+
const chains = await fetchChainsFromApi();
|
|
182
|
+
const tokens = deriveTokensFromChains(chains);
|
|
183
|
+
return tokens.length > 0 ? tokens : [];
|
|
184
|
+
},
|
|
185
|
+
async getSupportedChains(token, _direction) {
|
|
186
|
+
const chains = await fetchChainsFromApi();
|
|
187
|
+
const forToken = chains.filter((c) => c.tokens.some((t) => t.symbol === token));
|
|
188
|
+
const list = forToken.length > 0 ? forToken : chains;
|
|
189
|
+
return list.map(chainToChainInfo);
|
|
190
|
+
},
|
|
191
|
+
async getQuote(request) {
|
|
192
|
+
return computeDefaultQuote(request);
|
|
193
|
+
},
|
|
194
|
+
async getDepositAddress(token, chain) {
|
|
195
|
+
const session = sessionStore.getState().session;
|
|
196
|
+
const chains = await fetchChainsFromApi();
|
|
197
|
+
const meta = findTokenInChains(chains, chain, token);
|
|
198
|
+
const minimumDeposit = meta != null ? formatMinimumDepositDisplay(meta, token) : void 0;
|
|
199
|
+
return {
|
|
200
|
+
address: session?.address ?? "",
|
|
201
|
+
minimumDeposit
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// src/modules/balanceQuery.ts
|
|
208
|
+
var ERC20_BALANCE_OF_SELECTOR = "0x70a08231";
|
|
209
|
+
function padAddress(address) {
|
|
210
|
+
return address.toLowerCase().replace("0x", "").padStart(64, "0");
|
|
211
|
+
}
|
|
212
|
+
function formatUnits2(value, decimals) {
|
|
213
|
+
const divisor = 10n ** BigInt(decimals);
|
|
214
|
+
const intPart = value / divisor;
|
|
215
|
+
const fracPart = value % divisor;
|
|
216
|
+
if (fracPart === 0n) return intPart.toString();
|
|
217
|
+
const fracStr = fracPart.toString().padStart(decimals, "0").replace(/0+$/, "");
|
|
218
|
+
return `${intPart}.${fracStr}`;
|
|
219
|
+
}
|
|
220
|
+
function formatBalanceDisplay(value, decimals) {
|
|
221
|
+
const full = formatUnits2(value, decimals);
|
|
222
|
+
const n = Number(full);
|
|
223
|
+
return Number.isNaN(n) ? full : n.toFixed(2);
|
|
224
|
+
}
|
|
225
|
+
async function fetchErc20Balance(rpcUrl, tokenAddress, walletAddress) {
|
|
226
|
+
const data = `${ERC20_BALANCE_OF_SELECTOR}${padAddress(walletAddress)}`;
|
|
227
|
+
const response = await fetch(rpcUrl, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers: { "Content-Type": "application/json" },
|
|
230
|
+
body: JSON.stringify({
|
|
231
|
+
jsonrpc: "2.0",
|
|
232
|
+
id: 1,
|
|
233
|
+
method: "eth_call",
|
|
234
|
+
params: [{ to: tokenAddress, data }, "latest"]
|
|
235
|
+
})
|
|
236
|
+
});
|
|
237
|
+
const json = await response.json();
|
|
238
|
+
if (json.error) throw new Error(json.error.message ?? "RPC error");
|
|
239
|
+
return BigInt(json.result ?? "0x0");
|
|
240
|
+
}
|
|
241
|
+
async function fetchFundingTokenBalance(walletAddress, options) {
|
|
242
|
+
const chain = getChainInfo(options?.chainId);
|
|
243
|
+
const rpcUrl = options?.rpcUrl ?? chain.rpcUrls[0];
|
|
244
|
+
const tokenAddress = options?.tokenAddress ?? getFundingTokenAddress(options?.chainId);
|
|
245
|
+
const decimals = options?.decimals ?? chain.nativeCurrencyDecimals;
|
|
246
|
+
const FUNDING_TOKEN_SYMBOL = getEnv("FUNDING_TOKEN_SYMBOL");
|
|
247
|
+
const displaySymbol = options?.displaySymbol ?? (FUNDING_TOKEN_SYMBOL || "Funding");
|
|
248
|
+
const raw = await fetchErc20Balance(rpcUrl, tokenAddress, walletAddress);
|
|
249
|
+
return {
|
|
250
|
+
raw,
|
|
251
|
+
formatted: formatBalanceDisplay(raw, decimals),
|
|
252
|
+
symbol: displaySymbol
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/modules/withdrawDirect.ts
|
|
257
|
+
function isUsdtWithdrawDirect(chainId, tokenAddress, chains) {
|
|
258
|
+
if (chainId !== String(DEFAULT_FUNDING_CHAIN_ID)) return false;
|
|
259
|
+
const addr = tokenAddress.trim();
|
|
260
|
+
if (!addr) return false;
|
|
261
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
262
|
+
const token = chain?.tokens.find((t) => t.address.toLowerCase() === addr.toLowerCase());
|
|
263
|
+
return token?.is_usd_stable === true;
|
|
264
|
+
}
|
|
265
|
+
function findTokenDataFromChains(chains, chainId, opts) {
|
|
266
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
267
|
+
if (!chain?.tokens.length) return void 0;
|
|
268
|
+
const sym = opts.symbol.trim();
|
|
269
|
+
const addr = opts.tokenAddress?.trim().toLowerCase();
|
|
270
|
+
return chain.tokens.find((t) => {
|
|
271
|
+
if (addr && t.address.toLowerCase() === addr) return true;
|
|
272
|
+
if (sym.length > 0 && t.symbol === sym) return true;
|
|
273
|
+
return false;
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// src/modules/withdrawExecutor.ts
|
|
278
|
+
function parseUnits(value, decimals) {
|
|
279
|
+
if (!value || value === "0") return 0n;
|
|
280
|
+
const [intPart = "0", fracPart = ""] = value.split(".");
|
|
281
|
+
const padded = fracPart.padEnd(decimals, "0").slice(0, decimals);
|
|
282
|
+
return BigInt(intPart) * 10n ** BigInt(decimals) + BigInt(padded);
|
|
283
|
+
}
|
|
284
|
+
function getDstTokenAddress(chains, chainId, tokenSymbol) {
|
|
285
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
286
|
+
return chain?.tokens.find((t) => t.symbol === tokenSymbol)?.address;
|
|
287
|
+
}
|
|
288
|
+
function createFundingWithdrawExecutor(options) {
|
|
289
|
+
const fundingChain = getChainInfo(options?.chainId);
|
|
290
|
+
const tokenAddress = options?.tokenAddress ?? getFundingTokenAddress(options?.chainId);
|
|
291
|
+
const decimals = options?.decimals ?? fundingChain.nativeCurrencyDecimals;
|
|
292
|
+
const maxAmountWei = options?.maxAmountWei;
|
|
293
|
+
const fundingLegTokenSymbol = options?.fundingLegTokenSymbol || getEnv("FUNDING_TOKEN_SYMBOL") || "USDT";
|
|
294
|
+
return async (request) => {
|
|
295
|
+
const chainsRes = await getChains();
|
|
296
|
+
const chains = chainsRes?.chains ?? [];
|
|
297
|
+
if (isUsdtWithdrawDirect(request.chain, request.tokenAddress, chains)) {
|
|
298
|
+
return {
|
|
299
|
+
txRequest: {
|
|
300
|
+
toAddress: request.toAddress,
|
|
301
|
+
amount: request.amount,
|
|
302
|
+
token: request.token,
|
|
303
|
+
tokenAddress: request.tokenAddress,
|
|
304
|
+
tokenDecimals: chains.find((c) => c.chain_id === request.chain)?.tokens.find((t) => t.address.toLowerCase() === request.tokenAddress.toLowerCase())?.decimals ?? decimals,
|
|
305
|
+
chain: request.chain
|
|
306
|
+
},
|
|
307
|
+
fundingChainId: request.chain,
|
|
308
|
+
withdrawMode: "direct"
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const amountWei = parseUnits(request.amount, decimals);
|
|
312
|
+
const amountWeiStr = amountWei.toString();
|
|
313
|
+
if (maxAmountWei != null && amountWei > BigInt(maxAmountWei)) {
|
|
314
|
+
throw new Error("Withdraw amount exceeds the single-transaction limit");
|
|
315
|
+
}
|
|
316
|
+
const session = sessionStore.getState().session;
|
|
317
|
+
if (!session) throw new Error("Login required");
|
|
318
|
+
const dstTokenAddress = getDstTokenAddress(chains, request.chain, request.token);
|
|
319
|
+
if (!dstTokenAddress) {
|
|
320
|
+
throw new Error(`Unsupported token ${request.token} on chain ${request.chain}`);
|
|
321
|
+
}
|
|
322
|
+
const sourceTokenSymbol = fundingLegTokenSymbol;
|
|
323
|
+
const orderRes = await createOrder({
|
|
324
|
+
intent_id: `withdraw-${Date.now()}`,
|
|
325
|
+
order_type: "NATIVE_SWAP",
|
|
326
|
+
order_payload: {
|
|
327
|
+
chain_id: fundingChain.chainId,
|
|
328
|
+
token_address: tokenAddress,
|
|
329
|
+
token_amount: amountWeiStr,
|
|
330
|
+
dst_chain_id: request.chain,
|
|
331
|
+
dst_token_address: dstTokenAddress,
|
|
332
|
+
recipient: request.toAddress
|
|
333
|
+
},
|
|
334
|
+
payment_pairs: [
|
|
335
|
+
{
|
|
336
|
+
token_symbol: sourceTokenSymbol,
|
|
337
|
+
token_amount: amountWeiStr,
|
|
338
|
+
token_address: tokenAddress,
|
|
339
|
+
user_address: session.address,
|
|
340
|
+
chain_id: fundingChain.chainId
|
|
341
|
+
}
|
|
342
|
+
]
|
|
343
|
+
});
|
|
344
|
+
const oneTimeAddress = orderRes.payment_sessions?.[0]?.one_time_wallet_address;
|
|
345
|
+
if (!oneTimeAddress) {
|
|
346
|
+
throw new Error("Order created but no one-time wallet address returned");
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
txRequest: {
|
|
350
|
+
toAddress: oneTimeAddress,
|
|
351
|
+
amount: request.amount,
|
|
352
|
+
token: fundingLegTokenSymbol,
|
|
353
|
+
tokenAddress,
|
|
354
|
+
tokenDecimals: decimals,
|
|
355
|
+
chain: fundingChain.chainId
|
|
356
|
+
},
|
|
357
|
+
orderId: orderRes.order_id,
|
|
358
|
+
fundingChainId: fundingChain.chainId,
|
|
359
|
+
withdrawMode: "cross_chain"
|
|
360
|
+
};
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
var createPolicy = (overrides, options) => createSessionCapabilityPolicy({
|
|
364
|
+
appId: options?.appId,
|
|
365
|
+
origin: options?.origin,
|
|
366
|
+
expiresAt: options?.expiresAt,
|
|
367
|
+
...overrides
|
|
368
|
+
});
|
|
369
|
+
var withActionMetadata = (action, policy) => ({
|
|
370
|
+
...policy,
|
|
371
|
+
metadata: {
|
|
372
|
+
...policy.metadata ?? {},
|
|
373
|
+
action
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
var createPredicateMarketPolicyAdapter = (options) => ({
|
|
377
|
+
deposit(token, chain, maxAmount) {
|
|
378
|
+
return withActionMetadata(
|
|
379
|
+
"deposit",
|
|
380
|
+
createPolicy(
|
|
381
|
+
{
|
|
382
|
+
methods: ["eth_sendTransaction"],
|
|
383
|
+
chains: [chain],
|
|
384
|
+
tokens: [token],
|
|
385
|
+
maxAmount
|
|
386
|
+
},
|
|
387
|
+
options
|
|
388
|
+
)
|
|
389
|
+
);
|
|
390
|
+
},
|
|
391
|
+
withdraw(token, chain, maxAmount) {
|
|
392
|
+
return withActionMetadata(
|
|
393
|
+
"withdraw",
|
|
394
|
+
createPolicy(
|
|
395
|
+
{
|
|
396
|
+
methods: ["eth_sendTransaction"],
|
|
397
|
+
chains: [chain],
|
|
398
|
+
tokens: [token],
|
|
399
|
+
maxAmount
|
|
400
|
+
},
|
|
401
|
+
options
|
|
402
|
+
)
|
|
403
|
+
);
|
|
404
|
+
},
|
|
405
|
+
trade(chain, capabilities = ["eth_sendTransaction"]) {
|
|
406
|
+
return withActionMetadata(
|
|
407
|
+
"trade",
|
|
408
|
+
createPolicy(
|
|
409
|
+
{
|
|
410
|
+
methods: capabilities,
|
|
411
|
+
chains: [chain]
|
|
412
|
+
},
|
|
413
|
+
options
|
|
414
|
+
)
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
export { createDepositController, createFundingWithdrawExecutor, createMarketDataProvider, createPredicateMarketPolicyAdapter, createWithdrawController, fetchErc20Balance, fetchFundingTokenBalance, findTokenDataFromChains, isUsdtWithdrawDirect, parseUnits };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { getOptionalEnv, setMerchantBaseUrl } from './chunk-SHLNBZBY.js';
|
|
2
|
+
import { getSDKConfig, initSDK } from './chunk-WHTI52FI.js';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
|
|
5
|
+
// src/auth/bundledConfig.ts
|
|
6
|
+
function getBundledAuthConfig() {
|
|
7
|
+
const relayOrigin = getOptionalEnv("RELAY_ORIGIN");
|
|
8
|
+
const cubeEnv = getOptionalEnv("CUBE_SIGNER_ENV");
|
|
9
|
+
const cubeOrgId = getOptionalEnv("CUBE_SIGNER_ORG_ID");
|
|
10
|
+
return {
|
|
11
|
+
googleClientId: getOptionalEnv("GOOGLE_CLIENT_ID"),
|
|
12
|
+
twitterClientId: getOptionalEnv("X_CLIENT_ID"),
|
|
13
|
+
twitterRedirectUri: relayOrigin ? `${relayOrigin}/auth/twitter-callback` : void 0,
|
|
14
|
+
cubeSigner: cubeEnv && cubeOrgId ? {
|
|
15
|
+
env: cubeEnv,
|
|
16
|
+
orgId: cubeOrgId
|
|
17
|
+
} : void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function resolveSignerApiRoot(env) {
|
|
21
|
+
if (!env) return "https://gamma.signer.cubist.dev";
|
|
22
|
+
if (/^https?:\/\//.test(env)) return env.replace(/\/$/, "");
|
|
23
|
+
if (env === "gamma" || env === "dev") return "https://gamma.signer.cubist.dev";
|
|
24
|
+
if (env === "prod") return "https://prod.signer.cubist.dev";
|
|
25
|
+
return "https://gamma.signer.cubist.dev";
|
|
26
|
+
}
|
|
27
|
+
async function sha256Hex(input) {
|
|
28
|
+
const g = globalThis;
|
|
29
|
+
try {
|
|
30
|
+
if (g.crypto?.subtle) {
|
|
31
|
+
const enc = new TextEncoder();
|
|
32
|
+
const buf = await g.crypto.subtle.digest("SHA-256", enc.encode(input));
|
|
33
|
+
const bytes = new Uint8Array(buf);
|
|
34
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const { createHash } = await import('crypto');
|
|
40
|
+
return createHash("sha256").update(input).digest("hex");
|
|
41
|
+
} catch {
|
|
42
|
+
throw new Error("SHA-256 not available in this runtime");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function pickStageSalt() {
|
|
46
|
+
const stage = getOptionalEnv("STAGE") ?? "dev";
|
|
47
|
+
if (stage === "prod" || stage === "pre") return "xnPWRJT5XG2WyevuydMjMpZq";
|
|
48
|
+
return "dev@tomo";
|
|
49
|
+
}
|
|
50
|
+
async function defaultRegisterUser(oidcToken) {
|
|
51
|
+
const env = getOptionalEnv("CUBE_SIGNER_ENV") ?? "gamma";
|
|
52
|
+
const orgId = getOptionalEnv("CUBE_SIGNER_ORG_ID") ?? "";
|
|
53
|
+
const registerApi = getOptionalEnv("CUBE_REG") ?? "";
|
|
54
|
+
if (!orgId) throw new Error("CUBE_SIGNER_ORG_ID is not set");
|
|
55
|
+
if (!registerApi) throw new Error("CUBE_REG is not set");
|
|
56
|
+
const root = resolveSignerApiRoot(env);
|
|
57
|
+
const proveUrl = `${root}/v0/org/${encodeURIComponent(orgId)}/identity/prove/oidc`;
|
|
58
|
+
const proveRes = await axios.post(proveUrl, void 0, {
|
|
59
|
+
headers: { Authorization: oidcToken },
|
|
60
|
+
timeout: 2e4
|
|
61
|
+
});
|
|
62
|
+
const proof = proveRes.data ?? {};
|
|
63
|
+
const identity_proof = {
|
|
64
|
+
id: proof?.user_info?.user_id,
|
|
65
|
+
aud: proof?.aud,
|
|
66
|
+
email: proof?.email,
|
|
67
|
+
username: proof?.preferred_username,
|
|
68
|
+
identity: { iss: proof?.identity?.iss, sub: proof?.identity?.sub },
|
|
69
|
+
exp_epoch: proof?.exp_epoch
|
|
70
|
+
};
|
|
71
|
+
const timestamp = Date.now().toString();
|
|
72
|
+
const sigPayload = JSON.stringify({ iss: identity_proof.identity.iss, sub: identity_proof.identity.sub, timestamp });
|
|
73
|
+
const signature = await sha256Hex(sigPayload + pickStageSalt());
|
|
74
|
+
const regRes = await axios.post(
|
|
75
|
+
registerApi,
|
|
76
|
+
{ identity_proof, timestamp, signature },
|
|
77
|
+
{ headers: { "Content-Type": "application/json" }, timeout: 2e4 }
|
|
78
|
+
);
|
|
79
|
+
const body = regRes.data ?? {};
|
|
80
|
+
if (typeof body.code !== "undefined" && body.code !== 0) {
|
|
81
|
+
throw new Error(`User register failed: ${body?.message || body?.error || body.code}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/auth/config.ts
|
|
86
|
+
function getFixedAuthConfig() {
|
|
87
|
+
const bundled = getBundledAuthConfig();
|
|
88
|
+
const envGoogle = getOptionalEnv("GOOGLE_CLIENT_ID");
|
|
89
|
+
const envTwitter = getOptionalEnv("X_CLIENT_ID");
|
|
90
|
+
const relayOrigin = getOptionalEnv("RELAY_ORIGIN");
|
|
91
|
+
const envRedirect = relayOrigin ? `${relayOrigin}/auth/twitter-callback` : void 0;
|
|
92
|
+
const cubeEnv = getOptionalEnv("CUBE_SIGNER_ENV");
|
|
93
|
+
const cubeOrgId = getOptionalEnv("CUBE_SIGNER_ORG_ID");
|
|
94
|
+
const cubeSignerFromEnv = cubeEnv && cubeOrgId ? { env: cubeEnv, orgId: cubeOrgId } : void 0;
|
|
95
|
+
return {
|
|
96
|
+
googleClientId: envGoogle || bundled.googleClientId,
|
|
97
|
+
twitterClientId: envTwitter || bundled.twitterClientId,
|
|
98
|
+
twitterRedirectUri: envRedirect || bundled.twitterRedirectUri,
|
|
99
|
+
cubeSigner: cubeSignerFromEnv ?? bundled.cubeSigner
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function scheduleAutoReconnect() {
|
|
103
|
+
if (typeof window === "undefined") return;
|
|
104
|
+
void import('./autoReconnect-IFPVI2XU.js').then(({ tryAutoReconnect }) => tryAutoReconnect()).catch(() => {
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function initSDK2(config = {}) {
|
|
108
|
+
const { merchantBaseUrl, registerUser, ...rest } = config;
|
|
109
|
+
const fixed = getFixedAuthConfig();
|
|
110
|
+
const prev = getSDKConfig();
|
|
111
|
+
const merged = {
|
|
112
|
+
...prev,
|
|
113
|
+
...fixed,
|
|
114
|
+
...rest,
|
|
115
|
+
cubeSigner: rest.cubeSigner ?? fixed.cubeSigner ?? prev.cubeSigner
|
|
116
|
+
};
|
|
117
|
+
if (registerUser != null && merged.cubeSigner) {
|
|
118
|
+
merged.cubeSigner = {
|
|
119
|
+
...merged.cubeSigner,
|
|
120
|
+
oidcLoginHooks: {
|
|
121
|
+
...merged.cubeSigner.oidcLoginHooks,
|
|
122
|
+
registerUser
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (registerUser == null && merged.cubeSigner) {
|
|
127
|
+
const hasCubeReg = Boolean(getOptionalEnv("CUBE_REG"));
|
|
128
|
+
const alreadyHas = Boolean(merged.cubeSigner.oidcLoginHooks?.registerUser);
|
|
129
|
+
if (hasCubeReg && alreadyHas == false) {
|
|
130
|
+
merged.cubeSigner = {
|
|
131
|
+
...merged.cubeSigner,
|
|
132
|
+
oidcLoginHooks: {
|
|
133
|
+
...merged.cubeSigner.oidcLoginHooks,
|
|
134
|
+
registerUser: defaultRegisterUser
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (merchantBaseUrl) {
|
|
140
|
+
setMerchantBaseUrl(merchantBaseUrl);
|
|
141
|
+
}
|
|
142
|
+
initSDK(merged);
|
|
143
|
+
scheduleAutoReconnect();
|
|
144
|
+
}
|
|
145
|
+
function getSDKConfig2() {
|
|
146
|
+
return getSDKConfig();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export { getFixedAuthConfig, getSDKConfig2 as getSDKConfig, initSDK2 as initSDK };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/utils/env.ts
|
|
2
|
+
function pick(...candidates) {
|
|
3
|
+
for (const candidate of candidates) {
|
|
4
|
+
if (candidate != null && candidate !== "") return candidate;
|
|
5
|
+
}
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
function nextPublicProcessEnvKey(logicalKey) {
|
|
9
|
+
return `NEXT_PUBLIC_${logicalKey}`;
|
|
10
|
+
}
|
|
11
|
+
function readProcessEnvStatic(key) {
|
|
12
|
+
if (typeof process === "undefined" || !process.env) return void 0;
|
|
13
|
+
switch (key) {
|
|
14
|
+
case "STAGE":
|
|
15
|
+
return pick(process.env.NEXT_PUBLIC_STAGE, process.env.STAGE);
|
|
16
|
+
case "GOOGLE_CLIENT_ID":
|
|
17
|
+
return pick(process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_ID);
|
|
18
|
+
case "X_CLIENT_ID":
|
|
19
|
+
return pick(process.env.NEXT_PUBLIC_X_CLIENT_ID, process.env.X_CLIENT_ID);
|
|
20
|
+
case "MERCHANT_BASE_URL":
|
|
21
|
+
return pick(process.env.NEXT_PUBLIC_MERCHANT_BASE_URL, process.env.MERCHANT_BASE_URL);
|
|
22
|
+
case "CUBE_SIGNER_ENV":
|
|
23
|
+
return pick(process.env.NEXT_PUBLIC_CUBE_SIGNER_ENV, process.env.CUBE_SIGNER_ENV);
|
|
24
|
+
case "CUBE_SIGNER_ORG_ID":
|
|
25
|
+
return pick(process.env.NEXT_PUBLIC_CUBE_SIGNER_ORG_ID, process.env.CUBE_SIGNER_ORG_ID);
|
|
26
|
+
case "CUBE_REG":
|
|
27
|
+
return pick(process.env.NEXT_PUBLIC_CUBE_REG, process.env.CUBE_REG);
|
|
28
|
+
case "RELAY_ORIGIN":
|
|
29
|
+
return pick(process.env.NEXT_PUBLIC_RELAY_ORIGIN, process.env.RELAY_ORIGIN);
|
|
30
|
+
case "FUNDING_TOKEN_SYMBOL":
|
|
31
|
+
return pick(process.env.NEXT_PUBLIC_FUNDING_TOKEN_SYMBOL, process.env.FUNDING_TOKEN_SYMBOL) || "USDT";
|
|
32
|
+
default:
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function readEnv(key) {
|
|
37
|
+
const staticVal = readProcessEnvStatic(key);
|
|
38
|
+
if (staticVal != null && staticVal !== "") return staticVal;
|
|
39
|
+
const globalEnv = globalThis.process?.env;
|
|
40
|
+
if (globalEnv) {
|
|
41
|
+
const pub = nextPublicProcessEnvKey(key);
|
|
42
|
+
const val = globalEnv[key] ?? globalEnv[pub];
|
|
43
|
+
if (val != null && val !== "") return val;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const metaEnv = import.meta.env;
|
|
47
|
+
if (metaEnv) {
|
|
48
|
+
const pub = nextPublicProcessEnvKey(key);
|
|
49
|
+
const val = metaEnv[key] ?? metaEnv[pub];
|
|
50
|
+
if (val != null && val !== "") return val;
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
function getOptionalEnv(key) {
|
|
57
|
+
return readEnv(key);
|
|
58
|
+
}
|
|
59
|
+
function getEnv(key) {
|
|
60
|
+
return readEnv(key) ?? "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/modules/apiConfig.ts
|
|
64
|
+
var configuredMerchantBaseUrl;
|
|
65
|
+
function setMerchantBaseUrl(baseUrl) {
|
|
66
|
+
configuredMerchantBaseUrl = baseUrl && baseUrl.trim() !== "" ? baseUrl : void 0;
|
|
67
|
+
}
|
|
68
|
+
function getMerchantBaseUrl() {
|
|
69
|
+
return configuredMerchantBaseUrl ?? getOptionalEnv("MERCHANT_BASE_URL");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { getEnv, getMerchantBaseUrl, getOptionalEnv, setMerchantBaseUrl };
|