@b3dotfun/sdk 0.1.65-alpha.5 → 0.1.65-alpha.6

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 (53) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +4 -2
  3. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  4. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  5. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  6. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +2 -2
  7. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  8. package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +3 -3
  9. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  10. package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +3 -57
  11. package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
  12. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  13. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  14. package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  15. package/dist/cjs/anyspend/services/anyspend.d.ts +2 -1
  16. package/dist/cjs/anyspend/services/anyspend.js +2 -1
  17. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +2 -0
  18. package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -0
  19. package/dist/esm/anyspend/react/components/AnySpend.js +4 -2
  20. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  21. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +4 -2
  22. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  23. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +2 -2
  24. package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  25. package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +3 -3
  26. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  27. package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +2 -56
  28. package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
  29. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +1 -0
  30. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  31. package/dist/esm/anyspend/react/hooks/useAnyspendCreateOrder.js +1 -0
  32. package/dist/esm/anyspend/services/anyspend.d.ts +2 -1
  33. package/dist/esm/anyspend/services/anyspend.js +2 -1
  34. package/dist/esm/global-account/react/stores/useModalStore.d.ts +2 -0
  35. package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -0
  36. package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +2 -0
  37. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  38. package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +1 -3
  39. package/dist/types/anyspend/react/components/common/OrderTokenAmount.d.ts +1 -4
  40. package/dist/types/anyspend/react/hooks/useAnyspendCreateOrder.d.ts +1 -0
  41. package/dist/types/anyspend/services/anyspend.d.ts +2 -1
  42. package/dist/types/global-account/react/stores/useModalStore.d.ts +2 -0
  43. package/package.json +1 -1
  44. package/src/anyspend/react/components/AnySpend.tsx +6 -1
  45. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +5 -1
  46. package/src/anyspend/react/components/AnySpendDeposit.tsx +5 -0
  47. package/src/anyspend/react/components/common/CryptoPaySection.tsx +0 -5
  48. package/src/anyspend/react/components/common/OrderTokenAmount.tsx +1 -70
  49. package/src/anyspend/react/components/common/PaySection.tsx +0 -1
  50. package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +1 -0
  51. package/src/anyspend/react/hooks/useAnyspendCreateOrder.ts +2 -0
  52. package/src/anyspend/services/anyspend.ts +3 -0
  53. package/src/global-account/react/stores/useModalStore.ts +2 -0
@@ -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, {
@@ -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) {
@@ -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();
@@ -536,6 +536,8 @@ export interface AnySpendDepositModalProps extends BaseModalProps {
536
536
  classes?: AnySpendAllClasses;
537
537
  /** Whether to allow direct transfer without swap */
538
538
  allowDirectTransfer?: boolean;
539
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
540
+ callbackMetadata?: Record<string, unknown>;
539
541
  }
540
542
  /**
541
543
  * Union type of all possible modal content types
@@ -53,4 +53,6 @@ export declare function AnySpend(props: {
53
53
  allowDirectTransfer?: boolean;
54
54
  /** Fixed destination token amount (in wei/smallest unit). When provided, user cannot change the amount. */
55
55
  destinationTokenAmount?: string;
56
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
57
+ callbackMetadata?: Record<string, unknown>;
56
58
  }): import("react/jsx-runtime").JSX.Element;
@@ -44,6 +44,8 @@ export interface AnySpendCustomExactInProps {
44
44
  classes?: AnySpendCustomExactInClasses;
45
45
  /** When true, allows direct transfer without swap if source and destination token/chain are the same */
46
46
  allowDirectTransfer?: boolean;
47
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
48
+ callbackMetadata?: Record<string, unknown>;
47
49
  }
48
50
  export declare function AnySpendCustomExactIn(props: AnySpendCustomExactInProps): import("react/jsx-runtime").JSX.Element;
49
51
  export {};
@@ -101,6 +101,8 @@ export interface AnySpendDepositProps {
101
101
  allowDirectTransfer?: boolean;
102
102
  /** Fixed destination token amount (in wei/smallest unit). When provided, user cannot change the amount. */
103
103
  destinationTokenAmount?: string;
104
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
105
+ callbackMetadata?: Record<string, unknown>;
104
106
  }
