0xtrails 0.4.2 → 0.5.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.
Files changed (81) hide show
  1. package/dist/{ccip-Dl3umoGg.js → ccip-DhEkQ6QC.js} +27 -27
  2. package/dist/cctpqueue.d.ts.map +1 -1
  3. package/dist/chains.d.ts +3 -1
  4. package/dist/chains.d.ts.map +1 -1
  5. package/dist/config.d.ts +17 -52
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/constants.d.ts +0 -6
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/{index-sMS_ge1R.js → index-MhD2DA7_.js} +23613 -23893
  10. package/dist/index.d.ts +7 -7
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +319 -944
  13. package/dist/indexerClient.d.ts +9 -6
  14. package/dist/indexerClient.d.ts.map +1 -1
  15. package/dist/intents.d.ts +0 -1
  16. package/dist/intents.d.ts.map +1 -1
  17. package/dist/prepareSend.d.ts.map +1 -1
  18. package/dist/sequenceWallet.d.ts +1 -1
  19. package/dist/sequenceWallet.d.ts.map +1 -1
  20. package/dist/trailsClient.d.ts +3 -3
  21. package/dist/trailsClient.d.ts.map +1 -1
  22. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  23. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  24. package/dist/transactionIntent/handlers/crossChain.d.ts +3 -1
  25. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -1
  26. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -1
  27. package/dist/transactionIntent/types.d.ts +1 -0
  28. package/dist/transactionIntent/types.d.ts.map +1 -1
  29. package/dist/transactions.d.ts +8 -2
  30. package/dist/transactions.d.ts.map +1 -1
  31. package/dist/wallets.d.ts.map +1 -1
  32. package/dist/widget/components/AccountIntentTransactionHistory.d.ts.map +1 -1
  33. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  34. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  35. package/dist/widget/components/SlippageToleranceSettings.d.ts +1 -0
  36. package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
  37. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  38. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  39. package/dist/widget/hooks/useQuote.d.ts +2 -4
  40. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  41. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  42. package/dist/widget/index.d.ts +1 -0
  43. package/dist/widget/index.d.ts.map +1 -1
  44. package/dist/widget/index.js +4 -2
  45. package/dist/widget/providers/TrailsProvider.d.ts +18 -0
  46. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -0
  47. package/dist/widget/widget.d.ts +3 -3
  48. package/dist/widget/widget.d.ts.map +1 -1
  49. package/package.json +3 -2
  50. package/src/analytics.ts +2 -2
  51. package/src/cctpqueue.ts +6 -3
  52. package/src/chains.ts +62 -29
  53. package/src/config.ts +36 -210
  54. package/src/constants.ts +0 -9
  55. package/src/index.ts +12 -35
  56. package/src/indexerClient.ts +39 -48
  57. package/src/intents.ts +0 -21
  58. package/src/prepareSend.ts +16 -2
  59. package/src/sequenceWallet.ts +1 -2
  60. package/src/trailsClient.ts +17 -12
  61. package/src/transactionIntent/deposits/gaslessDeposit.ts +88 -43
  62. package/src/transactionIntent/deposits/standardDeposit.ts +91 -53
  63. package/src/transactionIntent/handlers/crossChain.ts +88 -0
  64. package/src/transactionIntent/handlers/sameChainSameToken.ts +22 -0
  65. package/src/transactionIntent/types.ts +1 -0
  66. package/src/transactions.ts +122 -24
  67. package/src/wallets.ts +5 -6
  68. package/src/widget/components/AccountIntentTransactionHistory.tsx +5 -0
  69. package/src/widget/components/ConfigDisplay.tsx +19 -59
  70. package/src/widget/components/FeeOptions.tsx +1 -1
  71. package/src/widget/components/SlippageToleranceSettings.tsx +63 -14
  72. package/src/widget/components/WalletConnect.tsx +37 -99
  73. package/src/widget/hooks/useIntentTransactionHistory.ts +9 -1
  74. package/src/widget/hooks/useQuote.ts +11 -17
  75. package/src/widget/hooks/useSendForm.ts +4 -0
  76. package/src/widget/index.tsx +8 -0
  77. package/src/widget/providers/TrailsProvider.tsx +95 -0
  78. package/src/widget/widget.tsx +49 -98
  79. package/dist/trails.d.ts +0 -110
  80. package/dist/trails.d.ts.map +0 -1
  81. package/src/trails.ts +0 -1303
@@ -1,7 +1,7 @@
1
1
  import { abortControllerRegistry } from "./abortController.js"
