@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.js CHANGED
@@ -521,12 +521,16 @@ function buildSelectSourceChoices(options, minTransferAmountUsd = DEFAULT_MIN_SE
521
521
  } else if (!existing.walletName && option.walletName) {
522
522
  existing.walletName = option.walletName;
523
523
  }
524
+ if (!existing.logoURI && option.logoURI) {
525
+ existing.logoURI = option.logoURI;
526
+ }
524
527
  } else {
525
528
  chainChoice.tokens.push({
526
529
  tokenSymbol,
527
530
  balance,
528
531
  ...option.walletName ? { walletName: option.walletName } : {},
529
- ...option.walletLogoUrl ? { walletLogoUrl: option.walletLogoUrl } : {}
532
+ ...option.walletLogoUrl ? { walletLogoUrl: option.walletLogoUrl } : {},
533
+ ...option.logoURI ? { logoURI: option.logoURI } : {}
530
534
  });
531
535
  }
532
536
  }
@@ -1387,6 +1391,263 @@ async function revokeAndDisconnectActiveWagmiConnector(wagmiConfig) {
1387
1391
  });
1388
1392
  }
1389
1393
 
1394
+ // src/solanaWalletRuntime.ts
1395
+ function asSigner(adapter) {
1396
+ return adapter;
1397
+ }
1398
+ var PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE = "PHANTOM_SOLANA_CONNECT_TIMEOUT";
1399
+ var APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE = "APPROVE_SPL_CONFIRMATION_TIMEOUT";
1400
+ var APPROVE_SPL_ONCHAIN_FAILURE_PREFIX = "Solana transaction failed:";
1401
+ var DEFAULT_CONFIRM_TIMEOUT_MS = 45e3;
1402
+ var DEFAULT_POLL_INTERVAL_MS = 1e3;
1403
+ var DEFAULT_COMMITMENT = "confirmed";
1404
+ var cachedAdapter = null;
1405
+ var cachedProviderKey = null;
1406
+ function providerKey(selection) {
1407
+ const providerName = selection.providerName?.trim();
1408
+ if (!providerName) {
1409
+ throw new Error("Solana wallet metadata is missing providerName.");
1410
+ }
1411
+ return `${selection.providerId ?? ""}:${providerName.toLowerCase()}`;
1412
+ }
1413
+ function assertSupportedProvider(selection) {
1414
+ const name = selection.providerName?.trim().toLowerCase();
1415
+ if (name !== "phantom") {
1416
+ throw new Error(`Unsupported Solana wallet provider: ${selection.providerName ?? "unknown"}.`);
1417
+ }
1418
+ }
1419
+ async function createAdapter(selection) {
1420
+ assertSupportedProvider(selection);
1421
+ const { PhantomWalletAdapter } = await import('@solana/wallet-adapter-phantom');
1422
+ return new PhantomWalletAdapter();
1423
+ }
1424
+ function readPublicKey(adapter) {
1425
+ const publicKey = adapter.publicKey?.toBase58();
1426
+ if (!publicKey) {
1427
+ throw new Error("Solana wallet did not return a public key.");
1428
+ }
1429
+ return publicKey;
1430
+ }
1431
+ async function connectSolanaWallet(selection, options) {
1432
+ const key = providerKey(selection);
1433
+ if (!cachedAdapter || cachedProviderKey !== key) {
1434
+ cachedAdapter = await createAdapter(selection);
1435
+ cachedProviderKey = key;
1436
+ }
1437
+ if (!cachedAdapter.connected) {
1438
+ const adapter = cachedAdapter;
1439
+ const connectPromise = adapter.connect();
1440
+ const timeoutMs = options?.timeoutMs;
1441
+ if (typeof timeoutMs === "number" && timeoutMs > 0) {
1442
+ let timeoutHandle = null;
1443
+ const timeoutPromise = new Promise((_, reject) => {
1444
+ timeoutHandle = setTimeout(() => {
1445
+ reject(new Error(PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE));
1446
+ }, timeoutMs);
1447
+ });
1448
+ try {
1449
+ await Promise.race([connectPromise, timeoutPromise]);
1450
+ } finally {
1451
+ if (timeoutHandle) clearTimeout(timeoutHandle);
1452
+ }
1453
+ } else {
1454
+ await connectPromise;
1455
+ }
1456
+ }
1457
+ return {
1458
+ adapter: cachedAdapter,
1459
+ publicKey: readPublicKey(cachedAdapter)
1460
+ };
1461
+ }
1462
+ async function signSolanaTransaction(selection, unsignedTxBase64, expectedOwnerPubkey) {
1463
+ const { adapter, publicKey } = await connectSolanaWallet(selection);
1464
+ if (publicKey !== expectedOwnerPubkey) {
1465
+ throw new Error(
1466
+ `Connected Solana wallet ${publicKey} does not match the required source wallet ${expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
1467
+ );
1468
+ }
1469
+ const signer = asSigner(adapter);
1470
+ if (typeof signer.signTransaction !== "function") {
1471
+ throw new Error("Selected Solana wallet does not support transaction signing.");
1472
+ }
1473
+ const transaction = await deserializeTransaction(unsignedTxBase64);
1474
+ const signedTransaction = await signer.signTransaction(transaction);
1475
+ return {
1476
+ ownerPubkey: publicKey,
1477
+ signedTxBase64: bytesToBase64(serializeTransaction(signedTransaction))
1478
+ };
1479
+ }
1480
+ async function deserializeTransaction(unsignedTxBase64) {
1481
+ const { Transaction, VersionedTransaction } = await import('@solana/web3.js');
1482
+ const bytes = base64ToBytes(unsignedTxBase64);
1483
+ try {
1484
+ return Transaction.from(bytes);
1485
+ } catch {
1486
+ return VersionedTransaction.deserialize(bytes);
1487
+ }
1488
+ }
1489
+ function serializeTransaction(transaction) {
1490
+ if ("version" in transaction) {
1491
+ return transaction.serialize();
1492
+ }
1493
+ return transaction.serialize({
1494
+ requireAllSignatures: false,
1495
+ verifySignatures: false
1496
+ });
1497
+ }
1498
+ function base64ToBytes(value) {
1499
+ if (typeof globalThis.atob === "function") {
1500
+ const binary = globalThis.atob(value);
1501
+ const bytes = new Uint8Array(binary.length);
1502
+ for (let i = 0; i < binary.length; i++) {
1503
+ bytes[i] = binary.charCodeAt(i);
1504
+ }
1505
+ return bytes;
1506
+ }
1507
+ const bufferCtor = globalThis.Buffer;
1508
+ if (bufferCtor) {
1509
+ return bufferCtor.from(value, "base64");
1510
+ }
1511
+ throw new Error("Base64 decoding is not available in this environment.");
1512
+ }
1513
+ function bytesToBase64(bytes) {
1514
+ if (typeof globalThis.btoa === "function") {
1515
+ let binary = "";
1516
+ for (const byte of bytes) {
1517
+ binary += String.fromCharCode(byte);
1518
+ }
1519
+ return globalThis.btoa(binary);
1520
+ }
1521
+ const bufferCtor = globalThis.Buffer;
1522
+ if (bufferCtor) {
1523
+ return bufferCtor.from(bytes).toString("base64");
1524
+ }
1525
+ throw new Error("Base64 encoding is not available in this environment.");
1526
+ }
1527
+ async function signAndSendApproveSplViaWallet(params) {
1528
+ const rpcUrl = params.rpcUrl?.trim();
1529
+ if (!rpcUrl) {
1530
+ throw new Error("signAndSendApproveSplViaWallet requires an rpcUrl.");
1531
+ }
1532
+ const unsignedTxBase64 = params.unsignedTxBase64?.trim();
1533
+ if (!unsignedTxBase64) {
1534
+ throw new Error("signAndSendApproveSplViaWallet requires unsignedTxBase64.");
1535
+ }
1536
+ const commitment = params.commitment ?? DEFAULT_COMMITMENT;
1537
+ const { adapter, publicKey } = await connectSolanaWallet(params.selection);
1538
+ if (publicKey !== params.expectedOwnerPubkey) {
1539
+ throw new Error(
1540
+ `Connected Solana wallet ${publicKey} does not match the required source wallet ${params.expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
1541
+ );
1542
+ }
1543
+ if (!adapter.sendTransaction) {
1544
+ throw new Error("Selected Solana wallet does not support sendTransaction.");
1545
+ }
1546
+ const transaction = await deserializeTransaction(unsignedTxBase64);
1547
+ const connection = await defaultConnectionFactory(rpcUrl, commitment);
1548
+ const signature = await adapter.sendTransaction(
1549
+ transaction,
1550
+ connection,
1551
+ {
1552
+ preflightCommitment: commitment,
1553
+ maxRetries: 3
1554
+ }
1555
+ );
1556
+ return { ownerPubkey: publicKey, signature };
1557
+ }
1558
+ async function confirmApproveSplViaPolling(params) {
1559
+ const rpcUrl = params.rpcUrl?.trim();
1560
+ if (!rpcUrl) {
1561
+ throw new Error("confirmApproveSplViaPolling requires an rpcUrl.");
1562
+ }
1563
+ const signature = params.signature?.trim();
1564
+ if (!signature) {
1565
+ throw new Error("confirmApproveSplViaPolling requires a signature.");
1566
+ }
1567
+ const confirmTimeoutMs = params.confirmTimeoutMs ?? DEFAULT_CONFIRM_TIMEOUT_MS;
1568
+ const pollIntervalMs = params.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
1569
+ const commitment = params.commitment ?? DEFAULT_COMMITMENT;
1570
+ const connection = await defaultConnectionFactory(rpcUrl, commitment);
1571
+ const slot = await pollForConfirmation({
1572
+ connection,
1573
+ signature,
1574
+ confirmTimeoutMs,
1575
+ pollIntervalMs
1576
+ });
1577
+ return { signature, slot };
1578
+ }
1579
+ async function defaultConnectionFactory(rpcUrl, commitment) {
1580
+ const { Connection } = await import('@solana/web3.js');
1581
+ return new Connection(rpcUrl, commitment);
1582
+ }
1583
+ async function pollForConfirmation(args) {
1584
+ const { connection, signature, confirmTimeoutMs, pollIntervalMs } = args;
1585
+ const expiresAt = Date.now() + confirmTimeoutMs;
1586
+ while (Date.now() <= expiresAt) {
1587
+ const result = await connection.getSignatureStatuses(
1588
+ [signature],
1589
+ { searchTransactionHistory: true }
1590
+ );
1591
+ const status = result.value[0];
1592
+ if (status?.err) {
1593
+ throw new Error(`${APPROVE_SPL_ONCHAIN_FAILURE_PREFIX} ${JSON.stringify(status.err)}`);
1594
+ }
1595
+ const confirmationStatus = status?.confirmationStatus;
1596
+ if (confirmationStatus === "confirmed" || confirmationStatus === "finalized") {
1597
+ return status?.slot;
1598
+ }
1599
+ await sleep(pollIntervalMs);
1600
+ }
1601
+ throw new Error(APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE);
1602
+ }
1603
+ function sleep(ms) {
1604
+ return new Promise((resolve) => setTimeout(resolve, ms));
1605
+ }
1606
+ function getInjectedSolanaProvider(windowImpl) {
1607
+ const win = (typeof window === "undefined" ? void 0 : window);
1608
+ if (!win) return null;
1609
+ return win.phantom?.solana ?? win.solana ?? null;
1610
+ }
1611
+ async function disconnectSolanaWallet(windowImpl) {
1612
+ const adapter = cachedAdapter;
1613
+ cachedAdapter = null;
1614
+ cachedProviderKey = null;
1615
+ if (adapter?.connected) {
1616
+ try {
1617
+ console.info("[blink-sdk][solana-disconnect] disconnecting cached adapter");
1618
+ await adapter.disconnect();
1619
+ console.info("[blink-sdk][solana-disconnect] ok (cached adapter)");
1620
+ return;
1621
+ } catch (err) {
1622
+ console.warn("[blink-sdk][solana-disconnect] cached adapter disconnect failed", {
1623
+ message: err instanceof Error ? err.message : String(err)
1624
+ });
1625
+ }
1626
+ }
1627
+ const provider = getInjectedSolanaProvider();
1628
+ if (!provider) {
1629
+ console.info("[blink-sdk][solana-disconnect] no cached adapter and no injected provider \u2014 nothing to disconnect");
1630
+ return;
1631
+ }
1632
+ if (provider.isConnected === false) {
1633
+ console.info("[blink-sdk][solana-disconnect] injected provider already disconnected");
1634
+ return;
1635
+ }
1636
+ if (typeof provider.disconnect !== "function") {
1637
+ console.warn("[blink-sdk][solana-disconnect] injected provider has no disconnect() method");
1638
+ return;
1639
+ }
1640
+ try {
1641
+ console.info("[blink-sdk][solana-disconnect] disconnecting injected provider");
1642
+ await provider.disconnect();
1643
+ console.info("[blink-sdk][solana-disconnect] ok (injected provider)");
1644
+ } catch (err) {
1645
+ console.warn("[blink-sdk][solana-disconnect] injected provider disconnect failed", {
1646
+ message: err instanceof Error ? err.message : String(err)
1647
+ });
1648
+ }
1649
+ }
1650
+
1390
1651
  // src/otherWalletConnect.ts
1391
1652
  function findWalletConnectConnector(connectors) {
1392
1653
  return connectors.find((connector) => {
@@ -1816,6 +2077,7 @@ __export(api_exports, {
1816
2077
  setAuthorizationSessionPaymentIntentAmount: () => setAuthorizationSessionPaymentIntentAmount,
1817
2078
  setAuthorizationSessionProvider: () => setAuthorizationSessionProvider,
1818
2079
  signTransfer: () => signTransfer,
2080
+ updateManualTransferDepositTargetChain: () => updateManualTransferDepositTargetChain,
1819
2081
  updateUserConfig: () => updateUserConfig,
1820
2082
  updateUserConfigBySession: () => updateUserConfigBySession,
1821
2083
  waitForActionTransactionReceipt: () => waitForActionTransactionReceipt
@@ -2214,6 +2476,15 @@ async function fetchManualTransferSession(apiBaseUrl, sessionId) {
2214
2476
  if (!res.ok) await throwApiError(res);
2215
2477
  return await res.json();
2216
2478
  }
2479
+ async function updateManualTransferDepositTargetChain(apiBaseUrl, sessionId, selectedChainId) {
2480
+ const res = await fetch(`${apiBaseUrl}/v1/manual-transfers/${sessionId}`, {
2481
+ method: "PATCH",
2482
+ headers: { "Content-Type": "application/json" },
2483
+ body: JSON.stringify({ selectedChainId })
2484
+ });
2485
+ if (!res.ok) await throwApiError(res);
2486
+ return await res.json();
2487
+ }
2217
2488
  async function refreshManualTransferQuote(apiBaseUrl, sessionId) {
2218
2489
  const res = await fetch(
2219
2490
  `${apiBaseUrl}/v1/manual-transfers/${sessionId}/refresh-quote`,
@@ -2966,7 +3237,7 @@ async function waitForWalletNonceAgreement(params) {
2966
3237
  }
2967
3238
 
2968
3239
  // src/walletCallsStatus.ts
2969
- var DEFAULT_POLL_INTERVAL_MS = 2e3;
3240
+ var DEFAULT_POLL_INTERVAL_MS2 = 2e3;
2970
3241
  var DEFAULT_MAX_ATTEMPTS = 60;
2971
3242
  var DEFAULT_REQUEST_TIMEOUT_MS = 8e3;
2972
3243
  var DEFAULT_MAX_CONSECUTIVE_ERRORS = 5;
@@ -2988,7 +3259,7 @@ function classifyCallsStatus(status) {
2988
3259
  return "pending";
2989
3260
  }
2990
3261
  async function pollWalletCallsStatus(walletClient, callsId, options = {}) {
2991
- const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
3262
+ const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
2992
3263
  const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
2993
3264
  const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
2994
3265
  const maxConsecutiveErrors = options.maxConsecutiveErrors ?? DEFAULT_MAX_CONSECUTIVE_ERRORS;
@@ -3106,219 +3377,6 @@ async function withWatchdog(promise, label, options = {}) {
3106
3377
  }
3107
3378
  }
3108
3379
 
3109
- // src/solanaWalletRuntime.ts
3110
- function asSigner(adapter) {
3111
- return adapter;
3112
- }
3113
- var PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE = "PHANTOM_SOLANA_CONNECT_TIMEOUT";
3114
- var APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE = "APPROVE_SPL_CONFIRMATION_TIMEOUT";
3115
- var APPROVE_SPL_ONCHAIN_FAILURE_PREFIX = "Solana transaction failed:";
3116
- var DEFAULT_CONFIRM_TIMEOUT_MS = 45e3;
3117
- var DEFAULT_POLL_INTERVAL_MS2 = 1e3;
3118
- var DEFAULT_COMMITMENT = "confirmed";
3119
- var cachedAdapter = null;
3120
- var cachedProviderKey = null;
3121
- function providerKey(selection) {
3122
- const providerName = selection.providerName?.trim();
3123
- if (!providerName) {
3124
- throw new Error("Solana wallet metadata is missing providerName.");
3125
- }
3126
- return `${selection.providerId ?? ""}:${providerName.toLowerCase()}`;
3127
- }
3128
- function assertSupportedProvider(selection) {
3129
- const name = selection.providerName?.trim().toLowerCase();
3130
- if (name !== "phantom") {
3131
- throw new Error(`Unsupported Solana wallet provider: ${selection.providerName ?? "unknown"}.`);
3132
- }
3133
- }
3134
- async function createAdapter(selection) {
3135
- assertSupportedProvider(selection);
3136
- const { PhantomWalletAdapter } = await import('@solana/wallet-adapter-phantom');
3137
- return new PhantomWalletAdapter();
3138
- }
3139
- function readPublicKey(adapter) {
3140
- const publicKey = adapter.publicKey?.toBase58();
3141
- if (!publicKey) {
3142
- throw new Error("Solana wallet did not return a public key.");
3143
- }
3144
- return publicKey;
3145
- }
3146
- async function connectSolanaWallet(selection, options) {
3147
- const key = providerKey(selection);
3148
- if (!cachedAdapter || cachedProviderKey !== key) {
3149
- cachedAdapter = await createAdapter(selection);
3150
- cachedProviderKey = key;
3151
- }
3152
- if (!cachedAdapter.connected) {
3153
- const adapter = cachedAdapter;
3154
- const connectPromise = adapter.connect();
3155
- const timeoutMs = options?.timeoutMs;
3156
- if (typeof timeoutMs === "number" && timeoutMs > 0) {
3157
- let timeoutHandle = null;
3158
- const timeoutPromise = new Promise((_, reject) => {
3159
- timeoutHandle = setTimeout(() => {
3160
- reject(new Error(PHANTOM_SOLANA_CONNECT_TIMEOUT_MESSAGE));
3161
- }, timeoutMs);
3162
- });
3163
- try {
3164
- await Promise.race([connectPromise, timeoutPromise]);
3165
- } finally {
3166
- if (timeoutHandle) clearTimeout(timeoutHandle);
3167
- }
3168
- } else {
3169
- await connectPromise;
3170
- }
3171
- }
3172
- return {
3173
- adapter: cachedAdapter,
3174
- publicKey: readPublicKey(cachedAdapter)
3175
- };
3176
- }
3177
- async function signSolanaTransaction(selection, unsignedTxBase64, expectedOwnerPubkey) {
3178
- const { adapter, publicKey } = await connectSolanaWallet(selection);
3179
- if (publicKey !== expectedOwnerPubkey) {
3180
- throw new Error(
3181
- `Connected Solana wallet ${publicKey} does not match the required source wallet ${expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
3182
- );
3183
- }
3184
- const signer = asSigner(adapter);
3185
- if (typeof signer.signTransaction !== "function") {
3186
- throw new Error("Selected Solana wallet does not support transaction signing.");
3187
- }
3188
- const transaction = await deserializeTransaction(unsignedTxBase64);
3189
- const signedTransaction = await signer.signTransaction(transaction);
3190
- return {
3191
- ownerPubkey: publicKey,
3192
- signedTxBase64: bytesToBase64(serializeTransaction(signedTransaction))
3193
- };
3194
- }
3195
- async function deserializeTransaction(unsignedTxBase64) {
3196
- const { Transaction, VersionedTransaction } = await import('@solana/web3.js');
3197
- const bytes = base64ToBytes(unsignedTxBase64);
3198
- try {
3199
- return Transaction.from(bytes);
3200
- } catch {
3201
- return VersionedTransaction.deserialize(bytes);
3202
- }
3203
- }
3204
- function serializeTransaction(transaction) {
3205
- if ("version" in transaction) {
3206
- return transaction.serialize();
3207
- }
3208
- return transaction.serialize({
3209
- requireAllSignatures: false,
3210
- verifySignatures: false
3211
- });
3212
- }
3213
- function base64ToBytes(value) {
3214
- if (typeof globalThis.atob === "function") {
3215
- const binary = globalThis.atob(value);
3216
- const bytes = new Uint8Array(binary.length);
3217
- for (let i = 0; i < binary.length; i++) {
3218
- bytes[i] = binary.charCodeAt(i);
3219
- }
3220
- return bytes;
3221
- }
3222
- const bufferCtor = globalThis.Buffer;
3223
- if (bufferCtor) {
3224
- return bufferCtor.from(value, "base64");
3225
- }
3226
- throw new Error("Base64 decoding is not available in this environment.");
3227
- }
3228
- function bytesToBase64(bytes) {
3229
- if (typeof globalThis.btoa === "function") {
3230
- let binary = "";
3231
- for (const byte of bytes) {
3232
- binary += String.fromCharCode(byte);
3233
- }
3234
- return globalThis.btoa(binary);
3235
- }
3236
- const bufferCtor = globalThis.Buffer;
3237
- if (bufferCtor) {
3238
- return bufferCtor.from(bytes).toString("base64");
3239
- }
3240
- throw new Error("Base64 encoding is not available in this environment.");
3241
- }
3242
- async function signAndSendApproveSplViaWallet(params) {
3243
- const rpcUrl = params.rpcUrl?.trim();
3244
- if (!rpcUrl) {
3245
- throw new Error("signAndSendApproveSplViaWallet requires an rpcUrl.");
3246
- }
3247
- const unsignedTxBase64 = params.unsignedTxBase64?.trim();
3248
- if (!unsignedTxBase64) {
3249
- throw new Error("signAndSendApproveSplViaWallet requires unsignedTxBase64.");
3250
- }
3251
- const commitment = params.commitment ?? DEFAULT_COMMITMENT;
3252
- const { adapter, publicKey } = await connectSolanaWallet(params.selection);
3253
- if (publicKey !== params.expectedOwnerPubkey) {
3254
- throw new Error(
3255
- `Connected Solana wallet ${publicKey} does not match the required source wallet ${params.expectedOwnerPubkey}. Please switch accounts in Phantom and retry.`
3256
- );
3257
- }
3258
- if (!adapter.sendTransaction) {
3259
- throw new Error("Selected Solana wallet does not support sendTransaction.");
3260
- }
3261
- const transaction = await deserializeTransaction(unsignedTxBase64);
3262
- const connection = await defaultConnectionFactory(rpcUrl, commitment);
3263
- const signature = await adapter.sendTransaction(
3264
- transaction,
3265
- connection,
3266
- {
3267
- preflightCommitment: commitment,
3268
- maxRetries: 3
3269
- }
3270
- );
3271
- return { ownerPubkey: publicKey, signature };
3272
- }
3273
- async function confirmApproveSplViaPolling(params) {
3274
- const rpcUrl = params.rpcUrl?.trim();
3275
- if (!rpcUrl) {
3276
- throw new Error("confirmApproveSplViaPolling requires an rpcUrl.");
3277
- }
3278
- const signature = params.signature?.trim();
3279
- if (!signature) {
3280
- throw new Error("confirmApproveSplViaPolling requires a signature.");
3281
- }
3282
- const confirmTimeoutMs = params.confirmTimeoutMs ?? DEFAULT_CONFIRM_TIMEOUT_MS;
3283
- const pollIntervalMs = params.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
3284
- const commitment = params.commitment ?? DEFAULT_COMMITMENT;
3285
- const connection = await defaultConnectionFactory(rpcUrl, commitment);
3286
- const slot = await pollForConfirmation({
3287
- connection,
3288
- signature,
3289
- confirmTimeoutMs,
3290
- pollIntervalMs
3291
- });
3292
- return { signature, slot };
3293
- }
3294
- async function defaultConnectionFactory(rpcUrl, commitment) {
3295
- const { Connection } = await import('@solana/web3.js');
3296
- return new Connection(rpcUrl, commitment);
3297
- }
3298
- async function pollForConfirmation(args) {
3299
- const { connection, signature, confirmTimeoutMs, pollIntervalMs } = args;
3300
- const expiresAt = Date.now() + confirmTimeoutMs;
3301
- while (Date.now() <= expiresAt) {
3302
- const result = await connection.getSignatureStatuses(
3303
- [signature],
3304
- { searchTransactionHistory: true }
3305
- );
3306
- const status = result.value[0];
3307
- if (status?.err) {
3308
- throw new Error(`${APPROVE_SPL_ONCHAIN_FAILURE_PREFIX} ${JSON.stringify(status.err)}`);
3309
- }
3310
- const confirmationStatus = status?.confirmationStatus;
3311
- if (confirmationStatus === "confirmed" || confirmationStatus === "finalized") {
3312
- return status?.slot;
3313
- }
3314
- await sleep(pollIntervalMs);
3315
- }
3316
- throw new Error(APPROVE_SPL_CONFIRMATION_TIMEOUT_MESSAGE);
3317
- }
3318
- function sleep(ms) {
3319
- return new Promise((resolve) => setTimeout(resolve, ms));
3320
- }
3321
-
3322
3380
  // src/walletConnectRuntime.ts
3323
3381
  var PRIMARY_CHAIN_ID = 8453;
3324
3382
  var OPTIONAL_CHAIN_IDS = [1, 42161, 137, 56, 6342, 10143, 999, 84532];
@@ -6263,61 +6321,14 @@ function useAuthorizationOrchestrator(deps) {
6263
6321
  if (cachedBatchSupport == null) {
6264
6322
  cachedBatchSupport = await authExecutor.canBatch();
6265
6323
  }
6266
- const batchSupported = cachedBatchSupport;
6324
+ const batchSupported = false;
6267
6325
  console.info("[blink-sdk][orchestrator] Batch evaluation complete.", {
6268
6326
  ownerSessionId,
6269
6327
  batchSupported,
6270
6328
  actionIds: batchable.map((candidate) => candidate.id),
6271
6329
  actionTypes: batchable.map((candidate) => candidate.type)
6272
6330
  });
6273
- if (batchSupported) {
6274
- const readyBatchable = await waitForBatchableActionsReady({
6275
- apiBaseUrl,
6276
- batchable,
6277
- sessions,
6278
- actionSessionMap
6279
- });
6280
- const batchInputs = readyBatchable.map((candidate) => ({
6281
- action: candidate,
6282
- sessionId: actionSessionMap.get(candidate.id) ?? sessionId
6283
- }));
6284
- const batchWalletConnectRuntimeKey = getWalletConnectRuntimeKeyForAction(
6285
- batchInputs[0]?.action,
6286
- batchInputs[0]?.sessionId ?? ownerSessionId,
6287
- sessions
6288
- );
6289
- const paymasterUrl = `${apiBaseUrl}/v1/paymaster`;
6290
- const batchResult = await authExecutor.executeBatch(batchInputs, {
6291
- paymasterUrl,
6292
- ...batchWalletConnectRuntimeKey ? { walletConnectRuntimeKey: batchWalletConnectRuntimeKey } : {},
6293
- onWalletConnectDisplayUri: options?.onWalletConnectDisplayUri
6294
- });
6295
- for (const { action: batchedAction, result: result2 } of batchResult.actionResults) {
6296
- completedIds.add(batchedAction.id);
6297
- authExecutor.addResult(result2);
6298
- if (isSubmittedApprovePermit2Result(batchedAction, result2)) {
6299
- submittedApprovePermit2ActionIdsRef.current.add(batchedAction.id);
6300
- }
6301
- if (isSubmittedSignPermit2Result(batchedAction, result2)) {
6302
- submittedSignPermit2ActionIdsRef.current.add(batchedAction.id);
6303
- }
6304
- const batchedOwnerSessionId = actionSessionMap.get(batchedAction.id) ?? ownerSessionId;
6305
- const reportedSession2 = await reportActionCompletionWithLogging(
6306
- apiBaseUrl,
6307
- batchedAction,
6308
- batchedOwnerSessionId,
6309
- result2
6310
- );
6311
- updateTrackedSession(sessions, batchedOwnerSessionId, reportedSession2, actionSessionMap);
6312
- }
6313
- mergedPending = await waitForPendingActions({
6314
- apiBaseUrl,
6315
- sessions,
6316
- completedIds,
6317
- actionSessionMap
6318
- });
6319
- continue;
6320
- }
6331
+ if (batchSupported) ;
6321
6332
  }
6322
6333
  const approvePermit2WasSubmitted = action.type === "APPROVE_PERMIT2" && submittedApprovePermit2ActionIdsRef.current.has(action.id);
6323
6334
  const signPermit2WasSubmitted = action.type === "SIGN_PERMIT2" && submittedSignPermit2ActionIdsRef.current.has(action.id);
@@ -6970,6 +6981,7 @@ function useManualTransferSession({
6970
6981
  const completedRef = useRef(/* @__PURE__ */ new Set());
6971
6982
  const premintedFamiliesRef = useRef(/* @__PURE__ */ new Set());
6972
6983
  const inFlightPerTokenRef = useRef(/* @__PURE__ */ new Set());
6984
+ const reportedTargetChainRef = useRef(/* @__PURE__ */ new Map());
6973
6985
  useEffect(() => {
6974
6986
  if (!merchantAuthorization) return;
6975
6987
  let cancelled = false;
@@ -7122,6 +7134,51 @@ function useManualTransferSession({
7122
7134
  }, 2e3);
7123
7135
  return () => window.clearInterval(timer);
7124
7136
  }, [apiBaseUrl, activeSessionId, activeSessionStatus, pollEnabled]);
7137
+ const selectedSourceChainId = selectedOption?.chainId;
7138
+ const sessionRegistrationChainId = session?.source.chainId;
7139
+ useEffect(() => {
7140
+ if (!activeSessionId) return;
7141
+ if (selectedSourceChainId === void 0) return;
7142
+ if (sessionRegistrationChainId === void 0) return;
7143
+ if (!selectedOption) return;
7144
+ if (selectedOption.chainFamily !== "evm") return;
7145
+ if (isSameChainSameTokenSelection(selectedOption, destination)) return;
7146
+ const lastReported = reportedTargetChainRef.current.get(activeSessionId) ?? sessionRegistrationChainId;
7147
+ if (selectedSourceChainId === lastReported) return;
7148
+ reportedTargetChainRef.current.set(activeSessionId, selectedSourceChainId);
7149
+ let cancelled = false;
7150
+ updateManualTransferDepositTargetChain(apiBaseUrl, activeSessionId, selectedSourceChainId).then((updated) => {
7151
+ if (cancelled) return;
7152
+ setSessionsByFamily((prev) => {
7153
+ for (const family of Object.keys(prev)) {
7154
+ if (prev[family]?.sessionId === updated.sessionId) {
7155
+ return { ...prev, [family]: updated };
7156
+ }
7157
+ }
7158
+ return prev;
7159
+ });
7160
+ setPerTokenSessions((prev) => {
7161
+ for (const k of Object.keys(prev)) {
7162
+ if (prev[k]?.sessionId === updated.sessionId) {
7163
+ return { ...prev, [k]: updated };
7164
+ }
7165
+ }
7166
+ return prev;
7167
+ });
7168
+ }).catch(() => {
7169
+ reportedTargetChainRef.current.set(activeSessionId, lastReported);
7170
+ });
7171
+ return () => {
7172
+ cancelled = true;
7173
+ };
7174
+ }, [
7175
+ apiBaseUrl,
7176
+ activeSessionId,
7177
+ selectedSourceChainId,
7178
+ sessionRegistrationChainId,
7179
+ selectedOption,
7180
+ destination
7181
+ ]);
7125
7182
  const completionSignature = useMemo(() => {
7126
7183
  const entries2 = [];
7127
7184
  for (const family of Object.keys(sessionsByFamily)) {
@@ -12555,6 +12612,7 @@ function SelectDepositSourceScreen({
12555
12612
  {
12556
12613
  symbol: opt.symbol,
12557
12614
  chainName: opt.chainName,
12615
+ tokenLogoUri: opt.logoURI,
12558
12616
  balance: opt.balance,
12559
12617
  selected: !hasPendingMobileSelection && isSelected(opt),
12560
12618
  onClick: () => handleAuthorizedPick(opt)
@@ -12566,6 +12624,7 @@ function SelectDepositSourceScreen({
12566
12624
  {
12567
12625
  symbol: opt.symbol,
12568
12626
  chainName: opt.chainName,
12627
+ tokenLogoUri: opt.logoURI,
12569
12628
  balance: opt.balance,
12570
12629
  requiresAuth: true,
12571
12630
  selected: hasPendingMobileSelection ? pendingMobileSelection?.key === tokenOptionKey(opt) : isSelected(opt),
@@ -13603,7 +13662,7 @@ function SelectSourceScreen({
13603
13662
  /* @__PURE__ */ jsx("label", { style: labelStyle5(tokens.textSecondary), children: "Token" }),
13604
13663
  /* @__PURE__ */ jsx("div", { style: optionListStyle, children: tokenChoices.map((token) => {
13605
13664
  const isSelected = token.tokenSymbol === selectedTokenSymbol;
13606
- const logo = token.walletLogoUrl ?? TOKEN_LOGOS[token.tokenSymbol];
13665
+ const logo = token.walletLogoUrl ?? token.logoURI ?? TOKEN_LOGOS[token.tokenSymbol];
13607
13666
  const logoAlt = token.walletLogoUrl ? token.walletName ?? token.tokenSymbol : token.tokenSymbol;
13608
13667
  return /* @__PURE__ */ jsxs(
13609
13668
  "button",
@@ -15200,10 +15259,12 @@ function TokenPickerScreen({
15200
15259
  tokenSymbol: source.token.symbol,
15201
15260
  tokenAddress: source.address,
15202
15261
  balance: visibleBalance,
15203
- status: source.token.status
15262
+ status: source.token.status,
15263
+ logoURI: source.token.logoURI
15204
15264
  });
15205
15265
  }
15206
15266
  }
15267
+ const selectedEntryLogo = selectedTokenSymbol ? entries2.find((e) => e.tokenSymbol === selectedTokenSymbol)?.logoURI ?? TOKEN_LOGOS[selectedTokenSymbol] : void 0;
15207
15268
  const handleSelect = (entry) => {
15208
15269
  if (entry.status === "AUTHORIZED") {
15209
15270
  onSelectAuthorized(entry.walletId, entry.tokenSymbol);
@@ -15230,7 +15291,7 @@ function TokenPickerScreen({
15230
15291
  onClick: onBack,
15231
15292
  style: tokenIconButtonStyle,
15232
15293
  children: [
15233
- /* @__PURE__ */ jsx("div", { style: tokenIconWrapStyle, children: selectedTokenSymbol && TOKEN_LOGOS[selectedTokenSymbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[selectedTokenSymbol], alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
15294
+ /* @__PURE__ */ jsx("div", { style: tokenIconWrapStyle, children: selectedEntryLogo ? /* @__PURE__ */ jsx("img", { src: selectedEntryLogo, alt: selectedTokenSymbol, width: 36, height: 36, style: { borderRadius: "50%" } }) : /* @__PURE__ */ jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", children: [
15234
15295
  /* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "18", fill: "#2DB84B" }),
15235
15296
  /* @__PURE__ */ jsx("text", { x: "18", y: "23", textAnchor: "middle", fontSize: "18", fill: "#fff", fontWeight: "700", children: "$" })
15236
15297
  ] }) }),
@@ -15244,6 +15305,7 @@ function TokenPickerScreen({
15244
15305
  /* @__PURE__ */ jsx("div", { style: tokenListStyle2, children: entries2.map((entry) => {
15245
15306
  const authorized = entry.status === "AUTHORIZED";
15246
15307
  const isSelected = entry.walletId === selectedWalletId && entry.tokenSymbol === selectedTokenSymbol;
15308
+ const entryLogo = entry.logoURI ?? TOKEN_LOGOS[entry.tokenSymbol];
15247
15309
  return /* @__PURE__ */ jsxs(
15248
15310
  "button",
15249
15311
  {
@@ -15251,7 +15313,7 @@ function TokenPickerScreen({
15251
15313
  onClick: () => handleSelect(entry),
15252
15314
  style: tokenRowStyle2(t),
15253
15315
  children: [
15254
- /* @__PURE__ */ jsx("div", { style: tokenIconCircleStyle2(t, !!TOKEN_LOGOS[entry.tokenSymbol]), children: TOKEN_LOGOS[entry.tokenSymbol] ? /* @__PURE__ */ jsx("img", { src: TOKEN_LOGOS[entry.tokenSymbol], alt: entry.tokenSymbol, style: tokenLogoImgStyle2 }) : /* @__PURE__ */ jsx("span", { style: tokenIconTextStyle2(t.textMuted), children: "$" }) }),
15316
+ /* @__PURE__ */ jsx("div", { style: tokenIconCircleStyle2(t, !!entryLogo), children: entryLogo ? /* @__PURE__ */ jsx("img", { src: entryLogo, alt: entry.tokenSymbol, style: tokenLogoImgStyle2 }) : /* @__PURE__ */ jsx("span", { style: tokenIconTextStyle2(t.textMuted), children: "$" }) }),
15255
15317
  /* @__PURE__ */ jsxs("div", { style: tokenInfoStyle2, children: [
15256
15318
  /* @__PURE__ */ jsxs("div", { style: tokenNameRowStyle, children: [
15257
15319
  /* @__PURE__ */ jsx("span", { style: tokenSymbolTextStyle(t.text), children: entry.tokenSymbol }),
@@ -16138,7 +16200,8 @@ function buildDepositScreenProps({
16138
16200
  status: source.token.status,
16139
16201
  tokenAddress: source.address,
16140
16202
  chainId: chain?.commonId ?? void 0,
16141
- accountId: account.id
16203
+ accountId: account.id,
16204
+ logoURI: source.token.logoURI
16142
16205
  });
16143
16206
  }
16144
16207
  }
@@ -16191,6 +16254,7 @@ function buildDepositScreenProps({
16191
16254
  },
16192
16255
  selectedTokenSymbol: selectedSource?.token.symbol,
16193
16256
  selectedChainName: selectedWallet?.chain.name,
16257
+ selectedTokenLogoUri: selectedSource?.token.logoURI,
16194
16258
  selectedWalletId: selectedWallet?.id ?? null,
16195
16259
  selectedTokenStatus,
16196
16260
  onAuthorizeSelectedToken,
@@ -19588,12 +19652,20 @@ function BlinkPaymentInner({
19588
19652
  dispatch,
19589
19653
  orchestrator
19590
19654
  ]);
19655
+ const disconnectWallets = useCallback(async () => {
19656
+ await Promise.allSettled([
19657
+ revokeAndDisconnectActiveWagmiConnector(wagmiConfig),
19658
+ authExecutor.resetWalletConnect().catch(() => {
19659
+ }),
19660
+ disconnectSolanaWallet()
19661
+ ]);
19662
+ }, [authExecutor, wagmiConfig]);
19591
19663
  const handleBackFromSetupDeposit = useCallback(async () => {
19592
19664
  orchestrator.cancelPendingFlow();
19593
19665
  authExecutor.cancelPendingExecution();
19594
19666
  clearScreenErrors();
19595
19667
  if (isDesktop) {
19596
- await revokeAndDisconnectActiveWagmiConnector(wagmiConfig);
19668
+ await disconnectWallets();
19597
19669
  }
19598
19670
  dispatch({ type: "RESTORE_SELECTION" });
19599
19671
  dispatch({ type: "CLEAR_SETUP_DEPOSIT_TOKEN" });
@@ -19601,7 +19673,7 @@ function BlinkPaymentInner({
19601
19673
  dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19602
19674
  dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19603
19675
  dispatch({ type: "SET_USER_INTENT", intent: { step: "wallet-picker", reason: "switch" } });
19604
- }, [authExecutor, clearScreenErrors, orchestrator, dispatch, isDesktop, wagmiConfig]);
19676
+ }, [authExecutor, clearScreenErrors, orchestrator, dispatch, isDesktop, disconnectWallets]);
19605
19677
  const handleAuthorizationRetry = useCallback(() => {
19606
19678
  void (async () => {
19607
19679
  try {
@@ -19646,11 +19718,7 @@ function BlinkPaymentInner({
19646
19718
  dispatch({ type: "DESKTOP_WAIT_CLEARED" });
19647
19719
  dispatch({ type: "SET_STANDARD_DESKTOP_INLINE_OPEN_WALLET", value: false });
19648
19720
  dispatch({ type: "SET_USER_INTENT", intent: { step: "wallet-picker", reason: "switch" } });
19649
- void (async () => {
19650
- await revokeAndDisconnectActiveWagmiConnector(wagmiConfig);
19651
- await authExecutor.resetWalletConnect().catch(() => {
19652
- });
19653
- })();
19721
+ void disconnectWallets();
19654
19722
  },
19655
19723
  onSendManually: () => handleSetPhase({ step: "manual-transfer" }),
19656
19724
  onBackFromSetupDeposit: handleBackFromSetupDeposit,
@@ -19697,7 +19765,7 @@ function BlinkPaymentInner({
19697
19765
  handleConfirmSetupDeposit,
19698
19766
  handleBackFromSetupDeposit,
19699
19767
  handleAuthorizationRetry,
19700
- wagmiConfig
19768
+ disconnectWallets
19701
19769
  ]);
19702
19770
  return /* @__PURE__ */ jsx(EffectiveDepositAmountProvider, { value: effectiveDepositAmount, children: /* @__PURE__ */ jsx(
19703
19771
  ManualTransferSessionProvider,