import {z} from 'zod' export type GetApiExternalAccountsExternalAccountIdArgs = {externalAccountId: string}; export type GetApiExternalAccountsExternalAccountIdOptions = {baseUrl?: string | undefined, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const typeId = z.string(); export const externalAccountOwner = z.discriminatedUnion("kind", [z.object({kind: z.literal("customer"), customerId: typeId}), z.object({kind: z.literal("counterparty"), counterpartyId: typeId})]); export const externalAccountType = z.enum(["bankUs", "bankIban", "bankCanada", "card", "walletExternal"]); export const externalAccountCategory = z.enum(["fiatAccount", "crypto"]); export const externalAccountStatus = z.enum(["active", "pending", "rejected", "invalid", "deleted", "failed"]); export const externalAccountFailureReason = z.enum(["ereborRejected", "cardProviderRejected", "providerAccountMissing", "cardLimitReached", "cardInUse", "provisioningTimeout", "systemError"]); export const providerRejectionDetail = z.object({provider: z.string().optional(), code: z.string().optional(), message: z.string().optional(), details: z.array(z.string()).optional(), providerRequestId: z.string().optional()}); export const bankAccountType = z.enum(["checking", "savings"]); export const externalAccountBankUsResponse = z.object({accountNumberLast4: z.string(), routingNumber: z.string(), accountType: bankAccountType.optional(), bankName: z.string().optional()}); export const address = z.object({line1: z.string().optional(), line2: z.string().optional(), city: z.string().optional(), state: z.string().optional(), country: z.string().optional(), zipCode: z.string().optional()}); export const externalAccountBankIbanResponse = z.object({ibanLast4: z.string(), BIC: z.string(), bankAddress: address.optional(), countryCode: z.string()}); export const externalAccountBankCanadaResponse = z.object({institutionNumber: z.string(), transitNumber: z.string(), accountNumberLast4: z.string(), bankName: z.string().optional()}); export const networkFamily = z.enum(["evm", "solana"]); export const destinationCustodian = z.enum(["ANCHORAGE_SG", "ANCHORAGE_US", "AQUANOW_CA", "B2C2_UK", "B2C2_US", "BITGO_SG", "BITGO_US", "BITSTAMP_US", "BVNK_US", "CIRCLE_FR", "CIRCLE_US", "CITIBANK_US", "COINBASE_US", "COINSMART_CA", "COPPER_CH", "COPPER_UK", "CUMBERLAND_DRW_LLC_US", "CUMBERLAND_SG", "EREBOR_BANK_US", "FALCONX_US", "FIDELITY_UK", "FIDELITY_US", "FIREBLOCKS_APAC", "FIREBLOCKS_US", "GALAXY_KY", "GEMINI_US", "KRAKEN_BVI", "KRAKEN_EU_IE", "KRAKEN_UK", "KRAKEN_US", "NUBANK_BR", "PAXOS_US", "RAMP_NETWORK_US", "ROBINHOOD_US", "WINTERMUTE_GB", "SELF_HOSTED", "OTHER"]); export const supportedDestination = z.object({asset: z.string(), network: z.string()}); export const externalAccountWalletExternalResponse = z.object({blockchainAddress: z.string(), networkFamily: networkFamily, custodian: destinationCustodian, otherCustodian: z.string().optional(), supportedDestinations: z.array(supportedDestination).optional()}); export const cardBrand = z.enum(["visa", "mastercard", "amex", "discover"]); export const cardType = z.enum(["debit", "credit", "prepaid"]); export const billingAddressSource = z.enum(["provided", "customerDefault"]); export const externalAccountCardResponse = z.object({cardNumberLast4: z.string().optional(), cardProvider: cardBrand.optional(), cardType: cardType.optional(), expiryMonth: z.number().int().optional(), expiryYear: z.number().int().optional(), billingAddressSource: billingAddressSource.optional()}); export const externalAccount = z.object({id: typeId.optional(), object: z.literal("externalAccount").optional(), owner: externalAccountOwner.optional(), type: externalAccountType.optional(), category: externalAccountCategory.optional(), status: externalAccountStatus.optional(), failureReason: externalAccountFailureReason.optional(), failureDetail: providerRejectionDetail.optional(), rejectionReason: z.string().optional(), invalidReason: z.string().optional(), label: z.string().optional(), metadata: z.record(z.string(), z.string()).optional(), bankUs: externalAccountBankUsResponse.optional(), bankIban: externalAccountBankIbanResponse.optional(), bankCanada: externalAccountBankCanadaResponse.optional(), walletExternal: externalAccountWalletExternalResponse.optional(), card: externalAccountCardResponse.optional(), resolvedTransactions: z.array(typeId).optional(), createdAt: z.string().optional(), updatedAt: z.string().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 }; /** * Get an External Account * * GET /external-accounts/{externalAccountId} */ export const getApiExternalAccountsExternalAccountId = async (args: GetApiExternalAccountsExternalAccountIdArgs, options?: GetApiExternalAccountsExternalAccountIdOptions) => { const {baseUrl = "https://sandbox-api.polygon.technology/v0.10", fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/external-accounts/${encodeURIComponent(String(args.externalAccountId))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(externalAccount, await res.json()) };