@pushchain/core 5.1.17 → 5.1.18

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/lib/constants/index.d.ts +1 -1
  3. package/src/lib/constants/index.js +2 -1
  4. package/src/lib/constants/selectors.d.ts +8 -0
  5. package/src/lib/constants/selectors.js +9 -1
  6. package/src/lib/formatters.d.ts +1 -0
  7. package/src/lib/formatters.js +32 -0
  8. package/src/lib/orchestrator/internals/cascade.d.ts +8 -1
  9. package/src/lib/orchestrator/internals/cascade.js +486 -143
  10. package/src/lib/orchestrator/internals/error-decoder.d.ts +2 -6
  11. package/src/lib/orchestrator/internals/error-decoder.js +10 -10
  12. package/src/lib/orchestrator/internals/errors.d.ts +1 -1
  13. package/src/lib/orchestrator/internals/errors.js +7 -4
  14. package/src/lib/orchestrator/internals/execute-standard.js +7 -6
  15. package/src/lib/orchestrator/internals/gas-calculator.js +78 -11
  16. package/src/lib/orchestrator/internals/helpers.d.ts +2 -1
  17. package/src/lib/orchestrator/internals/helpers.js +13 -11
  18. package/src/lib/orchestrator/internals/outbound-sync.d.ts +1 -0
  19. package/src/lib/orchestrator/internals/outbound-sync.js +93 -37
  20. package/src/lib/orchestrator/internals/preflight.d.ts +2 -16
  21. package/src/lib/orchestrator/internals/preflight.js +2 -36
  22. package/src/lib/orchestrator/internals/response-builder.js +23 -7
  23. package/src/lib/orchestrator/internals/route-handlers.js +34 -49
  24. package/src/lib/orchestrator/orchestrator.d.ts +7 -1
  25. package/src/lib/orchestrator/orchestrator.js +40 -2
  26. package/src/lib/orchestrator/orchestrator.types.d.ts +4 -14
  27. package/src/lib/progress-hook/progress-hook.js +13 -20
  28. package/src/lib/push-chain/push-chain.d.ts +11 -1
  29. package/src/lib/push-chain/push-chain.js +2 -2
  30. package/src/lib/universal-tx-detector/cascade.js +14 -4
  31. package/src/lib/universal-tx-detector/child-inbounds.js +9 -1
  32. package/src/lib/universal-tx-detector/detector.js +9 -3
  33. package/src/lib/universal-tx-detector/normalize.d.ts +42 -0
  34. package/src/lib/universal-tx-detector/normalize.js +127 -0
  35. package/src/lib/utils/external-tx-hash.d.ts +37 -0
  36. package/src/lib/utils/external-tx-hash.js +62 -0
@@ -25,6 +25,7 @@ const enums_1 = require("../constants/enums");
25
25
  Object.defineProperty(exports, "PUSH_NETWORK", { enumerable: true, get: function () { return enums_1.PUSH_NETWORK; } });
26
26
  const child_inbounds_1 = require("./child-inbounds");
27
27
  const detector_1 = require("./detector");