2
2
  import { createPublicClient, http, zeroAddress } from "viem"
3
3
  import { trackPaymentError, trackPaymentStarted } from "./analytics.js"
4
- import { getSlippageTolerance } from "./config.js"
4
+ import { getSlippageToleranceValue } from "./widget/components/SlippageToleranceSettings.js"
5
5
  import { getERC20TransferData } from "./encoders.js"
6
6
  import { getTokenPrice } from "./prices.js"
7
7
  import {
@@ -73,7 +73,7 @@ export async function prepareSend(
73
73
  sourceTokenDecimals,
74
74
  destinationTokenDecimals,
75
75
  paymasterUrl,
76
- slippageTolerance = getSlippageTolerance(),
76
+ slippageTolerance: slippageToleranceFromOptions,
77
77
  originNativeTokenPriceUsd,
78
78
  quoteProvider,
79
79
  fundMethod,
@@ -84,9 +84,17 @@ export async function prepareSend(
84
84
  abortSignal,
85
85
  commitIntentFn,
86
86
  executeIntentFn,
87
+ sequenceProjectAccessKey,
88
+ sequenceIndexerUrl,
87
89
  } = options
88
90
  let { sourceTokenPriceUsd, destinationTokenPriceUsd } = options
89
91
 
92
+ // Use slippage from options, or get from localStorage with config default fallback
93
+ // The config default (slippageToleranceFromOptions) comes from React component context
94
+ const slippageTolerance = getSlippageToleranceValue(
95
+ slippageToleranceFromOptions || "0.01",
96
+ )
97
+
90
98
  if (!sourceTokenDecimals) {
91
99
  throw new Error("Source token decimals not provided")
92
100
  }
@@ -312,6 +320,10 @@ export async function prepareSend(
312
320
  }
313
321
 
314
322
  onTransactionStateChange(transactionStates)
323
+ // Also trigger checkout status update if handler is provided
324
+ if (checkoutOnHandlers?.triggerCheckoutStatusUpdate) {
325
+ checkoutOnHandlers.triggerCheckoutStatusUpdate(transactionStates)
326
+ }
315
327
 
316
328
  // Call onCheckoutStart callback if provided
317
329
  if (checkoutOnHandlers?.triggerCheckoutStart) {
@@ -413,6 +425,8 @@ export async function prepareSend(
413
425
  abortSignal,
414
426
  commitIntentFn,
415
427
  executeIntentFn,
428
+ sequenceProjectAccessKey,
429
+ sequenceIndexerUrl,
416
430
  })
417
431
  }
418
432
 
@@ -12,7 +12,6 @@ import {
12
12
  toHex,
13
13
  type WalletClient,
14
14
  } from "viem"
15
- import { getSequenceProjectAccessKey } from "./config.js"
16
15
  import { logger } from "./logger.js"
17
16
 
18
17
  export type FlatTransaction = {
@@ -221,7 +220,7 @@ export async function sequenceSendTransaction(
221
220
  publicClient: PublicClient,
222
221
  calls: any[],
223
222
  chain: Chain,
224
- sequenceProjectAccessKey: string = getSequenceProjectAccessKey(),
223
+ sequenceProjectAccessKey: string,
225
224
  ): Promise<string | null> {
226
225
  const chainId = chain.id
227
226
  if (!accountClient?.account?.address || !sequenceWalletAddress) {
@@ -1,10 +1,9 @@
1
- import { useConfig } from "@0xsequence/hooks"
2
1
  import { TrailsApi } from "@0xsequence/trails-api"
3
2
  import { useMemo } from "react"
4
- import { getTrailsApiUrl, getSequenceProjectAccessKey } from "./config.js"
3
+ import { useTrails } from "./widget/providers/TrailsProvider.js"
5
4
 
6
5
  export type TrailsClientConfig = {
7
- apiKey?: string
6
+ apiKey: string
8
7
  jwt?: string
9
8
  hostname?: string
10
9
  }
@@ -12,24 +11,30 @@ export type TrailsClientConfig = {
12
11
  export class TrailsClient extends TrailsApi {}
13
12
 
14
13
  export function getTrailsClient({
15
- apiKey = getSequenceProjectAccessKey(),
14
+ apiKey,
16
15
  jwt,
17
16
  hostname,
18
- }: TrailsClientConfig = {}): TrailsClient {
17
+ }: TrailsClientConfig): TrailsClient {
19
18
  return new TrailsApi(apiKey, { jwt, hostname })
20
19
  }
21
20
 
22
- export const useTrailsClient = (config?: TrailsClientConfig) => {
23
- const { projectAccessKey, jwt } = useConfig()
21
+ export const useTrailsClient = (
22
+ configOverride?: Partial<TrailsClientConfig>,
23
+ ) => {
24
+ const trailsConfig = useTrails()
24
25
 
25
26
  const trailsClient = useMemo(() => {
26
27
  return getTrailsClient({
27
- hostname: config?.hostname || getTrailsApiUrl(),
28
- apiKey:
29
- config?.apiKey || getSequenceProjectAccessKey() || projectAccessKey,
30
- jwt: config?.jwt || jwt,
28
+ apiKey: configOverride?.apiKey || trailsConfig.trailsApiKey,
29
+ hostname: configOverride?.hostname || trailsConfig.trailsApiUrl,
30
+ jwt: configOverride?.jwt,
31
31
  })
32
- }, [config?.hostname, config?.apiKey, config?.jwt, projectAccessKey, jwt])
32
+ }, [
33
+ configOverride?.hostname,
34
+ configOverride?.apiKey,
35
+ configOverride?.jwt,
36
+ trailsConfig,
37
+ ])
33
38
 
34
39
  return trailsClient
35
40
  }
@@ -31,6 +31,7 @@ import {
31
31
  signIntent,
32
32
  getPermitSignature,
33
33
  } from "../../gasless.js"
34
+ import { getIsUserRejectionError } from "../../error.js"
34
35
 
35
36
  export async function attemptGaslessDeposit({
36
37
  paymasterUrl,
@@ -154,18 +155,29 @@ export async function attemptGaslessDeposit({
154
155
  checkoutOnHandlers.triggerCheckoutSignatureRequest()
155
156
  }
156
157
 
157
- const txHash = await sendPaymasterGaslessTransaction({
158
- walletClient,
159
- publicClient,
160
- chain,
161
- paymasterUrl,
162
- delegatorSmartAccount,
163
- calls,
164
- })
165
-
166
- // Trigger signature confirmed callback after successful signing
167
- if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
168
- checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
158
+ let txHash: any
159
+ try {
160
+ txHash = await sendPaymasterGaslessTransaction({
161
+ walletClient,
162
+ publicClient,
163
+ chain,
164
+ paymasterUrl,
165
+ delegatorSmartAccount,
166
+ calls,
167
+ })
168
+
169
+ // Trigger signature confirmed callback after successful signing
170
+ if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
171
+ checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
172
+ }
173
+ } catch (error) {
174
+ // Check if this is a user rejection error
175
+ if (getIsUserRejectionError(error)) {
176
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
177
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
178
+ }
179
+ }
180
+ throw error
169
181
  }
170
182
 
171
183
  if (onOriginSend) {
@@ -324,18 +336,39 @@ export async function attemptGaslessDeposit({
324
336
  },
325
337
  )
326
338
 
327
- const permitSig = await getPermitSignature({
328
- publicClient,
329
- walletClient,
330
- signer: account.address,
331
- spender: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
332
- tokenAddress: depositTokenAddress as `0x${string}`,
333
- amount: permitAmount, // Infinite approval
334
- chain,
335
- deadline: BigInt(deadline),
336
- })
337
- permitSignature = permitSig.signature
338
- permitDeadline = Number(permitSig.deadline)
339
+ // Trigger signature request callback before prompting wallet for permit
340
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRequest) {
341
+ checkoutOnHandlers.triggerCheckoutSignatureRequest()
342
+ }
343
+
344
+ let permitSig
345
+ try {
346
+ permitSig = await getPermitSignature({
347
+ publicClient,
348
+ walletClient,
349
+ signer: account.address,
350
+ spender: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
351
+ tokenAddress: depositTokenAddress as `0x${string}`,
352
+ amount: permitAmount, // Infinite approval
353
+ chain,
354
+ deadline: BigInt(deadline),
355
+ })
356
+ permitSignature = permitSig.signature
357
+ permitDeadline = Number(permitSig.deadline)
358
+
359
+ // Trigger signature confirmed callback after successful signing
360
+ if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
361
+ checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
362
+ }
363
+ } catch (error) {
364
+ // Check if this is a user rejection error
365
+ if (getIsUserRejectionError(error)) {
366
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
367
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
368
+ }
369
+ }
370
+ throw error
371
+ }
339
372
  logger.console.log(
340
373
  "[trails-sdk] Deposit token permit signature obtained for infinite approval",
341
374
  )
@@ -375,26 +408,38 @@ export async function attemptGaslessDeposit({
375
408
  checkoutOnHandlers.triggerCheckoutSignatureRequest()
376
409
  }
377
410
 
378
- const { signature: intentSignature } = await signIntent({
379
- client: walletClient,
380
- intentParams: {
381
- user: account.address,
382
- token: depositTokenAddress as `0x${string}`,
383
- amount: BigInt(depositTokenAmount),
384
- intentAddress: depositRecipient as `0x${string}`,
385
- deadline: BigInt(deadline),
386
- chainId: originChainId,
387
- contractAddress: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
388
- nonce,
389
- feeAmount: BigInt(selectedFeeOption?.amount || "0"),
390
- feeCollector: feeCollectorAddress,
391
- },
392
- })
393
- logger.console.log("[trails-sdk] Intent signature received")
411
+ let intentSignature: string
412
+ try {
413
+ const result = await signIntent({
414
+ client: walletClient,
415
+ intentParams: {
416
+ user: account.address,
417
+ token: depositTokenAddress as `0x${string}`,
418
+ amount: BigInt(depositTokenAmount),
419
+ intentAddress: depositRecipient as `0x${string}`,
420
+ deadline: BigInt(deadline),
421
+ chainId: originChainId,
422
+ contractAddress: TRAILS_INTENT_ENTRYPOINT_ADDRESS,
423
+ nonce,
424
+ feeAmount: BigInt(selectedFeeOption?.amount || "0"),
425
+ feeCollector: feeCollectorAddress,
426
+ },
427
+ })
428
+ intentSignature = result.signature
429
+ logger.console.log("[trails-sdk] Intent signature received")
394
430
 
395
- // Trigger signature confirmed callback after successful signing
396
- if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
397
- checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
431
+ // Trigger signature confirmed callback after successful signing
432
+ if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
433
+ checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
434
+ }
435
+ } catch (error) {
436
+ // Check if this is a user rejection error
437
+ if (getIsUserRejectionError(error)) {
438
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
439
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
440
+ }
441
+ }
442
+ throw error
398
443
  }
399
444
 
400
445
  // 5. Call the deposit endpoint with permit support and optional fee
@@ -23,6 +23,7 @@ import { updatePersistentToast } from "../../toast.js"
23
23
  import { getChainInfo } from "../../chains.js"
24
24
  import { trackTransactionConfirmed } from "../../analytics.js"
25
25
  import { zeroAddress } from "viem"
26
+ import { getIsUserRejectionError } from "../../error.js"
26
27
 
27
28
  export async function attemptStandardDeposit({
28
29
  originTokenAddress,
@@ -77,6 +78,7 @@ export async function attemptStandardDeposit({
77
78
  recipient?: string
78
79
  destinationCalldata?: string
79
80
  }): Promise<TransactionReceipt | null> {
81
+ console.log("IN ATTEMPT STANDARD DEPOSIT!")
80
82
  let depositUserTxnReceipt: TransactionReceipt | null = null
81
83
  const usingLIfi = false
82
84
  let needsNativeFee = false
@@ -176,24 +178,36 @@ export async function attemptStandardDeposit({
176
178
  args: [recipient as `0x${string}`, requiredAmount],
177
179
  }) as `0x${string}`
178
180
 
179
- const approveHash = await sendOriginTransaction(
180
- account,
181
- walletClient,
182
- {
183
- to: originTokenAddress as `0x${string}`,
184
- data: approveData,
185
- value: 0n,
186
- chain,
187
- },
188
- {
189
- transactionType: "token_approve",
190
- depositTokenAmountUsd: depositAmountUsd?.toString(),
191
- },
192
- )
181
+ let approveHash: `0x${string}`
182
+ let approveReceipt: TransactionReceipt
183
+ try {
184
+ approveHash = await sendOriginTransaction(
185
+ account,
186
+ walletClient,
187
+ {
188
+ to: originTokenAddress as `0x${string}`,
189
+ data: approveData,
190
+ value: 0n,
191
+ chain,
192
+ },
193
+ {
194
+ transactionType: "token_approve",
195
+ depositTokenAmountUsd: depositAmountUsd?.toString(),
196
+ },
197
+ )
193
198
 
194
- const approveReceipt = await publicClient.waitForTransactionReceipt({
195
- hash: approveHash,
196
- })
199
+ approveReceipt = await publicClient.waitForTransactionReceipt({
200
+ hash: approveHash,
201
+ })
202
+ } catch (error) {
203
+ // Check if this is a user rejection error
204
+ if (getIsUserRejectionError(error)) {
205
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
206
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
207
+ }
208
+ }
209
+ throw error
210
+ }
197
211
 
198
212
  logger.console.log(
199
213
  "[trails-sdk] Approve transaction confirmed:",
@@ -397,31 +411,44 @@ export async function attemptStandardDeposit({
397
411
  checkoutOnHandlers.triggerCheckoutSignatureRequest()
398
412
  }
399
413
 
400
- const txHashNativeFee = await sendOriginTransaction(
401
- account,
402
- walletClient,
403
- {
404
- to: originIntentAddress,
405
- data: "0x00",
406
- value: nativeFee,
407
- chainId: originChainId,
408
- chain,
409
- } as any,
410
- {
411
- depositTokenAmountUsd: depositAmountUsd?.toString(),
412
- },
413
- ) // TODO: Add proper type
414
- logger.console.log("[trails-sdk] origin tx native fee", txHashNativeFee)
414
+ try {
415
+ const txHashNativeFee = await sendOriginTransaction(
416
+ account,
417
+ walletClient,
418
+ {
419
+ to: originIntentAddress,
420
+ data: "0x00",
421
+ value: nativeFee,
422
+ chainId: originChainId,
423
+ chain,
424
+ } as any,
425
+ {
426
+ depositTokenAmountUsd: depositAmountUsd?.toString(),
427
+ },
428
+ ) // TODO: Add proper type
429
+ logger.console.log(
430
+ "[trails-sdk] origin tx native fee",
431
+ txHashNativeFee,
432
+ )
415
433
 
416
- // Trigger signature confirmed callback after successful signing
417
- if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
418
- checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
434
+ // Trigger signature confirmed callback after successful signing
435
+ if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
436
+ checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
437
+ }
438
+ // Wait for transaction receipt
439
+ const feeReceipt = await publicClient.waitForTransactionReceipt({
440
+ hash: txHashNativeFee,
441
+ })
442
+ logger.console.log("[trails-sdk] nativeFeeReceipt", feeReceipt)
443
+ } catch (error) {
444
+ // Check if this is a user rejection error
445
+ if (getIsUserRejectionError(error)) {
446
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
447
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
448
+ }
449
+ }
450
+ throw error
419
451
  }
420
- // Wait for transaction receipt
421
- const feeReceipt = await publicClient.waitForTransactionReceipt({
422
- hash: txHashNativeFee,
423
- })
424
- logger.console.log("[trails-sdk] nativeFeeReceipt", feeReceipt)
425
452
  }
426
453
 
427
454
  // Show persistent toast for checkout flow
@@ -436,19 +463,30 @@ export async function attemptStandardDeposit({
436
463
  checkoutOnHandlers.triggerCheckoutSignatureRequest()
437
464
  }
438
465
 
439
- const txHash = await sendOriginTransaction(
440
- account,
441
- walletClient,
442
- originCallParams as any,
443
- {
444
- depositTokenAmountUsd: depositAmountUsd?.toString(),
445
- },
446
- ) // TODO: Add proper type
447
- logger.console.log("[trails-sdk] origin tx", txHash)
448
-
449
- // Trigger signature confirmed callback after successful signing
450
- if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
451
- checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
466
+ let txHash: `0x${string}`
467
+ try {
468
+ txHash = await sendOriginTransaction(
469
+ account,
470
+ walletClient,
471
+ originCallParams as any,
472
+ {
473
+ depositTokenAmountUsd: depositAmountUsd?.toString(),
474
+ },
475
+ ) // TODO: Add proper type
476
+ logger.console.log("[trails-sdk] origin tx", txHash)
477
+
478
+ // Trigger signature confirmed callback after successful signing
479
+ if (checkoutOnHandlers?.triggerCheckoutSignatureConfirmed) {
480
+ checkoutOnHandlers.triggerCheckoutSignatureConfirmed()
481
+ }
482
+ } catch (error) {
483
+ // Check if this is a user rejection error
484
+ if (getIsUserRejectionError(error)) {
485
+ if (checkoutOnHandlers?.triggerCheckoutSignatureRejected) {
486
+ checkoutOnHandlers.triggerCheckoutSignatureRejected(error)
487
+ }
488
+ }
489
+ throw error
452
490
  }
453
491
 
454
492
  if (onOriginSend) {