@pushchain/core 6.0.20 → 6.0.21

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 (111) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/package.json +1 -1
  3. package/src/lib/cache/cache.js +2 -0
  4. package/src/lib/constants/abi/index.d.ts +1 -0
  5. package/src/lib/constants/abi/index.js +8 -1
  6. package/src/lib/constants/abi/pc20.evm.d.ts +217 -0
  7. package/src/lib/constants/abi/pc20.evm.js +150 -0
  8. package/src/lib/constants/abi/prc20.evm.d.ts +172 -0
  9. package/src/lib/constants/abi/prc20.evm.js +97 -0
  10. package/src/lib/constants/abi/universalGatewayV0.json +1 -1
  11. package/src/lib/constants/chain.js +38 -8
  12. package/src/lib/constants/selectors.js +2 -2
  13. package/src/lib/constants/tokens.js +4 -3
  14. package/src/lib/formatters.js +16 -6
  15. package/src/lib/generated/uexecutor/v1/query.js +2 -4
  16. package/src/lib/generated/uexecutor/v1/types.d.ts +14 -0
  17. package/src/lib/generated/uexecutor/v1/types.js +90 -47
  18. package/src/lib/generated/uexecutor/v2/query.js +2 -4
  19. package/src/lib/generated/uexecutor/v2/types.d.ts +20 -0
  20. package/src/lib/generated/uexecutor/v2/types.js +49 -33
  21. package/src/lib/generated/v1/tx.js +30 -37
  22. package/src/lib/index.d.ts +3 -0
  23. package/src/lib/index.js +21 -3
  24. package/src/lib/internal/buffer.js +1 -2
  25. package/src/lib/orchestrator/cea-utils.js +73 -83
  26. package/src/lib/orchestrator/internals/account-manager.js +130 -139
  27. package/src/lib/orchestrator/internals/cascade.d.ts +0 -6
  28. package/src/lib/orchestrator/internals/cascade.js +1184 -1059
  29. package/src/lib/orchestrator/internals/confirmation.js +138 -148
  30. package/src/lib/orchestrator/internals/error-decoder.js +1 -1
  31. package/src/lib/orchestrator/internals/errors.js +12 -3
  32. package/src/lib/orchestrator/internals/execute-funds-only.d.ts +2 -2
  33. package/src/lib/orchestrator/internals/execute-funds-only.js +297 -259
  34. package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +2 -2
  35. package/src/lib/orchestrator/internals/execute-funds-payload.js +220 -220
  36. package/src/lib/orchestrator/internals/execute-standard.d.ts +0 -8
  37. package/src/lib/orchestrator/internals/execute-standard.js +339 -342
  38. package/src/lib/orchestrator/internals/gas-calculator.js +497 -520
  39. package/src/lib/orchestrator/internals/gas-usd-sizer.js +101 -110
  40. package/src/lib/orchestrator/internals/gateway-client.js +102 -103
  41. package/src/lib/orchestrator/internals/helpers.js +30 -27
  42. package/src/lib/orchestrator/internals/inbound-tracker.js +234 -238
  43. package/src/lib/orchestrator/internals/outbound-sync.js +463 -452
  44. package/src/lib/orchestrator/internals/outbound-tracker.js +27 -34
  45. package/src/lib/orchestrator/internals/payload-builder.d.ts +2 -2
  46. package/src/lib/orchestrator/internals/payload-builder.js +119 -100
  47. package/src/lib/orchestrator/internals/pc-usd-oracle.js +121 -129
  48. package/src/lib/orchestrator/internals/pc20/address-codec.d.ts +31 -0
  49. package/src/lib/orchestrator/internals/pc20/address-codec.js +124 -0
  50. package/src/lib/orchestrator/internals/pc20/chain-namespace.d.ts +68 -0
  51. package/src/lib/orchestrator/internals/pc20/chain-namespace.js +136 -0
  52. package/src/lib/orchestrator/internals/pc20/errors.d.ts +160 -0
  53. package/src/lib/orchestrator/internals/pc20/errors.js +236 -0
  54. package/src/lib/orchestrator/internals/pc20/export.d.ts +172 -0
  55. package/src/lib/orchestrator/internals/pc20/export.js +412 -0
  56. package/src/lib/orchestrator/internals/pc20/gate.d.ts +67 -0
  57. package/src/lib/orchestrator/internals/pc20/gate.js +184 -0
  58. package/src/lib/orchestrator/internals/pc20/resolver.d.ts +187 -0
  59. package/src/lib/orchestrator/internals/pc20/resolver.js +658 -0
  60. package/src/lib/orchestrator/internals/pc20/svm.d.ts +189 -0
  61. package/src/lib/orchestrator/internals/pc20/svm.js +286 -0
  62. package/src/lib/orchestrator/internals/pc20/tracking.d.ts +46 -0
  63. package/src/lib/orchestrator/internals/pc20/tracking.js +109 -0
  64. package/src/lib/orchestrator/internals/preflight.js +1 -1
  65. package/src/lib/orchestrator/internals/progress-route-hooks.js +2 -2
  66. package/src/lib/orchestrator/internals/push-chain-tx.js +319 -329
  67. package/src/lib/orchestrator/internals/quote.js +90 -94
  68. package/src/lib/orchestrator/internals/rescue.js +76 -79
  69. package/src/lib/orchestrator/internals/response-builder.d.ts +28 -1
  70. package/src/lib/orchestrator/internals/response-builder.js +817 -701
  71. package/src/lib/orchestrator/internals/route-handlers.d.ts +7 -15
  72. package/src/lib/orchestrator/internals/route-handlers.js +1512 -1178
  73. package/src/lib/orchestrator/internals/signing.js +78 -83
  74. package/src/lib/orchestrator/internals/svm-bridge.d.ts +2 -2
  75. package/src/lib/orchestrator/internals/svm-bridge.js +161 -93
  76. package/src/lib/orchestrator/internals/svm-helpers.d.ts +15 -1
  77. package/src/lib/orchestrator/internals/svm-helpers.js +68 -24
  78. package/src/lib/orchestrator/internals/svm-rent.d.ts +19 -1
  79. package/src/lib/orchestrator/internals/svm-rent.js +163 -141
  80. package/src/lib/orchestrator/internals/tx-transformer.js +26 -23
  81. package/src/lib/orchestrator/internals/uea-manager.js +89 -86
  82. package/src/lib/orchestrator/max-pc-for-gas.js +5 -6
  83. package/src/lib/orchestrator/orchestrator.js +217 -200
  84. package/src/lib/orchestrator/orchestrator.types.d.ts +121 -1
  85. package/src/lib/orchestrator/orchestrator.types.js +19 -0
  86. package/src/lib/orchestrator/payload-builders.d.ts +2 -2
  87. package/src/lib/orchestrator/payload-builders.js +26 -24
  88. package/src/lib/orchestrator/route-detector.js +26 -9
  89. package/src/lib/orchestrator/svm-idl/ix-encoder.js +1 -2
  90. package/src/lib/orchestrator/svm-idl/normalize-address.js +2 -2
  91. package/src/lib/orchestrator/svm-idl/resolve.js +1 -2
  92. package/src/lib/price-fetch/price-fetch.js +67 -68
  93. package/src/lib/progress-hook/progress-hook.js +124 -72
  94. package/src/lib/push-chain/push-chain.js +171 -153
  95. package/src/lib/push-client/push-client.js +223 -237
  96. package/src/lib/universal/account/account.js +349 -365
  97. package/src/lib/universal/signer/signer.js +306 -294
  98. package/src/lib/universal-tx-detector/auto-detect.js +55 -60
  99. package/src/lib/universal-tx-detector/cascade.js +160 -172
  100. package/src/lib/universal-tx-detector/child-inbounds.js +67 -75
  101. package/src/lib/universal-tx-detector/classify.js +2 -3
  102. package/src/lib/universal-tx-detector/detector-svm.js +139 -147
  103. package/src/lib/universal-tx-detector/detector.js +145 -157
  104. package/src/lib/universal-tx-detector/normalize.js +7 -7
  105. package/src/lib/utils/external-tx-hash.js +1 -2
  106. package/src/lib/utils.d.ts +44 -0
  107. package/src/lib/utils.js +762 -683
  108. package/src/lib/vm-client/evm-client.js +186 -202
  109. package/src/lib/vm-client/svm-client.d.ts +1 -1
  110. package/src/lib/vm-client/svm-client.js +220 -224
  111. package/src/lib/vm-client/vm-client.types.d.ts +14 -2
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PushClient = void 0;
4
- const tslib_1 = require("tslib");
5
4
  const viem_1 = require("viem");
