@0xsequence/relayer 0.40.5 → 0.41.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/dist/0xsequence-relayer.cjs.dev.js +172 -57
- package/dist/0xsequence-relayer.cjs.prod.js +172 -57
- package/dist/0xsequence-relayer.esm.js +172 -57
- package/dist/declarations/src/index.d.ts +2 -2
- package/dist/declarations/src/local-relayer.d.ts +2 -2
- package/dist/declarations/src/provider-relayer.d.ts +2 -2
- package/dist/declarations/src/rpc-relayer/index.d.ts +3 -3
- package/package.json +5 -5
- package/src/index.ts +6 -2
- package/src/local-relayer.ts +11 -3
- package/src/provider-relayer.ts +115 -49
- package/src/rpc-relayer/index.ts +105 -28
package/src/rpc-relayer/index.ts
CHANGED
|
@@ -21,7 +21,14 @@ import * as proto from './relayer.gen'
|
|
|
21
21
|
|
|
22
22
|
export { proto }
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const FINAL_STATUSES = [
|
|
25
|
+
proto.ETHTxnStatus.DROPPED,
|
|
26
|
+
proto.ETHTxnStatus.SUCCEEDED,
|
|
27
|
+
proto.ETHTxnStatus.PARTIALLY_FAILED,
|
|
28
|
+
proto.ETHTxnStatus.FAILED
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const FAILED_STATUSES = [proto.ETHTxnStatus.DROPPED, proto.ETHTxnStatus.PARTIALLY_FAILED, proto.ETHTxnStatus.FAILED]
|
|
25
32
|
|
|
26
33
|
export interface RpcRelayerOptions extends BaseRelayerOptions {
|
|
27
34
|
url: string
|
|
@@ -39,32 +46,51 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
39
46
|
this.service = new proto.Relayer(options.url, fetchPonyfill().fetch)
|
|
40
47
|
}
|
|
41
48
|
|
|
42
|
-
async waitReceipt(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
async waitReceipt(
|
|
50
|
+
metaTxnId: string | SignedTransactions,
|
|
51
|
+
delay: number = 1000,
|
|
52
|
+
maxFails: number = 5,
|
|
53
|
+
isCancelled?: () => boolean
|
|
54
|
+
): Promise<proto.GetMetaTxnReceiptReturn> {
|
|
55
|
+
if (typeof metaTxnId !== 'string') {
|
|
56
|
+
logger.info('computing id', metaTxnId.config, metaTxnId.context, metaTxnId.chainId, ...metaTxnId.transactions)
|
|
57
|
+
|
|
58
|
+
metaTxnId = computeMetaTxnHash(addressOf(metaTxnId.config, metaTxnId.context), metaTxnId.chainId, ...metaTxnId.transactions)
|
|
48
59
|
}
|
|
49
60
|
|
|
50
|
-
logger.info(`[rpc-relayer/waitReceipt] waiting for ${
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
logger.info(`[rpc-relayer/waitReceipt] waiting for ${metaTxnId}`)
|
|
62
|
+
|
|
63
|
+
let fails = 0
|
|
64
|
+
|
|
65
|
+
while (isCancelled === undefined || !isCancelled()) {
|
|
66
|
+
try {
|
|
67
|
+
const { receipt } = await this.service.getMetaTxnReceipt({ metaTxID: metaTxnId })
|
|
68
|
+
|
|
69
|
+
if (!receipt) {
|
|
70
|
+
throw new Error('missing expected receipt')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!receipt.txnReceipt) {
|
|
74
|
+
throw new Error('missing expected transaction receipt')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (FINAL_STATUSES.includes(receipt.status as proto.ETHTxnStatus)) {
|
|
78
|
+
return { receipt }
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
fails++
|
|
82
|
+
|
|
83
|
+
if (fails === maxFails) {
|
|
84
|
+
throw e
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isCancelled === undefined || !isCancelled()) {
|
|
89
|
+
await new Promise(resolve => setTimeout(resolve, delay))
|
|
90
|
+
}
|
|
65
91
|
}
|
|
66
92
|
|
|
67
|
-
|
|
93
|
+
throw new Error(`Cancelled waiting for transaction receipt ${metaTxnId}`)
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
async simulate(wallet: string, ...transactions: Transaction[]): Promise<SimulateResult[]> {
|
|
@@ -180,7 +206,11 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
180
206
|
return nonce
|
|
181
207
|
}
|
|
182
208
|
|
|
183
|
-
async relay(
|
|
209
|
+
async relay(
|
|
210
|
+
signedTxs: SignedTransactions,
|
|
211
|
+
quote?: FeeQuote,
|
|
212
|
+
waitForReceipt: boolean = true
|
|
213
|
+
): Promise<TransactionResponse<RelayerTxReceipt>> {
|
|
184
214
|
logger.info(
|
|
185
215
|
`[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}`
|
|
186
216
|
)
|
|
@@ -213,11 +243,58 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
213
243
|
|
|
214
244
|
logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`)
|
|
215
245
|
|
|
216
|
-
|
|
246
|
+
if (waitForReceipt) {
|
|
247
|
+
return this.wait(metaTxn.txnHash)
|
|
248
|
+
} else {
|
|
249
|
+
const response = {
|
|
250
|
+
hash: metaTxn.txnHash,
|
|
251
|
+
confirmations: 0,
|
|
252
|
+
from: walletAddress,
|
|
253
|
+
wait: (_confirmations?: number): Promise<ethers.providers.TransactionReceipt> => Promise.reject(new Error('impossible'))
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const wait = async (confirmations?: number): Promise<ethers.providers.TransactionReceipt> => {
|
|
257
|
+
if (!this.provider) {
|
|
258
|
+
throw new Error('cannot wait for receipt, relayer has no provider set')
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const waitResponse = await this.wait(metaTxn.txnHash)
|
|
262
|
+
const transactionHash = waitResponse.receipt?.transactionHash
|
|
263
|
+
|
|
264
|
+
if (!transactionHash) {
|
|
265
|
+
throw new Error('cannot wait for receipt, unknown native transaction hash')
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
Object.assign(response, waitResponse)
|
|
269
|
+
|
|
270
|
+
return this.provider.waitForTransaction(transactionHash, confirmations)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
response.wait = wait
|
|
274
|
+
|
|
275
|
+
return response as TransactionResponse
|
|
276
|
+
}
|
|
217
277
|
}
|
|
218
278
|
|
|
219
|
-
async wait(
|
|
220
|
-
|
|
279
|
+
async wait(
|
|
280
|
+
metaTxnId: string | SignedTransactions,
|
|
281
|
+
timeout?: number,
|
|
282
|
+
delay: number = 1000,
|
|
283
|
+
maxFails: number = 5
|
|
284
|
+
): Promise<TransactionResponse<RelayerTxReceipt>> {
|
|
285
|
+
let timedOut = false
|
|
286
|
+
|
|
287
|
+
const { receipt } = await (timeout !== undefined
|
|
288
|
+
? Promise.race([
|
|
289
|
+
this.waitReceipt(metaTxnId, delay, maxFails, () => timedOut),
|
|
290
|
+
new Promise<proto.GetMetaTxnReceiptReturn>((_, reject) =>
|
|
291
|
+
setTimeout(() => {
|
|
292
|
+
timedOut = true
|
|
293
|
+
reject(`Timeout waiting for transaction receipt ${metaTxnId}`)
|
|
294
|
+
}, timeout)
|
|
295
|
+
)
|
|
296
|
+
])
|
|
297
|
+
: this.waitReceipt(metaTxnId, delay, maxFails))
|
|
221
298
|
|
|
222
299
|
if (!receipt.txnReceipt || FAILED_STATUSES.includes(receipt.status as proto.ETHTxnStatus)) {
|
|
223
300
|
throw new MetaTransactionResponseException(receipt)
|
|
@@ -229,7 +306,7 @@ export class RpcRelayer extends BaseRelayer implements Relayer {
|
|
|
229
306
|
blockHash: txReceipt.blockHash,
|
|
230
307
|
blockNumber: ethers.BigNumber.from(txReceipt.blockNumber).toNumber(),
|
|
231
308
|
confirmations: 1,
|
|
232
|
-
from: typeof
|
|
309
|
+
from: typeof metaTxnId === 'string' ? undefined : addressOf(metaTxnId.config, metaTxnId.context),
|
|
233
310
|
hash: txReceipt.transactionHash,
|
|
234
311
|
raw: receipt.txnReceipt,
|
|
235
312
|
receipt: txReceipt, // extended type which is Sequence-specific. Contains the decoded metaTxReceipt
|