28
+ const normalize_1 = require("./normalize");
28
29
  const PUSH_CHAIN_CAIPS = new Set([
29
30
  enums_1.CHAIN.PUSH_MAINNET,
30
31
  enums_1.CHAIN.PUSH_TESTNET_DONUT,
@@ -46,8 +47,10 @@ function traceUniversalTxCascade(startHash, startChain, opts) {
46
47
  const root = yield walk(startHash, startChain, 0, state, opts);
47
48
  if (!root) {
48
49
  // Should never happen for depth=0; return an empty detection node so the
49
- // caller has something to render.
50
- return {
50
+ // caller has something to render. No outbound summaries → nothing to
51
+ // normalize, but we still pass through `normalizeCascadeNodeForUser`
52
+ // for symmetry with the happy path below.
53
+ return (0, normalize_1.normalizeCascadeNodeForUser)({
51
54
  detection: {
52
55
  txHash: startHash,
53
56
  chain: startChain,
@@ -60,9 +63,16 @@ function traceUniversalTxCascade(startHash, startChain, opts) {
60
63
  },
61
64
  children: [],
62
65
  depth: 0,
63
- };
66
+ });
64
67
  }
65
- return root;
68
+ // User-facing normalization pass — recursively rewrites every
69
+ // `PushChainOutboundSummary.externalTxHash` in the tree to base58 for SVM
70
+ // destinations. Each internal `detectUniversalTx` call (in `walk`) already
71
+ // produced a normalized detection; this final pass also normalizes the
72
+ // edge-level `relation` summaries inside `expandPushOutbounds` /
73
+ // `expandExternalChildInbounds` which build summaries DIRECTLY (without
74
+ // going through `detectUniversalTx`).
75
+ return (0, normalize_1.normalizeCascadeNodeForUser)(root);
66
76
  });
67
77
  }
68
78
  // ── Core recursion ────────────────────────────────────────────────────
@@ -22,6 +22,7 @@ const tslib_1 = require("tslib");
22
22
  * `pushClient.getUniversalTxByIdV2`, no event-attribute predicate needed.
23
23
  */
24
24
  const viem_1 = require("viem");
25
+ const normalize_1 = require("./normalize");
25
26
  const STATUS_NAMES = {
26
27
  0: 'UNIVERSAL_TX_STATUS_UNSPECIFIED',
27
28
  1: 'INBOUND_SUCCESS',
@@ -75,7 +76,14 @@ function resolveChildInboundsFromDetection(pushClient, detection, diagnostics) {
75
76
  const inboundLogs = detection.detections
76
77
  .filter((d) => INBOUND_EVENT_NAMES.has(d.log.eventName))
77
78
  .map((d) => d.log);
78
- return resolveChildInboundsFromLogs(pushClient, detection.chain, detection.txHash, inboundLogs, diagnostics);
79
+ const resolutions = yield resolveChildInboundsFromLogs(pushClient, detection.chain, detection.txHash, inboundLogs, diagnostics);
80
+ // User-facing normalization pass: rewrites nested
81
+ // `outboundHashes[n].externalTxHash` to base58 for SVM destinations.
82
+ // `pcTxHashes` is Push Chain (EVM) and stays hex by chain type. The lower-
83
+ // level `resolveChildInboundsFromLogs` is left producing raw hex so
84
+ // internal callers (`findChildUtxIdFromExternalTx` via the detector path)
85
+ // that go through it directly still see the canonical form.
86
+ return resolutions.map(normalize_1.normalizeChildInboundResolutionForUser);
79
87
  });
80
88
  }