6
5
  const tx_1 = require("../generated/v1/tx");
7
6
  const tx_2 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
@@ -26,18 +25,33 @@ function pushNetworkToChain(network) {
26
25
  return enums_1.CHAIN.PUSH_LOCALNET;
27
26
  }
28
27
  class PushClient extends evm_client_1.EvmClient {
28
+ /** Gas limit for Cosmos transactions on Push Chain */
29
+ static COSMOS_GAS_LIMIT = 100000000000;
30
+ pushChainInfo;
31
+ ephemeralKey;
32
+ ephemeralAccount;
33
+ currentRpcIndex = 0;
34
+ /**
35
+ * Archive (full-history) endpoints. History-sensitive reads fall back from
36
+ * the prune RPC to these on a pruned-history miss. Resolved from the chain's
37
+ * configured archive endpoints — empty/undefined for chains without one
38
+ * (mainnet/localnet), where the fallback is a no-op (prune-only behaviour).
39
+ */
40
+ archiveTendermintRpc;
41
+ archivePublicClient;
29
42
  constructor(clientOptions) {
30
- var _a, _b, _c;
31
43
  const pushChainKey = pushNetworkToChain(clientOptions.network);
32
- const chain = (_a = clientOptions.chain) !== null && _a !== void 0 ? _a : (0, chain_1.getPushViemChain)(pushChainKey);
33
- super(Object.assign(Object.assign({}, clientOptions), { chain }));
34
- this.currentRpcIndex = 0;
44
+ const chain = clientOptions.chain ?? (0, chain_1.getPushViemChain)(pushChainKey);
45
+ super({
46
+ ...clientOptions,
47
+ chain,
48
+ });
35
49
  this.pushChainInfo = chain_1.PUSH_CHAIN_INFO[pushChainKey];
36
50
  // Archive fallback is always set up; it's inert for chains without an
37
51
  // archive endpoint (mainnet/localnet → empty lists), and otherwise lets
38
52
  // history-sensitive reads recover a pruned tx from the archive node.
39
- this.archiveTendermintRpc = (_b = this.pushChainInfo.archiveTendermintRpc) !== null && _b !== void 0 ? _b : [];
40
- const archiveEvmUrls = (_c = chain_1.CHAIN_INFO[pushChainKey].archiveRPC) !== null && _c !== void 0 ? _c : [];
53
+ this.archiveTendermintRpc = this.pushChainInfo.archiveTendermintRpc ?? [];
54
+ const archiveEvmUrls = chain_1.CHAIN_INFO[pushChainKey].archiveRPC ?? [];
41
55
  if (archiveEvmUrls.length > 0) {
42
56
  this.archivePublicClient = (0, viem_1.createPublicClient)({
43
57
  chain,
@@ -51,58 +65,55 @@ class PushClient extends evm_client_1.EvmClient {
51
65
  * Executes an operation with automatic fallback to next RPC endpoint on failure.
52
66
  * Follows the same pattern as SvmClient.executeWithFallback().
53
67
  */
54
- executeWithRpcFallback(operation_1) {
55
- return tslib_1.__awaiter(this, arguments, void 0, function* (operation, operationName = 'operation', rpcUrls = this.pushChainInfo.tendermintRpc,
56
- // Sticky cursor (`currentRpcIndex`) is only meaningful for the primary
57
- // prune pool; the archive pass passes `sticky=false` so a single archive
58
- // URL can't pin the prune cursor.
59
- sticky = true) {
60
- let lastError = null;
61
- // Cycle the RPC URLs, but also RETRY transient failures (5xx / network /
62
- // "HTTP request failed") with backoff — otherwise a single 502 on a
63
- // single-endpoint chain (e.g. Donut) aborts a tx mid status-poll. Total
64
- // attempts = urls × (RETRIES_PER_URL + 1).
65
- const RETRIES_PER_URL = 4;
66
- const totalAttempts = rpcUrls.length * (RETRIES_PER_URL + 1);
67
- const isTransient = (e) => {
68
- var _a;
69
- const m = `${(_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : ''}`.toLowerCase();
70
- return (/\b(502|503|504|429)\b/.test(m) ||
71
- m.includes('http request failed') ||
72
- m.includes('server error') ||
73
- m.includes('timeout') ||
74
- m.includes('timed out') ||
75
- m.includes('econnreset') ||
76
- m.includes('socket hang up') ||
77
- m.includes('fetch failed'));
78
- };
79
- for (let attempt = 0; attempt < totalAttempts; attempt++) {
80
- const baseIndex = sticky ? this.currentRpcIndex : 0;
81
- const rpcIndex = (baseIndex + attempt) % rpcUrls.length;
82
- const rpcUrl = rpcUrls[rpcIndex];
83
- try {
84
- const result = yield operation(rpcUrl);
85
- if (sticky && rpcIndex !== this.currentRpcIndex) {
86
- this.currentRpcIndex = rpcIndex;
87
- }
88
- return result;
68
+ async executeWithRpcFallback(operation, operationName = 'operation', rpcUrls = this.pushChainInfo.tendermintRpc,
69
+ // Sticky cursor (`currentRpcIndex`) is only meaningful for the primary
70
+ // prune pool; the archive pass passes `sticky=false` so a single archive
71
+ // URL can't pin the prune cursor.
72
+ sticky = true) {
73
+ let lastError = null;
74
+ // Cycle the RPC URLs, but also RETRY transient failures (5xx / network /
75
+ // "HTTP request failed") with backoff — otherwise a single 502 on a
76
+ // single-endpoint chain (e.g. Donut) aborts a tx mid status-poll. Total
77
+ // attempts = urls × (RETRIES_PER_URL + 1).
78
+ const RETRIES_PER_URL = 4;
79
+ const totalAttempts = rpcUrls.length * (RETRIES_PER_URL + 1);
80
+ const isTransient = (e) => {
81
+ const m = `${e?.message ?? ''}`.toLowerCase();
82
+ return (/\b(502|503|504|429)\b/.test(m) ||
83
+ m.includes('http request failed') ||
84
+ m.includes('server error') ||
85
+ m.includes('timeout') ||
86
+ m.includes('timed out') ||
87
+ m.includes('econnreset') ||
88
+ m.includes('socket hang up') ||
89
+ m.includes('fetch failed'));
90
+ };
91
+ for (let attempt = 0; attempt < totalAttempts; attempt++) {
92
+ const baseIndex = sticky ? this.currentRpcIndex : 0;
93
+ const rpcIndex = (baseIndex + attempt) % rpcUrls.length;
94
+ const rpcUrl = rpcUrls[rpcIndex];
95
+ try {
96
+ const result = await operation(rpcUrl);
97
+ if (sticky && rpcIndex !== this.currentRpcIndex) {
98
+ this.currentRpcIndex = rpcIndex;
89
99
  }
90
- catch (error) {
91
- lastError = error;
92
- if (attempt === totalAttempts - 1) {
93
- break;
94
- }
95
- // Non-transient errors: move to the next URL quickly. Transient ones:
96
- // back off (200ms → 400 → 800 …, capped) so a flaky RPC can recover.
97
- const cycle = Math.floor(attempt / rpcUrls.length);
98
- const delay = isTransient(lastError)
99
- ? Math.min(2000, 200 * Math.pow(2, cycle))
100
- : 100;
101
- yield new Promise((resolve) => setTimeout(resolve, delay));
100
+ return result;
101
+ }
102
+ catch (error) {
103
+ lastError = error;
104
+ if (attempt === totalAttempts - 1) {
105
+ break;
102
106
  }
107
+ // Non-transient errors: move to the next URL quickly. Transient ones:
108
+ // back off (200ms → 400 → 800 …, capped) so a flaky RPC can recover.
109
+ const cycle = Math.floor(attempt / rpcUrls.length);
110
+ const delay = isTransient(lastError)
111
+ ? Math.min(2000, 200 * 2 ** cycle)
112
+ : 100;
113
+ await new Promise((resolve) => setTimeout(resolve, delay));
103
114
  }
104
- throw new Error(`All RPC endpoints failed for ${operationName}. Last error: ${lastError === null || lastError === void 0 ? void 0 : lastError.message}`);
105
- });
115
+ }
116
+ throw new Error(`All RPC endpoints failed for ${operationName}. Last error: ${lastError?.message}`);
106
117
  }
107
118
  /**
108
119
  * Runs a history-sensitive Tendermint operation over the prune pool first and,
@@ -116,30 +127,28 @@ class PushClient extends evm_client_1.EvmClient {
116
127
  * off) this is a pass-through: the original throw or empty result is returned
117
128
  * unchanged — behaviour identical to before.
118
129
  */
119
- executeWithArchiveFallback(operation, operationName, isEmpty) {
120
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
121
- let pruneResult;
122
- let pruneError;
123
- try {
124
- pruneResult = yield this.executeWithRpcFallback(operation, operationName);
125
- }
126
- catch (error) {
127
- pruneError = error;
128
- }
129
- const pruneMissed = pruneError !== undefined ||
130
- (pruneResult !== undefined && isEmpty(pruneResult));
131
- if (!pruneMissed) {
132
- return pruneResult;
133
- }
134
- if (this.archiveTendermintRpc.length === 0) {
135
- // No archive: preserve original behaviour (re-throw, or return empty).
136
- if (pruneError !== undefined)
137
- throw pruneError;
138
- return pruneResult;
139
- }
140
- // Prune missed + archive available → re-query archive (non-sticky).
141
- return this.executeWithRpcFallback(operation, `${operationName} (archive)`, this.archiveTendermintRpc, false);
142
- });
130
+ async executeWithArchiveFallback(operation, operationName, isEmpty) {
131
+ let pruneResult;
132
+ let pruneError;
133
+ try {
134
+ pruneResult = await this.executeWithRpcFallback(operation, operationName);
135
+ }
136
+ catch (error) {
137
+ pruneError = error;
138
+ }
139
+ const pruneMissed = pruneError !== undefined ||
140
+ (pruneResult !== undefined && isEmpty(pruneResult));
141
+ if (!pruneMissed) {
142
+ return pruneResult;
143
+ }
144
+ if (this.archiveTendermintRpc.length === 0) {
145
+ // No archive: preserve original behaviour (re-throw, or return empty).
146
+ if (pruneError !== undefined)
147
+ throw pruneError;
148
+ return pruneResult;
149
+ }
150
+ // Prune missed + archive available → re-query archive (non-sticky).
151
+ return this.executeWithRpcFallback(operation, `${operationName} (archive)`, this.archiveTendermintRpc, false);
143
152
  }
144
153
  /** True when this client has a usable archive EVM endpoint configured. */
145
154
  get hasArchiveEvm() {
@@ -185,10 +194,8 @@ class PushClient extends evm_client_1.EvmClient {
185
194
  };
186
195
  }
187
196
  // --- Tx Builder ---
188
- createCosmosTxBody(messages, memo) {
189
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
190
- return tx_2.TxBody.fromPartial({ messages, memo });
191
- });
197
+ async createCosmosTxBody(messages, memo) {
198
+ return tx_2.TxBody.fromPartial({ messages, memo });
192
199
  }
193
200
  // --- Tx Signer ---
194
201
  getSignerAddress() {
@@ -201,124 +208,114 @@ class PushClient extends evm_client_1.EvmClient {
201
208
  * Signs a Cosmos tx using a temporary account.
202
209
  * In prod, signer should be passed in instead.
203
210
  */
204
- signCosmosTx(txBody) {
205
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
206
- const sender = (0, encoding_1.toBech32)(this.pushChainInfo.prefix, (0, viem_1.hexToBytes)(this.ephemeralAccount.address));
207
- return this.executeWithRpcFallback((rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
208
- const tmClient = yield tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
209
- const status = yield tmClient.status();
210
- const chainId = status.nodeInfo.network;
211
- const queryClient = stargate_1.QueryClient.withExtensions(tmClient, stargate_1.setupAuthExtension);
212
- let baseAccount = null;
213
- try {
214
- const accountResp = yield queryClient.auth.account(sender);
215
- baseAccount = auth_1.BaseAccount.decode(accountResp.value);
216
- }
217
- catch (err) {
218
- // Account may not exist on-chain yet; default to sequence=0 / accountNumber=0
219
- const msg = err instanceof Error ? err.message : String(err);
220
- if (!msg.includes('NotFound') && !msg.includes('not found')) {
221
- console.warn(`[PushClient:signCosmosTx] Account lookup failed for ${sender}:`, err);
222
- }
211
+ async signCosmosTx(txBody) {
212
+ const sender = (0, encoding_1.toBech32)(this.pushChainInfo.prefix, (0, viem_1.hexToBytes)(this.ephemeralAccount.address));
213
+ return this.executeWithRpcFallback(async (rpcUrl) => {
214
+ const tmClient = await tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
215
+ const status = await tmClient.status();
216
+ const chainId = status.nodeInfo.network;
217
+ const queryClient = stargate_1.QueryClient.withExtensions(tmClient, stargate_1.setupAuthExtension);
218
+ let baseAccount = null;
219
+ try {
220
+ const accountResp = await queryClient.auth.account(sender);
221
+ baseAccount = auth_1.BaseAccount.decode(accountResp.value);
222
+ }
223
+ catch (err) {
224
+ // Account may not exist on-chain yet; default to sequence=0 / accountNumber=0
225
+ const msg = err instanceof Error ? err.message : String(err);
226
+ if (!msg.includes('NotFound') && !msg.includes('not found')) {
227
+ console.warn(`[PushClient:signCosmosTx] Account lookup failed for ${sender}:`, err);
223
228
  }
224
- // 📦 Encode pubkey
225
- const uncompressedPubKey = (0, viem_1.hexToBytes)(this.ephemeralAccount.publicKey);
226
- const compressedPubKey = crypto_1.Secp256k1.compressPubkey(uncompressedPubKey);
227
- // Manual protobuf encode: field 1 (tag=10), length-delimited bytes
228
- const keyLen = compressedPubKey.length;
229
- const pubkeyValue = new Uint8Array(2 + keyLen);
230
- pubkeyValue[0] = 10; // field 1, wire type 2 (length-delimited)
231
- pubkeyValue[1] = keyLen;
232
- pubkeyValue.set(compressedPubKey, 2);
233
- const pubkeyEncoded = {
234
- typeUrl: '/cosmos.evm.crypto.v1.ethsecp256k1.PubKey',
235
- value: pubkeyValue,
236
- };
237
- const authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([
238
- {
239
- pubkey: pubkeyEncoded,
240
- sequence: baseAccount ? Number(baseAccount.sequence) : 0,
241
- },
242
- ], [], PushClient.COSMOS_GAS_LIMIT, undefined, undefined);
243
- const txBodyBytes = tx_2.TxBody.encode(txBody).finish();
244
- const signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, baseAccount ? Number(baseAccount.accountNumber) : 0);
245
- const digest = (0, viem_1.keccak256)(tx_2.SignDoc.encode(signDoc).finish());
246
- const signature = yield this.ephemeralAccount.sign({ hash: digest });
247
- return tx_2.TxRaw.fromPartial({
248
- bodyBytes: txBodyBytes,
249
- authInfoBytes,
250
- signatures: [(0, viem_1.hexToBytes)(signature)],
251
- });
252
- }), 'signCosmosTx');
253
- });
229
+ }
230
+ // 📦 Encode pubkey
231
+ const uncompressedPubKey = (0, viem_1.hexToBytes)(this.ephemeralAccount.publicKey);
232
+ const compressedPubKey = crypto_1.Secp256k1.compressPubkey(uncompressedPubKey);
233
+ // Manual protobuf encode: field 1 (tag=10), length-delimited bytes
234
+ const keyLen = compressedPubKey.length;
235
+ const pubkeyValue = new Uint8Array(2 + keyLen);
236
+ pubkeyValue[0] = 10; // field 1, wire type 2 (length-delimited)
237
+ pubkeyValue[1] = keyLen;
238
+ pubkeyValue.set(compressedPubKey, 2);
239
+ const pubkeyEncoded = {
240
+ typeUrl: '/cosmos.evm.crypto.v1.ethsecp256k1.PubKey',
241
+ value: pubkeyValue,
242
+ };
243
+ const authInfoBytes = (0, proto_signing_1.makeAuthInfoBytes)([
244
+ {
245
+ pubkey: pubkeyEncoded,
246
+ sequence: baseAccount ? Number(baseAccount.sequence) : 0,
247
+ },
248
+ ], [], PushClient.COSMOS_GAS_LIMIT, undefined, undefined);
249
+ const txBodyBytes = tx_2.TxBody.encode(txBody).finish();
250
+ const signDoc = (0, proto_signing_1.makeSignDoc)(txBodyBytes, authInfoBytes, chainId, baseAccount ? Number(baseAccount.accountNumber) : 0);
251
+ const digest = (0, viem_1.keccak256)(tx_2.SignDoc.encode(signDoc).finish());
252
+ const signature = await this.ephemeralAccount.sign({ hash: digest });
253
+ return tx_2.TxRaw.fromPartial({
254
+ bodyBytes: txBodyBytes,
255
+ authInfoBytes,
256
+ signatures: [(0, viem_1.hexToBytes)(signature)],
257
+ });
258
+ }, 'signCosmosTx');
254
259
  }
255
- broadcastCosmosTx(txRaw) {
256
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
257
- return this.executeWithRpcFallback((rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
258
- const client = yield stargate_1.StargateClient.connect(rpcUrl);
259
- return client.broadcastTx(tx_2.TxRaw.encode(txRaw).finish());
260
- }), 'broadcastCosmosTx');
261
- });
260
+ async broadcastCosmosTx(txRaw) {
261
+ return this.executeWithRpcFallback(async (rpcUrl) => {
262
+ const client = await stargate_1.StargateClient.connect(rpcUrl);
263
+ return client.broadcastTx(tx_2.TxRaw.encode(txRaw).finish());
264
+ }, 'broadcastCosmosTx');
262
265
  }
263
266
  /**
264
267
  * Queries Push Chain's uexecutor gRPC service for a UniversalTx by its ID.
265
268
  */
266
- getUniversalTxById(id) {
267
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
268
- return this.executeWithRpcFallback((rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
269
- const tmClient = yield tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
270
- const queryClient = new stargate_1.QueryClient(tmClient);
271
- const rpc = (0, stargate_1.createProtobufRpcClient)(queryClient);
272
- const request = query_1.QueryGetUniversalTxRequest.fromPartial({ id });
273
- const responseBytes = yield rpc.request('uexecutor.v1.Query', 'GetUniversalTx', query_1.QueryGetUniversalTxRequest.encode(request).finish());
274
- return query_1.QueryGetUniversalTxResponse.decode(responseBytes);
275
- }), 'getUniversalTxById');
276
- });
269
+ async getUniversalTxById(id) {
270
+ return this.executeWithRpcFallback(async (rpcUrl) => {
271
+ const tmClient = await tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
272
+ const queryClient = new stargate_1.QueryClient(tmClient);
273
+ const rpc = (0, stargate_1.createProtobufRpcClient)(queryClient);
274
+ const request = query_1.QueryGetUniversalTxRequest.fromPartial({ id });
275
+ const responseBytes = await rpc.request('uexecutor.v1.Query', 'GetUniversalTx', query_1.QueryGetUniversalTxRequest.encode(request).finish());
276
+ return query_1.QueryGetUniversalTxResponse.decode(responseBytes);
277
+ }, 'getUniversalTxById');
277
278
  }
278
279
  /**
279
280
  * Queries Push Chain's uexecutor v2 gRPC service for a UniversalTx by its ID.
280
281
  * V2 returns expanded OutboundTx fields and repeated outbound_tx array.
281
282
  */
282
- getUniversalTxByIdV2(id) {
283
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
284
- const operation = (rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
285
- const tmClient = yield tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
286
- const queryClient = new stargate_1.QueryClient(tmClient);
287
- const rpc = (0, stargate_1.createProtobufRpcClient)(queryClient);
288
- const request = query_2.QueryGetUniversalTxRequestV2.fromPartial({ id });
289
- const responseBytes = yield rpc.request('uexecutor.v2.Query', 'GetUniversalTx', query_2.QueryGetUniversalTxRequestV2.encode(request).finish());
290
- return query_2.QueryGetUniversalTxResponseV2.decode(responseBytes);
291
- });
292
- // This is a current-STATE query (abci_query), so prune is always
293
- // authoritative — an empty `universalTx` is a real "doesn't exist", not a
294
- // pruned-history miss. Only fall back to archive on a hard error (all prune
295
- // attempts failed); never on an empty result (would double-load on polls).
296
- try {
297
- return yield this.executeWithRpcFallback(operation, 'getUniversalTxByIdV2');
298
- }
299
- catch (error) {
300
- if (this.archiveTendermintRpc.length === 0)
301
- throw error;
302
- return this.executeWithRpcFallback(operation, 'getUniversalTxByIdV2 (archive)', this.archiveTendermintRpc, false);
303
- }
304
- });
283
+ async getUniversalTxByIdV2(id) {
284
+ const operation = async (rpcUrl) => {
285
+ const tmClient = await tendermint_rpc_1.Tendermint34Client.connect(rpcUrl);
286
+ const queryClient = new stargate_1.QueryClient(tmClient);
287
+ const rpc = (0, stargate_1.createProtobufRpcClient)(queryClient);
288
+ const request = query_2.QueryGetUniversalTxRequestV2.fromPartial({ id });
289
+ const responseBytes = await rpc.request('uexecutor.v2.Query', 'GetUniversalTx', query_2.QueryGetUniversalTxRequestV2.encode(request).finish());
290
+ return query_2.QueryGetUniversalTxResponseV2.decode(responseBytes);
291
+ };
292
+ // This is a current-STATE query (abci_query), so prune is always
293
+ // authoritative — an empty `universalTx` is a real "doesn't exist", not a
294
+ // pruned-history miss. Only fall back to archive on a hard error (all prune
295
+ // attempts failed); never on an empty result (would double-load on polls).
296
+ try {
297
+ return await this.executeWithRpcFallback(operation, 'getUniversalTxByIdV2');
298
+ }
299
+ catch (error) {
300
+ if (this.archiveTendermintRpc.length === 0)
301
+ throw error;
302
+ return this.executeWithRpcFallback(operation, 'getUniversalTxByIdV2 (archive)', this.archiveTendermintRpc, false);
303
+ }
305
304
  }
306
305
  /**
307
306
  * Generic Cosmos searchTx — returns the raw indexed results so callers can
308
307
  * walk events themselves. Used by the inbound-tracker to find a child UTX
309
308
  * created from an external tx hash (`universal_tx_created.inbound_tx_hash`).
310
309
  */
311
- searchCosmosByQuery(query) {
312
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
313
- const operation = (rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
314
- const client = yield stargate_1.StargateClient.connect(rpcUrl);
315
- const results = yield client.searchTx(query);
316
- return results.map((result) => JSON.parse(JSON.stringify(result, (_key, value) => typeof value === 'bigint' ? value.toString() : value)));
317
- });
318
- // History-sensitive (tx_search): an empty result on prune may just mean the
319
- // matching tx is outside the prune window → retry archive.
320
- return this.executeWithArchiveFallback(operation, 'searchCosmosByQuery', (results) => results.length === 0);
321
- });
310
+ async searchCosmosByQuery(query) {
311
+ const operation = async (rpcUrl) => {
312
+ const client = await stargate_1.StargateClient.connect(rpcUrl);
313
+ const results = await client.searchTx(query);
314
+ return results.map((result) => JSON.parse(JSON.stringify(result, (_key, value) => typeof value === 'bigint' ? value.toString() : value)));
315
+ };
316
+ // History-sensitive (tx_search): an empty result on prune may just mean the
317
+ // matching tx is outside the prune window → retry archive.
318
+ return this.executeWithArchiveFallback(operation, 'searchCosmosByQuery', (results) => results.length === 0);
322
319
  }
