@b3dotfun/sdk 0.1.65 → 0.1.66-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +7 -16
  3. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +151 -22
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +4 -50
  6. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  7. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  8. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  9. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +2 -2
  10. package/dist/cjs/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  11. package/dist/cjs/anyspend/react/components/AnySpendWorkflowTrigger.js +14 -0
  12. package/dist/cjs/anyspend/react/components/QRDeposit.js +5 -13
  13. package/dist/cjs/anyspend/react/components/ccShopAbi.d.ts +113 -0
  14. package/dist/cjs/anyspend/react/components/ccShopAbi.js +63 -0
  15. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  16. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +3 -3
  17. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  18. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +3 -57
  19. package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
  20. package/dist/cjs/anyspend/react/components/index.d.ts +2 -0
  21. package/dist/cjs/anyspend/react/components/index.js +3 -1
  22. package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
  23. package/dist/cjs/anyspend/react/hooks/index.js +1 -0
  24. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  25. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  26. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  27. package/dist/cjs/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  28. package/dist/cjs/anyspend/react/hooks/useOnOrderSuccess.js +27 -0
  29. package/dist/cjs/anyspend/services/anyspend.d.ts +2 -1
  30. package/dist/cjs/anyspend/services/anyspend.js +2 -1
  31. package/dist/cjs/anyspend/utils/chain.d.ts +1 -1
  32. package/dist/cjs/anyspend/utils/chain.js +72 -62
  33. package/dist/cjs/app.shared.js +8 -0
  34. package/dist/cjs/global-account/react/components/B3DynamicModal.js +4 -0
  35. package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +4 -4
  36. package/dist/cjs/global-account/react/hooks/useUserQuery.js +10 -0
  37. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +37 -1
  38. package/dist/cjs/global-account/react/stores/userStore.js +1 -0
  39. package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -0
  40. package/dist/esm/anyspend/react/components/AnySpend.js +7 -16
  41. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  42. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +152 -23
  43. package/dist/esm/anyspend/react/components/AnySpendCustom.js +4 -17
  44. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  45. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  46. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  47. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +2 -2
  48. package/dist/esm/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  49. package/dist/esm/anyspend/react/components/AnySpendWorkflowTrigger.js +11 -0
  50. package/dist/esm/anyspend/react/components/QRDeposit.js +6 -14
  51. package/dist/esm/anyspend/react/components/ccShopAbi.d.ts +113 -0
  52. package/dist/esm/anyspend/react/components/ccShopAbi.js +60 -0
  53. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  54. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +3 -3
  55. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  56. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +2 -56
  57. package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
  58. package/dist/esm/anyspend/react/components/index.d.ts +2 -0
  59. package/dist/esm/anyspend/react/components/index.js +1 -0
  60. package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
  61. package/dist/esm/anyspend/react/hooks/index.js +1 -0
  62. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  63. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  64. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  65. package/dist/esm/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  66. package/dist/esm/anyspend/react/hooks/useOnOrderSuccess.js +24 -0
  67. package/dist/esm/anyspend/services/anyspend.d.ts +2 -1
  68. package/dist/esm/anyspend/services/anyspend.js +2 -1
  69. package/dist/esm/anyspend/utils/chain.d.ts +1 -1
  70. package/dist/esm/anyspend/utils/chain.js +72 -62
  71. package/dist/esm/app.shared.js +8 -0
  72. package/dist/esm/global-account/react/components/B3DynamicModal.js +4 -0
  73. package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +4 -4
  74. package/dist/esm/global-account/react/hooks/useUserQuery.js +11 -1
  75. package/dist/esm/global-account/react/stores/useModalStore.d.ts +37 -1
  76. package/dist/esm/global-account/react/stores/userStore.js +1 -0
  77. package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -0
  78. package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +6 -1
  79. package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  80. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  81. package/dist/types/anyspend/react/components/AnySpendWorkflowTrigger.d.ts +31 -0
  82. package/dist/types/anyspend/react/components/ccShopAbi.d.ts +113 -0
  83. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  84. package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  85. package/dist/types/anyspend/react/components/index.d.ts +2 -0
  86. package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
  87. package/dist/types/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  88. package/dist/types/anyspend/react/hooks/useOnOrderSuccess.d.ts +10 -0
  89. package/dist/types/anyspend/services/anyspend.d.ts +2 -1
  90. package/dist/types/anyspend/utils/chain.d.ts +1 -1
  91. package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +4 -4
  92. package/dist/types/global-account/react/stores/useModalStore.d.ts +37 -1
  93. package/package.json +1 -1
  94. package/src/anyspend/README.md +14 -0
  95. package/src/anyspend/docs/checkout-sessions.md +228 -0
  96. package/src/anyspend/docs/components.md +26 -0
  97. package/src/anyspend/docs/examples.md +58 -0
  98. package/src/anyspend/docs/hooks.md +32 -0
  99. package/src/anyspend/llms.txt +185 -0
  100. package/src/anyspend/react/components/AnySpend.tsx +9 -17
  101. package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +206 -22
  102. package/src/anyspend/react/components/AnySpendCustom.tsx +3 -18
  103. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +5 -1
  104. package/src/anyspend/react/components/AnySpendDeposit.tsx +5 -0
  105. package/src/anyspend/react/components/AnySpendWorkflowTrigger.tsx +73 -0
  106. package/src/anyspend/react/components/QRDeposit.tsx +19 -15
  107. package/src/anyspend/react/components/ccShopAbi.ts +64 -0
  108. package/src/anyspend/react/components/common/CryptoPaySection.tsx +0 -5
  109. package/src/anyspend/react/components/common/OrderTokenAmount.tsx +1 -70
  110. package/src/anyspend/react/components/common/PaySection.tsx +0 -1
  111. package/src/anyspend/react/components/index.ts +2 -0
  112. package/src/anyspend/react/hooks/index.ts +1 -0
  113. package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +1 -0
  114. package/src/anyspend/react/hooks/useAnyspendCreateOrder.ts +2 -0
  115. package/src/anyspend/react/hooks/useOnOrderSuccess.ts +36 -0
  116. package/src/anyspend/services/anyspend.ts +3 -0
  117. package/src/anyspend/utils/chain.ts +81 -65
  118. package/src/app.shared.ts +11 -0
  119. package/src/global-account/react/components/B3DynamicModal.tsx +4 -0
  120. package/src/global-account/react/hooks/useUserQuery.ts +12 -1
  121. package/src/global-account/react/stores/useModalStore.ts +39 -2
  122. package/src/global-account/react/stores/userStore.ts +1 -0
