@pushchain/core 5.1.3 → 5.1.4-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +29 -6
- package/src/lib/constants/abi/prc20.evm.d.ts +22 -2
- package/src/lib/constants/abi/prc20.evm.js +11 -3
- package/src/lib/constants/abi/universalGatewayPC.evm.d.ts +59 -0
- package/src/lib/constants/abi/universalGatewayPC.evm.js +26 -0
- package/src/lib/constants/chain.d.ts +4 -0
- package/src/lib/constants/chain.js +6 -2
- package/src/lib/index.d.ts +2 -2
- package/src/lib/internal/bs58.d.ts +2 -0
- package/src/lib/internal/bs58.js +7 -0
- package/src/lib/orchestrator/cea-utils.d.ts +0 -9
- package/src/lib/orchestrator/cea-utils.js +15 -4
- package/src/lib/orchestrator/internals/account-manager.d.ts +16 -0
- package/src/lib/orchestrator/internals/account-manager.js +191 -0
- package/src/lib/orchestrator/internals/cascade.d.ts +23 -0
- package/src/lib/orchestrator/internals/cascade.js +945 -0
- package/src/lib/orchestrator/internals/confirmation.d.ts +9 -0
- package/src/lib/orchestrator/internals/confirmation.js +123 -0
- package/src/lib/orchestrator/internals/context.d.ts +38 -0
- package/src/lib/orchestrator/internals/context.js +49 -0
- package/src/lib/orchestrator/internals/execute-funds-only.d.ts +11 -0
- package/src/lib/orchestrator/internals/execute-funds-only.js +219 -0
- package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +11 -0
- package/src/lib/orchestrator/internals/execute-funds-payload.js +222 -0
- package/src/lib/orchestrator/internals/execute-standard.d.ts +13 -0
- package/src/lib/orchestrator/internals/execute-standard.js +225 -0
- package/src/lib/orchestrator/internals/gas-calculator.d.ts +38 -0
- package/src/lib/orchestrator/internals/gas-calculator.js +424 -0
- package/src/lib/orchestrator/internals/gateway-client.d.ts +24 -0
- package/src/lib/orchestrator/internals/gateway-client.js +191 -0
- package/src/lib/orchestrator/internals/helpers.d.ts +26 -0
- package/src/lib/orchestrator/internals/helpers.js +181 -0
- package/src/lib/orchestrator/internals/index.d.ts +24 -0
- package/src/lib/orchestrator/internals/index.js +132 -0
- package/src/lib/orchestrator/internals/outbound-sync.d.ts +49 -0
- package/src/lib/orchestrator/internals/outbound-sync.js +357 -0
- package/src/lib/orchestrator/internals/outbound-tracker.d.ts +8 -0
- package/src/lib/orchestrator/internals/outbound-tracker.js +64 -0
- package/src/lib/orchestrator/internals/payload-builder.d.ts +24 -0
- package/src/lib/orchestrator/internals/payload-builder.js +178 -0
- package/src/lib/orchestrator/internals/push-chain-tx.d.ts +32 -0
- package/src/lib/orchestrator/internals/push-chain-tx.js +207 -0
- package/src/lib/orchestrator/internals/quote.d.ts +9 -0
- package/src/lib/orchestrator/internals/quote.js +114 -0
- package/src/lib/orchestrator/internals/rescue.d.ts +20 -0
- package/src/lib/orchestrator/internals/rescue.js +112 -0
- package/src/lib/orchestrator/internals/response-builder.d.ts +26 -0
- package/src/lib/orchestrator/internals/response-builder.js +504 -0
- package/src/lib/orchestrator/internals/route-handlers.d.ts +77 -0
- package/src/lib/orchestrator/internals/route-handlers.js +1192 -0
- package/src/lib/orchestrator/internals/signing.d.ts +27 -0
- package/src/lib/orchestrator/internals/signing.js +258 -0
- package/src/lib/orchestrator/internals/svm-bridge.d.ts +21 -0
- package/src/lib/orchestrator/internals/svm-bridge.js +122 -0
- package/src/lib/orchestrator/internals/svm-helpers.d.ts +35 -0
- package/src/lib/orchestrator/internals/svm-helpers.js +143 -0
- package/src/lib/orchestrator/internals/tx-transformer.d.ts +12 -0
- package/src/lib/orchestrator/internals/tx-transformer.js +120 -0
- package/src/lib/orchestrator/internals/uea-manager.d.ts +17 -0
- package/src/lib/orchestrator/internals/uea-manager.js +164 -0
- package/src/lib/orchestrator/orchestrator.d.ts +33 -431
- package/src/lib/orchestrator/orchestrator.js +124 -6125
- package/src/lib/orchestrator/orchestrator.types.d.ts +11 -10
- package/src/lib/orchestrator/payload-builders.js +34 -8
- package/src/lib/price-fetch/price-fetch.js +19 -7
- package/src/lib/push-chain/push-chain.d.ts +6 -0
- package/src/lib/push-chain/push-chain.js +10 -2
- package/src/lib/push-client/push-client.d.ts +3 -0
- package/src/lib/push-client/push-client.js +21 -31
- package/src/lib/universal/account/account.d.ts +35 -16
- package/src/lib/universal/account/account.js +298 -16
- package/src/lib/universal/signer/signer.d.ts +2 -3
- package/src/lib/universal/signer/signer.js +65 -115
- package/src/lib/universal/universal.types.d.ts +41 -0
- package/src/lib/utils.d.ts +7 -2
- package/src/lib/utils.js +65 -34
- package/src/lib/vm-client/evm-client.js +3 -11
- package/src/lib/vm-client/svm-client.d.ts +0 -4
- package/src/lib/vm-client/svm-client.js +2 -8
- package/src/index.js.map +0 -1
- package/src/lib/cache/cache.js.map +0 -1
- package/src/lib/constants/abi/cea.evm.js.map +0 -1
- package/src/lib/constants/abi/ceaFactory.evm.js.map +0 -1
- package/src/lib/constants/abi/erc20.evm.js.map +0 -1
- package/src/lib/constants/abi/factoryV1.js.map +0 -1
- package/src/lib/constants/abi/feeLocker.evm.js.map +0 -1
- package/src/lib/constants/abi/index.js.map +0 -1
- package/src/lib/constants/abi/prc20.evm.js.map +0 -1
- package/src/lib/constants/abi/uea-factory.js.map +0 -1
- package/src/lib/constants/abi/uea.evm.js.map +0 -1
- package/src/lib/constants/abi/uea.svm.js.map +0 -1
- package/src/lib/constants/abi/universalGateway.evm.js.map +0 -1
- package/src/lib/constants/abi/universalGatewayPC.evm.js.map +0 -1
- package/src/lib/constants/abi/universalGatewayV0.evm.js.map +0 -1
- package/src/lib/constants/chain.js.map +0 -1
- package/src/lib/constants/enums.js.map +0 -1
- package/src/lib/constants/index.js.map +0 -1
- package/src/lib/constants/selectors.js.map +0 -1
- package/src/lib/constants/tokens.js.map +0 -1
- package/src/lib/generated/uexecutor/v1/query.js.map +0 -1
- package/src/lib/generated/uexecutor/v1/types.js.map +0 -1
- package/src/lib/generated/uexecutor/v2/index.js.map +0 -1
- package/src/lib/generated/uexecutor/v2/query.js.map +0 -1
- package/src/lib/generated/uexecutor/v2/types.js.map +0 -1
- package/src/lib/generated/v1/tx.js.map +0 -1
- package/src/lib/index.js.map +0 -1
- package/src/lib/internal/buffer.js.map +0 -1
- package/src/lib/internal/global-buffer-polyfill.js.map +0 -1
- package/src/lib/orchestrator/cea-utils.js.map +0 -1
- package/src/lib/orchestrator/orchestrator.js.map +0 -1
- package/src/lib/orchestrator/orchestrator.types.js.map +0 -1
- package/src/lib/orchestrator/payload-builders.js.map +0 -1
- package/src/lib/orchestrator/route-detector.js.map +0 -1
- package/src/lib/price-fetch/price-fetch.js.map +0 -1
- package/src/lib/progress-hook/progress-hook.js.map +0 -1
- package/src/lib/progress-hook/progress-hook.types.js.map +0 -1
- package/src/lib/push-chain/helpers/abis.js.map +0 -1
- package/src/lib/push-chain/helpers/addresses.js.map +0 -1
- package/src/lib/push-chain/push-chain.js.map +0 -1
- package/src/lib/push-client/push-client.js.map +0 -1
- package/src/lib/push-client/push-client.types.js.map +0 -1
- package/src/lib/universal/account/account.js.map +0 -1
- package/src/lib/universal/account/index.js.map +0 -1
- package/src/lib/universal/signer/index.js.map +0 -1
- package/src/lib/universal/signer/signer.js.map +0 -1
- package/src/lib/universal/signer/signer.types.js.map +0 -1
- package/src/lib/universal/universal.types.js.map +0 -1
- package/src/lib/utils.js.map +0 -1
- package/src/lib/vm-client/evm-client.js.map +0 -1
- package/src/lib/vm-client/svm-client.js.map +0 -1
- package/src/lib/vm-client/vm-client.types.js.map +0 -1
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Response builder functions extracted from Orchestrator.
|
|
4
|
+
*
|
|
5
|
+
* Contains: queryUniversalTxStatusFromGatewayTx, trackTransaction,
|
|
6
|
+
* transformToUniversalTxResponse, and the ResponseBuilderCallbacks interface.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.queryUniversalTxStatusFromGatewayTx = queryUniversalTxStatusFromGatewayTx;
|
|
10
|
+
exports.trackTransaction = trackTransaction;
|
|
11
|
+
exports.transformToUniversalTxResponse = transformToUniversalTxResponse;
|
|
12
|
+
const tslib_1 = require("tslib");
|
|
13
|
+
const bs58_1 = require("../../internal/bs58");
|
|
14
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
15
|
+
const viem_1 = require("viem");
|
|
16
|
+
const uea_evm_1 = require("../../constants/abi/uea.evm");
|
|
17
|
+
const chain_1 = require("../../constants/chain");
|
|
18
|
+
const enums_1 = require("../../constants/enums");
|
|
19
|
+
const account_1 = require("../../universal/account/account");
|
|
20
|
+
const push_client_1 = require("../../push-client/push-client");
|
|
21
|
+
const route_detector_1 = require("../route-detector");
|
|
22
|
+
const context_1 = require("./context");
|
|
23
|
+
const helpers_1 = require("./helpers");
|
|
24
|
+
const svm_helpers_1 = require("./svm-helpers");
|
|
25
|
+
const outbound_tracker_1 = require("./outbound-tracker");
|
|
26
|
+
const tx_transformer_1 = require("./tx-transformer");
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// queryUniversalTxStatusFromGatewayTx
|
|
29
|
+
// ============================================================================
|
|
30
|
+
function queryUniversalTxStatusFromGatewayTx(ctx, evmClient, gatewayAddress,
|
|
31
|
+
// DEBUG: section marker added
|
|
32
|
+
txHash, evmGatewayMethod) {
|
|
33
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
try {
|
|
36
|
+
const chain = ctx.universalSigner.account.chain;
|
|
37
|
+
const { vm } = chain_1.CHAIN_INFO[chain];
|
|
38
|
+
let logIndexStr = '0';
|
|
39
|
+
let txHashHex = txHash;
|
|
40
|
+
if (vm === enums_1.VM.EVM) {
|
|
41
|
+
if (!evmClient || !gatewayAddress)
|
|
42
|
+
throw new Error('Missing EVM context');
|
|
43
|
+
let receipt;
|
|
44
|
+
try {
|
|
45
|
+
receipt = yield evmClient.publicClient.getTransactionReceipt({
|
|
46
|
+
hash: txHash,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (_c) {
|
|
50
|
+
// Receipt might not be indexed yet on this RPC; wait briefly for it
|
|
51
|
+
receipt = yield evmClient.publicClient.waitForTransactionReceipt({
|
|
52
|
+
hash: txHash,
|
|
53
|
+
confirmations: 0,
|
|
54
|
+
timeout: chain_1.CHAIN_INFO[chain].timeout,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const gatewayLogs = (receipt.logs || []).filter((l) => (l.address || '').toLowerCase() === gatewayAddress.toLowerCase());
|
|
58
|
+
(0, context_1.printLog)(ctx, `queryUniversalTxStatus — receipt logs count: ${(_a = receipt.logs) === null || _a === void 0 ? void 0 : _a.length}, gateway logs count: ${gatewayLogs.length}, evmGatewayMethod: ${evmGatewayMethod}`);
|
|
59
|
+
(0, context_1.printLog)(ctx, 'queryUniversalTxStatus — gatewayLogs: ' + JSON.stringify(gatewayLogs.map((l) => { var _a; return ({ address: l.address, logIndex: l.logIndex, topics: (_a = l.topics) === null || _a === void 0 ? void 0 : _a[0] }); }), null, 2));
|
|
60
|
+
// Use the last gateway log to derive the log index
|
|
61
|
+
const logIndexToUse = gatewayLogs.length - 1;
|
|
62
|
+
const firstLog = (gatewayLogs[logIndexToUse] ||
|
|
63
|
+
(receipt.logs || []).at(-1));
|
|
64
|
+
const logIndexVal = (_b = firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex) !== null && _b !== void 0 ? _b : 0;
|
|
65
|
+
(0, context_1.printLog)(ctx, `queryUniversalTxStatus — logIndexToUse: ${logIndexToUse}, firstLog.logIndex: ${firstLog === null || firstLog === void 0 ? void 0 : firstLog.logIndex}, logIndexVal: ${logIndexVal}`);
|
|
66
|
+
logIndexStr =
|
|
67
|
+
typeof logIndexVal === 'bigint'
|
|
68
|
+
? logIndexVal.toString()
|
|
69
|
+
: String(logIndexVal);
|
|
70
|
+
}
|
|
71
|
+
else if (vm === enums_1.VM.SVM) {
|
|
72
|
+
// Normalize Solana signature to 0x-hex for ID composition
|
|
73
|
+
let txSignature = txHash;
|
|
74
|
+
if (!txHash.startsWith('0x')) {
|
|
75
|
+
const decoded = bs58_1.bs58.decode(txHash);
|
|
76
|
+
txHashHex = (0, viem_1.bytesToHex)(new Uint8Array(decoded));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// When provided as hex, convert to base58 for RPC
|
|
80
|
+
const hex = txHash.slice(2);
|
|
81
|
+
const bytes = Uint8Array.from(Buffer.from(hex, 'hex'));
|
|
82
|
+
txSignature = bs58_1.bs58.encode(Buffer.from(bytes));
|
|
83
|
+
}
|
|
84
|
+
// Fetch transaction by initializing a Connection and calling Solana RPC
|
|
85
|
+
const rpcUrls = ctx.rpcUrls[chain] || chain_1.CHAIN_INFO[chain].defaultRPC;
|
|
86
|
+
const connection = new web3_js_1.Connection(rpcUrls[0], 'confirmed');
|
|
87
|
+
const txResp = yield connection.getTransaction(txSignature, {
|
|
88
|
+
maxSupportedTransactionVersion: 0,
|
|
89
|
+
commitment: 'confirmed',
|
|
90
|
+
});
|
|
91
|
+
// Derive proper log index using discriminator matching
|
|
92
|
+
const svmLogIndex = (0, svm_helpers_1.getSvmGatewayLogIndexFromTx)(txResp);
|
|
93
|
+
logIndexStr = String(svmLogIndex);
|
|
94
|
+
}
|
|
95
|
+
const sourceChain = `${chain_1.VM_NAMESPACE[vm]}:${chain_1.CHAIN_INFO[chain].chainId}`;
|
|
96
|
+
// ID = sha256("${sourceChain}:${txHash}:${logIndex}") as hex string (no 0x)
|
|
97
|
+
const idInput = `${sourceChain}:${txHashHex}:${logIndexStr}`;
|
|
98
|
+
const idHex = (0, viem_1.sha256)((0, viem_1.stringToBytes)(idInput)).slice(2);
|
|
99
|
+
(0, context_1.printLog)(ctx, 'Query ID extraction: ' + JSON.stringify({
|
|
100
|
+
sourceChain,
|
|
101
|
+
txHashHex,
|
|
102
|
+
logIndexStr,
|
|
103
|
+
idInput,
|
|
104
|
+
idHex,
|
|
105
|
+
}, null, 2));
|
|
106
|
+
// Fetch UniversalTx via gRPC with linear-then-exponential retry
|
|
107
|
+
const LINEAR_ATTEMPTS = 10;
|
|
108
|
+
const LINEAR_DELAY_MS = 3000;
|
|
109
|
+
const EXPONENTIAL_BASE_MS = 4000;
|
|
110
|
+
const MAX_ATTEMPTS = 15;
|
|
111
|
+
let universalTxObj;
|
|
112
|
+
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
113
|
+
(0, context_1.printLog)(ctx, `[Sync] Attempt ${attempt + 1}/${MAX_ATTEMPTS} | Query ID: ${idHex}`);
|
|
114
|
+
try {
|
|
115
|
+
const universalTxResp = yield ctx.pushClient.getUniversalTxById(idHex);
|
|
116
|
+
universalTxObj = universalTxResp === null || universalTxResp === void 0 ? void 0 : universalTxResp.universalTx;
|
|
117
|
+
if (universalTxObj) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
// ignore and retry
|
|
123
|
+
}
|
|
124
|
+
// Linear delay for first N attempts, then exponential backoff
|
|
125
|
+
let delay;
|
|
126
|
+
if (attempt < LINEAR_ATTEMPTS) {
|
|
127
|
+
delay = LINEAR_DELAY_MS;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Exponential: 2000, 4000, 8000, 16000, ...
|
|
131
|
+
const exponentialAttempt = attempt - LINEAR_ATTEMPTS;
|
|
132
|
+
delay = EXPONENTIAL_BASE_MS * Math.pow(2, exponentialAttempt);
|
|
133
|
+
}
|
|
134
|
+
yield new Promise((r) => setTimeout(r, delay));
|
|
135
|
+
}
|
|
136
|
+
return universalTxObj;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
(0, context_1.printLog)(ctx, `queryUniversalTxStatusFromGatewayTx failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// ============================================================================
|
|
145
|
+
// trackTransaction
|
|
146
|
+
// ============================================================================
|
|
147
|
+
function trackTransaction(ctx, txHash, options, callbacks) {
|
|
148
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
if (!callbacks) {
|
|
150
|
+
throw new Error('trackTransaction requires ResponseBuilderCallbacks');
|
|
151
|
+
}
|
|
152
|
+
const { chain = (0, helpers_1.getPushChainForNetwork)(ctx.pushNetwork), progressHook, waitForCompletion = true, advanced = {}, } = options !== null && options !== void 0 ? options : {};
|
|
153
|
+
const { timeout = 300000, rpcUrls = {} } = advanced;
|
|
154
|
+
// Event buffer for replay via response.progressHook()
|
|
155
|
+
const eventBuffer = [];
|
|
156
|
+
// Helper to emit progress events
|
|
157
|
+
const emitProgress = (event) => {
|
|
158
|
+
eventBuffer.push(event);
|
|
159
|
+
(0, context_1.printLog)(ctx, event.message);
|
|
160
|
+
// Per-transaction hook called FIRST
|
|
161
|
+
if (progressHook) {
|
|
162
|
+
progressHook(event);
|
|
163
|
+
}
|
|
164
|
+
// Orchestrator-level hook called SECOND
|
|
165
|
+
if (ctx.progressHook) {
|
|
166
|
+
ctx.progressHook(event);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
// Create client for target chain with optional RPC override
|
|
170
|
+
const chainRPCs = rpcUrls[chain] || ctx.rpcUrls[chain] || chain_1.CHAIN_INFO[chain].defaultRPC;
|
|
171
|
+
const client = new push_client_1.PushClient({
|
|
172
|
+
rpcUrls: chainRPCs,
|
|
173
|
+
network: ctx.pushNetwork,
|
|
174
|
+
});
|
|
175
|
+
// Poll for transaction
|
|
176
|
+
const start = Date.now();
|
|
177
|
+
let tx;
|
|
178
|
+
// eslint-disable-next-line no-constant-condition
|
|
179
|
+
while (true) {
|
|
180
|
+
try {
|
|
181
|
+
tx = yield client.getTransaction(txHash);
|
|
182
|
+
break; // Found transaction
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (!waitForCompletion) {
|
|
186
|
+
throw new Error(`Transaction ${txHash} not found`);
|
|
187
|
+
}
|
|
188
|
+
// Check timeout
|
|
189
|
+
if (Date.now() - start > timeout) {
|
|
190
|
+
throw new Error(`Timeout: transaction ${txHash} not confirmed within ${timeout}ms`);
|
|
191
|
+
}
|
|
192
|
+
// Brief delay before retry
|
|
193
|
+
yield new Promise((r) => setTimeout(r, 1000));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Try to get UniversalTx data for richer progress reconstruction
|
|
197
|
+
// (may not exist for direct Push Chain transactions)
|
|
198
|
+
// Three-tier lookup: direct hash → computed keccak ID → Cosmos event extraction
|
|
199
|
+
let universalTxData;
|
|
200
|
+
try {
|
|
201
|
+
const utxResponse = yield ctx.pushClient.getUniversalTxByIdV2(txHash);
|
|
202
|
+
if (utxResponse === null || utxResponse === void 0 ? void 0 : utxResponse.universalTx) {
|
|
203
|
+
universalTxData = utxResponse.universalTx;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (_a) {
|
|
207
|
+
// Ignore - try computed ID next
|
|
208
|
+
}
|
|
209
|
+
if (!universalTxData) {
|
|
210
|
+
try {
|
|
211
|
+
const computedId = (0, outbound_tracker_1.computeUniversalTxId)(ctx.pushNetwork, txHash);
|
|
212
|
+
const queryId = computedId.startsWith('0x') ? computedId.slice(2) : computedId;
|
|
213
|
+
const utxResponse = yield ctx.pushClient.getUniversalTxByIdV2(queryId);
|
|
214
|
+
if (utxResponse === null || utxResponse === void 0 ? void 0 : utxResponse.universalTx) {
|
|
215
|
+
universalTxData = utxResponse.universalTx;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (_b) {
|
|
219
|
+
// Ignore - try Cosmos event extraction next
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (!universalTxData) {
|
|
223
|
+
try {
|
|
224
|
+
const extractedId = yield (0, outbound_tracker_1.extractUniversalSubTxIdFromTx)(ctx, txHash);
|
|
225
|
+
if (extractedId) {
|
|
226
|
+
const queryId = extractedId.startsWith('0x') ? extractedId.slice(2) : extractedId;
|
|
227
|
+
const utxResponse = yield ctx.pushClient.getUniversalTxByIdV2(queryId);
|
|
228
|
+
if (utxResponse === null || utxResponse === void 0 ? void 0 : utxResponse.universalTx) {
|
|
229
|
+
universalTxData = utxResponse.universalTx;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (_c) {
|
|
234
|
+
// Ignore - no universal tx data available
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Transform to UniversalTxResponse
|
|
238
|
+
const universalTxResponse = yield transformToUniversalTxResponse(ctx, tx, eventBuffer, callbacks);
|
|
239
|
+
// Detect route from UniversalTxV2 data and set on response
|
|
240
|
+
// This enables wait() to trigger outbound polling via waitForOutboundTx()
|
|
241
|
+
const detectedRoute = (0, tx_transformer_1.detectRouteFromUniversalTxData)(universalTxData);
|
|
242
|
+
if (detectedRoute) {
|
|
243
|
+
universalTxResponse.route = detectedRoute;
|
|
244
|
+
}
|
|
245
|
+
// Reconstruct and emit SEND-TX-* progress events
|
|
246
|
+
const reconstructedEvents = (0, tx_transformer_1.reconstructProgressEvents)(universalTxResponse, universalTxData);
|
|
247
|
+
for (const event of reconstructedEvents) {
|
|
248
|
+
emitProgress(event);
|
|
249
|
+
}
|
|
250
|
+
return universalTxResponse;
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// ============================================================================
|
|
254
|
+
// transformToUniversalTxResponse
|
|
255
|
+
// ============================================================================
|
|
256
|
+
function transformToUniversalTxResponse(ctx_1, tx_1) {
|
|
257
|
+
return tslib_1.__awaiter(this, arguments, void 0, function* (ctx, tx, eventBuffer = [], callbacks) {
|
|
258
|
+
const chain = ctx.universalSigner.account.chain;
|
|
259
|
+
const { vm, chainId } = chain_1.CHAIN_INFO[chain];
|
|
260
|
+
let from;
|
|
261
|
+
let to;
|
|
262
|
+
let value;
|
|
263
|
+
let data;
|
|
264
|
+
let rawTransactionData;
|
|
265
|
+
const ueaOrigin = yield (0, account_1.convertExecutorToOrigin)(tx.to, { _internal: true });
|
|
266
|
+
let originAddress;
|
|
267
|
+
if (ueaOrigin.exists) {
|
|
268
|
+
if (!ueaOrigin.account) {
|
|
269
|
+
throw new Error('UEA origin account is null');
|
|
270
|
+
}
|
|
271
|
+
originAddress = ueaOrigin.account.address;
|
|
272
|
+
from = (0, viem_1.getAddress)(tx.to);
|
|
273
|
+
let decoded;
|
|
274
|
+
if (tx.input !== '0x') {
|
|
275
|
+
decoded = (0, viem_1.decodeFunctionData)({
|
|
276
|
+
abi: uea_evm_1.UEA_EVM,
|
|
277
|
+
data: tx.input,
|
|
278
|
+
});
|
|
279
|
+
if (!(decoded === null || decoded === void 0 ? void 0 : decoded.args)) {
|
|
280
|
+
throw new Error('Failed to decode function data');
|
|
281
|
+
}
|
|
282
|
+
const universalPayload = decoded === null || decoded === void 0 ? void 0 : decoded.args[0];
|
|
283
|
+
to = universalPayload.to;
|
|
284
|
+
value = BigInt(universalPayload.value);
|
|
285
|
+
data = universalPayload.data;
|
|
286
|
+
// Extract 'to' from single-element multicall
|
|
287
|
+
if (data && data.length >= 10) {
|
|
288
|
+
const multicallSelector = (0, viem_1.keccak256)((0, viem_1.toBytes)('UEA_MULTICALL')).slice(0, 10);
|
|
289
|
+
if (data.slice(0, 10) === multicallSelector) {
|
|
290
|
+
try {
|
|
291
|
+
const innerData = ('0x' + data.slice(10));
|
|
292
|
+
const [decodedCalls] = (0, viem_1.decodeAbiParameters)([
|
|
293
|
+
{
|
|
294
|
+
type: 'tuple[]',
|
|
295
|
+
components: [
|
|
296
|
+
{ name: 'to', type: 'address' },
|
|
297
|
+
{ name: 'value', type: 'uint256' },
|
|
298
|
+
{ name: 'data', type: 'bytes' },
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
], innerData);
|
|
302
|
+
// If single call, use its 'to' address
|
|
303
|
+
if (decodedCalls.length === 1) {
|
|
304
|
+
to = (0, viem_1.getAddress)(decodedCalls[0].to);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (_a) {
|
|
308
|
+
// Keep original 'to' if decoding fails
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
rawTransactionData = {
|
|
313
|
+
from: (0, viem_1.getAddress)(tx.from),
|
|
314
|
+
to: (0, viem_1.getAddress)(tx.to),
|
|
315
|
+
nonce: tx.nonce,
|
|
316
|
+
data: tx.input,
|
|
317
|
+
value: tx.value,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
to = (0, viem_1.getAddress)(tx.to);
|
|
322
|
+
value = tx.value;
|
|
323
|
+
data = tx.input;
|
|
324
|
+
rawTransactionData = {
|
|
325
|
+
from: (0, viem_1.getAddress)(tx.from),
|
|
326
|
+
to: (0, viem_1.getAddress)(tx.to),
|
|
327
|
+
nonce: tx.nonce,
|
|
328
|
+
data: tx.input,
|
|
329
|
+
value: tx.value,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
originAddress = (0, viem_1.getAddress)(tx.from);
|
|
335
|
+
from = (0, viem_1.getAddress)(tx.from);
|
|
336
|
+
to = (0, viem_1.getAddress)(tx.to);
|
|
337
|
+
value = tx.value;
|
|
338
|
+
data = tx.input;
|
|
339
|
+
rawTransactionData = {
|
|
340
|
+
from: (0, viem_1.getAddress)(tx.from),
|
|
341
|
+
to: (0, viem_1.getAddress)(tx.to),
|
|
342
|
+
nonce: tx.nonce,
|
|
343
|
+
data: tx.input,
|
|
344
|
+
value: tx.value,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// Extract 'to' and 'from' from depositPRC20WithAutoSwap (precompile call)
|
|
348
|
+
if (data && data.length >= 10) {
|
|
349
|
+
const depositPRC20Selector = '0x780ad827';
|
|
350
|
+
if (data.slice(0, 10) === depositPRC20Selector) {
|
|
351
|
+
try {
|
|
352
|
+
const decoded = (0, viem_1.decodeFunctionData)({
|
|
353
|
+
abi: [
|
|
354
|
+
{
|
|
355
|
+
name: 'depositPRC20WithAutoSwap',
|
|
356
|
+
type: 'function',
|
|
357
|
+
inputs: [
|
|
358
|
+
{ name: 'prc20', type: 'address' },
|
|
359
|
+
{ name: 'amount', type: 'uint256' },
|
|
360
|
+
{ name: 'target', type: 'address' },
|
|
361
|
+
{ name: 'fee', type: 'uint24' },
|
|
362
|
+
{ name: 'minPCOut', type: 'uint256' },
|
|
363
|
+
{ name: 'deadline', type: 'uint256' },
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
data: data,
|
|
368
|
+
});
|
|
369
|
+
if (decoded.args) {
|
|
370
|
+
const target = decoded.args[2];
|
|
371
|
+
to = (0, viem_1.getAddress)(target);
|
|
372
|
+
from = '0x0000000000000000000000000000000000000000';
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
catch (_b) {
|
|
376
|
+
// Keep original values if decoding fails
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
const origin = `${chain_1.VM_NAMESPACE[vm]}:${chainId}:${originAddress}`;
|
|
381
|
+
// Create signature from transaction r, s, v values
|
|
382
|
+
let signature;
|
|
383
|
+
try {
|
|
384
|
+
signature = {
|
|
385
|
+
r: tx.r || '0x0',
|
|
386
|
+
s: tx.s || '0x0',
|
|
387
|
+
v: typeof tx.v === 'bigint' ? Number(tx.v) : tx.v || 0,
|
|
388
|
+
yParity: tx.yParity,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
catch (_c) {
|
|
392
|
+
// Fallback signature if parsing fails
|
|
393
|
+
signature = {
|
|
394
|
+
r: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
395
|
+
s: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
396
|
+
v: 0,
|
|
397
|
+
yParity: 0,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
// Determine transaction type and typeVerbose
|
|
401
|
+
let type = '99'; // universal
|
|
402
|
+
let typeVerbose = 'universal';
|
|
403
|
+
if (tx.type !== undefined) {
|
|
404
|
+
const txType = tx.type;
|
|
405
|
+
if (txType === 'eip1559') {
|
|
406
|
+
type = '2';
|
|
407
|
+
typeVerbose = 'eip1559';
|
|
408
|
+
}
|
|
409
|
+
else if (txType === 'eip2930') {
|
|
410
|
+
type = '1';
|
|
411
|
+
typeVerbose = 'eip2930';
|
|
412
|
+
}
|
|
413
|
+
else if (txType === 'legacy') {
|
|
414
|
+
type = '0';
|
|
415
|
+
typeVerbose = 'legacy';
|
|
416
|
+
}
|
|
417
|
+
else if (txType === 'eip4844') {
|
|
418
|
+
type = '3';
|
|
419
|
+
typeVerbose = 'eip4844';
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
// Storage for registered progress callback (used by progressHook method)
|
|
423
|
+
let registeredProgressHook;
|
|
424
|
+
const universalTxResponse = {
|
|
425
|
+
// 1. Identity
|
|
426
|
+
hash: tx.hash,
|
|
427
|
+
origin,
|
|
428
|
+
// 2. Block Info
|
|
429
|
+
blockNumber: tx.blockNumber || BigInt(0),
|
|
430
|
+
blockHash: tx.blockHash || '',
|
|
431
|
+
transactionIndex: tx.transactionIndex || 0,
|
|
432
|
+
chainId,
|
|
433
|
+
// 3. Execution Context
|
|
434
|
+
from: from, // UEA (executor) address, checksummed for EVM
|
|
435
|
+
to: to || '',
|
|
436
|
+
nonce: tx.nonce,
|
|
437
|
+
// 4. Payload
|
|
438
|
+
data, // perceived calldata (was input)
|
|
439
|
+
value,
|
|
440
|
+
// 5. Gas
|
|
441
|
+
gasLimit: tx.gas || BigInt(0), // (was gas)
|
|
442
|
+
gasPrice: tx.gasPrice,
|
|
443
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
444
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
|
445
|
+
accessList: Array.isArray(tx.accessList) ? [...tx.accessList] : [],
|
|
446
|
+
// 6. Utilities
|
|
447
|
+
wait: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
448
|
+
// Use trackTransaction with registered hook if available
|
|
449
|
+
let baseReceipt;
|
|
450
|
+
if (registeredProgressHook) {
|
|
451
|
+
const trackedResponse = yield callbacks.trackTransaction(tx.hash, {
|
|
452
|
+
waitForCompletion: true,
|
|
453
|
+
progressHook: registeredProgressHook,
|
|
454
|
+
});
|
|
455
|
+
// Get receipt from the tracked response
|
|
456
|
+
const receipt = yield tx.wait();
|
|
457
|
+
baseReceipt = callbacks.transformToUniversalTxReceipt(receipt, trackedResponse);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
const receipt = yield tx.wait();
|
|
461
|
+
baseReceipt = callbacks.transformToUniversalTxReceipt(receipt, universalTxResponse);
|
|
462
|
+
}
|
|
463
|
+
// If outbound route, poll for external chain details
|
|
464
|
+
const routeInfo = universalTxResponse.route
|
|
465
|
+
? (0, route_detector_1.getRouteInfo)(universalTxResponse.route)
|
|
466
|
+
: undefined;
|
|
467
|
+
if (routeInfo === null || routeInfo === void 0 ? void 0 : routeInfo.isOutbound) {
|
|
468
|
+
try {
|
|
469
|
+
const outboundDetails = yield callbacks.waitForOutboundTx(tx.hash, {
|
|
470
|
+
initialWaitMs: callbacks.outboundConstants.initialWaitMs,
|
|
471
|
+
pollingIntervalMs: callbacks.outboundConstants.pollingIntervalMs,
|
|
472
|
+
timeout: callbacks.outboundConstants.maxTimeoutMs,
|
|
473
|
+
});
|
|
474
|
+
// Merge external chain details into receipt
|
|
475
|
+
baseReceipt = Object.assign(Object.assign({}, baseReceipt), { externalTxHash: outboundDetails.externalTxHash, externalChain: outboundDetails.destinationChain, externalExplorerUrl: outboundDetails.explorerUrl, externalRecipient: outboundDetails.recipient, externalAmount: outboundDetails.amount, externalAssetAddr: outboundDetails.assetAddr });
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
// Outbound polling timed out - return partial receipt (don't throw)
|
|
479
|
+
// Push Chain tx succeeded, external tracking can be retried later
|
|
480
|
+
callbacks.printLog(`[wait] External chain tracking failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return baseReceipt;
|
|
484
|
+
}),
|
|
485
|
+
progressHook: (callback) => {
|
|
486
|
+
registeredProgressHook = callback;
|
|
487
|
+
// Immediately replay buffered events from execution
|
|
488
|
+
if (eventBuffer.length > 0) {
|
|
489
|
+
for (const event of eventBuffer) {
|
|
490
|
+
callback(event);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
// 7. Metadata
|
|
495
|
+
type,
|
|
496
|
+
typeVerbose,
|
|
497
|
+
signature,
|
|
498
|
+
// 8. Raw Universal Fields
|
|
499
|
+
raw: rawTransactionData,
|
|
500
|
+
};
|
|
501
|
+
return universalTxResponse;
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
//# sourceMappingURL=response-builder.js.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route handler functions extracted from Orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Each function corresponds to one of the multichain execution routes:
|
|
5
|
+
* - executeMultiChain (dispatch)
|
|
6
|
+
* - executeUoaToCea (Route 2 EVM)
|
|
7
|
+
* - executeUoaToCeaSvm (Route 2 SVM)
|
|
8
|
+
* - executeCeaToPush (Route 3 EVM)
|
|
9
|
+
* - executeCeaToPushSvm(Route 3 SVM)
|
|
10
|
+
* - executeCeaToCea (Route 4 stub)
|
|
11
|
+
* - buildPayloadForRoute
|
|
12
|
+
*
|
|
13
|
+
* Every method receives an `OrchestratorContext` as first parameter and an
|
|
14
|
+
* `executeFn` callback that replaces the former `this.execute()` call.
|
|
15
|
+
*/
|
|
16
|
+
import type { OrchestratorContext } from './context';
|
|
17
|
+
import { CHAIN } from '../../constants/enums';
|
|
18
|
+
import { TransactionRoute } from '../route-detector';
|
|
19
|
+
import type { ChainTarget, ExecuteParams, UniversalExecuteParams, UniversalOutboundTxRequest, UniversalTxRequest, UniversalTxResponse } from '../orchestrator.types';
|
|
20
|
+
type ExecuteFn = (params: ExecuteParams | UniversalExecuteParams) => Promise<UniversalTxResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* Dispatch a universal execution to the correct route handler.
|
|
23
|
+
*/
|
|
24
|
+
export declare function executeMultiChain(ctx: OrchestratorContext, params: UniversalExecuteParams, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* Route 2: Execute outbound transaction from Push Chain to external CEA.
|
|
27
|
+
*
|
|
28
|
+
* Builds a multicall that executes on Push Chain (from UEA context):
|
|
29
|
+
* 1. Approves the gateway to spend PRC-20 tokens (if needed)
|
|
30
|
+
* 2. Calls sendUniversalTxOutbound on UniversalGatewayPC precompile
|
|
31
|
+
*
|
|
32
|
+
* The multicall is executed through the normal execute() flow which handles
|
|
33
|
+
* fee-locking on the origin chain and signature verification.
|
|
34
|
+
*/
|
|
35
|
+
export declare function executeUoaToCea(ctx: OrchestratorContext, params: UniversalExecuteParams, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Route 2 for SVM targets: Outbound from Push Chain to Solana.
|
|
38
|
+
*
|
|
39
|
+
* Three cases:
|
|
40
|
+
* 1. Withdraw SOL: Burn pSOL on Push Chain, recipient gets native SOL
|
|
41
|
+
* 2. Withdraw SPL: Burn PRC-20 on Push Chain, recipient gets SPL token
|
|
42
|
+
* 3. Execute (CPI): Burn pSOL + execute CPI on target Solana program
|
|
43
|
+
*/
|
|
44
|
+
export declare function executeUoaToCeaSvm(ctx: OrchestratorContext, params: UniversalExecuteParams, target: ChainTarget, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
45
|
+
/**
|
|
46
|
+
* Route 3: Execute inbound transaction from CEA to Push Chain.
|
|
47
|
+
*
|
|
48
|
+
* This route instructs CEA on an external chain to call sendUniversalTxFromCEA,
|
|
49
|
+
* bridging funds/payloads back to Push Chain.
|
|
50
|
+
*
|
|
51
|
+
* Flow:
|
|
52
|
+
* 1. Build multicall for CEA: [approve Gateway (if ERC20), sendUniversalTxFromCEA]
|
|
53
|
+
* 2. Execute via Route 2 (UOA -> CEA) with PAYLOAD-only (CEA uses its own funds)
|
|
54
|
+
* 3. CEA executes multicall, Gateway locks funds, relayer mints PRC-20 on Push Chain
|
|
55
|
+
*/
|
|
56
|
+
export declare function executeCeaToPush(ctx: OrchestratorContext, params: UniversalExecuteParams, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
57
|
+
/**
|
|
58
|
+
* Route 3 SVM: Execute CEA-to-Push for Solana chains.
|
|
59
|
+
*
|
|
60
|
+
* Unlike EVM Route 3 which builds CEA multicalls, SVM Route 3 encodes a
|
|
61
|
+
* `send_universal_tx_to_uea` instruction as an execute payload targeting
|
|
62
|
+
* the SVM gateway program (self-call). The drain amount is embedded in
|
|
63
|
+
* the instruction data, not in the outbound request amount.
|
|
64
|
+
*/
|
|
65
|
+
export declare function executeCeaToPushSvm(ctx: OrchestratorContext, params: UniversalExecuteParams, sourceChain: CHAIN, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Route 4: Execute CEA to CEA transaction via Push Chain.
|
|
68
|
+
*/
|
|
69
|
+
export declare function executeCeaToCea(ctx: OrchestratorContext, params: UniversalExecuteParams, executeFn: ExecuteFn): Promise<UniversalTxResponse>;
|
|
70
|
+
/**
|
|
71
|
+
* Build payload for a specific route.
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildPayloadForRoute(ctx: OrchestratorContext, params: UniversalExecuteParams, route: TransactionRoute, nonce: bigint): Promise<{
|
|
74
|
+
payload: `0x${string}`;
|
|
75
|
+
gatewayRequest: UniversalTxRequest | UniversalOutboundTxRequest;
|
|
76
|
+
}>;
|
|
77
|
+
export {};
|