105
107
  /**
106
108
  * A flexible deposit component that wraps AnySpendCustomExactIn with optional chain selection.
@@ -137,4 +139,4 @@ export interface AnySpendDepositProps {
137
139
  * onSuccess={(amount) => console.log(`Deposited ${amount}`)}
138
140
  * />
139
141
  */
140
- export declare function AnySpendDeposit({ loadOrder, mode, recipientAddress, paymentType: initialPaymentType, sourceTokenAddress, sourceTokenChainId: initialSourceChainId, destinationTokenAddress, destinationTokenChainId, onSuccess, onOpenCustomModal, mainFooter, onTokenSelect, customUsdInputValues, preferEoa, minDestinationAmount, header, orderType, depositContractConfig, showChainSelection, supportedChains, minPoolSize, topChainsCount, onClose, returnToHomeUrl, customRecipientLabel, returnHomeLabel, isCustomDeposit, classes, allowDirectTransfer, destinationTokenAmount, }: AnySpendDepositProps): import("react/jsx-runtime").JSX.Element | null;
142
+ export declare function AnySpendDeposit({ loadOrder, mode, recipientAddress, paymentType: initialPaymentType, sourceTokenAddress, sourceTokenChainId: initialSourceChainId, destinationTokenAddress, destinationTokenChainId, onSuccess, onOpenCustomModal, mainFooter, onTokenSelect, customUsdInputValues, preferEoa, minDestinationAmount, header, orderType, depositContractConfig, showChainSelection, supportedChains, minPoolSize, topChainsCount, onClose, returnToHomeUrl, customRecipientLabel, returnHomeLabel, isCustomDeposit, classes, allowDirectTransfer, destinationTokenAmount, callbackMetadata, }: AnySpendDepositProps): import("react/jsx-runtime").JSX.Element | null;
@@ -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 {};
@@ -1,5 +1,5 @@
1
1
  import { components } from "@b3dotfun/sdk/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;
@@ -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;
@@ -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;
@@ -536,6 +536,8 @@ export interface AnySpendDepositModalProps extends BaseModalProps {
536
536
  classes?: AnySpendAllClasses;
537
537
  /** Whether to allow direct transfer without swap */
538
538
  allowDirectTransfer?: boolean;
539
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
540
+ callbackMetadata?: Record<string, unknown>;
539
541
  }
540
542
  /**
541
543
  * Union type of all possible modal content types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.1.65-alpha.5",
3
+ "version": "0.1.65-alpha.6",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -127,6 +127,8 @@ export function AnySpend(props: {
127
127
  allowDirectTransfer?: boolean;
128
128
  /** Fixed destination token amount (in wei/smallest unit). When provided, user cannot change the amount. */
129
129
  destinationTokenAmount?: string;