@@ -0,0 +1,60 @@
1
+ // CCShop contract ABI fragments used by AnySpendCollectorClubPurchase
2
+ export const BUY_PACKS_FOR_ABI = {
3
+ inputs: [
4
+ { internalType: "address", name: "user", type: "address" },
5
+ { internalType: "uint256", name: "packId", type: "uint256" },
6
+ { internalType: "uint256", name: "amount", type: "uint256" },
7
+ ],
8
+ name: "buyPacksFor",
9
+ outputs: [],
10
+ stateMutability: "nonpayable",
11
+ type: "function",
12
+ };
13
+ export const BUY_PACKS_FOR_WITH_DISCOUNT_ABI = {
14
+ inputs: [
15
+ { internalType: "address", name: "user", type: "address" },
16
+ { internalType: "uint256", name: "packId", type: "uint256" },
17
+ { internalType: "uint256", name: "amount", type: "uint256" },
18
+ { internalType: "string", name: "discountCode", type: "string" },
19
+ ],
20
+ name: "buyPacksForWithDiscount",
21
+ outputs: [],
22
+ stateMutability: "nonpayable",
23
+ type: "function",
24
+ };
25
+ export const IS_DISCOUNT_CODE_VALID_FOR_PACK_ABI = {
26
+ inputs: [
27
+ { internalType: "string", name: "code", type: "string" },
28
+ { internalType: "uint256", name: "packId", type: "uint256" },
29
+ ],
30
+ name: "isDiscountCodeValidForPack",
31
+ outputs: [
32
+ { internalType: "bool", name: "isValid", type: "bool" },
33
+ { internalType: "uint256", name: "discountAmount", type: "uint256" },
34
+ ],
35
+ stateMutability: "view",
36
+ type: "function",
37
+ };
38
+ export const GET_DISCOUNT_CODE_ABI = {
39
+ inputs: [{ internalType: "string", name: "code", type: "string" }],
40
+ name: "getDiscountCode",
41
+ outputs: [
42
+ {
43
+ components: [
44
+ { internalType: "uint256", name: "discountAmount", type: "uint256" },
45
+ { internalType: "uint256", name: "expiresAt", type: "uint256" },
46
+ { internalType: "bool", name: "used", type: "bool" },
47
+ { internalType: "bool", name: "exists", type: "bool" },
48
+ { internalType: "uint256", name: "maxUses", type: "uint256" },
49
+ { internalType: "uint256", name: "usedCount", type: "uint256" },
50
+ { internalType: "uint256", name: "packId", type: "uint256" },
51
+ { internalType: "uint256", name: "minPurchaseAmount", type: "uint256" },
52
+ ],
53
+ internalType: "struct CCShop.DiscountCode",
54
+ name: "",
55
+ type: "tuple",
56
+ },
57
+ ],
58
+ stateMutability: "view",
59
+ type: "function",
60
+ };
@@ -18,8 +18,6 @@ interface CryptoPaySectionProps {
18
18
  }) => void;
19
19
  onShowFeeDetail?: () => void;
20
20
  classes?: CryptoPaySectionClasses;
21
- /** When true, skip auto-setting max balance when token changes (used for fixed destination amount mode) */
22
- skipAutoMaxOnTokenChange?: boolean;
23
21
  }
24
- export declare function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, onTokenSelect, onShowFeeDetail, classes, skipAutoMaxOnTokenChange, }: CryptoPaySectionProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, onTokenSelect, onShowFeeDetail, classes, }: CryptoPaySectionProps): import("react/jsx-runtime").JSX.Element;
25
23
  export {};
