import {z} from 'zod' export type CreateApiPaymentsWorkflowExecutionWorkflowExecutionIdActionsExecuteArgs = {workflowExecutionId: string, 'Idempotency-Key'?: string | undefined}; export type CreateApiPaymentsWorkflowExecutionWorkflowExecutionIdActionsExecuteOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const preScreening = z.object({enabled: z.boolean()}); export const conversionOperationType = z.literal("CONVERSION"); export const conversionOperationConfigParams = z.object({amount: z.string().optional(), accountId: z.string().optional(), srcAssetId: z.string().optional(), destAssetId: z.string(), slippageBasisPoints: z.number().int().gte(0).lte(10000).optional()}); export const configConversionOperationSnapshot = z.object({operationId: z.string(), type: conversionOperationType, params: conversionOperationConfigParams}); export const transferOperationType = z.literal("TRANSFER"); export const accountType = z.enum(["EXCHANGE_ACCOUNT", "UNMANAGED_WALLET", "VAULT_ACCOUNT", "NETWORK_CONNECTION", "FIAT_ACCOUNT"]); export const account = z.object({accountId: z.string(), accountType: accountType}); export const oneTimeAddressAccount = z.object({oneTimeAddress: z.string(), tag: z.string().optional()}); export const destination = z.union([account, oneTimeAddressAccount]); export const transferOperationConfigParams = z.object({amount: z.string().optional(), assetId: z.string().optional(), source: account.optional(), destination: destination}); export const configTransferOperationSnapshot = z.object({operationId: z.string(), type: transferOperationType, params: transferOperationConfigParams}); export const disbursementOperationType = z.literal("DISBURSEMENT"); export const disbursementAmountInstruction = z.object({payeeAccount: destination, assetId: z.string(), amount: z.string()}); export const disbursementPercentageInstruction = z.object({payeeAccount: destination, assetId: z.string(), percentage: z.string()}); export const disbursementInstruction = z.union([disbursementAmountInstruction, disbursementPercentageInstruction]); export const disbursementOperationConfigParams = z.object({paymentAccount: account.optional(), instructionSet: z.array(disbursementInstruction)}); export const configDisbursementOperationSnapshot = z.object({operationId: z.string(), type: disbursementOperationType, params: disbursementOperationConfigParams}); export const configOperationSnapshot = z.union([configConversionOperationSnapshot, configTransferOperationSnapshot, configDisbursementOperationSnapshot]); export const correlationData = z.union([z.record(z.string(), z.string()), z.string()]); export const workflowConfigurationSnapshot = z.object({configId: z.string(), configName: z.string(), createdAt: z.number(), configOperations: z.array(configOperationSnapshot), externalCorrelationData: correlationData.optional()}); export const executionOperationStatus = z.enum(["PENDING", "VALIDATION_IN_PROGRESS", "VALIDATION_FAILED", "VALIDATION_COMPLETED", "PREVIEW_REQUESTED", "PREVIEW_IN_PROGRESS", "PREVIEW_FAILED", "READY_FOR_LAUNCH", "EXECUTION_REQUESTED", "EXECUTION_IN_PROGRESS", "EXECUTION_COMPLETED", "EXECUTION_FAILED"]); export const screeningOperationType = z.literal("SCREENING"); export const screeningValidationFailure = z.object({reason: z.literal("SCREENING_DISABLED_IN_TENANT"), data: z.record(z.string(), z.unknown()).optional()}); export const screeningVerdict = z.object({verdict: z.enum(["PASSED", "PASSED_WITH_ALERT", "REJECTED", "FAILED", "BYPASSED"]), executionOperationId: z.string(), account: destination, assetId: z.string(), amount: z.string(), matchedRule: z.object({action: z.string().optional(), category: z.array(z.string()).optional()}).optional()}); export const screeningOperationExecutionOutput = z.object({verdicts: z.array(screeningVerdict)}); export const screeningOperationFailure = z.object({reason: z.enum(["AML_PROCESS_FAILED", "SCREENING_REJECTED"]), data: screeningOperationExecutionOutput.optional()}); export const screeningOperationExecution = z.object({output: screeningOperationExecutionOutput.optional(), startedAt: z.number(), finishedAt: z.number().optional(), failure: screeningOperationFailure.optional()}); export const executionScreeningOperation = z.object({operationId: z.string(), status: executionOperationStatus, operationType: screeningOperationType, validationFailure: screeningValidationFailure.optional(), execution: screeningOperationExecution.optional()}); export const conversionValidationFailure = z.object({reason: z.enum(["ACCOUNT_NOT_FOUND", "ACCOUNT_TYPE_NOT_SUPPORTED", "INSUFFICIENT_BALANCE", "ASSET_NOT_FOUND", "ASSETS_CONTINUITY_MISMATCH", "EXCHANGE_BASKETS_MISMATCH", "ACCOUNTS_CONTINUITY_MISMATCH", "ONE_TIME_ADDRESS_CONTINUITY_NOT_ALLOWED", "EQUAL_ACCOUNTS_NOT_ALLOWED", "EQUAL_ASSETS_NOT_ALLOWED", "INVALID_AMOUNT", "UNMANAGED_WALLET_AS_SOURCE_NOT_ALLOWED", "MANAGED_OPERATION_PARAMS_INVALID_SCHEMA", "ACCOUNT_IS_NOT_EXCHANGE", "UNSUPPORTED_TRADING_METHOD", "ASSETS_CAN_NOT_CONVERTED"]), data: z.record(z.string(), z.unknown()).optional()}); export const assetAmount = z.object({amount: z.string(), assetId: z.string()}); export const conversionOperationPreviewOutput = z.object({amount: assetAmount, fee: assetAmount, conversionRate: z.string(), timeSeconds: z.number()}); export const conversionOperationFailure = z.object({reason: z.enum(["INVALID_AMOUNT", "SLIPPAGE_EXCEEDED", "AMOUNT_TOO_SMALL", "INSUFFICIENT_FUNDS"]), data: z.record(z.string(), z.unknown()).optional()}); export const conversionOperationPreview = z.object({input: conversionOperationConfigParams, output: conversionOperationPreviewOutput.optional(), failure: conversionOperationFailure.optional()}); export const conversionOperationExecutionOutput = z.object({amount: assetAmount, fee: assetAmount, conversionRate: z.string()}); export const conversionOperationExecution = z.object({input: conversionOperationConfigParams, output: conversionOperationExecutionOutput.optional(), startedAt: z.number(), finishedAt: z.number().optional(), failure: conversionOperationFailure.optional()}); export const executionConversionOperation = z.object({operationId: z.string(), status: executionOperationStatus, validationFailure: conversionValidationFailure.optional(), operationType: conversionOperationType, preview: conversionOperationPreview.optional(), execution: conversionOperationExecution.optional()}); export const transferValidationFailure = z.object({reason: z.enum(["ACCOUNT_NOT_FOUND", "ACCOUNT_TYPE_NOT_SUPPORTED", "INSUFFICIENT_BALANCE", "ASSET_NOT_FOUND", "ASSETS_CONTINUITY_MISMATCH", "EXCHANGE_BASKETS_MISMATCH", "ACCOUNTS_CONTINUITY_MISMATCH", "ONE_TIME_ADDRESS_CONTINUITY_NOT_ALLOWED", "EQUAL_ACCOUNTS_NOT_ALLOWED", "EQUAL_ASSETS_NOT_ALLOWED", "INVALID_AMOUNT", "UNMANAGED_WALLET_AS_SOURCE_NOT_ALLOWED", "MANAGED_OPERATION_PARAMS_INVALID_SCHEMA"]), data: z.record(z.string(), z.unknown()).optional()}); export const transferOperationPreviewOutput = z.object({amount: assetAmount, fee: assetAmount, isSignRequired: z.boolean(), timeSeconds: z.number()}); export const transferOperationFailure = z.object({reason: z.enum(["INVALID_AMOUNT", "SUBMISSION_FAILED", "TRANSACTION_FAILED"]), data: z.object({txId: z.string(), txStatus: z.string(), txSubStatus: z.string().optional()}).optional()}); export const transferOperationPreview = z.object({input: transferOperationConfigParams, output: transferOperationPreviewOutput.optional(), failure: transferOperationFailure.optional()}); export const transferOperationExecutionOutput = z.object({amount: assetAmount, fee: assetAmount}); export const transferOperationExecution = z.object({input: transferOperationConfigParams, output: transferOperationExecutionOutput.optional(), txId: z.string().optional(), startedAt: z.number(), finishedAt: z.number().optional(), failure: transferOperationFailure.optional()}); export const executionTransferOperation = z.object({operationId: z.string(), status: executionOperationStatus, validationFailure: transferValidationFailure.optional(), operationType: transferOperationType, preview: transferOperationPreview.optional(), execution: transferOperationExecution.optional()}); export const disbursementValidationFailure = z.object({reason: z.enum(["ACCOUNT_NOT_FOUND", "ACCOUNT_TYPE_NOT_SUPPORTED", "INSUFFICIENT_BALANCE", "ASSET_NOT_FOUND", "ASSETS_CONTINUITY_MISMATCH", "EXCHANGE_BASKETS_MISMATCH", "ACCOUNTS_CONTINUITY_MISMATCH", "ONE_TIME_ADDRESS_CONTINUITY_NOT_ALLOWED", "EQUAL_ACCOUNTS_NOT_ALLOWED", "EQUAL_ASSETS_NOT_ALLOWED", "INVALID_AMOUNT", "UNMANAGED_WALLET_AS_SOURCE_NOT_ALLOWED", "MANAGED_OPERATION_PARAMS_INVALID_SCHEMA", "INSTRUCTIONS_EXCEED_HUNDRED_PERCENT", "INSTRUCTIONS_ARRAY_EMPTY"]), data: z.record(z.string(), z.unknown()).optional()}); export const disbursementOperationInput = z.object({amount: z.string().optional(), paymentAccount: account, instructionSet: z.array(disbursementInstruction)}); export const disbursementOperationPreviewOutput = z.object({instructionSet: z.array(z.object({amount: assetAmount, fee: assetAmount, payeeAccount: destination, timeSeconds: z.number()}))}); export const operationExecutionFailure = z.object({reason: z.string(), data: z.record(z.string(), z.unknown()).optional()}); export const disbursementOperationPreview = z.object({input: disbursementOperationInput, output: disbursementOperationPreviewOutput.optional(), failure: operationExecutionFailure.optional()}); export const disbursementInstructionOutput = z.object({amount: assetAmount, fee: assetAmount, payeeAccount: destination}); export const disbursementOperationExecutionOutput = z.object({instructionSet: z.array(disbursementInstructionOutput)}); export const disbursementOperationExecution = z.object({input: disbursementOperationInput, output: disbursementOperationExecutionOutput.optional(), payoutId: z.string().optional(), startedAt: z.number(), finishedAt: z.number().optional(), failure: operationExecutionFailure.optional()}); export const executionDisbursementOperation = z.object({operationId: z.string(), status: executionOperationStatus, validationFailure: disbursementValidationFailure.optional(), operationType: disbursementOperationType, preview: disbursementOperationPreview.optional(), execution: disbursementOperationExecution.optional()}); export const workflowExecutionOperation = z.union([executionScreeningOperation, executionConversionOperation, executionTransferOperation, executionDisbursementOperation]); export const workflowExecution = z.object({executionId: z.string(), preScreening: preScreening.optional(), configSnapshot: workflowConfigurationSnapshot, executionOperations: z.array(workflowExecutionOperation), status: z.enum(["PENDING", "VALIDATION_IN_PROGRESS", "VALIDATION_FAILED", "VALIDATION_COMPLETED", "PREVIEW_IN_PROGRESS", "PREVIEW_FAILED", "READY_FOR_LAUNCH", "EXECUTION_IN_PROGRESS", "EXECUTION_COMPLETED", "EXECUTION_FAILED"]), triggeredBy: z.string().optional(), triggeredAt: z.number().optional(), finishedAt: z.number().optional(), externalCorrelationData: correlationData.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 }; /** * Execute the payments workflow * * POST /payments/workflow_execution/{workflowExecutionId}/actions/execute */ export const createApiPaymentsWorkflowExecutionWorkflowExecutionIdActionsExecute = async (args: CreateApiPaymentsWorkflowExecutionWorkflowExecutionIdActionsExecuteArgs, options?: CreateApiPaymentsWorkflowExecutionWorkflowExecutionIdActionsExecuteOptions) => { const {baseUrl = "https://api.fireblocks.io/v1", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args['Idempotency-Key'] != null) headers.set("Idempotency-Key", String(args['Idempotency-Key'])) const url = `${baseUrl.replace(/\/+$/, '')}/payments/workflow_execution/${encodeURIComponent(String(args.workflowExecutionId))}/actions/execute${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(workflowExecution, await res.json()) };