import {z} from 'zod' export type GetApiScreeningTransactionTxIdArgs = {txId: string}; export type GetApiScreeningTransactionTxIdOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const amlStatusEnum = z.enum(["COMPLETED", "PENDING", "BYPASSED", "FAILED", "FROZEN"]); export const screeningVerdictEnum = z.enum(["PASS", "FAIL", "ALERT", "REJECT", "WARN", "TRAVEL_RULE_REQUIRED", "ACCEPT", "REVIEW", "WAIT"]); export const alertLevelEnum = z.enum(["SEVERE", "HIGH", "MEDIUM", "LOW"]); export const screeningAlertExposureTypeEnum = z.enum(["DIRECT", "INDIRECT"]); export const screeningAmlAlert = z.object({alertLevel: alertLevelEnum, alertName: z.string().optional(), category: z.string().optional(), service: z.string().optional(), externalId: z.string(), alertAmount: z.number(), exposureType: screeningAlertExposureTypeEnum, policyAction: z.string().optional(), categoryId: z.number().optional()}); export const policyVerdictActionEnum2 = z.enum(["ALLOW", "BLOCK", "SCREEN", "ACCEPT", "REJECT", "ALERT", "WAIT", "FREEZE", "CANCEL"]); export const screeningAmlMatchedRule = z.object({ruleId: z.string().optional(), ruleName: z.string().optional(), action: policyVerdictActionEnum2.optional()}); export const screeningAmlResult = z.object({alerts: z.array(screeningAmlAlert).optional(), providerResponse: z.record(z.string(), z.unknown()).optional(), matchedRule: screeningAmlMatchedRule.optional(), matchedAlert: screeningAmlAlert.optional()}); export const travelRuleDirectionEnum = z.enum(["INBOUND", "OUTBOUND"]); export const travelRuleVerdictEnum = z.enum(["ACCEPT", "REJECT", "ALERT", "REVIEW", "WAIT", "FREEZE", "CANCEL"]); export const travelRuleStatusEnum = z.enum(["COMPLETED", "PENDING", "BYPASSED", "FAILED", "FROZEN", "REJECTED", "CANCELED", "BLOCKING_TIME_EXPIRED"]); export const screeningTravelRuleMatchedRule = z.object({direction: travelRuleDirectionEnum.optional(), status: travelRuleStatusEnum.optional(), amountUSD: z.number().optional(), amount: z.number().optional(), asset: z.string().optional(), action: travelRuleVerdictEnum.optional()}); export const screeningTravelRuleResult = z.object({direction: travelRuleDirectionEnum.optional(), isVerified: z.boolean().optional(), action: travelRuleVerdictEnum.optional(), providerResponse: z.record(z.string(), z.unknown()).optional(), matchedRule: screeningTravelRuleMatchedRule.optional()}); export const transferPeerTypeEnum2 = z.enum(["VAULT_ACCOUNT", "EXCHANGE_ACCOUNT", "INTERNAL_WALLET", "EXTERNAL_WALLET", "CONTRACT", "NETWORK_CONNECTION", "FIAT_ACCOUNT", "COMPOUND", "GAS_STATION", "ONE_TIME_ADDRESS", "UNKNOWN", "END_USER_WALLET", "PROGRAM_CALL", "MULTI_DESTINATION"]); export const transferPeerSubTypeEnum = z.enum(["EXTERNAL", "INTERNAL", "CONTRACT", "EXCHANGETEST"]); export const transactionOperationEnum = z.enum(["TRANSFER", "BURN", "CONTRACT_CALL", "MINT", "RAW", "TYPED_MESSAGE", "ENABLE_ASSET", "STAKE", "UNSTAKE", "WITHDRAW", "REDEEM_FROM_COMPOUND", "SUPPLY_TO_COMPOUND", "PROGRAM_CALL", "APPROVE"]); export const travelRuleActionEnum = z.enum(["SCREEN", "BYPASS", "BLOCK", "PASS", "FREEZE"]); export const screeningTravelRulePrescreeningRule = z.object({bypassReason: z.string().optional(), sourceType: transferPeerTypeEnum2.optional(), sourceSubType: transferPeerSubTypeEnum.optional(), destType: transferPeerTypeEnum2.optional(), destSubType: transferPeerSubTypeEnum.optional(), transferPeerType: transferPeerTypeEnum2.optional(), transferPeerSubType: transferPeerSubTypeEnum.optional(), destAddress: z.string().optional(), sourceId: z.string().optional(), destId: z.string().optional(), asset: z.string().optional(), baseAsset: z.string().optional(), amount: z.number().optional(), amountUSD: z.number().optional(), networkProtocol: z.string().optional(), operation: transactionOperationEnum.optional(), action: travelRuleActionEnum.optional()}); export const screeningProviderResponse = z.record(z.string(), z.unknown()); export const complianceScreeningResultFullPayload = z.object({provider: z.string().optional(), payload: z.object({}).optional(), timestamp: z.number().optional(), screeningStatus: z.enum(["COMPLETED", "PENDING", "BYPASSED", "FAILED", "FROZEN"]).optional(), bypassReason: z.string().optional(), status: amlStatusEnum.optional(), prevStatus: amlStatusEnum.optional(), prevBypassReason: z.string().optional(), verdict: screeningVerdictEnum.optional(), risk: z.string().optional(), extendedRisk: z.string().optional(), externalId: z.string().optional(), customerRefId: z.string().optional(), refId: z.string().optional(), category: z.string().optional(), categoryId: z.number().optional(), destAddress: z.string().optional(), destTag: z.string().optional(), destRecordId: z.string().optional(), addressResolutionSignature: z.string().optional(), amlResult: screeningAmlResult.optional(), result: screeningTravelRuleResult.optional(), detailsMessage: z.string().optional(), matchedAlert: z.object({}).optional(), matchedRule: z.object({}).optional(), matchedPrescreeningRule: screeningTravelRulePrescreeningRule.optional(), matchedNoTrmScreeningRule: z.object({}).optional(), customerIntegrationId: z.string().optional(), customerShortName: z.string().optional(), travelRuleMessageId: z.string().optional(), providerResponse: screeningProviderResponse.optional()}); export const complianceResultStatusesEnum = z.enum(["Unknown", "Stalled", "Started", "NetworkConnectionAddressResolve", "ScreeningPrepare", "AMLStarted", "AMLCompleted", "AMLFailed", "AMLInBackground", "TRPreconditionChecks", "TRStarted", "TRLinkStarted", "TRLinkDestinationStarted", "TRLinkDestinationPrescreenPolicy", "TRLinkDestinationNoTRMPolicy", "TRLinkDestinationScreen", "TRLinkDestinationPostscreenPolicy", "TRLinkDestinationCompleted", "TRLinkCompleted", "TRCompleted", "TRFailed", "Completed", "RegistrationStarted", "RegistrationWaitForFirstConfirmation", "AMLRegistrationStarted", "AMLRegistrationCompleted", "TRUpdateStarted", "TRUpdateCompleted", "UpdateCompleted", "IncomingStarted", "IncomingByorkSL", "IncomingScreeningPrepare", "IncomingWaitForFirstConfirmation", "AMLIncomingStarted", "AMLIncomingCompleted", "AMLIncomingFailed", "AMLIncomingInBackground", "TRIncomingStarted", "TRIncomingCompleted", "TRIncomingFailed", "IncomingCompleted", "AddressAmlInitiated", "AddressAmlAddressResolve", "AddressAmlPrepare", "AddressAmlProcessing", "AddressAmlSucceeded", "AddressAmlFailed", "AddressAmlCompleted"]); export const amlRegistrationResultFullPayload = z.object({provider: z.string().optional(), success: z.boolean().optional(), timestamp: z.number().optional()}); export const tRLinkRegistrationStatusEnum = z.enum(["STARTING", "PRESCREENED", "COMPLETED", "FAILED", "VOID"]); export const tRLinkProviderResult = z.object({providerResponse: z.object({}).optional()}); export const amountRangeMinMax = z.object({min: z.string().optional(), max: z.string().optional()}); export const screeningTRLinkAmount = z.object({range: amountRangeMinMax.optional(), currency: z.enum(["USD", "NATIVE"]).optional()}); export const tRLinkPreScreeningActionEnum = z.enum(["SCREEN", "PASS"]); export const screeningTRLinkPrescreeningRule = z.object({customerId: z.string().optional(), direction: travelRuleDirectionEnum.optional(), sourceType: transferPeerTypeEnum2.optional(), sourceSubType: transferPeerSubTypeEnum.optional(), sourceAddress: z.string().optional(), destType: transferPeerTypeEnum2.optional(), destSubType: transferPeerSubTypeEnum.optional(), destAddress: z.string().optional(), sourceId: z.string().optional(), destId: z.string().optional(), asset: z.string().optional(), baseAsset: z.string().optional(), amount: screeningTRLinkAmount.optional(), networkProtocol: z.string().optional(), operation: transactionOperationEnum.optional(), description: z.string().optional(), isDefault: z.boolean().optional(), action: tRLinkPreScreeningActionEnum}); export const tRLinkRegistrationResultFullPayload = z.object({status: tRLinkRegistrationStatusEnum, provider: z.string().optional(), success: z.boolean().optional(), timestamp: z.number(), destRecordId: z.string().optional(), travelRuleMessageId: z.string().optional(), customerIntegrationId: z.string().optional(), customerShortName: z.string().optional(), result: tRLinkProviderResult.optional(), matchedPrescreeningRule: screeningTRLinkPrescreeningRule.optional()}); export const tRLinkVerdictEnum = z.enum(["ACCEPT", "ALERT", "REJECT", "WAIT"]); export const tRLinkTrmScreeningStatusEnum = z.enum(["PENDING", "ACCEPTED", "REJECTED", "FAILED"]); export const screeningTRLinkPostScreeningRule = z.object({customerId: z.string().optional(), direction: travelRuleDirectionEnum.optional(), sourceType: transferPeerTypeEnum2.optional(), sourceSubType: transferPeerSubTypeEnum.optional(), sourceAddress: z.string().optional(), destType: transferPeerTypeEnum2.optional(), destSubType: transferPeerSubTypeEnum.optional(), destAddress: z.string().optional(), sourceId: z.string().optional(), destId: z.string().optional(), asset: z.string().optional(), baseAsset: z.string().optional(), amount: screeningTRLinkAmount.optional(), networkProtocol: z.string().optional(), operation: transactionOperationEnum.optional(), description: z.string().optional(), isDefault: z.boolean().optional(), providerIdent: z.string().optional(), trmStatus: tRLinkTrmScreeningStatusEnum.optional(), validBefore: z.number().optional(), validAfter: z.number().optional(), action: tRLinkVerdictEnum}); export const tRLinkProviderResultWithRule2 = z.object({providerResponse: z.object({}).optional(), matchedRule: screeningTRLinkPostScreeningRule.optional()}); export const tRLinkMissingTrmActionEnum = z.enum(["WAIT", "REJECT", "ACCEPT", "INITIATE_TRM"]); export const screeningTRLinkMissingTrmDecision = z.object({customerId: z.string().optional(), direction: travelRuleDirectionEnum.optional(), sourceType: transferPeerTypeEnum2.optional(), sourceSubType: transferPeerSubTypeEnum.optional(), sourceAddress: z.string().optional(), destType: transferPeerTypeEnum2.optional(), destSubType: transferPeerSubTypeEnum.optional(), destAddress: z.string().optional(), sourceId: z.string().optional(), destId: z.string().optional(), asset: z.string().optional(), baseAsset: z.string().optional(), amount: screeningTRLinkAmount.optional(), networkProtocol: z.string().optional(), operation: transactionOperationEnum.optional(), description: z.string().optional(), isDefault: z.boolean().optional(), validBefore: z.number().optional(), validAfter: z.number().optional(), action: tRLinkMissingTrmActionEnum, source: z.string(), timestamp: z.string().optional(), reason: z.string().optional()}); export const tRLinkResultFullPayload = z.object({provider: z.string(), timestamp: z.number(), status: z.enum(["COMPLETED", "PENDING", "BYPASSED", "FAILED", "FROZEN"]), verdict: tRLinkVerdictEnum.optional(), destAddress: z.string().optional(), destTag: z.string().optional(), bypassReason: z.string().optional(), detailsMessage: z.string().optional(), customerIntegrationId: z.string().optional(), customerShortName: z.string().optional(), travelRuleMessageId: z.string().optional(), result: tRLinkProviderResultWithRule2.optional(), matchedPrescreeningRule: screeningTRLinkPrescreeningRule.optional(), matchedNoTrmScreeningRule: screeningTRLinkMissingTrmDecision.optional()}); export const complianceResultFullPayload = z.object({aml: complianceScreeningResultFullPayload.optional(), tr: complianceScreeningResultFullPayload.optional(), amlList: z.array(complianceScreeningResultFullPayload).optional(), status: complianceResultStatusesEnum.optional(), amlRegistration: amlRegistrationResultFullPayload.optional(), trlinkRegistration: tRLinkRegistrationResultFullPayload.optional(), trlinkDestinations: z.array(tRLinkResultFullPayload).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 }; /** * Provides all the compliance details for the given screened transaction. * * GET /screening/transaction/{txId} */ export const getApiScreeningTransactionTxId = async (args: GetApiScreeningTransactionTxIdArgs, options?: GetApiScreeningTransactionTxIdOptions) => { const {baseUrl = "https://api.fireblocks.io/v1", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/screening/transaction/${encodeURIComponent(String(args.txId))}${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(complianceResultFullPayload, await res.json()) };