import { HotBridgeEVMChain } from "./bridges/hot-bridge/hot-bridge-chains.cjs"; import { BridgeNameEnumValues } from "./constants/bridge-name-enum.cjs"; import { RouteEnum, RouteEnumValues } from "./constants/route-enum.cjs"; import { IntentHash, IntentPayloadFactory, IntentPrimitive, IntentRelayParamsFactory, MultiPayload } from "./intents/shared-types.cjs"; import { IIntentSigner } from "./intents/interfaces/intent-signer.cjs"; import { OnBeforePublishIntentHook } from "./intents/intent-executer-impl/intent-executer.cjs"; import { Chain, Chains } from "./lib/caip2.cjs"; import { ILogger, RpcEndpoint, solverRelay } from "@defuse-protocol/internal-utils"; //#region src/shared-types.d.ts interface IntentPublishResult { intentHash: IntentHash; } interface WithdrawalResult { feeEstimation: FeeEstimation; intentHash: IntentHash; intentTx: NearTxInfo; destinationTx: TxInfo | TxNoInfo; } interface BatchWithdrawalResult { feeEstimation: FeeEstimation[]; intentHash: IntentHash; intentTx: NearTxInfo; destinationTx: (TxInfo | TxNoInfo)[]; } type IntentSettlementStatus = solverRelay.GetStatusReturnType; /** * Configuration for including pre-signed intents to be published atomically. * * Pre-signed intents can be included in two ways: * - `before`: Pre-signed intents that execute before the newly created intent * - `after`: Pre-signed intents that execute after the newly created intent * * The execution order is guaranteed: before → new intent → after * * @example * ```typescript * // Include pre-signed intents from other users * const signedIntents: SignedIntents = { * before: [signedIntent1, signedIntent2], * after: [cleanupIntent], * }; * * await sdk.signAndSendIntent({ * intents: [myNewIntent], * signedIntents, * }); * ``` */ interface SignedIntentsComposition { /** * Pre-signed intents (MultiPayload) to execute before the newly created intent. * Useful for dependencies that must be executed first. */ before?: MultiPayload[]; /** * Pre-signed intents (MultiPayload) to execute after the newly created intent. * Useful for cleanup or follow-up actions. */ after?: MultiPayload[]; } interface SignAndSendArgs { intents: IntentPrimitive[]; /** * Factory function to modify the intent payload draft before signing. * Use this to add or modify intent primitives in the payload. * * @example * ```typescript * payload: (draft) => ({ * intents: [...draft.intents, { intent: "transfer", ... }] * }) * ``` */ payload?: IntentPayloadFactory; relayParams?: IntentRelayParamsFactory; signer?: IIntentSigner; onBeforePublishIntent?: OnBeforePublishIntentHook; /** * Pre-signed intents for atomic execution. * The newly created intent will be published together with these pre-signed intents. */ signedIntents?: SignedIntentsComposition; logger?: ILogger; } type SignAndSendWithdrawalArgs = { withdrawalParams: T; feeEstimation: T extends WithdrawalParams[] ? FeeEstimation[] : FeeEstimation; referral?: string; intent?: Omit; logger?: ILogger; }; type ProcessWithdrawalArgs = { withdrawalParams: T; feeEstimation?: T extends WithdrawalParams[] ? FeeEstimation[] : FeeEstimation; intent?: { /** @see SignAndSendArgs.payload */ payload?: IntentPayloadFactory; /** @see SignAndSendArgs.relayParams */ relayParams?: IntentRelayParamsFactory; /** @see SignAndSendArgs.signer */ signer?: IIntentSigner; /** @see SignAndSendArgs.onBeforePublishIntent */ onBeforePublishIntent?: OnBeforePublishIntentHook; /** @see SignAndSendArgs.signedIntents */ signedIntents?: SignedIntentsComposition; }; referral?: string; logger?: ILogger; }; interface IIntentsSDK { setIntentSigner(signer: IIntentSigner): void; sendSignedIntents(args: { multiPayloads: MultiPayload[]; quoteHashes?: string[]; logger?: ILogger; }): Promise<{ tickets: IntentHash[]; }>; signAndSendIntent(args: SignAndSendArgs): Promise; waitForIntentSettlement(args: { intentHash: IntentHash; /** AbortSignal for cancellation/timeout. Use AbortSignal.timeout(ms) for timeout. */ signal?: AbortSignal; logger?: ILogger; }): Promise; getIntentStatus(args: { intentHash: IntentHash; logger?: ILogger; }): Promise; invalidateNonces(args: { nonces: string[]; signer?: IIntentSigner; logger?: ILogger; }): Promise; estimateWithdrawalFee(args: { withdrawalParams: WithdrawalParams; quoteOptions?: QuoteOptions; logger?: ILogger; }): Promise; estimateWithdrawalFee(args: { withdrawalParams: WithdrawalParams[]; quoteOptions?: QuoteOptions; logger?: ILogger; }): Promise; signAndSendWithdrawalIntent(args: SignAndSendWithdrawalArgs | SignAndSendWithdrawalArgs): Promise; waitForWithdrawalCompletion(args: { withdrawalParams: WithdrawalParams; intentTx: NearTxInfo; signal?: AbortSignal; logger?: ILogger; }): Promise; waitForWithdrawalCompletion(args: { withdrawalParams: WithdrawalParams[]; intentTx: NearTxInfo; signal?: AbortSignal; logger?: ILogger; }): Promise>; createWithdrawalCompletionPromises(params: CreateWithdrawalCompletionPromisesParams): Array>; createWithdrawalIntents(args: { withdrawalParams: WithdrawalParams; feeEstimation: FeeEstimation; referral?: string; logger?: ILogger; }): Promise; parseAssetId(assetId: string): ParsedAssetInfo; processWithdrawal(args: ProcessWithdrawalArgs): Promise; processWithdrawal(args: ProcessWithdrawalArgs): Promise; } interface QuoteOptions { waitMs?: number; minWaitMs?: number; maxWaitMs?: number; trustedMetadata?: unknown; } interface NearTxInfo { hash: string; accountId: string; } interface TxInfo { hash: string; } interface TxNoInfo { hash: null; } interface CreateWithdrawalCompletionPromisesParams { withdrawalParams: WithdrawalParams[]; intentTx: NearTxInfo; signal?: AbortSignal; logger?: ILogger; } interface WithdrawalParams { assetId: string; amount: bigint; destinationAddress: string; /** * Optional memo attached to the withdrawal. * - XRP Ledger: included in the transaction memo field * - Internal transfers (intents): passed as memo in the transfer intent * - Stellar, TON: NOT SUPPORTED (will throw error) */ destinationMemo?: string | undefined; feeInclusive: boolean; routeConfig?: RouteConfig | undefined; } type NearWithdrawalRouteConfig = { route: RouteEnum["NearWithdrawal"]; msg?: string; }; type InternalTransferRouteConfig = { route: RouteEnum["InternalTransfer"]; }; type VirtualChainRouteConfig = { route: RouteEnum["VirtualChain"]; auroraEngineContractId: string; proxyTokenContractId: string | null; }; type PoaBridgeRouteConfig = { route: RouteEnum["PoaBridge"]; }; type HotBridgeRouteConfig = { route: RouteEnum["HotBridge"]; chain: Chain; }; type OmniBridgeRouteConfig = { route: RouteEnum["OmniBridge"]; chain?: Chain; }; type RouteConfig = NearWithdrawalRouteConfig | InternalTransferRouteConfig | VirtualChainRouteConfig | PoaBridgeRouteConfig | HotBridgeRouteConfig | OmniBridgeRouteConfig; /** * Fee structure definitions for each route type. */ interface RouteFeeStructures { [RouteEnum.HotBridge]: { /** Relayer fee for processing the withdrawal on destination chain, taken in base token of destination chain. */ relayerFee: bigint; /** Block number at the time of fee estimation, required for building gasless withdraw intent. */ blockNumber: bigint; }; [RouteEnum.PoaBridge]: { /** Relayer fee for POA bridge transfers, taken in transferred token. */ relayerFee: bigint; }; [RouteEnum.NearWithdrawal]: { /** Fee for nep141 storage deposit in NEAR blockchain, taken in wrap.near token. Paid for a token recipient. */ storageDepositFee: bigint; }; [RouteEnum.OmniBridge]: { /** Fee for nep141 storage deposit in NEAR blockchain, taken in wrap.near token. Paid for omni bridge contract. */ storageDepositFee: bigint; /** Relayer fee for transferring tokens via Omni Bridge to other supported blockchains, taken in wrap.near token. */ relayerFee: bigint; /** Fee taken when making a withdrawal via UTXO connector (e.g., btc-connector.bridge.near), taken in transferred token. */ utxoProtocolFee?: bigint; /** Maximum amount of tokens that can be spent on gas when making a withdrawal via UTXO connector (e.g., btc-connector.bridge.near), taken in transferred token. */ utxoMaxGasFee?: bigint; }; [RouteEnum.VirtualChain]: { /** Fee for nep141 storage deposit in NEAR blockchain, taken in wrap.near token. Paid for virtual chain contract */ storageDepositFee: bigint; }; /** Internal transfers have no fees */ [RouteEnum.InternalTransfer]: null; } /** * Prefunded withdrawal fees: the account already holds the fee asset * (e.g. NEAR, or the destination chain's native token for HOT Bridge), so the SDK * skips quoting the withdrawal asset into the fee asset during fee estimation. */ interface PrefundedFeesConfig { /** Asset IDs whose withdrawal fees are prefunded. Ignored when `feesPrefunded` is `true`. */ prefundedFeesTokens?: string[]; /** * Withdrawal fees are prefunded for all tokens, overriding `prefundedFeesTokens`. * * @default false */ feesPrefunded?: boolean; } /** * Per-bridge configuration, keyed by route. Each entry is optional and tunes * the behaviour of a single bridge; omitting one falls back to that bridge's defaults. */ interface BridgeConfigs { [RouteEnum.HotBridge]?: PrefundedFeesConfig; [RouteEnum.OmniBridge]?: PrefundedFeesConfig; [RouteEnum.NearWithdrawal]?: PrefundedFeesConfig; [RouteEnum.VirtualChain]?: PrefundedFeesConfig; } /** * Represents the different categories of fees that may apply across various withdrawal operations. * Each route type has an optional fee structure. Uses a mapped type to ensure all RouteEnum values are covered. */ type UnderlyingFees = { [K in RouteEnumValues]?: RouteFeeStructures[K] }; interface FeeEstimation { amount: bigint; /** * @internal Implementation detail - do not use directly. * This field may change or be removed without notice. */ quote: null | solverRelay.Quote; /** * @internal Implementation detail - do not use directly. * This field may change or be removed without notice. */ underlyingFees: UnderlyingFees; } interface Bridge { readonly route: RouteEnumValues; supports(params: Pick): Promise; parseAssetId(assetId: string): ParsedAssetInfo | null; /** * Validates withdrawal constraints for the bridge. * Each bridge implementation may have different withdrawal requirements. * Some bridges (like Aurora Engine, Intents) have no restrictions and will always pass. * Others (like POA) check minimum amounts, and HOT Bridge checks trustlines for Stellar. * @throws {MinWithdrawalAmountError} If the amount is below the minimum required * @throws {TrustlineNotFoundError} If destination address lacks required trustline */ validateWithdrawal(args: { assetId: string; amount: bigint; destinationAddress: string; destinationMemo?: string; feeEstimation: FeeEstimation; routeConfig?: RouteConfig; logger?: ILogger; skipMinAmountValidation?: boolean; }): Promise; estimateWithdrawalFee>(args: { withdrawalParams: T; quoteOptions?: QuoteOptions; logger?: ILogger; }): Promise; createWithdrawalIntents(args: { withdrawalParams: WithdrawalParams; feeEstimation: FeeEstimation; referral?: string; }): Promise; /** * Creates a complete withdrawal identifier with all required info. * Derives landingChain from withdrawalParams.routeConfig.chain if available, otherwise from assetId. */ createWithdrawalIdentifier(args: { withdrawalParams: WithdrawalParams; index: number; tx: NearTxInfo; }): WithdrawalIdentifier; /** * One-shot status check for a withdrawal. * Returns the current status without polling. */ describeWithdrawal(args: WithdrawalIdentifier & { logger?: ILogger; }): Promise; } interface WithdrawalIdentifier { /** Actual chain where funds arrive; Near for virtual/internal routes */ landingChain: Chain; /** Per-bridge withdrawal sequence number */ index: number; withdrawalParams: WithdrawalParams; tx: NearTxInfo; } /** * Represents the current state of a withdrawal as returned by bridge adapters. * * Error handling follows AWS SDK "describe" API patterns: * - **Thrown errors**: Infrastructure failures (network, auth, service unavailable). * Meaning: "I couldn't check the status." * - **`failed` status**: Job-level failure reported by the bridge. * Meaning: "I checked, and the withdrawal failed." * * @see https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-job-status.html */ type WithdrawalStatus = { status: "pending"; } | { status: "completed"; txHash: string | null; } | { status: "failed"; reason: string; }; type ParsedAssetInfo = ({ blockchain: Chain; bridgeName: BridgeNameEnumValues; standard: "nep141"; contractId: string; } | { blockchain: Chain; bridgeName: BridgeNameEnumValues; standard: "nep245"; contractId: string; tokenId: string; }) & ({ native: true; } | { address: string; }); type RPCEndpointMap = Record & { [K in typeof Chains.Stellar]: { soroban: RpcEndpoint[]; horizon: RpcEndpoint[]; } }; /** * Partial RPC endpoint map where each chain's URLs are optional, * but individual RpcEndpoint items remain valid (not deeply partial). */ type PartialRPCEndpointMap = { [K in keyof RPCEndpointMap]?: K extends typeof Chains.Stellar ? { soroban?: RpcEndpoint[]; horizon?: RpcEndpoint[]; } : RpcEndpoint[] }; //#endregion export { BatchWithdrawalResult, Bridge, BridgeConfigs, CreateWithdrawalCompletionPromisesParams, FeeEstimation, HotBridgeRouteConfig, IIntentsSDK, IntentPublishResult, IntentSettlementStatus, InternalTransferRouteConfig, NearTxInfo, NearWithdrawalRouteConfig, OmniBridgeRouteConfig, ParsedAssetInfo, PartialRPCEndpointMap, PoaBridgeRouteConfig, ProcessWithdrawalArgs, QuoteOptions, RouteConfig, SignAndSendArgs, SignAndSendWithdrawalArgs, SignedIntentsComposition, TxInfo, TxNoInfo, VirtualChainRouteConfig, WithdrawalIdentifier, WithdrawalParams, WithdrawalResult };