@pushchain/core 5.1.5-alpha.0 → 5.1.5-alpha.1
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/package.json +1 -1
- package/src/lib/orchestrator/internals/cascade.js +52 -3
- package/src/lib/orchestrator/internals/response-builder.js +24 -1
- package/src/lib/orchestrator/orchestrator.types.d.ts +11 -2
- package/src/lib/progress-hook/progress-hook.js +40 -0
- package/src/lib/progress-hook/progress-hook.types.d.ts +5 -0
- package/src/lib/progress-hook/progress-hook.types.js +6 -0
package/package.json
CHANGED
|
@@ -28,6 +28,8 @@ const uea_manager_1 = require("./uea-manager");
|
|
|
28
28
|
const gas_calculator_1 = require("./gas-calculator");
|
|
29
29
|
const route_handlers_1 = require("./route-handlers");
|
|
30
30
|
const build_payload_1 = require("../svm-idl/build-payload");
|
|
31
|
+
const progress_hook_types_1 = require("../../progress-hook/progress-hook.types");
|
|
32
|
+
const progress_hook_1 = tslib_1.__importDefault(require("../../progress-hook/progress-hook"));
|
|
31
33
|
// ============================================================================
|
|
32
34
|
// prepareTransaction
|
|
33
35
|
// ============================================================================
|
|
@@ -775,8 +777,8 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
775
777
|
hops: hopInfos,
|
|
776
778
|
hopCount: hops.length,
|
|
777
779
|
waitForAll: (opts) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
778
|
-
var _a;
|
|
779
|
-
const { pollingIntervalMs = 10000, timeout = 300000, progressHook: cascadeProgressHook, } = opts || {};
|
|
780
|
+
var _a, _b;
|
|
781
|
+
const { pollingIntervalMs = 10000, timeout = 300000, progressHook: cascadeProgressHook, eventHook, } = opts || {};
|
|
780
782
|
const startTime = Date.now();
|
|
781
783
|
try {
|
|
782
784
|
// 1. Wait for initial Push Chain tx confirmation
|
|
@@ -841,12 +843,14 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
841
843
|
status: 'timeout',
|
|
842
844
|
elapsed: Date.now() - startTime,
|
|
843
845
|
});
|
|
846
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04](Date.now() - startTime));
|
|
844
847
|
return {
|
|
845
848
|
success: false,
|
|
846
849
|
hops: hopInfos,
|
|
847
850
|
failedAt: hop.hopIndex,
|
|
848
851
|
};
|
|
849
852
|
}
|
|
853
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01](hop.executionChain));
|
|
850
854
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
851
855
|
hopIndex: hop.hopIndex,
|
|
852
856
|
route: hop.route,
|
|
@@ -854,6 +858,7 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
854
858
|
status: 'polling',
|
|
855
859
|
elapsed: Date.now() - startTime,
|
|
856
860
|
});
|
|
861
|
+
let lastEmittedStatus;
|
|
857
862
|
try {
|
|
858
863
|
const outboundDetails = yield callbacks.waitForOutboundTxFn(response.hash, {
|
|
859
864
|
initialWaitMs: Math.min(60000, remainingTimeout),
|
|
@@ -867,11 +872,17 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
867
872
|
status: event.status,
|
|
868
873
|
elapsed: Date.now() - startTime,
|
|
869
874
|
});
|
|
875
|
+
if (event.status === 'polling' &&
|
|
876
|
+
lastEmittedStatus !== 'polling') {
|
|
877
|
+
lastEmittedStatus = 'polling';
|
|
878
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02](event.elapsed));
|
|
879
|
+
}
|
|
870
880
|
},
|
|
871
881
|
});
|
|
872
882
|
hop.status = 'confirmed';
|
|
873
883
|
hop.txHash = outboundDetails.externalTxHash;
|
|
874
884
|
hop.outboundDetails = outboundDetails;
|
|
885
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03](outboundDetails));
|
|
875
886
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
876
887
|
hopIndex: hop.hopIndex,
|
|
877
888
|
route: hop.route,
|
|
@@ -882,6 +893,11 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
882
893
|
});
|
|
883
894
|
}
|
|
884
895
|
catch (err) {
|
|
896
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
897
|
+
const isTimeout = errMsg.startsWith('Timeout waiting for outbound transaction');
|
|
898
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(isTimeout
|
|
899
|
+
? progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04](remainingTimeout)
|
|
900
|
+
: progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05](errMsg));
|
|
885
901
|
hop.status = 'failed';
|
|
886
902
|
cascadeProgressHook === null || cascadeProgressHook === void 0 ? void 0 : cascadeProgressHook({
|
|
887
903
|
hopIndex: hop.hopIndex,
|
|
@@ -899,6 +915,13 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
899
915
|
}
|
|
900
916
|
else {
|
|
901
917
|
// Multiple outbound hops: use V2 API which returns outboundTx[]
|
|
918
|
+
// Emit "Awaiting External Chain" once per outbound hop before
|
|
919
|
+
// polling begins.
|
|
920
|
+
for (const outHop of outboundHops) {
|
|
921
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01](outHop.executionChain));
|
|
922
|
+
}
|
|
923
|
+
const perHopLastStatus = new Map();
|
|
924
|
+
const confirmedHops = new Set();
|
|
902
925
|
const allOutboundDetails = yield callbacks.waitForAllOutboundTxsFn(response.hash, outboundHops, {
|
|
903
926
|
initialWaitMs: Math.min(60000, timeout - (Date.now() - startTime)),
|
|
904
927
|
pollingIntervalMs,
|
|
@@ -912,13 +935,39 @@ function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
|
912
935
|
txHash: event.txHash,
|
|
913
936
|
elapsed: Date.now() - startTime,
|
|
914
937
|
});
|
|
938
|
+
const prev = perHopLastStatus.get(event.hopIndex);
|
|
939
|
+
if (event.status === 'polling' &&
|
|
940
|
+
prev !== 'polling') {
|
|
941
|
+
perHopLastStatus.set(event.hopIndex, 'polling');
|
|
942
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02](Date.now() - startTime));
|
|
943
|
+
}
|
|
944
|
+
if (event.status === 'confirmed' &&
|
|
945
|
+
event.txHash &&
|
|
946
|
+
!confirmedHops.has(event.hopIndex)) {
|
|
947
|
+
// waitForAllOutboundTxsV2 populates hop.outboundDetails
|
|
948
|
+
// on the matched hop before emitting 'confirmed' (see
|
|
949
|
+
// outbound-sync.ts:348-355). Auto-promotion paths
|
|
950
|
+
// without a txHash are skipped by the `event.txHash`
|
|
951
|
+
// guard above, so we only reach here with full details.
|
|
952
|
+
const matchedHop = outboundHops.find((h) => h.hopIndex === event.hopIndex);
|
|
953
|
+
if (matchedHop === null || matchedHop === void 0 ? void 0 : matchedHop.outboundDetails) {
|
|
954
|
+
confirmedHops.add(event.hopIndex);
|
|
955
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03](matchedHop.outboundDetails));
|
|
956
|
+
}
|
|
957
|
+
}
|
|
915
958
|
},
|
|
916
959
|
});
|
|
917
960
|
if (!allOutboundDetails.success) {
|
|
961
|
+
const failedIdx = (_b = allOutboundDetails.failedAt) !== null && _b !== void 0 ? _b : 0;
|
|
962
|
+
const failedHop = outboundHops.find((h) => h.hopIndex === failedIdx);
|
|
963
|
+
const failMsg = failedHop
|
|
964
|
+
? `Outbound failed for hop ${failedIdx} on ${failedHop.executionChain}`
|
|
965
|
+
: `Outbound cascade failed at hop ${failedIdx}`;
|
|
966
|
+
eventHook === null || eventHook === void 0 ? void 0 : eventHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05](failMsg));
|
|
918
967
|
return {
|
|
919
968
|
success: false,
|
|
920
969
|
hops: hopInfos,
|
|
921
|
-
failedAt:
|
|
970
|
+
failedAt: failedIdx,
|
|
922
971
|
};
|
|
923
972
|
}
|
|
924
973
|
}
|
|
@@ -16,6 +16,8 @@ const viem_1 = require("viem");
|
|
|
16
16
|
const uea_evm_1 = require("../../constants/abi/uea.evm");
|
|
17
17
|
const chain_1 = require("../../constants/chain");
|
|
18
18
|
const enums_1 = require("../../constants/enums");
|
|
19
|
+
const progress_hook_types_1 = require("../../progress-hook/progress-hook.types");
|
|
20
|
+
const progress_hook_1 = tslib_1.__importDefault(require("../../progress-hook/progress-hook"));
|
|
19
21
|
const account_1 = require("../../universal/account/account");
|
|
20
22
|
const push_client_1 = require("../../push-client/push-client");
|
|
21
23
|
const route_detector_1 = require("../route-detector");
|
|
@@ -472,19 +474,40 @@ function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
|
472
474
|
? (0, route_detector_1.getRouteInfo)(universalTxResponse.route)
|
|
473
475
|
: undefined;
|
|
474
476
|
if (routeInfo === null || routeInfo === void 0 ? void 0 : routeInfo.isOutbound) {
|
|
477
|
+
// Response-level only — NOT routed through ctx.progressHook because
|
|
478
|
+
// the default ui-kit toast lacks icon/hide-timer handling for these
|
|
479
|
+
// events. A follow-up ui-kit PR will add handling and can route
|
|
480
|
+
// through both hooks.
|
|
481
|
+
registeredProgressHook === null || registeredProgressHook === void 0 ? void 0 : registeredProgressHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01]());
|
|
482
|
+
let lastEmittedStatus;
|
|
483
|
+
const outboundTranslator = (event) => {
|
|
484
|
+
if (!registeredProgressHook)
|
|
485
|
+
return;
|
|
486
|
+
if (event.status === 'polling' && lastEmittedStatus !== 'polling') {
|
|
487
|
+
lastEmittedStatus = 'polling';
|
|
488
|
+
registeredProgressHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02](event.elapsed));
|
|
489
|
+
}
|
|
490
|
+
};
|
|
475
491
|
try {
|
|
476
492
|
const outboundDetails = yield callbacks.waitForOutboundTx(tx.hash, {
|
|
477
493
|
initialWaitMs: callbacks.outboundConstants.initialWaitMs,
|
|
478
494
|
pollingIntervalMs: callbacks.outboundConstants.pollingIntervalMs,
|
|
479
495
|
timeout: callbacks.outboundConstants.maxTimeoutMs,
|
|
496
|
+
progressHook: outboundTranslator,
|
|
480
497
|
});
|
|
498
|
+
registeredProgressHook === null || registeredProgressHook === void 0 ? void 0 : registeredProgressHook(progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03](outboundDetails));
|
|
481
499
|
// Merge external chain details into receipt
|
|
482
500
|
baseReceipt = Object.assign(Object.assign({}, baseReceipt), { externalTxHash: outboundDetails.externalTxHash, externalChain: outboundDetails.destinationChain, externalExplorerUrl: outboundDetails.explorerUrl, externalRecipient: outboundDetails.recipient, externalAmount: outboundDetails.amount, externalAssetAddr: outboundDetails.assetAddr });
|
|
483
501
|
}
|
|
484
502
|
catch (error) {
|
|
503
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
504
|
+
const isTimeout = errMsg.startsWith('Timeout waiting for outbound transaction');
|
|
505
|
+
registeredProgressHook === null || registeredProgressHook === void 0 ? void 0 : registeredProgressHook(isTimeout
|
|
506
|
+
? progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04](callbacks.outboundConstants.maxTimeoutMs)
|
|
507
|
+
: progress_hook_1.default[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05](errMsg));
|
|
485
508
|
// Outbound polling timed out - return partial receipt (don't throw)
|
|
486
509
|
// Push Chain tx succeeded, external tracking can be retried later
|
|
487
|
-
callbacks.printLog(`[wait] External chain tracking failed: ${
|
|
510
|
+
callbacks.printLog(`[wait] External chain tracking failed: ${errMsg}`);
|
|
488
511
|
}
|
|
489
512
|
}
|
|
490
513
|
return baseReceipt;
|
|
@@ -138,7 +138,10 @@ export interface UniversalTxResponse {
|
|
|
138
138
|
wait: () => Promise<UniversalTxReceipt>;
|
|
139
139
|
/**
|
|
140
140
|
* Register a progress callback for events during wait().
|
|
141
|
-
* Call this BEFORE calling wait() to receive tracking events
|
|
141
|
+
* Call this BEFORE calling wait() to receive tracking events, including
|
|
142
|
+
* the SEND-TX-08-xx / SEND-TX-99-03/04/05 external chain polling events
|
|
143
|
+
* emitted on outbound routes. Registering after wait() resolves will
|
|
144
|
+
* replay the pre-execution event buffer but miss outbound polling events.
|
|
142
145
|
* @param callback - Function called with each progress event
|
|
143
146
|
*/
|
|
144
147
|
progressHook: (callback: (event: import('../progress-hook/progress-hook.types').ProgressEvent) => void) => void;
|
|
@@ -515,8 +518,14 @@ export interface CascadeTrackOptions {
|
|
|
515
518
|
pollingIntervalMs?: number;
|
|
516
519
|
/** Total timeout (default: 600000ms = 10 min) */
|
|
517
520
|
timeout?: number;
|
|
518
|
-
/**
|
|
521
|
+
/** Per-hop progress callback */
|
|
519
522
|
progressHook?: (event: CascadeProgressEvent) => void;
|
|
523
|
+
/**
|
|
524
|
+
* Unified ProgressEvent stream for SEND-TX-08/99_03-05 telemetry.
|
|
525
|
+
* Fires per outbound hop during external chain polling. Use alongside
|
|
526
|
+
* `progressHook` — they emit complementary views of the same events.
|
|
527
|
+
*/
|
|
528
|
+
eventHook?: (event: import('../progress-hook/progress-hook.types').ProgressEvent) => void;
|
|
520
529
|
}
|
|
521
530
|
/**
|
|
522
531
|
* Progress event emitted during cascade tracking
|
|
@@ -158,6 +158,25 @@ const RAW_HOOKS = {
|
|
|
158
158
|
response: null,
|
|
159
159
|
level: 'INFO',
|
|
160
160
|
}),
|
|
161
|
+
// External chain polling (08-x) — emitted from .wait() / cascade.waitForAll()
|
|
162
|
+
// after Push Chain tx success, while the SDK polls the relay for the
|
|
163
|
+
// external chain tx hash on outbound routes.
|
|
164
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01]: (destinationChain) => ({
|
|
165
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01,
|
|
166
|
+
title: 'Awaiting External Chain',
|
|
167
|
+
message: destinationChain
|
|
168
|
+
? `Waiting for relay to dispatch to ${destinationChain}...`
|
|
169
|
+
: 'Waiting for relay to dispatch to external chain...',
|
|
170
|
+
response: null,
|
|
171
|
+
level: 'INFO',
|
|
172
|
+
}),
|
|
173
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02]: (elapsedMs) => ({
|
|
174
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02,
|
|
175
|
+
title: 'Polling External Chain',
|
|
176
|
+
message: `Polling relay for external transaction hash (elapsed: ${Math.round(elapsedMs / 1000)}s)`,
|
|
177
|
+
response: null,
|
|
178
|
+
level: 'INFO',
|
|
179
|
+
}),
|
|
161
180
|
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01]: (txResponse) => ({
|
|
162
181
|
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01,
|
|
163
182
|
title: 'Push Chain Tx Success',
|
|
@@ -172,6 +191,27 @@ const RAW_HOOKS = {
|
|
|
172
191
|
response: null,
|
|
173
192
|
level: 'ERROR',
|
|
174
193
|
}),
|
|
194
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03]: (details) => ({
|
|
195
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03,
|
|
196
|
+
title: 'External Chain Tx Confirmed',
|
|
197
|
+
message: `External tx confirmed on ${details.destinationChain}: ${details.externalTxHash}`,
|
|
198
|
+
response: details,
|
|
199
|
+
level: 'SUCCESS',
|
|
200
|
+
}),
|
|
201
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04]: (elapsedMs) => ({
|
|
202
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04,
|
|
203
|
+
title: 'External Chain Tx Timeout',
|
|
204
|
+
message: `Timed out waiting for external chain tx after ${Math.round(elapsedMs / 1000)}s. Push Chain tx succeeded; the relay may still be processing.`,
|
|
205
|
+
response: null,
|
|
206
|
+
level: 'WARNING',
|
|
207
|
+
}),
|
|
208
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05]: (errorMessage) => ({
|
|
209
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05,
|
|
210
|
+
title: 'External Chain Tx Failed',
|
|
211
|
+
message: errorMessage,
|
|
212
|
+
response: null,
|
|
213
|
+
level: 'ERROR',
|
|
214
|
+
}),
|
|
175
215
|
// UEA Migration hooks
|
|
176
216
|
[progress_hook_types_1.PROGRESS_HOOK.UEA_MIG_01]: () => ({
|
|
177
217
|
id: progress_hook_types_1.PROGRESS_HOOK.UEA_MIG_01,
|
|
@@ -34,8 +34,13 @@ export declare enum PROGRESS_HOOK {
|
|
|
34
34
|
SEND_TX_06_05 = "SEND-TX-06-05",// Syncing with Push Chain
|
|
35
35
|
SEND_TX_06_06 = "SEND-TX-06-06",// Funds Credited on Push Chain (was 06_05)
|
|
36
36
|
SEND_TX_07 = "SEND-TX-07",// Broadcasting to Push Chain
|
|
37
|
+
SEND_TX_08_01 = "SEND-TX-08-01",// Awaiting External Chain
|
|
38
|
+
SEND_TX_08_02 = "SEND-TX-08-02",// Polling External Chain
|
|
37
39
|
SEND_TX_99_01 = "SEND-TX-99-01",
|
|
38
40
|
SEND_TX_99_02 = "SEND-TX-99-02",
|
|
41
|
+
SEND_TX_99_03 = "SEND-TX-99-03",// External Chain Tx Confirmed (SUCCESS)
|
|
42
|
+
SEND_TX_99_04 = "SEND-TX-99-04",// External Chain Tx Timeout (WARNING)
|
|
43
|
+
SEND_TX_99_05 = "SEND-TX-99-05",// External Chain Tx Failed (ERROR)
|
|
39
44
|
UEA_MIG_01 = "UEA-MIG-01",
|
|
40
45
|
UEA_MIG_02 = "UEA-MIG-02",
|
|
41
46
|
UEA_MIG_03 = "UEA-MIG-03",
|
|
@@ -28,9 +28,15 @@ var PROGRESS_HOOK;
|
|
|
28
28
|
PROGRESS_HOOK["SEND_TX_06_06"] = "SEND-TX-06-06";
|
|
29
29
|
// 07-x: Execution / broadcasting flow
|
|
30
30
|
PROGRESS_HOOK["SEND_TX_07"] = "SEND-TX-07";
|
|
31
|
+
// 08-x: External chain polling (after Push Chain tx success, outbound routes)
|
|
32
|
+
PROGRESS_HOOK["SEND_TX_08_01"] = "SEND-TX-08-01";
|
|
33
|
+
PROGRESS_HOOK["SEND_TX_08_02"] = "SEND-TX-08-02";
|
|
31
34
|
// 99-x: Final outcome
|
|
32
35
|
PROGRESS_HOOK["SEND_TX_99_01"] = "SEND-TX-99-01";
|
|
33
36
|
PROGRESS_HOOK["SEND_TX_99_02"] = "SEND-TX-99-02";
|
|
37
|
+
PROGRESS_HOOK["SEND_TX_99_03"] = "SEND-TX-99-03";
|
|
38
|
+
PROGRESS_HOOK["SEND_TX_99_04"] = "SEND-TX-99-04";
|
|
39
|
+
PROGRESS_HOOK["SEND_TX_99_05"] = "SEND-TX-99-05";
|
|
34
40
|
// UEA Migration hooks
|
|
35
41
|
PROGRESS_HOOK["UEA_MIG_01"] = "UEA-MIG-01";
|
|
36
42
|
PROGRESS_HOOK["UEA_MIG_02"] = "UEA-MIG-02";
|