coinley-pay 0.0.76 → 0.0.78
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/{appKitEVM-gWlDgC4I.js → appKitEVM-C17FPKPo.js} +2 -2
- package/dist/{appKitSolana-CGUDW_KI.js → appKitSolana-AZtdMOls.js} +2 -2
- package/dist/coinley-vanilla.min.js +1474 -1474
- package/dist/{index-eI8nBZJW.js → index-CEBT3A4T.js} +452 -77
- package/dist/index.esm.js +1 -1
- package/dist/index.umd.js +9 -9
- package/package.json +1 -1
|
@@ -28649,7 +28649,16 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28649
28649
|
}
|
|
28650
28650
|
};
|
|
28651
28651
|
const createPayment = async (config) => {
|
|
28652
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
28652
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
28653
|
+
const attemptMeta = (config == null ? void 0 : config.__coinleyAttemptMeta) || null;
|
|
28654
|
+
const attemptStillCurrent = () => {
|
|
28655
|
+
if (!(attemptMeta == null ? void 0 : attemptMeta.isStillCurrent)) return true;
|
|
28656
|
+
try {
|
|
28657
|
+
return !!attemptMeta.isStillCurrent();
|
|
28658
|
+
} catch {
|
|
28659
|
+
return false;
|
|
28660
|
+
}
|
|
28661
|
+
};
|
|
28653
28662
|
try {
|
|
28654
28663
|
setLoading(true);
|
|
28655
28664
|
setError("");
|
|
@@ -28691,22 +28700,37 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28691
28700
|
console.log(" 📈 Coinley Percentage:", (_g = payment.payment) == null ? void 0 : _g.coinleyPercentage, `(${(((_h = payment.payment) == null ? void 0 : _h.coinleyPercentage) || 0) / 100}%)`);
|
|
28692
28701
|
console.log("📊 Contract Address:", (_i = payment.payment) == null ? void 0 : _i.contractAddress);
|
|
28693
28702
|
console.log("📊 Split Params:", (_j = payment.payment) == null ? void 0 : _j.splitParams);
|
|
28703
|
+
console.log("📊 Attempt ID:", (attemptMeta == null ? void 0 : attemptMeta.attemptId) || "(none)");
|
|
28694
28704
|
console.log("📊 =============================================");
|
|
28695
|
-
|
|
28705
|
+
if (!attemptStillCurrent()) {
|
|
28706
|
+
console.log("[PaymentFlow] Dropping stale createPayment response", { attemptId: attemptMeta == null ? void 0 : attemptMeta.attemptId, paymentId: (_k = payment.payment) == null ? void 0 : _k.id });
|
|
28707
|
+
const stale = new Error("Your payment quote changed while you were switching networks or tokens. Please try again.");
|
|
28708
|
+
stale.code = "STALE_ATTEMPT";
|
|
28709
|
+
throw stale;
|
|
28710
|
+
}
|
|
28711
|
+
setPaymentData({
|
|
28712
|
+
...payment.payment,
|
|
28713
|
+
__coinleyAttemptId: (attemptMeta == null ? void 0 : attemptMeta.attemptId) ?? null,
|
|
28714
|
+
__coinleySelectionSnapshot: (attemptMeta == null ? void 0 : attemptMeta.selectionSnapshot) ?? null
|
|
28715
|
+
});
|
|
28696
28716
|
sdkAnalytics.trackPaymentCreated(
|
|
28697
|
-
(
|
|
28717
|
+
(_l = payment.payment) == null ? void 0 : _l.id,
|
|
28698
28718
|
config.amount,
|
|
28699
28719
|
selectedNetwork.shortName,
|
|
28700
28720
|
selectedToken.symbol
|
|
28701
28721
|
);
|
|
28702
28722
|
clarityAnalytics.trackPaymentCreated(
|
|
28703
|
-
(
|
|
28723
|
+
(_m = payment.payment) == null ? void 0 : _m.id,
|
|
28704
28724
|
config.amount,
|
|
28705
28725
|
selectedNetwork.shortName,
|
|
28706
28726
|
selectedToken.symbol
|
|
28707
28727
|
);
|
|
28708
28728
|
setCurrentStep("confirm");
|
|
28709
28729
|
} catch (err) {
|
|
28730
|
+
if ((err == null ? void 0 : err.code) === "STALE_ATTEMPT") {
|
|
28731
|
+
console.log("[PaymentFlow] createPayment aborted — stale attempt");
|
|
28732
|
+
throw err;
|
|
28733
|
+
}
|
|
28710
28734
|
setError(err.message);
|
|
28711
28735
|
sdkAnalytics.trackError("payment_creation_failed", err.message, {
|
|
28712
28736
|
amount: config.amount,
|
|
@@ -28737,7 +28761,16 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28737
28761
|
return supportedChains.includes(chainId);
|
|
28738
28762
|
};
|
|
28739
28763
|
const createDepositPayment = async (config) => {
|
|
28740
|
-
var _a2, _b, _c, _d, _e, _f, _g;
|
|
28764
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
28765
|
+
const attemptMeta = (config == null ? void 0 : config.__coinleyAttemptMeta) || null;
|
|
28766
|
+
const attemptStillCurrent = () => {
|
|
28767
|
+
if (!(attemptMeta == null ? void 0 : attemptMeta.isStillCurrent)) return true;
|
|
28768
|
+
try {
|
|
28769
|
+
return !!attemptMeta.isStillCurrent();
|
|
28770
|
+
} catch {
|
|
28771
|
+
return false;
|
|
28772
|
+
}
|
|
28773
|
+
};
|
|
28741
28774
|
try {
|
|
28742
28775
|
setLoading(true);
|
|
28743
28776
|
setError("");
|
|
@@ -28768,10 +28801,20 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28768
28801
|
}
|
|
28769
28802
|
};
|
|
28770
28803
|
if ((paymentData == null ? void 0 : paymentData.id) && !(paymentData == null ? void 0 : paymentData.isDepositPayment)) {
|
|
28771
|
-
|
|
28772
|
-
|
|
28804
|
+
const existingAttemptId = paymentData.__coinleyAttemptId ?? null;
|
|
28805
|
+
const sameAttempt = !(attemptMeta == null ? void 0 : attemptMeta.attemptId) || !existingAttemptId || existingAttemptId === attemptMeta.attemptId;
|
|
28806
|
+
if (sameAttempt) {
|
|
28807
|
+
depositPayload.existingPaymentId = paymentData.id;
|
|
28808
|
+
console.log("📤 Converting existing payment to deposit:", { debugId, paymentId: paymentData.id, attemptId: attemptMeta == null ? void 0 : attemptMeta.attemptId });
|
|
28809
|
+
} else {
|
|
28810
|
+
console.log("📤 Not reusing existing payment — different attempt", {
|
|
28811
|
+
debugId,
|
|
28812
|
+
existingAttemptId,
|
|
28813
|
+
currentAttemptId: attemptMeta == null ? void 0 : attemptMeta.attemptId
|
|
28814
|
+
});
|
|
28815
|
+
}
|
|
28773
28816
|
}
|
|
28774
|
-
console.log("📤 Creating deposit payment:", { debugId, depositPayload });
|
|
28817
|
+
console.log("📤 Creating deposit payment:", { debugId, attemptId: attemptMeta == null ? void 0 : attemptMeta.attemptId, depositPayload });
|
|
28775
28818
|
const response = await api.current.createDepositPayment(depositPayload);
|
|
28776
28819
|
if (!response.success) {
|
|
28777
28820
|
throw new Error(response.error || "Failed to create deposit payment");
|
|
@@ -28779,22 +28822,34 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28779
28822
|
console.log("📊 ========== DEPOSIT PAYMENT CREATED ==========");
|
|
28780
28823
|
console.log("📊 Payment ID:", (_b = response.payment) == null ? void 0 : _b.id);
|
|
28781
28824
|
console.log("📊 Debug ID:", debugId);
|
|
28825
|
+
console.log("📊 Attempt ID:", (attemptMeta == null ? void 0 : attemptMeta.attemptId) || "(none)");
|
|
28782
28826
|
console.log("📊 Deposit Address:", (_c = response.payment) == null ? void 0 : _c.depositAddress);
|
|
28783
28827
|
console.log("📊 Amount:", (_d = response.payment) == null ? void 0 : _d.amount);
|
|
28784
28828
|
console.log("📊 Expires At:", (_e = response.payment) == null ? void 0 : _e.expiresAt);
|
|
28785
28829
|
console.log("📊 =============================================");
|
|
28830
|
+
if (!attemptStillCurrent()) {
|
|
28831
|
+
console.log("[PaymentFlow] Dropping stale createDepositPayment response", {
|
|
28832
|
+
attemptId: attemptMeta == null ? void 0 : attemptMeta.attemptId,
|
|
28833
|
+
paymentId: (_f = response.payment) == null ? void 0 : _f.id
|
|
28834
|
+
});
|
|
28835
|
+
const stale = new Error("Your payment quote changed while you were switching networks or tokens. Please try again.");
|
|
28836
|
+
stale.code = "STALE_ATTEMPT";
|
|
28837
|
+
throw stale;
|
|
28838
|
+
}
|
|
28786
28839
|
setPaymentData({
|
|
28787
28840
|
...response.payment,
|
|
28788
|
-
isDepositPayment: true
|
|
28841
|
+
isDepositPayment: true,
|
|
28842
|
+
__coinleyAttemptId: (attemptMeta == null ? void 0 : attemptMeta.attemptId) ?? null,
|
|
28843
|
+
__coinleySelectionSnapshot: (attemptMeta == null ? void 0 : attemptMeta.selectionSnapshot) ?? null
|
|
28789
28844
|
});
|
|
28790
28845
|
sdkAnalytics.trackPaymentCreated(
|
|
28791
|
-
(
|
|
28846
|
+
(_g = response.payment) == null ? void 0 : _g.id,
|
|
28792
28847
|
config.amount,
|
|
28793
28848
|
selectedNetwork.shortName,
|
|
28794
28849
|
selectedToken.symbol
|
|
28795
28850
|
);
|
|
28796
28851
|
clarityAnalytics.trackPaymentCreated(
|
|
28797
|
-
(
|
|
28852
|
+
(_h = response.payment) == null ? void 0 : _h.id,
|
|
28798
28853
|
config.amount,
|
|
28799
28854
|
selectedNetwork.shortName,
|
|
28800
28855
|
selectedToken.symbol
|
|
@@ -28802,6 +28857,10 @@ const usePaymentFlow = (apiUrl, apiKey, apiSecret) => {
|
|
|
28802
28857
|
setCurrentStep("confirm");
|
|
28803
28858
|
return response.payment;
|
|
28804
28859
|
} catch (err) {
|
|
28860
|
+
if ((err == null ? void 0 : err.code) === "STALE_ATTEMPT") {
|
|
28861
|
+
console.log("[PaymentFlow] createDepositPayment aborted — stale attempt");
|
|
28862
|
+
throw err;
|
|
28863
|
+
}
|
|
28805
28864
|
setError(err.message);
|
|
28806
28865
|
sdkAnalytics.trackError("deposit_payment_creation_failed", err.message, {
|
|
28807
28866
|
amount: config.amount,
|
|
@@ -46976,7 +47035,7 @@ const WalletSelector = ({
|
|
|
46976
47035
|
try {
|
|
46977
47036
|
setAppKitError(null);
|
|
46978
47037
|
setWalletConnectAddress(solanaAccountState.address);
|
|
46979
|
-
const { createWalletConnectAdapter } = await import("./appKitSolana-
|
|
47038
|
+
const { createWalletConnectAdapter } = await import("./appKitSolana-AZtdMOls.js");
|
|
46980
47039
|
const adapter = createWalletConnectAdapter(solanaAccountState.address);
|
|
46981
47040
|
await solanaWallet.connectWalletConnect(adapter, solanaAccountState.address);
|
|
46982
47041
|
console.log("✅ WalletConnect synced with SDK");
|
|
@@ -47081,7 +47140,7 @@ const WalletSelector = ({
|
|
|
47081
47140
|
setAppKitLoading(true);
|
|
47082
47141
|
setAppKitError(null);
|
|
47083
47142
|
try {
|
|
47084
|
-
const { initializeAppKitEVM, openAppKitModal } = await import("./appKitEVM-
|
|
47143
|
+
const { initializeAppKitEVM, openAppKitModal } = await import("./appKitEVM-C17FPKPo.js");
|
|
47085
47144
|
await initializeAppKitEVM(wagmiConfig);
|
|
47086
47145
|
await openAppKitModal();
|
|
47087
47146
|
} catch (error) {
|
|
@@ -47101,7 +47160,7 @@ const WalletSelector = ({
|
|
|
47101
47160
|
setAppKitError(null);
|
|
47102
47161
|
try {
|
|
47103
47162
|
console.log("📦 Loading AppKit Solana module...");
|
|
47104
|
-
const { initializeAppKitSolana } = await import("./appKitSolana-
|
|
47163
|
+
const { initializeAppKitSolana } = await import("./appKitSolana-AZtdMOls.js");
|
|
47105
47164
|
console.log("✅ Module loaded, initializing...");
|
|
47106
47165
|
const modal = await initializeAppKitSolana(solanaWallet);
|
|
47107
47166
|
console.log("✅ AppKit Solana initialized successfully");
|
|
@@ -47379,8 +47438,17 @@ const useBridge = () => {
|
|
|
47379
47438
|
return [];
|
|
47380
47439
|
}
|
|
47381
47440
|
}, []);
|
|
47382
|
-
const getBridgeQuote = useCallback(async (originChainId, destChainId, originTokenAddress, originTokenSymbol, originTokenDecimals, destTokenAddress, destTokenSymbol, amount, recipient, _originBridgeTokens, _destBridgeTokens, user, debugId = createDebugId()) => {
|
|
47441
|
+
const getBridgeQuote = useCallback(async (originChainId, destChainId, originTokenAddress, originTokenSymbol, originTokenDecimals, destTokenAddress, destTokenSymbol, amount, recipient, _originBridgeTokens, _destBridgeTokens, user, debugId = createDebugId(), attemptMeta = null) => {
|
|
47383
47442
|
var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
47443
|
+
const attemptId = (attemptMeta == null ? void 0 : attemptMeta.attemptId) ?? null;
|
|
47444
|
+
const isStillCurrent = () => {
|
|
47445
|
+
if (!(attemptMeta == null ? void 0 : attemptMeta.isStillCurrent)) return true;
|
|
47446
|
+
try {
|
|
47447
|
+
return !!attemptMeta.isStillCurrent();
|
|
47448
|
+
} catch {
|
|
47449
|
+
return false;
|
|
47450
|
+
}
|
|
47451
|
+
};
|
|
47384
47452
|
setBridgeStatus("quoting");
|
|
47385
47453
|
setBridgeError(null);
|
|
47386
47454
|
try {
|
|
@@ -47464,10 +47532,13 @@ const useBridge = () => {
|
|
|
47464
47532
|
effectiveRecipient: extractQuoteRecipient(quote),
|
|
47465
47533
|
// Li.Fi provides transactionRequest directly
|
|
47466
47534
|
transactionRequest: quote.transactionRequest,
|
|
47467
|
-
approvalAddress: estimate.approvalAddress
|
|
47535
|
+
approvalAddress: estimate.approvalAddress,
|
|
47536
|
+
attemptId,
|
|
47537
|
+
selectionSnapshot: (attemptMeta == null ? void 0 : attemptMeta.selectionSnapshot) ?? null
|
|
47468
47538
|
};
|
|
47469
47539
|
console.log("[LiFi] Quote response:", {
|
|
47470
47540
|
debugId,
|
|
47541
|
+
attemptId,
|
|
47471
47542
|
tool: quote.tool,
|
|
47472
47543
|
requestedRecipient: parsedQuote.requestedRecipient,
|
|
47473
47544
|
effectiveRecipient: parsedQuote.effectiveRecipient,
|
|
@@ -47484,11 +47555,20 @@ const useBridge = () => {
|
|
|
47484
47555
|
hasValue: quote.transactionRequest.value !== void 0
|
|
47485
47556
|
} : null
|
|
47486
47557
|
});
|
|
47558
|
+
if (!isStillCurrent()) {
|
|
47559
|
+
console.log("[LiFi] Dropping stale quote result — attempt no longer current", { debugId, attemptId });
|
|
47560
|
+
return parsedQuote;
|
|
47561
|
+
}
|
|
47487
47562
|
setBridgeQuote(parsedQuote);
|
|
47488
47563
|
setBridgeStatus("idle");
|
|
47489
47564
|
return parsedQuote;
|
|
47490
47565
|
} catch (error) {
|
|
47491
|
-
|
|
47566
|
+
const stillCurrent = isStillCurrent();
|
|
47567
|
+
console.warn("[LiFi] Quote failed:", error.message, { debugId, attemptId, stillCurrent });
|
|
47568
|
+
if (!stillCurrent) {
|
|
47569
|
+
console.log("[LiFi] Ignoring stale quote error");
|
|
47570
|
+
return null;
|
|
47571
|
+
}
|
|
47492
47572
|
setBridgeQuote(null);
|
|
47493
47573
|
setBridgeError(error.message);
|
|
47494
47574
|
setBridgeStatus("error");
|
|
@@ -47830,7 +47910,34 @@ const TOKEN_LIST_TTL = 10 * 60 * 1e3;
|
|
|
47830
47910
|
const WALLET_TOKEN_CACHE_TTL_MS = 30 * 1e3;
|
|
47831
47911
|
const WEAK_WALLET_TOKEN_CACHE_TTL_MS = 5 * 1e3;
|
|
47832
47912
|
const EMPTY_WALLET_TOKEN_CACHE_TTL_MS = 3 * 1e3;
|
|
47913
|
+
const EMPTY_CATALOG_CACHE_TTL = 60 * 1e3;
|
|
47833
47914
|
const EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
47915
|
+
const FETCH_RETRY_DELAY_MS = 1e3;
|
|
47916
|
+
const fetchRpcWithRetry = async (chainSlug, method, params, { timeout = 1e4, retryDelay = FETCH_RETRY_DELAY_MS, label = method }) => {
|
|
47917
|
+
const doFetch = (t) => fetch(`https://${chainSlug}.g.alchemy.com/v2/${ALCHEMY_API_KEY_PRIMARY$1}`, {
|
|
47918
|
+
method: "POST",
|
|
47919
|
+
headers: { "Content-Type": "application/json" },
|
|
47920
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
|
|
47921
|
+
signal: AbortSignal.timeout(t)
|
|
47922
|
+
}).then((r) => {
|
|
47923
|
+
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
47924
|
+
return r.json();
|
|
47925
|
+
});
|
|
47926
|
+
try {
|
|
47927
|
+
return { data: await doFetch(timeout), ok: true, retried: false };
|
|
47928
|
+
} catch (firstErr) {
|
|
47929
|
+
console.warn(`[WalletTokens] ${label} attempt 1 failed: ${firstErr.message}`);
|
|
47930
|
+
await new Promise((r) => setTimeout(r, retryDelay));
|
|
47931
|
+
const retryTimeout = Math.round(timeout * 1.5);
|
|
47932
|
+
try {
|
|
47933
|
+
console.log(`[WalletTokens] ${label} retrying (timeout=${retryTimeout}ms)`);
|
|
47934
|
+
return { data: await doFetch(retryTimeout), ok: true, retried: true };
|
|
47935
|
+
} catch (retryErr) {
|
|
47936
|
+
console.warn(`[WalletTokens] ${label} retry failed: ${retryErr.message}`);
|
|
47937
|
+
return { data: null, ok: false, retried: true, error: retryErr.message };
|
|
47938
|
+
}
|
|
47939
|
+
}
|
|
47940
|
+
};
|
|
47834
47941
|
const formatBalance = (balance) => {
|
|
47835
47942
|
if (balance > 1e6) return `${(balance / 1e6).toFixed(1)}M`;
|
|
47836
47943
|
if (balance > 1e3) return `${(balance / 1e3).toFixed(1)}K`;
|
|
@@ -47904,9 +48011,11 @@ const useWalletTokens = () => {
|
|
|
47904
48011
|
return fallbackListCache.current[cacheKey];
|
|
47905
48012
|
}
|
|
47906
48013
|
const lookup2 = {};
|
|
48014
|
+
let fetchOk = false;
|
|
47907
48015
|
try {
|
|
47908
48016
|
const uniRes = await fetch(UNISWAP_TOKEN_LIST_URL, { signal: AbortSignal.timeout(1e4) });
|
|
47909
48017
|
const uniData = await uniRes.json();
|
|
48018
|
+
fetchOk = true;
|
|
47910
48019
|
for (const token of uniData.tokens || []) {
|
|
47911
48020
|
if (token.chainId !== chainId) continue;
|
|
47912
48021
|
lookup2[`${token.chainId}:${token.address.toLowerCase()}`] = {
|
|
@@ -47928,6 +48037,7 @@ const useWalletTokens = () => {
|
|
|
47928
48037
|
signal: AbortSignal.timeout(1e4)
|
|
47929
48038
|
});
|
|
47930
48039
|
const cgData = await cgRes.json();
|
|
48040
|
+
fetchOk = true;
|
|
47931
48041
|
for (const token of cgData.tokens || []) {
|
|
47932
48042
|
const key = `${token.chainId}:${token.address.toLowerCase()}`;
|
|
47933
48043
|
if (!lookup2[key]) {
|
|
@@ -47945,9 +48055,15 @@ const useWalletTokens = () => {
|
|
|
47945
48055
|
} catch (error) {
|
|
47946
48056
|
console.warn("[WalletTokens] CoinGecko list fetch failed:", error.message);
|
|
47947
48057
|
}
|
|
47948
|
-
|
|
47949
|
-
|
|
47950
|
-
|
|
48058
|
+
const fallbackCount = Object.keys(lookup2).length;
|
|
48059
|
+
if (fallbackCount > 0) {
|
|
48060
|
+
fallbackListCache.current[cacheKey] = lookup2;
|
|
48061
|
+
fallbackListCacheTime.current[cacheKey] = Date.now();
|
|
48062
|
+
} else if (fetchOk) {
|
|
48063
|
+
fallbackListCache.current[cacheKey] = lookup2;
|
|
48064
|
+
fallbackListCacheTime.current[cacheKey] = Date.now() - TOKEN_LIST_TTL + EMPTY_CATALOG_CACHE_TTL;
|
|
48065
|
+
}
|
|
48066
|
+
console.log(`[WalletTokens] Loaded ${fallbackCount} fallback tokens for chain ${chainId} (fetchOk=${fetchOk})`);
|
|
47951
48067
|
return lookup2;
|
|
47952
48068
|
}, []);
|
|
47953
48069
|
const getLiFiTokenCatalog = useCallback(async (chainId, chainType = "EVM") => {
|
|
@@ -47957,6 +48073,7 @@ const useWalletTokens = () => {
|
|
|
47957
48073
|
return lifiTokenCache.current[cacheKey];
|
|
47958
48074
|
}
|
|
47959
48075
|
const lookup2 = {};
|
|
48076
|
+
let fetchOk = false;
|
|
47960
48077
|
try {
|
|
47961
48078
|
const params = new URLSearchParams({
|
|
47962
48079
|
chains: chainId.toString(),
|
|
@@ -47974,6 +48091,7 @@ const useWalletTokens = () => {
|
|
|
47974
48091
|
}
|
|
47975
48092
|
const data = await response.json();
|
|
47976
48093
|
const chainTokens = getLiFiChainTokens(data, chainId);
|
|
48094
|
+
fetchOk = true;
|
|
47977
48095
|
for (const token of chainTokens) {
|
|
47978
48096
|
const key = chainType === "SVM" ? token.address : (_a2 = token.address) == null ? void 0 : _a2.toLowerCase();
|
|
47979
48097
|
if (!key) continue;
|
|
@@ -47982,9 +48100,15 @@ const useWalletTokens = () => {
|
|
|
47982
48100
|
} catch (error) {
|
|
47983
48101
|
console.warn(`[WalletTokens] Li.Fi catalog fetch failed for chain ${chainId}:`, error.message);
|
|
47984
48102
|
}
|
|
47985
|
-
|
|
47986
|
-
|
|
47987
|
-
|
|
48103
|
+
const lifiCount = Object.keys(lookup2).length;
|
|
48104
|
+
if (lifiCount > 0) {
|
|
48105
|
+
lifiTokenCache.current[cacheKey] = lookup2;
|
|
48106
|
+
lifiTokenCacheTime.current[cacheKey] = Date.now();
|
|
48107
|
+
} else if (fetchOk) {
|
|
48108
|
+
lifiTokenCache.current[cacheKey] = lookup2;
|
|
48109
|
+
lifiTokenCacheTime.current[cacheKey] = Date.now() - TOKEN_LIST_TTL + EMPTY_CATALOG_CACHE_TTL;
|
|
48110
|
+
}
|
|
48111
|
+
console.log(`[WalletTokens] Loaded ${lifiCount} Li.Fi tokens for chain ${chainId} (fetchOk=${fetchOk})`);
|
|
47988
48112
|
return lookup2;
|
|
47989
48113
|
}, []);
|
|
47990
48114
|
const fetchWalletTokens = useCallback(async (walletAddress, chainId, paymentAmount = 0) => {
|
|
@@ -48012,32 +48136,42 @@ const useWalletTokens = () => {
|
|
|
48012
48136
|
setLoadingTokens(true);
|
|
48013
48137
|
setTokenError(null);
|
|
48014
48138
|
try {
|
|
48015
|
-
const [
|
|
48016
|
-
getLiFiTokenCatalog(numericChainId, "EVM")
|
|
48017
|
-
|
|
48018
|
-
|
|
48019
|
-
|
|
48020
|
-
|
|
48021
|
-
|
|
48022
|
-
|
|
48023
|
-
|
|
48024
|
-
|
|
48025
|
-
|
|
48026
|
-
|
|
48027
|
-
|
|
48028
|
-
|
|
48029
|
-
|
|
48030
|
-
|
|
48031
|
-
|
|
48032
|
-
|
|
48033
|
-
|
|
48034
|
-
|
|
48035
|
-
|
|
48036
|
-
|
|
48037
|
-
|
|
48038
|
-
signal: AbortSignal.timeout(5e3)
|
|
48039
|
-
}).then(async (r) => r.ok ? r.json() : { result: "0x0" })
|
|
48139
|
+
const [lifiResult, fallbackResult, balanceResult, nativeResult] = await Promise.all([
|
|
48140
|
+
getLiFiTokenCatalog(numericChainId, "EVM").then(
|
|
48141
|
+
(data) => ({ data, ok: true }),
|
|
48142
|
+
(err) => {
|
|
48143
|
+
console.warn(`[WalletTokens] Li.Fi catalog failed (chain ${numericChainId}): ${err.message}`);
|
|
48144
|
+
return { data: {}, ok: false };
|
|
48145
|
+
}
|
|
48146
|
+
),
|
|
48147
|
+
getFallbackTokenList(numericChainId).then(
|
|
48148
|
+
(data) => ({ data, ok: true }),
|
|
48149
|
+
(err) => {
|
|
48150
|
+
console.warn(`[WalletTokens] Fallback list failed (chain ${numericChainId}): ${err.message}`);
|
|
48151
|
+
return { data: {}, ok: false };
|
|
48152
|
+
}
|
|
48153
|
+
),
|
|
48154
|
+
fetchRpcWithRetry(chainSlug, "alchemy_getTokenBalances", [walletAddress, "erc20"], {
|
|
48155
|
+
timeout: 1e4,
|
|
48156
|
+
label: `ERC20 balances (${chainSlug})`
|
|
48157
|
+
}),
|
|
48158
|
+
fetchRpcWithRetry(chainSlug, "eth_getBalance", [walletAddress, "latest"], {
|
|
48159
|
+
timeout: 5e3,
|
|
48160
|
+
label: `Native balance (${chainSlug})`
|
|
48161
|
+
})
|
|
48040
48162
|
]);
|
|
48163
|
+
const lifiCatalog = lifiResult.data;
|
|
48164
|
+
const fallbackList = fallbackResult.data;
|
|
48165
|
+
const balancesRes = balanceResult.ok ? balanceResult.data : { result: { tokenBalances: [] } };
|
|
48166
|
+
const nativeRes = nativeResult.ok ? nativeResult.data : { result: "0x0" };
|
|
48167
|
+
let resultQuality = "complete";
|
|
48168
|
+
if (!balanceResult.ok && !nativeResult.ok) resultQuality = "failed";
|
|
48169
|
+
else if (!balanceResult.ok || !nativeResult.ok) resultQuality = "partial";
|
|
48170
|
+
if (resultQuality !== "complete") {
|
|
48171
|
+
console.warn(
|
|
48172
|
+
`[WalletTokens] Fetch quality: ${resultQuality} — balances=${balanceResult.ok ? balanceResult.retried ? "ok(retried)" : "ok" : "FAILED"}, native=${nativeResult.ok ? nativeResult.retried ? "ok(retried)" : "ok" : "FAILED"} (chain ${numericChainId})`
|
|
48173
|
+
);
|
|
48174
|
+
}
|
|
48041
48175
|
const tokens = [];
|
|
48042
48176
|
const tokenBalances = ((_a2 = balancesRes.result) == null ? void 0 : _a2.tokenBalances) || [];
|
|
48043
48177
|
const unresolvedBalances = [];
|
|
@@ -48072,6 +48206,7 @@ const useWalletTokens = () => {
|
|
|
48072
48206
|
}
|
|
48073
48207
|
if (unresolvedBalances.length > 0) {
|
|
48074
48208
|
console.log(`[WalletTokens] ${unresolvedBalances.length} tokens missing metadata, fetching from Alchemy`);
|
|
48209
|
+
let metadataFetchFailures = 0;
|
|
48075
48210
|
const metadataResults = await Promise.all(
|
|
48076
48211
|
unresolvedBalances.map(async ({ contractAddress, rawBalance }) => {
|
|
48077
48212
|
try {
|
|
@@ -48103,6 +48238,7 @@ const useWalletTokens = () => {
|
|
|
48103
48238
|
extra: { isUnverified: true }
|
|
48104
48239
|
});
|
|
48105
48240
|
} catch {
|
|
48241
|
+
metadataFetchFailures++;
|
|
48106
48242
|
return null;
|
|
48107
48243
|
}
|
|
48108
48244
|
})
|
|
@@ -48112,6 +48248,12 @@ const useWalletTokens = () => {
|
|
|
48112
48248
|
console.log(`[WalletTokens] Recovered ${resolved.length} tokens via alchemy_getTokenMetadata`);
|
|
48113
48249
|
tokens.push(...resolved);
|
|
48114
48250
|
}
|
|
48251
|
+
if (metadataFetchFailures > 0) {
|
|
48252
|
+
console.warn(
|
|
48253
|
+
`[WalletTokens] ${metadataFetchFailures}/${unresolvedBalances.length} metadata fetches failed (chain ${numericChainId}) — downgrading quality from ${resultQuality}`
|
|
48254
|
+
);
|
|
48255
|
+
if (resultQuality === "complete") resultQuality = "partial";
|
|
48256
|
+
}
|
|
48115
48257
|
}
|
|
48116
48258
|
const nativeBalance = Number(BigInt(nativeRes.result || "0")) / 1e18;
|
|
48117
48259
|
if (nativeBalance > 1e-4) {
|
|
@@ -48250,18 +48392,33 @@ const useWalletTokens = () => {
|
|
|
48250
48392
|
const missingUsdCount = resolvedTokens.filter(
|
|
48251
48393
|
(token) => !token.isStablecoin && token.usdValue === void 0
|
|
48252
48394
|
).length;
|
|
48253
|
-
|
|
48254
|
-
|
|
48255
|
-
|
|
48395
|
+
if (resultQuality === "failed" && resolvedTokens.length === 0) {
|
|
48396
|
+
console.warn(`[WalletTokens] Result: FAILED with 0 tokens — not caching (chain ${numericChainId})`);
|
|
48397
|
+
setTokenError("Token discovery timed out — reselect network to retry");
|
|
48398
|
+
setWalletTokens([]);
|
|
48399
|
+
return [];
|
|
48400
|
+
}
|
|
48401
|
+
let cacheTtl;
|
|
48402
|
+
if (resolvedTokens.length === 0) {
|
|
48403
|
+
cacheTtl = EMPTY_WALLET_TOKEN_CACHE_TTL_MS;
|
|
48404
|
+
} else if (resultQuality === "partial" || missingUsdCount > 0) {
|
|
48405
|
+
cacheTtl = WEAK_WALLET_TOKEN_CACHE_TTL_MS;
|
|
48406
|
+
} else {
|
|
48407
|
+
cacheTtl = WALLET_TOKEN_CACHE_TTL_MS;
|
|
48408
|
+
}
|
|
48409
|
+
console.log(
|
|
48410
|
+
`[WalletTokens] Result: ${resolvedTokens.length} tokens, quality=${resultQuality}, priced=${resolvedTokens.length - missingUsdCount}/${resolvedTokens.length}, cacheTTL=${cacheTtl}ms (chain ${numericChainId}, payment: $${paymentAmount})`
|
|
48411
|
+
);
|
|
48256
48412
|
balanceCache.current[cacheKey] = {
|
|
48257
48413
|
tokens: resolvedTokens,
|
|
48258
48414
|
time: Date.now(),
|
|
48259
48415
|
ttl: cacheTtl
|
|
48260
48416
|
};
|
|
48261
48417
|
setWalletTokens(resolvedTokens);
|
|
48418
|
+
setTokenError(null);
|
|
48262
48419
|
return resolvedTokens;
|
|
48263
48420
|
} catch (error) {
|
|
48264
|
-
console.
|
|
48421
|
+
console.error("[WalletTokens] Unexpected error in token processing:", error.message, error.stack);
|
|
48265
48422
|
setTokenError(error.message);
|
|
48266
48423
|
setWalletTokens([]);
|
|
48267
48424
|
return [];
|
|
@@ -48290,8 +48447,9 @@ const useWalletTokens = () => {
|
|
|
48290
48447
|
}).then((r) => r.json());
|
|
48291
48448
|
const balance = BigInt(res.result || "0x0");
|
|
48292
48449
|
return { chainId: numericId, hasBalance: balance > 0n };
|
|
48293
|
-
} catch {
|
|
48294
|
-
|
|
48450
|
+
} catch (err) {
|
|
48451
|
+
console.warn(`[WalletTokens] Chain ${numericId} (${slug}) balance check failed: ${err.message}`);
|
|
48452
|
+
return { chainId: numericId, hasBalance: true };
|
|
48295
48453
|
}
|
|
48296
48454
|
})
|
|
48297
48455
|
);
|
|
@@ -48659,7 +48817,7 @@ const deepLinkUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defin
|
|
|
48659
48817
|
isInDAppBrowser,
|
|
48660
48818
|
openCurrentPageInWallet
|
|
48661
48819
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
48662
|
-
const CHECKOUT_BUILD = "checkout-2026-04-
|
|
48820
|
+
const CHECKOUT_BUILD = "checkout-2026-04-10a-token-discovery-retry-fix";
|
|
48663
48821
|
const normalizeEvmAddress = (value) => {
|
|
48664
48822
|
if (typeof value !== "string") return null;
|
|
48665
48823
|
const trimmed = value.trim();
|
|
@@ -48928,6 +49086,71 @@ const CoinleyPaymentInternal = ({
|
|
|
48928
49086
|
const hasCommittedTransaction = Boolean(
|
|
48929
49087
|
currentTransactionHash || (solanaTransaction == null ? void 0 : solanaTransaction.txSignature) || (paymentData == null ? void 0 : paymentData.transactionHash)
|
|
48930
49088
|
);
|
|
49089
|
+
const activeAttemptRef = useRef(null);
|
|
49090
|
+
const [retryEpoch, setRetryEpoch] = useState(0);
|
|
49091
|
+
const buildSelectionSnapshot = (networkArg = selectedNetwork, tokenArg = selectedToken, addressArg = address, solanaPubkeyArg = solanaWallet == null ? void 0 : solanaWallet.publicKey) => ({
|
|
49092
|
+
networkId: (networkArg == null ? void 0 : networkArg.id) ?? null,
|
|
49093
|
+
chainId: (networkArg == null ? void 0 : networkArg.chainId) ?? null,
|
|
49094
|
+
networkShortName: (networkArg == null ? void 0 : networkArg.shortName) ?? null,
|
|
49095
|
+
tokenId: (tokenArg == null ? void 0 : tokenArg.id) ?? null,
|
|
49096
|
+
tokenSymbol: (tokenArg == null ? void 0 : tokenArg.symbol) ?? null,
|
|
49097
|
+
tokenContract: (tokenArg == null ? void 0 : tokenArg.contractAddress) ?? null,
|
|
49098
|
+
walletAddress: addressArg || solanaPubkeyArg || null,
|
|
49099
|
+
isSwap: !!(tokenArg == null ? void 0 : tokenArg.isSwapToken),
|
|
49100
|
+
isBridge: !!(networkArg == null ? void 0 : networkArg.isBridgeNetwork)
|
|
49101
|
+
});
|
|
49102
|
+
const createNewAttempt = (reason, overrides = {}) => {
|
|
49103
|
+
const snapshot2 = overrides.snapshot || buildSelectionSnapshot(
|
|
49104
|
+
overrides.network,
|
|
49105
|
+
overrides.token,
|
|
49106
|
+
overrides.address,
|
|
49107
|
+
overrides.solanaPubkey
|
|
49108
|
+
);
|
|
49109
|
+
const attempt = {
|
|
49110
|
+
id: `attempt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
49111
|
+
reason,
|
|
49112
|
+
createdAt: Date.now(),
|
|
49113
|
+
snapshot: snapshot2
|
|
49114
|
+
};
|
|
49115
|
+
activeAttemptRef.current = attempt;
|
|
49116
|
+
console.log("[Attempt] created", { id: attempt.id, reason, snapshot: snapshot2 });
|
|
49117
|
+
return attempt;
|
|
49118
|
+
};
|
|
49119
|
+
const invalidateCurrentAttempt = (reason) => {
|
|
49120
|
+
const prev = activeAttemptRef.current;
|
|
49121
|
+
if (prev) {
|
|
49122
|
+
console.log("[Attempt] invalidated", { id: prev.id, reason });
|
|
49123
|
+
}
|
|
49124
|
+
activeAttemptRef.current = null;
|
|
49125
|
+
};
|
|
49126
|
+
const normalizeWalletAddress = (value) => typeof value === "string" ? value.trim().toLowerCase() : null;
|
|
49127
|
+
const snapshotsMatch = (a, b) => {
|
|
49128
|
+
if (!a || !b) return false;
|
|
49129
|
+
return a.chainId === b.chainId && a.networkShortName === b.networkShortName && a.tokenSymbol === b.tokenSymbol && a.tokenContract === b.tokenContract && a.isSwap === b.isSwap && a.isBridge === b.isBridge && normalizeWalletAddress(a.walletAddress) === normalizeWalletAddress(b.walletAddress);
|
|
49130
|
+
};
|
|
49131
|
+
const buildAttemptMeta = (attempt) => {
|
|
49132
|
+
if (!attempt) return null;
|
|
49133
|
+
const attemptId = attempt.id;
|
|
49134
|
+
return {
|
|
49135
|
+
attemptId,
|
|
49136
|
+
selectionSnapshot: attempt.snapshot,
|
|
49137
|
+
isStillCurrent: () => {
|
|
49138
|
+
var _a3;
|
|
49139
|
+
return ((_a3 = activeAttemptRef.current) == null ? void 0 : _a3.id) === attemptId;
|
|
49140
|
+
}
|
|
49141
|
+
};
|
|
49142
|
+
};
|
|
49143
|
+
const STALE_ATTEMPT_MESSAGE = "Your payment quote changed while you were switching networks or tokens. Please try again.";
|
|
49144
|
+
const handleHardFailure = (reason, { swapBridgeFlow = false } = {}) => {
|
|
49145
|
+
var _a3;
|
|
49146
|
+
invalidateCurrentAttempt(reason);
|
|
49147
|
+
(_a3 = transactionHandling.resetTransaction) == null ? void 0 : _a3.call(transactionHandling);
|
|
49148
|
+
if (swapBridgeFlow) {
|
|
49149
|
+
setPaymentData(null);
|
|
49150
|
+
relayBridge.resetBridge();
|
|
49151
|
+
setRetryEpoch((epoch) => epoch + 1);
|
|
49152
|
+
}
|
|
49153
|
+
};
|
|
48931
49154
|
useEffect(() => {
|
|
48932
49155
|
if (paymentData && selectedToken && selectedNetwork) {
|
|
48933
49156
|
generateQRCode(paymentData, selectedToken, selectedNetwork, preferredWallet);
|
|
@@ -49146,7 +49369,8 @@ const CoinleyPaymentInternal = ({
|
|
|
49146
49369
|
const timeout = setTimeout(() => {
|
|
49147
49370
|
setError("Transaction timed out. Please try again.");
|
|
49148
49371
|
setCurrentStep(PAYMENT_STEPS.CONFIRM);
|
|
49149
|
-
|
|
49372
|
+
const wasSwapBridgeFlow = !!((selectedToken == null ? void 0 : selectedToken.isSwapToken) || (selectedNetwork == null ? void 0 : selectedNetwork.isBridgeNetwork));
|
|
49373
|
+
handleHardFailure("transaction-timeout", { swapBridgeFlow: wasSwapBridgeFlow });
|
|
49150
49374
|
}, 12e4);
|
|
49151
49375
|
return () => clearTimeout(timeout);
|
|
49152
49376
|
}
|
|
@@ -49300,6 +49524,7 @@ const CoinleyPaymentInternal = ({
|
|
|
49300
49524
|
}, [paymentData == null ? void 0 : paymentData.id, activeTab, currentStep, verifyingPayment, paymentType, selectedNetwork, selectedToken, onSuccess, paymentFlow.api]);
|
|
49301
49525
|
const resetAllTransactionState = async () => {
|
|
49302
49526
|
var _a3;
|
|
49527
|
+
invalidateCurrentAttempt("reset-all-transaction-state");
|
|
49303
49528
|
transactionHandling.resetTransaction();
|
|
49304
49529
|
(_a3 = solanaTransaction.resetTransaction) == null ? void 0 : _a3.call(solanaTransaction);
|
|
49305
49530
|
relayBridge.resetBridge();
|
|
@@ -49488,6 +49713,13 @@ const CoinleyPaymentInternal = ({
|
|
|
49488
49713
|
}
|
|
49489
49714
|
const amount = paymentAmount || parseFloat(config == null ? void 0 : config.amount) || 0;
|
|
49490
49715
|
if (amount <= 0) return;
|
|
49716
|
+
let attempt = activeAttemptRef.current;
|
|
49717
|
+
if (!attempt || !snapshotsMatch(attempt.snapshot, buildSelectionSnapshot())) {
|
|
49718
|
+
attempt = createNewAttempt("quote-effect", {
|
|
49719
|
+
snapshot: buildSelectionSnapshot()
|
|
49720
|
+
});
|
|
49721
|
+
}
|
|
49722
|
+
const attemptMeta = buildAttemptMeta(attempt);
|
|
49491
49723
|
if (isSwap && !isBridge) {
|
|
49492
49724
|
const DEPOSIT_SUPPORTED_CHAINS = [8453, 56, 42161, 137, 10, 43114, 143];
|
|
49493
49725
|
const isSolanaSwap = (selectedNetwork == null ? void 0 : selectedNetwork.shortName) === "solana" || (selectedNetwork == null ? void 0 : selectedNetwork.chainType) === "solana";
|
|
@@ -49547,8 +49779,12 @@ const CoinleyPaymentInternal = ({
|
|
|
49547
49779
|
// recipient (EVM address for cross-VM)
|
|
49548
49780
|
null,
|
|
49549
49781
|
null,
|
|
49550
|
-
quoteUser
|
|
49782
|
+
quoteUser,
|
|
49551
49783
|
// user/signer (Solana address for cross-VM)
|
|
49784
|
+
void 0,
|
|
49785
|
+
// debugId (let hook generate)
|
|
49786
|
+
attemptMeta
|
|
49787
|
+
// attempt identity for stale-result drop
|
|
49552
49788
|
);
|
|
49553
49789
|
} else if (isBridge) {
|
|
49554
49790
|
const destNetwork = selectedNetwork.bridgeDestination;
|
|
@@ -49567,7 +49803,12 @@ const CoinleyPaymentInternal = ({
|
|
|
49567
49803
|
amount.toString(),
|
|
49568
49804
|
address,
|
|
49569
49805
|
selectedNetwork.bridgeTokens,
|
|
49570
|
-
destNetwork.bridgeTokens
|
|
49806
|
+
destNetwork.bridgeTokens,
|
|
49807
|
+
void 0,
|
|
49808
|
+
// user
|
|
49809
|
+
void 0,
|
|
49810
|
+
// debugId
|
|
49811
|
+
attemptMeta
|
|
49571
49812
|
);
|
|
49572
49813
|
} else {
|
|
49573
49814
|
relayBridge.getBridgeQuote(
|
|
@@ -49583,11 +49824,16 @@ const CoinleyPaymentInternal = ({
|
|
|
49583
49824
|
amount.toString(),
|
|
49584
49825
|
address,
|
|
49585
49826
|
selectedNetwork.bridgeTokens,
|
|
49586
|
-
destNetwork.bridgeTokens
|
|
49827
|
+
destNetwork.bridgeTokens,
|
|
49828
|
+
void 0,
|
|
49829
|
+
// user
|
|
49830
|
+
void 0,
|
|
49831
|
+
// debugId
|
|
49832
|
+
attemptMeta
|
|
49587
49833
|
);
|
|
49588
49834
|
}
|
|
49589
49835
|
}
|
|
49590
|
-
}, [selectedNetwork == null ? void 0 : selectedNetwork.id, selectedToken == null ? void 0 : selectedToken.id, address, paymentAmount]);
|
|
49836
|
+
}, [selectedNetwork == null ? void 0 : selectedNetwork.id, selectedToken == null ? void 0 : selectedToken.id, address, solanaWallet == null ? void 0 : solanaWallet.publicKey, paymentAmount, retryEpoch]);
|
|
49591
49837
|
useEffect(() => {
|
|
49592
49838
|
const requiresRouteValidation = (selectedToken == null ? void 0 : selectedToken.isSwapToken) || (selectedNetwork == null ? void 0 : selectedNetwork.isBridgeNetwork);
|
|
49593
49839
|
if (!requiresRouteValidation || !(selectedToken == null ? void 0 : selectedToken.id) || relayBridge.bridgeStatus === "quoting") {
|
|
@@ -49617,11 +49863,25 @@ const CoinleyPaymentInternal = ({
|
|
|
49617
49863
|
if (!(paymentData == null ? void 0 : paymentData.depositAddress) || !relayBridge.bridgeQuote) return;
|
|
49618
49864
|
const amount = paymentAmount || parseFloat(config == null ? void 0 : config.amount) || 0;
|
|
49619
49865
|
if (amount <= 0) return;
|
|
49866
|
+
const activeAttempt = activeAttemptRef.current;
|
|
49867
|
+
const paymentAttemptId = paymentData.__coinleyAttemptId ?? null;
|
|
49868
|
+
if (!activeAttempt) {
|
|
49869
|
+
console.log("[Swap] Skipping re-quote — no active attempt");
|
|
49870
|
+
return;
|
|
49871
|
+
}
|
|
49872
|
+
if (paymentAttemptId && paymentAttemptId !== activeAttempt.id) {
|
|
49873
|
+
console.log("[Swap] Skipping re-quote — paymentData belongs to stale attempt", {
|
|
49874
|
+
paymentAttemptId,
|
|
49875
|
+
activeAttemptId: activeAttempt.id
|
|
49876
|
+
});
|
|
49877
|
+
return;
|
|
49878
|
+
}
|
|
49620
49879
|
const currentQuote = relayBridge.bridgeQuote;
|
|
49621
49880
|
const depositAddr = paymentData.depositAddress;
|
|
49622
|
-
console.log("[Swap] Re-quoting with deposit address as recipient:", depositAddr);
|
|
49881
|
+
console.log("[Swap] Re-quoting with deposit address as recipient:", depositAddr, { attemptId: activeAttempt.id });
|
|
49623
49882
|
const isSolanaOrigin = currentQuote.originChainId === 792703809;
|
|
49624
49883
|
const reQuoteUser = isSolanaOrigin ? solanaWallet == null ? void 0 : solanaWallet.publicKey : void 0;
|
|
49884
|
+
const attemptMeta = buildAttemptMeta(activeAttempt);
|
|
49625
49885
|
relayBridge.getBridgeQuote(
|
|
49626
49886
|
currentQuote.originChainId,
|
|
49627
49887
|
currentQuote.destChainId,
|
|
@@ -49635,8 +49895,11 @@ const CoinleyPaymentInternal = ({
|
|
|
49635
49895
|
// Relay delivers output here (EVM address)
|
|
49636
49896
|
null,
|
|
49637
49897
|
null,
|
|
49638
|
-
reQuoteUser
|
|
49898
|
+
reQuoteUser,
|
|
49639
49899
|
// Signer on origin chain (Solana pubkey for cross-VM)
|
|
49900
|
+
void 0,
|
|
49901
|
+
// debugId
|
|
49902
|
+
attemptMeta
|
|
49640
49903
|
);
|
|
49641
49904
|
}, [paymentData == null ? void 0 : paymentData.depositAddress]);
|
|
49642
49905
|
useEffect(() => {
|
|
@@ -49664,6 +49927,8 @@ const CoinleyPaymentInternal = ({
|
|
|
49664
49927
|
await resetAllTransactionState();
|
|
49665
49928
|
relayBridge.resetBridge();
|
|
49666
49929
|
resetWalletTokens();
|
|
49930
|
+
setPaymentData(null);
|
|
49931
|
+
setError("");
|
|
49667
49932
|
setSelectedNetwork(network);
|
|
49668
49933
|
setSelectedToken(null);
|
|
49669
49934
|
if (network == null ? void 0 : network.isBridgeNetwork) {
|
|
@@ -49677,7 +49942,16 @@ const CoinleyPaymentInternal = ({
|
|
|
49677
49942
|
clarityAnalytics.trackNetworkSelected(network == null ? void 0 : network.name, config == null ? void 0 : config.merchantName);
|
|
49678
49943
|
};
|
|
49679
49944
|
const handleTokenSelect = (token) => {
|
|
49945
|
+
var _a3;
|
|
49946
|
+
invalidateCurrentAttempt("token-changed");
|
|
49947
|
+
relayBridge.resetBridge();
|
|
49948
|
+
(_a3 = transactionHandling.resetTransaction) == null ? void 0 : _a3.call(transactionHandling);
|
|
49949
|
+
setPaymentData(null);
|
|
49950
|
+
setError("");
|
|
49680
49951
|
setSelectedToken(token);
|
|
49952
|
+
createNewAttempt("token-selected", {
|
|
49953
|
+
snapshot: buildSelectionSnapshot(selectedNetwork, token, address, solanaWallet == null ? void 0 : solanaWallet.publicKey)
|
|
49954
|
+
});
|
|
49681
49955
|
sdkAnalytics.trackTokenSelected(token == null ? void 0 : token.symbol, selectedNetwork == null ? void 0 : selectedNetwork.name, config == null ? void 0 : config.merchantName);
|
|
49682
49956
|
clarityAnalytics.trackTokenSelected(token == null ? void 0 : token.symbol, selectedNetwork == null ? void 0 : selectedNetwork.name, config == null ? void 0 : config.merchantName);
|
|
49683
49957
|
};
|
|
@@ -49692,11 +49966,43 @@ const CoinleyPaymentInternal = ({
|
|
|
49692
49966
|
setError("Invalid payment amount. Please refresh and try again.");
|
|
49693
49967
|
return;
|
|
49694
49968
|
}
|
|
49695
|
-
|
|
49969
|
+
let attempt = activeAttemptRef.current;
|
|
49970
|
+
if (!attempt || !snapshotsMatch(attempt.snapshot, buildSelectionSnapshot())) {
|
|
49971
|
+
attempt = createNewAttempt("connect-wallet", {
|
|
49972
|
+
snapshot: buildSelectionSnapshot()
|
|
49973
|
+
});
|
|
49974
|
+
}
|
|
49975
|
+
const attemptMeta = buildAttemptMeta(attempt);
|
|
49976
|
+
let effectivePaymentData = paymentData;
|
|
49977
|
+
if ((effectivePaymentData == null ? void 0 : effectivePaymentData.__coinleyAttemptId) && effectivePaymentData.__coinleyAttemptId !== attempt.id) {
|
|
49978
|
+
const existingSnapshot = effectivePaymentData.__coinleySelectionSnapshot;
|
|
49979
|
+
if (existingSnapshot && snapshotsMatch(existingSnapshot, attempt.snapshot)) {
|
|
49980
|
+
console.log("[Attempt] re-stamping paymentData for retry", {
|
|
49981
|
+
paymentId: effectivePaymentData.id,
|
|
49982
|
+
priorAttempt: effectivePaymentData.__coinleyAttemptId,
|
|
49983
|
+
newAttempt: attempt.id
|
|
49984
|
+
});
|
|
49985
|
+
const restamped = {
|
|
49986
|
+
...effectivePaymentData,
|
|
49987
|
+
__coinleyAttemptId: attempt.id
|
|
49988
|
+
};
|
|
49989
|
+
setPaymentData(restamped);
|
|
49990
|
+
effectivePaymentData = restamped;
|
|
49991
|
+
} else {
|
|
49992
|
+
console.log("[Attempt] discarding stale paymentData from prior attempt", {
|
|
49993
|
+
priorAttempt: effectivePaymentData.__coinleyAttemptId,
|
|
49994
|
+
currentAttempt: attempt.id
|
|
49995
|
+
});
|
|
49996
|
+
setPaymentData(null);
|
|
49997
|
+
effectivePaymentData = null;
|
|
49998
|
+
}
|
|
49999
|
+
}
|
|
50000
|
+
if (!effectivePaymentData) {
|
|
49696
50001
|
const configWithConvertedAmount = {
|
|
49697
50002
|
...config,
|
|
49698
50003
|
amount: paymentAmount,
|
|
49699
50004
|
// Use USD amount after currency conversion
|
|
50005
|
+
__coinleyAttemptMeta: attemptMeta,
|
|
49700
50006
|
metadata: {
|
|
49701
50007
|
...config.metadata,
|
|
49702
50008
|
originalCurrency: merchantCurrency,
|
|
@@ -49711,7 +50017,15 @@ const CoinleyPaymentInternal = ({
|
|
|
49711
50017
|
const merchantHasSolanaWallet = !!(((_a3 = config == null ? void 0 : config.merchantWalletAddresses) == null ? void 0 : _a3.solana) || ((_b = config == null ? void 0 : config.merchantWalletAddresses) == null ? void 0 : _b["solana-devnet"]));
|
|
49712
50018
|
if (connectedWalletType === "solana" && merchantHasSolanaWallet && !(selectedToken == null ? void 0 : selectedToken.isSwapToken)) {
|
|
49713
50019
|
console.log("[Payment] Solana direct: merchant has Solana wallet");
|
|
49714
|
-
|
|
50020
|
+
try {
|
|
50021
|
+
await createPayment(configWithConvertedAmount);
|
|
50022
|
+
} catch (e) {
|
|
50023
|
+
if ((e == null ? void 0 : e.code) === "STALE_ATTEMPT") {
|
|
50024
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50025
|
+
return;
|
|
50026
|
+
}
|
|
50027
|
+
return;
|
|
50028
|
+
}
|
|
49715
50029
|
} else if (connectedWalletType === "solana" && !merchantHasSolanaWallet) {
|
|
49716
50030
|
const bestDest = getBestDestinationChain(networks);
|
|
49717
50031
|
const effectiveNetwork = (bestDest == null ? void 0 : bestDest.shortName) || "base";
|
|
@@ -49730,6 +50044,10 @@ const CoinleyPaymentInternal = ({
|
|
|
49730
50044
|
try {
|
|
49731
50045
|
await createDepositPayment(depositConfig);
|
|
49732
50046
|
} catch (e) {
|
|
50047
|
+
if ((e == null ? void 0 : e.code) === "STALE_ATTEMPT") {
|
|
50048
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50049
|
+
return;
|
|
50050
|
+
}
|
|
49733
50051
|
return;
|
|
49734
50052
|
}
|
|
49735
50053
|
} else if ((selectedToken == null ? void 0 : selectedToken.isSwapToken) || (selectedNetwork == null ? void 0 : selectedNetwork.isBridgeNetwork)) {
|
|
@@ -49759,10 +50077,22 @@ const CoinleyPaymentInternal = ({
|
|
|
49759
50077
|
try {
|
|
49760
50078
|
await createDepositPayment(depositConfig);
|
|
49761
50079
|
} catch (e) {
|
|
50080
|
+
if ((e == null ? void 0 : e.code) === "STALE_ATTEMPT") {
|
|
50081
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50082
|
+
return;
|
|
50083
|
+
}
|
|
49762
50084
|
return;
|
|
49763
50085
|
}
|
|
49764
50086
|
} else {
|
|
49765
|
-
|
|
50087
|
+
try {
|
|
50088
|
+
await createPayment(configWithConvertedAmount);
|
|
50089
|
+
} catch (e) {
|
|
50090
|
+
if ((e == null ? void 0 : e.code) === "STALE_ATTEMPT") {
|
|
50091
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50092
|
+
return;
|
|
50093
|
+
}
|
|
50094
|
+
return;
|
|
50095
|
+
}
|
|
49766
50096
|
}
|
|
49767
50097
|
}
|
|
49768
50098
|
setShowWalletConfirm(true);
|
|
@@ -49772,11 +50102,54 @@ const CoinleyPaymentInternal = ({
|
|
|
49772
50102
|
await resetAllTransactionState();
|
|
49773
50103
|
};
|
|
49774
50104
|
const executePayment = async () => {
|
|
49775
|
-
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
49776
|
-
|
|
50105
|
+
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
50106
|
+
const isSwapOrBridgeFlow = !!((selectedToken == null ? void 0 : selectedToken.isSwapToken) || (selectedNetwork == null ? void 0 : selectedNetwork.isBridgeNetwork));
|
|
50107
|
+
if (isSwapOrBridgeFlow && relayBridge.bridgeStatus === "quoting") {
|
|
49777
50108
|
setError("Payment quote is being refreshed. Please wait a moment and try again.");
|
|
49778
50109
|
return;
|
|
49779
50110
|
}
|
|
50111
|
+
if (isSwapOrBridgeFlow) {
|
|
50112
|
+
const activeAttempt = activeAttemptRef.current;
|
|
50113
|
+
if (!activeAttempt) {
|
|
50114
|
+
console.warn("[Attempt] executePayment blocked — no active attempt");
|
|
50115
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50116
|
+
return;
|
|
50117
|
+
}
|
|
50118
|
+
const currentSnapshot = buildSelectionSnapshot();
|
|
50119
|
+
if (!snapshotsMatch(activeAttempt.snapshot, currentSnapshot)) {
|
|
50120
|
+
console.warn("[Attempt] executePayment blocked — snapshot mismatch", {
|
|
50121
|
+
attempt: activeAttempt.snapshot,
|
|
50122
|
+
current: currentSnapshot
|
|
50123
|
+
});
|
|
50124
|
+
invalidateCurrentAttempt("snapshot-mismatch-at-execute");
|
|
50125
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50126
|
+
return;
|
|
50127
|
+
}
|
|
50128
|
+
if (paymentData && paymentData.__coinleyAttemptId && paymentData.__coinleyAttemptId !== activeAttempt.id) {
|
|
50129
|
+
console.warn("[Attempt] executePayment blocked — paymentData attempt mismatch", {
|
|
50130
|
+
paymentAttemptId: paymentData.__coinleyAttemptId,
|
|
50131
|
+
activeAttemptId: activeAttempt.id
|
|
50132
|
+
});
|
|
50133
|
+
setPaymentData(null);
|
|
50134
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50135
|
+
return;
|
|
50136
|
+
}
|
|
50137
|
+
const quoteAttemptId = ((_a3 = relayBridge.bridgeQuote) == null ? void 0 : _a3.attemptId) ?? null;
|
|
50138
|
+
if (quoteAttemptId && quoteAttemptId !== activeAttempt.id) {
|
|
50139
|
+
console.warn("[Attempt] executePayment blocked — bridgeQuote attempt mismatch", {
|
|
50140
|
+
quoteAttemptId,
|
|
50141
|
+
activeAttemptId: activeAttempt.id
|
|
50142
|
+
});
|
|
50143
|
+
relayBridge.resetBridge();
|
|
50144
|
+
setError(STALE_ATTEMPT_MESSAGE);
|
|
50145
|
+
return;
|
|
50146
|
+
}
|
|
50147
|
+
console.log("[Attempt] executePayment proceeding", {
|
|
50148
|
+
attemptId: activeAttempt.id,
|
|
50149
|
+
hasPaymentData: !!paymentData,
|
|
50150
|
+
hasQuote: !!relayBridge.bridgeQuote
|
|
50151
|
+
});
|
|
50152
|
+
}
|
|
49780
50153
|
if (isSolana) {
|
|
49781
50154
|
if (!solanaWallet.publicKey || !solanaWallet.connectedWallet) {
|
|
49782
50155
|
setError("Please connect your Solana wallet first");
|
|
@@ -49800,11 +50173,11 @@ const CoinleyPaymentInternal = ({
|
|
|
49800
50173
|
const amount = paymentAmount || parseFloat(config == null ? void 0 : config.amount) || 0;
|
|
49801
50174
|
const SOL_MINT = "So11111111111111111111111111111111111111112";
|
|
49802
50175
|
const tokenMint = selectedToken == null ? void 0 : selectedToken.contractAddress;
|
|
49803
|
-
const isNativeSOL = tokenMint === "native" || ((
|
|
50176
|
+
const isNativeSOL = tokenMint === "native" || ((_b = selectedToken == null ? void 0 : selectedToken.symbol) == null ? void 0 : _b.toUpperCase()) === "SOL";
|
|
49804
50177
|
let quote = relayBridge.bridgeQuote;
|
|
49805
50178
|
if (!quote) {
|
|
49806
50179
|
console.log("[Solana Bridge] No quote cached — fetching fresh quote...");
|
|
49807
|
-
const originTokenAddress = isNativeSOL ? SOLANA_TOKEN_ADDRESSES.SOL : SOLANA_TOKEN_ADDRESSES[(
|
|
50180
|
+
const originTokenAddress = isNativeSOL ? SOLANA_TOKEN_ADDRESSES.SOL : SOLANA_TOKEN_ADDRESSES[(_c = selectedToken == null ? void 0 : selectedToken.symbol) == null ? void 0 : _c.toUpperCase()] || tokenMint;
|
|
49808
50181
|
quote = await relayBridge.getBridgeQuote(
|
|
49809
50182
|
RELAY_SOLANA_CHAIN_ID,
|
|
49810
50183
|
destChainId,
|
|
@@ -49841,7 +50214,7 @@ const CoinleyPaymentInternal = ({
|
|
|
49841
50214
|
if (!solQuote) {
|
|
49842
50215
|
throw new Error("Unable to find a bridge route. Try paying with SOL, USDC, or USDT.");
|
|
49843
50216
|
}
|
|
49844
|
-
const solNeededLamports = BigInt(((
|
|
50217
|
+
const solNeededLamports = BigInt(((_f = (_e = (_d = solQuote.raw) == null ? void 0 : _d.details) == null ? void 0 : _e.currencyIn) == null ? void 0 : _f.amount) || "0");
|
|
49845
50218
|
const solWithBuffer = solNeededLamports * 105n / 100n;
|
|
49846
50219
|
const solAmount = Number(solWithBuffer) / 1e9;
|
|
49847
50220
|
console.log(`[Solana Bridge] Need ~${solAmount.toFixed(6)} SOL for bridge`);
|
|
@@ -49883,8 +50256,8 @@ const CoinleyPaymentInternal = ({
|
|
|
49883
50256
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
49884
50257
|
try {
|
|
49885
50258
|
const status = await paymentFlow.api.getDepositStatus(paymentData.id);
|
|
49886
|
-
console.log(`[Solana Bridge] Deposit check ${attempt + 1}/${maxAttempts}:`, (
|
|
49887
|
-
if (((
|
|
50259
|
+
console.log(`[Solana Bridge] Deposit check ${attempt + 1}/${maxAttempts}:`, (_g = status == null ? void 0 : status.payment) == null ? void 0 : _g.status);
|
|
50260
|
+
if (((_h = status == null ? void 0 : status.payment) == null ? void 0 : _h.detectedAt) || ((_i = status == null ? void 0 : status.payment) == null ? void 0 : _i.status) === "completed" || ((_j = status == null ? void 0 : status.payment) == null ? void 0 : _j.status) === "swept") {
|
|
49888
50261
|
detected = true;
|
|
49889
50262
|
console.log("[Solana Bridge] Deposit detected on destination chain!");
|
|
49890
50263
|
break;
|
|
@@ -49983,6 +50356,7 @@ const CoinleyPaymentInternal = ({
|
|
|
49983
50356
|
const friendly = parseUserFriendlyError(err);
|
|
49984
50357
|
setError((friendly == null ? void 0 : friendly.message) || "Transaction failed. Please try again.");
|
|
49985
50358
|
setCurrentStep(PAYMENT_STEPS.CONFIRM);
|
|
50359
|
+
handleHardFailure("solana-execute-failed", { swapBridgeFlow: isSwapOrBridgeFlow });
|
|
49986
50360
|
}
|
|
49987
50361
|
} else {
|
|
49988
50362
|
if (!connectedWallet || !address) {
|
|
@@ -50005,8 +50379,8 @@ const CoinleyPaymentInternal = ({
|
|
|
50005
50379
|
const { getWalletClient: getWalletClient2 } = await import("@wagmi/core");
|
|
50006
50380
|
const targetChainId = parseInt(selectedNetwork.chainId);
|
|
50007
50381
|
const expectedDepositAddress = normalizeEvmAddress(paymentData.depositAddress);
|
|
50008
|
-
const quoteRequestedRecipient = normalizeEvmAddress((
|
|
50009
|
-
const quoteEffectiveRecipient = normalizeEvmAddress((
|
|
50382
|
+
const quoteRequestedRecipient = normalizeEvmAddress((_k = relayBridge.bridgeQuote) == null ? void 0 : _k.requestedRecipient);
|
|
50383
|
+
const quoteEffectiveRecipient = normalizeEvmAddress((_l = relayBridge.bridgeQuote) == null ? void 0 : _l.effectiveRecipient);
|
|
50010
50384
|
console.log(`[${action}] validating deposit recipient`, {
|
|
50011
50385
|
expectedDepositAddress,
|
|
50012
50386
|
quoteRequestedRecipient,
|
|
@@ -50031,10 +50405,10 @@ const CoinleyPaymentInternal = ({
|
|
|
50031
50405
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
50032
50406
|
try {
|
|
50033
50407
|
walletClient = await getWalletClient2(wagmiConfig, { chainId: targetChainId });
|
|
50034
|
-
console.log(`[${action}] connector confirmed: chain=${(
|
|
50408
|
+
console.log(`[${action}] connector confirmed: chain=${(_m = walletClient.chain) == null ? void 0 : _m.id} | attempts=${attempt + 1}`);
|
|
50035
50409
|
break;
|
|
50036
50410
|
} catch (e) {
|
|
50037
|
-
if (((
|
|
50411
|
+
if (((_n = e.message) == null ? void 0 : _n.includes("does not match")) && attempt < maxAttempts - 1) {
|
|
50038
50412
|
console.log(`[${action}] connector still settling, attempt ${attempt + 1}: ${e.message}`);
|
|
50039
50413
|
await new Promise((resolve2) => setTimeout(resolve2, 200));
|
|
50040
50414
|
continue;
|
|
@@ -50122,6 +50496,7 @@ const CoinleyPaymentInternal = ({
|
|
|
50122
50496
|
const friendly = parseUserFriendlyError(err);
|
|
50123
50497
|
setError((friendly == null ? void 0 : friendly.message) || "Transaction failed. Please try again.");
|
|
50124
50498
|
setCurrentStep(PAYMENT_STEPS.CONFIRM);
|
|
50499
|
+
handleHardFailure("evm-execute-failed", { swapBridgeFlow: isSwapOrBridgeFlow });
|
|
50125
50500
|
}
|
|
50126
50501
|
}
|
|
50127
50502
|
};
|
|
@@ -53383,4 +53758,4 @@ export {
|
|
|
53383
53758
|
verifyWebhookSignature as w,
|
|
53384
53759
|
coinleyWebhookMiddleware as x
|
|
53385
53760
|
};
|
|
53386
|
-
//# sourceMappingURL=index-
|
|
53761
|
+
//# sourceMappingURL=index-CEBT3A4T.js.map
|