@keplr-wallet/background 0.12.312 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +1 -0
- package/build/index.js +7 -1
- package/build/index.js.map +1 -1
- package/build/keyring-cosmos/service.d.ts +10 -0
- package/build/keyring-cosmos/service.js +100 -0
- package/build/keyring-cosmos/service.js.map +1 -1
- package/build/keyring-ethereum/service.d.ts +5 -0
- package/build/keyring-ethereum/service.js +66 -0
- package/build/keyring-ethereum/service.js.map +1 -1
- package/build/recent-send-history/api.d.ts +31 -0
- package/build/recent-send-history/api.js +97 -0
- package/build/recent-send-history/api.js.map +1 -0
- package/build/recent-send-history/handler.js +36 -0
- package/build/recent-send-history/handler.js.map +1 -1
- package/build/recent-send-history/init.js +5 -0
- package/build/recent-send-history/init.js.map +1 -1
- package/build/recent-send-history/messages.d.ts +76 -1
- package/build/recent-send-history/messages.js +121 -1
- package/build/recent-send-history/messages.js.map +1 -1
- package/build/recent-send-history/service.d.ts +262 -9
- package/build/recent-send-history/service.js +2103 -812
- package/build/recent-send-history/service.js.map +1 -1
- package/build/recent-send-history/types.d.ts +214 -22
- package/build/recent-send-history/types.js +21 -0
- package/build/recent-send-history/types.js.map +1 -1
- package/build/tx/service.d.ts +2 -0
- package/build/tx/service.js +35 -0
- package/build/tx/service.js.map +1 -1
- package/build/tx-ethereum/service.d.ts +2 -0
- package/build/tx-ethereum/service.js +42 -0
- package/build/tx-ethereum/service.js.map +1 -1
- package/build/tx-executor/constants.d.ts +1 -0
- package/build/tx-executor/constants.js +5 -0
- package/build/tx-executor/constants.js.map +1 -0
- package/build/tx-executor/handler.d.ts +3 -0
- package/build/tx-executor/handler.js +45 -0
- package/build/tx-executor/handler.js.map +1 -0
- package/build/tx-executor/index.d.ts +3 -0
- package/build/tx-executor/index.js +20 -0
- package/build/tx-executor/index.js.map +1 -0
- package/build/tx-executor/init.d.ts +3 -0
- package/build/tx-executor/init.js +14 -0
- package/build/tx-executor/init.js.map +1 -0
- package/build/tx-executor/internal.d.ts +4 -0
- package/build/tx-executor/internal.js +24 -0
- package/build/tx-executor/internal.js.map +1 -0
- package/build/tx-executor/messages.d.ts +53 -0
- package/build/tx-executor/messages.js +116 -0
- package/build/tx-executor/messages.js.map +1 -0
- package/build/tx-executor/service.d.ts +67 -0
- package/build/tx-executor/service.js +715 -0
- package/build/tx-executor/service.js.map +1 -0
- package/build/tx-executor/types.d.ts +105 -0
- package/build/tx-executor/types.js +33 -0
- package/build/tx-executor/types.js.map +1 -0
- package/build/tx-executor/utils/cosmos.d.ts +59 -0
- package/build/tx-executor/utils/cosmos.js +526 -0
- package/build/tx-executor/utils/cosmos.js.map +1 -0
- package/build/tx-executor/utils/evm.d.ts +4 -0
- package/build/tx-executor/utils/evm.js +236 -0
- package/build/tx-executor/utils/evm.js.map +1 -0
- package/package.json +13 -13
- package/src/index.ts +24 -1
- package/src/keyring-cosmos/service.ts +151 -0
- package/src/keyring-ethereum/service.ts +103 -6
- package/src/recent-send-history/api.ts +119 -0
- package/src/recent-send-history/handler.ts +84 -0
- package/src/recent-send-history/init.ts +10 -0
- package/src/recent-send-history/messages.ts +163 -1
- package/src/recent-send-history/service.ts +3042 -1153
- package/src/recent-send-history/types.ts +268 -31
- package/src/tx/service.ts +41 -0
- package/src/tx-ethereum/service.ts +57 -0
- package/src/tx-executor/constants.ts +1 -0
- package/src/tx-executor/handler.ts +71 -0
- package/src/tx-executor/index.ts +3 -0
- package/src/tx-executor/init.ts +20 -0
- package/src/tx-executor/internal.ts +9 -0
- package/src/tx-executor/messages.ts +157 -0
- package/src/tx-executor/service.ts +1025 -0
- package/src/tx-executor/types.ts +161 -0
- package/src/tx-executor/utils/cosmos.ts +771 -0
- package/src/tx-executor/utils/evm.ts +310 -0
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import { AppCurrency } from "@keplr-wallet/types";
|
|
1
|
+
import { AppCurrency, SwapProvider } from "@keplr-wallet/types";
|
|
2
2
|
|
|
3
|
+
export { SwapProvider };
|
|
4
|
+
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// RecentSend History Types
|
|
7
|
+
// ============================================================================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Stored recent send history record.
|
|
11
|
+
*/
|
|
3
12
|
export interface RecentSendHistory {
|
|
4
|
-
timestamp: number;
|
|
5
13
|
sender: string;
|
|
6
14
|
recipient: string;
|
|
7
15
|
amount: {
|
|
@@ -9,7 +17,6 @@ export interface RecentSendHistory {
|
|
|
9
17
|
denom: string;
|
|
10
18
|
}[];
|
|
11
19
|
memo: string;
|
|
12
|
-
|
|
13
20
|
ibcChannels:
|
|
14
21
|
| {
|
|
15
22
|
portId: string;
|
|
@@ -17,8 +24,123 @@ export interface RecentSendHistory {
|
|
|
17
24
|
counterpartyChainId: string;
|
|
18
25
|
}[]
|
|
19
26
|
| undefined;
|
|
27
|
+
timestamp: number;
|
|
20
28
|
}
|
|
21
29
|
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// IBC History Types (Transfer & Swap)
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Data required to record an IBC transfer history.
|
|
36
|
+
* Used by tx-executor when creating history entries.
|
|
37
|
+
*/
|
|
38
|
+
export interface IBCTransferHistoryData {
|
|
39
|
+
readonly historyType: string;
|
|
40
|
+
readonly sourceChainId: string;
|
|
41
|
+
readonly destinationChainId: string;
|
|
42
|
+
readonly channels: {
|
|
43
|
+
portId: string;
|
|
44
|
+
channelId: string;
|
|
45
|
+
counterpartyChainId: string;
|
|
46
|
+
}[];
|
|
47
|
+
readonly sender: string;
|
|
48
|
+
readonly recipient: string;
|
|
49
|
+
readonly amount: {
|
|
50
|
+
readonly amount: string;
|
|
51
|
+
readonly denom: string;
|
|
52
|
+
}[];
|
|
53
|
+
readonly memo: string;
|
|
54
|
+
readonly notificationInfo: {
|
|
55
|
+
readonly currencies: AppCurrency[];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Data required to record an IBC swap history.
|
|
61
|
+
* Used by tx-executor when creating history entries.
|
|
62
|
+
*/
|
|
63
|
+
export interface IBCSwapHistoryData {
|
|
64
|
+
readonly swapType: "amount-in" | "amount-out";
|
|
65
|
+
readonly chainId: string;
|
|
66
|
+
readonly destinationChainId: string;
|
|
67
|
+
readonly sender: string;
|
|
68
|
+
readonly amount: {
|
|
69
|
+
amount: string;
|
|
70
|
+
denom: string;
|
|
71
|
+
}[];
|
|
72
|
+
readonly memo: string;
|
|
73
|
+
readonly ibcChannels: {
|
|
74
|
+
portId: string;
|
|
75
|
+
channelId: string;
|
|
76
|
+
counterpartyChainId: string;
|
|
77
|
+
}[];
|
|
78
|
+
readonly destinationAsset: {
|
|
79
|
+
chainId: string;
|
|
80
|
+
denom: string;
|
|
81
|
+
};
|
|
82
|
+
readonly swapChannelIndex: number;
|
|
83
|
+
readonly swapReceiver: string[];
|
|
84
|
+
readonly notificationInfo: {
|
|
85
|
+
currencies: AppCurrency[];
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// IBC swap 추가 트래킹에 필요한 최소 입력 데이터
|
|
90
|
+
export type IBCSwapMinimalTrackingData = Pick<
|
|
91
|
+
IBCSwapHistoryData,
|
|
92
|
+
"chainId" | "swapReceiver" | "ibcChannels" | "swapChannelIndex"
|
|
93
|
+
>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Stored IBC transfer history record (subset of IBCHistory).
|
|
97
|
+
*/
|
|
98
|
+
export interface IBCTransferHistory {
|
|
99
|
+
recipient: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Stored IBC swap history record (subset of IBCHistory).
|
|
104
|
+
*/
|
|
105
|
+
export interface IBCSwapHistory {
|
|
106
|
+
swapType: "amount-in" | "amount-out";
|
|
107
|
+
swapChannelIndex: number;
|
|
108
|
+
swapReceiver: string[];
|
|
109
|
+
|
|
110
|
+
destinationAsset: {
|
|
111
|
+
chainId: string;
|
|
112
|
+
denom: string;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
resAmount: {
|
|
116
|
+
amount: string;
|
|
117
|
+
denom: string;
|
|
118
|
+
}[][];
|
|
119
|
+
|
|
120
|
+
swapRefundInfo?: {
|
|
121
|
+
chainId: string;
|
|
122
|
+
amount: {
|
|
123
|
+
amount: string;
|
|
124
|
+
denom: string;
|
|
125
|
+
}[];
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export type IbcHop = {
|
|
130
|
+
portId: string;
|
|
131
|
+
channelId: string;
|
|
132
|
+
counterpartyChainId: string;
|
|
133
|
+
sequence?: string;
|
|
134
|
+
dstChannelId?: string;
|
|
135
|
+
completed: boolean;
|
|
136
|
+
error?: string;
|
|
137
|
+
rewound?: boolean;
|
|
138
|
+
rewoundButNextRewindingBlocked?: boolean;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Stored IBC history record (union of IBCTransferHistory and IBCSwapHistory).
|
|
143
|
+
*/
|
|
22
144
|
export type IBCHistory = {
|
|
23
145
|
id: string;
|
|
24
146
|
chainId: string;
|
|
@@ -38,25 +160,7 @@ export type IBCHistory = {
|
|
|
38
160
|
txError?: string;
|
|
39
161
|
packetTimeout?: boolean;
|
|
40
162
|
|
|
41
|
-
ibcHistory:
|
|
42
|
-
| {
|
|
43
|
-
portId: string;
|
|
44
|
-
channelId: string;
|
|
45
|
-
counterpartyChainId: string;
|
|
46
|
-
|
|
47
|
-
sequence?: string;
|
|
48
|
-
// 위의 channel id는 src channel id이고
|
|
49
|
-
// 얘는 dst channel id이다
|
|
50
|
-
// 각 tracking이 완료될때마다 events에서 찾아서 추가된다.
|
|
51
|
-
dstChannelId?: string;
|
|
52
|
-
|
|
53
|
-
completed: boolean;
|
|
54
|
-
error?: string;
|
|
55
|
-
rewound?: boolean;
|
|
56
|
-
// swap 이후에는 rewind가 불가능하기 때문에
|
|
57
|
-
// swap 등에서는 이 값이 true일 수 있음
|
|
58
|
-
rewoundButNextRewindingBlocked?: boolean;
|
|
59
|
-
}[];
|
|
163
|
+
ibcHistory: IbcHop[];
|
|
60
164
|
|
|
61
165
|
// Already notified to user
|
|
62
166
|
notified?: boolean;
|
|
@@ -65,34 +169,155 @@ export type IBCHistory = {
|
|
|
65
169
|
};
|
|
66
170
|
} & (IBCTransferHistory | IBCSwapHistory);
|
|
67
171
|
|
|
68
|
-
|
|
69
|
-
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// SwapV2 History Types
|
|
174
|
+
// ============================================================================
|
|
175
|
+
|
|
176
|
+
export enum SwapV2RouteStepStatus {
|
|
177
|
+
IN_PROGRESS = "in_progress",
|
|
178
|
+
SUCCESS = "success",
|
|
179
|
+
FAILED = "failed",
|
|
180
|
+
UNKNOWN = "unknown",
|
|
70
181
|
}
|
|
71
182
|
|
|
72
|
-
export
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
183
|
+
export enum SwapV2TxStatus {
|
|
184
|
+
IN_PROGRESS = "in_progress",
|
|
185
|
+
SUCCESS = "success",
|
|
186
|
+
PARTIAL_SUCCESS = "partial_success",
|
|
187
|
+
FAILED = "failed",
|
|
188
|
+
UNKNOWN = "unknown",
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface SwapV2TxStatusStep {
|
|
192
|
+
chain_id: string;
|
|
193
|
+
status: SwapV2RouteStepStatus;
|
|
194
|
+
tx_hash?: string;
|
|
195
|
+
explorer_url?: string;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface SwapV2AssetLocation {
|
|
199
|
+
chain_id: string;
|
|
200
|
+
denom: string;
|
|
201
|
+
amount: string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface SwapV2TxStatusRequest {
|
|
205
|
+
provider: SwapProvider;
|
|
206
|
+
from_chain: string;
|
|
207
|
+
to_chain?: string; // optional, used by Squid
|
|
208
|
+
tx_hash: string;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface SwapV2TxStatusResponse {
|
|
212
|
+
provider: SwapProvider;
|
|
213
|
+
status: SwapV2TxStatus;
|
|
214
|
+
steps: SwapV2TxStatusStep[];
|
|
215
|
+
asset_location?: SwapV2AssetLocation | null;
|
|
216
|
+
}
|
|
76
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Base interface for SwapV2History data.
|
|
220
|
+
* Contains common fields between SwapV2HistoryData and SwapV2History.
|
|
221
|
+
*/
|
|
222
|
+
export interface SwapV2HistoryBase {
|
|
223
|
+
fromChainId: string;
|
|
224
|
+
toChainId: string;
|
|
225
|
+
provider: SwapProvider;
|
|
226
|
+
sender: string;
|
|
227
|
+
recipient: string;
|
|
228
|
+
amount: {
|
|
229
|
+
amount: string;
|
|
230
|
+
denom: string;
|
|
231
|
+
}[];
|
|
232
|
+
simpleRoute: {
|
|
233
|
+
isOnlyEvm: boolean;
|
|
234
|
+
chainId: string;
|
|
235
|
+
receiver: string;
|
|
236
|
+
}[];
|
|
77
237
|
destinationAsset: {
|
|
78
238
|
chainId: string;
|
|
79
239
|
denom: string;
|
|
240
|
+
expectedAmount: string;
|
|
241
|
+
};
|
|
242
|
+
routeDurationSeconds: number;
|
|
243
|
+
notificationInfo: {
|
|
244
|
+
currencies: AppCurrency[];
|
|
80
245
|
};
|
|
246
|
+
isOnlyUseBridge?: boolean;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Data required to record a SwapV2 history.
|
|
251
|
+
* Used by tx-executor when creating history entries.
|
|
252
|
+
*/
|
|
253
|
+
export type SwapV2HistoryData = SwapV2HistoryBase;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Stored SwapV2 history record.
|
|
257
|
+
*/
|
|
258
|
+
export interface SwapV2History extends SwapV2HistoryBase {
|
|
259
|
+
id: string;
|
|
260
|
+
timestamp: number;
|
|
261
|
+
txHash: string;
|
|
262
|
+
|
|
263
|
+
status: SwapV2TxStatus;
|
|
264
|
+
routeIndex: number; // 현재까지 진행된 라우팅 인덱스
|
|
81
265
|
|
|
82
266
|
resAmount: {
|
|
83
267
|
amount: string;
|
|
84
268
|
denom: string;
|
|
85
269
|
}[][];
|
|
86
270
|
|
|
87
|
-
|
|
271
|
+
assetLocationInfo?: {
|
|
88
272
|
chainId: string;
|
|
89
273
|
amount: {
|
|
90
274
|
amount: string;
|
|
91
275
|
denom: string;
|
|
92
276
|
}[];
|
|
277
|
+
/**
|
|
278
|
+
* "refund": 실패/오류로 인해 자산이 중간에서 릴리즈된 경우
|
|
279
|
+
* "intermediate": TX는 성공했지만 자산이 최종 목적지가 아닌 중간 단계에 도달한 경우
|
|
280
|
+
* (예: base USDC -> osmosis OSMO 스왑 시, noble USDC가 먼저 도착)
|
|
281
|
+
* 이 경우 추가 TX를 실행하여 최종 목적지로 자산을 보내거나,
|
|
282
|
+
* 현재 받은 자산을 그대로 둘 수 있음
|
|
283
|
+
*/
|
|
284
|
+
type: "refund" | "intermediate";
|
|
93
285
|
};
|
|
286
|
+
|
|
287
|
+
backgroundExecutionId?: string;
|
|
288
|
+
|
|
289
|
+
// Multi TX swap 재개 시 추가 트래킹 데이터
|
|
290
|
+
additionalTrackingData?:
|
|
291
|
+
| { type: "evm"; chainId: string; txHash: string } // EVM: debug_traceTransaction으로 추적
|
|
292
|
+
| {
|
|
293
|
+
type: "cosmos-ibc";
|
|
294
|
+
chainId: string;
|
|
295
|
+
swapReceiver: string[];
|
|
296
|
+
swapChannelIndex: number;
|
|
297
|
+
txHash: string; // 시작 트랜잭션 해시
|
|
298
|
+
txFulfilled?: boolean; // 시작 트랜잭션 완료 여부
|
|
299
|
+
packetTimeout?: boolean;
|
|
300
|
+
dynamicHopDetected?: boolean; // 동적 홉이 감지되었는지 여부
|
|
301
|
+
// 각 IBC hop의 tracking 상태 (필요 최소 데이터만 저장)
|
|
302
|
+
ibcHistory: IbcHop[];
|
|
303
|
+
};
|
|
304
|
+
additionalTrackDone?: boolean; // additional tracking 완료 여부
|
|
305
|
+
additionalTrackError?: string; // additional tracking 에러
|
|
306
|
+
|
|
307
|
+
trackDone?: boolean; // status tracking이 완료되었는지 여부
|
|
308
|
+
trackError?: string; // status tracking 중 에러가 발생했는지 여부
|
|
309
|
+
finalizationRetryCount?: number; // success/partial_success/failed 상태에서 currentStep이 진행 중일 때 추가 polling 횟수
|
|
310
|
+
unknownStatusFirstSeenAt?: number; // UNKNOWN 상태가 처음 발견된 timestamp (ms)
|
|
311
|
+
|
|
312
|
+
notified?: boolean;
|
|
313
|
+
|
|
314
|
+
hidden?: boolean;
|
|
94
315
|
}
|
|
95
316
|
|
|
317
|
+
// ============================================================================
|
|
318
|
+
// Skip History Types (Legacy)
|
|
319
|
+
// ============================================================================
|
|
320
|
+
|
|
96
321
|
export type SkipHistory = {
|
|
97
322
|
id: string;
|
|
98
323
|
chainId: string;
|
|
@@ -147,10 +372,22 @@ export type SkipHistory = {
|
|
|
147
372
|
isOnlyUseBridge?: boolean; // send bridge 페이지에서 swap코드를 사용 하고 있기 때문에 브릿지만 사용했는지 여부 필요함
|
|
148
373
|
};
|
|
149
374
|
|
|
375
|
+
// ============================================================================
|
|
376
|
+
// History Data Union Type
|
|
377
|
+
// ============================================================================
|
|
378
|
+
|
|
150
379
|
/**
|
|
151
|
-
*
|
|
152
|
-
* Reference: https://github.com/skip-mev/skip-go/blob/staging/packages/client/src/types/lifecycle.ts
|
|
380
|
+
* Union type of all history data types.
|
|
153
381
|
*/
|
|
382
|
+
export type HistoryData =
|
|
383
|
+
| IBCTransferHistoryData
|
|
384
|
+
| IBCSwapHistoryData
|
|
385
|
+
| SwapV2HistoryData;
|
|
386
|
+
|
|
387
|
+
// ============================================================================
|
|
388
|
+
// Skip/Bridge Tracking Types
|
|
389
|
+
// Reference: https://github.com/skip-mev/skip-go/blob/staging/packages/client/src/types/lifecycle.ts
|
|
390
|
+
// ============================================================================
|
|
154
391
|
|
|
155
392
|
export type StatusState =
|
|
156
393
|
| "STATE_UNKNOWN"
|
package/src/tx/service.ts
CHANGED
|
@@ -35,6 +35,7 @@ export class BackgroundTxService {
|
|
|
35
35
|
mode: "async" | "sync" | "block",
|
|
36
36
|
options: {
|
|
37
37
|
silent?: boolean;
|
|
38
|
+
skipTracingTxResult?: boolean;
|
|
38
39
|
onFulfill?: (tx: any) => void;
|
|
39
40
|
}
|
|
40
41
|
): Promise<Uint8Array> {
|
|
@@ -92,6 +93,10 @@ export class BackgroundTxService {
|
|
|
92
93
|
|
|
93
94
|
const txHash = Buffer.from(txResponse.txhash, "hex");
|
|
94
95
|
|
|
96
|
+
if (options.skipTracingTxResult) {
|
|
97
|
+
return txHash;
|
|
98
|
+
}
|
|
99
|
+
|
|
95
100
|
// 이 기능은 tx commit일때 notification을 띄울 뿐이다.
|
|
96
101
|
// 실제 로직 처리와는 관계가 없어야하기 때문에 여기서 await을 하면 안된다!!
|
|
97
102
|
retry(
|
|
@@ -152,6 +157,42 @@ export class BackgroundTxService {
|
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
|
|
160
|
+
async traceTx(chainId: string, txHash: string): Promise<any> {
|
|
161
|
+
const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
|
|
162
|
+
const txHashBuffer = Buffer.from(txHash, "hex");
|
|
163
|
+
|
|
164
|
+
return await retry(
|
|
165
|
+
() => {
|
|
166
|
+
return new Promise<any>((resolve, reject) => {
|
|
167
|
+
const txTracer = new TendermintTxTracer(chainInfo.rpc, "/websocket");
|
|
168
|
+
txTracer.addEventListener("close", () => {
|
|
169
|
+
// reject if ws closed before fulfilled
|
|
170
|
+
// 하지만 로직상 fulfill 되기 전에 ws가 닫히는게 되기 때문에
|
|
171
|
+
// delay를 좀 준다.
|
|
172
|
+
// trace 이후 로직은 동기적인 로직밖에 없기 때문에 문제될 게 없다.
|
|
173
|
+
// 문제될게 없다.
|
|
174
|
+
setTimeout(() => {
|
|
175
|
+
reject();
|
|
176
|
+
}, 500);
|
|
177
|
+
});
|
|
178
|
+
txTracer.addEventListener("error", () => {
|
|
179
|
+
reject();
|
|
180
|
+
});
|
|
181
|
+
txTracer.traceTx(txHashBuffer).then((tx) => {
|
|
182
|
+
txTracer.close();
|
|
183
|
+
|
|
184
|
+
resolve(tx);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
maxRetries: 10,
|
|
190
|
+
waitMsAfterError: 10 * 1000, // 10sec
|
|
191
|
+
maxWaitMsAfterError: 5 * 60 * 1000, // 5min
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
155
196
|
private static processTxResultNotification(
|
|
156
197
|
notification: Notification,
|
|
157
198
|
result: any
|
|
@@ -20,6 +20,7 @@ export class BackgroundTxEthereumService {
|
|
|
20
20
|
tx: Uint8Array,
|
|
21
21
|
options: {
|
|
22
22
|
silent?: boolean;
|
|
23
|
+
skipTracingTxResult?: boolean;
|
|
23
24
|
onFulfill?: (txReceipt: EthTxReceipt) => void;
|
|
24
25
|
}
|
|
25
26
|
): Promise<string> {
|
|
@@ -64,6 +65,10 @@ export class BackgroundTxEthereumService {
|
|
|
64
65
|
);
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
if (options.skipTracingTxResult) {
|
|
69
|
+
return txHash;
|
|
70
|
+
}
|
|
71
|
+
|
|
67
72
|
retry(
|
|
68
73
|
() => {
|
|
69
74
|
return new Promise<void>(async (resolve, reject) => {
|
|
@@ -121,6 +126,58 @@ export class BackgroundTxEthereumService {
|
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
|
|
129
|
+
async getEthereumTxReceipt(
|
|
130
|
+
origin: string,
|
|
131
|
+
chainId: string,
|
|
132
|
+
txHash: string
|
|
133
|
+
): Promise<EthTxReceipt | null> {
|
|
134
|
+
const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
|
|
135
|
+
const evmInfo = ChainsService.getEVMInfo(chainInfo);
|
|
136
|
+
if (!evmInfo) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return await retry(
|
|
141
|
+
() => {
|
|
142
|
+
return new Promise<EthTxReceipt | null>(async (resolve, reject) => {
|
|
143
|
+
const txReceiptResponse = await simpleFetch<{
|
|
144
|
+
result: EthTxReceipt | null;
|
|
145
|
+
error?: Error;
|
|
146
|
+
}>(evmInfo.rpc, {
|
|
147
|
+
method: "POST",
|
|
148
|
+
headers: {
|
|
149
|
+
"content-type": "application/json",
|
|
150
|
+
"request-source": origin,
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify({
|
|
153
|
+
jsonrpc: "2.0",
|
|
154
|
+
method: "eth_getTransactionReceipt",
|
|
155
|
+
params: [txHash],
|
|
156
|
+
id: 1,
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (txReceiptResponse.data.error) {
|
|
161
|
+
console.error(txReceiptResponse.data.error);
|
|
162
|
+
resolve(null);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const txReceipt = txReceiptResponse.data.result;
|
|
166
|
+
if (txReceipt) {
|
|
167
|
+
resolve(txReceipt);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
reject(new Error("No tx receipt responded"));
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
maxRetries: 50,
|
|
175
|
+
waitMsAfterError: 500,
|
|
176
|
+
maxWaitMsAfterError: 15000,
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
124
181
|
private static processTxResultNotification(notification: Notification): void {
|
|
125
182
|
try {
|
|
126
183
|
notification.create({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const ROUTE = "background-tx-executor";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Env,
|
|
3
|
+
Handler,
|
|
4
|
+
InternalHandler,
|
|
5
|
+
KeplrError,
|
|
6
|
+
Message,
|
|
7
|
+
} from "@keplr-wallet/router";
|
|
8
|
+
import { BackgroundTxExecutorService } from "./service";
|
|
9
|
+
import {
|
|
10
|
+
RecordAndExecuteTxsMsg,
|
|
11
|
+
ResumeTxMsg,
|
|
12
|
+
GetTxExecutionMsg,
|
|
13
|
+
} from "./messages";
|
|
14
|
+
|
|
15
|
+
export const getHandler: (service: BackgroundTxExecutorService) => Handler = (
|
|
16
|
+
service: BackgroundTxExecutorService
|
|
17
|
+
) => {
|
|
18
|
+
return (env: Env, msg: Message<unknown>) => {
|
|
19
|
+
switch (msg.constructor) {
|
|
20
|
+
case RecordAndExecuteTxsMsg:
|
|
21
|
+
return handleRecordAndExecuteTxsMsg(service)(
|
|
22
|
+
env,
|
|
23
|
+
msg as RecordAndExecuteTxsMsg
|
|
24
|
+
);
|
|
25
|
+
case GetTxExecutionMsg:
|
|
26
|
+
return handleGetTxExecutionMsg(service)(env, msg as GetTxExecutionMsg);
|
|
27
|
+
case ResumeTxMsg:
|
|
28
|
+
return handleResumeTxMsg(service)(env, msg as ResumeTxMsg);
|
|
29
|
+
default:
|
|
30
|
+
throw new KeplrError("direct-tx-executor", 100, "Unknown msg type");
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const handleRecordAndExecuteTxsMsg: (
|
|
36
|
+
service: BackgroundTxExecutorService
|
|
37
|
+
) => InternalHandler<RecordAndExecuteTxsMsg> = (service) => {
|
|
38
|
+
return (env, msg) => {
|
|
39
|
+
return service.recordAndExecuteTxs(
|
|
40
|
+
env,
|
|
41
|
+
msg.vaultId,
|
|
42
|
+
msg.executionType,
|
|
43
|
+
msg.txs,
|
|
44
|
+
msg.executableChainIds,
|
|
45
|
+
msg.historyData,
|
|
46
|
+
msg.historyTxIndex
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleResumeTxMsg: (
|
|
52
|
+
service: BackgroundTxExecutorService
|
|
53
|
+
) => InternalHandler<ResumeTxMsg> = (service) => {
|
|
54
|
+
return async (env, msg) => {
|
|
55
|
+
return await service.resumeTx(
|
|
56
|
+
env,
|
|
57
|
+
msg.id,
|
|
58
|
+
msg.txIndex,
|
|
59
|
+
msg.signedTx,
|
|
60
|
+
msg.ibcSwapData
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const handleGetTxExecutionMsg: (
|
|
66
|
+
service: BackgroundTxExecutorService
|
|
67
|
+
) => InternalHandler<GetTxExecutionMsg> = (service) => {
|
|
68
|
+
return (_env, msg) => {
|
|
69
|
+
return service.getTxExecution(msg.id);
|
|
70
|
+
};
|
|
71
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Router } from "@keplr-wallet/router";
|
|
2
|
+
import { ROUTE } from "./constants";
|
|
3
|
+
import { getHandler } from "./handler";
|
|
4
|
+
import { BackgroundTxExecutorService } from "./service";
|
|
5
|
+
import {
|
|
6
|
+
RecordAndExecuteTxsMsg,
|
|
7
|
+
ResumeTxMsg,
|
|
8
|
+
GetTxExecutionMsg,
|
|
9
|
+
} from "./messages";
|
|
10
|
+
|
|
11
|
+
export function init(
|
|
12
|
+
router: Router,
|
|
13
|
+
service: BackgroundTxExecutorService
|
|
14
|
+
): void {
|
|
15
|
+
router.registerMessage(RecordAndExecuteTxsMsg);
|
|
16
|
+
router.registerMessage(ResumeTxMsg);
|
|
17
|
+
router.registerMessage(GetTxExecutionMsg);
|
|
18
|
+
|
|
19
|
+
router.addHandler(ROUTE, getHandler(service));
|
|
20
|
+
}
|