323
320
  /**
324
321
  * Fetches a Cosmos transaction by its hash.
@@ -326,71 +323,60 @@ class PushClient extends evm_client_1.EvmClient {
326
323
  * @returns The indexed transaction (height, logs, events, etc.).
327
324
  * @throws If the tx isn't found.
328
325
  */
329
- getCosmosTx(txHash) {
330
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
331
- const operation = (rpcUrl) => tslib_1.__awaiter(this, void 0, void 0, function* () {
332
- const client = yield stargate_1.StargateClient.connect(rpcUrl);
333
- const query = `ethereum_tx.ethereumTxHash='${txHash}'`;
334
- const results = yield client.searchTx(query);
335
- // Convert bigint values to strings in the results. This is done to avoid JSON.stringify()
336
- // from converting bigint to string when on the client side.
337
- // On documentation, one thing very common was to use JSON.stringify() to log the results, then we would get an error.
338
- const convertedResults = results.map((result) => JSON.parse(JSON.stringify(result, (key, value) => typeof value === 'bigint' ? value.toString() : value)));
339
- if (convertedResults.length === 0) {
340
- throw new Error(`No Cosmos-indexed tx for EVM hash ${txHash}`);
341
- }
342
- return Object.assign(Object.assign({}, convertedResults[0]), { transactionHash: txHash });
343
- });
344
- // History-sensitive (tx_search). The op throws on an empty result, so the
345
- // pruned-history miss surfaces as a thrown error — `isEmpty` stays false and
346
- // the wrapper retries archive via its caught-error path.
347
- return this.executeWithArchiveFallback(operation, 'getCosmosTx', () => false);
348
- });
326
+ async getCosmosTx(txHash) {
327
+ const operation = async (rpcUrl) => {
328
+ const client = await stargate_1.StargateClient.connect(rpcUrl);
329
+ const query = `ethereum_tx.ethereumTxHash='${txHash}'`;
330
+ const results = await client.searchTx(query);
331
+ // Convert bigint values to strings in the results. This is done to avoid JSON.stringify()
332
+ // from converting bigint to string when on the client side.
333
+ // On documentation, one thing very common was to use JSON.stringify() to log the results, then we would get an error.
334
+ const convertedResults = results.map((result) => JSON.parse(JSON.stringify(result, (key, value) => typeof value === 'bigint' ? value.toString() : value)));
335
+ if (convertedResults.length === 0) {
336
+ throw new Error(`No Cosmos-indexed tx for EVM hash ${txHash}`);
337
+ }
338
+ return { ...convertedResults[0], transactionHash: txHash };
339
+ };
340
+ // History-sensitive (tx_search). The op throws on an empty result, so the
341
+ // pruned-history miss surfaces as a thrown error — `isEmpty` stays false and
342
+ // the wrapper retries archive via its caught-error path.
343
+ return this.executeWithArchiveFallback(operation, 'getCosmosTx', () => false);
349
344
  }