81
89
  /**
@@ -25,6 +25,7 @@ const events_1 = require("./events");
25
25
  const classify_1 = require("./classify");
26
26
  const child_inbounds_1 = require("./child-inbounds");
27
27
  const detector_svm_1 = require("./detector-svm");
28
+ const normalize_1 = require("./normalize");
28
29
  // ── Status name table (copied from scripts/poll-outbound.ts:33-44) ────
29
30
  const UNIVERSAL_TX_STATUS_NAMES = {
30
31
  0: 'UNIVERSAL_TX_STATUS_UNSPECIFIED',
@@ -51,7 +52,7 @@ function detectUniversalTx(txHash_1, chain_2) {
51
52
  throw new Error(`detectUniversalTx: unknown chain ${chain}`);
52
53
  }
53
54
  if (chainInfo.vm === enums_1.VM.SVM) {
54
- return (0, detector_svm_1.detectUniversalTxSvm)(txHash, chain, opts);
55
+ return (0, normalize_1.normalizeDetectionForUser)(yield (0, detector_svm_1.detectUniversalTxSvm)(txHash, chain, opts));
55
56
  }
56
57
  if (chainInfo.vm !== enums_1.VM.EVM) {
57
58
  throw new Error(`detectUniversalTx: unsupported vm=${chainInfo.vm} for ${chain}`);
@@ -132,7 +133,12 @@ function detectUniversalTx(txHash_1, chain_2) {
132
133
  notes.push('push cross-reference skipped (no pushClient provided)');
133
134
  }
134
135
  const detections = (0, classify_1.classifyAll)(classified.matchingLogs);
135
- return {
136
+ // User-facing normalization pass: rewrites `pushChainTx.outboundHashes[n]
137
+ // .externalTxHash` to base58 for SVM destinations. The raw `0x`-hex form
138
+ // never leaves this function — internal consumers (findChildUtxIdFromExternalTx,
139
+ // Cosmos `inbound_tx_hash=` queries) work off their own input parameters,
140
+ // not the detection result's outbound summaries.
141
+ return (0, normalize_1.normalizeDetectionForUser)({
136
142
  txHash,
137
143
  chain,
138
144
  kind: classified.kind,
@@ -142,7 +148,7 @@ function detectUniversalTx(txHash_1, chain_2) {
142
148
  detections,
143
149
  pushChainTx,
144
150
  notes,
145
- };
151
+ });
146
152
  });
147
153
  }
148
154
  // ── Helpers ───────────────────────────────────────────────────────────
@@ -0,0 +1,42 @@
1
+ /**
2
+ * User-facing normalization pass for detector outputs.
3
+ *
4
+ * The detector module's internal pipeline produces `PushChainOutboundSummary`
5
+ * objects with raw `0x`-hex `externalTxHash` for SVM destinations — that's
6
+ * the form Cosmos delivers and the form `findChildUtxIdFromExternalTx` /
7
+ * `inbound_tx_hash='…'` queries require. For USER-facing entry points
8
+ * (`detectUniversalTx`, `traceUniversalTxCascade`,
9
+ * `resolveChildInboundsFromDetection`), the SVM hash should be base58 so
10
+ * consumers can paste it straight into a Solana explorer or
11
+ * `connection.getTransaction(sig)`.
12
+ *
13
+ * These helpers are applied at the three public-API return points (and
14
+ * NOWHERE else) — they walk the result tree and rewrite
15
+ * `PushChainOutboundSummary.externalTxHash` for SVM destinations. The
16
+ * internal pipeline never sees the normalized form.
17
+ *
18
+ * Helpers are idempotent: a value not starting with `0x` or whose
19
+ * `destinationChain` isn't SVM passes through unchanged. New objects are
20
+ * returned only when a field actually changed; otherwise the same reference
21
+ * is reused so EVM-only graphs incur near-zero allocation.
22
+ */
23
+ import type { PushChainOutboundSummary, UniversalTxDetection } from './types';
24
+ import type { CascadeNode } from './cascade';
25
+ import type { ChildInboundResolution } from './child-inbounds';
26
+ /**
27
+ * Normalize a single outbound summary's `externalTxHash` for user display.
28
+ * Returns the same reference when no change is needed.
29
+ */
30
+ export declare function normalizeOutboundSummaryForUser(s: PushChainOutboundSummary): PushChainOutboundSummary;
31
+ /**
32
+ * Normalize the outbound summaries embedded in `detection.pushChainTx`.
33
+ * The root `detection.txHash` is left untouched — per agreed scope.
34
+ */
35
+ export declare function normalizeDetectionForUser(d: UniversalTxDetection): UniversalTxDetection;
36
+ /**
37
+ * Normalize the outbound summaries inside a `ChildInboundResolution`.
38
+ * `pcTxHashes` (Push Chain — always EVM) is left untouched.
39
+ */
40
+ export declare function normalizeChildInboundResolutionForUser(r: ChildInboundResolution): ChildInboundResolution;
41
+ /** Recursively normalize a cascade tree. */
42
+ export declare function normalizeCascadeNodeForUser(n: CascadeNode): CascadeNode;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * User-facing normalization pass for detector outputs.
4
+ *
5
+ * The detector module's internal pipeline produces `PushChainOutboundSummary`
6
+ * objects with raw `0x`-hex `externalTxHash` for SVM destinations — that's
7
+ * the form Cosmos delivers and the form `findChildUtxIdFromExternalTx` /
8
+ * `inbound_tx_hash='…'` queries require. For USER-facing entry points
9
+ * (`detectUniversalTx`, `traceUniversalTxCascade`,
10
+ * `resolveChildInboundsFromDetection`), the SVM hash should be base58 so
11
+ * consumers can paste it straight into a Solana explorer or
12
+ * `connection.getTransaction(sig)`.
13
+ *
14
+ * These helpers are applied at the three public-API return points (and
15
+ * NOWHERE else) — they walk the result tree and rewrite
16
+ * `PushChainOutboundSummary.externalTxHash` for SVM destinations. The
17
+ * internal pipeline never sees the normalized form.
18
+ *
19
+ * Helpers are idempotent: a value not starting with `0x` or whose
20
+ * `destinationChain` isn't SVM passes through unchanged. New objects are
21
+ * returned only when a field actually changed; otherwise the same reference
22
+ * is reused so EVM-only graphs incur near-zero allocation.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.normalizeOutboundSummaryForUser = normalizeOutboundSummaryForUser;
26
+ exports.normalizeDetectionForUser = normalizeDetectionForUser;
27
+ exports.normalizeChildInboundResolutionForUser = normalizeChildInboundResolutionForUser;
28
+ exports.normalizeCascadeNodeForUser = normalizeCascadeNodeForUser;
29
+ const external_tx_hash_1 = require("../utils/external-tx-hash");
30
+ /**
31
+ * Normalize a single outbound summary's `externalTxHash` for user display.
32
+ * Returns the same reference when no change is needed.
33
+ */
34
+ function normalizeOutboundSummaryForUser(s) {
35
+ if (!s.externalTxHash)
36
+ return s;
37
+ const chain = (0, external_tx_hash_1.chainFromNamespace)(s.destinationChain);
38
+ const next = (0, external_tx_hash_1.toExternalTxHashDisplay)(chain !== null && chain !== void 0 ? chain : undefined, s.externalTxHash);
39
+ if (next === s.externalTxHash)
40
+ return s;
41
+ return Object.assign(Object.assign({}, s), { externalTxHash: next });
42
+ }
43
+ /**
44
+ * Normalize the outbound summaries inside `PushChainCrossRef.outboundHashes`.
45
+ * Reuses the input when no nested summary changed.
46
+ */
47
+ function normalizeCrossRefForUser(x) {
48
+ if (!x.outboundHashes || x.outboundHashes.length === 0)
49
+ return x;
50
+ let changed = false;
51
+ const next = x.outboundHashes.map((s) => {
52
+ const n = normalizeOutboundSummaryForUser(s);
53
+ if (n !== s)
54
+ changed = true;
55
+ return n;
56
+ });
57
+ if (!changed)
58
+ return x;
59
+ return Object.assign(Object.assign({}, x), { outboundHashes: next });
60
+ }
61
+ /**
62
+ * Normalize the outbound summaries embedded in `detection.pushChainTx`.
63
+ * The root `detection.txHash` is left untouched — per agreed scope.
64
+ */
65
+ function normalizeDetectionForUser(d) {
66
+ if (!d.pushChainTx)
67
+ return d;
68
+ const nextPushChainTx = normalizeCrossRefForUser(d.pushChainTx);
69
+ if (nextPushChainTx === d.pushChainTx)
70
+ return d;
71
+ return Object.assign(Object.assign({}, d), { pushChainTx: nextPushChainTx });
72
+ }
73
+ /**
74
+ * Normalize the outbound summaries inside a `ChildInboundResolution`.
75
+ * `pcTxHashes` (Push Chain — always EVM) is left untouched.
76
+ */
77
+ function normalizeChildInboundResolutionForUser(r) {
78
+ if (!r.outboundHashes || r.outboundHashes.length === 0)
79
+ return r;
80
+ let changed = false;
81
+ const next = r.outboundHashes.map((s) => {
82
+ const n = normalizeOutboundSummaryForUser(s);
83
+ if (n !== s)
84
+ changed = true;
85
+ return n;
86
+ });
87
+ if (!changed)
88
+ return r;
89
+ return Object.assign(Object.assign({}, r), { outboundHashes: next });
90
+ }
91
+ /**
92
+ * Type guard: identifies a `CascadeEdge.relation` as a
93
+ * `PushChainOutboundSummary`. Outbound summaries carry `destinationChain` and
94
+ * (optionally) `externalTxHash`; refund summaries and child-inbound
95
+ * resolutions don't.
96
+ */
97
+ function isOutboundRelation(r) {
98
+ return (typeof r.destinationChain === 'string' &&
99
+ !('universalTxId' in r) &&
100
+ !('parentOutboundId' in r));
101
+ }
102
+ function isChildInboundRelation(r) {
103
+ return 'universalTxId' in r;
104
+ }
105
+ /** Recursively normalize a cascade tree. */
106
+ function normalizeCascadeNodeForUser(n) {
107
+ const nextDetection = normalizeDetectionForUser(n.detection);
108
+ let childrenChanged = nextDetection !== n.detection;
109
+ const nextChildren = n.children.map((edge) => {
110
+ let nextRelation = edge.relation;
111
+ if (isOutboundRelation(edge.relation)) {
112
+ nextRelation = normalizeOutboundSummaryForUser(edge.relation);
113
+ }
114
+ else if (isChildInboundRelation(edge.relation)) {
115
+ nextRelation = normalizeChildInboundResolutionForUser(edge.relation);
116
+ }
117
+ const nextNode = edge.node ? normalizeCascadeNodeForUser(edge.node) : edge.node;
118
+ if (nextRelation === edge.relation && nextNode === edge.node)
119
+ return edge;
120
+ childrenChanged = true;
121
+ return Object.assign(Object.assign({}, edge), { relation: nextRelation, node: nextNode });
122
+ });
123
+ if (!childrenChanged)
124
+ return n;
125
+ return Object.assign(Object.assign({}, n), { detection: nextDetection, children: nextChildren });
126
+ }
127
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * External-tx-hash display helpers.
3
+ *
4
+ * Lives at a neutral cross-module location so both the orchestrator and the
5
+ * universal-tx-detector module can import without creating a circular /
6
+ * back-layered dependency (orchestrator/internals imports detector via
7
+ * inbound-tracker.ts; detector must not import back into orchestrator).
8
+ *
9
+ * The SDK stores SVM (Solana) outbound tx signatures as `0x`-prefixed hex
10
+ * internally — that's how the Cosmos keeper indexes them. Users, however,
11
+ * expect Solana explorers / RPCs to see base58 signatures. `toExternalTxHashDisplay`
12
+ * is the one-way conversion applied at every user-facing boundary; the
13
+ * internal canonical form stays hex.
14
+ */
15
+ import { CHAIN } from '../constants/enums';
16
+ /**
17
+ * Convert an outbound tx hash from the internal canonical form (`0x`-prefixed
18
+ * hex, as Cosmos delivers it) to the form users expect on the destination
19
+ * chain. SVM signatures (64 bytes) become base58; EVM hashes pass through
20
+ * unchanged. Idempotent: a value that already lacks `0x` or whose chain isn't
21
+ * SVM is returned as-is.
22
+ *
23
+ * Used at user-facing boundaries that surface `externalTxHash` (receipt
24
+ * construction in response-builder, cascade hop info in cascade.ts, detector
25
+ * public-API output normalization). Do NOT apply at internal boundaries —
26
+ * `findChildUtxIdFromExternalTx` and the Cosmos tx-search query in
27
+ * inbound-tracker.ts expect the raw hex form.
28
+ */
29
+ export declare function toExternalTxHashDisplay(chain: CHAIN | undefined, rawTxHash: string | undefined): string | undefined;
30
+ /**
31
+ * Map a CAIP namespace string (e.g. `'solana:devnet'`, `'eip155:11155111'`)
32
+ * to the corresponding `CHAIN` enum value, or `null` if no matching chain is
33
+ * registered. Used to resolve `PushChainOutboundSummary.destinationChain`
34
+ * (string) to a CHAIN enum so `toExternalTxHashDisplay` can decide whether
35
+ * to convert.
36
+ */
37
+ export declare function chainFromNamespace(namespace: string): CHAIN | null;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ /**
3
+ * External-tx-hash display helpers.
4
+ *
5
+ * Lives at a neutral cross-module location so both the orchestrator and the
6
+ * universal-tx-detector module can import without creating a circular /
7
+ * back-layered dependency (orchestrator/internals imports detector via
8
+ * inbound-tracker.ts; detector must not import back into orchestrator).
9
+ *
10
+ * The SDK stores SVM (Solana) outbound tx signatures as `0x`-prefixed hex
11
+ * internally — that's how the Cosmos keeper indexes them. Users, however,
12
+ * expect Solana explorers / RPCs to see base58 signatures. `toExternalTxHashDisplay`
13
+ * is the one-way conversion applied at every user-facing boundary; the
14
+ * internal canonical form stays hex.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.toExternalTxHashDisplay = toExternalTxHashDisplay;
18
+ exports.chainFromNamespace = chainFromNamespace;
19
+ const chain_1 = require("../constants/chain");
20
+ const enums_1 = require("../constants/enums");
21
+ const bs58_1 = require("../internal/bs58");
22
+ /**
23
+ * Convert an outbound tx hash from the internal canonical form (`0x`-prefixed
24
+ * hex, as Cosmos delivers it) to the form users expect on the destination
25
+ * chain. SVM signatures (64 bytes) become base58; EVM hashes pass through
26
+ * unchanged. Idempotent: a value that already lacks `0x` or whose chain isn't
27
+ * SVM is returned as-is.
28
+ *
29
+ * Used at user-facing boundaries that surface `externalTxHash` (receipt
30
+ * construction in response-builder, cascade hop info in cascade.ts, detector
31
+ * public-API output normalization). Do NOT apply at internal boundaries —
32
+ * `findChildUtxIdFromExternalTx` and the Cosmos tx-search query in
33
+ * inbound-tracker.ts expect the raw hex form.
34
+ */
35
+ function toExternalTxHashDisplay(chain, rawTxHash) {
36
+ var _a;
37
+ if (!rawTxHash)
38
+ return rawTxHash;
39
+ if (!chain || ((_a = chain_1.CHAIN_INFO[chain]) === null || _a === void 0 ? void 0 : _a.vm) !== enums_1.VM.SVM)
40
+ return rawTxHash;
41
+ if (!rawTxHash.startsWith('0x'))
42
+ return rawTxHash;
43
+ const bytes = new Uint8Array(Buffer.from(rawTxHash.slice(2), 'hex'));
44
+ return bs58_1.bs58.encode(Buffer.from(bytes));
45
+ }
46
+ /**
47
+ * Map a CAIP namespace string (e.g. `'solana:devnet'`, `'eip155:11155111'`)
48
+ * to the corresponding `CHAIN` enum value, or `null` if no matching chain is
49
+ * registered. Used to resolve `PushChainOutboundSummary.destinationChain`
50
+ * (string) to a CHAIN enum so `toExternalTxHashDisplay` can decide whether
51
+ * to convert.
52
+ */
53
+ function chainFromNamespace(namespace) {
54
+ for (const [chainKey, info] of Object.entries(chain_1.CHAIN_INFO)) {
55
+ const expected = `${chain_1.VM_NAMESPACE[info.vm]}:${info.chainId}`;
56
+ if (expected === namespace) {
57
+ return chainKey;
58
+ }
59
+ }
60
+ return null;
61
+ }
62
+ //# sourceMappingURL=external-tx-hash.js.map