@b3dotfun/sdk 0.0.20-alpha.6 → 0.0.20-alpha.7
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/cjs/anyspend/react/components/common/OrderDetails.js +1 -1
- package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
- package/dist/cjs/anyspend/utils/chain.d.ts +1 -1
- package/dist/cjs/anyspend/utils/chain.js +52 -6
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +1 -1
- package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
- package/dist/esm/anyspend/utils/chain.d.ts +1 -1
- package/dist/esm/anyspend/utils/chain.js +52 -6
- package/dist/types/anyspend/utils/chain.d.ts +1 -1
- package/package.json +1 -1
- package/src/anyspend/react/components/common/OrderDetails.tsx +1 -0
- package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +1 -0
- package/src/anyspend/utils/chain.ts +55 -7
|
@@ -488,7 +488,7 @@ exports.OrderDetails = (0, react_5.memo)(function OrderDetails({ isMainnet, mode
|
|
|
488
488
|
? (0, centerTruncate_1.default)(phantomWalletAddress, 6)
|
|
489
489
|
: (0, centerTruncate_1.default)(account?.address || "", 6)] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full flex-col items-center gap-2", children: [(0, jsx_runtime_1.jsxs)(react_1.ShinyButton, { accentColor: colorMode === "dark" ? "#ffffff" : "#000000", className: "flex w-5/6 items-center gap-2 sm:px-0", onClick: () => setShowQRCode(true), children: [(0, jsx_runtime_1.jsx)("span", { className: "pl-4 text-lg md:text-sm", children: "Pay from a different wallet" }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(react_3.WalletMetamask, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletPhantom, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletTrust, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletWalletConnect, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)("span", { className: "label-style text-as-primary/30 text-xs", children: "& more" })] })] })] }) })) : (
|
|
490
490
|
// Default case - existing QR code flow
|
|
491
|
-
(0, jsx_runtime_1.jsx)(react_4.motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [(0, jsx_runtime_1.jsx)(qrcode_react_1.QRCodeSVG, { value: (0, anyspend_1.getPaymentUrl)(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === anyspend_1.RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain), className: "max-w-[200px]" }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)("span", { className: "label-style text-as-brand/70 text-sm", children: "Scan with" }), (0, jsx_runtime_1.jsxs)(react_1.TextLoop, { interval: 3, children: [(0, jsx_runtime_1.jsx)(react_3.WalletMetamask, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletPhantom, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }))] })) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full items-center justify-center gap-1 text-sm", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-as-primary/30", children: "Time remaining:" }), (0, jsx_runtime_1.jsx)("div", { className: "text-as-primary", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : ((0, jsx_runtime_1.jsx)(react_timeago_1.default, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && ((0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })), (0, jsx_runtime_1.jsxs)("button", { className: "flex w-full items-center justify-center gap-2", onClick: handleBack, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
491
|
+
(0, jsx_runtime_1.jsx)(react_4.motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [(0, jsx_runtime_1.jsx)(qrcode_react_1.QRCodeSVG, { value: (0, anyspend_1.getPaymentUrl)(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === anyspend_1.RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "max-w-[200px]" }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)("span", { className: "label-style text-as-brand/70 text-sm", children: "Scan with" }), (0, jsx_runtime_1.jsxs)(react_1.TextLoop, { interval: 3, children: [(0, jsx_runtime_1.jsx)(react_3.WalletMetamask, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletPhantom, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_3.WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }))] })) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full items-center justify-center gap-1 text-sm", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-as-primary/30", children: "Time remaining:" }), (0, jsx_runtime_1.jsx)("div", { className: "text-as-primary", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : ((0, jsx_runtime_1.jsx)(react_timeago_1.default, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && ((0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })), (0, jsx_runtime_1.jsxs)("button", { className: "flex w-full items-center justify-center gap-2", onClick: handleBack, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
492
492
|
});
|
|
493
493
|
function TransactionDetails({ title, chainId, tx, isProcessing, delay, }) {
|
|
494
494
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full flex-1 items-center justify-between gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex grow items-center gap-4", children: [(0, jsx_runtime_1.jsx)(react_4.motion.div, { className: "bg-b3-react-background relative h-10 w-10 rounded-full", children: isProcessing ? ((0, jsx_runtime_1.jsx)(react_4.motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeInOut", delay }, className: "absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full bg-black/70 shadow-lg backdrop-blur-sm", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-as-primary h-4 w-4 animate-spin" }) })) : ((0, jsx_runtime_1.jsx)(react_4.motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeOut", delay }, className: "bg-as-brand/70 absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border border-white/30 shadow-lg shadow-purple-500/30 backdrop-blur-sm", style: {
|
|
@@ -69,5 +69,5 @@ exports.TransferCryptoDetails = (0, react_3.memo)(function TransferCryptoDetails
|
|
|
69
69
|
transition: "stroke-dashoffset 1s linear",
|
|
70
70
|
} })] }), (0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)("span", { className: "text-as-primary text-[10px] font-semibold", children: formatTime(timeLeft) }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex w-full flex-col gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-content-secondary text-sm font-medium", children: "Amount" }), (0, jsx_runtime_1.jsx)("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: roundedUpSrcAmount || "", onCopy: () => {
|
|
71
71
|
sonner_1.toast.success("Amount copied to clipboard");
|
|
72
|
-
}, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), (0, jsx_runtime_1.jsx)("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("img", { src: anyspend_1.ALL_CHAINS[order.srcChain].logoUrl, alt: (0, anyspend_1.getChainName)(order.srcChain), className: (0, utils_1.cn)("h-6 rounded-full", order.srcChain === chains_1.b3.id && "h-5 rounded-none") }), (0, jsx_runtime_1.jsx)("span", { className: "text-as-primary text-sm font-semibold", children: (0, anyspend_1.getChainName)(order.srcChain) })] }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [(0, jsx_runtime_1.jsx)("div", { className: "border-as-border-primary h-full w-full border-r", children: (0, jsx_runtime_1.jsx)("div", { className: "flex justify-center", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [(0, jsx_runtime_1.jsx)(qrcode_react_1.QRCodeSVG, { value: (0, anyspend_1.getPaymentUrl)(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === anyspend_1.RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain), className: "bg-as-surface-secondary max-h-48 max-w-48" }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), (0, jsx_runtime_1.jsxs)(react_1.TextLoop, { interval: 3, children: [(0, jsx_runtime_1.jsx)(react_2.WalletMetamask, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletPhantom, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [(0, jsx_runtime_1.jsx)("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), (0, jsx_runtime_1.jsx)("div", { className: "place-self-end", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col gap-3", children: (0, jsx_runtime_1.jsx)(react_1.ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
|
|
72
|
+
}, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [(0, jsx_runtime_1.jsxs)("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), (0, jsx_runtime_1.jsx)("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("img", { src: anyspend_1.ALL_CHAINS[order.srcChain].logoUrl, alt: (0, anyspend_1.getChainName)(order.srcChain), className: (0, utils_1.cn)("h-6 rounded-full", order.srcChain === chains_1.b3.id && "h-5 rounded-none") }), (0, jsx_runtime_1.jsx)("span", { className: "text-as-primary text-sm font-semibold", children: (0, anyspend_1.getChainName)(order.srcChain) })] }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [(0, jsx_runtime_1.jsx)("div", { className: "border-as-border-primary h-full w-full border-r", children: (0, jsx_runtime_1.jsx)("div", { className: "flex justify-center", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [(0, jsx_runtime_1.jsx)(qrcode_react_1.QRCodeSVG, { value: (0, anyspend_1.getPaymentUrl)(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === anyspend_1.RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "bg-as-surface-secondary max-h-48 max-w-48" }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), (0, jsx_runtime_1.jsxs)(react_1.TextLoop, { interval: 3, children: [(0, jsx_runtime_1.jsx)(react_2.WalletMetamask, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletPhantom, { className: "h-5 w-5", variant: "branded" }), (0, jsx_runtime_1.jsx)(react_2.WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [(0, jsx_runtime_1.jsx)("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), (0, jsx_runtime_1.jsx)("div", { className: "place-self-end", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col gap-3", children: (0, jsx_runtime_1.jsx)(react_1.ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
|
|
73
73
|
});
|
|
@@ -18,7 +18,7 @@ export declare function isMainnet(chainId: number): boolean;
|
|
|
18
18
|
export declare function isTestnet(chainId: number): boolean;
|
|
19
19
|
export declare function getDefaultToken(chainId: number): components["schemas"]["Token"];
|
|
20
20
|
export declare function getChainName(chainId: number): string;
|
|
21
|
-
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number): string;
|
|
21
|
+
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number, decimals?: number): string;
|
|
22
22
|
export declare function getExplorerTxUrl(chainId: number, txHash: string): string;
|
|
23
23
|
export declare function getExplorerAddressUrl(chainId: number, address: string): string;
|
|
24
24
|
export declare function getMulticall3Address(chainId: number): string;
|
|
@@ -260,7 +260,7 @@ function getChainName(chainId) {
|
|
|
260
260
|
(0, invariant_1.default)(exports.ALL_CHAINS[chainId], `Chain ${chainId} is not supported`);
|
|
261
261
|
return exports.EVM_CHAINS[chainId] ? exports.EVM_CHAINS[chainId].viem.name : "Solana";
|
|
262
262
|
}
|
|
263
|
-
function getPaymentUrl(address, amount, currency, chainId) {
|
|
263
|
+
function getPaymentUrl(address, amount, currency, chainId, decimals) {
|
|
264
264
|
// Get chain type to determine URL format
|
|
265
265
|
const chainType = getChainType(chainId);
|
|
266
266
|
const chain = exports.ALL_CHAINS[chainId];
|
|
@@ -274,14 +274,60 @@ function getPaymentUrl(address, amount, currency, chainId) {
|
|
|
274
274
|
if (currency === chain.nativeToken.symbol) {
|
|
275
275
|
params.append("value", amount.toString());
|
|
276
276
|
}
|
|
277
|
-
//
|
|
278
|
-
const chainParam = chainId !== chains_1.mainnet.id ? `@${chainId}` : "";
|
|
279
|
-
// Add token info for non-native token transfers
|
|
277
|
+
// Handle token transfers differently from native transfers
|
|
280
278
|
if (currency !== chain.nativeToken.symbol) {
|
|
281
|
-
|
|
279
|
+
// For ERC20 tokens, the issue is that mobile wallets often ignore chainId
|
|
280
|
+
// and default to mainnet when they see ethereum: scheme
|
|
281
|
+
// Let's try a different approach: put chainId first and be very explicit
|
|
282
|
+
const tokenParams = new URLSearchParams();
|
|
283
|
+
// Put chainId first to make it more prominent
|
|
284
|
+
if (chainId !== chains_1.mainnet.id) {
|
|
285
|
+
tokenParams.append("chainId", chainId.toString());
|
|
286
|
+
}
|
|
287
|
+
// For ERC20 tokens, convert from smallest unit to display units using decimals
|
|
288
|
+
// For example: 2400623 (raw) with 6 decimals becomes "2.400623"
|
|
289
|
+
let displayAmount;
|
|
290
|
+
if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
|
|
291
|
+
// Convert from smallest unit to display unit for ERC20 tokens
|
|
292
|
+
const divisor = BigInt(10 ** decimals);
|
|
293
|
+
const wholePart = amount / divisor;
|
|
294
|
+
const fractionalPart = amount % divisor;
|
|
295
|
+
if (fractionalPart === BigInt(0)) {
|
|
296
|
+
displayAmount = wholePart.toString();
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
// Format fractional part with leading zeros if needed
|
|
300
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
301
|
+
// Remove trailing zeros
|
|
302
|
+
const trimmedFractional = fractionalStr.replace(/0+$/, "");
|
|
303
|
+
displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
// For native tokens or when decimals not provided, use raw amount
|
|
308
|
+
displayAmount = amount.toString();
|
|
309
|
+
}
|
|
310
|
+
tokenParams.append("amount", displayAmount);
|
|
311
|
+
tokenParams.append("address", address); // recipient address
|
|
312
|
+
// For Arbitrum and other L2s, try a more explicit format
|
|
313
|
+
if (chainId !== chains_1.mainnet.id) {
|
|
314
|
+
// Include the token contract address in the path more explicitly
|
|
315
|
+
const url = `ethereum:${currency}@${chainId}?${tokenParams.toString()}`;
|
|
316
|
+
return url;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// Mainnet tokens
|
|
320
|
+
const url = `ethereum:${currency}?${tokenParams.toString()}`;
|
|
321
|
+
return url;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// For native ETH transfers:
|
|
325
|
+
if (chainId !== chains_1.mainnet.id) {
|
|
326
|
+
params.append("chainId", chainId.toString());
|
|
282
327
|
}
|
|
283
328
|
const queryString = params.toString();
|
|
284
|
-
|
|
329
|
+
const url = `ethereum:${address}${queryString ? `?${queryString}` : ""}`;
|
|
330
|
+
return url;
|
|
285
331
|
}
|
|
286
332
|
case chain_1.ChainType.SOLANA: {
|
|
287
333
|
// Solana URL format: solana:${address}?amount=${amount}&spl-token=${tokenAddress}
|
|
@@ -482,7 +482,7 @@ export const OrderDetails = memo(function OrderDetails({ isMainnet, mode = "moda
|
|
|
482
482
|
? centerTruncate(phantomWalletAddress, 6)
|
|
483
483
|
: centerTruncate(account?.address || "", 6)] })] }), _jsxs("div", { className: "flex w-full flex-col items-center gap-2", children: [_jsxs(ShinyButton, { accentColor: colorMode === "dark" ? "#ffffff" : "#000000", className: "flex w-5/6 items-center gap-2 sm:px-0", onClick: () => setShowQRCode(true), children: [_jsx("span", { className: "pl-4 text-lg md:text-sm", children: "Pay from a different wallet" }), _jsx(ChevronRight, { className: "h-4 w-4" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletWalletConnect, { className: "h-5 w-5", variant: "branded" }), _jsx("span", { className: "label-style text-as-primary/30 text-xs", children: "& more" })] })] })] }) })) : (
|
|
484
484
|
// Default case - existing QR code flow
|
|
485
|
-
_jsx(motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: _jsxs("div", { className: "mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain), className: "max-w-[200px]" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "label-style text-as-brand/70 text-sm", children: "Scan with" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }))] })) })), _jsxs("div", { className: "flex w-full items-center justify-center gap-1 text-sm", children: [_jsx("div", { className: "text-as-primary/30", children: "Time remaining:" }), _jsx("div", { className: "text-as-primary", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : (_jsx(TimeAgo, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && (_jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })), _jsxs("button", { className: "flex w-full items-center justify-center gap-2", onClick: handleBack, children: [_jsx(RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
485
|
+
_jsx(motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: _jsxs("div", { className: "mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "max-w-[200px]" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "label-style text-as-brand/70 text-sm", children: "Scan with" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }))] })) })), _jsxs("div", { className: "flex w-full items-center justify-center gap-1 text-sm", children: [_jsx("div", { className: "text-as-primary/30", children: "Time remaining:" }), _jsx("div", { className: "text-as-primary", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : (_jsx(TimeAgo, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && (_jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })), _jsxs("button", { className: "flex w-full items-center justify-center gap-2", onClick: handleBack, children: [_jsx(RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
486
486
|
});
|
|
487
487
|
function TransactionDetails({ title, chainId, tx, isProcessing, delay, }) {
|
|
488
488
|
return (_jsxs("div", { className: "relative flex w-full flex-1 items-center justify-between gap-4", children: [_jsxs("div", { className: "flex grow items-center gap-4", children: [_jsx(motion.div, { className: "bg-b3-react-background relative h-10 w-10 rounded-full", children: isProcessing ? (_jsx(motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeInOut", delay }, className: "absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full bg-black/70 shadow-lg backdrop-blur-sm", children: _jsx(Loader2, { className: "text-as-primary h-4 w-4 animate-spin" }) })) : (_jsx(motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeOut", delay }, className: "bg-as-brand/70 absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border border-white/30 shadow-lg shadow-purple-500/30 backdrop-blur-sm", style: {
|
|
@@ -66,5 +66,5 @@ export const TransferCryptoDetails = memo(function TransferCryptoDetails({ order
|
|
|
66
66
|
transition: "stroke-dashoffset 1s linear",
|
|
67
67
|
} })] }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("span", { className: "text-as-primary text-[10px] font-semibold", children: formatTime(timeLeft) }) })] })] }), _jsxs("div", { className: "flex w-full flex-col gap-4", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Amount" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsx(CopyToClipboard, { text: roundedUpSrcAmount || "", onCopy: () => {
|
|
68
68
|
toast.success("Amount copied to clipboard");
|
|
69
|
-
}, children: _jsxs("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [_jsxs("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), _jsx(Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), _jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.srcChain].logoUrl, alt: getChainName(order.srcChain), className: cn("h-6 rounded-full", order.srcChain === b3.id && "h-5 rounded-none") }), _jsx("span", { className: "text-as-primary text-sm font-semibold", children: getChainName(order.srcChain) })] }) })] })] }), _jsxs("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [_jsx("div", { className: "border-as-border-primary h-full w-full border-r", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain), className: "bg-as-surface-secondary max-h-48 max-w-48" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), _jsxs("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), _jsxs("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [_jsx("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), _jsx("div", { className: "place-self-end", children: _jsx(Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), _jsx("div", { className: "flex flex-col gap-3", children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
|
|
69
|
+
}, children: _jsxs("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [_jsxs("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), _jsx(Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), _jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.srcChain].logoUrl, alt: getChainName(order.srcChain), className: cn("h-6 rounded-full", order.srcChain === b3.id && "h-5 rounded-none") }), _jsx("span", { className: "text-as-primary text-sm font-semibold", children: getChainName(order.srcChain) })] }) })] })] }), _jsxs("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [_jsx("div", { className: "border-as-border-primary h-full w-full border-r", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "bg-as-surface-secondary max-h-48 max-w-48" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), _jsxs("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), _jsxs("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [_jsx("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), _jsx("div", { className: "place-self-end", children: _jsx(Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), _jsx("div", { className: "flex flex-col gap-3", children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
|
|
70
70
|
});
|
|
@@ -18,7 +18,7 @@ export declare function isMainnet(chainId: number): boolean;
|
|
|
18
18
|
export declare function isTestnet(chainId: number): boolean;
|
|
19
19
|
export declare function getDefaultToken(chainId: number): components["schemas"]["Token"];
|
|
20
20
|
export declare function getChainName(chainId: number): string;
|
|
21
|
-
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number): string;
|
|
21
|
+
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number, decimals?: number): string;
|
|
22
22
|
export declare function getExplorerTxUrl(chainId: number, txHash: string): string;
|
|
23
23
|
export declare function getExplorerAddressUrl(chainId: number, address: string): string;
|
|
24
24
|
export declare function getMulticall3Address(chainId: number): string;
|
|
@@ -237,7 +237,7 @@ export function getChainName(chainId) {
|
|
|
237
237
|
invariant(ALL_CHAINS[chainId], `Chain ${chainId} is not supported`);
|
|
238
238
|
return EVM_CHAINS[chainId] ? EVM_CHAINS[chainId].viem.name : "Solana";
|
|
239
239
|
}
|
|
240
|
-
export function getPaymentUrl(address, amount, currency, chainId) {
|
|
240
|
+
export function getPaymentUrl(address, amount, currency, chainId, decimals) {
|
|
241
241
|
// Get chain type to determine URL format
|
|
242
242
|
const chainType = getChainType(chainId);
|
|
243
243
|
const chain = ALL_CHAINS[chainId];
|
|
@@ -251,14 +251,60 @@ export function getPaymentUrl(address, amount, currency, chainId) {
|
|
|
251
251
|
if (currency === chain.nativeToken.symbol) {
|
|
252
252
|
params.append("value", amount.toString());
|
|
253
253
|
}
|
|
254
|
-
//
|
|
255
|
-
const chainParam = chainId !== mainnet.id ? `@${chainId}` : "";
|
|
256
|
-
// Add token info for non-native token transfers
|
|
254
|
+
// Handle token transfers differently from native transfers
|
|
257
255
|
if (currency !== chain.nativeToken.symbol) {
|
|
258
|
-
|
|
256
|
+
// For ERC20 tokens, the issue is that mobile wallets often ignore chainId
|
|
257
|
+
// and default to mainnet when they see ethereum: scheme
|
|
258
|
+
// Let's try a different approach: put chainId first and be very explicit
|
|
259
|
+
const tokenParams = new URLSearchParams();
|
|
260
|
+
// Put chainId first to make it more prominent
|
|
261
|
+
if (chainId !== mainnet.id) {
|
|
262
|
+
tokenParams.append("chainId", chainId.toString());
|
|
263
|
+
}
|
|
264
|
+
// For ERC20 tokens, convert from smallest unit to display units using decimals
|
|
265
|
+
// For example: 2400623 (raw) with 6 decimals becomes "2.400623"
|
|
266
|
+
let displayAmount;
|
|
267
|
+
if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
|
|
268
|
+
// Convert from smallest unit to display unit for ERC20 tokens
|
|
269
|
+
const divisor = BigInt(10 ** decimals);
|
|
270
|
+
const wholePart = amount / divisor;
|
|
271
|
+
const fractionalPart = amount % divisor;
|
|
272
|
+
if (fractionalPart === BigInt(0)) {
|
|
273
|
+
displayAmount = wholePart.toString();
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
// Format fractional part with leading zeros if needed
|
|
277
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
278
|
+
// Remove trailing zeros
|
|
279
|
+
const trimmedFractional = fractionalStr.replace(/0+$/, "");
|
|
280
|
+
displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
// For native tokens or when decimals not provided, use raw amount
|
|
285
|
+
displayAmount = amount.toString();
|
|
286
|
+
}
|
|
287
|
+
tokenParams.append("amount", displayAmount);
|
|
288
|
+
tokenParams.append("address", address); // recipient address
|
|
289
|
+
// For Arbitrum and other L2s, try a more explicit format
|
|
290
|
+
if (chainId !== mainnet.id) {
|
|
291
|
+
// Include the token contract address in the path more explicitly
|
|
292
|
+
const url = `ethereum:${currency}@${chainId}?${tokenParams.toString()}`;
|
|
293
|
+
return url;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
// Mainnet tokens
|
|
297
|
+
const url = `ethereum:${currency}?${tokenParams.toString()}`;
|
|
298
|
+
return url;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// For native ETH transfers:
|
|
302
|
+
if (chainId !== mainnet.id) {
|
|
303
|
+
params.append("chainId", chainId.toString());
|
|
259
304
|
}
|
|
260
305
|
const queryString = params.toString();
|
|
261
|
-
|
|
306
|
+
const url = `ethereum:${address}${queryString ? `?${queryString}` : ""}`;
|
|
307
|
+
return url;
|
|
262
308
|
}
|
|
263
309
|
case ChainType.SOLANA: {
|
|
264
310
|
// Solana URL format: solana:${address}?amount=${amount}&spl-token=${tokenAddress}
|
|
@@ -18,7 +18,7 @@ export declare function isMainnet(chainId: number): boolean;
|
|
|
18
18
|
export declare function isTestnet(chainId: number): boolean;
|
|
19
19
|
export declare function getDefaultToken(chainId: number): components["schemas"]["Token"];
|
|
20
20
|
export declare function getChainName(chainId: number): string;
|
|
21
|
-
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number): string;
|
|
21
|
+
export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number, decimals?: number): string;
|
|
22
22
|
export declare function getExplorerTxUrl(chainId: number, txHash: string): string;
|
|
23
23
|
export declare function getExplorerAddressUrl(chainId: number, address: string): string;
|
|
24
24
|
export declare function getMulticall3Address(chainId: number): string;
|
package/package.json
CHANGED
|
@@ -1069,6 +1069,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
1069
1069
|
BigInt(order.srcAmount),
|
|
1070
1070
|
order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress,
|
|
1071
1071
|
order.srcChain,
|
|
1072
|
+
srcToken?.decimals,
|
|
1072
1073
|
)}
|
|
1073
1074
|
className="max-w-[200px]"
|
|
1074
1075
|
/>
|
|
@@ -195,6 +195,7 @@ export const TransferCryptoDetails = memo(function TransferCryptoDetails({
|
|
|
195
195
|
BigInt(order.srcAmount),
|
|
196
196
|
order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress,
|
|
197
197
|
order.srcChain,
|
|
198
|
+
srcToken?.decimals,
|
|
198
199
|
)}
|
|
199
200
|
className="bg-as-surface-secondary max-h-48 max-w-48"
|
|
200
201
|
/>
|
|
@@ -304,7 +304,7 @@ export function getChainName(chainId: number): string {
|
|
|
304
304
|
return EVM_CHAINS[chainId] ? EVM_CHAINS[chainId].viem.name : "Solana";
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
-
export function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number) {
|
|
307
|
+
export function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number, decimals?: number) {
|
|
308
308
|
// Get chain type to determine URL format
|
|
309
309
|
const chainType = getChainType(chainId);
|
|
310
310
|
const chain = ALL_CHAINS[chainId];
|
|
@@ -321,16 +321,64 @@ export function getPaymentUrl(address: string, amount: bigint, currency: string,
|
|
|
321
321
|
params.append("value", amount.toString());
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
//
|
|
325
|
-
const chainParam = chainId !== mainnet.id ? `@${chainId}` : "";
|
|
326
|
-
|
|
327
|
-
// Add token info for non-native token transfers
|
|
324
|
+
// Handle token transfers differently from native transfers
|
|
328
325
|
if (currency !== chain.nativeToken.symbol) {
|
|
329
|
-
|
|
326
|
+
// For ERC20 tokens, the issue is that mobile wallets often ignore chainId
|
|
327
|
+
// and default to mainnet when they see ethereum: scheme
|
|
328
|
+
// Let's try a different approach: put chainId first and be very explicit
|
|
329
|
+
|
|
330
|
+
const tokenParams = new URLSearchParams();
|
|
331
|
+
|
|
332
|
+
// Put chainId first to make it more prominent
|
|
333
|
+
if (chainId !== mainnet.id) {
|
|
334
|
+
tokenParams.append("chainId", chainId.toString());
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// For ERC20 tokens, convert from smallest unit to display units using decimals
|
|
338
|
+
// For example: 2400623 (raw) with 6 decimals becomes "2.400623"
|
|
339
|
+
let displayAmount: string;
|
|
340
|
+
if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
|
|
341
|
+
// Convert from smallest unit to display unit for ERC20 tokens
|
|
342
|
+
const divisor = BigInt(10 ** decimals);
|
|
343
|
+
const wholePart = amount / divisor;
|
|
344
|
+
const fractionalPart = amount % divisor;
|
|
345
|
+
|
|
346
|
+
if (fractionalPart === BigInt(0)) {
|
|
347
|
+
displayAmount = wholePart.toString();
|
|
348
|
+
} else {
|
|
349
|
+
// Format fractional part with leading zeros if needed
|
|
350
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
351
|
+
// Remove trailing zeros
|
|
352
|
+
const trimmedFractional = fractionalStr.replace(/0+$/, "");
|
|
353
|
+
displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
|
|
354
|
+
}
|
|
355
|
+
} else {
|
|
356
|
+
// For native tokens or when decimals not provided, use raw amount
|
|
357
|
+
displayAmount = amount.toString();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
tokenParams.append("amount", displayAmount);
|
|
361
|
+
tokenParams.append("address", address); // recipient address
|
|
362
|
+
|
|
363
|
+
// For Arbitrum and other L2s, try a more explicit format
|
|
364
|
+
if (chainId !== mainnet.id) {
|
|
365
|
+
// Include the token contract address in the path more explicitly
|
|
366
|
+
const url = `ethereum:${currency}@${chainId}?${tokenParams.toString()}`;
|
|
367
|
+
return url;
|
|
368
|
+
} else {
|
|
369
|
+
// Mainnet tokens
|
|
370
|
+
const url = `ethereum:${currency}?${tokenParams.toString()}`;
|
|
371
|
+
return url;
|
|
372
|
+
}
|
|
330
373
|
}
|
|
331
374
|
|
|
375
|
+
// For native ETH transfers:
|
|
376
|
+
if (chainId !== mainnet.id) {
|
|
377
|
+
params.append("chainId", chainId.toString());
|
|
378
|
+
}
|
|
332
379
|
const queryString = params.toString();
|
|
333
|
-
|
|
380
|
+
const url = `ethereum:${address}${queryString ? `?${queryString}` : ""}`;
|
|
381
|
+
return url;
|
|
334
382
|
}
|
|
335
383
|
|
|
336
384
|
case ChainType.SOLANA: {
|