350
345
  /**
351
346
  * EVM `getTransaction` with archive fallback. Prune first; on a not-found
352
347
  * (pruned, or not yet indexed) and an archive EVM endpoint configured, retry
353
348
  * the archive client. Without archive this is exactly `super.getTransaction`.
354
349
  */
355
- getTransaction(txHash) {
356
- const _super = Object.create(null, {
357
- getTransaction: { get: () => super.getTransaction }
358
- });
359
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
360
- try {
361
- return yield _super.getTransaction.call(this, txHash);
362
- }
363
- catch (error) {
364
- if (!this.hasArchiveEvm)
365
- throw error;
366
- const archiveClient = this.archivePublicClient;
367
- const tx = yield archiveClient.getTransaction({ hash: txHash });
368
- const wait = (...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (confirmations = 1) { return archiveClient.waitForTransactionReceipt({ hash: txHash, confirmations }); });
369
- return Object.assign(Object.assign({}, tx), { wait });
370
- }
371
- });
350
+ async getTransaction(txHash) {
351
+ try {
352
+ return await super.getTransaction(txHash);
353
+ }
354
+ catch (error) {
355
+ if (!this.hasArchiveEvm)
356
+ throw error;
357
+ const archiveClient = this.archivePublicClient;
358
+ const tx = await archiveClient.getTransaction({ hash: txHash });
359
+ const wait = async (confirmations = 1) => archiveClient.waitForTransactionReceipt({ hash: txHash, confirmations });
360
+ return { ...tx, wait };
361
+ }
372
362
  }
