@swype-org/react-sdk 0.2.303 → 0.2.311

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -545,12 +545,16 @@ function buildSelectSourceChoices(options, minTransferAmountUsd = DEFAULT_MIN_SE
545
545
  } else if (!existing.walletName && option.walletName) {
546
546
  existing.walletName = option.walletName;
547
547
  }
548
+ if (!existing.logoURI && option.logoURI) {
549
+ existing.logoURI = option.logoURI;
550
+ }
548
551
  } else {
549
552
  chainChoice.tokens.push({
550
553
  tokenSymbol,
551
554
  balance,
552
555
  ...option.walletName ? { walletName: option.walletName } : {},
553
- ...option.walletLogoUrl ? { walletLogoUrl: option.walletLogoUrl } : {}
556
+ ...option.walletLogoUrl ? { walletLogoUrl: option.walletLogoUrl } : {},
557
+ ...option.logoURI ? { logoURI: option.logoURI } : {}
554
558
  });
555
559
  }
556
560
  }
@@ -1411,6 +1415,263 @@ async function revokeAndDisconnectActiveWagmiConnector(wagmiConfig) {
1411
1415
  });
1412
1416
  }
1413
1417
 
1418
+ // src/solanaWalletRuntime.ts
1419
+ function asSigner(adapter) {
1420
+ return adapter;
1421
+ }
1422
+ var PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE = "PHANTOM_SOLANA_CONNECT_TIMEOUT";
1423
+ var APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE = "APPROVE_SPL_CONFIRMATION_TIMEOUT";
1424
+ var APPROVE_SPL_ONCHAIN_FAILURE_PREFIX = "Solana transaction failed:";
1425
+ var DEFAULT_CONFIRM_TIMEOUT_MS = 45e3;
1426
+ var DEFAULT_POLL_INTERVAL_MS = 1e3;
1427
+ var DEFAULT_COMMITMENT = "confirmed";
1428
+ var cachedAdapter = null;
1429
+ var cachedProviderKey = null;
1430
+ function providerKey(selection) {
1431
+ const providerName = selection.providerName?.trim();
1432
+ if (!providerName) {
1433
+ throw new Error("Solana wallet metadata is missing providerName.");
1434
+ }
1435
+ return `${selection.providerId ?? ""}:${providerName.toLowerCase()}`;
1436
+ }
1437
+ function assertSupportedProvider(selection) {
1438
+ const name = selection.providerName?.trim().toLowerCase();
1439
+ if (name !== "phantom") {
1440
+ throw new Error(`Unsupported Solana wallet provider: ${selection.providerName ?? "unknown"}.`);
1441
+ }
1442
+ }
1443
+ async function createAdapter(selection) {
1444
+ assertSupportedProvider(selection);
1445
+ const { PhantomWalletAdapter } = await import('@solana/wallet-adapter-phantom');
1446
+ return new PhantomWalletAdapter();
1447
+ }
1448
+ function readPublicKey(adapter) {
1449
+ const publicKey = adapter.publicKey?.toBase58();
1450
+ if (!publicKey) {
1451
+ throw new Error("Solana wallet did not return a public key.");
1452
+ }
1453
+ return publicKey;
1454
+ }
1455
+ async function connectSolanaWallet(selection, options) {
1456
+ const key = providerKey(selection);
1457
+ if (!cachedAdapter || cachedProviderKey !== key) {
1458
+ cachedAdapter = await createAdapter(selection);
1459
+ cachedProviderKey = key;
1460
+ }
1461
+ if (!cachedAdapter.connected) {
1462
+ const adapter = cachedAdapter;
1463
+ const connectPromise = adapter.connect();
1464
+ const timeoutMs = options?.timeoutMs;
1465
+ if (typeof timeoutMs === "number" && timeoutMs > 0) {
1466
+ let timeoutHandle = null;
1467
+ const timeoutPromise = new Promise((_, reject) => {
1468
+ timeoutHandle = setTimeout(() => {
1469
+ reject(new Error(PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE));
1470
+ }, timeoutMs);
1471
+ });
1472
+ try {
1473
+ await Promise.race([connectPromise, timeoutPromise]);
1474
+ } finally {
1475
+ if (timeoutHandle) clearTimeout(timeoutHandle);
1476
+ }
1477
+ } else {
1478
+ await connectPromise;
1479
+ }
1480
+ }
1481
+ return {
1482
+ adapter: cachedAdapter,
1483
+ publicKey: readPublicKey(cachedAdapter)
1484
+ };
1485
+ }
1486
+ async function signSolanaTransaction(selection, unsignedTxBase64, expectedOwnerPubkey) {
1487
+ const { adapter, publicKey } = await connectSolanaWallet(selection);
1488
+ if (publicKey !== expectedOwnerPubkey) {
1489
+ throw new Error(
1490
+ `Connected Solana wallet ${publicKey} does not match the required source wallet ${expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
1491
+ );
1492
+ }
1493
+ const signer = asSigner(adapter);
1494
+ if (typeof signer.signTransaction !== "function") {
1495
+ throw new Error("Selected Solana wallet does not support transaction signing.");
1496
+ }
1497
+ const transaction = await deserializeTransaction(unsignedTxBase64);
1498
+ const signedTransaction = await signer.signTransaction(transaction);
1499
+ return {
1500
+ ownerPubkey: publicKey,
1501
+ signedTxBase64: bytesToBase64(serializeTransaction(signedTransaction))
1502
+ };
1503
+ }
1504
+ async function deserializeTransaction(unsignedTxBase64) {
1505
+ const { Transaction, VersionedTransaction } = await import('@solana/web3.js');
1506
+ const bytes = base64ToBytes(unsignedTxBase64);
1507
+ try {
1508
+ return Transaction.from(bytes);
1509
+ } catch {
1510
+ return VersionedTransaction.deserialize(bytes);
1511
+ }
1512
+ }
1513
+ function serializeTransaction(transaction) {
1514
+ if ("version" in transaction) {
1515
+ return transaction.serialize();
1516
+ }
1517
+ return transaction.serialize({
1518
+ requireAllSignatures: false,
1519
+ verifySignatures: false
1520
+ });
1521
+ }
1522
+ function base64ToBytes(value) {
1523
+ if (typeof globalThis.atob === "function") {
1524
+ const binary = globalThis.atob(value);
1525
+ const bytes = new Uint8Array(binary.length);
1526
+ for (let i = 0; i < binary.length; i++) {
1527
+ bytes[i] = binary.charCodeAt(i);
1528
+ }
1529
+ return bytes;
1530
+ }
1531
+ const bufferCtor = globalThis.Buffer;
1532
+ if (bufferCtor) {
1533
+ return bufferCtor.from(value, "base64");
1534
+ }
1535
+ throw new Error("Base64 decoding is not available in this environment.");
1536
+ }
1537
+ function bytesToBase64(bytes) {
1538
+ if (typeof globalThis.btoa === "function") {
1539
+ let binary = "";
1540
+ for (const byte of bytes) {
1541
+ binary += String.fromCharCode(byte);
1542
+ }
1543
+ return globalThis.btoa(binary);
1544
+ }
1545
+ const bufferCtor = globalThis.Buffer;
1546
+ if (bufferCtor) {
1547
+ return bufferCtor.from(bytes).toString("base64");
1548
+ }
1549
+ throw new Error("Base64 encoding is not available in this environment.");
1550
+ }
1551
+ async function signAndSendApproveSplViaWallet(params) {
1552
+ const rpcUrl = params.rpcUrl?.trim();
1553
+ if (!rpcUrl) {
1554
+ throw new Error("signAndSendApproveSplViaWallet requires an rpcUrl.");
1555
+ }
1556
+ const unsignedTxBase64 = params.unsignedTxBase64?.trim();
1557
+ if (!unsignedTxBase64) {
1558
+ throw new Error("signAndSendApproveSplViaWallet requires unsignedTxBase64.");
1559
+ }
1560
+ const commitment = params.commitment ?? DEFAULT_COMMITMENT;
1561
+ const { adapter, publicKey } = await connectSolanaWallet(params.selection);
1562
+ if (publicKey !== params.expectedOwnerPubkey) {
1563
+ throw new Error(
1564
+ `Connected Solana wallet ${publicKey} does not match the required source wallet ${params.expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
1565
+ );
1566
+ }
1567
+ if (!adapter.sendTransaction) {
1568
+ throw new Error("Selected Solana wallet does not support sendTransaction.");
1569
+ }
1570
+ const transaction = await deserializeTransaction(unsignedTxBase64);
1571
+ const connection = await defaultConnectionFactory(rpcUrl, commitment);
1572
+ const signature = await adapter.sendTransaction(
1573
+ transaction,
1574
+ connection,
1575
+ {
1576
+ preflightCommitment: commitment,
1577
+ maxRetries: 3
1578
+ }
1579
+ );
1580
+ return { ownerPubkey: publicKey, signature };
1581
+ }
1582
+ async function confirmApproveSplViaPolling(params) {
1583
+ const rpcUrl = params.rpcUrl?.trim();
1584
+ if (!rpcUrl) {
1585
+ throw new Error("confirmApproveSplViaPolling requires an rpcUrl.");
1586
+ }
1587
+ const signature = params.signature?.trim();
1588
+ if (!signature) {
1589
+ throw new Error("confirmApproveSplViaPolling requires a signature.");
1590
+ }
1591
+ const confirmTimeoutMs = params.confirmTimeoutMs ?? DEFAULT_CONFIRM_TIMEOUT_MS;
1592
+ const pollIntervalMs = params.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
1593
+ const commitment = params.commitment ?? DEFAULT_COMMITMENT;
1594
+ const connection = await defaultConnectionFactory(rpcUrl, commitment);
1595
+ const slot = await pollForConfirmation({
1596
+ connection,
1597
+ signature,
1598
+ confirmTimeoutMs,
1599
+ pollIntervalMs
1600
+ });
1601
+ return { signature, slot };
1602
+ }
1603
+ async function defaultConnectionFactory(rpcUrl, commitment) {
1604
+ const { Connection } = await import('@solana/web3.js');
1605
+ return new Connection(rpcUrl, commitment);
1606
+ }
1607
+ async function pollForConfirmation(args) {
1608
+ const { connection, signature, confirmTimeoutMs, pollIntervalMs } = args;
1609
+ const expiresAt = Date.now() + confirmTimeoutMs;
1610
+ while (Date.now() <= expiresAt) {
1611
+ const result = await connection.getSignatureStatuses(
1612
+ [signature],
1613
+ { searchTransactionHistory: true }
1614
+ );
1615
+ const status = result.value[0];
1616
+ if (status?.err) {
1617
+ throw new Error(`${APPROVE_SPL_ONCHAIN_FAILURE_PREFIX} ${JSON.stringify(status.err)}`);
1618
+ }
1619
+ const confirmationStatus = status?.confirmationStatus;
1620
+ if (confirmationStatus === "confirmed" || confirmationStatus === "finalized") {
1621
+ return status?.slot;
1622
+ }
1623
+ await sleep(pollIntervalMs);
1624
+ }
1625
+ throw new Error(APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE);
1626
+ }
1627
+ function sleep(ms) {
1628
+ return new Promise((resolve) => setTimeout(resolve, ms));
1629
+ }
1630
+ function getInjectedSolanaProvider(windowImpl) {
1631
+ const win = (typeof window === "undefined" ? void 0 : window);
1632
+ if (!win) return null;
1633
+ return win.phantom?.solana ?? win.solana ?? null;
1634
+ }
1635
+ async function disconnectSolanaWallet(windowImpl) {
1636
+ const adapter = cachedAdapter;
1637
+ cachedAdapter = null;
1638
+ cachedProviderKey = null;
1639
+ if (adapter?.connected) {
1640
+ try {
1641
+ console.info("[blink-sdk][solana-disconnect] disconnecting cached adapter");
1642
+ await adapter.disconnect();
1643
+ console.info("[blink-sdk][solana-disconnect] ok (cached adapter)");
1644
+ return;
1645
+ } catch (err) {
1646
+ console.warn("[blink-sdk][solana-disconnect] cached adapter disconnect failed", {
1647
+ message: err instanceof Error ? err.message : String(err)
1648
+ });
1649
+ }
1650
+ }
1651
+ const provider = getInjectedSolanaProvider();
1652
+ if (!provider) {
1653
+ console.info("[blink-sdk][solana-disconnect] no cached adapter and no injected provider \u2014 nothing to disconnect");
1654
+ return;
1655
+ }
1656
+ if (provider.isConnected === false) {
1657
+ console.info("[blink-sdk][solana-disconnect] injected provider already disconnected");
1658
+ return;
1659
+ }
1660
+ if (typeof provider.disconnect !== "function") {
1661
+ console.warn("[blink-sdk][solana-disconnect] injected provider has no disconnect() method");
1662
+ return;
1663
+ }
1664
+ try {
1665
+ console.info("[blink-sdk][solana-disconnect] disconnecting injected provider");
1666
+ await provider.disconnect();
1667
+ console.info("[blink-sdk][solana-disconnect] ok (injected provider)");
1668
+ } catch (err) {
1669
+ console.warn("[blink-sdk][solana-disconnect] injected provider disconnect failed", {
1670
+ message: err instanceof Error ? err.message : String(err)
1671
+ });
1672
+ }
1673
+ }
1674
+
1414
1675
  // src/otherWalletConnect.ts
1415
1676
  function findWalletConnectConnector(connectors) {
1416
1677
  return connectors.find((connector) => {
@@ -1840,6 +2101,7 @@ __export(api_exports, {
1840
2101
  setAuthorizationSessionPaymentIntentAmount: () => setAuthorizationSessionPaymentIntentAmount,
1841
2102
  setAuthorizationSessionProvider: () => setAuthorizationSessionProvider,
1842
2103
  signTransfer: () => signTransfer,
2104
+ updateManualTransferDepositTargetChain: () => updateManualTransferDepositTargetChain,
1843
2105
  updateUserConfig: () => updateUserConfig,
1844
2106
  updateUserConfigBySession: () => updateUserConfigBySession,
1845
2107
  waitForActionTransactionReceipt: () => waitForActionTransactionReceipt
@@ -2238,6 +2500,15 @@ async function fetchManualTransferSession(apiBaseUrl, sessionId) {
2238
2500
  if (!res.ok) await throwApiError(res);
2239
2501
  return await res.json();
2240
2502
  }
2503
+ async function updateManualTransferDepositTargetChain(apiBaseUrl, sessionId, selectedChainId) {
2504
+ const res = await fetch(`${apiBaseUrl}/v1/manual-transfers/${sessionId}`, {
2505
+ method: "PATCH",
2506
+ headers: { "Content-Type": "application/json" },
2507
+ body: JSON.stringify({ selectedChainId })
2508
+ });
2509
+ if (!res.ok) await throwApiError(res);
2510
+ return await res.json();
2511
+ }
2241
2512
  async function refreshManualTransferQuote(apiBaseUrl, sessionId) {
2242
2513
  const res = await fetch(
2243
2514
  `${apiBaseUrl}/v1/manual-transfers/${sessionId}/refresh-quote`,
@@ -2990,7 +3261,7 @@ async function waitForWalletNonceAgreement(params) {
2990
3261
  }
2991
3262
 
2992
3263
  // src/walletCallsStatus.ts
2993
- var DEFAULT_POLL_INTERVAL_MS = 2e3;
3264
+ var DEFAULT_POLL_INTERVAL_MS2 = 2e3;
2994
3265
  var DEFAULT_MAX_ATTEMPTS = 60;
2995
3266
  var DEFAULT_REQUEST_TIMEOUT_MS = 8e3;
2996
3267
  var DEFAULT_MAX_CONSECUTIVE_ERRORS = 5;
@@ -3012,7 +3283,7 @@ function classifyCallsStatus(status) {
3012
3283
  return "pending";
3013
3284
  }
3014
3285
  async function pollWalletCallsStatus(walletClient, callsId, options = {}) {
3015
- const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
3286
+ const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
3016
3287
  const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
3017
3288
  const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
3018
3289
  const maxConsecutiveErrors = options.maxConsecutiveErrors ?? DEFAULT_MAX_CONSECUTIVE_ERRORS;
@@ -3130,219 +3401,6 @@ async function withWatchdog(promise, label, options = {}) {
3130
3401
  }
3131
3402
  }
3132
3403
 
3133
- // src/solanaWalletRuntime.ts
3134
- function asSigner(adapter) {
3135
- return adapter;
3136
- }
3137
- var PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE = "PHANTOM_SOLANA_CONNECT_TIMEOUT";
3138
- var APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE = "APPROVE_SPL_CONFIRMATION_TIMEOUT";
3139
- var APPROVE_SPL_ONCHAIN_FAILURE_PREFIX = "Solana transaction failed:";
3140
- var DEFAULT_CONFIRM_TIMEOUT_MS = 45e3;
3141
- var DEFAULT_POLL_INTERVAL_MS2 = 1e3;
3142
- var DEFAULT_COMMITMENT = "confirmed";
3143
- var cachedAdapter = null;
3144
- var cachedProviderKey = null;
3145
- function providerKey(selection) {
3146
- const providerName = selection.providerName?.trim();
3147
- if (!providerName) {
3148
- throw new Error("Solana wallet metadata is missing providerName.");
3149
- }
3150
- return `${selection.providerId ?? ""}:${providerName.toLowerCase()}`;
3151
- }
3152
- function assertSupportedProvider(selection) {
3153
- const name = selection.providerName?.trim().toLowerCase();
3154
- if (name !== "phantom") {
3155
- throw new Error(`Unsupported Solana wallet provider: ${selection.providerName ?? "unknown"}.`);
3156
- }
3157
- }
3158
- async function createAdapter(selection) {
3159
- assertSupportedProvider(selection);
3160
- const { PhantomWalletAdapter } = await import('@solana/wallet-adapter-phantom');
3161
- return new PhantomWalletAdapter();
3162
- }
3163
- function readPublicKey(adapter) {
3164
- const publicKey = adapter.publicKey?.toBase58();
3165
- if (!publicKey) {
3166
- throw new Error("Solana wallet did not return a public key.");
3167
- }
3168
- return publicKey;
3169
- }
3170
- async function connectSolanaWallet(selection, options) {
3171
- const key = providerKey(selection);
3172
- if (!cachedAdapter || cachedProviderKey !== key) {
3173
- cachedAdapter = await createAdapter(selection);
3174
- cachedProviderKey = key;
3175
- }
3176
- if (!cachedAdapter.connected) {
3177
- const adapter = cachedAdapter;
3178
- const connectPromise = adapter.connect();
3179
- const timeoutMs = options?.timeoutMs;
3180
- if (typeof timeoutMs === "number" && timeoutMs > 0) {
3181
- let timeoutHandle = null;
3182
- const timeoutPromise = new Promise((_, reject) => {
3183
- timeoutHandle = setTimeout(() => {
3184
- reject(new Error(PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE));
3185
- }, timeoutMs);
3186
- });
3187
- try {
3188
- await Promise.race([connectPromise, timeoutPromise]);
3189
- } finally {
3190
- if (timeoutHandle) clearTimeout(timeoutHandle);
3191
- }
3192
- } else {
3193
- await connectPromise;
3194
- }
3195
- }
3196
- return {
3197
- adapter: cachedAdapter,
3198
- publicKey: readPublicKey(cachedAdapter)
3199
- };
3200
- }
3201
- async function signSolanaTransaction(selection, unsignedTxBase64, expectedOwnerPubkey) {
3202
- const { adapter, publicKey } = await connectSolanaWallet(selection);
3203
- if (publicKey !== expectedOwnerPubkey) {
3204
- throw new Error(
3205
- `Connected Solana wallet ${publicKey} does not match the required source wallet ${expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
3206
- );
3207
- }
3208
- const signer = asSigner(adapter);
3209
- if (typeof signer.signTransaction !== "function") {
3210
- throw new Error("Selected Solana wallet does not support transaction signing.");
3211
- }
3212
- const transaction = await deserializeTransaction(unsignedTxBase64);
3213
- const signedTransaction = await signer.signTransaction(transaction);
3214
- return {
3215
- ownerPubkey: publicKey,
3216
- signedTxBase64: bytesToBase64(serializeTransaction(signedTransaction))
3217
- };
3218
- }
3219
- async function deserializeTransaction(unsignedTxBase64) {
3220
- const { Transaction, VersionedTransaction } = await import('@solana/web3.js');
3221
- const bytes = base64ToBytes(unsignedTxBase64);
3222
- try {
3223
- return Transaction.from(bytes);
3224
- } catch {
3225
- return VersionedTransaction.deserialize(bytes);
3226
- }
3227
- }
3228
- function serializeTransaction(transaction) {
3229
- if ("version" in transaction) {
3230
- return transaction.serialize();
3231
- }
3232
- return transaction.serialize({
3233
- requireAllSignatures: false,
3234
- verifySignatures: false
3235
- });
3236
- }
3237
- function base64ToBytes(value) {
3238
- if (typeof globalThis.atob === "function") {
3239
- const binary = globalThis.atob(value);
3240
- const bytes = new Uint8Array(binary.length);
3241
- for (let i = 0; i < binary.length; i++) {
3242
- bytes[i] = binary.charCodeAt(i);
3243
- }
3244
- return bytes;
3245
- }
3246
- const bufferCtor = globalThis.Buffer;
3247
- if (bufferCtor) {
3248
- return bufferCtor.from(value, "base64");
3249
- }
3250
- throw new Error("Base64 decoding is not available in this environment.");
3251
- }
3252
- function bytesToBase64(bytes) {
3253
- if (typeof globalThis.btoa === "function") {
3254
- let binary = "";
3255
- for (const byte of bytes) {
3256
- binary += String.fromCharCode(byte);
3257
- }
3258
- return globalThis.btoa(binary);
3259
- }
3260
- const bufferCtor = globalThis.Buffer;
3261
- if (bufferCtor) {
3262
- return bufferCtor.from(bytes).toString("base64");
3263
- }
3264
- throw new Error("Base64 encoding is not available in this environment.");
3265
- }
3266
- async function signAndSendApproveSplViaWallet(params) {
3267
- const rpcUrl = params.rpcUrl?.trim();
3268
- if (!rpcUrl) {
3269
- throw new Error("signAndSendApproveSplViaWallet requires an rpcUrl.");
3270
- }
3271
- const unsignedTxBase64 = params.unsignedTxBase64?.trim();
3272
- if (!unsignedTxBase64) {
3273
- throw new Error("signAndSendApproveSplViaWallet requires unsignedTxBase64.");
3274
- }
3275
- const commitment = params.commitment ?? DEFAULT_COMMITMENT;
3276
- const { adapter, publicKey } = await connectSolanaWallet(params.selection);
3277
- if (publicKey !== params.expectedOwnerPubkey) {
3278
- throw new Error(
3279
- `Connected Solana wallet ${publicKey} does not match the required source wallet ${params.expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
3280
- );
3281
- }
3282
- if (!adapter.sendTransaction) {
3283
- throw new Error("Selected Solana wallet does not support sendTransaction.");
3284
- }
3285
- const transaction = await deserializeTransaction(unsignedTxBase64);
3286
- const connection = await defaultConnectionFactory(rpcUrl, commitment);
3287
- const signature = await adapter.sendTransaction(
3288
- transaction,
3289
- connection,
3290
- {
3291
- preflightCommitment: commitment,
3292
- maxRetries: 3
3293
- }
3294
- );
3295
- return { ownerPubkey: publicKey, signature };
3296
- }
3297
- async function confirmApproveSplViaPolling(params) {
3298
- const rpcUrl = params.rpcUrl?.trim();
3299
- if (!rpcUrl) {
3300
- throw new Error("confirmApproveSplViaPolling requires an rpcUrl.");
3301
- }
3302
- const signature = params.signature?.trim();
3303
- if (!signature) {
3304
- throw new Error("confirmApproveSplViaPolling requires a signature.");
3305
- }
3306
- const confirmTimeoutMs = params.confirmTimeoutMs ?? DEFAULT_CONFIRM_TIMEOUT_MS;
3307
- const pollIntervalMs = params.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
3308
- const commitment = params.commitment ?? DEFAULT_COMMITMENT;
3309
- const connection = await defaultConnectionFactory(rpcUrl, commitment);
3310
- const slot = await pollForConfirmation({
3311
- connection,
3312
- signature,
3313
- confirmTimeoutMs,
3314
- pollIntervalMs
3315
- });
3316
- return { signature, slot };
3317
- }
3318
- async function defaultConnectionFactory(rpcUrl, commitment) {
3319
- const { Connection } = await import('@solana/web3.js');
3320
- return new Connection(rpcUrl, commitment);
3321
- }
3322
- async function pollForConfirmation(args) {
3323
- const { connection, signature, confirmTimeoutMs, pollIntervalMs } = args;
3324
- const expiresAt = Date.now() + confirmTimeoutMs;
3325
- while (Date.now() <= expiresAt) {
3326
- const result = await connection.getSignatureStatuses(
3327
- [signature],
3328
- { searchTransactionHistory: true }
3329
- );
3330
- const status = result.value[0];
3331
- if (status?.err) {
3332
- throw new Error(`${APPROVE_SPL_ONCHAIN_FAILURE_PREFIX} ${JSON.stringify(status.err)}`);
3333
- }
3334
- const confirmationStatus = status?.confirmationStatus;
3335
- if (confirmationStatus === "confirmed" || confirmationStatus === "finalized") {
3336
- return status?.slot;
3337
- }
3338
- await sleep(pollIntervalMs);
3339
- }
3340
- throw new Error(APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE);
3341
- }
3342
- function sleep(ms) {
3343
- return new Promise((resolve) => setTimeout(resolve, ms));
3344
- }
3345
-
3346
3404
  // src/walletConnectRuntime.ts
3347
3405
  var PRIMARY_CHAIN_ID = 8453;
3348
3406
  var OPTIONAL_CHAIN_IDS = [1, 42161, 137, 56, 6342, 10143, 999, 84532];
@@ -6287,61 +6345,14 @@ function useAuthorizationOrchestrator(deps) {
6287
6345
  if (cachedBatchSupport == null) {
6288
6346
  cachedBatchSupport = await authExecutor.canBatch();
6289
6347
  }
6290
- const batchSupported = cachedBatchSupport;
6348
+ const batchSupported = false;
6291
6349
  console.info("[blink-sdk][orchestrator] Batch evaluation complete.", {
6292
6350
  ownerSessionId,
6293
6351
  batchSupported,
6294
6352
  actionIds: batchable.map((candidate) => candidate.id),
6295
6353
  actionTypes: batchable.map((candidate) => candidate.type)
6296
6354
  });
6297
- if (batchSupported) {
6298
- const readyBatchable = await waitForBatchableActionsReady({
6299
- apiBaseUrl,
6300
- batchable,
6301
- sessions,
6302
- actionSessionMap
6303
- });
6304
- const batchInputs = readyBatchable.map((candidate) => ({
6305
- action: candidate,
6306
- sessionId: actionSessionMap.get(candidate.id) ?? sessionId
6307
- }));
6308
- const batchWalletConnectRuntimeKey = getWalletConnectRuntimeKeyForAction(
6309
- batchInputs[0]?.action,
6310
- batchInputs[0]?.sessionId ?? ownerSessionId,
6311
- sessions
6312
- );
6313
- const paymasterUrl = `${apiBaseUrl}/v1/paymaster`;
6314
- const batchResult = await authExecutor.executeBatch(batchInputs, {
6315
- paymasterUrl,
6316
- ...batchWalletConnectRuntimeKey ? { walletConnectRuntimeKey: batchWalletConnectRuntimeKey } : {},
6317
- onWalletConnectDisplayUri: options?.onWalletConnectDisplayUri
6318
- });
6319
- for (const { action: batchedAction, result: result2 } of batchResult.actionResults) {
6320
- completedIds.add(batchedAction.id);
6321
- authExecutor.addResult(result2);
6322
- if (isSubmittedApprovePermit2Result(batchedAction, result2)) {
6323
- submittedApprovePermit2ActionIdsRef.current.add(batchedAction.id);
6324
- }
6325
- if (isSubmittedSignPermit2Result(batchedAction, result2)) {
6326
- submittedSignPermit2ActionIdsRef.current.add(batchedAction.id);
6327
- }
6328
- const batchedOwnerSessionId = actionSessionMap.get(batchedAction.id) ?? ownerSessionId;
6329
- const reportedSession2 = await reportActionCompletionWithLogging(
6330
- apiBaseUrl,
6331
- batchedAction,
6332
- batchedOwnerSessionId,
6333
- result2
6334
- );
6335
- updateTrackedSession(sessions, batchedOwnerSessionId, reportedSession2, actionSessionMap);
6336
- }
6337
- mergedPending = await waitForPendingActions({
6338
- apiBaseUrl,
6339
- sessions,
6340
- completedIds,
6341
- actionSessionMap
6342
- });
6343
- continue;
6344
- }
6355
+ if (batchSupported) ;
6345
6356
  }
6346
6357
  const approvePermit2WasSubmitted = action.type === "APPROVE_PERMIT2" && submittedApprovePermit2ActionIdsRef.current.has(action.id);
6347
6358
  const signPermit2WasSubmitted = action.type === "SIGN_PERMIT2" && submittedSignPermit2ActionIdsRef.current.has(action.id);
@@ -6994,6 +7005,7 @@ function useManualTransferSession({
6994
7005
  const completedRef = react.useRef(/* @__PURE__ */ new Set());
6995
7006
  const premintedFamiliesRef = react.useRef(/* @__PURE__ */ new Set());
6996
7007
  const inFlightPerTokenRef = react.useRef(/* @__PURE__ */ new Set());
7008
+ const reportedTargetChainRef = react.useRef(/* @__PURE__ */ new Map());
6997
7009
  react.useEffect(() => {
6998
7010
  if (!merchantAuthorization) return;
6999
7011
  let cancelled = false;
@@ -7146,6 +7158,51 @@ function useManualTransferSession({
7146
7158
  }, 2e3);
7147
7159
  return () => window.clearInterval(timer);
7148
7160
  }, [apiBaseUrl, activeSessionId, activeSessionStatus, pollEnabled]);
7161
+ const selectedSourceChainId = selectedOption?.chainId;
7162
+ const sessionRegistrationChainId = session?.source.chainId;
7163
+ react.useEffect(() => {
7164
+ if (!activeSessionId) return;
7165
+ if (selectedSourceChainId === void 0) return;
7166
+ if (sessionRegistrationChainId === void 0) return;
7167
+ if (!selectedOption) return;
7168
+ if (selectedOption.chainFamily !== "evm") return;
7169
+ if (isSameChainSameTokenSelection(selectedOption, destination)) return;
7170
+ const lastReported = reportedTargetChainRef.current.get(activeSessionId) ?? sessionRegistrationChainId;
7171
+ if (selectedSourceChainId === lastReported) return;
7172
+ reportedTargetChainRef.current.set(activeSessionId, selectedSourceChainId);
7173
+ let cancelled = false;
7174
+ updateManualTransferDepositTargetChain(apiBaseUrl, activeSessionId, selectedSourceChainId).then((updated) => {
7175
+ if (cancelled) return;
7176
+ setSessionsByFamily((prev) => {
7177
+ for (const family of Object.keys(prev)) {
7178
+ if (prev[family]?.sessionId === updated.sessionId) {
7179
+ return { ...prev, [family]: updated };
7180
+ }
7181
+ }
7182
+ return prev;
7183
+ });
7184
+ setPerTokenSessions((prev) => {
7185
+ for (const k of Object.keys(prev)) {
7186
+ if (prev[k]?.sessionId === updated.sessionId) {
7187
+ return { ...prev, [k]: updated };
7188
+ }
7189
+ }
7190
+ return prev;
7191
+ });
7192
+ }).catch(() => {
7193
+ reportedTargetChainRef.current.set(activeSessionId, lastReported);
7194
+ });
7195
+ return () => {
7196
+ cancelled = true;
7197
+ };
7198
+ }, [
7199
+ apiBaseUrl,
7200
+ activeSessionId,
7201
+ selectedSourceChainId,
7202
+ sessionRegistrationChainId,
7203
+ selectedOption,
7204
+ destination
7205
+ ]);
7149
7206
  const completionSignature = react.useMemo(() => {
7150
7207
  const entries2 = [];
7151
7208
  for (const family of Object.keys(sessionsByFamily)) {
@@ -12579,6 +12636,7 @@ function SelectDepositSourceScreen({
12579
12636
  {
12580
12637
  symbol: opt.symbol,
12581
12638
  chainName: opt.chainName,
12639
+ tokenLogoUri: opt.logoURI,
12582
12640
  balance: opt.balance,
12583
12641
  selected: !hasPendingMobileSelection && isSelected(opt),
12584
12642
  onClick: () => handleAuthorizedPick(opt)
@@ -12590,6 +12648,7 @@ function SelectDepositSourceScreen({
12590
12648
  {
12591
12649
  symbol: opt.symbol,
12592
12650
  chainName: opt.chainName,
12651
+ tokenLogoUri: opt.logoURI,
12593
12652
  balance: opt.balance,
12594
12653
  requiresAuth: true,
12595
12654
  selected: hasPendingMobileSelection ? pendingMobileSelection?.key === tokenOptionKey(opt) : isSelected(opt),
@@ -13627,7 +13686,7 @@ function SelectSourceScreen({
13627
13686
  /* @__PURE__ */ jsxRuntime.jsx("label", { style: labelStyle5(tokens.textSecondary), children: "Token" }),
13628
13687
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: optionListStyle, children: tokenChoices.map((token) => {
13629
13688
  const isSelected = token.tokenSymbol === selectedTokenSymbol;
13630
- const logo = token.walletLogoUrl ?? TOKEN_LOGOS[token.tokenSymbol];
13689
+ const logo = token.walletLogoUrl ?? token.logoURI ?? TOKEN_LOGOS[token.tokenSymbol];
13631
13690
  const logoAlt = token.walletLogoUrl ? token.walletName ?? token.tokenSymbol : token.tokenSymbol;
13632
13691
  return /* @__PURE__ */ jsxRuntime.jsxs(
13633
13692
  "button",
@@ -15224,10 +15283,12 @@ function TokenPickerScreen({
15224
15283
  tokenSymbol: source.token.symbol,
15225
15284
  tokenAddress: source.address,
15226
15285
  balance: visibleBalance,
15227
- status: source.token.status
15286
+ status: source.token.status,
15287
+ logoURI: source.token.logoURI
15228
15288
  });
15229
15289
  }
15230
15290
  }
15291
+ const selectedEntryLogo = selectedTokenSymbol ? entries2.find((e) => e.tokenSymbol === selectedTokenSymbol)?.logoURI ?? TOKEN_LOGOS[selectedTokenSymbol] : void 0;
15231
15292
  const handleSelect = (entry) => {
15232
15293
  if (entry.status === "AUTHORIZED") {
15233
15294
  onSelectAuthorized(entry.walletId, entry.tokenSymbol);
@@ -15254,7 +15315,7 @@ function TokenPickerScreen({
15254
15315
  onClick: onBack,
15255
15316
  style: tokenIconButtonStyle,
15256
15317
  children: [
15257
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
15318
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconWrapStyle, children: selectedEntryLogo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: selectedEntryLogo, alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
15258
15319
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
15259
15320
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
15260
15321
  ] }) }),
@@ -15268,6 +15329,7 @@ function TokenPickerScreen({
15268
15329
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenListStyle2, children: entries2.map((entry) => {
15269
15330
  const authorized = entry.status === "AUTHORIZED";
15270
15331
  const isSelected = entry.walletId === selectedWalletId && entry.tokenSymbol === selectedTokenSymbol;
15332
+ const entryLogo = entry.logoURI ?? TOKEN_LOGOS[entry.tokenSymbol];
15271
15333
  return /* @__PURE__ */ jsxRuntime.jsxs(
15272
15334
  "button",
15273
15335
  {
@@ -15275,7 +15337,7 @@ function TokenPickerScreen({
15275
15337
  onClick: () => handleSelect(entry),
15276
15338
  style: tokenRowStyle2(t),
15277
15339
  children: [
15278
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconCircleStyle2(t, !!TOKEN_LOGOS[entry.tokenSymbol]), children: TOKEN_LOGOS[entry.tokenSymbol] ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: TOKEN_LOGOS[entry.tokenSymbol], alt: entry.tokenSymbol, style: tokenLogoImgStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenIconTextStyle2(t.textMuted), children: "$" }) }),
15340
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: tokenIconCircleStyle2(t, !!entryLogo), children: entryLogo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: entryLogo, alt: entry.tokenSymbol, style: tokenLogoImgStyle2 }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenIconTextStyle2(t.textMuted), children: "$" }) }),
15279
15341
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenInfoStyle2, children: [
15280
15342
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: tokenNameRowStyle, children: [
15281
15343
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: tokenSymbolTextStyle(t.text), children: entry.tokenSymbol }),
@@ -16162,7 +16224,8 @@ function buildDepositScreenProps({
16162
16224
  status: source.token.status,
16163
16225
  tokenAddress: source.address,
16164
16226
  chainId: chain?.commonId ?? void 0,
16165
- accountId: account.id
16227
+ accountId: account.id,
16228
+ logoURI: source.token.logoURI
16166
16229
  });
16167
16230
  }
16168
16231
  }
@@ -16215,6 +16278,7 @@ function buildDepositScreenProps({
16215
16278
  },
16216
16279
  selectedTokenSymbol: selectedSource?.token.symbol,
16217
16280
  selectedChainName: selectedWallet?.chain.name,
16281
+ selectedTokenLogoUri: selectedSource?.token.logoURI,
16218
16282
  selectedWalletId: selectedWallet?.id ?? null,
16219
16283
  selectedTokenStatus,
16220
16284
  onAuthorizeSelectedToken,
@@ -19612,12 +19676,20 @@ function BlinkPaymentInner({
19612
19676
  dispatch,
19613
19677
  orchestrator
19614
19678
  ]);
19679
+ const disconnectWallets = react.useCallback(async () => {
19680
+ await Promise.allSettled([
19681
+ revokeAndDisconnectActiveWagmiConnector(wagmiConfig),
19682
+ authExecutor.resetWalletConnect().catch(() => {
19683
+ }),
19684
+ disconnectSolanaWallet()
19685
+ ]);
19686
+ }, [authExecutor, wagmiConfig]);
19615
19687
  const handleBackFromSetupDeposit = react.useCallback(async () => {
19616
19688
  orchestrator.cancelPendingFlow();
19617
19689
  authExecutor.cancelPendingExecution();
19618
19690
  clearScreenErrors();
19619
19691
  if (isDesktop) {
19620
- await revokeAndDisconnectActiveWagmiConnector(wagmiConfig);
19692
+ await disconnectWallets();
19621
19693
  }
19622
19694
  dispatch({ type: "RESTORE_SELECTION" });
19623
19695
  dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
@@ -19625,7 +19697,7 @@ function BlinkPaymentInner({
19625
19697
  dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19626
19698
  dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19627
19699
  dispatch({ type: "SET_USER_INTENT", intent: { step: "wallet-picker", reason: "switch" } });
19628
- }, [authExecutor, clearScreenErrors, orchestrator, dispatch, isDesktop, wagmiConfig]);
19700
+ }, [authExecutor, clearScreenErrors, orchestrator, dispatch, isDesktop, disconnectWallets]);
19629
19701
  const handleAuthorizationRetry = react.useCallback(() => {
19630
19702
  void (async () => {
19631
19703
  try {
@@ -19670,11 +19742,7 @@ function BlinkPaymentInner({
19670
19742
  dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19671
19743
  dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19672
19744
  dispatch({ type: "SET_USER_INTENT", intent: { step: "wallet-picker", reason: "switch" } });
19673
- void (async () => {
19674
- await revokeAndDisconnectActiveWagmiConnector(wagmiConfig);
19675
- await authExecutor.resetWalletConnect().catch(() => {
19676
- });
19677
- })();
19745
+ void disconnectWallets();
19678
19746
  },
19679
19747
  onSendManually: () => handleSetPhase({ step: "manual-transfer" }),
19680
19748
  onBackFromSetupDeposit: handleBackFromSetupDeposit,
@@ -19721,7 +19789,7 @@ function BlinkPaymentInner({
19721
19789
  handleConfirmSetupDeposit,
19722
19790
  handleBackFromSetupDeposit,
19723
19791
  handleAuthorizationRetry,
19724
- wagmiConfig
19792
+ disconnectWallets
19725
19793
  ]);
19726
19794
  return /* @__PURE__ */ jsxRuntime.jsx(EffectiveDepositAmountProvider, { value: effectiveDepositAmount, children: /* @__PURE__ */ jsxRuntime.jsx(
19727
19795
  ManualTransferSessionProvider,