@pushchain/core 6.0.23 → 6.0.25

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 (94) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/package.json +1 -1
  3. package/src/lib/constants/abi/index.d.ts +1 -0
  4. package/src/lib/constants/abi/index.js +4 -1
  5. package/src/lib/constants/abi/prc20.evm.d.ts +32 -0
  6. package/src/lib/constants/abi/prc20.evm.js +20 -0
  7. package/src/lib/constants/abi/uea-factory.d.ts +31 -0
  8. package/src/lib/constants/abi/uea-factory.js +19 -0
  9. package/src/lib/constants/abi/universalCallback.evm.d.ts +561 -0
  10. package/src/lib/constants/abi/universalCallback.evm.js +247 -0
  11. package/src/lib/constants/abi/universalGatewayV0.json +1 -1
  12. package/src/lib/constants/abi/universalReadRegistry.evm.d.ts +247 -0
  13. package/src/lib/constants/abi/universalReadRegistry.evm.js +38 -0
  14. package/src/lib/constants/chain.d.ts +12 -0
  15. package/src/lib/constants/chain.js +23 -1
  16. package/src/lib/constants/enums.d.ts +7 -0
  17. package/src/lib/constants/enums.js +11 -0
  18. package/src/lib/constants/index.d.ts +52 -0
  19. package/src/lib/constants/index.js +37 -8
  20. package/src/lib/constants/read-state.d.ts +53 -0
  21. package/src/lib/constants/read-state.js +59 -0
  22. package/src/lib/generated/ucallback/v1/index.d.ts +2 -0
  23. package/src/lib/generated/ucallback/v1/index.js +6 -0
  24. package/src/lib/generated/ucallback/v1/query.d.ts +47 -0
  25. package/src/lib/generated/ucallback/v1/query.js +131 -0
  26. package/src/lib/generated/ucallback/v1/types.d.ts +99 -0
  27. package/src/lib/generated/ucallback/v1/types.js +366 -0
  28. package/src/lib/generated/uexecutor/v1/query.d.ts +29 -0
  29. package/src/lib/generated/uexecutor/v1/query.js +98 -1
  30. package/src/lib/index.d.ts +9 -0
  31. package/src/lib/index.js +37 -1
  32. package/src/lib/orchestrator/internals/cascade.js +5 -2
  33. package/src/lib/orchestrator/internals/errors.d.ts +6 -0
  34. package/src/lib/orchestrator/internals/errors.js +13 -1
  35. package/src/lib/orchestrator/internals/index.d.ts +1 -0
  36. package/src/lib/orchestrator/internals/index.js +6 -1
  37. package/src/lib/orchestrator/internals/push-chain-tx.js +81 -61
  38. package/src/lib/orchestrator/internals/read-state.d.ts +24 -0
  39. package/src/lib/orchestrator/internals/read-state.js +47 -0
  40. package/src/lib/orchestrator/internals/route-handlers.js +6 -1
  41. package/src/lib/orchestrator/internals/svm-helpers.js +24 -0
  42. package/src/lib/orchestrator/orchestrator.d.ts +26 -0
  43. package/src/lib/orchestrator/orchestrator.js +22 -0
  44. package/src/lib/orchestrator/orchestrator.types.d.ts +2 -0
  45. package/src/lib/orchestrator/route-detector.js +4 -0
  46. package/src/lib/progress-hook/progress-hook.js +271 -0
  47. package/src/lib/progress-hook/progress-hook.types.d.ts +32 -0
  48. package/src/lib/progress-hook/progress-hook.types.js +34 -0
  49. package/src/lib/push-chain/push-chain.d.ts +70 -0
  50. package/src/lib/push-chain/push-chain.js +27 -0
  51. package/src/lib/push-client/push-client.d.ts +35 -2
  52. package/src/lib/push-client/push-client.js +117 -4
  53. package/src/lib/read-state/budget.d.ts +16 -0
  54. package/src/lib/read-state/budget.js +32 -0
  55. package/src/lib/read-state/destination.d.ts +12 -0
  56. package/src/lib/read-state/destination.js +51 -0
  57. package/src/lib/read-state/envelopes/evm.d.ts +24 -0
  58. package/src/lib/read-state/envelopes/evm.js +148 -0
  59. package/src/lib/read-state/envelopes/index.d.ts +12 -0
  60. package/src/lib/read-state/envelopes/index.js +45 -0
  61. package/src/lib/read-state/envelopes/svm.d.ts +32 -0
  62. package/src/lib/read-state/envelopes/svm.js +107 -0
  63. package/src/lib/read-state/envelopes/web2.d.ts +29 -0
  64. package/src/lib/read-state/envelopes/web2.js +149 -0
  65. package/src/lib/read-state/errors.d.ts +70 -0
  66. package/src/lib/read-state/errors.js +116 -0
  67. package/src/lib/read-state/index.d.ts +13 -0
  68. package/src/lib/read-state/index.js +38 -0
  69. package/src/lib/read-state/preflight.d.ts +21 -0
  70. package/src/lib/read-state/preflight.js +70 -0
  71. package/src/lib/read-state/read-events.d.ts +27 -0
  72. package/src/lib/read-state/read-events.js +135 -0
  73. package/src/lib/read-state/read-executor.d.ts +18 -0
  74. package/src/lib/read-state/read-executor.js +212 -0
  75. package/src/lib/read-state/read-params.d.ts +205 -0
  76. package/src/lib/read-state/read-params.js +120 -0
  77. package/src/lib/read-state/read-state.types.d.ts +417 -0
  78. package/src/lib/read-state/read-state.types.js +50 -0
  79. package/src/lib/read-state/read-tracker.d.ts +50 -0
  80. package/src/lib/read-state/read-tracker.js +415 -0
  81. package/src/lib/read-state/registry.d.ts +21 -0
  82. package/src/lib/read-state/registry.js +54 -0
  83. package/src/lib/read-state/result-decoder.d.ts +16 -0
  84. package/src/lib/read-state/result-decoder.js +73 -0
  85. package/src/lib/read-state/spec-builder.d.ts +47 -0
  86. package/src/lib/read-state/spec-builder.js +251 -0
  87. package/src/lib/read-state/validate.d.ts +22 -0
  88. package/src/lib/read-state/validate.js +80 -0
  89. package/src/lib/universal-tx-detector/child-inbounds.d.ts +3 -1
  90. package/src/lib/universal-tx-detector/child-inbounds.js +4 -5
  91. package/src/lib/universal-tx-detector/detector-svm.js +29 -20
  92. package/src/lib/universal-tx-detector/svm-events.d.ts +17 -5
  93. package/src/lib/universal-tx-detector/svm-events.js +81 -6
  94. package/src/lib/vm-client/evm-client.js +27 -10
