import {z} from 'zod' export type MoneyMovementsCreateOnchainWithdrawalInput = {account_id: string, amount: string}; export type CreateApiMoneyOnchainWithdrawalsArgs = {'Idempotency-Key': string, body: MoneyMovementsCreateOnchainWithdrawalInput}; export type CreateApiMoneyOnchainWithdrawalsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const withdrawaltraceEvaluation = z.object({evaluated_ts: z.string(), result: z.enum(["passed", "waiting"]), type: z.enum(["rail_access", "agreements", "destination", "withdrawal_limit", "business_eligibility", "approval", "release_delay", "destination_cooloff", "destination_authorization"])}); export const moneyMovementsMovementExecution = z.literal("after_funding"); export const moneyfmtFormattedMoneyAmountView = z.object({compact: z.string(), currency_sign: z.string(), currency_sign_position: z.string(), full: z.string()}); export const moneyfmtMoneyAmountView = z.object({float: z.number(), formatted: moneyfmtFormattedMoneyAmountView, precise: z.string(), symbol: z.string(), zero: z.boolean()}); export const moneyMovementsTransactionSideView = z.object({amount: moneyfmtMoneyAmountView, amount_estimated: z.boolean(), money_account_id: z.string(), money_symbol: z.string(), payment_rail: z.string().optional(), quoted_amount: moneyfmtMoneyAmountView.optional()}); export const moneyMovementsMovementMetadataView = z.object({created_by: z.string(), created_ts: z.string(), updated_ts: z.string()}); export const moneyMovementsOfframpAmountsView = z.object({bank_fee_usd: z.string(), collected_platform_fee_usdc: z.string(), collection_status: z.enum(["not_needed", "pending", "collected", "failed"]), payout_delivered: z.boolean(), payout_estimated: z.boolean(), payout_usd: z.string(), platform_fee_usdc: z.string(), total_debit_usdc: z.string()}); export const moneyMovementsOnchainTransactionView = z.object({chain: z.string().optional(), explorer_url: z.string().optional(), tx_hash: z.string()}); export const moneyMovementsOnrampAmountsView = z.object({collected_platform_fee_usdc: z.string(), collection_status: z.enum(["not_needed", "pending", "collected", "failed", "insufficient_proceeds"]), first_observed_ts: z.string().nullable().optional(), gross_deposit_usd: z.string(), gross_proceeds_usdc: z.string(), net_usdc: z.string(), platform_fee_usdc: z.string(), pricing_basis: z.string().nullable().optional(), pricing_ts: z.string().nullable().optional(), proceeds_available: z.boolean(), proceeds_estimated: z.boolean()}); export const moneyMovementsRampFeeReturnsView = z.object({original_movement_id: z.string().nullable().optional(), refund_movement_ids: z.array(z.string()).nullable(), refunded: z.boolean(), refunded_usdc: z.string(), waived: z.boolean()}); export const moneyenumLifecycleStatus = z.enum(["pending", "completed", "failed"]); export const moneyenumChain = z.enum(["arbitrum", "base", "ethereum", "polygon", "solana", "stellar"]); export const moneyMovementsSwapTradeView = z.object({chain: moneyenumChain, rate: z.string(), trade_booked: z.boolean()}); export const moneyMovementsMoneyMovementView = z.object({automation_id: z.string().nullable().optional(), complete: z.boolean(), completed_ts: z.string().optional(), controls: z.array(withdrawaltraceEvaluation).optional(), created_by: z.string(), created_ts: z.string(), estimated_execution_ts: z.string().optional(), execution: moneyMovementsMovementExecution.optional(), failed_ts: z.string().optional(), fee: moneyfmtMoneyAmountView.optional(), fund_symbol: z.string().optional(), group_id: z.string(), id: z.string(), input: moneyMovementsTransactionSideView, metadata: moneyMovementsMovementMetadataView, net_amount_estimated: z.boolean().optional(), net_amount_view: moneyfmtMoneyAmountView.optional(), occurred_ts: z.string(), offramp_amounts: moneyMovementsOfframpAmountsView.optional(), onchain_transactions: z.array(moneyMovementsOnchainTransactionView).optional(), onramp_amounts: moneyMovementsOnrampAmountsView.optional(), output: moneyMovementsTransactionSideView, price_per_unit_estimated: z.boolean().optional(), price_per_unit_view: moneyfmtMoneyAmountView.optional(), quoted_net_amount_view: moneyfmtMoneyAmountView.optional(), quoted_price_per_unit_view: moneyfmtMoneyAmountView.optional(), ramp_fee_returns: moneyMovementsRampFeeReturnsView.optional(), settlement_commission_view: moneyfmtMoneyAmountView.optional(), settlement_pathway: z.string().optional(), settlement_ts: z.string().optional(), status: moneyenumLifecycleStatus, swap: moneyMovementsSwapTradeView.optional(), transaction_count: z.number().int(), type: z.string()}); export const moneyMovementsApprovalRequirementKind = z.enum(["ordinary_quorum", "additional_named", "selected_member"]); export const moneyMovementsApprovalRequirementSource = z.enum(["business", "member"]); export const moneyMovementsApprovalClauseView = z.object({approvals_received: z.number().int().gte(0).optional(), count: z.number().int().gte(1).optional(), excluded_individual_ids: z.array(z.string()).optional(), individual_id: z.string().optional(), individual_name: z.string().optional(), kind: moneyMovementsApprovalRequirementKind.optional(), progress_available: z.boolean().optional(), satisfied: z.boolean().optional(), source: moneyMovementsApprovalRequirementSource.optional()}); export const moneyMovementsApprovalValuationStatus = z.enum(["valued", "unavailable"]); export const moneyMovementsApprovalPolicyValuationView = z.object({amount_usd: z.string().nullable().optional(), amount_usd_view: z.union([moneyfmtMoneyAmountView, z.unknown()]).optional(), status: moneyMovementsApprovalValuationStatus.optional()}); export const moneyMovementsApprovalPolicyView = z.object({action_allowed: z.boolean().optional(), business_policy_revision: z.string().nullable().optional(), permission_allowed: z.boolean().optional(), requirements: z.array(moneyMovementsApprovalClauseView).nullable().optional(), revision: z.string().optional(), valuation: moneyMovementsApprovalPolicyValuationView.optional()}); export const moneyMovementsTransferApprovalAssetDisplay = z.object({amount: z.string().optional(), network: z.string().optional(), symbol: z.string().optional()}); export const moneyMovementsRampFeeDisclosure = z.object({bank_fee_usd: z.string(), platform_fee_usdc: z.string(), total_debit_usdc: z.string()}); export const moneyMovementsTransferApprovalDestination = z.object({account_id: z.string().optional(), masked_account: z.string().optional(), masked_address: z.string().optional()}); export const moneyMovementsTransferApprovalNetwork = z.enum(["ethereum", "stellar", "solana"]); export const moneyMovementsTransferApprovalFundRoute = z.object({pathway: z.enum(["standard", "express"]).optional(), pathway_defaulted: z.boolean().optional(), source: z.enum(["platform", "stellar", "solana"]).optional(), source_defaulted: z.boolean().optional(), source_network: moneyMovementsTransferApprovalNetwork.optional()}); export const moneyMovementsTransferApprovalInstructions = z.object({action: z.enum(["buy", "sell", "withdrawal"]).optional(), amount: moneyfmtMoneyAmountView.optional(), asset_symbol: z.string().optional(), destination: moneyMovementsTransferApprovalDestination.optional(), fund_route: moneyMovementsTransferApprovalFundRoute.optional()}); export const moneyMovementsTransferApprovalStatus = z.enum(["pending", "approved", "denied", "cancelled", "expired", "policy_changed", "failed"]); export const moneyenumTransferApprovalVoteDecision = z.enum(["approved", "denied"]); export const moneyMovementsTransferApprovalVoteView = z.object({approver: z.string().optional(), approver_name: z.string().optional(), decision: moneyenumTransferApprovalVoteDecision.optional(), note: z.string().max(500).optional(), voted_ts: z.string().optional()}); export const moneyMovementsTransferApprovalView = z.object({also_required_ind_id: z.string().nullable().optional(), also_required_name: z.string().optional(), also_required_satisfied: z.boolean().optional(), amount_usd: moneyfmtMoneyAmountView.optional(), approvals_received: z.number().int().optional(), composed_policy: moneyMovementsApprovalPolicyView.optional(), controls: z.array(withdrawaltraceEvaluation).optional(), current_approver_names: z.array(z.string()).nullable().optional(), decided_by: z.string().nullable().optional(), decided_ts: z.string().nullable().optional(), decider_name: z.string().optional(), decision_comment: z.string().max(500).optional(), decision_note: z.string().optional(), expires_ts: z.string().optional(), flow_label: z.string().optional(), group_id: z.string().optional(), human_approval: z.enum(["unknown", "none", "required"]), id: z.string().optional(), money_movement_id: z.string().nullable().optional(), native_asset: moneyMovementsTransferApprovalAssetDisplay.optional(), progress_available: z.boolean().optional(), rail: z.string().optional(), ramp_fees: moneyMovementsRampFeeDisclosure.optional(), release_ts: z.string().nullable().optional(), request_summary: moneyMovementsTransferApprovalInstructions.optional(), requested_by: z.string().optional(), requested_ts: z.string().optional(), requester_name: z.string().optional(), required_approvals: z.number().int().optional(), selected_approver_name: z.string().optional(), selected_approver_satisfied: z.boolean().optional(), status: moneyMovementsTransferApprovalStatus.optional(), valuation_unavailable: z.boolean().optional(), votes: z.array(moneyMovementsTransferApprovalVoteView).nullable().optional(), withdrawal_release_held: z.boolean(), withdrawals_paused: z.boolean().optional()}); export const moneyMovementsCreateMoneyMovementOutput = z.object({money_movement_id: z.string().optional(), outcome: z.enum(["created", "approval_pending"]).optional(), transaction: moneyMovementsMoneyMovementView.optional(), transfer_approval: moneyMovementsTransferApprovalView.optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Create an on-chain withdrawal * * POST /money/onchain/withdrawals */ export const createApiMoneyOnchainWithdrawals = async (args: CreateApiMoneyOnchainWithdrawalsArgs, options: CreateApiMoneyOnchainWithdrawalsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['Idempotency-Key'] != null) headers.set("Idempotency-Key", String(args['Idempotency-Key'])) const url = `${baseUrl.replace(/\/+$/, '')}/money/onchain/withdrawals${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(moneyMovementsCreateMoneyMovementOutput, await res.json()) };