0xtrails 0.12.2 → 0.12.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"MeldStepsFlow.d.ts","sourceRoot":"","sources":["../../../src/widget/components/MeldStepsFlow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAwJD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAg6CtD,CAAA"}
1
+ {"version":3,"file":"MeldStepsFlow.d.ts","sourceRoot":"","sources":["../../../src/widget/components/MeldStepsFlow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAwJD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA85CtD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"QuoteDetails.d.ts","sourceRoot":"","sources":["../../../src/widget/components/QuoteDetails.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAK5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAW7D,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,WAAW,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,+DAA+D;IAC/D,qBAAqB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC1C,4DAA4D;IAC5D,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,OAAO,GAAG,SAAS,CAAA;CAC/D;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAunCpD,CAAA;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"QuoteDetails.d.ts","sourceRoot":"","sources":["../../../src/widget/components/QuoteDetails.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAK5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAW7D,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,WAAW,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,+DAA+D;IAC/D,qBAAqB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC1C,4DAA4D;IAC5D,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,OAAO,GAAG,SAAS,CAAA;CAC/D;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAynCpD,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"TransferPendingVertical.d.ts","sourceRoot":"","sources":["../../../src/widget/components/TransferPendingVertical.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAI7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AA4F7D,UAAU,oBAAoB;IAC5B,aAAa,EAAE,CAAC,sBAAsB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxD,iBAAiB,EAAE,gBAAgB,EAAE,CAAA;IACrC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;CACjC;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAid1D,CAAA;AAED,eAAe,eAAe,CAAA"}
1
+ {"version":3,"file":"TransferPendingVertical.d.ts","sourceRoot":"","sources":["../../../src/widget/components/TransferPendingVertical.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAI7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AA8F7D,UAAU,oBAAoB;IAC5B,aAAa,EAAE,CAAC,sBAAsB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACxD,iBAAiB,EAAE,gBAAgB,EAAE,CAAA;IACrC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;CACjC;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAsd1D,CAAA;AAED,eAAe,eAAe,CAAA"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { v as r, w as l, y as o, z as e, J as i, a as d, b as T } from "../index-C0QTNYIA.js";
2
+ import { v as r, w as l, y as o, z as e, J as i, a as d, b as T } from "../index-DnW6yCTQ.js";
3
3
  export {
4
4
  r as TrailsHookModal,
5
5
  l as TrailsModalProvider,
@@ -1 +1 @@
1
- {"version":3,"file":"forexRateStore.d.ts","sourceRoot":"","sources":["../../../src/widget/utils/forexRateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,cAAM,cAAc;IAElB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO;IAKP,MAAM,CAAC,WAAW,IAAI,cAAc;IAQpC,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAmBtC,OAAO,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiBpD,SAAS;IAWT;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAOjD;AAED,eAAO,MAAM,cAAc,gBAA+B,CAAA"}
1
+ {"version":3,"file":"forexRateStore.d.ts","sourceRoot":"","sources":["../../../src/widget/utils/forexRateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAgB;IACvC,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO;IAKP,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAmBtC,OAAO,IAAI;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiBpD,SAAS;IAWT;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAOjD;AAED,eAAO,MAAM,cAAc,gBAA+B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"localeStore.d.ts","sourceRoot":"","sources":["../../../src/widget/utils/localeStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAM,WAAW;IAEf,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAa;IACpC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAkD;IAEnE,OAAO;IAeP,MAAM,CAAC,WAAW,IAAI,WAAW;IAOjC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,kBAAkB,IAAI,MAAM;IAa5B,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;IAOnD,OAAO,CAAC,eAAe;CAKxB;AAED,eAAO,MAAM,WAAW,aAA4B,CAAA"}
1
+ {"version":3,"file":"localeStore.d.ts","sourceRoot":"","sources":["../../../src/widget/utils/localeStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAa;IACpC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAkD;IAEnE,OAAO;IAeP,MAAM,CAAC,WAAW,IAAI,WAAW;IAOjC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,kBAAkB,IAAI,MAAM;IAa5B,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI;IAOnD,OAAO,CAAC,eAAe;CAKxB;AAED,eAAO,MAAM,WAAW,aAA4B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"intentExecutionWorker.d.ts","sourceRoot":"","sources":["../../../src/widget/workers/intentExecutionWorker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAezD,UAAU,4BAA4B;IACpC,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAGD,qBAAa,qBAAqB;IAEhC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAA+B;IAEtD,OAAO;IAOP;;OAEG;IACH,MAAM,CAAC,WAAW,CAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB;IAqBxB;;OAEG;IAEH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,MAAM,CAAC,eAAe,IAAI,IAAI;IAU9B;;OAEG;IACH,KAAK,IAAI,IAAI;IA4Bb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;YACW,mBAAmB;IAkCjC;;OAEG;YACW,aAAa;IA0I3B;;;OAGG;IACH,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqEvD;;OAEG;IAEH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAgBrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,MAAM,CAAC,qBAAqB,IAAI,IAAI;CAarC"}
1
+ {"version":3,"file":"intentExecutionWorker.d.ts","sourceRoot":"","sources":["../../../src/widget/workers/intentExecutionWorker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAezD,UAAU,4BAA4B;IACpC,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAGD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAA+B;IAEtD,OAAO;IAOP;;OAEG;IACH,MAAM,CAAC,WAAW,CAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB;IAqBxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,MAAM,CAAC,eAAe,IAAI,IAAI;IAU9B;;OAEG;IACH,KAAK,IAAI,IAAI;IA4Bb;;OAEG;IACH,IAAI,IAAI,IAAI;IAiBZ;;OAEG;YACW,mBAAmB;IAkCjC;;OAEG;YACW,aAAa;IA0I3B;;;OAGG;IACH,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqEvD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAgBrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,MAAM,CAAC,qBAAqB,IAAI,IAAI;CAarC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0xtrails",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "SDK for Trails",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -260,6 +260,33 @@ export async function pollIntentReceipt(
260
260
  }
261
261
  }
262
262
 
263
+ // Defensive fallback for backend lag/inconsistency:
264
+ // if receipt status has not flipped to terminal yet, but destination
265
+ // transaction is already succeeded and we have a finished marker, treat
266
+ // the flow as complete to avoid indefinite pending UI.
267
+ const summary = (
268
+ receipt as unknown as { summary?: { finishedAt?: string | null } }
269
+ ).summary
270
+ const hasFinishedMarker = Boolean(
271
+ summary?.finishedAt ||
272
+ receipt.destinationTransaction?.txnMinedAt ||
273
+ receipt.destinationTransaction?.txnHash,
274
+ )
275
+ const destinationSucceeded =
276
+ receipt.destinationTransaction?.status === "SUCCEEDED"
277
+ if (destinationSucceeded && hasFinishedMarker) {
278
+ logger.console.warn(
279
+ "[trails-sdk] Treating receipt as complete via destination-success fallback",
280
+ {
281
+ intentId,
282
+ status: receipt.status,
283
+ destinationTxHash: receipt.destinationTransaction?.txnHash,
284
+ hasFinishedMarker,
285
+ },
286
+ )
287
+ return receipt
288
+ }
289
+
263
290
  // If intent is done, stop polling
264
291
  if (response.done) {
265
292
  logger.console.log("[trails-sdk] Intent receipt polling complete", {
package/src/recover.ts CHANGED
@@ -1067,8 +1067,6 @@ export function useIntentRecover({
1067
1067
  refundToAddress: refundToAddress || walletAddress,
1068
1068
  })
1069
1069
 
1070
- // TODO: temporary ignore this Biome warning for now; do not refactor code in this pass.
1071
- // biome-ignore lint/correctness/useExhaustiveDependencies: Preserve current dependency shape per requested no-code-change rollback.
1072
1070
  const signPayload = useCallback(async (): Promise<{
1073
1071
  signature: string
1074
1072
  payload: Payload.Calls
@@ -1099,10 +1097,8 @@ export function useIntentRecover({
1099
1097
  )
1100
1098
 
1101
1099
  return { signature, payload, refundCall }
1102
- }, [walletClient, inner.getDataToSign])
1100
+ }, [walletClient, inner])
1103
1101
 
1104
- // TODO: temporary ignore this Biome warning for now; do not refactor code in this pass.
1105
- // biome-ignore lint/correctness/useExhaustiveDependencies: Preserve current dependency shape per requested no-code-change rollback.
1106
1102
  const getRecoverTx = useCallback(
1107
1103
  async (params: {
1108
1104
  signedHash: string
@@ -1117,7 +1113,7 @@ export function useIntentRecover({
1117
1113
  signature: params.signedHash,
1118
1114
  payload: params.payload,
1119
1115
  }),
1120
- [inner.getRecoverTx],
1116
+ [inner],
1121
1117
  )
1122
1118
 
1123
1119
  const recover = useCallback(async (): Promise<{
@@ -683,6 +683,7 @@ async function executeIntent(
683
683
  }
684
684
  // Start polling for intent completion to update transaction states
685
685
  let finalReceipt: Awaited<ReturnType<typeof pollIntentReceipt>> = null
686
+ let pollStartMs = 0
686
687
  if (intent.intentId) {
687
688
  // Determine max wait time based on route provider.
688
689
  // OFT routes (LayerZero OFT) can take 5-10+ minutes to complete.
@@ -695,6 +696,7 @@ async function executeIntent(
695
696
  routeProviders: intent.quote?.routeProviders,
696
697
  })
697
698
  try {
699
+ pollStartMs = Date.now()
698
700
  finalReceipt = await pollIntentReceipt({
699
701
  intentId: intent.intentId,
700
702
  trailsClient,
@@ -931,22 +933,43 @@ async function executeIntent(
931
933
  IntentStatus.REFUNDED,
932
934
  IntentStatus.ABORTED,
933
935
  ]
936
+ const summary = (
937
+ finalReceipt as unknown as { summary?: { finishedAt?: string | null } }
938
+ )?.summary
939
+ const hasFinishedMarker = Boolean(
940
+ summary?.finishedAt ||
941
+ finalReceipt?.destinationTransaction?.txnMinedAt ||
942
+ finalReceipt?.destinationTransaction?.txnHash,
943
+ )
944
+ const destinationSucceeded =
945
+ finalReceipt?.destinationTransaction?.status === "SUCCEEDED"
946
+ const completeViaDestinationFallback =
947
+ !!finalReceipt && destinationSucceeded && hasFinishedMarker
934
948
  const isComplete =
935
- finalReceipt && terminalStatuses.includes(finalReceipt.status)
949
+ !!finalReceipt &&
950
+ (terminalStatuses.includes(finalReceipt.status) ||
951
+ completeViaDestinationFallback)
936
952
 
937
953
  if (!isComplete) {
938
- // Intent still executing after timeout - don't report success
954
+ const elapsedMs = pollStartMs > 0 ? Date.now() - pollStartMs : 0
955
+ const timedOut = elapsedMs >= maxWaitTime
956
+ const reason = timedOut
957
+ ? `Intent execution timed out after ${Math.round(maxWaitTime / 60000)} minutes.`
958
+ : "Unable to confirm final intent status from receipt polling."
959
+
939
960
  logger.console.warn(
940
- "[trails-sdk] Intent polling timed out before reaching terminal status",
961
+ "[trails-sdk] Intent polling ended without terminal status",
941
962
  {
942
963
  intentId: intent.intentId,
943
964
  status: finalReceipt?.status,
944
965
  maxWaitTime,
966
+ elapsedMs,
967
+ timedOut,
945
968
  },
946
969
  )
947
970
 
948
971
  trackPaymentError({
949
- error: `Transaction still in progress after ${Math.round(maxWaitTime / 60000)} minutes - please check transaction history`,
972
+ error: `${reason} Please check transaction history or query GetIntentReceipt.`,
950
973
  userAddress: account.address,
951
974
  mode,
952
975
  fundMethod,
@@ -957,12 +980,12 @@ async function executeIntent(
957
980
 
958
981
  if (checkoutOnHandlers?.triggerCheckoutError) {
959
982
  checkoutOnHandlers.triggerCheckoutError(
960
- "Transaction still in progress - please check your transaction history for the final status",
983
+ "Unable to confirm final transaction status",
961
984
  )
962
985
  }
963
986
 
964
987
  throw new Error(
965
- `Intent execution timed out after ${Math.round(maxWaitTime / 60000)} minutes - transaction still in progress. Please check your transaction history for the final status.`,
988
+ `${reason} Please check transaction history or query GetIntentReceipt with this intent ID.`,
966
989
  )
967
990
  }
968
991
  } catch (error) {
@@ -247,8 +247,6 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
247
247
  }>({ status: "", message: "", type: null })
248
248
 
249
249
  // Check for transaction status from URL parameters (when user returns from Meld)
250
- // TODO: temporary ignore this Biome warning for now; do not refactor code in this pass.
251
- // biome-ignore lint/correctness/useExhaustiveDependencies: Preserve current dependency shape per requested no-code-change rollback.
252
250
  useEffect(() => {
253
251
  const urlParams = new URLSearchParams(window.location.search)
254
252
 
@@ -686,7 +684,7 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
686
684
  "[MeldStepsFlow] No transaction ID found in URL parameters",
687
685
  )
688
686
  }
689
- }, [trailsClient.searchMeldTransactions])
687
+ }, [trailsClient])
690
688
 
691
689
  // Function to check transaction status
692
690
  const checkTransactionStatus = useCallback(
@@ -1,7 +1,7 @@
1
1
  import type React from "react"
2
2
  import { TokenImage } from "./TokenImage.js"
3
3
  import type { PrepareSendQuote } from "../../prepareSend.js"
4
- import { timeAgo } from "../../utils/time.js"
4
+ import { formatDuration, timeAgo } from "../../utils/time.js"
5
5
 
6
6
  interface OriginTransferInformationProps {
7
7
  quote: PrepareSendQuote
@@ -37,7 +37,7 @@ export const OriginTransferInformation: React.FC<
37
37
  className="ml-1 font-mono animate-pulse text-gray-500 dark:text-gray-400"
38
38
  title="Elapsed time"
39
39
  >
40
- {elapsedSeconds}s
40
+ {formatDuration(elapsedSeconds)}
41
41
  </span>
42
42
  </span>
43
43
  </div>
@@ -77,9 +77,11 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
77
77
  ? onRampQuote?.totalFee / (fiatToUsdExchangeRate ?? 1)
78
78
  : 0
79
79
 
80
- logger.console.log("[trails-sdk] OnRamp Quote", {
81
- onRampQuote,
82
- })
80
+ if (onRampQuote) {
81
+ logger.console.log("[trails-sdk] OnRamp Quote", {
82
+ onRampQuote,
83
+ })
84
+ }
83
85
 
84
86
  // Sync with initialExpanded prop changes
85
87
  useEffect(() => {
@@ -28,6 +28,8 @@ const isOFTRoute = (routeProviders?: { id: string }[]): boolean => {
28
28
  // Timeout constants
29
29
  const OFT_TIMEOUT_MS = 60 * MINUTE_MS // 1 hour for OFT routes
30
30
  const DEFAULT_TIMEOUT_MS = MINUTE_MS // 1 minute for normal routes
31
+ const MAINNET_TIMEOUT_MS = 2 * MINUTE_MS // 2 minutes for Ethereum mainnet routes
32
+ const ETHEREUM_MAINNET_CHAIN_ID = 1
31
33
 
32
34
  // Checkmark icon for completed steps
33
35
  const CheckmarkIcon = () => (
@@ -127,20 +129,25 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
127
129
  null,
128
130
  )
129
131
  const isOFT = isOFTRoute(quote?.routeProviders)
132
+ const isMainnetOrigin = quote?.originChain?.id === ETHEREUM_MAINNET_CHAIN_ID
130
133
 
131
134
  const showContinueButton =
132
135
  hasAnyFailedOrAbortedTransactions(transactionStates) && onContinue
133
136
 
134
137
  // Timeout warning: OFT routes can take significantly longer than standard routes.
135
138
  useEffect(() => {
136
- const timeoutMs = isOFT ? OFT_TIMEOUT_MS : DEFAULT_TIMEOUT_MS
139
+ const timeoutMs = isOFT
140
+ ? OFT_TIMEOUT_MS
141
+ : isMainnetOrigin
142
+ ? MAINNET_TIMEOUT_MS
143
+ : DEFAULT_TIMEOUT_MS
137
144
 
138
145
  const timeoutTimer = setTimeout(() => {
139
146
  setShowTimeoutWarning(true)
140
147
  }, timeoutMs)
141
148
 
142
149
  return () => clearTimeout(timeoutTimer)
143
- }, [isOFT])
150
+ }, [isOFT, isMainnetOrigin])
144
151
  useEffect(() => {
145
152
  const depositConfirmed = transactionStates?.[0]?.state === "confirmed"
146
153
 
@@ -22,7 +22,6 @@ const canUseLocalStorage = () =>
22
22
  typeof localStorage.removeItem === "function"
23
23
 
24
24
  class ForexRateStore {
25
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance()
26
25
  private static instance: ForexRateStore
27
26
  private currentRate: ForexRateData | null = null
28
27
 
@@ -38,7 +37,6 @@ class ForexRateStore {
38
37
  return ForexRateStore.instance
39
38
  }
40
39
 
41
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called in constructor
42
40
  private loadFromStorage() {
43
41
  try {
44
42
  if (canUseLocalStorage()) {
@@ -3,7 +3,6 @@
3
3
  * This is used by utility functions that need locale information but can't use React hooks
4
4
  */
5
5
  class LocaleStore {
6
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance()
7
6
  private static instance: LocaleStore
8
7
  private locale: string | null = null
9
8
  private listeners: Set<(locale: string | null) => void> = new Set()
@@ -875,19 +875,19 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
875
875
 
876
876
  // Keep screen and wallet-connection state in sync without bouncing between screens
877
877
  useEffect(() => {
878
- const connectionExemptScreens = [
878
+ const disconnectedAllowedScreens = [
879
879
  "connect",
880
880
  "wallet-connect",
881
881
  "wallet-connection-pending",
882
882
  "wallet-list",
883
883
  ]
884
884
 
885
- if (!isConnected && !connectionExemptScreens.includes(currentScreen)) {
885
+ if (!isConnected && !disconnectedAllowedScreens.includes(currentScreen)) {
886
886
  setCurrentScreen("connect")
887
887
  return
888
888
  }
889
889
 
890
- if (isConnected && connectionExemptScreens.includes(currentScreen)) {
890
+ if (isConnected && currentScreen === "connect") {
891
891
  setCurrentScreen(getInitialScreenForMode(currentMode))
892
892
  }
893
893
  }, [
@@ -25,7 +25,6 @@ interface IntentExecutionWorkerOptions {
25
25
 
26
26
  // @preserve - Prevent tree-shaking of this class
27
27
  export class IntentExecutionWorker {
28
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance() and storeIntentForMonitoring()
29
28
  private static instance: IntentExecutionWorker | null = null
30
29
  private intervalId: NodeJS.Timeout | null = null
31
30
  private isRunning = false
@@ -71,7 +70,6 @@ export class IntentExecutionWorker {
71
70
  /**
72
71
  * Update the worker options (used when re-initializing with new config)
73
72
  */
74
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance() method when updating existing instance
75
73
  private updateOptions(options: IntentExecutionWorkerOptions): void {
76
74
  const wasRunning = this.isRunning
77
75
 
@@ -410,7 +408,6 @@ export class IntentExecutionWorker {
410
408
  /**
411
409
  * Get stored intents (static version for external use)
412
410
  */
413
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in storeIntentForMonitoring() and getStoredIntents() methods
414
411
  private static getStoredIntentsStatic(): StoredIntent[] {
415
412
  try {
416
413
  const stored = localStorage.getItem(INTENT_STORAGE_KEY)