UNPKG

@atomiqlabs/sdk

Version:

atomiq labs SDK for cross-chain swaps between smart chains and bitcoin

98 lines (95 loc) 4.05 kB
import { SwapExecutionAction, SwapExecutionActionSendToAddress, SwapExecutionActionSignPSBT, SwapExecutionActionSignSmartChainTx, SwapExecutionActionWait } from "../types/SwapExecutionAction"; import {ApiAmount, toApiAmount} from "./ApiTypes"; /** * Strips non-serializable fields (functions, complex objects) from SwapExecutionAction types. * Uses key-remapping to truly omit function keys from the resulting type. * * - SignSmartChainTransaction: functions removed, txs → string[] * - SignPSBT: functions removed, txs[].psbt (Transaction object) omitted * - SendToAddress: functions removed, txs[].amount (TokenAmount) → ApiAmount * - Wait: functions removed, data fields kept as-is * * @category API */ export type SerializedAction<T extends SwapExecutionAction> = T["type"] extends "SignSmartChainTransaction" ? { [K in keyof T as T[K] extends Function ? never : K]: K extends "txs" ? string[] : T[K] } : T["type"] extends "SignPSBT" ? { [K in keyof T as T[K] extends Function ? never : K]: K extends "txs" ? (T extends { txs: (infer U)[] } ? Omit<U, "psbt">[] : never) : T[K] } : T["type"] extends "SendToAddress" ? { [K in keyof T as T[K] extends Function ? never : K]: K extends "txs" ? (T extends { txs: (infer U)[] } ? (Omit<U, "amount"> & { amount: ApiAmount })[] : never) : T[K] } : { [K in keyof T as T[K] extends Function ? never : K]: T[K] }; /** * Runtime serializer that strips non-serializable fields from a SwapExecutionAction. * Matches the compile-time SerializedAction<T> type. * * @param action The swap execution action to serialize * @param txSerializer Optional chain-specific transaction serializer for SignSmartChainTransaction actions. * Accepts the chain identifier and raw transaction, returns the serialized string. * Falls back to JSON.stringify if not provided. * * @category API */ export async function serializeAction( action: SwapExecutionAction, txSerializer?: (chainId: string, tx: any) => Promise<string> ): Promise<SerializedAction<SwapExecutionAction>> { switch (action.type) { case "SendToAddress": { const {waitForTransactions, ...rest} = action as SwapExecutionActionSendToAddress<boolean>; return { ...rest, txs: rest.txs.map(tx => ({ type: tx.type, address: tx.address, hyperlink: tx.hyperlink, amount: toApiAmount(tx.amount) })) } as unknown as SerializedAction<SwapExecutionAction>; } case "SignPSBT": { const {submitPsbt, txs, ...rest} = action as SwapExecutionActionSignPSBT<"FUNDED_PSBT" | "RAW_PSBT">; return { ...rest, txs: txs.map(tx => { const {psbt, ...txRest} = tx; return txRest; }) } as unknown as SerializedAction<SwapExecutionAction>; } case "SignSmartChainTransaction": { const {submitTransactions, ...rest} = action as SwapExecutionActionSignSmartChainTx; return { ...rest, txs: await Promise.all(rest.txs.map(tx => txSerializer != null ? txSerializer(rest.chain, tx) : Promise.resolve(JSON.stringify(tx)) )) } as unknown as SerializedAction<SwapExecutionAction>; } case "Wait": { const {wait, ...rest} = action as SwapExecutionActionWait; return rest as unknown as SerializedAction<SwapExecutionAction>; } default: { const _exhaustive: never = action; throw new Error(`Unknown action type: ${(_exhaustive as any).type}`); } } }