@pear-protocol/symmio-client 0.3.24 → 0.3.27-alpha.1

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.
@@ -615,6 +615,7 @@ var symmKeys = {
615
615
  tpslOrdersRoot: ["symm", "tpslOrders"],
616
616
  twapOrdersRoot: ["symm", "twapOrders"],
617
617
  triggerOrdersRoot: ["symm", "triggerOrders"],
618
+ bridgesRoot: ["symm", "bridges"],
618
619
  accounts: (address, chainId) => ["symm", "accounts", address, chainId],
619
620
  accountsApi: (address, chainId) => ["symm", "accountsApi", address, chainId],
620
621
  accountsLength: (address, chainId) => ["symm", "accountsLength", address, chainId],
@@ -651,7 +652,12 @@ var symmKeys = {
651
652
  pendingInstantOpens: (accountAddress, chainId) => ["symm", "pendingInstantOpens", accountAddress, chainId],
652
653
  twapOrder: (orderId) => ["symm", "twapOrder", orderId],
653
654
  delegation: (account, target, selectors, chainId) => ["symm", "delegation", account, target, selectors, chainId],
654
- chartMetadata: (symbolsKey, positionKey) => ["symm", "chartMetadata", symbolsKey, positionKey]
655
+ chartMetadata: (symbolsKey, positionKey) => ["symm", "chartMetadata", symbolsKey, positionKey],
656
+ instantWithdrawalAuth: (signerAddress, chainId) => ["symm", "instantWithdrawalAuth", signerAddress, chainId],
657
+ withdrawalConfig: (chainId) => ["symm", "withdrawalConfig", chainId],
658
+ maxInstantValue: (account, chainId) => ["symm", "maxInstantValue", account, chainId],
659
+ pendingFeePolicy: (account, chainId) => ["symm", "pendingFeePolicy", account, chainId],
660
+ bridges: (params) => ["symm", "bridges", params]
655
661
  };
656
662
  var useSymmWsStore = zustand.create((set) => ({
657
663
  isConnected: false,
@@ -846,6 +852,9 @@ var HEDGER_BASE_URLS = {
846
852
  [42161 /* ARBITRUM */]: "https://www.perps-streaming.com/v1/42161a/0x6273242a7E88b3De90822b31648C212215caaFE4/",
847
853
  [8453 /* BASE */]: "https://www.perps-streaming.com/v1/8453a/0xE43166cE17d3511B09438a359dAa53513225101D/"
848
854
  };
855
+ var INSTANT_WITHDRAWAL_BASE_URLS = {
856
+ [8453 /* BASE */]: "https://instant-withdrawal-base.symmio.foundation/v1/"
857
+ };
849
858
 
850
859
  // src/actions/instant.ts
851
860
  function getHedgerBaseUrl(chainId) {
@@ -1288,6 +1297,9 @@ var SIGNATURE_STORE_ADDRESS = {
1288
1297
  [42161 /* ARBITRUM */]: "0x94eEa58De1C8945c342dB4bE9670301638E403e2",
1289
1298
  [8453 /* BASE */]: "0xC19e66D08350Eb88A41377b16C8Ab93EE0FB4996"
1290
1299
  };
1300
+ var INSTANT_WITHDRAWAL_ADDRESS = {
1301
+ [8453 /* BASE */]: "0xE0650873D8DadB54a6AC7c666BC98ab45f827b6D"
1302
+ };
1291
1303
  var DEFAULT_PARTY_B_ADDRESS = {
1292
1304
  [42161 /* ARBITRUM */]: "0x00c069d68bc7420740460DBC3cc3fFF9b3742421",
1293
1305
  [8453 /* BASE */]: "0x1EcAbF0Eba136920677C9575FAccee36f30592cf"
@@ -2032,6 +2044,10 @@ function invalidatePositions(qc) {
2032
2044
  qc.invalidateQueries({ queryKey: symmKeys.tradeHistoryRoot });
2033
2045
  qc.invalidateQueries({ queryKey: symmKeys.portfolioRoot });
2034
2046
  }
2047
+ function invalidateBridges(qc) {
2048
+ qc.invalidateQueries({ queryKey: symmKeys.bridgesRoot });
2049
+ qc.invalidateQueries({ queryKey: symmKeys.balancesRoot });
2050
+ }
2035
2051
  function invalidateOrders(qc) {
2036
2052
  qc.invalidateQueries({ queryKey: symmKeys.openOrdersRoot });
2037
2053
  qc.invalidateQueries({ queryKey: symmKeys.tpslOrdersRoot });
@@ -2673,53 +2689,6 @@ function useSymmDepositAndAllocateMutation(params = {}, options) {
2673
2689
  }
2674
2690
  });
2675
2691
  }
2676
- function prepareWithdraw(multiAccount, account, params) {
2677
- validateAmount(params.amount, "withdraw amount");
2678
- validateAddress(params.account, "account");
2679
- const data = viem.encodeFunctionData({
2680
- abi: MultiAccountABI,
2681
- functionName: "withdrawFromAccount",
2682
- args: [params.account, params.amount]
2683
- });
2684
- return {
2685
- functionName: "withdrawFromAccount",
2686
- args: [params.account, params.amount],
2687
- config: { account, to: multiAccount, data, value: 0n }
2688
- };
2689
- }
2690
- async function withdraw(walletClient, publicClient, multiAccount, params) {
2691
- const account = walletClient.account?.address;
2692
- if (!account) throw new Error("Wallet client has no account");
2693
- const prepared = prepareWithdraw(multiAccount, account, params);
2694
- const gas = await publicClient.estimateGas(prepared.config);
2695
- return walletClient.sendTransaction({
2696
- ...prepared.config,
2697
- gas: calculateGasMargin(gas),
2698
- chain: walletClient.chain
2699
- });
2700
- }
2701
-
2702
- // src/react/hooks/use-symm-withdraw.ts
2703
- function useSymmWithdraw(params = {}, options) {
2704
- const { chainId, symmioConfig } = useSymmContext();
2705
- const { publicClient, walletClient } = params;
2706
- const queryClient = reactQuery.useQueryClient();
2707
- const multiAccount = symmioConfig?.multiAccountAddress ?? getAddress(MULTI_ACCOUNT_ADDRESS, chainId, "MultiAccount");
2708
- return reactQuery.useMutation({
2709
- ...withSymmMutationConfig(options?.mutation, {
2710
- onSuccess: () => {
2711
- invalidateBalances(queryClient);
2712
- }
2713
- }),
2714
- mutationFn: async ({
2715
- account,
2716
- amount
2717
- }) => {
2718
- if (!walletClient || !publicClient) throw new Error("Clients not available");
2719
- return withdraw(walletClient, publicClient, multiAccount, { account, amount });
2720
- }
2721
- });
2722
- }
2723
2692
 
2724
2693
  // src/abis/SymmioDiamond.ts
2725
2694
  var SymmioDiamondABI = [
@@ -25105,6 +25074,17 @@ var SymmioDiamondABI = [
25105
25074
  type: "function"
25106
25075
  }
25107
25076
  ];
25077
+
25078
+ // src/abis/InstantWithdrawal.ts
25079
+ var InstantWithdrawalABI = [
25080
+ {
25081
+ inputs: [{ internalType: "uint256", name: "bridgeId", type: "uint256" }],
25082
+ name: "processWithdrawal",
25083
+ outputs: [],
25084
+ stateMutability: "nonpayable",
25085
+ type: "function"
25086
+ }
25087
+ ];
25108
25088
  function wrapInProxyCall(accountDiamondAbi, subAccount, callDatas) {
25109
25089
  const data = viem.encodeFunctionData({
25110
25090
  abi: accountDiamondAbi,
@@ -25118,7 +25098,795 @@ function wrapInProxyCall(accountDiamondAbi, subAccount, callDatas) {
25118
25098
  };
25119
25099
  }
25120
25100
 
25121
- // src/actions/allocate.ts
25101
+ // src/actions/withdraw.ts
25102
+ function prepareWithdraw(multiAccount, account, params) {
25103
+ validateAmount(params.amount, "withdraw amount");
25104
+ validateAddress(params.account, "account");
25105
+ const data = viem.encodeFunctionData({
25106
+ abi: MultiAccountABI,
25107
+ functionName: "withdrawFromAccount",
25108
+ args: [params.account, params.amount]
25109
+ });
25110
+ return {
25111
+ functionName: "withdrawFromAccount",
25112
+ args: [params.account, params.amount],
25113
+ config: { account, to: multiAccount, data, value: 0n }
25114
+ };
25115
+ }
25116
+ async function withdraw(walletClient, publicClient, multiAccount, params) {
25117
+ const account = walletClient.account?.address;
25118
+ if (!account) throw new Error("Wallet client has no account");
25119
+ const prepared = prepareWithdraw(multiAccount, account, params);
25120
+ const gas = await publicClient.estimateGas(prepared.config);
25121
+ return walletClient.sendTransaction({
25122
+ ...prepared.config,
25123
+ gas: calculateGasMargin(gas),
25124
+ chain: walletClient.chain
25125
+ });
25126
+ }
25127
+ function encodeDeallocate(amount, upnlSig) {
25128
+ validateAmount(amount, "deallocate amount");
25129
+ const muonSig = {
25130
+ reqId: upnlSig.reqId,
25131
+ timestamp: upnlSig.timestamp,
25132
+ upnl: upnlSig.upnl,
25133
+ gatewaySignature: upnlSig.gatewaySignature,
25134
+ sigs: {
25135
+ signature: upnlSig.sigs.signature,
25136
+ owner: upnlSig.sigs.owner,
25137
+ nonce: upnlSig.sigs.nonce
25138
+ }
25139
+ };
25140
+ return viem.encodeFunctionData({
25141
+ abi: SymmioDiamondABI,
25142
+ functionName: "deallocate",
25143
+ args: [amount, muonSig]
25144
+ });
25145
+ }
25146
+ function encodeTransferToBridge(amount, bridgeAddress) {
25147
+ validateAmount(amount, "bridge amount");
25148
+ validateAddress(bridgeAddress, "bridgeAddress");
25149
+ return viem.encodeFunctionData({
25150
+ abi: SymmioDiamondABI,
25151
+ functionName: "transferToBridge",
25152
+ args: [amount, bridgeAddress]
25153
+ });
25154
+ }
25155
+ function prepareTransferToBridge(symmioDiamond, account, params) {
25156
+ const data = encodeTransferToBridge(params.amount, params.bridgeAddress);
25157
+ return {
25158
+ functionName: "transferToBridge",
25159
+ args: [params.amount, params.bridgeAddress],
25160
+ config: { account, to: symmioDiamond, data, value: 0n }
25161
+ };
25162
+ }
25163
+ function prepareBridgeWithdraw(multiAccount, account, subAccount, params) {
25164
+ const callDatas = [];
25165
+ if (params.deallocate) {
25166
+ callDatas.push(
25167
+ encodeDeallocate(params.deallocate.amount, params.deallocate.upnlSig)
25168
+ );
25169
+ }
25170
+ callDatas.push(encodeTransferToBridge(params.amount, params.bridgeAddress));
25171
+ const proxy = wrapInProxyCall(MultiAccountABI, subAccount, callDatas);
25172
+ return {
25173
+ functionName: "_call",
25174
+ args: proxy.args,
25175
+ config: { account, to: multiAccount, data: proxy.data, value: 0n }
25176
+ };
25177
+ }
25178
+ async function transferToBridge(walletClient, publicClient, symmioDiamond, params) {
25179
+ const account = walletClient.account?.address;
25180
+ if (!account) throw new Error("Wallet client has no account");
25181
+ const prepared = prepareTransferToBridge(symmioDiamond, account, params);
25182
+ const gas = await publicClient.estimateGas(prepared.config);
25183
+ return walletClient.sendTransaction({
25184
+ ...prepared.config,
25185
+ gas: calculateGasMargin(gas),
25186
+ chain: walletClient.chain
25187
+ });
25188
+ }
25189
+ async function bridgeWithdraw(walletClient, publicClient, multiAccount, subAccount, params) {
25190
+ const account = walletClient.account?.address;
25191
+ if (!account) throw new Error("Wallet client has no account");
25192
+ const prepared = prepareBridgeWithdraw(multiAccount, account, subAccount, params);
25193
+ const gas = await publicClient.estimateGas(prepared.config);
25194
+ return walletClient.sendTransaction({
25195
+ ...prepared.config,
25196
+ gas: calculateGasMargin(gas),
25197
+ chain: walletClient.chain
25198
+ });
25199
+ }
25200
+ function prepareProcessWithdrawal(instantWithdrawal, account, params) {
25201
+ const data = viem.encodeFunctionData({
25202
+ abi: InstantWithdrawalABI,
25203
+ functionName: "processWithdrawal",
25204
+ args: [params.bridgeId]
25205
+ });
25206
+ return {
25207
+ functionName: "processWithdrawal",
25208
+ args: [params.bridgeId],
25209
+ config: { account, to: instantWithdrawal, data, value: 0n }
25210
+ };
25211
+ }
25212
+ async function processWithdrawal(walletClient, publicClient, instantWithdrawal, params) {
25213
+ const account = walletClient.account?.address;
25214
+ if (!account) throw new Error("Wallet client has no account");
25215
+ const prepared = prepareProcessWithdrawal(instantWithdrawal, account, params);
25216
+ const gas = await publicClient.estimateGas(prepared.config);
25217
+ return walletClient.sendTransaction({
25218
+ ...prepared.config,
25219
+ gas: calculateGasMargin(gas),
25220
+ chain: walletClient.chain
25221
+ });
25222
+ }
25223
+
25224
+ // src/react/hooks/use-symm-withdraw.ts
25225
+ function useSymmWithdraw(params = {}, options) {
25226
+ const { chainId, symmioConfig } = useSymmContext();
25227
+ const { publicClient, walletClient } = params;
25228
+ const queryClient = reactQuery.useQueryClient();
25229
+ const multiAccount = symmioConfig?.multiAccountAddress ?? getAddress(MULTI_ACCOUNT_ADDRESS, chainId, "MultiAccount");
25230
+ return reactQuery.useMutation({
25231
+ ...withSymmMutationConfig(options?.mutation, {
25232
+ onSuccess: () => {
25233
+ invalidateBalances(queryClient);
25234
+ }
25235
+ }),
25236
+ mutationFn: async ({
25237
+ account,
25238
+ amount
25239
+ }) => {
25240
+ if (!walletClient || !publicClient) throw new Error("Clients not available");
25241
+ return withdraw(walletClient, publicClient, multiAccount, { account, amount });
25242
+ }
25243
+ });
25244
+ }
25245
+
25246
+ // src/types/instant-withdrawal.ts
25247
+ var InstantWithdrawalError = class extends Error {
25248
+ code;
25249
+ status;
25250
+ detail;
25251
+ constructor(message, options) {
25252
+ super(message);
25253
+ this.name = "InstantWithdrawalError";
25254
+ this.code = options?.code;
25255
+ this.status = options?.status;
25256
+ this.detail = options?.detail;
25257
+ }
25258
+ };
25259
+
25260
+ // src/actions/instant-withdrawal.ts
25261
+ function getInstantWithdrawalBaseUrl(chainId) {
25262
+ const baseUrl = INSTANT_WITHDRAWAL_BASE_URLS[chainId];
25263
+ if (!baseUrl) {
25264
+ throw new Error(
25265
+ `Instant withdrawal is not available on chain ${chainId}.`
25266
+ );
25267
+ }
25268
+ return baseUrl;
25269
+ }
25270
+ function buildUrl(chainId, path, query) {
25271
+ const url = new URL(path, getInstantWithdrawalBaseUrl(chainId));
25272
+ if (query) {
25273
+ for (const [key, value] of Object.entries(query)) {
25274
+ if (value !== void 0) url.searchParams.set(key, String(value));
25275
+ }
25276
+ }
25277
+ return url.href;
25278
+ }
25279
+ async function iwFetch(url, options) {
25280
+ const headers = {};
25281
+ if (options?.body !== void 0) {
25282
+ headers["Content-Type"] = "application/json";
25283
+ }
25284
+ if (options?.token) {
25285
+ headers.Authorization = `Bearer ${options.token}`;
25286
+ }
25287
+ const response = await fetch(url, {
25288
+ method: options?.method ?? "GET",
25289
+ headers,
25290
+ body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
25291
+ });
25292
+ if (!response.ok) {
25293
+ const raw = await response.text().catch(() => "");
25294
+ let code;
25295
+ let message = "";
25296
+ let detail;
25297
+ if (raw) {
25298
+ try {
25299
+ const parsed = JSON.parse(raw);
25300
+ code = parsed.error_code;
25301
+ message = parsed.error_message ?? parsed.message ?? (typeof parsed.detail === "string" ? parsed.detail : "") ?? "";
25302
+ detail = parsed.error_detail ?? parsed.detail;
25303
+ } catch {
25304
+ message = raw;
25305
+ }
25306
+ }
25307
+ throw new InstantWithdrawalError(
25308
+ message || response.statusText || "Instant withdrawal request failed",
25309
+ { code, status: response.status, detail }
25310
+ );
25311
+ }
25312
+ if (response.status === 204) return void 0;
25313
+ return response.json();
25314
+ }
25315
+ async function getNonce2(chainId, address) {
25316
+ const data = await iwFetch(
25317
+ buildUrl(chainId, "auth/nonce"),
25318
+ { method: "POST", body: { address } }
25319
+ );
25320
+ return data.nonce;
25321
+ }
25322
+ async function getSignInMessage(chainId, params) {
25323
+ return iwFetch(
25324
+ buildUrl(chainId, "auth/sign-in-message", {
25325
+ address: params.address,
25326
+ domain: params.domain,
25327
+ uri: params.uri,
25328
+ statement: params.statement,
25329
+ version: params.version
25330
+ })
25331
+ );
25332
+ }
25333
+ async function login2(chainId, message, signature) {
25334
+ return iwFetch(buildUrl(chainId, "auth/login"), {
25335
+ method: "POST",
25336
+ body: { message, signature }
25337
+ });
25338
+ }
25339
+ async function getFeeOptions(chainId, account, amount, token) {
25340
+ return iwFetch(
25341
+ buildUrl(chainId, "fee-options", {
25342
+ account,
25343
+ amount: amount.toString()
25344
+ }),
25345
+ { method: "POST", token }
25346
+ );
25347
+ }
25348
+ async function unlockAccount(chainId, account, token) {
25349
+ return iwFetch(
25350
+ buildUrl(chainId, `unlock/${account}`),
25351
+ { method: "POST", token }
25352
+ );
25353
+ }
25354
+ async function getPendingFeePolicy(chainId, account, token) {
25355
+ return iwFetch(
25356
+ buildUrl(chainId, `pending-fee-policy/${account}`),
25357
+ { token }
25358
+ );
25359
+ }
25360
+ async function getMaxInstantValue(chainId, account, token) {
25361
+ const data = await iwFetch(
25362
+ buildUrl(chainId, `max-instant-value/${account}`),
25363
+ { token }
25364
+ );
25365
+ return BigInt(data.amount);
25366
+ }
25367
+ async function getWithdrawalConfig(chainId) {
25368
+ const data = await iwFetch(
25369
+ buildUrl(chainId, "withdrawal-config")
25370
+ );
25371
+ return {
25372
+ operatorFee: data.operator_fee,
25373
+ maxInstantAmount: data.max_instant_amount,
25374
+ instantFeeRate: data.instant_fee_rate,
25375
+ policyValidTime: data.policy_valid_time,
25376
+ minWithdrawalCooldown: data.min_withdrawal_cooldown
25377
+ };
25378
+ }
25379
+ async function getSelectReceiverMessage(chainId, receiver, bridgeId) {
25380
+ return iwFetch(
25381
+ buildUrl(chainId, "get-select-receiver-message", {
25382
+ receiver,
25383
+ bridgeId
25384
+ })
25385
+ );
25386
+ }
25387
+ async function selectFeePolicy(chainId, body, token) {
25388
+ return iwFetch(
25389
+ buildUrl(chainId, "select-fee-policy"),
25390
+ { method: "POST", token, body }
25391
+ );
25392
+ }
25393
+ async function getBridges(chainId, account, start, size, filters, token) {
25394
+ return iwFetch(
25395
+ buildUrl(chainId, `bridges/${account}/${start}/${size}`),
25396
+ { method: "POST", token, body: filters }
25397
+ );
25398
+ }
25399
+
25400
+ // src/react/instant-withdrawal-auth.ts
25401
+ var TOKEN_STORAGE_PREFIX2 = "symm_iw_token";
25402
+ var TOKEN_STORAGE_VERSION2 = 1;
25403
+ var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
25404
+ var EXPIRY_SKEW_MS = 6e4;
25405
+ function storageKey2(address, chainId) {
25406
+ return `${TOKEN_STORAGE_PREFIX2}:${TOKEN_STORAGE_VERSION2}:${address.toLowerCase()}:${chainId}`;
25407
+ }
25408
+ function readJwtExpiryMs(token) {
25409
+ try {
25410
+ const payload = token.split(".")[1];
25411
+ if (!payload) return null;
25412
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
25413
+ const json = typeof atob === "function" ? atob(normalized) : Buffer.from(normalized, "base64").toString("binary");
25414
+ const parsed = JSON.parse(json);
25415
+ return typeof parsed.exp === "number" ? parsed.exp * 1e3 : null;
25416
+ } catch {
25417
+ return null;
25418
+ }
25419
+ }
25420
+ function getCachedTokenEntry2(address, chainId) {
25421
+ if (typeof window === "undefined") return null;
25422
+ const key = storageKey2(address, chainId);
25423
+ try {
25424
+ const raw = window.localStorage.getItem(key);
25425
+ if (!raw) return null;
25426
+ const parsed = JSON.parse(raw);
25427
+ if (!parsed || typeof parsed.token !== "string" || typeof parsed.expiresAt !== "number" || Date.now() >= parsed.expiresAt) {
25428
+ window.localStorage.removeItem(key);
25429
+ return null;
25430
+ }
25431
+ return parsed;
25432
+ } catch {
25433
+ window.localStorage.removeItem(key);
25434
+ return null;
25435
+ }
25436
+ }
25437
+ function getCachedToken(address, chainId) {
25438
+ return getCachedTokenEntry2(address, chainId)?.token ?? null;
25439
+ }
25440
+ function writeStoredToken2(address, chainId, cached) {
25441
+ if (typeof window === "undefined") return;
25442
+ try {
25443
+ window.localStorage.setItem(
25444
+ storageKey2(address, chainId),
25445
+ JSON.stringify(cached)
25446
+ );
25447
+ } catch {
25448
+ }
25449
+ }
25450
+ function clearCachedToken2(address, chainId) {
25451
+ if (typeof window === "undefined") return;
25452
+ try {
25453
+ window.localStorage.removeItem(storageKey2(address, chainId));
25454
+ } catch {
25455
+ }
25456
+ }
25457
+ async function fetchInstantWithdrawalTokenEntry(walletClient, signerAddress, chainId, domain) {
25458
+ const resolvedDomain = domain ?? (typeof window !== "undefined" ? window.location.hostname : "localhost");
25459
+ const uri = typeof window !== "undefined" ? window.location.origin : `https://${resolvedDomain}`;
25460
+ await getNonce2(chainId, signerAddress);
25461
+ const { message, params } = await getSignInMessage(chainId, {
25462
+ address: signerAddress,
25463
+ domain: resolvedDomain,
25464
+ uri
25465
+ });
25466
+ const signature = await walletClient.signMessage({
25467
+ account: signerAddress,
25468
+ message
25469
+ });
25470
+ const { accessToken } = await login2(chainId, params, signature);
25471
+ const expiresAt = (readJwtExpiryMs(accessToken) ?? Date.now() + DEFAULT_TTL_MS) - EXPIRY_SKEW_MS;
25472
+ const cached = { token: accessToken, expiresAt };
25473
+ writeStoredToken2(signerAddress, chainId, cached);
25474
+ return cached;
25475
+ }
25476
+ async function fetchInstantWithdrawalToken(walletClient, signerAddress, chainId, domain) {
25477
+ const entry = await fetchInstantWithdrawalTokenEntry(
25478
+ walletClient,
25479
+ signerAddress,
25480
+ chainId,
25481
+ domain
25482
+ );
25483
+ return entry.token;
25484
+ }
25485
+ async function resolveInstantWithdrawalToken(walletClient, signerAddress, chainId, options) {
25486
+ if (!options?.force) {
25487
+ const cached = getCachedToken(signerAddress, chainId);
25488
+ if (cached) return cached;
25489
+ }
25490
+ return fetchInstantWithdrawalToken(
25491
+ walletClient,
25492
+ signerAddress,
25493
+ chainId,
25494
+ options?.domain
25495
+ );
25496
+ }
25497
+
25498
+ // src/react/hooks/use-symm-instant-withdrawal-auth.ts
25499
+ function useSymmInstantWithdrawalAuth(params) {
25500
+ const context = useSymmContext();
25501
+ const address = params?.address ?? context.address;
25502
+ const chainId = params?.chainId ?? context.chainId;
25503
+ const walletClient = params?.walletClient ?? context.walletClient;
25504
+ const siweDomain = params?.siweDomain;
25505
+ const [accessToken, setAccessToken] = react.useState(null);
25506
+ const [isLoading, setIsLoading] = react.useState(false);
25507
+ const [error, setError] = react.useState(null);
25508
+ react.useEffect(() => {
25509
+ if (!address) {
25510
+ setAccessToken(null);
25511
+ return;
25512
+ }
25513
+ setAccessToken(getCachedToken(address, chainId));
25514
+ }, [address, chainId]);
25515
+ const signIn = react.useCallback(
25516
+ async (options) => {
25517
+ if (!walletClient || !address) return null;
25518
+ try {
25519
+ setError(null);
25520
+ setIsLoading(true);
25521
+ const token = await resolveInstantWithdrawalToken(
25522
+ walletClient,
25523
+ address,
25524
+ chainId,
25525
+ { domain: siweDomain, force: options?.force }
25526
+ );
25527
+ setAccessToken(token);
25528
+ return token;
25529
+ } catch (err) {
25530
+ const normalized = err instanceof Error ? err : new Error("failed to sign in");
25531
+ setError(normalized);
25532
+ return null;
25533
+ } finally {
25534
+ setIsLoading(false);
25535
+ }
25536
+ },
25537
+ [walletClient, address, chainId, siweDomain]
25538
+ );
25539
+ const clear = react.useCallback(() => {
25540
+ if (address) clearCachedToken2(address, chainId);
25541
+ setAccessToken(null);
25542
+ }, [address, chainId]);
25543
+ return {
25544
+ accessToken,
25545
+ isAuthenticated: !!accessToken,
25546
+ isLoading,
25547
+ error,
25548
+ signIn,
25549
+ clear
25550
+ };
25551
+ }
25552
+ function useSymmWithdrawalConfig(params) {
25553
+ const { chainId: ctxChainId } = useSymmContext();
25554
+ const chainId = params?.chainId ?? ctxChainId;
25555
+ return reactQuery.useQuery({
25556
+ staleTime: 6e4,
25557
+ ...params?.query,
25558
+ queryKey: symmKeys.withdrawalConfig(chainId),
25559
+ queryFn: () => getWithdrawalConfig(chainId),
25560
+ enabled: params?.query?.enabled ?? true
25561
+ });
25562
+ }
25563
+ function useSymmMaxInstantValue(params) {
25564
+ const { chainId: ctxChainId } = useSymmContext();
25565
+ const chainId = params.chainId ?? ctxChainId;
25566
+ const { account, accessToken } = params;
25567
+ const internalEnabled = !!account && !!accessToken;
25568
+ return reactQuery.useQuery({
25569
+ staleTime: 15e3,
25570
+ ...params.query,
25571
+ queryKey: symmKeys.maxInstantValue(account, chainId),
25572
+ queryFn: () => getMaxInstantValue(chainId, account, accessToken),
25573
+ enabled: internalEnabled && (params.query?.enabled ?? true)
25574
+ });
25575
+ }
25576
+ function useSymmFeeOptionsMutation(params, options) {
25577
+ const { chainId: ctxChainId } = useSymmContext();
25578
+ const chainId = params?.chainId ?? ctxChainId;
25579
+ return reactQuery.useMutation({
25580
+ ...withSymmMutationConfig(options?.mutation),
25581
+ mutationFn: ({ account, amount, accessToken }) => getFeeOptions(chainId, account, amount, accessToken)
25582
+ });
25583
+ }
25584
+ function useSymmPendingFeePolicy(params) {
25585
+ const { chainId: ctxChainId } = useSymmContext();
25586
+ const chainId = params.chainId ?? ctxChainId;
25587
+ const { account, accessToken } = params;
25588
+ const internalEnabled = !!account && !!accessToken;
25589
+ return reactQuery.useQuery({
25590
+ ...params.query,
25591
+ queryKey: symmKeys.pendingFeePolicy(account, chainId),
25592
+ queryFn: () => getPendingFeePolicy(chainId, account, accessToken),
25593
+ enabled: internalEnabled && (params.query?.enabled ?? true)
25594
+ });
25595
+ }
25596
+ function useSymmUnlockAccountMutation(params, options) {
25597
+ const { chainId: ctxChainId } = useSymmContext();
25598
+ const chainId = params?.chainId ?? ctxChainId;
25599
+ return reactQuery.useMutation({
25600
+ ...withSymmMutationConfig(options?.mutation),
25601
+ mutationFn: ({ account, accessToken }) => unlockAccount(chainId, account, accessToken)
25602
+ });
25603
+ }
25604
+ function useSymmRefreshFeeOptionsMutation(params, options) {
25605
+ const { chainId: ctxChainId } = useSymmContext();
25606
+ const chainId = params?.chainId ?? ctxChainId;
25607
+ return reactQuery.useMutation({
25608
+ ...withSymmMutationConfig(options?.mutation),
25609
+ mutationFn: async ({ account, amount, accessToken }) => {
25610
+ await unlockAccount(chainId, account, accessToken);
25611
+ return getFeeOptions(chainId, account, amount, accessToken);
25612
+ }
25613
+ });
25614
+ }
25615
+ function useSymmBridges(params) {
25616
+ const { chainId: ctxChainId } = useSymmContext();
25617
+ const chainId = params.chainId ?? ctxChainId;
25618
+ const {
25619
+ account,
25620
+ accessToken,
25621
+ start = null,
25622
+ size = null,
25623
+ bridgeState = null,
25624
+ bridgeType = null
25625
+ } = params;
25626
+ const internalEnabled = !!account && !!accessToken;
25627
+ return reactQuery.useQuery({
25628
+ ...params.query,
25629
+ queryKey: symmKeys.bridges({
25630
+ account,
25631
+ chainId,
25632
+ start,
25633
+ size,
25634
+ bridgeState,
25635
+ bridgeType
25636
+ }),
25637
+ queryFn: () => getBridges(
25638
+ chainId,
25639
+ account,
25640
+ start,
25641
+ size,
25642
+ { bridge_state: bridgeState, bridge_type: bridgeType },
25643
+ accessToken
25644
+ ),
25645
+ enabled: internalEnabled && (params.query?.enabled ?? true)
25646
+ });
25647
+ }
25648
+ async function buildSpecifiedReceiver(chainId, receiver, bridgeId, walletClient, signerAddress) {
25649
+ const { payload } = await getSelectReceiverMessage(chainId, receiver, bridgeId);
25650
+ const { EIP712Domain: _ignored, ...types } = payload.types;
25651
+ const signature = await walletClient.signTypedData({
25652
+ account: signerAddress,
25653
+ domain: payload.domain,
25654
+ types,
25655
+ primaryType: payload.primaryType,
25656
+ message: payload.message
25657
+ });
25658
+ return { address: receiver, signature };
25659
+ }
25660
+ function useSymmSelectFeePolicyMutation(params, options) {
25661
+ const { chainId: ctxChainId, address, walletClient: ctxWallet } = useSymmContext();
25662
+ const chainId = params?.chainId ?? ctxChainId;
25663
+ const walletClient = params?.walletClient ?? ctxWallet;
25664
+ const queryClient = reactQuery.useQueryClient();
25665
+ return reactQuery.useMutation({
25666
+ ...withSymmMutationConfig(options?.mutation, {
25667
+ onSuccess: () => invalidateBridges(queryClient)
25668
+ }),
25669
+ mutationFn: async (variables) => {
25670
+ let receiver = variables.receiver ?? null;
25671
+ if (!receiver && variables.newReceiver) {
25672
+ if (!walletClient || !address) {
25673
+ throw new Error("wallet client is required to sign a new receiver");
25674
+ }
25675
+ receiver = await buildSpecifiedReceiver(
25676
+ chainId,
25677
+ variables.newReceiver,
25678
+ variables.symmioBridgeId,
25679
+ walletClient,
25680
+ address
25681
+ );
25682
+ }
25683
+ return selectFeePolicy(
25684
+ chainId,
25685
+ {
25686
+ symmioBridgeId: variables.symmioBridgeId,
25687
+ cooldown: variables.cooldown,
25688
+ feeAmount: variables.feeAmount,
25689
+ receiver
25690
+ },
25691
+ variables.accessToken
25692
+ );
25693
+ }
25694
+ });
25695
+ }
25696
+ function pickOption(options, speed) {
25697
+ if (options.length === 0) {
25698
+ throw new InstantWithdrawalError("no fee options available", {
25699
+ code: 8 /* INVALID_BRIDGE_POLICY_OPTION */
25700
+ });
25701
+ }
25702
+ const sorted = [...options].sort((a, b) => a.cooldown - b.cooldown);
25703
+ return speed === "instant" ? sorted[0] : sorted[sorted.length - 1];
25704
+ }
25705
+ function useSymmInstantWithdraw(params, options) {
25706
+ const {
25707
+ chainId: ctxChainId,
25708
+ address,
25709
+ walletClient: ctxWallet,
25710
+ symmioConfig
25711
+ } = useSymmContext();
25712
+ const chainId = params.chainId ?? ctxChainId;
25713
+ const walletClient = params.walletClient ?? ctxWallet;
25714
+ const publicClient = params.publicClient;
25715
+ const queryClient = reactQuery.useQueryClient();
25716
+ const [status, setStatus] = react.useState("idle");
25717
+ const [bridgeTxHash, setBridgeTxHash] = react.useState();
25718
+ const reset = react.useCallback(() => {
25719
+ setStatus("idle");
25720
+ setBridgeTxHash(void 0);
25721
+ }, []);
25722
+ const mutation = reactQuery.useMutation({
25723
+ ...withSymmMutationConfig(options?.mutation, {
25724
+ onSuccess: () => invalidateBridges(queryClient)
25725
+ }),
25726
+ mutationFn: async (variables) => {
25727
+ if (!walletClient || !address) {
25728
+ throw new Error("wallet client and address are required");
25729
+ }
25730
+ if (!publicClient) throw new Error("public client is required");
25731
+ const speed = variables.speed ?? "instant";
25732
+ const apiAccount = variables.subAccount ?? address;
25733
+ const bridgeAddress = getAddress(
25734
+ INSTANT_WITHDRAWAL_ADDRESS,
25735
+ chainId,
25736
+ "InstantWithdrawal"
25737
+ );
25738
+ try {
25739
+ setStatus("authenticating");
25740
+ const accessToken = await resolveInstantWithdrawalToken(
25741
+ walletClient,
25742
+ address,
25743
+ chainId,
25744
+ { domain: params.siweDomain, force: variables.forceReauth }
25745
+ );
25746
+ if (speed === "instant") {
25747
+ const maxInstant = await getMaxInstantValue(
25748
+ chainId,
25749
+ apiAccount,
25750
+ accessToken
25751
+ );
25752
+ if (maxInstant <= 0n) {
25753
+ throw new InstantWithdrawalError(
25754
+ "instant withdrawal is not available for this account right now",
25755
+ { code: 7 /* INVALID_BRIDGE_TRANSACTION */ }
25756
+ );
25757
+ }
25758
+ if (variables.amount > maxInstant) {
25759
+ throw new InstantWithdrawalError(
25760
+ `amount exceeds max instant value (${maxInstant} wei); use the standard 12h withdrawal`,
25761
+ { code: 10 /* LOW_AMOUNT_TO_BRIDGE */ }
25762
+ );
25763
+ }
25764
+ }
25765
+ setStatus("bridging");
25766
+ let txHash;
25767
+ if (variables.subAccount) {
25768
+ const multiAccount = symmioConfig?.multiAccountAddress ?? getAddress(MULTI_ACCOUNT_ADDRESS, chainId, "MultiAccount");
25769
+ txHash = await bridgeWithdraw(
25770
+ walletClient,
25771
+ publicClient,
25772
+ multiAccount,
25773
+ variables.subAccount,
25774
+ {
25775
+ amount: variables.amount,
25776
+ bridgeAddress,
25777
+ deallocate: variables.deallocate
25778
+ }
25779
+ );
25780
+ } else {
25781
+ const symmioDiamond = symmioConfig?.symmioDiamondAddress ?? getAddress(SYMMIO_DIAMOND_ADDRESS, chainId, "SymmioDiamond");
25782
+ txHash = await transferToBridge(walletClient, publicClient, symmioDiamond, {
25783
+ amount: variables.amount,
25784
+ bridgeAddress
25785
+ });
25786
+ }
25787
+ setBridgeTxHash(txHash);
25788
+ await publicClient.waitForTransactionReceipt({ hash: txHash });
25789
+ setStatus("awaitingBridgeId");
25790
+ const bridgeId = await pollForBridgeId(
25791
+ chainId,
25792
+ apiAccount,
25793
+ variables.amount,
25794
+ accessToken,
25795
+ params.bridgeIdTimeoutMs ?? 3e4
25796
+ );
25797
+ setStatus("fetchingOptions");
25798
+ const { options: feeOptions } = await getFeeOptions(
25799
+ chainId,
25800
+ apiAccount,
25801
+ variables.amount,
25802
+ accessToken
25803
+ );
25804
+ const option = pickOption(feeOptions, speed);
25805
+ setStatus("selectingPolicy");
25806
+ let receiver = null;
25807
+ if (variables.newReceiver) {
25808
+ receiver = await buildSpecifiedReceiver(
25809
+ chainId,
25810
+ variables.newReceiver,
25811
+ bridgeId,
25812
+ walletClient,
25813
+ address
25814
+ );
25815
+ }
25816
+ const result = await selectFeePolicy(
25817
+ chainId,
25818
+ {
25819
+ symmioBridgeId: bridgeId,
25820
+ cooldown: option.cooldown,
25821
+ feeAmount: option.fee,
25822
+ receiver
25823
+ },
25824
+ accessToken
25825
+ );
25826
+ setStatus("done");
25827
+ return {
25828
+ bridgeId,
25829
+ executionTime: result.execution_time,
25830
+ fee: result.fee,
25831
+ bridgeTxHash: txHash
25832
+ };
25833
+ } catch (err) {
25834
+ setStatus("failed");
25835
+ throw err;
25836
+ }
25837
+ }
25838
+ });
25839
+ return { ...mutation, status, bridgeTxHash, reset };
25840
+ }
25841
+ async function pollForBridgeId(chainId, account, amount, accessToken, timeoutMs) {
25842
+ const deadline = Date.now() + timeoutMs;
25843
+ const intervalMs = 2e3;
25844
+ const target = Number(amount);
25845
+ while (Date.now() < deadline) {
25846
+ const { bridges } = await getBridges(
25847
+ chainId,
25848
+ account,
25849
+ 0,
25850
+ 50,
25851
+ { bridge_state: "pending" /* PENDING */, bridge_type: "no_policy" /* NO_POLICY */ },
25852
+ accessToken
25853
+ );
25854
+ const matches = (bridges ?? []).filter((b) => b.bridge_amount === target);
25855
+ if (matches.length > 0) {
25856
+ return matches.reduce((a, b) => b.bridge_id > a.bridge_id ? b : a).bridge_id;
25857
+ }
25858
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
25859
+ }
25860
+ throw new InstantWithdrawalError(
25861
+ "timed out resolving the bridge transaction; the bot may still be indexing \u2014 retry fee selection from your bridge list",
25862
+ { code: 7 /* INVALID_BRIDGE_TRANSACTION */ }
25863
+ );
25864
+ }
25865
+ function useSymmProcessWithdrawalMutation(params, options) {
25866
+ const { chainId: ctxChainId, walletClient: ctxWallet } = useSymmContext();
25867
+ const chainId = params.chainId ?? ctxChainId;
25868
+ const walletClient = params.walletClient ?? ctxWallet;
25869
+ const { publicClient } = params;
25870
+ const queryClient = reactQuery.useQueryClient();
25871
+ return reactQuery.useMutation({
25872
+ ...withSymmMutationConfig(options?.mutation, {
25873
+ onSuccess: () => invalidateBridges(queryClient)
25874
+ }),
25875
+ mutationFn: async ({ bridgeId }) => {
25876
+ if (!walletClient || !publicClient) {
25877
+ throw new Error("Clients not available");
25878
+ }
25879
+ const instantWithdrawal = getAddress(
25880
+ INSTANT_WITHDRAWAL_ADDRESS,
25881
+ chainId,
25882
+ "InstantWithdrawal"
25883
+ );
25884
+ return processWithdrawal(walletClient, publicClient, instantWithdrawal, {
25885
+ bridgeId
25886
+ });
25887
+ }
25888
+ });
25889
+ }
25122
25890
  function prepareAllocate(multiAccount, account, subAccount, params) {
25123
25891
  validateAmount(params.amount, "allocate amount");
25124
25892
  const innerData = viem.encodeFunctionData({
@@ -26340,6 +27108,24 @@ function useSymmBalances(params) {
26340
27108
  enabled: internalEnabled && (params.query?.enabled ?? true)
26341
27109
  });
26342
27110
  }
27111
+ function normalizeSideWeights(legs) {
27112
+ if (!legs?.length) return legs;
27113
+ const allWeighted = legs.every(
27114
+ (leg) => typeof leg.weight === "number" && Number.isFinite(leg.weight) && leg.weight > 0
27115
+ );
27116
+ if (!allWeighted) return legs;
27117
+ const total = legs.reduce((sum, leg) => sum + (leg.weight ?? 0), 0);
27118
+ if (total <= 0) return legs;
27119
+ if (Math.abs(total - 1) < 1e-9) return legs;
27120
+ return legs.map((leg) => ({ ...leg, weight: (leg.weight ?? 0) / total }));
27121
+ }
27122
+ function normalizeBasketWeights(request) {
27123
+ return {
27124
+ ...request,
27125
+ longPositions: normalizeSideWeights(request.longPositions),
27126
+ shortPositions: normalizeSideWeights(request.shortPositions)
27127
+ };
27128
+ }
26343
27129
  function useSymmOpenBasketMutation(options) {
26344
27130
  const { symmCoreClient } = useSymmContext();
26345
27131
  const queryClient = reactQuery.useQueryClient();
@@ -26360,10 +27146,12 @@ function useSymmOpenBasketMutation(options) {
26360
27146
  if (!authToken) {
26361
27147
  throw new Error("auth token is required to open a position");
26362
27148
  }
26363
- return symmCoreClient.positions.openBasket({
26364
- ...request,
26365
- authToken
26366
- });
27149
+ return symmCoreClient.positions.openBasket(
27150
+ normalizeBasketWeights({
27151
+ ...request,
27152
+ authToken
27153
+ })
27154
+ );
26367
27155
  }
26368
27156
  });
26369
27157
  }
@@ -28032,6 +28820,7 @@ function getSymmErrorMessage(error) {
28032
28820
  }
28033
28821
 
28034
28822
  exports.SymmProvider = SymmProvider;
28823
+ exports.buildSpecifiedReceiver = buildSpecifiedReceiver;
28035
28824
  exports.computeSymmAccountOverview = computeSymmAccountOverview;
28036
28825
  exports.computeSymmAccountOverviewFromData = computeSymmAccountOverviewFromData;
28037
28826
  exports.computeSymmNetDeposited = computeSymmNetDeposited;
@@ -28057,6 +28846,7 @@ exports.useSymmApproveMutation = useSymmApproveMutation;
28057
28846
  exports.useSymmAuth = useSymmAuth;
28058
28847
  exports.useSymmAvailableMargin = useSymmAvailableMargin;
28059
28848
  exports.useSymmBalances = useSymmBalances;
28849
+ exports.useSymmBridges = useSymmBridges;
28060
28850
  exports.useSymmCancelClose = useSymmCancelClose;
28061
28851
  exports.useSymmCancelOpenMutation = useSymmCancelOpenMutation;
28062
28852
  exports.useSymmCancelTpslMutation = useSymmCancelTpslMutation;
@@ -28076,6 +28866,7 @@ exports.useSymmDelegation = useSymmDelegation;
28076
28866
  exports.useSymmDepositAndAllocateMutation = useSymmDepositAndAllocateMutation;
28077
28867
  exports.useSymmDepositMutation = useSymmDepositMutation;
28078
28868
  exports.useSymmEditAccountNameMutation = useSymmEditAccountNameMutation;
28869
+ exports.useSymmFeeOptionsMutation = useSymmFeeOptionsMutation;
28079
28870
  exports.useSymmFunding = useSymmFunding;
28080
28871
  exports.useSymmFundingHistory = useSymmFundingHistory;
28081
28872
  exports.useSymmFundingPayments = useSymmFundingPayments;
@@ -28084,22 +28875,29 @@ exports.useSymmHedgerMarketBySymbol = useSymmHedgerMarketBySymbol;
28084
28875
  exports.useSymmHedgerMarkets = useSymmHedgerMarkets;
28085
28876
  exports.useSymmInstantTradeEnsureReadyMutation = useSymmInstantTradeEnsureReadyMutation;
28086
28877
  exports.useSymmInstantTradeExecuteMutation = useSymmInstantTradeExecuteMutation;
28878
+ exports.useSymmInstantWithdraw = useSymmInstantWithdraw;
28879
+ exports.useSymmInstantWithdrawalAuth = useSymmInstantWithdrawalAuth;
28087
28880
  exports.useSymmInternalTransferCollateralMutation = useSymmInternalTransferCollateralMutation;
28088
28881
  exports.useSymmLeaderboard = useSymmLeaderboard;
28089
28882
  exports.useSymmLockedParams = useSymmLockedParams;
28090
28883
  exports.useSymmMarkReadNotificationMutation = useSymmMarkReadNotificationMutation;
28091
28884
  exports.useSymmMarketPositioning = useSymmMarketPositioning;
28092
28885
  exports.useSymmMarkets = useSymmMarkets;
28886
+ exports.useSymmMaxInstantValue = useSymmMaxInstantValue;
28093
28887
  exports.useSymmNotificationsQuery = useSymmNotificationsQuery;
28094
28888
  exports.useSymmOpenBasketMutation = useSymmOpenBasketMutation;
28095
28889
  exports.useSymmOpenOrders = useSymmOpenOrders;
28890
+ exports.useSymmPendingFeePolicy = useSymmPendingFeePolicy;
28096
28891
  exports.useSymmPendingIds = useSymmPendingIds;
28097
28892
  exports.useSymmPendingInstantOpens = useSymmPendingInstantOpens;
28098
28893
  exports.useSymmPerformanceOverlays = useSymmPerformanceOverlays;
28099
28894
  exports.useSymmPortfolio = useSymmPortfolio;
28100
28895
  exports.useSymmPositions = useSymmPositions;
28896
+ exports.useSymmProcessWithdrawalMutation = useSymmProcessWithdrawalMutation;
28101
28897
  exports.useSymmProposeRevokeDelegationMutation = useSymmProposeRevokeDelegationMutation;
28898
+ exports.useSymmRefreshFeeOptionsMutation = useSymmRefreshFeeOptionsMutation;
28102
28899
  exports.useSymmRevokeDelegationMutation = useSymmRevokeDelegationMutation;
28900
+ exports.useSymmSelectFeePolicyMutation = useSymmSelectFeePolicyMutation;
28103
28901
  exports.useSymmSetTpslMutation = useSymmSetTpslMutation;
28104
28902
  exports.useSymmSetTriggerConfigMutation = useSymmSetTriggerConfigMutation;
28105
28903
  exports.useSymmSignTermsMutation = useSymmSignTermsMutation;
@@ -28113,10 +28911,12 @@ exports.useSymmTriggerConfigQuery = useSymmTriggerConfigQuery;
28113
28911
  exports.useSymmTriggerOrders = useSymmTriggerOrders;
28114
28912
  exports.useSymmTwapOrder = useSymmTwapOrder;
28115
28913
  exports.useSymmTwapOrdersQuery = useSymmTwapOrdersQuery;
28914
+ exports.useSymmUnlockAccountMutation = useSymmUnlockAccountMutation;
28116
28915
  exports.useSymmUnreadCountQuery = useSymmUnreadCountQuery;
28117
28916
  exports.useSymmUpdatePositionMutation = useSymmUpdatePositionMutation;
28118
28917
  exports.useSymmUpnlWebSocket = useSymmUpnlWebSocket;
28119
28918
  exports.useSymmWithdraw = useSymmWithdraw;
28919
+ exports.useSymmWithdrawalConfig = useSymmWithdrawalConfig;
28120
28920
  exports.useSymmWsStore = useSymmWsStore;
28121
28921
  //# sourceMappingURL=index.js.map
28122
28922
  //# sourceMappingURL=index.js.map