373
363
  /**
374
364
  * EVM `getTransactionReceipt` with archive fallback. Used by the inbound
375
365
  * tracker to fetch a Push-leg receipt that may predate the prune window.
376
366
  * Prune first; on not-found, retry the archive EVM client if configured.
377
367
  */
378
- getTransactionReceiptWithArchiveFallback(txHash) {
379
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
380
- try {
381
- return yield this.publicClient.getTransactionReceipt({ hash: txHash });
382
- }
383
- catch (error) {
384
- if (!this.hasArchiveEvm)
385
- throw error;
386
- return this.archivePublicClient.getTransactionReceipt({
387
- hash: txHash,
388
- });
389
- }
390
- });
368
+ async getTransactionReceiptWithArchiveFallback(txHash) {
369
+ try {
370
+ return await this.publicClient.getTransactionReceipt({ hash: txHash });
371
+ }
372
+ catch (error) {
373
+ if (!this.hasArchiveEvm)
374
+ throw error;
375
+ return this.archivePublicClient.getTransactionReceipt({
376
+ hash: txHash,
377
+ });
378
+ }
391
379
  }
392
380
  }
393
381
  exports.PushClient = PushClient;
394
- /** Gas limit for Cosmos transactions on Push Chain */
395
- PushClient.COSMOS_GAS_LIMIT = 100000000000;
396
382
  //# sourceMappingURL=push-client.js.map