@@ -8,7 +8,7 @@ import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay
8
8
  import { CryptoPaymentMethodDisplay } from "./CryptoPaymentMethodDisplay.js";
9
9
  import { OrderTokenAmount } from "./OrderTokenAmount.js";
10
10
  import { TokenBalance } from "./TokenBalance.js";
11
- export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, onTokenSelect, onShowFeeDetail, classes, skipAutoMaxOnTokenChange = false, }) {
11
+ export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod, anyspendQuote, onTokenSelect, onShowFeeDetail, classes, }) {
12
12
  const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
13
13
  // Use custom hook to determine wallet address based on payment method
14
14
  const { walletAddress } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
@@ -40,10 +40,10 @@ export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, se
40
40
  }, [selectedSrcToken.address, selectedSrcToken.chainId]);
41
41
  return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: classes?.container ||
42
42
  "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: classes?.label || "text-as-primary/50 flex h-7 items-center gap-1.5 text-sm", children: ["Pay", !isSrcInputDirty && anyspendQuote?.data?.fee && onShowFeeDetail && (_jsx("button", { onClick: onShowFeeDetail, className: "text-as-primary/40 hover:text-as-primary/60 transition-colors", children: _jsx(Info, { className: "h-4 w-4" }) }))] }), _jsx("button", { className: classes?.paymentMethodButton ||
43
- "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: _jsx(CryptoPaymentMethodDisplay, { paymentMethod: selectedCryptoPaymentMethod, connectedAddress: walletAddress, connectedName: connectedName }) })] }), _jsx("div", { className: classes?.inputContainer, children: _jsx(OrderTokenAmount, { address: walletAddress, walletAddress: walletAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
43
+ "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: _jsx(CryptoPaymentMethodDisplay, { paymentMethod: selectedCryptoPaymentMethod, connectedAddress: walletAddress, connectedName: connectedName }) })] }), _jsx("div", { className: classes?.inputContainer, children: _jsx(OrderTokenAmount, { address: walletAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
44
44
  setIsSrcInputDirty(true);
45
45
  setSrcAmount(value);
