UNPKG

@funkit/connect

Version:

Funkit Connect SDK elevates DeFi apps via web2 sign-ins and one-click checkouts.

164 lines (163 loc) 6.82 kB
import type { Dnum } from 'dnum'; import type { Address } from 'viem'; import { type PaymentMethodInfo } from '../../../domains/paymentMethods'; import type { QuoteBuilder } from '../../../domains/quoteMode/types'; import type { AssetHoldingsItem } from '../../../utils/assets'; import type { FunkitCheckoutConfig } from '../../../providers/FunkitCheckoutContext'; export interface AmountInputInitOptions { checkoutConfig: FunkitCheckoutConfig; paymentMethodInfo: PaymentMethodInfo; sourceHolding: AssetHoldingsItem | null; /** Default amount, in fiat since that's the default mode */ defaultAmount: number | undefined; /** Target asset unit price, in USD */ unitPrice: number; /** Maximum checkout amount, in USD */ maxUsd: number; /** Minimum checkout amount, in USD */ minUsd?: number; /** Currency code for the currently selected fiat currency. Defaults to USD */ fiatCurrency?: string; /** Locale */ locale: Intl.LocalesArgument; /** Quick options, in fiat (not %) */ quickOptions?: number[]; /** Whether meld is enabled */ meldEnabled: boolean; apiKey: string; /** Default value for isInputInFiat (preserved from modal state when navigating back) */ defaultIsInputInFiat?: boolean; /** Preserved token amount (in human-readable form) from a previous visit */ defaultAssetAmount?: number; /** Quote builder adapter (EXACT_IN / EXACT_OUT / ONE_TO_ONE) */ quoteBuilder: QuoteBuilder; /** Whether the source token is the chain's native gas token */ isNativeToken: boolean; /** Current gas price in wei (for native token gas buffer calculation) */ gasPriceWei: bigint | null; /** Gas-unit buffer reserved for the checkout tx (from Statsig dynamic config) */ gasUnits: bigint; } export interface AmountInputState { /** Current amount, in target asset. Undefined if input is empty */ assetAmount: number | undefined; /** Current amount, in fiat. Undefined if input is empty */ fiatAmount: number | undefined; /** Fiat currency */ fiatCurrency: string; /** Current input value (with leading currency symbol if in fiat) */ inputValue: string; /** Whether the input is currently in fiat */ isInputInFiat: boolean; /** Locale */ locale: Intl.LocalesArgument; /** Estimated available amount, in USD (defaults to unlimited) */ usdAvailableAmount: number | null; /** Maximum amount, in USD (defaults to unlimited) */ usdMaxAmount: number | null; /** Minimum amount, in USD (defaults to 0) */ usdMinAmount: number | null; /** Whether meld is enabled */ meldEnabled: boolean; /** Frozen token→USD exchange rate, set on InputAmount screen mount */ frozenUnitPrice?: number; /** Exact token balance as a Dnum (decimals embedded) */ tokenBalanceBaseUnit: Dnum | null; /** Whether quote mode is EXACT_IN (token amount is source of truth) */ isExactIn: boolean; /** Canonical token amount as a Dnum, set by setTokenAmount for lossless balance comparison */ tokenAmountBaseUnit: Dnum | null; /** Maximum sendable token amount, accounting for gas buffer on native tokens */ maxSendableAmount: Dnum | null; } /** Derived state includes additional fields that are pure functions of base state */ export interface AmountInputDerivedState extends AmountInputState { inputDecimals: number; inputError: AmountInputError | null; inputAffix: { content: string; type: 'prefix' | 'suffix'; }; isValid: boolean; placeholder: string; /** Decimal separator based on locale (e.g., '.' for en-US, ',' for de-DE) */ decimalSeparator: string; } export type AmountInputAction = { /** Switches between fiat and crypto input mode */ type: 'toggleInputInFiat'; } | { /** Sets the input value as string */ type: 'setInputValue'; inputValue: string; unitPrice: number; } | { /** Sets the input value as fiat amount */ type: 'setFiatAmount'; fiatAmount: number; unitPrice: number; } | { /** Changes formatting to new currency code */ type: 'setFiatCurrency'; fiatCurrency: string; } | { /** Sets the input value as an exact token amount (for EXACT_IN max button) */ type: 'setTokenAmount'; /** Exact token amount as a Dnum (decimals embedded) */ tokenAmountBaseUnit: Dnum; frozenUnitPrice: number; } | { /** Sets the input value as a target asset amount (for EXACT_OUT token-mode quick options) */ type: 'setAssetAmount'; assetAmount: number; unitPrice: number; }; export type AmountInputError = { /** Current amount is above available balance */ type: 'aboveAvailable'; usdAvailableAmount: number; } | { /** Current amount is above maximum */ type: 'aboveMax'; usdMaxAmount: number; } | { /** Current amount is below minimum */ type: 'belowMin'; usdMinAmount: number; } | { /** Available balance is 0 */ type: 'noAvailableBalance'; } | { /** Input is empty */ type: 'noInput'; }; /** * Calculate initial input amount for account balance deposits. * Return half the balance and round up to nearest 10, 100, 1000 etc */ export declare function calcInitialFiatAmount(balance: number): number; /** Minimal source-token identity needed to resolve the default input mode. */ export interface SourceTokenRef { chainId: string; address: Address; } /** * Resolves whether the amount screen should open in fiat (`true`) or token * (`false`) entry. * * Precedence: card and BTC Lightning payments always force fiat (ramps are * fiat-denominated, and Lightning's amount input only supports fiat today). * Lighter **spot** deposits paid with the same asset open in token entry — * perps deposits (and every other customer) keep the fiat default. * A value preserved from prior navigation (`defaultIsInputInFiat`) is handled * by the caller and wins over this. */ export declare function resolveDefaultIsInputInFiat({ checkoutConfig, paymentMethodInfo, sourceToken, apiKey, }: { checkoutConfig: FunkitCheckoutConfig; paymentMethodInfo: PaymentMethodInfo; sourceToken: SourceTokenRef | null; apiKey: string; }): boolean; export declare function initializeState({ checkoutConfig, defaultAmount, fiatCurrency, quoteBuilder, locale, maxUsd, minUsd, paymentMethodInfo, quickOptions, sourceHolding, unitPrice: realUnitPrice, meldEnabled, apiKey, defaultAssetAmount, defaultIsInputInFiat, isNativeToken, gasPriceWei, gasUnits, }: AmountInputInitOptions): AmountInputState; export declare function reduceState(state: AmountInputState, action: AmountInputAction): AmountInputState; export declare function getDerivedState(state: AmountInputState, _targetAssetTicker: string): AmountInputDerivedState;