@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,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push Chain transaction broadcasting — extracted from Orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* sendPushTx: Direct EVM tx on Push Chain (single or multicall batch)
|
|
5
|
+
* sendUniversalTx: Cosmos-wrapped EVM tx via PushClient (gasless path)
|
|
6
|
+
*/
|
|
7
|
+
import type { UniversalTx } from '../../generated/uexecutor/v1/types';
|
|
8
|
+
import { ProgressEvent } from '../../progress-hook/progress-hook.types';
|
|
9
|
+
import { UniversalPayload } from '../../generated/v1/tx';
|
|
10
|
+
import type { TxResponse } from '../../vm-client/vm-client.types';
|
|
11
|
+
import type { ExecuteParams, UniversalTxResponse } from '../orchestrator.types';
|
|
12
|
+
import type { OrchestratorContext } from './context';
|
|
13
|
+
type TransformToResponseFn = (tx: TxResponse, eventBuffer: ProgressEvent[]) => Promise<UniversalTxResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Sends an EVM transaction directly on Push Chain.
|
|
16
|
+
* Only used when universal signer is on Push Chain.
|
|
17
|
+
*
|
|
18
|
+
* For multicall arrays: executes each call as a separate transaction with
|
|
19
|
+
* local nonce management and per-tx receipt confirmation.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sendPushTx(ctx: OrchestratorContext, execute: ExecuteParams, eventBuffer: ProgressEvent[], transformFn: TransformToResponseFn): Promise<UniversalTxResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Sends a Cosmos tx to Push Chain (gasless) to execute user intent.
|
|
24
|
+
* Wraps the EVM payload in a MsgExecutePayload Cosmos message.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sendUniversalTx(ctx: OrchestratorContext, isUEADeployed: boolean, feeLockTxHash: string | undefined, universalPayload: UniversalPayload | undefined, verificationData: `0x${string}` | undefined, eventBuffer: ProgressEvent[], transformFn: TransformToResponseFn): Promise<UniversalTxResponse[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Validates Push Chain tx response, extracts last pcTx, fetches EVM tx,
|
|
29
|
+
* and transforms to UniversalTxResponse.
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractPcTxAndTransform(ctx: OrchestratorContext, pushChainUniversalTx: UniversalTx | undefined, gatewayTxHash: string, eventBuffer: ProgressEvent[], label: string, transformFn: TransformToResponseFn): Promise<UniversalTxResponse>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Push Chain transaction broadcasting — extracted from Orchestrator.
|
|
4
|
+
*
|
|
5
|
+
* sendPushTx: Direct EVM tx on Push Chain (single or multicall batch)
|
|
6
|
+
* sendUniversalTx: Cosmos-wrapped EVM tx via PushClient (gasless path)
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.sendPushTx = sendPushTx;
|
|
10
|
+
exports.sendUniversalTx = sendUniversalTx;
|
|
11
|
+
exports.extractPcTxAndTransform = extractPcTxAndTransform;
|
|
12
|
+
const tslib_1 = require("tslib");
|
|
13
|
+
const bs58_1 = require("../../internal/bs58");
|
|
14
|
+
const viem_1 = require("viem");
|
|
15
|
+
const chain_1 = require("../../constants/chain");
|
|
16
|
+
const enums_1 = require("../../constants/enums");
|
|
17
|
+
const context_1 = require("./context");
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// sendPushTx
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Sends an EVM transaction directly on Push Chain.
|
|
23
|
+
* Only used when universal signer is on Push Chain.
|
|
24
|
+
*
|
|
25
|
+
* For multicall arrays: executes each call as a separate transaction with
|
|
26
|
+
* local nonce management and per-tx receipt confirmation.
|
|
27
|
+
*/
|
|
28
|
+
function sendPushTx(ctx, execute, eventBuffer, transformFn) {
|
|
29
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
var _a, _b, _c;
|
|
31
|
+
if (Array.isArray(execute.data)) {
|
|
32
|
+
const PUSH_CHAIN_GAS_LIMIT = BigInt(500000);
|
|
33
|
+
const MAX_NONCE_RETRIES = 3;
|
|
34
|
+
let nonce = yield ctx.pushClient.publicClient.getTransactionCount({
|
|
35
|
+
address: ctx.universalSigner.account.address,
|
|
36
|
+
blockTag: 'pending',
|
|
37
|
+
});
|
|
38
|
+
let lastTxHash = '0x';
|
|
39
|
+
const calls = execute.data;
|
|
40
|
+
for (let i = 0; i < calls.length; i++) {
|
|
41
|
+
const call = calls[i];
|
|
42
|
+
let txSent = false;
|
|
43
|
+
for (let retry = 0; retry < MAX_NONCE_RETRIES && !txSent; retry++) {
|
|
44
|
+
try {
|
|
45
|
+
(0, context_1.printLog)(ctx, `sendPushTx — executing multicall operation ${i + 1}/${calls.length} to: ${call.to} (nonce: ${nonce})`);
|
|
46
|
+
lastTxHash = yield ctx.pushClient.sendTransaction({
|
|
47
|
+
to: call.to,
|
|
48
|
+
data: (call.data || '0x'),
|
|
49
|
+
value: call.value,
|
|
50
|
+
signer: ctx.universalSigner,
|
|
51
|
+
nonce,
|
|
52
|
+
gas: PUSH_CHAIN_GAS_LIMIT,
|
|
53
|
+
});
|
|
54
|
+
txSent = true;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const msg = (err === null || err === void 0 ? void 0 : err.message) || (err === null || err === void 0 ? void 0 : err.details) || '';
|
|
58
|
+
if (msg.includes('invalid nonce') || msg.includes('invalid sequence')) {
|
|
59
|
+
(0, context_1.printLog)(ctx, `sendPushTx — nonce mismatch on operation ${i + 1}/${calls.length} (retry ${retry + 1}/${MAX_NONCE_RETRIES}), re-fetching nonce`);
|
|
60
|
+
nonce = yield ctx.pushClient.publicClient.getTransactionCount({
|
|
61
|
+
address: ctx.universalSigner.account.address,
|
|
62
|
+
blockTag: 'pending',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!txSent) {
|
|
71
|
+
throw new Error(`sendPushTx — multicall operation ${i + 1}/${calls.length} failed after ${MAX_NONCE_RETRIES} nonce retries`);
|
|
72
|
+
}
|
|
73
|
+
const receipt = yield ctx.pushClient.publicClient.waitForTransactionReceipt({
|
|
74
|
+
hash: lastTxHash,
|
|
75
|
+
});
|
|
76
|
+
if (receipt.status === 'reverted') {
|
|
77
|
+
// Simulate the failed call to extract the revert reason
|
|
78
|
+
let revertReason = 'unknown';
|
|
79
|
+
try {
|
|
80
|
+
yield ctx.pushClient.publicClient.call({
|
|
81
|
+
to: call.to,
|
|
82
|
+
data: (call.data || '0x'),
|
|
83
|
+
value: call.value,
|
|
84
|
+
account: ctx.universalSigner.account.address,
|
|
85
|
+
blockNumber: receipt.blockNumber,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (simErr) {
|
|
89
|
+
// viem decodes common revert reasons into shortMessage
|
|
90
|
+
revertReason =
|
|
91
|
+
(simErr === null || simErr === void 0 ? void 0 : simErr.shortMessage) || ((_a = simErr === null || simErr === void 0 ? void 0 : simErr.cause) === null || _a === void 0 ? void 0 : _a.reason) || ((_b = simErr === null || simErr === void 0 ? void 0 : simErr.cause) === null || _b === void 0 ? void 0 : _b.message) || (simErr === null || simErr === void 0 ? void 0 : simErr.message) || String(simErr);
|
|
92
|
+
// Also log the raw revert data if available
|
|
93
|
+
const revertData = ((_c = simErr === null || simErr === void 0 ? void 0 : simErr.cause) === null || _c === void 0 ? void 0 : _c.data) || (simErr === null || simErr === void 0 ? void 0 : simErr.data);
|
|
94
|
+
if (revertData) {
|
|
95
|
+
revertReason += ` [data: ${revertData}]`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
(0, context_1.printLog)(ctx, `sendPushTx — multicall operation ${i + 1}/${calls.length} reverted (to: ${call.to}, txHash: ${lastTxHash}, revertReason: ${revertReason})`);
|
|
99
|
+
throw new Error(`sendPushTx — multicall operation ${i + 1}/${calls.length} reverted (to: ${call.to}, txHash: ${lastTxHash}, revertReason: ${revertReason})`);
|
|
100
|
+
}
|
|
101
|
+
(0, context_1.printLog)(ctx, `sendPushTx — operation ${i + 1}/${calls.length} confirmed in block ${receipt.blockNumber}`);
|
|
102
|
+
nonce++;
|
|
103
|
+
}
|
|
104
|
+
const txResponse = yield ctx.pushClient.getTransaction(lastTxHash);
|
|
105
|
+
return yield transformFn(txResponse, eventBuffer);
|
|
106
|
+
}
|
|
107
|
+
const txHash = yield ctx.pushClient.sendTransaction({
|
|
108
|
+
to: execute.to,
|
|
109
|
+
data: (execute.data || '0x'),
|
|
110
|
+
value: execute.value,
|
|
111
|
+
signer: ctx.universalSigner,
|
|
112
|
+
});
|
|
113
|
+
const txResponse = yield ctx.pushClient.getTransaction(txHash);
|
|
114
|
+
return yield transformFn(txResponse, eventBuffer);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// sendUniversalTx
|
|
119
|
+
// ============================================================================
|
|
120
|
+
/**
|
|
121
|
+
* Sends a Cosmos tx to Push Chain (gasless) to execute user intent.
|
|
122
|
+
* Wraps the EVM payload in a MsgExecutePayload Cosmos message.
|
|
123
|
+
*/
|
|
124
|
+
function sendUniversalTx(ctx, isUEADeployed, feeLockTxHash, universalPayload, verificationData, eventBuffer, transformFn) {
|
|
125
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
var _a, _b, _c, _d;
|
|
127
|
+
const { chain, address } = ctx.universalSigner.account;
|
|
128
|
+
const { vm, chainId } = chain_1.CHAIN_INFO[chain];
|
|
129
|
+
const universalAccountId = {
|
|
130
|
+
chainNamespace: chain_1.VM_NAMESPACE[vm],
|
|
131
|
+
chainId: chainId,
|
|
132
|
+
owner: vm === enums_1.VM.EVM
|
|
133
|
+
? address
|
|
134
|
+
: vm === enums_1.VM.SVM
|
|
135
|
+
? (0, viem_1.bytesToHex)(new Uint8Array(bs58_1.bs58.decode(address)))
|
|
136
|
+
: address,
|
|
137
|
+
};
|
|
138
|
+
const { cosmosAddress: signer } = ctx.pushClient.getSignerAddress();
|
|
139
|
+
const msgs = [];
|
|
140
|
+
if (universalPayload && verificationData) {
|
|
141
|
+
msgs.push(ctx.pushClient.createMsgExecutePayload({
|
|
142
|
+
signer,
|
|
143
|
+
universalAccountId,
|
|
144
|
+
universalPayload,
|
|
145
|
+
verificationData,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
const txBody = yield ctx.pushClient.createCosmosTxBody(msgs);
|
|
149
|
+
const txRaw = yield ctx.pushClient.signCosmosTx(txBody);
|
|
150
|
+
const tx = yield ctx.pushClient.broadcastCosmosTx(txRaw);
|
|
151
|
+
if (tx.code !== 0) {
|
|
152
|
+
const failedEthTxHashes = (_b = (_a = tx.events) === null || _a === void 0 ? void 0 : _a.filter((e) => e.type === 'ethereum_tx').flatMap((e) => {
|
|
153
|
+
var _a;
|
|
154
|
+
return (_a = e.attributes) === null || _a === void 0 ? void 0 : _a.filter((attr) => attr.key === 'ethereumTxHash').map((attr) => attr.value);
|
|
155
|
+
})) !== null && _b !== void 0 ? _b : [];
|
|
156
|
+
const failureSummary = [
|
|
157
|
+
`PUSH CHAIN TRANSACTION FAILED`,
|
|
158
|
+
`Cosmos TX Hash: ${tx.transactionHash}`,
|
|
159
|
+
`Block Height: ${tx.height}, TX Code: ${tx.code} (error)`,
|
|
160
|
+
`Gas Used: ${tx.gasUsed}, Gas Wanted: ${tx.gasWanted}`,
|
|
161
|
+
...(failedEthTxHashes.length > 0 ? [`Ethereum TX Hash(es): ${failedEthTxHashes.join(', ')}`] : []),
|
|
162
|
+
`Error: ${tx.rawLog}`,
|
|
163
|
+
].join(' | ');
|
|
164
|
+
(0, context_1.printLog)(ctx, failureSummary);
|
|
165
|
+
throw new Error(tx.rawLog);
|
|
166
|
+
}
|
|
167
|
+
const ethTxHashes = (_d = (_c = tx.events) === null || _c === void 0 ? void 0 : _c.filter((e) => e.type === 'ethereum_tx').flatMap((e) => {
|
|
168
|
+
var _a;
|
|
169
|
+
return (_a = e.attributes) === null || _a === void 0 ? void 0 : _a.filter((attr) => attr.key === 'ethereumTxHash').map((attr) => attr.value);
|
|
170
|
+
})) !== null && _d !== void 0 ? _d : [];
|
|
171
|
+
if (ethTxHashes.length === 0) {
|
|
172
|
+
throw new Error('No ethereumTxHash found in transaction events');
|
|
173
|
+
}
|
|
174
|
+
const evmTxs = yield Promise.all(ethTxHashes.map((hash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
return yield ctx.pushClient.getTransaction(hash);
|
|
176
|
+
})));
|
|
177
|
+
const responses = yield Promise.all(evmTxs.map((tx, index) => transformFn(tx, index === evmTxs.length - 1 ? eventBuffer : [])));
|
|
178
|
+
return responses;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// extractPcTxAndTransform
|
|
183
|
+
// ============================================================================
|
|
184
|
+
/**
|
|
185
|
+
* Validates Push Chain tx response, extracts last pcTx, fetches EVM tx,
|
|
186
|
+
* and transforms to UniversalTxResponse.
|
|
187
|
+
*/
|
|
188
|
+
function extractPcTxAndTransform(ctx, pushChainUniversalTx, gatewayTxHash, eventBuffer, label, transformFn) {
|
|
189
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
var _a;
|
|
191
|
+
if (!((_a = pushChainUniversalTx === null || pushChainUniversalTx === void 0 ? void 0 : pushChainUniversalTx.pcTx) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
192
|
+
throw new Error(`Failed to retrieve Push Chain transaction status for gateway tx: ${gatewayTxHash}. ` +
|
|
193
|
+
`The transaction may have failed on Push Chain or not been indexed yet.`);
|
|
194
|
+
}
|
|
195
|
+
const lastPcTransaction = pushChainUniversalTx.pcTx.at(-1);
|
|
196
|
+
(0, context_1.printLog)(ctx, `${label} — pcTx: ` + JSON.stringify(pushChainUniversalTx.pcTx.map((p) => ({ txHash: p.txHash, status: p.status, errorMsg: p.errorMsg })), null, 2));
|
|
197
|
+
(0, context_1.printLog)(ctx, `${label} — using lastPcTransaction: ` + JSON.stringify(lastPcTransaction, null, 2));
|
|
198
|
+
if (!(lastPcTransaction === null || lastPcTransaction === void 0 ? void 0 : lastPcTransaction.txHash)) {
|
|
199
|
+
const failedPcTx = pushChainUniversalTx.pcTx.find((pcTx) => pcTx.status === 'FAILED' && pcTx.errorMsg);
|
|
200
|
+
const errorDetails = (failedPcTx === null || failedPcTx === void 0 ? void 0 : failedPcTx.errorMsg) ? `: ${failedPcTx.errorMsg}` : '';
|
|
201
|
+
throw new Error(`No transaction hash found in Push Chain response for gateway tx: ${gatewayTxHash}${errorDetails}`);
|
|
202
|
+
}
|
|
203
|
+
const tx = yield ctx.pushClient.getTransaction(lastPcTransaction.txHash);
|
|
204
|
+
return transformFn(tx, eventBuffer);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=push-chain-tx.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uniswap V3 exact-output quoting — extracted from Orchestrator.
|
|
3
|
+
*/
|
|
4
|
+
import { ConversionQuote, MoveableToken, PayableToken } from '../../constants/tokens';
|
|
5
|
+
import type { OrchestratorContext } from './context';
|
|
6
|
+
export declare function quoteExactOutput(ctx: OrchestratorContext, amountOut: bigint, { from, to, }: {
|
|
7
|
+
from: PayableToken | undefined;
|
|
8
|
+
to: MoveableToken | undefined;
|
|
9
|
+
}): Promise<ConversionQuote>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Uniswap V3 exact-output quoting — extracted from Orchestrator.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.quoteExactOutput = quoteExactOutput;
|
|
7
|
+
const tslib_1 = require("tslib");
|
|
8
|
+
const viem_1 = require("viem");
|
|
9
|
+
const chain_1 = require("../../constants/chain");
|
|
10
|
+
const enums_1 = require("../../constants/enums");
|
|
11
|
+
const utils_1 = require("../../utils");
|
|
12
|
+
const evm_client_1 = require("../../vm-client/evm-client");
|
|
13
|
+
function quoteExactOutput(ctx_1, amountOut_1, _a) {
|
|
14
|
+
return tslib_1.__awaiter(this, arguments, void 0, function* (ctx, amountOut, { from, to, }) {
|
|
15
|
+
var _b, _c, _d;
|
|
16
|
+
const originChain = ctx.universalSigner.account.chain;
|
|
17
|
+
if (originChain !== enums_1.CHAIN.ETHEREUM_MAINNET &&
|
|
18
|
+
originChain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
|
|
19
|
+
throw new Error('Exact-output quoting is only supported on Ethereum Mainnet and Sepolia for now');
|
|
20
|
+
}
|
|
21
|
+
if (!from)
|
|
22
|
+
throw new Error('from token is required');
|
|
23
|
+
if (!to)
|
|
24
|
+
throw new Error('to token is required');
|
|
25
|
+
const rpcUrls = ctx.rpcUrls[originChain] || chain_1.CHAIN_INFO[originChain].defaultRPC;
|
|
26
|
+
const evm = new evm_client_1.EvmClient({ rpcUrls });
|
|
27
|
+
const factoryFromConfig = (_b = chain_1.CHAIN_INFO[originChain].dex) === null || _b === void 0 ? void 0 : _b.uniV3Factory;
|
|
28
|
+
const quoterFromConfig = (_c = chain_1.CHAIN_INFO[originChain].dex) === null || _c === void 0 ? void 0 : _c.uniV3QuoterV2;
|
|
29
|
+
if (!factoryFromConfig || !quoterFromConfig) {
|
|
30
|
+
throw new Error('Uniswap V3 addresses not configured for this chain');
|
|
31
|
+
}
|
|
32
|
+
const UNISWAP_V3_FACTORY = factoryFromConfig;
|
|
33
|
+
const UNISWAP_V3_QUOTER_V2 = quoterFromConfig;
|
|
34
|
+
const factoryAbi = (0, viem_1.parseAbi)([
|
|
35
|
+
'function getPool(address tokenA, address tokenB, uint24 fee) view returns (address)',
|
|
36
|
+
]);
|
|
37
|
+
const quoterAbi = (0, viem_1.parseAbi)([
|
|
38
|
+
'function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)',
|
|
39
|
+
]);
|
|
40
|
+
const poolAbi = (0, viem_1.parseAbi)([
|
|
41
|
+
'function liquidity() view returns (uint128)',
|
|
42
|
+
]);
|
|
43
|
+
const feeTiers = [100, 500, 3000, 10000];
|
|
44
|
+
let bestAmountIn = null;
|
|
45
|
+
let bestFee = null;
|
|
46
|
+
for (const fee of feeTiers) {
|
|
47
|
+
const poolAddress = yield evm.readContract({
|
|
48
|
+
abi: factoryAbi,
|
|
49
|
+
address: UNISWAP_V3_FACTORY,
|
|
50
|
+
functionName: 'getPool',
|
|
51
|
+
args: [from.address, to.address, fee],
|
|
52
|
+
});
|
|
53
|
+
const isZero = !poolAddress ||
|
|
54
|
+
poolAddress.toLowerCase() ===
|
|
55
|
+
'0x0000000000000000000000000000000000000000';
|
|
56
|
+
if (isZero)
|
|
57
|
+
continue;
|
|
58
|
+
try {
|
|
59
|
+
const liquidity = yield evm.readContract({
|
|
60
|
+
abi: poolAbi,
|
|
61
|
+
address: poolAddress,
|
|
62
|
+
functionName: 'liquidity',
|
|
63
|
+
args: [],
|
|
64
|
+
});
|
|
65
|
+
if (!liquidity || liquidity === BigInt(0))
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
catch (_e) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const result = yield evm.readContract({
|
|
73
|
+
abi: quoterAbi,
|
|
74
|
+
address: UNISWAP_V3_QUOTER_V2,
|
|
75
|
+
functionName: 'quoteExactOutputSingle',
|
|
76
|
+
args: [
|
|
77
|
+
{
|
|
78
|
+
tokenIn: from.address,
|
|
79
|
+
tokenOut: to.address,
|
|
80
|
+
amount: amountOut,
|
|
81
|
+
fee,
|
|
82
|
+
sqrtPriceLimitX96: BigInt(0),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
const amountIn = (_d = result === null || result === void 0 ? void 0 : result[0]) !== null && _d !== void 0 ? _d : BigInt(0);
|
|
87
|
+
if (amountIn === BigInt(0))
|
|
88
|
+
continue;
|
|
89
|
+
if (bestAmountIn === null || amountIn < bestAmountIn) {
|
|
90
|
+
bestAmountIn = amountIn;
|
|
91
|
+
bestFee = fee;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (_f) {
|
|
95
|
+
// try next fee
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (bestAmountIn === null || bestFee === null) {
|
|
99
|
+
throw new Error('No direct Uniswap V3 pool found for the given token pair on common fee tiers');
|
|
100
|
+
}
|
|
101
|
+
const amountInBig = BigInt(bestAmountIn);
|
|
102
|
+
const amountInHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountInBig, { decimals: from.decimals }));
|
|
103
|
+
const amountOutHuman = parseFloat(utils_1.Utils.helpers.formatUnits(amountOut, { decimals: to.decimals }));
|
|
104
|
+
const rate = amountInHuman > 0 ? amountOutHuman / amountInHuman : 0;
|
|
105
|
+
return {
|
|
106
|
+
amountIn: bestAmountIn.toString(),
|
|
107
|
+
amountOut: amountOut.toString(),
|
|
108
|
+
rate,
|
|
109
|
+
route: [from.symbol, to.symbol],
|
|
110
|
+
timestamp: Date.now(),
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=quote.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rescue funds flow — extracted from Orchestrator.rescueFunds.
|
|
3
|
+
*
|
|
4
|
+
* Recovers stuck tokens from failed inbound transactions by building
|
|
5
|
+
* a rescue multicall and executing it through the standard execute() flow.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExecuteParams, RescueFundsParams, UniversalTxResponse } from '../orchestrator.types';
|
|
8
|
+
import type { OrchestratorContext } from './context';
|
|
9
|
+
/**
|
|
10
|
+
* Rescue stuck funds on a source chain.
|
|
11
|
+
* When a CEA-to-Push inbound transaction fails, tokens get locked in the
|
|
12
|
+
* Vault on the source chain. This triggers a manual revert via TSS to
|
|
13
|
+
* release those funds back to the user.
|
|
14
|
+
*
|
|
15
|
+
* @param ctx - Orchestrator context
|
|
16
|
+
* @param params - RescueFundsParams with universalTxId and prc20 token
|
|
17
|
+
* @param executeFn - The Orchestrator.execute() method (avoids circular dep)
|
|
18
|
+
* @returns Transaction response
|
|
19
|
+
*/
|
|
20
|
+
export declare function rescueFunds(ctx: OrchestratorContext, params: RescueFundsParams, executeFn: (params: ExecuteParams) => Promise<UniversalTxResponse>): Promise<UniversalTxResponse>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rescue funds flow — extracted from Orchestrator.rescueFunds.
|
|
4
|
+
*
|
|
5
|
+
* Recovers stuck tokens from failed inbound transactions by building
|
|
6
|
+
* a rescue multicall and executing it through the standard execute() flow.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.rescueFunds = rescueFunds;
|
|
10
|
+
const tslib_1 = require("tslib");
|
|
11
|
+
const viem_1 = require("viem");
|
|
12
|
+
const universalGatewayPC_evm_1 = require("../../constants/abi/universalGatewayPC.evm");
|
|
13
|
+
const selectors_1 = require("../../constants/selectors");
|
|
14
|
+
const context_1 = require("./context");
|
|
15
|
+
const helpers_1 = require("./helpers");
|
|
16
|
+
const uea_manager_1 = require("./uea-manager");
|
|
17
|
+
const gas_calculator_1 = require("./gas-calculator");
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// rescueFunds
|
|
20
|
+
// ============================================================================
|
|
21
|
+
/**
|
|
22
|
+
* Rescue stuck funds on a source chain.
|
|
23
|
+
* When a CEA-to-Push inbound transaction fails, tokens get locked in the
|
|
24
|
+
* Vault on the source chain. This triggers a manual revert via TSS to
|
|
25
|
+
* release those funds back to the user.
|
|
26
|
+
*
|
|
27
|
+
* @param ctx - Orchestrator context
|
|
28
|
+
* @param params - RescueFundsParams with universalTxId and prc20 token
|
|
29
|
+
* @param executeFn - The Orchestrator.execute() method (avoids circular dep)
|
|
30
|
+
* @returns Transaction response
|
|
31
|
+
*/
|
|
32
|
+
function rescueFunds(ctx, params, executeFn) {
|
|
33
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
// Validate universalTxId format (bytes32: 0x + 64 hex chars)
|
|
35
|
+
if (!params.universalTxId ||
|
|
36
|
+
params.universalTxId.length !== 66 ||
|
|
37
|
+
!/^0x[0-9a-fA-F]{64}$/.test(params.universalTxId)) {
|
|
38
|
+
throw new Error(`Invalid universalTxId: expected 0x-prefixed bytes32 (66 chars), got "${params.universalTxId}"`);
|
|
39
|
+
}
|
|
40
|
+
// Validate prc20 is not zero address
|
|
41
|
+
if (!params.prc20 ||
|
|
42
|
+
params.prc20 === selectors_1.ZERO_ADDRESS) {
|
|
43
|
+
throw new Error('prc20 token address cannot be zero address');
|
|
44
|
+
}
|
|
45
|
+
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
46
|
+
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
47
|
+
(0, context_1.printLog)(ctx, `rescueFunds — universalTxId=${params.universalTxId}, prc20=${params.prc20}, gateway=${gatewayPcAddress}`);
|
|
48
|
+
// Pre-fetch UEA status
|
|
49
|
+
const [ueaCode, ueaBalance] = yield Promise.all([
|
|
50
|
+
ctx.pushClient.publicClient.getCode({ address: ueaAddress }),
|
|
51
|
+
ctx.pushClient.getBalance(ueaAddress),
|
|
52
|
+
]);
|
|
53
|
+
const isUEADeployed = ueaCode !== undefined;
|
|
54
|
+
const ueaNonce = isUEADeployed ? yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress) : BigInt(0);
|
|
55
|
+
// Query rescue gas fee
|
|
56
|
+
let nativeValueForGas = BigInt(0);
|
|
57
|
+
try {
|
|
58
|
+
const result = yield (0, gas_calculator_1.queryRescueGasFee)(ctx, params.prc20);
|
|
59
|
+
nativeValueForGas = result.nativeValueForGas;
|
|
60
|
+
(0, context_1.printLog)(ctx, `rescueFunds — queried gas fee: gasFee=${result.gasFee.toString()}, gasToken=${result.gasToken}, nativeValueForGas=${nativeValueForGas.toString()}`);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
throw new Error(`Failed to query rescue gas fee: ${err}`);
|
|
64
|
+
}
|
|
65
|
+
// Adjust nativeValueForGas using the same balance-capping pattern as outbound
|
|
66
|
+
const EVM_NATIVE_VALUE_TARGET = BigInt(200e18); // 200 UPC
|
|
67
|
+
const EVM_GAS_RESERVE = BigInt(3e18); // 3 UPC for tx overhead
|
|
68
|
+
const currentBalance = ueaBalance;
|
|
69
|
+
let adjustedValue;
|
|
70
|
+
if (currentBalance > EVM_NATIVE_VALUE_TARGET + EVM_GAS_RESERVE) {
|
|
71
|
+
adjustedValue = EVM_NATIVE_VALUE_TARGET;
|
|
72
|
+
}
|
|
73
|
+
else if (currentBalance > EVM_GAS_RESERVE) {
|
|
74
|
+
adjustedValue = currentBalance - EVM_GAS_RESERVE;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
adjustedValue = nativeValueForGas;
|
|
78
|
+
}
|
|
79
|
+
if (adjustedValue !== nativeValueForGas) {
|
|
80
|
+
(0, context_1.printLog)(ctx, `rescueFunds — adjusting nativeValueForGas from ${nativeValueForGas.toString()} to ${adjustedValue.toString()} (UEA balance: ${currentBalance.toString()})`);
|
|
81
|
+
nativeValueForGas = adjustedValue;
|
|
82
|
+
}
|
|
83
|
+
// Build single rescue multicall (no PRC-20 approval needed — no burn)
|
|
84
|
+
const rescueCallData = (0, viem_1.encodeFunctionData)({
|
|
85
|
+
abi: universalGatewayPC_evm_1.UNIVERSAL_GATEWAY_PC,
|
|
86
|
+
functionName: 'rescueFundsOnSourceChain',
|
|
87
|
+
args: [params.universalTxId, params.prc20],
|
|
88
|
+
});
|
|
89
|
+
const pushChainMulticalls = [
|
|
90
|
+
{
|
|
91
|
+
to: gatewayPcAddress,
|
|
92
|
+
value: nativeValueForGas,
|
|
93
|
+
data: rescueCallData,
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
(0, context_1.printLog)(ctx, `rescueFunds — built rescue multicall, nativeValueForGas=${nativeValueForGas.toString()}`);
|
|
97
|
+
const multicallNativeValue = pushChainMulticalls.reduce((sum, mc) => { var _a; return sum + ((_a = mc.value) !== null && _a !== void 0 ? _a : BigInt(0)); }, BigInt(0));
|
|
98
|
+
const executeParams = {
|
|
99
|
+
to: ueaAddress,
|
|
100
|
+
value: multicallNativeValue,
|
|
101
|
+
data: pushChainMulticalls,
|
|
102
|
+
_ueaStatus: {
|
|
103
|
+
isDeployed: isUEADeployed,
|
|
104
|
+
nonce: ueaNonce,
|
|
105
|
+
balance: ueaBalance,
|
|
106
|
+
},
|
|
107
|
+
_skipFeeLocking: true,
|
|
108
|
+
};
|
|
109
|
+
return executeFn(executeParams);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=rescue.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response builder functions extracted from Orchestrator.
|
|
3
|
+
*
|
|
4
|
+
* Contains: queryUniversalTxStatusFromGatewayTx, trackTransaction,
|
|
5
|
+
* transformToUniversalTxResponse, and the ResponseBuilderCallbacks interface.
|
|
6
|
+
*/
|
|
7
|
+
import { UniversalTx } from '../../generated/uexecutor/v1/types';
|
|
8
|
+
import { ProgressEvent } from '../../progress-hook/progress-hook.types';
|
|
9
|
+
import { EvmClient } from '../../vm-client/evm-client';
|
|
10
|
+
import type { TxResponse } from '../../vm-client/vm-client.types';
|
|
11
|
+
import type { UniversalTxReceipt, UniversalTxResponse, TrackTransactionOptions } from '../orchestrator.types';
|
|
12
|
+
import type { OrchestratorContext } from './context';
|
|
13
|
+
export interface ResponseBuilderCallbacks {
|
|
14
|
+
trackTransaction: (hash: string, opts?: any) => Promise<UniversalTxResponse>;
|
|
15
|
+
waitForOutboundTx: (hash: string, opts?: any) => Promise<any>;
|
|
16
|
+
transformToUniversalTxReceipt: (receipt: any, response: any) => UniversalTxReceipt;
|
|
17
|
+
printLog: (msg: string) => void;
|
|
18
|
+
outboundConstants: {
|
|
19
|
+
initialWaitMs: number;
|
|
20
|
+
pollingIntervalMs: number;
|
|
21
|
+
maxTimeoutMs: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export declare function queryUniversalTxStatusFromGatewayTx(ctx: OrchestratorContext, evmClient: EvmClient | undefined, gatewayAddress: `0x${string}` | undefined, txHash: string, evmGatewayMethod: 'sendFunds' | 'sendTxWithFunds' | 'sendTxWithGas'): Promise<UniversalTx | undefined>;
|
|
25
|
+
export declare function trackTransaction(ctx: OrchestratorContext, txHash: string, options?: TrackTransactionOptions, callbacks?: ResponseBuilderCallbacks): Promise<UniversalTxResponse>;
|
|
26
|
+
export declare function transformToUniversalTxResponse(ctx: OrchestratorContext, tx: TxResponse, eventBuffer: ProgressEvent[] | undefined, callbacks: ResponseBuilderCallbacks): Promise<UniversalTxResponse>;
|