@@ -0,0 +1,29 @@
1
+ import { type Hex } from 'viem';
2
+ import type { EncodedReadQuery, Web2ReadQuery, Web2ValueType } from '../read-state.types';
3
+ /** `universalClient/externalchains/web2/read_envelope.go`. */
4
+ export declare const WEB2_METHOD: {
5
+ readonly GET: 0;
6
+ readonly POST: 1;
7
+ };
8
+ export declare const WEB2_VALUE_TYPE: Record<Web2ValueType, number>;
9
+ /**
10
+ * Deterministic JSON object bytes: keys sorted, no whitespace. The validator
11
+ * `json.Unmarshal`s into map[string]string, so ordering does not affect the read —
12
+ * canonicalising just keeps the on-chain envelope stable across SDK versions.
13
+ */
14
+ export declare function canonicalizeHeaders(headers: Record<string, string> | undefined): Hex;
15
+ /** Encode a `web2` read query. Pure. `blockRef` is always 0 (heightless namespace). */
16
+ export declare function encodeWeb2QueryEnvelope(query: Web2ReadQuery): EncodedReadQuery;
17
+ export declare function decodeWeb2QueryEnvelope(encoded: Hex): {
18
+ method: number;
19
+ url: string;
20
+ headers: Record<string, string>;
21
+ body: Hex;
22
+ timeoutMs: bigint;
23
+ extract: {
24
+ path: string;
25
+ valueType: number;
26
+ mode: number;
27
+ decimals: number;
28
+ }[];
29
+ };
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WEB2_VALUE_TYPE = exports.WEB2_METHOD = void 0;
4
+ exports.canonicalizeHeaders = canonicalizeHeaders;
5
+ exports.encodeWeb2QueryEnvelope = encodeWeb2QueryEnvelope;
6
+ exports.decodeWeb2QueryEnvelope = decodeWeb2QueryEnvelope;
7
+ const viem_1 = require("viem");
8
+ const read_state_1 = require("../../constants/read-state");
9
+ const errors_1 = require("../errors");
10
+ /** `universalClient/externalchains/web2/read_envelope.go`. */
11
+ exports.WEB2_METHOD = { GET: 0, POST: 1 };
12
+ exports.WEB2_VALUE_TYPE = {
13
+ uint256: 0,
14
+ int256: 1,
15
+ bool: 2,
16
+ string: 3,
17
+ bytes: 4,
18
+ };
19
+ /** Only IDENTICAL (quorum on identical bytes) exists in v1. */
20
+ const WEB2_MODE_IDENTICAL = 0;
21
+ const WEB2_ENVELOPE_ABI = [
22
+ {
23
+ type: 'tuple',
24
+ components: [
25
+ { name: 'method', type: 'uint8' },
26
+ { name: 'url', type: 'string' },
27
+ { name: 'headers', type: 'bytes' },
28
+ { name: 'body', type: 'bytes' },
29
+ { name: 'timeoutMs', type: 'uint64' },
30
+ {
31
+ name: 'extract',
32
+ type: 'tuple[]',
33
+ components: [
34
+ { name: 'path', type: 'string' },
35
+ { name: 'valueType', type: 'uint8' },
36
+ { name: 'mode', type: 'uint8' },
37
+ { name: 'decimals', type: 'uint8' },
38
+ ],
39
+ },
40
+ ],
41
+ },
42
+ ];
43
+ const SENSITIVE_HEADER = /auth|key|token|secret|bearer|cookie|session/i;
44
+ const NUMERIC = new Set(['uint256', 'int256']);
45
+ /**
46
+ * Deterministic JSON object bytes: keys sorted, no whitespace. The validator
47
+ * `json.Unmarshal`s into map[string]string, so ordering does not affect the read —
48
+ * canonicalising just keeps the on-chain envelope stable across SDK versions.
49
+ */
50
+ function canonicalizeHeaders(headers) {
51
+ const entries = Object.entries(headers ?? {});
52
+ if (entries.length === 0)
53
+ return (0, viem_1.stringToHex)('{}');
54
+ for (const [k, v] of entries) {
55
+ if (typeof v !== 'string')
56
+ throw new errors_1.InvalidReadQueryError(`header ${k} must be a string`);
57
+ }
58
+ const sorted = Object.fromEntries(entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)));
59
+ return (0, viem_1.stringToHex)(JSON.stringify(sorted));
60
+ }
61
+ function toBodyHex(body) {
62
+ if (body === undefined)
63
+ return '0x';
64
+ return typeof body === 'string' ? (0, viem_1.stringToHex)(body) : (0, viem_1.bytesToHex)(body);
65
+ }
66
+ function validateExtract(extract) {
67
+ if (!Array.isArray(extract) || extract.length === 0) {
68
+ throw new errors_1.InvalidReadQueryError('web2 query needs at least one extract entry');
69
+ }
70
+ if (extract.length > read_state_1.WEB2_MAX_EXTRACT_ENTRIES) {
71
+ throw new errors_1.InvalidReadQueryError(`web2 query has ${extract.length} extracts; max is ${read_state_1.WEB2_MAX_EXTRACT_ENTRIES}`);
72
+ }
73
+ extract.forEach((e, i) => {
74
+ if (!e.path || !e.path.startsWith('$')) {
75
+ throw new errors_1.InvalidReadQueryError(`extract[${i}].path must be a JSONPath starting with "$": ${e.path}`);
76
+ }
77
+ if (!(e.valueType in exports.WEB2_VALUE_TYPE)) {
78
+ throw new errors_1.InvalidReadQueryError(`extract[${i}].valueType unknown: ${String(e.valueType)}`);
79
+ }
80
+ if (e.decimals !== undefined) {
81
+ if (!NUMERIC.has(e.valueType)) {
82
+ throw new errors_1.InvalidReadQueryError(`extract[${i}].decimals only applies to uint256/int256`);
83
+ }
84
+ if (!Number.isInteger(e.decimals) || e.decimals < 0 || e.decimals > 255) {
85
+ throw new errors_1.InvalidReadQueryError(`extract[${i}].decimals must be an integer 0..255`);
86
+ }
87
+ }
88
+ });
89
+ }
90
+ /** Encode a `web2` read query. Pure. `blockRef` is always 0 (heightless namespace). */
91
+ function encodeWeb2QueryEnvelope(query) {
92
+ const method = query.method ?? 'GET';
93
+ if (method !== 'GET' && method !== 'POST')
94
+ throw new errors_1.InvalidReadQueryError(`unsupported method: ${String(method)}`);
95
+ if (!/^https:\/\/\S+$/i.test(query.url)) {
96
+ throw new errors_1.InvalidReadQueryError('web2 url must be https:// — validators refuse other schemes');
97
+ }
98
+ if (method === 'GET' && query.body !== undefined) {
99
+ throw new errors_1.InvalidReadQueryError('body is only allowed with POST');
100
+ }
101
+ const timeoutMs = query.timeoutMs ?? read_state_1.WEB2_DEFAULT_TIMEOUT_MS;
102
+ if (!Number.isInteger(timeoutMs) || timeoutMs <= 0)
103
+ throw new errors_1.InvalidReadQueryError('timeoutMs must be a positive integer');
104
+ validateExtract(query.extract);
105
+ const warnings = [];
106
+ for (const name of Object.keys(query.headers ?? {})) {
107
+ if (SENSITIVE_HEADER.test(name)) {
108
+ warnings.push(`header "${name}" looks sensitive and will be written to a PUBLIC event log forever`);
109
+ }
110
+ }
111
+ if (timeoutMs > read_state_1.WEB2_MAX_TIMEOUT_MS) {
112
+ warnings.push(`timeoutMs ${timeoutMs} exceeds the validator clamp of ${read_state_1.WEB2_MAX_TIMEOUT_MS}`);
113
+ }
114
+ const encoded = (0, viem_1.encodeAbiParameters)(WEB2_ENVELOPE_ABI, [
115
+ {
116
+ method: exports.WEB2_METHOD[method],
117
+ url: query.url,
118
+ headers: canonicalizeHeaders(query.headers),
119
+ body: toBodyHex(query.body),
120
+ timeoutMs: BigInt(timeoutMs),
121
+ extract: query.extract.map((e) => ({
122
+ path: e.path,
123
+ valueType: exports.WEB2_VALUE_TYPE[e.valueType],
124
+ mode: WEB2_MODE_IDENTICAL,
125
+ decimals: e.decimals ?? 0,
126
+ })),
127
+ },
128
+ ]);
129
+ return {
130
+ namespace: read_state_1.READ_NAMESPACE.WEB2,
131
+ queryType: exports.WEB2_METHOD[method],
132
+ encoded,
133
+ blockRef: 0n,
134
+ resultShape: { kind: 'web2', extract: query.extract },
135
+ warnings,
136
+ };
137
+ }
138
+ function decodeWeb2QueryEnvelope(encoded) {
139
+ const [env] = (0, viem_1.decodeAbiParameters)(WEB2_ENVELOPE_ABI, encoded);
140
+ return {
141
+ method: env.method,
142
+ url: env.url,
143
+ headers: env.headers === '0x' ? {} : JSON.parse((0, viem_1.hexToString)(env.headers)),
144
+ body: env.body,
145
+ timeoutMs: env.timeoutMs,
146
+ extract: env.extract.map((e) => ({ ...e })),
147
+ };
148
+ }
149
+ //# sourceMappingURL=web2.js.map
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Typed read-state errors.
3
+ *
4
+ * Every error carries a stable `code` so callers classify by `instanceof` or
5
+ * `err.code`, plus curated context and a remediation hint. Mirrors the PC20 error
6
+ * family (`orchestrator/internals/pc20/errors.ts`).
7
+ */
8
+ export type ReadStateErrorContext = {
9
+ /** Destination in CAIP-2 form, when relevant. */
10
+ destination?: string;
11
+ /** requestId (0x-prefixed hex), when relevant. */
12
+ requestId?: string;
13
+ /** Push tx hash, when relevant. */
14
+ txHash?: string;
15
+ /** Successfully mined requests from a partial non-atomic batch. */
16
+ transactionHashes?: `0x${string}`[];
17
+ /** Broadcast transaction whose receipt could not be confirmed. Check before retrying. */
18
+ pendingTransactionHash?: `0x${string}`;
19
+ /** Short, actionable remediation. */
20
+ hint?: string;
21
+ };
22
+ /** Base class for all read-state failures. `instanceof ReadStateError` catches the family. */
23
+ export declare class ReadStateError extends Error {
24
+ readonly code: string;
25
+ readonly destination?: string;
26
+ readonly requestId?: string;
27
+ readonly txHash?: string;
28
+ readonly transactionHashes?: `0x${string}`[];
29
+ readonly pendingTransactionHash?: `0x${string}`;
30
+ readonly hint?: string;
31
+ constructor(code: string, message: string, ctx?: ReadStateErrorContext);
32
+ }
33
+ /** The query itself is malformed (bad target, non-view ABI function, too many extracts, …). */
34
+ export declare class InvalidReadQueryError extends ReadStateError {
35
+ constructor(message: string, ctx?: ReadStateErrorContext);
36
+ }
37
+ /** Every contract precondition the SDK mirrors client-side. Names match `UniversalCallbackErrors`. */
38
+ export type ReadSpecViolation = 'INVALID_ACCOUNT_ID' | 'EMPTY_QUERY' | 'INVALID_MIN_CONFIRMATIONS' | 'DOMAIN_BLOCKED' | 'INVALID_BLOCK_NUMBER' | 'INVALID_EXPIRY_HEIGHT' | 'ZERO_REVERT_RECIPIENT' | 'ZERO_CALLBACK_GAS_LIMIT' | 'CALLBACK_GAS_LIMIT_EXCEEDED' | 'INSUFFICIENT_FEE' | 'EXCESSIVE_FEE' | 'ZERO_CALLBACK_BUDGET'
39
+ /** Node affordability gate: remaining escrow must cover declared gas at current base fee. */
40
+ | 'INSUFFICIENT_CALLBACK_BUDGET' | 'SVM_OWNER_NOT_32_BYTES';
41
+ /** A `ReadSpec` that `requestExternalReadSelf` would revert on. */
42
+ export declare class InvalidReadSpecError extends ReadStateError {
43
+ readonly violations: readonly ReadSpecViolation[];
44
+ constructor(violations: readonly ReadSpecViolation[], ctx?: ReadStateErrorContext);
45
+ }
46
+ /** The destination's oracle height is zero — it is not a configured chain. */
47
+ export declare class ReadHeightUnavailableError extends ReadStateError {
48
+ constructor(destination: string, ctx?: ReadStateErrorContext);
49
+ }
50
+ /** Destination is not one the read path can route (unknown namespace, or on-chain blacklist). */
51
+ export declare class UnsupportedReadDestinationError extends ReadStateError {
52
+ constructor(message: string, ctx?: ReadStateErrorContext);
53
+ }
54
+ /** `resultData` does not match the shape the query declared. Fails loud, never mis-decodes. */
55
+ export declare class ReadDecodeError extends ReadStateError {
56
+ constructor(message: string, ctx?: ReadStateErrorContext);
57
+ }
58
+ /** Client-side polling deadline hit before a terminal status. Carries the last status seen. */
59
+ export declare class ReadTimeoutError extends ReadStateError {
60
+ readonly lastStatus: number;
61
+ constructor(lastStatus: number, elapsedMs: number, ctx?: ReadStateErrorContext);
62
+ }
63
+ /** No `UniversalRead` record for the reference — not ingested yet, or the tx made no read. */
64
+ export declare class ReadNotFoundError extends ReadStateError {
65
+ constructor(ref: string, ctx?: ReadStateErrorContext);
66
+ }
67
+ /** No custom receiver was supplied and this network has no configured registry. */
68
+ export declare class ReadRegistryUnavailableError extends ReadStateError {
69
+ constructor(method: string, ctx?: ReadStateErrorContext);
70
+ }
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * Typed read-state errors.
4
+ *
5
+ * Every error carries a stable `code` so callers classify by `instanceof` or
6
+ * `err.code`, plus curated context and a remediation hint. Mirrors the PC20 error
7
+ * family (`orchestrator/internals/pc20/errors.ts`).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ReadRegistryUnavailableError = exports.ReadNotFoundError = exports.ReadTimeoutError = exports.ReadDecodeError = exports.UnsupportedReadDestinationError = exports.ReadHeightUnavailableError = exports.InvalidReadSpecError = exports.InvalidReadQueryError = exports.ReadStateError = void 0;
11
+ /** Base class for all read-state failures. `instanceof ReadStateError` catches the family. */
12
+ class ReadStateError extends Error {
13
+ code;
14
+ destination;
15
+ requestId;
16
+ txHash;
17
+ transactionHashes;
18
+ pendingTransactionHash;
19
+ hint;
20
+ constructor(code, message, ctx = {}) {
21
+ const parts = [message];
22
+ if (ctx.destination)
23
+ parts.push(`destination=${ctx.destination}`);
24
+ if (ctx.requestId)
25
+ parts.push(`requestId=${ctx.requestId}`);
26
+ if (ctx.txHash)
27
+ parts.push(`txHash=${ctx.txHash}`);
28
+ if (ctx.hint)
29
+ parts.push(`hint: ${ctx.hint}`);
30
+ super(parts.join(' | '));
31
+ this.name = new.target.name;
32
+ this.code = code;
33
+ this.destination = ctx.destination;
34
+ this.requestId = ctx.requestId;
35
+ this.txHash = ctx.txHash;
36
+ this.transactionHashes = ctx.transactionHashes ? [...ctx.transactionHashes] : undefined;
37
+ this.pendingTransactionHash = ctx.pendingTransactionHash;
38
+ this.hint = ctx.hint;
39
+ Object.setPrototypeOf(this, new.target.prototype);
40
+ }
41
+ }
42
+ exports.ReadStateError = ReadStateError;
43
+ /** The query itself is malformed (bad target, non-view ABI function, too many extracts, …). */
44
+ class InvalidReadQueryError extends ReadStateError {
45
+ constructor(message, ctx = {}) {
46
+ super('INVALID_READ_QUERY', message, ctx);
47
+ }
48
+ }
49
+ exports.InvalidReadQueryError = InvalidReadQueryError;
50
+ /** A `ReadSpec` that `requestExternalReadSelf` would revert on. */
51
+ class InvalidReadSpecError extends ReadStateError {
52
+ violations;
53
+ constructor(violations, ctx = {}) {
54
+ super('INVALID_READ_SPEC', `ReadSpec violates contract preconditions: ${violations.join(', ')}`, ctx);
55
+ this.violations = violations;
56
+ }
57
+ }
58
+ exports.InvalidReadSpecError = InvalidReadSpecError;
59
+ /** The destination's oracle height is zero — it is not a configured chain. */
60
+ class ReadHeightUnavailableError extends ReadStateError {
61
+ constructor(destination, ctx = {}) {
62
+ super('READ_HEIGHT_UNAVAILABLE', 'destination has no observed chain height on UniversalCore', {
63
+ destination,
64
+ hint: 'Only chains with a running chain-meta oracle can be read. Check the CAIP-2 id.',
65
+ ...ctx,
66
+ });
67
+ }
68
+ }
69
+ exports.ReadHeightUnavailableError = ReadHeightUnavailableError;
70
+ /** Destination is not one the read path can route (unknown namespace, or on-chain blacklist). */
71
+ class UnsupportedReadDestinationError extends ReadStateError {
72
+ constructor(message, ctx = {}) {
73
+ super('UNSUPPORTED_READ_DESTINATION', message, ctx);
74
+ }
75
+ }
76
+ exports.UnsupportedReadDestinationError = UnsupportedReadDestinationError;
77
+ /** `resultData` does not match the shape the query declared. Fails loud, never mis-decodes. */
78
+ class ReadDecodeError extends ReadStateError {
79
+ constructor(message, ctx = {}) {
80
+ super('READ_DECODE_FAILED', message, ctx);
81
+ }
82
+ }
83
+ exports.ReadDecodeError = ReadDecodeError;
84
+ /** Client-side polling deadline hit before a terminal status. Carries the last status seen. */
85
+ class ReadTimeoutError extends ReadStateError {
86
+ lastStatus;
87
+ constructor(lastStatus, elapsedMs, ctx = {}) {
88
+ super('READ_TIMEOUT', `read did not reach a terminal status within ${elapsedMs} ms (last status ${lastStatus})`, {
89
+ hint: 'The request may still complete on-chain — resume with trackRead.',
90
+ ...ctx,
91
+ });
92
+ this.lastStatus = lastStatus;
93
+ }
94
+ }
95
+ exports.ReadTimeoutError = ReadTimeoutError;
96
+ /** No `UniversalRead` record for the reference — not ingested yet, or the tx made no read. */
97
+ class ReadNotFoundError extends ReadStateError {
98
+ constructor(ref, ctx = {}) {
99
+ super('READ_NOT_FOUND', `no read record for ${ref}`, {
100
+ hint: 'A request is indexed once its block is processed; a tx with no ReadRequested log never gets one.',
101
+ ...ctx,
102
+ });
103
+ }
104
+ }
105
+ exports.ReadNotFoundError = ReadNotFoundError;
106
+ /** No custom receiver was supplied and this network has no configured registry. */
107
+ class ReadRegistryUnavailableError extends ReadStateError {
108
+ constructor(method, ctx = {}) {
109
+ super('READ_REGISTRY_UNAVAILABLE', `${method} needs the UniversalReadRegistry, which is not deployed on this network`, {
110
+ hint: 'Pass callback.target, gasLimit, abi and functionName (plus optional args) for your app contract.',
111
+ ...ctx,
112
+ });
113
+ }
114
+ }
115
+ exports.ReadRegistryUnavailableError = ReadRegistryUnavailableError;
116
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,13 @@
1
+ export * from './read-state.types';
2
+ export * from './errors';
3
+ export { resolveDestination } from './destination';
4
+ export * from './envelopes';
5
+ export { decodeReadResult } from './result-decoder';
6
+ export * from './read-events';
7
+ export { preflightRead } from './preflight';
8
+ export { sizeCallbackBudget, MIN_CALLBACK_BUDGET_GAS_PRICE } from './budget';
9
+ export { validateReadSpec, assertValidReadSpec } from './validate';
10
+ export { buildReadSpecFromPreflight, prepareRead, simulateRead, toCallData, type PrepareReadDeps } from './spec-builder';
11
+ export { trackRead, waitForRead, inferResultShape, toRequestIdHex, statusName, defaultWaitTimeoutMs, type TrackReadDeps, type ReadHookEmitter } from './read-tracker';
12
+ export { toBuildReadSpecParams, toReadQuery, toReadDestination, toLifecycleOptions, type ReadOptions, type ReadPrepareOptions, type ReadQueryOptions, type ReadCallbackOptions, type ReadValue, type ValidateReadCall, type ReadWeb2Options, type ReadTrackOptions } from './read-params';
13
+ export type { ReadExecuteOptions } from './read-params';
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toLifecycleOptions = exports.toReadDestination = exports.toReadQuery = exports.toBuildReadSpecParams = exports.defaultWaitTimeoutMs = exports.statusName = exports.toRequestIdHex = exports.inferResultShape = exports.waitForRead = exports.trackRead = exports.toCallData = exports.simulateRead = exports.prepareRead = exports.buildReadSpecFromPreflight = exports.assertValidReadSpec = exports.validateReadSpec = exports.MIN_CALLBACK_BUDGET_GAS_PRICE = exports.sizeCallbackBudget = exports.preflightRead = exports.decodeReadResult = exports.resolveDestination = void 0;
4
+ const tslib_1 = require("tslib");
5
+ tslib_1.__exportStar(require("./read-state.types"), exports);
6
+ tslib_1.__exportStar(require("./errors"), exports);
7
+ var destination_1 = require("./destination");
8
+ Object.defineProperty(exports, "resolveDestination", { enumerable: true, get: function () { return destination_1.resolveDestination; } });
9
+ tslib_1.__exportStar(require("./envelopes"), exports);
10
+ var result_decoder_1 = require("./result-decoder");
11
+ Object.defineProperty(exports, "decodeReadResult", { enumerable: true, get: function () { return result_decoder_1.decodeReadResult; } });
12
+ tslib_1.__exportStar(require("./read-events"), exports);
13
+ var preflight_1 = require("./preflight");
14
+ Object.defineProperty(exports, "preflightRead", { enumerable: true, get: function () { return preflight_1.preflightRead; } });
15
+ var budget_1 = require("./budget");
16
+ Object.defineProperty(exports, "sizeCallbackBudget", { enumerable: true, get: function () { return budget_1.sizeCallbackBudget; } });
17
+ Object.defineProperty(exports, "MIN_CALLBACK_BUDGET_GAS_PRICE", { enumerable: true, get: function () { return budget_1.MIN_CALLBACK_BUDGET_GAS_PRICE; } });
18
+ var validate_1 = require("./validate");
19
+ Object.defineProperty(exports, "validateReadSpec", { enumerable: true, get: function () { return validate_1.validateReadSpec; } });
20
+ Object.defineProperty(exports, "assertValidReadSpec", { enumerable: true, get: function () { return validate_1.assertValidReadSpec; } });
21
+ var spec_builder_1 = require("./spec-builder");
22
+ Object.defineProperty(exports, "buildReadSpecFromPreflight", { enumerable: true, get: function () { return spec_builder_1.buildReadSpecFromPreflight; } });
23
+ Object.defineProperty(exports, "prepareRead", { enumerable: true, get: function () { return spec_builder_1.prepareRead; } });
24
+ Object.defineProperty(exports, "simulateRead", { enumerable: true, get: function () { return spec_builder_1.simulateRead; } });
25
+ Object.defineProperty(exports, "toCallData", { enumerable: true, get: function () { return spec_builder_1.toCallData; } });
26
+ var read_tracker_1 = require("./read-tracker");
27
+ Object.defineProperty(exports, "trackRead", { enumerable: true, get: function () { return read_tracker_1.trackRead; } });
28
+ Object.defineProperty(exports, "waitForRead", { enumerable: true, get: function () { return read_tracker_1.waitForRead; } });
29
+ Object.defineProperty(exports, "inferResultShape", { enumerable: true, get: function () { return read_tracker_1.inferResultShape; } });
30
+ Object.defineProperty(exports, "toRequestIdHex", { enumerable: true, get: function () { return read_tracker_1.toRequestIdHex; } });
31
+ Object.defineProperty(exports, "statusName", { enumerable: true, get: function () { return read_tracker_1.statusName; } });
32
+ Object.defineProperty(exports, "defaultWaitTimeoutMs", { enumerable: true, get: function () { return read_tracker_1.defaultWaitTimeoutMs; } });
33
+ var read_params_1 = require("./read-params");
34
+ Object.defineProperty(exports, "toBuildReadSpecParams", { enumerable: true, get: function () { return read_params_1.toBuildReadSpecParams; } });
35
+ Object.defineProperty(exports, "toReadQuery", { enumerable: true, get: function () { return read_params_1.toReadQuery; } });
36
+ Object.defineProperty(exports, "toReadDestination", { enumerable: true, get: function () { return read_params_1.toReadDestination; } });
37
+ Object.defineProperty(exports, "toLifecycleOptions", { enumerable: true, get: function () { return read_params_1.toLifecycleOptions; } });
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,21 @@
1
+ import type { PUSH_NETWORK } from '../constants/enums';
2
+ import type { PushClient } from '../push-client/push-client';
3
+ import type { ReadDestination, ReadPreflight } from './read-state.types';
4
+ /** The slice of OrchestratorContext preflight needs — keeps it testable with a bare mock. */
5
+ export interface PreflightDeps {
6
+ pushClient: Pick<PushClient, 'readContract' | 'getGasPrice' | 'publicClient'>;
7
+ pushNetwork: PUSH_NETWORK;
8
+ }
9
+ /**
10
+ * Fetch the on-chain values a valid ReadSpec depends on. Four reads against Push Chain,
11
+ * none against the destination:
12
+ *
13
+ * UniversalCore.chainHeightByChainNamespace(caip2) → blockNumber ceiling
14
+ * UniversalCallback.estimateFee(ns, chainId) → protocol fee (msg.value floor)
15
+ * UniversalCallback.blockedDomains(ns, chainId) → fail fast on a blocklisted domain
16
+ * eth_blockNumber + eth_gasPrice → expiry + budget sizing
17
+ *
18
+ * The height is keyed by the FULL CAIP-2 id — the oracle writes it that way. Passing the
19
+ * bare namespace reads 0 and was the C1 blocker.
20
+ */
21
+ export declare function preflightRead(deps: PreflightDeps, destination: ReadDestination): Promise<ReadPreflight>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preflightRead = preflightRead;
4
+ const universalCallback_evm_1 = require("../constants/abi/universalCallback.evm");
5
+ const prc20_evm_1 = require("../constants/abi/prc20.evm");
6
+ const chain_1 = require("../constants/chain");
7
+ const read_state_1 = require("../constants/read-state");
8
+ const destination_1 = require("./destination");
9
+ const errors_1 = require("./errors");
10
+ /**
11
+ * Fetch the on-chain values a valid ReadSpec depends on. Four reads against Push Chain,
12
+ * none against the destination:
13
+ *
14
+ * UniversalCore.chainHeightByChainNamespace(caip2) → blockNumber ceiling
15
+ * UniversalCallback.estimateFee(ns, chainId) → protocol fee (msg.value floor)
16
+ * UniversalCallback.blockedDomains(ns, chainId) → fail fast on a blocklisted domain
17
+ * eth_blockNumber + eth_gasPrice → expiry + budget sizing
18
+ *
19
+ * The height is keyed by the FULL CAIP-2 id — the oracle writes it that way. Passing the
20
+ * bare namespace reads 0 and was the C1 blocker.
21
+ */
22
+ async function preflightRead(deps, destination) {
23
+ const dest = (0, destination_1.resolveDestination)(destination);
24
+ const universalCore = chain_1.UNIVERSAL_CORE_ADDRESSES[deps.pushNetwork];
25
+ const universalCallback = chain_1.UNIVERSAL_CALLBACK_ADDRESSES[deps.pushNetwork];
26
+ const { pushClient } = deps;
27
+ const [observedChainHeight, protocolFee, blocked, pushBlockNumber, pushGasPrice] = await Promise.all([
28
+ pushClient.readContract({
29
+ address: universalCore,
30
+ abi: prc20_evm_1.UNIVERSAL_CORE_EVM,
31
+ functionName: 'chainHeightByChainNamespace',
32
+ args: [dest.caip2],
33
+ }),
34
+ pushClient.readContract({
35
+ address: universalCallback,
36
+ abi: universalCallback_evm_1.UNIVERSAL_CALLBACK_EVM,
37
+ functionName: 'estimateFee',
38
+ args: [dest.chainNamespace, dest.chainId],
39
+ }),
40
+ pushClient.readContract({
41
+ address: universalCallback,
42
+ abi: universalCallback_evm_1.UNIVERSAL_CALLBACK_EVM,
43
+ functionName: 'blockedDomains',
44
+ args: [dest.chainNamespace, dest.chainId],
45
+ }),
46
+ pushClient.publicClient.getBlockNumber(),
47
+ pushClient.getGasPrice(),
48
+ ]);
49
+ if (blocked) {
50
+ throw new errors_1.UnsupportedReadDestinationError('destination is on the UniversalCallback blocklist', {
51
+ destination: dest.caip2,
52
+ });
53
+ }
54
+ // Heightless namespaces (web2) legitimately read 0 and must pin blockNumber = 0.
55
+ // For a blockchain, 0 means no chain-meta oracle is voting → the guard can never pass.
56
+ if (dest.namespace !== read_state_1.READ_NAMESPACE.WEB2 && observedChainHeight === 0n) {
57
+ throw new errors_1.ReadHeightUnavailableError(dest.caip2);
58
+ }
59
+ return {
60
+ destination: dest,
61
+ protocolFee,
62
+ observedChainHeight,
63
+ pushBlockNumber,
64
+ pushGasPrice,
65
+ universalCallback,
66
+ universalCore,
67
+ fetchedAt: Date.now(),
68
+ };
69
+ }
70
+ //# sourceMappingURL=preflight.js.map
@@ -0,0 +1,27 @@
1
+ import { type AbiEvent, type Address, type Hex } from 'viem';
2
+ import type { FulfilOutcome, ParsedReadRequest, ReceiptLike } from './read-state.types';
3
+ export declare const READ_REQUESTED_EVENT: AbiEvent;
4
+ export declare const READ_REQUESTED_TOPIC0: Hex;
5
+ export declare const READ_FULFILLED_TOPIC0: Hex;
6
+ export declare const CALLBACK_FAILED_TOPIC0: Hex;
7
+ export declare const CALLBACK_GAS_REPORTED_TOPIC0: Hex;
8
+ export declare const REFUND_SENT_TOPIC0: Hex;
9
+ export declare const REFUND_FAILED_TOPIC0: Hex;
10
+ export declare const REQUEST_EXPIRED_TOPIC0: Hex;
11
+ /**
12
+ * Every read a transaction requested, in log order.
13
+ *
14
+ * Filters on BOTH the contract address and topic0. The address filter is a security
15
+ * control (the node applies the same one in `ingest.go`): without it any contract
16
+ * can forge a matching log.
17
+ */
18
+ export declare function parseReadRequestsFromReceipt(receipt: ReceiptLike, universalCallback: Address): ParsedReadRequest[];
19
+ /**
20
+ * Read the fulfil / settle / expiry logs for ONE request out of a receipt.
21
+ *
22
+ * `FULFILLED` on the node does not mean the app callback ran: the contract swallows
23
+ * a reverting callback into `CallbackFailed`. This is where `callbackDelivered`
24
+ * comes from. Note: EndBlocker-driven expiry transactions are NOT EVM-indexed —
25
+ * `RequestExpired` will never be seen through a receipt; use the node record.
26
+ */
27
+ export declare function parseFulfilOutcome(receipt: ReceiptLike, universalCallback: Address, requestId: Hex): FulfilOutcome;