130
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
131
+ callbackMetadata?: Record<string, unknown>;
130
132
  }) {
131
133
  const fingerprintConfig = getFingerprintConfig();
132
134
 
@@ -159,6 +161,7 @@ function AnySpendInner({
159
161
  classes,
160
162
  allowDirectTransfer = false,
161
163
  destinationTokenAmount,
164
+ callbackMetadata,
162
165
  }: {
163
166
  sourceChainId?: number;
164
167
  destinationTokenAddress?: string;
@@ -180,6 +183,7 @@ function AnySpendInner({
180
183
  classes?: AnySpendClasses;
181
184
  allowDirectTransfer?: boolean;
182
185
  destinationTokenAmount?: string;
186
+ callbackMetadata?: Record<string, unknown>;
183
187
  }) {
184
188
  const searchParams = useSearchParamsSSR();
185
189
  const router = useRouter();
@@ -966,6 +970,7 @@ function AnySpendInner({
966
970
  srcAmount: srcAmountBigInt.toString(),
967
971
  expectedDstAmount: anyspendQuote?.data?.currencyOut?.amount || "0",
968
972
  creatorAddress: globalAddress,
973
+ callbackMetadata,
969
974
  });
970
975
  } catch (err: any) {
971
976
  console.error(err);
@@ -1043,6 +1048,7 @@ function AnySpendInner({
1043
1048
  },
1044
1049
  expectedDstAmount: anyspendQuote?.data?.currencyOut?.amount?.toString() || "0",
1045
1050
  creatorAddress: globalAddress,
1051
+ callbackMetadata,
1046
1052
  });
1047
1053
  } catch (err: any) {
1048
1054
  console.error(err);
@@ -1214,7 +1220,6 @@ function AnySpendInner({
1214
1220
  anyspendQuote={anyspendQuote}
1215
1221
  onTokenSelect={onTokenSelect}
1216
1222
  onShowFeeDetail={() => navigateToPanel(PanelView.FEE_DETAIL, "forward")}
1217
- skipAutoMaxOnTokenChange={!!destinationTokenAmount}
1218
1223
  />
1219
1224
  ) : (
1220
1225
  <motion.div
@@ -83,6 +83,8 @@ export interface AnySpendCustomExactInProps {
83
83
  classes?: AnySpendCustomExactInClasses;
84
84
  /** When true, allows direct transfer without swap if source and destination token/chain are the same */
85
85
  allowDirectTransfer?: boolean;
86
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
87
+ callbackMetadata?: Record<string, unknown>;
86
88
  }
87
89
 
88
90
  export function AnySpendCustomExactIn(props: AnySpendCustomExactInProps) {
@@ -120,6 +122,7 @@ function AnySpendCustomExactInInner({
120
122
  returnHomeLabel,
121
123
  classes,
122
124
  allowDirectTransfer = false,
125
+ callbackMetadata,
123
126
  }: AnySpendCustomExactInProps) {
124
127
  const actionLabel = customExactInConfig?.action ?? "Custom Execution";
125
128
  const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
@@ -418,7 +421,6 @@ function AnySpendCustomExactInInner({
418
421
  onSelectCryptoPaymentMethod={() => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD)}
419
422
  anyspendQuote={anyspendQuote}
420
423
  onTokenSelect={onTokenSelect}
421
- skipAutoMaxOnTokenChange={!!destinationTokenAmount}
422
424
  />
423
425
  ) : (
424
426
  <motion.div
@@ -587,6 +589,7 @@ function AnySpendCustomExactInInner({
587
589
  ? normalizeAddress(customExactInConfig.spenderAddress)
588
590
  : undefined,
589
591
  },
592
+ callbackMetadata,
590
593
  });
591
594
  } else {
592
595
  // EXACT_INPUT mode: create custom_exact_in order (original behavior)
@@ -604,6 +607,7 @@ function AnySpendCustomExactInInner({
604
607
  expectedDstAmount: expectedDstAmountRaw,
605
608
  creatorAddress: globalAddress,
606
609
  payload,
610
+ callbackMetadata,
607
611
  });
608
612
  }
609
613
  } catch (err: any) {
@@ -123,6 +123,8 @@ export interface AnySpendDepositProps {
123
123
  allowDirectTransfer?: boolean;
124
124
  /** Fixed destination token amount (in wei/smallest unit). When provided, user cannot change the amount. */
125
125
  destinationTokenAmount?: string;
126
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
127
+ callbackMetadata?: Record<string, unknown>;
126
128
  }
127
129
 
128
130
  // Default supported chains
@@ -248,6 +250,7 @@ export function AnySpendDeposit({
248
250
  classes,
249
251
  allowDirectTransfer = false,
250
252
  destinationTokenAmount,
253
+ callbackMetadata,
251
254
  }: AnySpendDepositProps) {
252
255
  // Extract deposit-specific classes for convenience
253
256
  const depositClasses = classes?.deposit;
@@ -697,6 +700,7 @@ export function AnySpendDeposit({
697
700
  classes={classes?.customExactIn}
698
701
  allowDirectTransfer={allowDirectTransfer}
699
702
  destinationTokenAmount={destinationTokenAmount}
703
+ callbackMetadata={callbackMetadata}
700
704
  />
701
705
  ) : (
702
706
  <AnySpend
@@ -720,6 +724,7 @@ export function AnySpendDeposit({
720
724
  classes={classes?.anySpend}
721
725
  allowDirectTransfer={allowDirectTransfer}
722
726
  destinationTokenAmount={destinationTokenAmount}
727
+ callbackMetadata={callbackMetadata}
723
728
  />
724
729
  )}
725
730
  </div>
@@ -32,8 +32,6 @@ interface CryptoPaySectionProps {
32
32
  onShowFeeDetail?: () => void;
33
33
  // Custom classes for styling
34
34
  classes?: CryptoPaySectionClasses;
35
- /** When true, skip auto-setting max balance when token changes (used for fixed destination amount mode) */
36
- skipAutoMaxOnTokenChange?: boolean;
37
35
  }
38
36
 
39
37
  export function CryptoPaySection({
@@ -51,7 +49,6 @@ export function CryptoPaySection({
51
49
  onTokenSelect,
52
50
  onShowFeeDetail,
53
51
  classes,
54
- skipAutoMaxOnTokenChange = false,
55
52
  }: CryptoPaySectionProps) {
56
53
  const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
57
54
 
@@ -125,7 +122,6 @@ export function CryptoPaySection({
125
122
  <div className={classes?.inputContainer}>
126
123
  <OrderTokenAmount
127
124
  address={walletAddress}
128
- walletAddress={walletAddress}
129
125
  context="from"
130
126
  inputValue={srcAmount}
131
127
  onChangeInput={value => {
@@ -137,7 +133,6 @@ export function CryptoPaySection({
137
133
  token={selectedSrcToken}
138
134
  setToken={setSelectedSrcToken}
139
135
  onTokenSelect={onTokenSelect}
140
- skipAutoMaxOnTokenChange={skipAutoMaxOnTokenChange}
141
136
  />
142
137
  </div>
143
138
  <div className={classes?.balanceRow || "flex items-center justify-between"}>
@@ -1,15 +1,11 @@
1
1
  "use client";
2
2
 
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
 
8
6
  import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID, getAvailableChainIds } from "@b3dotfun/sdk/anyspend";
9
7
  import { components } from "@b3dotfun/sdk/anyspend/types/api";
10
- import { getNativeRequired } from "@b3dotfun/sdk/anyspend/utils/chain";
11
- import { isNativeToken } from "@b3dotfun/sdk/anyspend/utils/token";
12
- import { Button, useTokenBalance } from "@b3dotfun/sdk/global-account/react";
8
+ import { Button } from "@b3dotfun/sdk/global-account/react";
13
9
  import { cn } from "@b3dotfun/sdk/shared/utils";
14
10
  import { TokenSelector } from "@relayprotocol/relay-kit-ui";
15
11
  import { ChainTokenIcon } from "./ChainTokenIcon";
@@ -31,8 +27,6 @@ export function OrderTokenAmount({
31
27
  amountClassName,
32
28
  tokenSelectClassName,
33
29
  onTokenSelect,
34
- walletAddress,
35
- skipAutoMaxOnTokenChange = false,
36
30
  }: {
37
31
  disabled?: boolean;
38
32
  inputValue: string;
@@ -50,64 +44,7 @@ export function OrderTokenAmount({
50
44
  amountClassName?: string;
51
45
  tokenSelectClassName?: string;
52
46
  onTokenSelect?: (token: components["schemas"]["Token"], event: { preventDefault: () => void }) => void;
53
- walletAddress?: string | undefined;
54
- /** When true, skip auto-setting max balance when token changes (used for fixed destination amount mode) */
55
- skipAutoMaxOnTokenChange?: boolean;
56
47
  }) {
57
- // Track previous token to detect changes
58
- const prevTokenRef = useRef<string>(token.address);
59
-
60
- // Only get token balance when context is "from" (for setting max amount)
61
- const { rawBalance } = useTokenBalance({
62
- token,
63
- address: context === "from" && walletAddress ? walletAddress : undefined,
64
- });
65
-
66
- useEffect(() => {
67
- // Only handle "from" context
68
- if (context !== "from") return;
69
-
70
- // Skip auto-max when in fixed destination amount mode
71
- if (skipAutoMaxOnTokenChange) {
72
- prevTokenRef.current = token.address;
73
- return;
74
- }
75
-
76
- // Check if token changed or if this is the initial load with balance
77
- const isTokenChanged = prevTokenRef.current !== token.address;
78
-
79
- if (isTokenChanged && rawBalance) {
80
- console.log(`Setting max balance - Token: ${token.address}, Changed: ${isTokenChanged}`);
81
-
82
- // Calculate max amount with gas reserve for native tokens
83
- let maxAmount: bigint;
84
-
85
- if (isNativeToken(token.address)) {
86
- const gasReserve = getNativeRequired(token.chainId);
87
- // Ensure we don't go negative
88
- maxAmount = rawBalance > gasReserve ? rawBalance - gasReserve : BigInt(0);
89
- } else {
90
- // For ERC20 tokens, use full balance
91
- maxAmount = rawBalance;
92
- }
93
-
94
- // Set the max amount as input value
95
- onChangeInput(formatUnits(maxAmount, token.decimals));
96
-
97
- // Update refs
98
- prevTokenRef.current = token.address;
99
- }
100
- }, [
101
- token.address,
102
- token.chainId,
103
- token.decimals,
104
- chainId,
105
- context,
106
- onChangeInput,
107
- rawBalance,
108
- skipAutoMaxOnTokenChange,
109
- ]);
110
-
111
48
  const handleTokenSelect = (newToken: any) => {
112
49
  const token: components["schemas"]["Token"] = {
113
50
  address: newToken.address,
@@ -134,13 +71,7 @@ export function OrderTokenAmount({
134
71
  }
135
72
  }
136
73
 
137
- // Mark that we're about to change tokens
138
- prevTokenRef.current = "changing"; // Temporary value to force effect
139
-
140
- // Set the chain ID first
141
74
  setChainId(newToken.chainId);
142
-
143
- // Then set the new token - the useEffect will handle setting the max balance
144
75
  setToken(token);
145
76
  };
146
77
 
@@ -116,7 +116,6 @@ export function CryptoPaySection({
116
116
  </div>
117
117
  <OrderTokenAmount
118
118
  address={connectedAddress}
119
- walletAddress={connectedAddress}
120
119
  context="from"
121
120
  inputValue={srcAmount}
122
121
  onChangeInput={value => {
@@ -113,6 +113,7 @@ export function useAnyspendCreateOnrampOrder({ onSuccess, onError }: UseAnyspend
113
113
  partnerId,
114
114
  clientReferenceId,
115
115
  visitorData,
116
+ callbackMetadata: params.callbackMetadata,
116
117
  });
117
118
  } catch (error: any) {
118
119
  // If the error has a response with message and statusCode, throw that
@@ -22,6 +22,7 @@ export type CreateOrderParams = {
22
22
  creatorAddress?: string;
23
23
  payload?: any;
24
24
  metadata?: Record<string, any>;
25
+ callbackMetadata?: Record<string, unknown>;
25
26
  };
26
27
 
27
28
  export type UseAnyspendCreateOrderProps = {
@@ -87,6 +88,7 @@ export function useAnyspendCreateOrder({ onSuccess, onError }: UseAnyspendCreate
87
88
  partnerId,
88
89
  clientReferenceId,
89
90
  visitorData,
91
+ callbackMetadata: params.callbackMetadata,
90
92
  });
91
93
  } catch (error: any) {
92
94
  // If the error has a response with message and statusCode, throw that
@@ -70,6 +70,7 @@ export const anyspendService = {
70
70
  partnerId,
71
71
  clientReferenceId,
72
72
  visitorData,
73
+ callbackMetadata,
73
74
  }: {
74
75
  recipientAddress: string;
75
76
  type: string;
@@ -85,6 +86,7 @@ export const anyspendService = {
85
86
  partnerId?: string;
86
87
  clientReferenceId?: string;
87
88
  visitorData?: VisitorData;
89
+ callbackMetadata?: Record<string, unknown>;
88
90
  }) => {
89
91
  const accessToken = await app.authentication.getAccessToken();
90
92
  const response = await fetch(`${ANYSPEND_MAINNET_BASE_URL}/orders`, {
@@ -109,6 +111,7 @@ export const anyspendService = {
109
111
  creatorAddress,
110
112
  partnerId,
111
113
  ...(clientReferenceId && { clientReferenceId }),
114
+ ...(callbackMetadata && { callbackMetadata }),
112
115
  }),
113
116
  });
114
117
  const data: CreateOrderResponse = await response.json();
@@ -562,6 +562,8 @@ export interface AnySpendDepositModalProps extends BaseModalProps {
562
562
  classes?: AnySpendAllClasses;
563
563
  /** Whether to allow direct transfer without swap */
564
564
  allowDirectTransfer?: boolean;
565
+ /** Opaque metadata passed to the order for callbacks (e.g., workflow form data) */
566
+ callbackMetadata?: Record<string, unknown>;
565
567
  }
566
568
 
567
569
  /**