@pushchain/core 5.1.5-alpha.1 → 5.1.6

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 (86) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/package.json +1 -1
  3. package/src/lib/constants/abi/index.d.ts +2 -0
  4. package/src/lib/constants/abi/index.js +6 -1
  5. package/src/lib/constants/abi/uniswap-v3-router.evm.d.ts +58 -0
  6. package/src/lib/constants/abi/uniswap-v3-router.evm.js +41 -0
  7. package/src/lib/constants/abi/wpc.evm.d.ts +24 -0
  8. package/src/lib/constants/abi/wpc.evm.js +27 -0
  9. package/src/lib/constants/chain.d.ts +1 -0
  10. package/src/lib/constants/chain.js +8 -6
  11. package/src/lib/constants/tokens.js +3 -3
  12. package/src/lib/generated/uexecutor/v2/types.d.ts +14 -0
  13. package/src/lib/generated/uexecutor/v2/types.js +96 -3
  14. package/src/lib/orchestrator/internals/cascade.d.ts +1 -1
  15. package/src/lib/orchestrator/internals/cascade.js +521 -239
  16. package/src/lib/orchestrator/internals/confirmation.js +60 -15
  17. package/src/lib/orchestrator/internals/context.d.ts +23 -0
  18. package/src/lib/orchestrator/internals/context.js +58 -0
  19. package/src/lib/orchestrator/internals/execute-funds-only.js +47 -21
  20. package/src/lib/orchestrator/internals/execute-funds-payload.js +70 -37
  21. package/src/lib/orchestrator/internals/execute-standard.js +137 -26
  22. package/src/lib/orchestrator/internals/gas-calculator.d.ts +5 -2
  23. package/src/lib/orchestrator/internals/gas-calculator.js +59 -11
  24. package/src/lib/orchestrator/internals/gas-usd-sizer.d.ts +53 -0
  25. package/src/lib/orchestrator/internals/gas-usd-sizer.js +165 -0
  26. package/src/lib/orchestrator/internals/helpers.js +2 -0
  27. package/src/lib/orchestrator/internals/inbound-tracker.d.ts +83 -0
  28. package/src/lib/orchestrator/internals/inbound-tracker.js +322 -0
  29. package/src/lib/orchestrator/internals/index.d.ts +3 -1
  30. package/src/lib/orchestrator/internals/index.js +8 -2
  31. package/src/lib/orchestrator/internals/outbound-sync.d.ts +32 -1
  32. package/src/lib/orchestrator/internals/outbound-sync.js +154 -17
  33. package/src/lib/orchestrator/internals/pc-usd-oracle.d.ts +28 -0
  34. package/src/lib/orchestrator/internals/pc-usd-oracle.js +285 -0
  35. package/src/lib/orchestrator/internals/progress-route-hooks.d.ts +23 -0
  36. package/src/lib/orchestrator/internals/progress-route-hooks.js +72 -0
  37. package/src/lib/orchestrator/internals/push-chain-tx.d.ts +27 -1
  38. package/src/lib/orchestrator/internals/push-chain-tx.js +111 -15
  39. package/src/lib/orchestrator/internals/rescue.js +1 -1
  40. package/src/lib/orchestrator/internals/response-builder.d.ts +5 -0
  41. package/src/lib/orchestrator/internals/response-builder.js +242 -66
  42. package/src/lib/orchestrator/internals/route-handlers.js +480 -206
  43. package/src/lib/orchestrator/internals/tx-transformer.js +293 -35
  44. package/src/lib/orchestrator/orchestrator.d.ts +7 -1
  45. package/src/lib/orchestrator/orchestrator.js +108 -56
  46. package/src/lib/orchestrator/orchestrator.types.d.ts +111 -5
  47. package/src/lib/orchestrator/payload-builders.d.ts +16 -0
  48. package/src/lib/orchestrator/payload-builders.js +6 -5
  49. package/src/lib/orchestrator/route-detector.js +20 -8
  50. package/src/lib/orchestrator/svm-idl/normalize-address.d.ts +19 -0
  51. package/src/lib/orchestrator/svm-idl/normalize-address.js +56 -0
  52. package/src/lib/orchestrator/svm-idl/registry.d.ts +13 -4
  53. package/src/lib/orchestrator/svm-idl/registry.js +15 -14
  54. package/src/lib/orchestrator/svm-idl/resolve.js +5 -2
  55. package/src/lib/progress-hook/progress-hook.d.ts +28 -0
  56. package/src/lib/progress-hook/progress-hook.js +552 -133
  57. package/src/lib/progress-hook/progress-hook.types.d.ts +77 -29
  58. package/src/lib/progress-hook/progress-hook.types.js +75 -35
  59. package/src/lib/push-client/push-client.d.ts +7 -0
  60. package/src/lib/push-client/push-client.js +18 -1
  61. package/src/lib/universal-tx-detector/__tests__/fixtures/builders.d.ts +32 -0
  62. package/src/lib/universal-tx-detector/__tests__/fixtures/builders.js +65 -0
  63. package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.d.ts +72 -0
  64. package/src/lib/universal-tx-detector/__tests__/fixtures/scenarios.js +669 -0
  65. package/src/lib/universal-tx-detector/auto-detect.d.ts +37 -0
  66. package/src/lib/universal-tx-detector/auto-detect.js +112 -0
  67. package/src/lib/universal-tx-detector/cascade.d.ts +64 -0
  68. package/src/lib/universal-tx-detector/cascade.js +254 -0
  69. package/src/lib/universal-tx-detector/child-inbounds.d.ts +58 -0
  70. package/src/lib/universal-tx-detector/child-inbounds.js +145 -0
  71. package/src/lib/universal-tx-detector/classify.d.ts +33 -0
  72. package/src/lib/universal-tx-detector/classify.js +228 -0
  73. package/src/lib/universal-tx-detector/detector-svm.d.ts +46 -0
  74. package/src/lib/universal-tx-detector/detector-svm.js +324 -0
  75. package/src/lib/universal-tx-detector/detector.d.ts +13 -0
  76. package/src/lib/universal-tx-detector/detector.js +233 -0
  77. package/src/lib/universal-tx-detector/events.d.ts +765 -0
  78. package/src/lib/universal-tx-detector/events.js +241 -0
  79. package/src/lib/universal-tx-detector/index.d.ts +18 -0
  80. package/src/lib/universal-tx-detector/index.js +36 -0
  81. package/src/lib/universal-tx-detector/svm-events.d.ts +41 -0
  82. package/src/lib/universal-tx-detector/svm-events.js +68 -0
  83. package/src/lib/universal-tx-detector/types.d.ts +100 -0
  84. package/src/lib/universal-tx-detector/types.js +3 -0
  85. package/src/lib/utils.d.ts +30 -13
  86. package/src/lib/utils.js +47 -21