46
- }, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken, onTokenSelect: onTokenSelect, skipAutoMaxOnTokenChange: skipAutoMaxOnTokenChange }) }), _jsxs("div", { className: classes?.balanceRow || "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
46
+ }, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken, onTokenSelect: onTokenSelect }) }), _jsxs("div", { className: classes?.balanceRow || "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
47
47
  style: "currency",
48
48
  fallback: "",
49
49
  }) }), _jsx(TokenBalance, { token: selectedSrcToken, walletAddress: walletAddress, onChangeInput: value => {
@@ -1,5 +1,5 @@
1
1
  import { components } from "../../../../anyspend/types/api";
2
- export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect, canEditAmount, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, walletAddress, skipAutoMaxOnTokenChange, }: {
2
+ export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect, canEditAmount, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, }: {
3
3
  disabled?: boolean;
4
4
  inputValue: string;
5
5
  onChangeInput: (value: string) => void;
@@ -18,7 +18,4 @@ export declare function OrderTokenAmount({ disabled, inputValue, onChangeInput,
18
18
  onTokenSelect?: (token: components["schemas"]["Token"], event: {
19
19
  preventDefault: () => void;
20
20
  }) => void;
21
- walletAddress?: string | undefined;
22
- /** When true, skip auto-setting max balance when token changes (used for fixed destination amount mode) */
23
- skipAutoMaxOnTokenChange?: boolean;
24
21
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,63 +1,13 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ChevronsUpDown } from "lucide-react";
4
- import { useEffect, useRef } from "react";
5
4
  import { NumericFormat } from "react-number-format";
6
- import { formatUnits } from "viem";
7
5
  import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID, getAvailableChainIds } from "../../../../anyspend/index.js";
8
- import { getNativeRequired } from "../../../../anyspend/utils/chain.js";
9
- import { isNativeToken } from "../../../../anyspend/utils/token.js";
10
- import { Button, useTokenBalance } from "../../../../global-account/react/index.js";
6
+ import { Button } from "../../../../global-account/react/index.js";
11
7
  import { cn } from "../../../../shared/utils/index.js";
12
8
  import { TokenSelector } from "@relayprotocol/relay-kit-ui";
13
9
  import { ChainTokenIcon } from "./ChainTokenIcon.js";
14
- export function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect = false, canEditAmount = true, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, walletAddress, skipAutoMaxOnTokenChange = false, }) {
15
- // Track previous token to detect changes
16
- const prevTokenRef = useRef(token.address);
17
- // Only get token balance when context is "from" (for setting max amount)
18
- const { rawBalance } = useTokenBalance({
19
- token,
20
- address: context === "from" && walletAddress ? walletAddress : undefined,
21
- });
22
- useEffect(() => {
23
- // Only handle "from" context
24
- if (context !== "from")
25
- return;
26
- // Skip auto-max when in fixed destination amount mode
27
- if (skipAutoMaxOnTokenChange) {
28
- prevTokenRef.current = token.address;
29
- return;
30
- }
31
- // Check if token changed or if this is the initial load with balance
32
- const isTokenChanged = prevTokenRef.current !== token.address;
33
- if (isTokenChanged && rawBalance) {
34
- console.log(`Setting max balance - Token: ${token.address}, Changed: ${isTokenChanged}`);
35
- // Calculate max amount with gas reserve for native tokens
36
- let maxAmount;
37
- if (isNativeToken(token.address)) {
38
- const gasReserve = getNativeRequired(token.chainId);
39
- // Ensure we don't go negative
40
- maxAmount = rawBalance > gasReserve ? rawBalance - gasReserve : BigInt(0);
41
- }
42
- else {
43
- // For ERC20 tokens, use full balance
44
- maxAmount = rawBalance;
45
- }
46
- // Set the max amount as input value
47
- onChangeInput(formatUnits(maxAmount, token.decimals));
48
- // Update refs
49
- prevTokenRef.current = token.address;
50
- }
51
- }, [
52
- token.address,
53
- token.chainId,
54
- token.decimals,
55
- chainId,
56
- context,
57
- onChangeInput,
58
- rawBalance,
59
- skipAutoMaxOnTokenChange,
60
- ]);
10
+ export function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect = false, canEditAmount = true, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, }) {
61
11
  const handleTokenSelect = (newToken) => {
62
12
  const token = {
63
13
  address: newToken.address,
@@ -80,11 +30,7 @@ export function OrderTokenAmount({ disabled, inputValue, onChangeInput, context,
80
30
  return; // Early return if callback prevented default behavior
81
31
  }
82
32
  }
83
- // Mark that we're about to change tokens
84
- prevTokenRef.current = "changing"; // Temporary value to force effect
85
- // Set the chain ID first
86
33
  setChainId(newToken.chainId);
87
- // Then set the new token - the useEffect will handle setting the max balance
88
34
  setToken(token);
89
35
  };
90
36
  return (_jsx("div", { className: cn("border-as-stroke flex w-full flex-col gap-2 rounded-xl", className), children: _jsxs("div", { className: cn("flex items-center justify-between gap-3", innerClassName), children: [!canEditAmount ? (_jsx("h2", { className: cn("text-3xl font-medium text-white", amountClassName), children: inputValue || "--" })) : (_jsx(NumericFormat, { decimalSeparator: ".", allowedDecimalSeparators: [","], thousandSeparator: true, inputMode: "decimal", autoComplete: "off", autoCorrect: "off", type: "text", placeholder: "0.00", minLength: 1, maxLength: 30, spellCheck: "false", className: cn("placeholder:text-as-primary/70 disabled:text-as-primary/70 text-as-primary w-full bg-transparent text-4xl font-semibold leading-[42px] outline-none sm:text-[30px]", amountClassName), pattern: "^[0-9]*[.,]?[0-9]*$", disabled: disabled, value: inputValue, allowNegative: false, onChange: e => onChangeInput(e.currentTarget.value) }, `input-${token.address}-${chainId}`)), !hideTokenSelect && (_jsx(TokenSelector, { address: address, chainIdsFilter: getAvailableChainIds(context), context: context, fromChainWalletVMSupported: true, isValidAddress: true, lockedChainIds: getAvailableChainIds(context), multiWalletSupportEnabled: true, onAnalyticEvent: undefined, popularChainIds: [1, 8453, RELAY_SOLANA_MAINNET_CHAIN_ID], setToken: handleTokenSelect, supportedWalletVMs: ["evm", "svm"], token: undefined, trigger: _jsxs(Button, { variant: "outline", role: "combobox", className: cn("token-selector-button bg-b3-react-background border-as-stroke flex h-auto w-fit shrink-0 items-center justify-center gap-2 rounded-xl border-2 px-2 py-1 pr-2 text-center", tokenSelectClassName), children: [token.metadata.logoURI ? (_jsx(ChainTokenIcon, { chainUrl: ALL_CHAINS[chainId].logoUrl, tokenUrl: token.metadata.logoURI, className: "h-8 min-h-8 w-8 min-w-8" })) : (_jsx("div", { className: "h-8 w-8 rounded-full bg-gray-700" })), _jsxs("div", { className: "flex flex-col items-start gap-0", children: [_jsx("div", { className: "text-as-primary font-semibold", children: token.symbol }), _jsx("div", { className: "text-as-primary/70 text-xs", children: ALL_CHAINS[chainId].name })] }), _jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-70" })] }) }, `selector-${context}-${token.address}-${chainId}`))] }) }, `${context}-${token.address}-${chainId}`));
@@ -39,7 +39,7 @@ export function CryptoPaySection({ selectedSrcChainId, setSelectedSrcChainId, se
39
39
  useEffect(() => {
40
40
  appliedSrcMetadataRef.current = false;
41
41
  }, [selectedSrcToken.address, selectedSrcToken.chainId]);
42
- return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (_jsxs(_Fragment, { children: [isConnected ? (_jsx("div", { className: "flex items-center gap-1", children: connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "") })) : ("Connect wallet"), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsxs(_Fragment, { children: ["Global Account", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (_jsxs(_Fragment, { children: ["Transfer crypto", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx(OrderTokenAmount, { address: connectedAddress, walletAddress: connectedAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
42
+ return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "pay-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors focus:!outline-none", onClick: onSelectCryptoPaymentMethod, children: selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (_jsxs(_Fragment, { children: [isConnected ? (_jsx("div", { className: "flex items-center gap-1", children: connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "") })) : ("Connect wallet"), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsxs(_Fragment, { children: ["Global Account", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (_jsxs(_Fragment, { children: ["Transfer crypto", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx(OrderTokenAmount, { address: connectedAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
43
43
  setIsSrcInputDirty(true);
44
44
  setSrcAmount(value);
45
45
  }, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
@@ -8,6 +8,8 @@ export { AnySpendDeposit } from "./AnySpendDeposit";
8
8
  export type { AnySpendDepositProps, ChainConfig, DepositContractConfig } from "./AnySpendDeposit";
9
9
  export type { AnySpendAllClasses, AnySpendClasses, AnySpendCustomExactInClasses, AnySpendDepositClasses, CryptoPaymentMethodClasses, CryptoPaySectionClasses, CryptoReceiveSectionClasses, FiatPaymentMethodClasses, OrderDetailsClasses, PanelOnrampClasses, QRDepositClasses, RecipientSelectionClasses, } from "./types/classes";
10
10
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype";
11
+ export { AnySpendWorkflowTrigger } from "./AnySpendWorkflowTrigger";
12
+ export type { AnySpendWorkflowTriggerProps } from "./AnySpendWorkflowTrigger";
11
13
  export * from "./AnySpendFingerprintWrapper";
12
14
  export { AnySpendNFT } from "./AnySpendNFT";
13
15
  export { AnyspendSignatureMint } from "./AnyspendSignatureMint";
@@ -7,6 +7,7 @@ export { AnySpendCustom } from "./AnySpendCustom.js";
7
7
  export { AnySpendCustomExactIn } from "./AnySpendCustomExactIn.js";
8
8
  export { AnySpendDeposit } from "./AnySpendDeposit.js";
9
9
  export { AnySpendDepositHype, HYPE_TOKEN_DETAILS } from "./AnyspendDepositHype.js";
10
+ export { AnySpendWorkflowTrigger } from "./AnySpendWorkflowTrigger.js";
10
11
  export * from "./AnySpendFingerprintWrapper.js";
11
12
  export { AnySpendNFT } from "./AnySpendNFT.js";
12
13
  export { AnyspendSignatureMint } from "./AnyspendSignatureMint.js";
@@ -12,6 +12,7 @@ export * from "./useGasPrice";
12
12
  export * from "./useGeoOnrampOptions";
13
13
  export * from "./useGetGeo";
14
14
  export * from "./useHyperliquidTransfer";
15
+ export * from "./useOnOrderSuccess";
15
16
  export * from "./useRecipientAddressState";
16
17
  export * from "./useSigMint";
17
18
  export * from "./useStripeClientSecret";
@@ -12,6 +12,7 @@ export * from "./useGasPrice.js";
12
12
  export * from "./useGeoOnrampOptions.js";
13
13
  export * from "./useGetGeo.js";
14
14
  export * from "./useHyperliquidTransfer.js";
15
+ export * from "./useOnOrderSuccess.js";
15
16
  export * from "./useRecipientAddressState.js";
16
17
  export * from "./useSigMint.js";
17
18
  export * from "./useStripeClientSecret.js";
@@ -71,6 +71,7 @@ export function useAnyspendCreateOnrampOrder({ onSuccess, onError } = {}) {
71
71
  partnerId,
72
72
  clientReferenceId,
73
73
  visitorData,
74
+ callbackMetadata: params.callbackMetadata,
74
75
  });
75
76
  }
76
77
  catch (error) {
@@ -18,6 +18,7 @@ export type CreateOrderParams = {
18
18
  creatorAddress?: string;
19
19
  payload?: any;
20
20
  metadata?: Record<string, any>;
21
+ callbackMetadata?: Record<string, unknown>;
21
22
  };
22
23
  export type UseAnyspendCreateOrderProps = {
23
24
  onSuccess?: (data: any) => void;
@@ -60,6 +60,7 @@ export function useAnyspendCreateOrder({ onSuccess, onError } = {}) {
60
60
  partnerId,
61
61
  clientReferenceId,
62
62
  visitorData,
63
+ callbackMetadata: params.callbackMetadata,
63
64
  });
64
65
  }
65
66
  catch (error) {
@@ -0,0 +1,10 @@
1
+ import { GetOrderAndTxsResponse } from "../../types/api_req_res";
2
+ /**
3
+ * Hook to call onSuccess callback when an order is executed.
4
+ * Handles fallback to relayTxs when executeTx is null.
5
+ */
6
+ export declare function useOnOrderSuccess({ orderData, orderId, onSuccess, }: {
7
+ orderData: GetOrderAndTxsResponse | undefined;
8
+ orderId: string | undefined;
9
+ onSuccess?: (txHash?: string) => void;
10
+ }): void;
@@ -0,0 +1,24 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * Hook to call onSuccess callback when an order is executed.
4
+ * Handles fallback to relayTxs when executeTx is null.
5
+ */
6
+ export function useOnOrderSuccess({ orderData, orderId, onSuccess, }) {
7
+ const onSuccessCalled = useRef(false);
8
+ const prevOrderId = useRef(orderId);
9
+ useEffect(() => {
10
+ // Reset flag when orderId changes
11
+ if (prevOrderId.current !== orderId) {
12
+ onSuccessCalled.current = false;
13
+ prevOrderId.current = orderId;
14
+ }
15
+ // Call onSuccess when order is executed
16
+ if (orderData?.data?.order.status === "executed" && !onSuccessCalled.current) {
17
+ const relayTxs = orderData?.data?.relayTxs;
18
+ const lastSuccessfulRelayTx = relayTxs?.filter(tx => tx.status === "success").pop();
19
+ const txHash = orderData?.data?.executeTx?.txHash || lastSuccessfulRelayTx?.txHash;
20
+ onSuccess?.(txHash);
21
+ onSuccessCalled.current = true;
22
+ }
23
+ }, [orderData, orderId, onSuccess]);
24
+ }
@@ -6,7 +6,7 @@ export declare const anyspendService: {
6
6
  getTokenList: (chainId: number, query: string) => Promise<components["schemas"]["Token"][]>;
7
7
  getToken: (chainId: number, tokenAddress: string) => Promise<components["schemas"]["Token"]>;
8
8
  getQuote: (req: GetQuoteRequest, partnerId?: string) => Promise<GetQuoteResponse>;
9
- createOrder: ({ recipientAddress, type, srcChain, dstChain, srcTokenAddress, dstTokenAddress, srcAmount, payload, onramp, metadata, creatorAddress, partnerId, clientReferenceId, visitorData, }: {
9
+ createOrder: ({ recipientAddress, type, srcChain, dstChain, srcTokenAddress, dstTokenAddress, srcAmount, payload, onramp, metadata, creatorAddress, partnerId, clientReferenceId, visitorData, callbackMetadata, }: {
10
10
  recipientAddress: string;
11
11
  type: string;
12
12
  srcChain: number;
@@ -21,6 +21,7 @@ export declare const anyspendService: {
21
21
  partnerId?: string;
22
22
  clientReferenceId?: string;
23
23
  visitorData?: VisitorData;
24
+ callbackMetadata?: Record<string, unknown>;
24
25
  }) => Promise<{
25
26
  success: boolean;
26
27
  message: string;
@@ -36,7 +36,7 @@ export const anyspendService = {
36
36
  return data;
37
37
  },
38
38
  // Order related
39
- createOrder: async ({ recipientAddress, type, srcChain, dstChain, srcTokenAddress, dstTokenAddress, srcAmount, payload, onramp, metadata, creatorAddress, partnerId, clientReferenceId, visitorData, }) => {
39
+ createOrder: async ({ recipientAddress, type, srcChain, dstChain, srcTokenAddress, dstTokenAddress, srcAmount, payload, onramp, metadata, creatorAddress, partnerId, clientReferenceId, visitorData, callbackMetadata, }) => {
40
40
  const accessToken = await app.authentication.getAccessToken();
41
41
  const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders`, {
42
42
  method: "POST",
@@ -60,6 +60,7 @@ export const anyspendService = {
60
60
  creatorAddress,
61
61
  partnerId,
62
62
  ...(clientReferenceId && { clientReferenceId }),
63
+ ...(callbackMetadata && { callbackMetadata }),
63
64
  }),
64
65
  });
65
66
  const data = await response.json();
@@ -82,7 +82,7 @@ export declare function isTestnet(chainId: number): boolean;
82
82
  export declare function getDefaultToken(chainId: number): components["schemas"]["Token"];
83
83
  export declare function getChainName(chainId: number): string;
84
84
  export declare function getCoingeckoName(chainId: number): string | null;
85
- export declare function getPaymentUrl(address: string, amount: bigint, currency: string, chainId: number, decimals?: number): string;
85
+ export declare function getPaymentUrl(address: string, amount: bigint | undefined, currency: string, chainId: number, decimals?: number): string;
86
86
  export declare function getExplorerTxUrl(chainId: number, txHash: string): string;
87
87
  export declare function getExplorerAddressUrl(chainId: number, address: string): string;
88
88
  export declare function getMulticall3Address(chainId: number): string;
@@ -362,8 +362,8 @@ export function getPaymentUrl(address, amount, currency, chainId, decimals) {
362
362
  // For EVM chains, follow EIP-681 format
363
363
  // Format: ethereum:[address]@[chainId]?value=[amount]&symbol=[symbol]
364
364
  const params = new URLSearchParams();
365
- // Add value for native token transfers
366
- if (currency === chain.nativeToken.symbol) {
365
+ // Add value for native token transfers (skip if amount not provided, e.g. deposit_first)
366
+ if (currency === chain.nativeToken.symbol && amount !== undefined) {
367
367
  params.append("value", amount.toString());
368
368
  }
369
369
  // Handle token transfers differently from native transfers
@@ -378,28 +378,31 @@ export function getPaymentUrl(address, amount, currency, chainId, decimals) {
378
378
  }
379
379
  // For ERC20 tokens, convert from smallest unit to display units using decimals
380
380
  // For example: 2400623 (raw) with 6 decimals becomes "2.400623"
381
- let displayAmount;
382
- if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
383
- // Convert from smallest unit to display unit for ERC20 tokens
384
- const divisor = BigInt(10 ** decimals);
385
- const wholePart = amount / divisor;
386
- const fractionalPart = amount % divisor;
387
- if (fractionalPart === BigInt(0)) {
388
- displayAmount = wholePart.toString();
381
+ // Skip amount if not provided (e.g. deposit_first orders)
382
+ if (amount !== undefined) {
383
+ let displayAmount;
384
+ if (decimals !== undefined && currency !== chain.nativeToken.symbol) {
385
+ // Convert from smallest unit to display unit for ERC20 tokens
386
+ const divisor = BigInt(10 ** decimals);
387
+ const wholePart = amount / divisor;
388
+ const fractionalPart = amount % divisor;
389
+ if (fractionalPart === BigInt(0)) {
390
+ displayAmount = wholePart.toString();
391
+ }
392
+ else {
393
+ // Format fractional part with leading zeros if needed
394
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
395
+ // Remove trailing zeros
396
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
397
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
398
+ }
389
399
  }
390
400
  else {
391
- // Format fractional part with leading zeros if needed
392
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
393
- // Remove trailing zeros
394
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
395
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
401
+ // For native tokens or when decimals not provided, use raw amount
402
+ displayAmount = amount.toString();
396
403
  }
404
+ tokenParams.append("amount", displayAmount);
397
405
  }
398
- else {
399
- // For native tokens or when decimals not provided, use raw amount
400
- displayAmount = amount.toString();
401
- }
402
- tokenParams.append("amount", displayAmount);
403
406
  tokenParams.append("address", address); // recipient address
404
407
  // For Arbitrum and other L2s, try a more explicit format
405
408
  if (chainId !== mainnet.id) {
@@ -419,7 +422,9 @@ export function getPaymentUrl(address, amount, currency, chainId, decimals) {
419
422
  // to make sure wallets recognize the correct chain
420
423
  const nativeParams = new URLSearchParams();
421
424
  nativeParams.append("chainId", chainId.toString());
422
- nativeParams.append("value", amount.toString());
425
+ if (amount !== undefined) {
426
+ nativeParams.append("value", amount.toString());
427
+ }
423
428
  const url = `ethereum:${address}@${chainId}?${nativeParams.toString()}`;
424
429
  return url;
425
430
  }
@@ -438,60 +443,65 @@ export function getPaymentUrl(address, amount, currency, chainId, decimals) {
438
443
  const isNativeSOL = currency === chain.nativeToken.symbol || currency === "SOL" || currency === "11111111111111111111111111111111";
439
444
  if (isNativeSOL) {
440
445
  // Native SOL transfers - convert from lamports to SOL
441
- let displayAmount;
442
- if (decimals !== undefined) {
443
- const divisor = BigInt(10 ** decimals);
444
- const wholePart = amount / divisor;
445
- const fractionalPart = amount % divisor;
446
- if (fractionalPart === BigInt(0)) {
447
- displayAmount = wholePart.toString();
448
- }
449
- else {
450
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
451
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
452
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
453
- }
454
- }
455
- else {
456
- // Fallback: assume SOL has 9 decimals
457
- const divisor = BigInt(1000000000); // 1e9
458
- const wholePart = amount / divisor;
459
- const fractionalPart = amount % divisor;
460
- if (fractionalPart === BigInt(0)) {
461
- displayAmount = wholePart.toString();
446
+ if (amount !== undefined) {
447
+ let displayAmount;
448
+ if (decimals !== undefined) {
449
+ const divisor = BigInt(10 ** decimals);
450
+ const wholePart = amount / divisor;
451
+ const fractionalPart = amount % divisor;
452
+ if (fractionalPart === BigInt(0)) {
453
+ displayAmount = wholePart.toString();
454
+ }
455
+ else {
456
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
457
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
458
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
459
+ }
462
460
  }
463
461
  else {
464
- const fractionalStr = fractionalPart.toString().padStart(9, "0");
465
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
466
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
462
+ // Fallback: assume SOL has 9 decimals
463
+ const divisor = BigInt(1000000000); // 1e9
464
+ const wholePart = amount / divisor;
465
+ const fractionalPart = amount % divisor;
466
+ if (fractionalPart === BigInt(0)) {
467
+ displayAmount = wholePart.toString();
468
+ }
469
+ else {
470
+ const fractionalStr = fractionalPart.toString().padStart(9, "0");
471
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
472
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
473
+ }
467
474
  }
475
+ // For native SOL, use simple format without spl-token parameter
476
+ params.append("amount", displayAmount);
468
477
  }
469
- // For native SOL, use simple format without spl-token parameter
470
- params.append("amount", displayAmount);
471
478
  }
472
479
  else {
473
480
  // SPL token transfers
474
- let displayAmount;
475
- if (decimals !== undefined) {
476
- const divisor = BigInt(10 ** decimals);
477
- const wholePart = amount / divisor;
478
- const fractionalPart = amount % divisor;
479
- if (fractionalPart === BigInt(0)) {
480
- displayAmount = wholePart.toString();
481
+ if (amount !== undefined) {
482
+ let displayAmount;
483
+ if (decimals !== undefined) {
484
+ const divisor = BigInt(10 ** decimals);
485
+ const wholePart = amount / divisor;
486
+ const fractionalPart = amount % divisor;
487
+ if (fractionalPart === BigInt(0)) {
488
+ displayAmount = wholePart.toString();
489
+ }
490
+ else {
491
+ const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
492
+ const trimmedFractional = fractionalStr.replace(/0+$/, "");
493
+ displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
494
+ }
481
495
  }
482
496
  else {
483
- const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
484
- const trimmedFractional = fractionalStr.replace(/0+$/, "");
485
- displayAmount = trimmedFractional ? `${wholePart}.${trimmedFractional}` : wholePart.toString();
497
+ displayAmount = amount.toString();
486
498
  }
499
+ params.append("amount", displayAmount);
487
500
  }
488
- else {
489
- displayAmount = amount.toString();
490
- }
491
- params.append("amount", displayAmount);
492
501
  params.append("spl-token", currency); // token mint address
493
502
  }
494
- const url = `solana:${address}?${params.toString()}`;
503
+ const queryString = params.toString();
504
+ const url = queryString ? `solana:${address}?${queryString}` : `solana:${address}`;
495
505
  console.log("Solana URL (isNativeSOL:", isNativeSOL, "):", url);
496
506
  return url;
497
507
  }
@@ -2,6 +2,7 @@ import { AuthenticationClient } from "@feathersjs/authentication-client";
2
2
  import Cookies from "js-cookie";
3
3
  import { B3_AUTH_COOKIE_NAME } from "./shared/constants/index.js";
4
4
  export const B3_API_URL = process.env.EXPO_PUBLIC_B3_API || process.env.NEXT_PUBLIC_B3_API || process.env.PUBLIC_B3_API || "https://api.b3.fun";
5
+ const DEV_USER_GROUP = 4;
5
6
  export const authenticate = async (app, accessToken, identityToken, params) => {
6
7
  const fullToken = `${accessToken}+${identityToken}`;
7
8
  // Do not authenticate if there is no token
@@ -16,6 +17,13 @@ export const authenticate = async (app, accessToken, identityToken, params) => {
16
17
  }, {
17
18
  query: params || {},
18
19
  });
20
+ // Extend cookie expiration to 30 days for dev users
21
+ if (response?.user?.userGroups?.includes(DEV_USER_GROUP)) {
22
+ const token = Cookies.get(B3_AUTH_COOKIE_NAME);
23
+ if (token) {
24
+ Cookies.set(B3_AUTH_COOKIE_NAME, token, { expires: 30 });
25
+ }
26
+ }
19
27
  return response;
20
28
  }
21
29
  catch (error) {
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { AnySpend, AnySpendBondKit, AnySpendBuySpin, AnySpendCollectorClubPurchase, AnySpendNFT, AnyspendSignatureMint, AnySpendStakeB3, AnySpendStakeB3ExactIn, AnySpendTournament, OrderHistory, } from "../../../anyspend/react/index.js";
3
3
  import { AnySpendDeposit } from "../../../anyspend/react/components/AnySpendDeposit.js";
4
4
  import { AnySpendDepositHype } from "../../../anyspend/react/components/AnyspendDepositHype.js";
5
+ import { AnySpendWorkflowTrigger } from "../../../anyspend/react/components/AnySpendWorkflowTrigger.js";
5
6
  import { AnySpendDepositUpside } from "../../../anyspend/react/components/AnySpendDepositUpside.js";
6
7
  import { AnySpendStakeUpside } from "../../../anyspend/react/components/AnySpendStakeUpside.js";
7
8
  import { AnySpendStakeUpsideExactIn } from "../../../anyspend/react/components/AnySpendStakeUpsideExactIn.js";
@@ -52,6 +53,7 @@ export function B3DynamicModal() {
52
53
  "send",
53
54
  "notifications",
54
55
  "anySpendDeposit",
56
+ "anySpendWorkflowTrigger",
55
57
  ];
56
58
  const freestyleTypes = [
57
59
  "anySpendNft",
@@ -122,6 +124,8 @@ export function B3DynamicModal() {
122
124
  return _jsx(AnySpendCollectorClubPurchase, { ...contentType, mode: "modal" });
123
125
  case "anySpendDeposit":
124
126
  return _jsx(AnySpendDeposit, { ...contentType, mode: "modal" });
127
+ case "anySpendWorkflowTrigger":
128
+ return _jsx(AnySpendWorkflowTrigger, { ...contentType, mode: "modal" });
125
129
  case "avatarEditor":
126
130
  return _jsx(AvatarEditor, { onSetAvatar: contentType.onSuccess });
127
131
  case "deposit":