import { ChainsService } from "../chains"; import { AnalyticsService } from "../analytics"; import { TendermintTxTracer } from "@keplr-wallet/cosmos"; import { BackgroundTxService, Notification } from "../tx"; import { KVStore } from "@keplr-wallet/common"; import { IBCHistory, IBCSwapMinimalTrackingData, IbcHop, RecentSendHistory, SkipHistory, SwapProvider, SwapV2History, SwapV2TxStatusResponse } from "./types"; import { AppCurrency, EthTxReceipt, ModularChainInfo } from "@keplr-wallet/types"; import { EventBusPublisher } from "@keplr-wallet/common"; import { TxExecutionEvent } from "../tx-executor/types"; export declare const UNKNOWN_TX_STATUS_TIMEOUT_MS: number; export declare class RecentSendHistoryService { protected readonly kvStore: KVStore; protected readonly chainsService: ChainsService; protected readonly txService: BackgroundTxService; protected readonly analyticsService: AnalyticsService; protected readonly notification: Notification; protected readonly publisher: EventBusPublisher; protected readonly recentSendHistoryMap: Map; protected recentIBCHistorySeq: number; protected readonly recentIBCHistoryMap: Map; protected recentSkipHistorySeq: number; protected readonly recentSkipHistoryMap: Map; protected recentSwapV2HistorySeq: number; protected readonly recentSwapV2HistoryMap: Map; constructor(kvStore: KVStore, chainsService: ChainsService, txService: BackgroundTxService, analyticsService: AnalyticsService, notification: Notification, publisher: EventBusPublisher); init(): Promise; protected initRecentSendHistory(): Promise; protected initRecentIBCHistory(): Promise; protected initRecentSkipHistory(): Promise; protected initRecentSwapV2History(): Promise; sendTxAndRecord(type: string, sourceChainId: string, destinationChainId: string, tx: unknown, mode: "async" | "sync" | "block", silent: boolean, sender: string, recipient: string, amount: { amount: string; denom: string; }[], memo: string, ibcChannels: { portId: string; channelId: string; counterpartyChainId: string; }[] | undefined, notificationInfo: { currencies: AppCurrency[]; }, shouldLegacyTrack?: boolean): Promise; getRecentSendHistories(chainId: string, type: string): RecentSendHistory[]; addRecentSendHistory(chainId: string, type: string, history: Omit): void; sendTxAndRecordIBCSwap(swapType: "amount-in" | "amount-out", sourceChainId: string, destinationChainId: string, tx: unknown, mode: "async" | "sync" | "block", silent: boolean, sender: string, amount: { amount: string; denom: string; }[], memo: string, ibcChannels: { portId: string; channelId: string; counterpartyChainId: string; }[], destinationAsset: { chainId: string; denom: string; }, swapChannelIndex: number, swapReceiver: string[], notificationInfo: { currencies: AppCurrency[]; }, shouldLegacyTrack?: boolean): Promise; addRecentIBCTransferHistory(chainId: string, destinationChainId: string, sender: string, recipient: string, amount: { amount: string; denom: string; }[], memo: string, ibcChannels: { portId: string; channelId: string; counterpartyChainId: string; }[], notificationInfo: { currencies: AppCurrency[]; }, txHash: Uint8Array): string; addRecentIBCSwapHistory(swapType: "amount-in" | "amount-out", chainId: string, destinationChainId: string, sender: string, amount: { amount: string; denom: string; }[], memo: string, ibcChannels: { portId: string; channelId: string; counterpartyChainId: string; }[], destinationAsset: { chainId: string; denom: string; }, swapChannelIndex: number, swapReceiver: string[], notificationInfo: { currencies: AppCurrency[]; }, txHash: Uint8Array): string; getRecentIBCHistory(id: string): IBCHistory | undefined; getRecentIBCHistories(): IBCHistory[]; removeRecentIBCHistory(id: string): boolean; clearAllRecentIBCHistory(): void; trackIBCPacketForwardingRecursive(trackHandler: (onFulfill: () => void, onClose: () => void, onError: () => void) => void): void; protected trackIBCPacketForwardingRecursiveInternal: (id: string, onFulfill: () => void, onClose: () => void, onError: () => void) => void; protected checkAndTrackSwapTxFulfilledRecursive: (params: { chainId: string; txHash: string; onSuccess: () => void; onPending: () => void; onFailed: () => void; onError: () => void; }) => void; protected resolveTxExecutionStatus(modularChainInfo: ModularChainInfo, chainId: string, txHash: string): Promise<"success" | "failed" | "pending" | "error">; protected trackDestinationAssetAmount(params: { chainId: string; txHash: string; recipient: string; targetDenom: string; onResult: (resAmount: { amount: string; denom: string; }[]) => void; onRefund?: (refundInfo: { chainId: string; amount: { amount: string; denom: string; }[]; }, error?: string) => void; onFulfill: () => void; }): void; protected traceCosmosTransactionResult(params: { rpc: string; txHash: string; recipient: string; onResult: (resAmount: { amount: string; denom: string; }[]) => void; onFulfill: () => void; }): void; protected traceEVMTransactionResult(params: { chainId: string; txHash: string; recipient: string; targetDenom: string; onResult: (result: { success: boolean; resAmount?: { amount: string; denom: string; }[]; refundInfo?: { chainId: string; amount: { amount: string; denom: string; }[]; }; error?: string; }) => void; onFulfill: () => void; }): void; protected parseEVMTxReceiptLogs(params: { txReceipt: EthTxReceipt; recipient: string; targetChainId: string; targetDenom: string; onResult: (result: { success: boolean; resAmount?: { amount: string; denom: string; }[]; refundInfo?: { chainId: string; amount: { amount: string; denom: string; }[]; }; error?: string; }) => void; }): void; recordTxWithSkipSwap(sourceChainId: string, destinationChainId: string, destinationAsset: { chainId: string; denom: string; expectedAmount: string; }, simpleRoute: { isOnlyEvm: boolean; chainId: string; receiver: string; }[], sender: string, recipient: string, amount: { amount: string; denom: string; }[], notificationInfo: { currencies: AppCurrency[]; }, routeDurationSeconds: number | undefined, txHash: string, isOnlyUseBridge?: boolean): string; getRecentSkipHistory(id: string): SkipHistory | undefined; getRecentSkipHistories(): SkipHistory[]; trackSkipSwapRecursive(id: string): void; protected requestSkipTxTrackInternal(params: { chainId: string; txHash: string; onFulfill: (keepTracking: boolean) => void; onRemoveHistory: () => void; }): void; protected checkAndUpdateSkipSwapHistoryRecursive: (id: string, onFulfill: () => void, onError: () => void) => void; protected trackSkipDestinationAssetAmount(historyId: string, txHash: string, onFulfill: () => void): void; removeRecentSkipHistory(id: string): boolean; clearAllRecentSkipHistory(): void; recordTxWithSwapV2(fromChainId: string, toChainId: string, provider: SwapProvider, destinationAsset: { chainId: string; denom: string; expectedAmount: string; }, simpleRoute: { isOnlyEvm: boolean; chainId: string; receiver: string; }[], sender: string, recipient: string, amount: { amount: string; denom: string; }[], notificationInfo: { currencies: AppCurrency[]; }, routeDurationSeconds: number | undefined, txHash: string, isOnlyUseBridge?: boolean, squidQuoteId?: string, backgroundExecutionId?: string): string; trackSwapV2Recursive(id: string): void; protected checkAndUpdateSwapV2HistoryRecursive(id: string, onFulfill: () => void, onError: () => void): void; protected processSwapV2StatusResponse(id: string, response: SwapV2TxStatusResponse, onFulfill: () => void, onError: () => void): void; /** * Track released asset amount from tx receipt. * - SUCCESS: destination asset 추적 * - FAILED/PARTIAL_SUCCESS + assetLocationInfo: refund된 자산 추적 */ protected trackSwapV2ReleasedAssetAmount(historyId: string, txHash: string, targetChainId: string, targetDenom: string, onFulfill: () => void): void; getRecentSwapV2History(id: string): SwapV2History | undefined; getRecentSwapV2Histories(): SwapV2History[]; removeRecentSwapV2History(id: string): boolean; clearAllRecentSwapV2History(): void; protected notifySwapV2Success(history: SwapV2History): void; hideSwapV2History(id: string): boolean; showSwapV2History(id: string): boolean; setSwapV2HistoryError(id: string, error: string): boolean; clearSwapV2HistoryBackgroundExecutionId(id: string): boolean; setSwapV2AdditionalTrackingData(id: string, data: { type: "evm"; chainId: string; txHash: string; } | { type: "cosmos-ibc"; ibcSwapData: IBCSwapMinimalTrackingData; txHash: string; }): boolean; trackSwapV2AdditionalRecursive(id: string): void; protected trackSwapV2AdditionalEVM(id: string): void; protected trackSwapV2AdditionalCosmosIBCInternal(id: string, onFulfill: () => void, onClose: () => void, onError: () => void): void; /** * IBC tx 완료 대기 및 첫 번째 hop res amount 추출 */ protected trackIBCTxFulfillment(params: { chainId: string; txHash: string; ibcHistory: IbcHop[]; swapReceiver?: string[]; onTxFulfilled: (tx: any, firstHopResAmount?: { amount: string; denom: string; }[]) => void; onTxError: (error: string) => void; onFulfill: () => void; onClose: () => void; onError: () => void; }): void; /** * IBC rewind 필요 여부 확인 및 rewind 처리 */ protected handleIbcRewindIfNeeded(params: { sourceChainId: string; ibcHistory: IbcHop[]; packetTimeout?: boolean; swapContext?: { swapReceiver: string[]; swapChannelIndex: number; setSwapRefundInfo?: (refundInfo: { chainId: string; amount: { amount: string; denom: string; }[]; }) => void; }; onFulfill: () => void; onClose: () => void; onError: () => void; onRewindComplete: () => void; }): boolean; protected trackIbcHopFlowWithTimeout(params: { ibcHistory: IbcHop[]; sourceChainId: string; swapReceiver?: string[]; destinationAsset?: { chainId: string; denom: string; }; onHopCompleted?: (resAmount?: { amount: string; denom: string; }[], tx?: any) => void; onAllCompleted: () => void; onContinue: () => void; onRetry: () => void; onPacketTimeout?: () => void; onDynamicHopDetected?: () => void; onFulfill: () => void; onClose: () => void; onError: () => void; }): void; protected trackIBCHopRecvPacket(params: { ibcHistory: IbcHop[]; targetChannelIndex: number; swapReceiver?: string[]; destinationAsset?: { chainId: string; denom: string; }; onHopCompleted: (resAmount?: { amount: string; denom: string; }[], tx?: any) => void; onAllCompleted: () => void; onContinue: () => void; onFulfill: () => void; onClose: () => void; onError: () => void; onDynamicHopDetected?: (hopInfo: { portId: string; channelId: string; counterpartyChainId: string; sequence: string; dstChannelId: string; packetData: { denom: string; amount: string; receiver: string; }; }) => void; }): TendermintTxTracer | undefined; protected getIBCWriteAcknowledgementAckFromTx(tx: any, sourcePortId: string, sourceChannelId: string, sequence: string): Uint8Array | undefined; protected getIBCSwapResAmountFromTx(tx: any, receiver: string, startEventsIndex?: number, endEventsIndex?: number): { amount: string; denom: string; }[]; /** * TX에서 send_packet 이벤트 정보를 추출하여 추가 IBC 홉을 감지하기 위해 사용됩니다. * * 예를 들어, 마지막 목적지 체인에서 IBC wrapped token을 unwrap하는 경우, * send_packet 이벤트를 통해 추가 IBC 홉을 감지할 수 있습니다. */ protected getSendPacketInfoFromTx(tx: any, startEventsIndex?: number): { srcChannel: string; dstChannel: string; sequence: string; packetData: { denom: string; amount: string; receiver: string; }; }[]; protected getIBCAcknowledgementPacketIndexFromTx(tx: any, sourcePortId: string, sourceChannelId: string, sequence: string): number; protected getIBCTimeoutPacketIndexFromTx(tx: any, sourcePortId: string, sourceChannelId: string, sequence: string): number; protected getLastIBCTimeoutPacketBeforeIndexFromTx(tx: any, index: number): number; protected getIBCRecvPacketIndexFromTx(tx: any, sourcePortId: string, sourceChannelId: string, sequence: string): number; protected getIBCPacketSequenceFromTx(tx: any, sourcePortId: string, sourceChannelId: string, startingEventIndex?: number): string; protected getDstChannelIdFromTx(tx: any, sourcePortId: string, sourceChannelId: string, startingEventIndex?: number): string; protected readonly onChainRemoved: (chainId: string) => void; protected removeIBCHistoriesByChainIdentifier(chainIdentifier: string): void; protected removeSkipHistoriesByChainIdentifier(chainIdentifier: string): void; protected removeSwapV2HistoriesByChainIdentifier(chainIdentifier: string): void; private getExecutableChainIdsFromSwapV2History; }