@@ -0,0 +1,37 @@
1
+ import { CHAIN } from '../constants/enums';
2
+ import type { DetectUniversalTxOptions, UniversalTxDetection } from './types';
3
+ /**
4
+ * Every chain registered in CHAIN_INFO whose vm the detector supports
5
+ * (EVM + SVM), ordered Push-first.
6
+ */
7
+ export declare function listAutoProbeChains(): CHAIN[];
8
+ export interface DetectUniversalTxAutoOptions extends Omit<DetectUniversalTxOptions, 'rpcUrls'> {
9
+ /** Per-chain RPC overrides. Falls back to CHAIN_INFO defaults. */
10
+ rpcUrls?: Partial<Record<CHAIN, string[]>>;
11
+ /**
12
+ * Override the set of chains to probe. Defaults to every EVM chain in
13
+ * CHAIN_INFO with Push Chain first.
14
+ */
15
+ chains?: CHAIN[];
16
+ /**
17
+ * When true, continue probing all chains even after the first match and
18
+ * return every non-UNKNOWN detection. Default false (return first match).
19
+ */
20
+ exhaustive?: boolean;
21
+ }
22
+ export interface AutoDetectionResult {
23
+ /** The chosen detection — the first non-UNKNOWN result. `undefined` if no chain had a universal-tx event. */
24
+ detection?: UniversalTxDetection;
25
+ /** Every chain that was probed, whether or not it matched. */
26
+ attempts: Array<{
27
+ chain: CHAIN;
28
+ matched: boolean;
29
+ kind: UniversalTxDetection['kind'];
30
+ error?: string;
31
+ }>;
32
+ }
33
+ /**
34
+ * Probe every supported chain in parallel and return the first detection
35
+ * with a recognized universal-tx kind.
36
+ */
37
+ export declare function detectUniversalTxAuto(txHash: `0x${string}`, opts?: DetectUniversalTxAutoOptions): Promise<AutoDetectionResult>;
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listAutoProbeChains = listAutoProbeChains;
4
+ exports.detectUniversalTxAuto = detectUniversalTxAuto;
5
+ const tslib_1 = require("tslib");
6
+ /**
7
+ * Stage 4a — chain auto-detection.
8
+ *
9
+ * When a user pastes a tx hash without knowing which chain it lives on,
10
+ * probe every registered EVM chain in parallel, classify the first one that
11
+ * contains a universal-tx event, and return the detection.
12
+ *
13
+ * Probe order:
14
+ * 1. Push Chain CAIPs (most common case for "PC Execution" hashes)
15
+ * 2. All other EVM chains from CHAIN_INFO, in parallel
16
+ *
17
+ * The function resolves as soon as a non-UNKNOWN detection is found. Other
18
+ * pending probes are abandoned via an AbortController-style race.
19
+ */
20
+ const chain_1 = require("../constants/chain");
21
+ const enums_1 = require("../constants/enums");
22
+ const detector_1 = require("./detector");
23
+ const PUSH_CHAIN_CAIPS = [
24
+ enums_1.CHAIN.PUSH_TESTNET_DONUT,
25
+ enums_1.CHAIN.PUSH_MAINNET,
26
+ enums_1.CHAIN.PUSH_LOCALNET,
27
+ ];
28
+ /**
29
+ * Every chain registered in CHAIN_INFO whose vm the detector supports
30
+ * (EVM + SVM), ordered Push-first.
31
+ */
32
+ function listAutoProbeChains() {
33
+ const supported = Object.keys(chain_1.CHAIN_INFO).filter((c) => {
34
+ var _a;
35
+ const vm = (_a = chain_1.CHAIN_INFO[c]) === null || _a === void 0 ? void 0 : _a.vm;
36
+ return vm === enums_1.VM.EVM || vm === enums_1.VM.SVM;
37
+ });
38
+ const push = [];
39
+ const rest = [];
40
+ for (const c of supported) {
41
+ if (PUSH_CHAIN_CAIPS.includes(c))
42
+ push.push(c);
43
+ else
44
+ rest.push(c);
45
+ }
46
+ return [...push, ...rest];
47
+ }
48
+ /**
49
+ * Probe every supported chain in parallel and return the first detection
50
+ * with a recognized universal-tx kind.
51
+ */
52
+ function detectUniversalTxAuto(txHash_1) {
53
+ return tslib_1.__awaiter(this, arguments, void 0, function* (txHash, opts = {}) {
54
+ var _a, _b;
55
+ const chains = (_a = opts.chains) !== null && _a !== void 0 ? _a : listAutoProbeChains();
56
+ const exhaustive = (_b = opts.exhaustive) !== null && _b !== void 0 ? _b : false;
57
+ const attempts = [];
58
+ // Race probes. When a non-UNKNOWN detection lands, resolve early (unless
59
+ // `exhaustive` is set).
60
+ const seen = [];
61
+ yield new Promise((resolve) => {
62
+ let remaining = chains.length;
63
+ let resolved = false;
64
+ const finish = () => {
65
+ if (resolved)
66
+ return;
67
+ resolved = true;
68
+ resolve();
69
+ };
70
+ if (chains.length === 0)
71
+ return finish();
72
+ for (const chain of chains) {
73
+ (0, detector_1.detectUniversalTx)(txHash, chain, {
74
+ pushClient: opts.pushClient,
75
+ rpcUrls: opts.rpcUrls,
76
+ pushNetwork: opts.pushNetwork,
77
+ skipPushChainLookup: opts.skipPushChainLookup,
78
+ })
79
+ .then((d) => {
80
+ const matched = d.kind !== 'UNKNOWN';
81
+ attempts.push({ chain, matched, kind: d.kind });
82
+ if (matched)
83
+ seen.push(d);
84
+ if (matched && !exhaustive)
85
+ finish();
86
+ })
87
+ .catch((err) => {
88
+ attempts.push({
89
+ chain,
90
+ matched: false,
91
+ kind: 'UNKNOWN',
92
+ error: err instanceof Error ? err.message : String(err),
93
+ });
94
+ })
95
+ .finally(() => {
96
+ remaining -= 1;
97
+ if (remaining === 0)
98
+ finish();
99
+ });
100
+ }
101
+ });
102
+ // Sort attempts so matched chains come first for deterministic caller UX.
103
+ attempts.sort((a, b) => (a.matched === b.matched ? 0 : a.matched ? -1 : 1));
104
+ // Prefer the first chain from the probe list that matched — preserves
105
+ // Push-first order when exhaustive=true.
106
+ const winner = chains
107
+ .map((c) => seen.find((d) => d.chain === c))
108
+ .find((d) => d !== undefined);
109
+ return { detection: winner, attempts };
110
+ });
111
+ }
112
+ //# sourceMappingURL=auto-detect.js.map
@@ -0,0 +1,64 @@
1
+ import { CHAIN, PUSH_NETWORK } from '../constants/enums';
2
+ import type { PushClient } from '../push-client/push-client';
3
+ import { type ChildInboundResolution } from './child-inbounds';
4
+ import type { PushChainOutboundSummary, UniversalTxDetection } from './types';
5
+ export interface PcRefundSummary {
6
+ /** Refund tx on Push Chain. */
7
+ txHash: string;
8
+ sender: string;
9
+ gasUsed: number;
10
+ blockHeight: number;
11
+ status: string;
12
+ errorMsg: string;
13
+ /** subTxId of the parent outbound — useful for UI correlation. */
14
+ parentOutboundId: string;
15
+ }
16
+ export interface CascadeEdge {
17
+ edgeKind: 'outbound' | 'child-inbound' | 'pc-refund';
18
+ /**
19
+ * Summary of the relationship.
20
+ * - `outbound` → PushChainOutboundSummary (cosmos outbound tuple)
21
+ * - `child-inbound` → ChildInboundResolution (destination → Push follow-up)
22
+ * - `pc-refund` → PcRefundSummary (gas-refund tx on Push)
23
+ */
24
+ relation: PushChainOutboundSummary | ChildInboundResolution | PcRefundSummary;
25
+ /**
26
+ * Expanded child node, or null when the target chain isn't supported /
27
+ * depth is exhausted / an RPC lookup failed.
28
+ */
29
+ node: CascadeNode | null;
30
+ }
31
+ export interface CascadeNode {
32
+ detection: UniversalTxDetection;
33
+ children: CascadeEdge[];
34
+ /** Depth from the starting node (0 = root). */
35
+ depth: number;
36
+ /** Set when we stopped expanding because of maxDepth or a cycle. */
37
+ truncated?: 'maxDepth' | 'cycle';
38
+ }
39
+ export interface TraceCascadeOptions {
40
+ /** Required — cosmos queries drive the cascade. */
41
+ pushClient: PushClient;
42
+ /** Default 4. Depth 0 is the root. */
43
+ maxDepth?: number;
44
+ /** Per-chain RPC overrides. Falls back to CHAIN_INFO defaultRPC. */
45
+ rpcUrls?: Partial<Record<CHAIN, string[]>>;
46
+ /**
47
+ * Which Push Chain CAIP to recurse into when walking child-inbounds.
48
+ * Defaults to CHAIN.PUSH_TESTNET_DONUT.
49
+ */
50
+ pushChain?: CHAIN;
51
+ /**
52
+ * Called with each node as it is resolved. Useful for progressive UI.
53
+ */
54
+ onNode?: (node: CascadeNode) => void;
55
+ }
56
+ /**
57
+ * Walk the universal-tx graph starting from `(startHash, startChain)` and
58
+ * return the full cascade tree.
59
+ */
60
+ export declare function traceUniversalTxCascade(startHash: `0x${string}`, startChain: CHAIN, opts: TraceCascadeOptions): Promise<CascadeNode>;
61
+ /** Flatten a cascade tree into depth-first linear node list (root first). */
62
+ export declare function flattenCascade(root: CascadeNode): CascadeNode[];
63
+ export type { PublicClient } from 'viem';
64
+ export { PUSH_NETWORK };
@@ -0,0 +1,254 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PUSH_NETWORK = void 0;
4
+ exports.traceUniversalTxCascade = traceUniversalTxCascade;
5
+ exports.flattenCascade = flattenCascade;
6
+ const tslib_1 = require("tslib");
7
+ /**
8
+ * Stage 3 — recursive cascade walker.
9
+ *
10
+ * Starting from any universal-tx hash on a supported chain, walk forward
11
+ * across the universal-tx graph and return a tree:
12
+ *
13
+ * Push root ──outbound──▶ Destination finalize ──child-inbound──▶ Follow-up Push tx ─...
14
+ *
15
+ * Uses the chain-module key formulas (sha256-based; see
16
+ * push-chain/x/uexecutor/types/keys.go) to resolve:
17
+ * - Push-initiated outbounds → destination external txs (via pcTx utx record)
18
+ * - Destination CEA-originated inbounds → child Push txs (via inbound utx record)
19
+ *
20
+ * Cycle-safe via a `visited` set on (chain, txHash). Bounded by maxDepth.
21
+ */
22
+ const viem_1 = require("viem");
23
+ const chain_1 = require("../constants/chain");
24
+ const enums_1 = require("../constants/enums");
25
+ Object.defineProperty(exports, "PUSH_NETWORK", { enumerable: true, get: function () { return enums_1.PUSH_NETWORK; } });
26
+ const child_inbounds_1 = require("./child-inbounds");
27
+ const detector_1 = require("./detector");
28
+ const PUSH_CHAIN_CAIPS = new Set([
29
+ enums_1.CHAIN.PUSH_MAINNET,
30
+ enums_1.CHAIN.PUSH_TESTNET_DONUT,
31
+ enums_1.CHAIN.PUSH_LOCALNET,
32
+ ]);
33
+ /**
34
+ * Walk the universal-tx graph starting from `(startHash, startChain)` and
35
+ * return the full cascade tree.
36
+ */
37
+ function traceUniversalTxCascade(startHash, startChain, opts) {
38
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
39
+ var _a, _b;
40
+ const state = {
41
+ visited: new Set(),
42
+ pushChain: (_a = opts.pushChain) !== null && _a !== void 0 ? _a : enums_1.CHAIN.PUSH_TESTNET_DONUT,
43
+ maxDepth: (_b = opts.maxDepth) !== null && _b !== void 0 ? _b : 4,
44
+ notes: [],
45
+ };
46
+ const root = yield walk(startHash, startChain, 0, state, opts);
47
+ if (!root) {
48
+ // Should never happen for depth=0; return an empty detection node so the
49
+ // caller has something to render.
50
+ return {
51
+ detection: {
52
+ txHash: startHash,
53
+ chain: startChain,
54
+ kind: 'UNKNOWN',
55
+ emitters: [],
56
+ decoded: {},
57
+ matchingLogs: [],
58
+ detections: [],
59
+ notes: ['cascade: unable to fetch root'],
60
+ },
61
+ children: [],
62
+ depth: 0,
63
+ };
64
+ }
65
+ return root;
66
+ });
67
+ }
68
+ // ── Core recursion ────────────────────────────────────────────────────
69
+ function walk(txHash, chain, depth, state, opts, knownUtxId) {
70
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
71
+ var _a;
72
+ const key = `${chain}::${txHash.toLowerCase()}`;
73
+ if (state.visited.has(key)) {
74
+ // Return a stub node representing the cycle — callers can detect via
75
+ // `truncated === 'cycle'`.
76
+ return null;
77
+ }
78
+ state.visited.add(key);
79
+ const chainInfo = chain_1.CHAIN_INFO[chain];
80
+ if (!chainInfo)
81
+ return null;
82
+ if (chainInfo.vm !== enums_1.VM.EVM && chainInfo.vm !== enums_1.VM.SVM)
83
+ return null;
84
+ const detection = yield (0, detector_1.detectUniversalTx)(txHash, chain, {
85
+ pushClient: opts.pushClient,
86
+ rpcUrls: opts.rpcUrls,
87
+ // We run our own cosmos queries below to build the cascade; skip the
88
+ // detector's built-in single-record lookup to avoid redundant traffic.
89
+ skipPushChainLookup: true,
90
+ });
91
+ const node = { detection, children: [], depth };
92
+ (_a = opts.onNode) === null || _a === void 0 ? void 0 : _a.call(opts, node);
93
+ if (depth >= state.maxDepth) {
94
+ node.truncated = 'maxDepth';
95
+ return node;
96
+ }
97
+ if (PUSH_CHAIN_CAIPS.has(chain)) {
98
+ // Push Chain node — walk outbounds from the pc utx record.
99
+ yield expandPushOutbounds(node, txHash, chain, state, opts, knownUtxId);
100
+ }
101
+ else {
102
+ // External chain — walk child inbounds (CEA-originated UniversalTx logs).
103
+ yield expandExternalChildInbounds(node, detection, state, opts);
104
+ }
105
+ return node;
106
+ });
107
+ }
108
+ function expandPushOutbounds(node, txHash, chain, state, opts, knownUtxId) {
109
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
110
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
111
+ // Prefer the caller-supplied utx id — this covers follow-up Push txs that
112
+ // were triggered by an external CEA inbound (their outbounds live under
113
+ // `sha256(externalCaip:externalHash:logIndex)`, not the PC-derived key).
114
+ // For root Push txs the caller omits it and we derive the PC key.
115
+ const pcUtxId = knownUtxId !== null && knownUtxId !== void 0 ? knownUtxId : (0, child_inbounds_1.derivePcUniversalTxId)(chain, txHash);
116
+ try {
117
+ const resp = yield opts.pushClient.getUniversalTxByIdV2(pcUtxId.slice(2));
118
+ const utx = resp === null || resp === void 0 ? void 0 : resp.universalTx;
119
+ if (!utx || !utx.outboundTx || utx.outboundTx.length === 0)
120
+ return;
121
+ for (const ob of utx.outboundTx) {
122
+ const destChainStr = (_a = ob.destinationChain) !== null && _a !== void 0 ? _a : '';
123
+ const externalTxHash = ((_b = ob.observedTx) === null || _b === void 0 ? void 0 : _b.txHash) || '';
124
+ const summary = {
125
+ subTxId: (_c = ob.id) !== null && _c !== void 0 ? _c : '',
126
+ status: outboundStatusName(ob.outboundStatus),
127
+ destinationChain: destChainStr,
128
+ externalTxHash: externalTxHash || undefined,
129
+ amount: ob.amount,
130
+ recipient: ob.recipient,
131
+ };
132
+ if (!externalTxHash || !isSupportedChainCaip(destChainStr)) {
133
+ node.children.push({
134
+ edgeKind: 'outbound',
135
+ relation: summary,
136
+ node: null,
137
+ });
138
+ }
139
+ else {
140
+ const childNode = yield walk(externalTxHash, destChainStr, node.depth + 1, state, opts);
141
+ node.children.push({
142
+ edgeKind: 'outbound',
143
+ relation: summary,
144
+ node: childNode,
145
+ });
146
+ }
147
+ // Refund edges: the chain records two refund-tx fields on each outbound.
148
+ // - pcRefundExecution (field 18) — gas refund tx after a successful
149
+ // outbound (push-chain/x/uexecutor/keeper/outbound.go).
150
+ // - pcRevertExecution — revert/refund tx when the outbound reverted.
151
+ // Surface both as pc-refund edges and recurse into the refund tx on
152
+ // Push Chain.
153
+ const refundTxs = [];
154
+ if (ob.pcRefundExecution)
155
+ refundTxs.push(ob.pcRefundExecution);
156
+ if (ob.pcRevertExecution)
157
+ refundTxs.push(ob.pcRevertExecution);
158
+ for (const refund of refundTxs) {
159
+ if (!refund.txHash)
160
+ continue;
161
+ const refundSummary = {
162
+ txHash: refund.txHash,
163
+ sender: (_d = refund.sender) !== null && _d !== void 0 ? _d : '',
164
+ gasUsed: typeof refund.gasUsed === 'bigint'
165
+ ? Number(refund.gasUsed)
166
+ : (_e = refund.gasUsed) !== null && _e !== void 0 ? _e : 0,
167
+ blockHeight: typeof refund.blockHeight === 'bigint'
168
+ ? Number(refund.blockHeight)
169
+ : (_f = refund.blockHeight) !== null && _f !== void 0 ? _f : 0,
170
+ status: (_g = refund.status) !== null && _g !== void 0 ? _g : '',
171
+ errorMsg: (_h = refund.errorMsg) !== null && _h !== void 0 ? _h : '',
172
+ parentOutboundId: (_j = ob.id) !== null && _j !== void 0 ? _j : '',
173
+ };
174
+ const refundNode = yield walk(refund.txHash, chain, node.depth + 1, state, opts);
175
+ node.children.push({
176
+ edgeKind: 'pc-refund',
177
+ relation: refundSummary,
178
+ node: refundNode,
179
+ });
180
+ }
181
+ }
182
+ }
183
+ catch (err) {
184
+ node.detection.notes.push(`cascade: pc outbound lookup failed: ${err instanceof Error ? err.message : String(err)}`);
185
+ }
186
+ });
187
+ }
188
+ function expandExternalChildInbounds(node, detection, state, opts) {
189
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
190
+ const resolutions = yield (0, child_inbounds_1.resolveChildInboundsFromDetection)(opts.pushClient, detection, node.detection.notes);
191
+ for (const res of resolutions) {
192
+ // Walk each Push follow-up tx produced by this inbound.
193
+ if (res.pcTxHashes.length === 0) {
194
+ node.children.push({
195
+ edgeKind: 'child-inbound',
196
+ relation: res,
197
+ node: null,
198
+ });
199
+ continue;
200
+ }
201
+ for (const pcHash of res.pcTxHashes) {
202
+ const childNode = yield walk(pcHash, state.pushChain, node.depth + 1, state, opts, res.universalTxId);
203
+ node.children.push({
204
+ edgeKind: 'child-inbound',
205
+ relation: res,
206
+ node: childNode,
207
+ });
208
+ }
209
+ }
210
+ });
211
+ }
212
+ // ── Utilities ─────────────────────────────────────────────────────────
213
+ function isSupportedChainCaip(caip) {
214
+ if (!caip)
215
+ return false;
216
+ const info = chain_1.CHAIN_INFO[caip];
217
+ if (!info)
218
+ return false;
219
+ return info.vm === enums_1.VM.EVM || info.vm === enums_1.VM.SVM;
220
+ }
221
+ function outboundStatusName(n) {
222
+ switch (n) {
223
+ case 0:
224
+ return 'OUTBOUND_STATUS_UNSPECIFIED';
225
+ case 1:
226
+ return 'PENDING';
227
+ case 2:
228
+ return 'OBSERVED';
229
+ case 3:
230
+ return 'REVERTED';
231
+ default:
232
+ return `UNKNOWN(${n !== null && n !== void 0 ? n : '?'})`;
233
+ }
234
+ }
235
+ /** Flatten a cascade tree into depth-first linear node list (root first). */
236
+ function flattenCascade(root) {
237
+ const out = [];
238
+ const stack = [root];
239
+ while (stack.length > 0) {
240
+ const n = stack.pop();
241
+ out.push(n);
242
+ for (let i = n.children.length - 1; i >= 0; i--) {
243
+ const c = n.children[i].node;
244
+ if (c)
245
+ stack.push(c);
246
+ }
247
+ }
248
+ return out;
249
+ }
250
+ // silence unused-import warning for viem helpers not yet referenced
251
+ void viem_1.createPublicClient;
252
+ void viem_1.fallback;
253
+ void viem_1.http;
254
+ //# sourceMappingURL=cascade.js.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Stage 2 — resolve child universal-txs spawned by the inbound legs of a
3
+ * destination-chain transaction.
4
+ *
5
+ * The chain derives a universalTxId per inbound log as:
6
+ * utxId = sha256(`<sourceChainCaip>:<txHash>:<logIndex>`)
7
+ * See push-chain/x/uexecutor/types/keys.go:49-53 (GetInboundUniversalTxKey).
8
+ *
9
+ * For Push-initiated outbounds (pcTx entries) the formula drops the log index:
10
+ * utxId = sha256(`<pcChainCaip>:<pcTxHash>`)
11
+ * See push-chain/x/uexecutor/types/keys.go:63-67 (GetPcUniversalTxKey).
12
+ *
13
+ * This module derives those ids deterministically and queries cosmos via
14
+ * `pushClient.getUniversalTxByIdV2`, no event-attribute predicate needed.
15
+ */
16
+ import { toHex } from 'viem';
17
+ import type { PushClient } from '../push-client/push-client';
18
+ import type { MatchingLog, PushChainOutboundSummary, UniversalTxDetection } from './types';
19
+ export interface ChildInboundResolution {
20
+ /** Deterministically derived universalTxId for this inbound log. */
21
+ universalTxId: `0x${string}`;
22
+ /** Log that triggered the child inbound. */
23
+ sourceLogIndex: number;
24
+ sourceEventName: string;
25
+ status: number;
26
+ statusName: string;
27
+ /** Push Chain tx hashes that ran the child inbound payload. */
28
+ pcTxHashes: string[];
29
+ /** Any grandchild outbounds spawned from the child inbound. */
30
+ outboundHashes: PushChainOutboundSummary[];
31
+ /** Cosmos has no record for this id (not yet observed / relayer-voted). */
32
+ notFound?: boolean;
33
+ }
34
+ /**
35
+ * Deterministic child universalTxId for an inbound event on an external chain.
36
+ * Mirrors `GetInboundUniversalTxKey` from the chain module.
37
+ */
38
+ export declare function deriveChildUniversalTxId(sourceChainCaip: string, externalTxHash: string, logIndex: number | string): `0x${string}`;
39
+ /**
40
+ * Deterministic universalTxId for a Push-Chain-initiated tx (no log index).
41
+ * Mirrors `GetPcUniversalTxKey` from the chain module.
42
+ */
43
+ export declare function derivePcUniversalTxId(pushChainCaip: string, pushTxHash: string): `0x${string}`;
44
+ /**
45
+ * Given a destination-chain detection, resolve each inbound-log leg by
46
+ * computing its deterministic universalTxId and querying cosmos.
47
+ *
48
+ * Returns one entry per inbound log present in the receipt.
49
+ */
50
+ export declare function resolveChildInboundsFromDetection(pushClient: PushClient, detection: UniversalTxDetection, diagnostics?: string[]): Promise<ChildInboundResolution[]>;
51
+ /**
52
+ * Lower-level variant — resolve children from an explicit list of inbound
53
+ * logs (each with a logIndex).
54
+ */
55
+ export declare function resolveChildInboundsFromLogs(pushClient: PushClient, sourceChainCaip: string, externalTxHash: string, inboundLogs: Pick<MatchingLog, 'eventName' | 'logIndex'>[], diagnostics?: string[]): Promise<ChildInboundResolution[]>;
56
+ export declare const __internal: {
57
+ toHex: typeof toHex;
58
+ };
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.__internal = void 0;
4
+ exports.deriveChildUniversalTxId = deriveChildUniversalTxId;
5
+ exports.derivePcUniversalTxId = derivePcUniversalTxId;
6
+ exports.resolveChildInboundsFromDetection = resolveChildInboundsFromDetection;
7
+ exports.resolveChildInboundsFromLogs = resolveChildInboundsFromLogs;
8
+ const tslib_1 = require("tslib");
9
+ /**
10
+ * Stage 2 — resolve child universal-txs spawned by the inbound legs of a
11
+ * destination-chain transaction.
12
+ *
13
+ * The chain derives a universalTxId per inbound log as:
14
+ * utxId = sha256(`<sourceChainCaip>:<txHash>:<logIndex>`)
15
+ * See push-chain/x/uexecutor/types/keys.go:49-53 (GetInboundUniversalTxKey).
16
+ *
17
+ * For Push-initiated outbounds (pcTx entries) the formula drops the log index:
18
+ * utxId = sha256(`<pcChainCaip>:<pcTxHash>`)
19
+ * See push-chain/x/uexecutor/types/keys.go:63-67 (GetPcUniversalTxKey).
20
+ *
21
+ * This module derives those ids deterministically and queries cosmos via
22
+ * `pushClient.getUniversalTxByIdV2`, no event-attribute predicate needed.
23
+ */
24
+ const viem_1 = require("viem");
25
+ const STATUS_NAMES = {
26
+ 0: 'UNIVERSAL_TX_STATUS_UNSPECIFIED',
27
+ 1: 'INBOUND_SUCCESS',
28
+ 2: 'PENDING_INBOUND_EXECUTION',
29
+ 3: 'PC_EXECUTED_SUCCESS',
30
+ 4: 'PC_EXECUTED_FAILED',
31
+ 5: 'PC_PENDING_REVERT',
32
+ 6: 'OUTBOUND_PENDING',
33
+ 7: 'OUTBOUND_SUCCESS',
34
+ 8: 'OUTBOUND_FAILED',
35
+ 9: 'CANCELED',
36
+ };
37
+ const OUTBOUND_STATUS_NAMES = {
38
+ 0: 'OUTBOUND_STATUS_UNSPECIFIED',
39
+ 1: 'PENDING',
40
+ 2: 'OBSERVED',
41
+ 3: 'REVERTED',
42
+ };
43
+ const INBOUND_EVENT_NAMES = new Set([
44
+ 'UniversalTx',
45
+ 'RevertUniversalTx',
46
+ ]);
47
+ /**
48
+ * Deterministic child universalTxId for an inbound event on an external chain.
49
+ * Mirrors `GetInboundUniversalTxKey` from the chain module.
50
+ */
51
+ function deriveChildUniversalTxId(sourceChainCaip, externalTxHash, logIndex) {
52
+ const normHash = externalTxHash.startsWith('0x')
53
+ ? externalTxHash
54
+ : `0x${externalTxHash}`;
55
+ const input = `${sourceChainCaip}:${normHash}:${logIndex}`;
56
+ return (0, viem_1.sha256)((0, viem_1.toBytes)(input));
57
+ }
58
+ /**
59
+ * Deterministic universalTxId for a Push-Chain-initiated tx (no log index).
60
+ * Mirrors `GetPcUniversalTxKey` from the chain module.
61
+ */
62
+ function derivePcUniversalTxId(pushChainCaip, pushTxHash) {
63
+ const normHash = pushTxHash.startsWith('0x') ? pushTxHash : `0x${pushTxHash}`;
64
+ const input = `${pushChainCaip}:${normHash}`;
65
+ return (0, viem_1.sha256)((0, viem_1.toBytes)(input));
66
+ }
67
+ /**
68
+ * Given a destination-chain detection, resolve each inbound-log leg by
69
+ * computing its deterministic universalTxId and querying cosmos.
70
+ *
71
+ * Returns one entry per inbound log present in the receipt.
72
+ */
73
+ function resolveChildInboundsFromDetection(pushClient, detection, diagnostics) {
74
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
75
+ const inboundLogs = detection.detections
76
+ .filter((d) => INBOUND_EVENT_NAMES.has(d.log.eventName))
77
+ .map((d) => d.log);
78
+ return resolveChildInboundsFromLogs(pushClient, detection.chain, detection.txHash, inboundLogs, diagnostics);
79
+ });
80
+ }
81
+ /**
82
+ * Lower-level variant — resolve children from an explicit list of inbound
83
+ * logs (each with a logIndex).
84
+ */
85
+ function resolveChildInboundsFromLogs(pushClient, sourceChainCaip, externalTxHash, inboundLogs, diagnostics) {
86
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
87
+ var _a, _b, _c, _d;
88
+ const out = [];
89
+ for (const log of inboundLogs) {
90
+ if (log.logIndex < 0) {
91
+ diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.push(`skipped log with negative logIndex (eventName=${log.eventName})`);
92
+ continue;
93
+ }
94
+ const utxIdHex = deriveChildUniversalTxId(sourceChainCaip, externalTxHash, log.logIndex);
95
+ try {
96
+ const resp = yield pushClient.getUniversalTxByIdV2(utxIdHex.slice(2));
97
+ const utx = resp === null || resp === void 0 ? void 0 : resp.universalTx;
98
+ if (!utx || !utx.id) {
99
+ out.push({
100
+ universalTxId: utxIdHex,
101
+ sourceLogIndex: log.logIndex,
102
+ sourceEventName: log.eventName,
103
+ status: 0,
104
+ statusName: STATUS_NAMES[0],
105
+ pcTxHashes: [],
106
+ outboundHashes: [],
107
+ notFound: true,
108
+ });
109
+ continue;
110
+ }
111
+ const status = ((_a = utx.universalStatus) !== null && _a !== void 0 ? _a : 0);
112
+ const pcTxHashes = ((_b = utx.pcTx) !== null && _b !== void 0 ? _b : [])
113
+ .map((p) => p === null || p === void 0 ? void 0 : p.txHash)
114
+ .filter((h) => Boolean(h));
115
+ const outboundHashes = ((_c = utx.outboundTx) !== null && _c !== void 0 ? _c : []).map((ob) => {
116
+ var _a, _b, _c, _d;
117
+ return ({
118
+ subTxId: (_a = ob.id) !== null && _a !== void 0 ? _a : '',
119
+ status: (_b = OUTBOUND_STATUS_NAMES[ob.outboundStatus]) !== null && _b !== void 0 ? _b : `UNKNOWN(${ob.outboundStatus})`,
120
+ destinationChain: (_c = ob.destinationChain) !== null && _c !== void 0 ? _c : '',
121
+ externalTxHash: ((_d = ob.observedTx) === null || _d === void 0 ? void 0 : _d.txHash) || undefined,
122
+ amount: ob.amount,
123
+ recipient: ob.recipient,
124
+ });
125
+ });
126
+ out.push({
127
+ universalTxId: utxIdHex,
128
+ sourceLogIndex: log.logIndex,
129
+ sourceEventName: log.eventName,
130
+ status,
131
+ statusName: (_d = STATUS_NAMES[status]) !== null && _d !== void 0 ? _d : `UNKNOWN(${status})`,
132
+ pcTxHashes,
133
+ outboundHashes,
134
+ });
135
+ }
136
+ catch (err) {
137
+ diagnostics === null || diagnostics === void 0 ? void 0 : diagnostics.push(`getUniversalTxByIdV2(${utxIdHex}) failed: ${err instanceof Error ? err.message : String(err)}`);
138
+ }
139
+ }
140
+ return out;
141
+ });
142
+ }
143
+ // Debug-only re-export (avoid importing into production paths).
144
+ exports.__internal = { toHex: viem_1.toHex };
145
+ //# sourceMappingURL=child-inbounds.js.map