@pushchain/core 1.1.40 → 2.0.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/CHANGELOG.md +7 -0
- package/package.json +3 -4
- package/src/index.js +2 -1
- package/src/index.js.map +1 -1
- package/src/lib/constants/abi/feeLocker.evm.js +10 -0
- package/src/lib/constants/abi/feeLocker.evm.js.map +1 -1
- package/src/lib/constants/abi/feeLocker.json +2133 -94
- package/src/lib/constants/abi/index.d.ts +0 -2
- package/src/lib/constants/abi/index.js +1 -5
- package/src/lib/constants/abi/index.js.map +1 -1
- package/src/lib/constants/chain.js +3 -3
- package/src/lib/constants/index.d.ts +0 -1
- package/src/lib/constants/index.js.map +1 -1
- package/src/lib/index.d.ts +0 -1
- package/src/lib/index.js.map +1 -1
- package/src/lib/orchestrator/orchestrator.d.ts +0 -18
- package/src/lib/orchestrator/orchestrator.js +46 -333
- package/src/lib/orchestrator/orchestrator.js.map +1 -1
- package/src/lib/orchestrator/orchestrator.types.d.ts +9 -14
- package/src/lib/price-fetch/price-fetch.js +1 -1
- package/src/lib/price-fetch/price-fetch.js.map +1 -1
- package/src/lib/progress-hook/progress-hook.js +0 -66
- package/src/lib/progress-hook/progress-hook.js.map +1 -1
- package/src/lib/progress-hook/progress-hook.types.d.ts +0 -9
- package/src/lib/progress-hook/progress-hook.types.js +0 -12
- package/src/lib/progress-hook/progress-hook.types.js.map +1 -1
- package/src/lib/push-chain/push-chain.d.ts +0 -17
- package/src/lib/push-chain/push-chain.js +0 -190
- package/src/lib/push-chain/push-chain.js.map +1 -1
- package/src/lib/utils.d.ts +2 -98
- package/src/lib/utils.js +8 -264
- package/src/lib/utils.js.map +1 -1
- package/src/lib/constants/abi/erc20.evm.d.ts +0 -36
- package/src/lib/constants/abi/erc20.evm.js +0 -26
- package/src/lib/constants/abi/erc20.evm.js.map +0 -1
- package/src/lib/constants/abi/universalGatewayV0.evm.d.ts +0 -31
- package/src/lib/constants/abi/universalGatewayV0.evm.js +0 -141
- package/src/lib/constants/abi/universalGatewayV0.evm.js.map +0 -1
- package/src/lib/constants/tokens.d.ts +0 -64
- package/src/lib/constants/tokens.js +0 -218
- package/src/lib/constants/tokens.js.map +0 -1
|
@@ -3,5 +3,3 @@ export { default as FEE_LOCKER_SVM } from './feeLocker.json';
|
|
|
3
3
|
export { FACTORY_V1 } from './factoryV1';
|
|
4
4
|
export { UEA_EVM } from './uea.evm';
|
|
5
5
|
export { UEA_SVM } from './uea.svm';
|
|
6
|
-
export { UNIVERSAL_GATEWAY_V0 } from './universalGatewayV0.evm';
|
|
7
|
-
export { ERC20_EVM } from './erc20.evm';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.UEA_SVM = exports.UEA_EVM = exports.FACTORY_V1 = exports.FEE_LOCKER_SVM = exports.FEE_LOCKER_EVM = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
var feeLocker_evm_1 = require("./feeLocker.evm");
|
|
6
6
|
Object.defineProperty(exports, "FEE_LOCKER_EVM", { enumerable: true, get: function () { return feeLocker_evm_1.FEE_LOCKER_EVM; } });
|
|
@@ -12,8 +12,4 @@ var uea_evm_1 = require("./uea.evm");
|
|
|
12
12
|
Object.defineProperty(exports, "UEA_EVM", { enumerable: true, get: function () { return uea_evm_1.UEA_EVM; } });
|
|
13
13
|
var uea_svm_1 = require("./uea.svm");
|
|
14
14
|
Object.defineProperty(exports, "UEA_SVM", { enumerable: true, get: function () { return uea_svm_1.UEA_SVM; } });
|
|
15
|
-
var universalGatewayV0_evm_1 = require("./universalGatewayV0.evm");
|
|
16
|
-
Object.defineProperty(exports, "UNIVERSAL_GATEWAY_V0", { enumerable: true, get: function () { return universalGatewayV0_evm_1.UNIVERSAL_GATEWAY_V0; } });
|
|
17
|
-
var erc20_evm_1 = require("./erc20.evm");
|
|
18
|
-
Object.defineProperty(exports, "ERC20_EVM", { enumerable: true, get: function () { return erc20_evm_1.ERC20_EVM; } });
|
|
19
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/src/lib/constants/abi/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAiD;AAAxC,+GAAA,cAAc,OAAA;AACvB,mDAA6D;AAApD,yIAAA,OAAO,OAAkB;AAClC,yCAAyC;AAAhC,uGAAA,UAAU,OAAA;AACnB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/src/lib/constants/abi/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAiD;AAAxC,+GAAA,cAAc,OAAA;AACvB,mDAA6D;AAApD,yIAAA,OAAO,OAAkB;AAClC,yCAAyC;AAAhC,uGAAA,UAAU,OAAA;AACnB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,qCAAoC;AAA3B,kGAAA,OAAO,OAAA"}
|
|
@@ -17,8 +17,8 @@ exports.VM_NAMESPACE = {
|
|
|
17
17
|
*/
|
|
18
18
|
exports.UEA_PROXY = {
|
|
19
19
|
[enums_1.PUSH_NETWORK.MAINNET]: '0xTBD',
|
|
20
|
-
[enums_1.PUSH_NETWORK.TESTNET_DONUT]: '
|
|
21
|
-
[enums_1.PUSH_NETWORK.TESTNET]: '
|
|
20
|
+
[enums_1.PUSH_NETWORK.TESTNET_DONUT]: '0x53179F638eC4613015EC1aA83e89B48BE6ed6d6d',
|
|
21
|
+
[enums_1.PUSH_NETWORK.TESTNET]: '0x53179F638eC4613015EC1aA83e89B48BE6ed6d6d',
|
|
22
22
|
[enums_1.PUSH_NETWORK.LOCALNET]: '0x2FE70447492307108Bdc7Ff6BaB33Ff37Dacc479',
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
@@ -90,7 +90,7 @@ exports.CHAIN_INFO = {
|
|
|
90
90
|
[enums_1.CHAIN.SOLANA_DEVNET]: {
|
|
91
91
|
chainId: 'EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
|
|
92
92
|
vm: enums_1.VM.SVM,
|
|
93
|
-
lockerContract: '
|
|
93
|
+
lockerContract: 'CFVSincHYbETh2k7w6u1ENEkjbSLtveRCEBupKidw2VS',
|
|
94
94
|
defaultRPC: ['https://api.devnet.solana.com'],
|
|
95
95
|
confirmations: 1,
|
|
96
96
|
timeout: 5000,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CHAIN, LIBRARY, PUSH_NETWORK } from './enums';
|
|
2
2
|
import { TypedDataDomain, TypedData } from '../universal/signer/signer.types';
|
|
3
|
-
export type { MoveableToken, PayableToken } from './tokens';
|
|
4
3
|
export declare const CONSTANTS: {
|
|
5
4
|
PUSH_NETWORK: typeof PUSH_NETWORK;
|
|
6
5
|
CHAIN: typeof CHAIN;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/constants/index.ts"],"names":[],"mappings":";;;AAAA,mCAAuD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/core/src/lib/constants/index.ts"],"names":[],"mappings":";;;AAAA,mCAAuD;AAGvD,+EAA+E;AAClE,QAAA,SAAS,GAAG;IACvB,YAAY,EAAZ,oBAAY;IACZ,KAAK,EAAL,aAAK;IACL,OAAO,EAAP,eAAO;CACR,CAAC"}
|
package/src/lib/index.d.ts
CHANGED
package/src/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,wDAAoD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/src/lib/index.ts"],"names":[],"mappings":";;;AAAA,wDAAoD;AAE3C,0FAFA,sBAAS,OAEA"}
|
|
@@ -75,23 +75,6 @@ export declare class Orchestrator {
|
|
|
75
75
|
private getUEANonce;
|
|
76
76
|
getUOA(): UniversalAccount;
|
|
77
77
|
private waitForLockerFeeConfirmation;
|
|
78
|
-
private ensureErc20Allowance;
|
|
79
|
-
/**
|
|
80
|
-
* Ensures we're on Sepolia, returns EVM client and gateway address.
|
|
81
|
-
*/
|
|
82
|
-
private ensureSepoliaGateway;
|
|
83
|
-
/**
|
|
84
|
-
* Computes UEA and fetches its nonce if deployed; returns 0 otherwise.
|
|
85
|
-
*/
|
|
86
|
-
private getUeaNonceForExecution;
|
|
87
|
-
/**
|
|
88
|
-
* Returns UEA deployment status and nonce (0 if not deployed).
|
|
89
|
-
*/
|
|
90
|
-
private getUeaStatusAndNonce;
|
|
91
|
-
/**
|
|
92
|
-
* Builds UniversalPayload for the gateway and computes the native gas deposit.
|
|
93
|
-
*/
|
|
94
|
-
private buildGatewayPayloadAndGas;
|
|
95
78
|
/********************************** HELPER FUNCTIONS **************************************************/
|
|
96
79
|
/**
|
|
97
80
|
* Transforms a TransactionReceipt to UniversalTxReceipt format
|
|
@@ -113,5 +96,4 @@ export declare class Orchestrator {
|
|
|
113
96
|
private validateMainnetConnection;
|
|
114
97
|
private printLog;
|
|
115
98
|
private executeProgressHook;
|
|
116
|
-
private waitForEvmConfirmationsWithCountdown;
|
|
117
99
|
}
|
|
@@ -18,7 +18,6 @@ const anchor_1 = require("@coral-xyz/anchor");
|
|
|
18
18
|
const progress_hook_types_1 = require("../progress-hook/progress-hook.types");
|
|
19
19
|
const progress_hook_1 = tslib_1.__importDefault(require("../progress-hook/progress-hook"));
|
|
20
20
|
const uea_evm_1 = require("../constants/abi/uea.evm");
|
|
21
|
-
const tokens_1 = require("../constants/tokens");
|
|
22
21
|
class Orchestrator {
|
|
23
22
|
constructor(universalSigner, pushNetwork, rpcUrls = {}, printTraces = false, progressHook) {
|
|
24
23
|
this.universalSigner = universalSigner;
|
|
@@ -64,173 +63,6 @@ class Orchestrator {
|
|
|
64
63
|
execute(execute) {
|
|
65
64
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
66
65
|
try {
|
|
67
|
-
// FUNDS_TX short-circuit: Bridge tokens from Ethereum Sepolia to Push Chain
|
|
68
|
-
// No payload execution; supports USDC/USDT ERC-20 via UniversalGatewayV0.sendFunds
|
|
69
|
-
if (execute.funds) {
|
|
70
|
-
if (!execute.data || execute.data === '0x') {
|
|
71
|
-
// Disallow user-provided `value` for funds-only bridging. The SDK derives
|
|
72
|
-
// origin-chain msg.value automatically from the funds input:
|
|
73
|
-
// - Native path: msg.value = bridgeAmount
|
|
74
|
-
// - ERC-20 path: msg.value = 0
|
|
75
|
-
if (execute.value !== undefined && execute.value !== BigInt(0)) {
|
|
76
|
-
throw new Error('Do not set `value` when using funds bridging; the SDK sets origin msg.value from `funds.amount` automatically');
|
|
77
|
-
}
|
|
78
|
-
const chain = this.universalSigner.account.chain;
|
|
79
|
-
if (chain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
|
|
80
|
-
throw new Error('Funds bridging is only supported on Ethereum Sepolia for now');
|
|
81
|
-
}
|
|
82
|
-
// Progress: Origin chain detected
|
|
83
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_01, chain);
|
|
84
|
-
const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
|
|
85
|
-
const rpcUrls = this.rpcUrls[chain] || defaultRPC;
|
|
86
|
-
const evmClient = new evm_client_1.EvmClient({ rpcUrls });
|
|
87
|
-
const gatewayAddress = lockerContract;
|
|
88
|
-
if (!gatewayAddress) {
|
|
89
|
-
throw new Error('Universal Gateway address not configured');
|
|
90
|
-
}
|
|
91
|
-
// Resolve token: default to native token based on VM (ETH for EVM, SOL for SVM)
|
|
92
|
-
if (!execute.funds.token) {
|
|
93
|
-
const available = tokens_1.MOVEABLE_TOKENS[chain] || [];
|
|
94
|
-
const vm = chain_1.CHAIN_INFO[chain].vm;
|
|
95
|
-
const preferredSymbol = vm === enums_1.VM.EVM ? 'ETH' : vm === enums_1.VM.SVM ? 'SOL' : undefined;
|
|
96
|
-
const nativeToken = preferredSymbol
|
|
97
|
-
? available.find((t) => t.symbol === preferredSymbol)
|
|
98
|
-
: undefined;
|
|
99
|
-
if (!nativeToken) {
|
|
100
|
-
throw new Error('Native token not configured for this chain');
|
|
101
|
-
}
|
|
102
|
-
execute.funds.token = nativeToken;
|
|
103
|
-
}
|
|
104
|
-
const tokenAddr = execute.funds.token.address;
|
|
105
|
-
const amount = execute.funds.amount;
|
|
106
|
-
const symbol = execute.funds.token.symbol;
|
|
107
|
-
// Funds Flow: Preparing funds transfer
|
|
108
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_01, amount, execute.funds.token.decimals, symbol);
|
|
109
|
-
// Approve gateway to pull tokens if ERC-20 (not native sentinel)
|
|
110
|
-
if (execute.funds.token.mechanism === 'approve') {
|
|
111
|
-
yield this.ensureErc20Allowance(evmClient, tokenAddr, gatewayAddress, amount);
|
|
112
|
-
}
|
|
113
|
-
else if (execute.funds.token.mechanism === 'permit2') {
|
|
114
|
-
throw new Error('Permit2 is not supported yet');
|
|
115
|
-
}
|
|
116
|
-
else if (execute.funds.token.mechanism === 'native') {
|
|
117
|
-
// Native flow uses msg.value == bridgeAmount and bridgeToken = address(0)
|
|
118
|
-
}
|
|
119
|
-
// Call UniversalGatewayV0.sendFunds(recipient, bridgeToken, bridgeAmount, revertCFG)
|
|
120
|
-
const recipient = execute.to; // funds to recipient on Push Chain
|
|
121
|
-
const isNative = execute.funds.token.mechanism === 'native';
|
|
122
|
-
const bridgeToken = execute.funds.token.mechanism === 'approve'
|
|
123
|
-
? tokenAddr
|
|
124
|
-
: '0x0000000000000000000000000000000000000000';
|
|
125
|
-
const bridgeAmount = amount;
|
|
126
|
-
const revertCFG = {
|
|
127
|
-
fundRecipient: this.universalSigner.account
|
|
128
|
-
.address,
|
|
129
|
-
revertMsg: '0x',
|
|
130
|
-
}; // typed by viem via ABI
|
|
131
|
-
let txHash;
|
|
132
|
-
try {
|
|
133
|
-
txHash = yield evmClient.writeContract({
|
|
134
|
-
abi: abi_1.UNIVERSAL_GATEWAY_V0,
|
|
135
|
-
address: gatewayAddress,
|
|
136
|
-
functionName: 'sendFunds',
|
|
137
|
-
args: [recipient, bridgeToken, bridgeAmount, revertCFG],
|
|
138
|
-
signer: this.universalSigner,
|
|
139
|
-
value: isNative ? bridgeAmount : BigInt(0),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
// Payload Flow: Verification declined by user (wallet rejection)
|
|
144
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_04_04);
|
|
145
|
-
throw err;
|
|
146
|
-
}
|
|
147
|
-
// Payload Flow: Verification Success
|
|
148
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_04_03);
|
|
149
|
-
// Funds Flow: Funds lock submitted
|
|
150
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
151
|
-
// Wait for confirmations on origin chain per chain config with countdown
|
|
152
|
-
yield this.waitForEvmConfirmationsWithCountdown(evmClient, txHash, 14, 210000 // CHAIN_INFO[chain].timeout
|
|
153
|
-
);
|
|
154
|
-
// Funds Flow: Confirmed on origin
|
|
155
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06);
|
|
156
|
-
// Fetch origin-chain tx and transform to UniversalTxResponse
|
|
157
|
-
const tx = yield evmClient.getTransaction(txHash);
|
|
158
|
-
return yield this.transformToUniversalTxResponse(tx);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
// Bridge funds + execute payload. Support ERC-20 (approve) and native ETH.
|
|
162
|
-
const { chain, evmClient, gatewayAddress } = this.ensureSepoliaGateway();
|
|
163
|
-
if (!execute.funds.token) {
|
|
164
|
-
throw new Error('Token is required for bridging with payload');
|
|
165
|
-
}
|
|
166
|
-
const mechanism = execute.funds.token.mechanism;
|
|
167
|
-
if (mechanism !== 'approve') {
|
|
168
|
-
throw new Error('Only ERC-20 tokens are supported for funds+payload; native and permit2 are not supported yet');
|
|
169
|
-
}
|
|
170
|
-
const { nonce } = yield this.getUeaStatusAndNonce();
|
|
171
|
-
const { payload: universalPayload, gasAmount } = yield this.buildGatewayPayloadAndGas(execute, nonce);
|
|
172
|
-
const [minMax] = yield Promise.all([
|
|
173
|
-
evmClient.readContract({
|
|
174
|
-
abi: abi_1.UNIVERSAL_GATEWAY_V0,
|
|
175
|
-
address: gatewayAddress,
|
|
176
|
-
functionName: 'getMinMaxValueForNative',
|
|
177
|
-
}),
|
|
178
|
-
]);
|
|
179
|
-
const minAllowed = minMax[0];
|
|
180
|
-
const maxAllowed = minMax[1];
|
|
181
|
-
if (gasAmount < minAllowed || gasAmount > maxAllowed) {
|
|
182
|
-
throw new Error(`Gas deposit out of range. min=${minAllowed.toString()} max=${maxAllowed.toString()} got=${gasAmount.toString()}`);
|
|
183
|
-
}
|
|
184
|
-
const revertCFG = {
|
|
185
|
-
fundRecipient: this.universalSigner.account
|
|
186
|
-
.address,
|
|
187
|
-
revertMsg: '0x',
|
|
188
|
-
};
|
|
189
|
-
// ERC-20 bridge token path
|
|
190
|
-
const tokenAddr = execute.funds.token.address;
|
|
191
|
-
const bridgeAmount = execute.funds.amount;
|
|
192
|
-
const symbol = execute.funds.token.symbol;
|
|
193
|
-
// Funds Flow: Preparing funds transfer
|
|
194
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_01, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
195
|
-
yield this.ensureErc20Allowance(evmClient, tokenAddr, gatewayAddress, bridgeAmount);
|
|
196
|
-
let txHash;
|
|
197
|
-
try {
|
|
198
|
-
txHash = yield evmClient.writeContract({
|
|
199
|
-
abi: abi_1.UNIVERSAL_GATEWAY_V0,
|
|
200
|
-
address: gatewayAddress,
|
|
201
|
-
functionName: 'sendTxWithFunds',
|
|
202
|
-
args: [
|
|
203
|
-
tokenAddr,
|
|
204
|
-
bridgeAmount,
|
|
205
|
-
universalPayload,
|
|
206
|
-
revertCFG,
|
|
207
|
-
viem_1.zeroHash,
|
|
208
|
-
],
|
|
209
|
-
signer: this.universalSigner,
|
|
210
|
-
value: gasAmount,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
catch (err) {
|
|
214
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_04_04);
|
|
215
|
-
throw err;
|
|
216
|
-
}
|
|
217
|
-
// Payload Flow: Verification Success
|
|
218
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_04_03);
|
|
219
|
-
// Funds Flow: Funds lock submitted
|
|
220
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_02, txHash, bridgeAmount, execute.funds.token.decimals, symbol);
|
|
221
|
-
// Awaiting confirmations
|
|
222
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_03, 1);
|
|
223
|
-
yield evmClient.waitForConfirmations({
|
|
224
|
-
txHash: txHash,
|
|
225
|
-
confirmations: 1,
|
|
226
|
-
timeoutMs: chain_1.CHAIN_INFO[chain].timeout,
|
|
227
|
-
});
|
|
228
|
-
// Funds Flow: Confirmed on origin
|
|
229
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_06);
|
|
230
|
-
const tx = yield evmClient.getTransaction(txHash);
|
|
231
|
-
return yield this.transformToUniversalTxResponse(tx);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
66
|
// Set default value for value if undefined
|
|
235
67
|
if (execute.value === undefined) {
|
|
236
68
|
execute.value = BigInt(0);
|
|
@@ -278,14 +110,52 @@ class Orchestrator {
|
|
|
278
110
|
let feeLockTxHash = execute.feeLockTxHash;
|
|
279
111
|
if (feeLockTxHash && !feeLockTxHash.startsWith('0x')) {
|
|
280
112
|
// decode svm base58
|
|
281
|
-
|
|
113
|
+
const decoded = anchor_1.utils.bytes.bs58.decode(feeLockTxHash);
|
|
114
|
+
feeLockTxHash = (0, viem_1.bytesToHex)(Uint8Array.from(decoded));
|
|
282
115
|
}
|
|
283
116
|
// Fee locking is required if UEA is not deployed OR insufficient funds
|
|
284
117
|
const feeLockingRequired = (!isUEADeployed || funds < requiredFunds) && !feeLockTxHash;
|
|
118
|
+
// Support multicall payload encoding when execute.data is an array
|
|
119
|
+
let payloadData;
|
|
120
|
+
if (Array.isArray(execute.data)) {
|
|
121
|
+
// Gate multicall to Ethereum Sepolia and Solana Devnet only
|
|
122
|
+
const allowedChains = [enums_1.CHAIN.ETHEREUM_SEPOLIA, enums_1.CHAIN.SOLANA_DEVNET];
|
|
123
|
+
if (!allowedChains.includes(this.universalSigner.account.chain)) {
|
|
124
|
+
throw new Error('Multicall is only enabled for Ethereum Sepolia and Solana Devnet');
|
|
125
|
+
}
|
|
126
|
+
// Validate `to` is a 0x-prefixed address
|
|
127
|
+
if (typeof execute.to !== 'string' || !execute.to.startsWith('0x')) {
|
|
128
|
+
throw new Error('When using multicall, "to" must be a 0x-prefixed address');
|
|
129
|
+
}
|
|
130
|
+
// Normalize and validate calls
|
|
131
|
+
const normalizedCalls = execute.data.map((c) => ({
|
|
132
|
+
to: (0, viem_1.getAddress)(c.to),
|
|
133
|
+
value: c.value,
|
|
134
|
+
data: c.data,
|
|
135
|
+
}));
|
|
136
|
+
// bytes4(keccak256("UEA_MULTICALL")) selector, e.g., 0x4e2d2ff6-like prefix
|
|
137
|
+
const selector = (0, viem_1.keccak256)((0, viem_1.toBytes)('UEA_MULTICALL')).slice(0, 10);
|
|
138
|
+
// abi.encode(Call[]), where Call = { address to; uint256 value; bytes data; }
|
|
139
|
+
const encodedCalls = (0, viem_1.encodeAbiParameters)([
|
|
140
|
+
{
|
|
141
|
+
type: 'tuple[]',
|
|
142
|
+
components: [
|
|
143
|
+
{ name: 'to', type: 'address' },
|
|
144
|
+
{ name: 'value', type: 'uint256' },
|
|
145
|
+
{ name: 'data', type: 'bytes' },
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
], [normalizedCalls]);
|
|
149
|
+
// Concatenate prefix selector with encodedCalls without 0x
|
|
150
|
+
payloadData = (selector + encodedCalls.slice(2));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
payloadData = (execute.data || '0x');
|
|
154
|
+
}
|
|
285
155
|
const universalPayload = JSON.parse(JSON.stringify({
|
|
286
156
|
to: execute.to,
|
|
287
157
|
value: execute.value,
|
|
288
|
-
data:
|
|
158
|
+
data: payloadData,
|
|
289
159
|
gasLimit: execute.gasLimit || BigInt(1e7),
|
|
290
160
|
maxFeePerGas: execute.maxFeePerGas || BigInt(1e10),
|
|
291
161
|
maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
|
|
@@ -349,19 +219,7 @@ class Orchestrator {
|
|
|
349
219
|
return transactions[transactions.length - 1];
|
|
350
220
|
}
|
|
351
221
|
catch (err) {
|
|
352
|
-
|
|
353
|
-
? err.message
|
|
354
|
-
: typeof err === 'string'
|
|
355
|
-
? err
|
|
356
|
-
: (() => {
|
|
357
|
-
try {
|
|
358
|
-
return JSON.stringify(err);
|
|
359
|
-
}
|
|
360
|
-
catch (_a) {
|
|
361
|
-
return 'Unknown error';
|
|
362
|
-
}
|
|
363
|
-
})();
|
|
364
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_02, errMessage);
|
|
222
|
+
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_02, err);
|
|
365
223
|
throw err;
|
|
366
224
|
}
|
|
367
225
|
});
|
|
@@ -551,9 +409,13 @@ class Orchestrator {
|
|
|
551
409
|
*/
|
|
552
410
|
sendPushTx(execute) {
|
|
553
411
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
412
|
+
// For PushChain, multicall is not supported. Ensure data is hex string.
|
|
413
|
+
if (Array.isArray(execute.data)) {
|
|
414
|
+
throw new Error('Multicall is not supported on PushChain');
|
|
415
|
+
}
|
|
554
416
|
const txHash = yield this.pushClient.sendTransaction({
|
|
555
417
|
to: execute.to,
|
|
556
|
-
data: execute.data || '0x',
|
|
418
|
+
data: (execute.data || '0x'),
|
|
557
419
|
value: execute.value,
|
|
558
420
|
signer: this.universalSigner,
|
|
559
421
|
});
|
|
@@ -773,129 +635,6 @@ class Orchestrator {
|
|
|
773
635
|
}
|
|
774
636
|
});
|
|
775
637
|
}
|
|
776
|
-
ensureErc20Allowance(evmClient, tokenAddress, spender, requiredAmount) {
|
|
777
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
778
|
-
const chain = this.universalSigner.account.chain;
|
|
779
|
-
const owner = this.universalSigner.account.address;
|
|
780
|
-
const currentAllowance = yield evmClient.readContract({
|
|
781
|
-
abi: abi_1.ERC20_EVM,
|
|
782
|
-
address: tokenAddress,
|
|
783
|
-
functionName: 'allowance',
|
|
784
|
-
args: [owner, spender],
|
|
785
|
-
});
|
|
786
|
-
if (currentAllowance >= requiredAmount)
|
|
787
|
-
return;
|
|
788
|
-
// Some ERC-20s like USDT require setting allowance to 0 before changing
|
|
789
|
-
// an existing non-zero allowance to a different non-zero value.
|
|
790
|
-
if (currentAllowance > BigInt(0)) {
|
|
791
|
-
this.printLog(`Resetting existing allowance from ${currentAllowance.toString()} to 0 for spender ${spender}`);
|
|
792
|
-
const resetTxHash = yield evmClient.writeContract({
|
|
793
|
-
abi: abi_1.ERC20_EVM,
|
|
794
|
-
address: tokenAddress,
|
|
795
|
-
functionName: 'approve',
|
|
796
|
-
args: [spender, BigInt(0)],
|
|
797
|
-
signer: this.universalSigner,
|
|
798
|
-
});
|
|
799
|
-
yield evmClient.waitForConfirmations({
|
|
800
|
-
txHash: resetTxHash,
|
|
801
|
-
confirmations: 1,
|
|
802
|
-
timeoutMs: chain_1.CHAIN_INFO[chain].timeout,
|
|
803
|
-
});
|
|
804
|
-
}
|
|
805
|
-
const setTxHash = yield evmClient.writeContract({
|
|
806
|
-
abi: abi_1.ERC20_EVM,
|
|
807
|
-
address: tokenAddress,
|
|
808
|
-
functionName: 'approve',
|
|
809
|
-
args: [spender, requiredAmount],
|
|
810
|
-
signer: this.universalSigner,
|
|
811
|
-
});
|
|
812
|
-
yield evmClient.waitForConfirmations({
|
|
813
|
-
txHash: setTxHash,
|
|
814
|
-
confirmations: 1,
|
|
815
|
-
timeoutMs: chain_1.CHAIN_INFO[chain].timeout,
|
|
816
|
-
});
|
|
817
|
-
try {
|
|
818
|
-
const updated = yield evmClient.readContract({
|
|
819
|
-
abi: abi_1.ERC20_EVM,
|
|
820
|
-
address: tokenAddress,
|
|
821
|
-
functionName: 'allowance',
|
|
822
|
-
args: [owner, spender],
|
|
823
|
-
});
|
|
824
|
-
if (updated < requiredAmount) {
|
|
825
|
-
this.printLog('Warning: allowance not updated yet; proceeding');
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
catch (_a) {
|
|
829
|
-
// ignore
|
|
830
|
-
}
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
/**
|
|
834
|
-
* Ensures we're on Sepolia, returns EVM client and gateway address.
|
|
835
|
-
*/
|
|
836
|
-
ensureSepoliaGateway() {
|
|
837
|
-
const chain = this.universalSigner.account.chain;
|
|
838
|
-
if (chain !== enums_1.CHAIN.ETHEREUM_SEPOLIA) {
|
|
839
|
-
throw new Error('Funds + payload bridging is only supported on Ethereum Sepolia for now');
|
|
840
|
-
}
|
|
841
|
-
const { defaultRPC, lockerContract } = chain_1.CHAIN_INFO[chain];
|
|
842
|
-
const rpcUrls = this.rpcUrls[chain] || defaultRPC;
|
|
843
|
-
const evmClient = new evm_client_1.EvmClient({ rpcUrls });
|
|
844
|
-
const gatewayAddress = lockerContract;
|
|
845
|
-
if (!gatewayAddress) {
|
|
846
|
-
throw new Error('Universal Gateway address not configured');
|
|
847
|
-
}
|
|
848
|
-
return { chain, evmClient, gatewayAddress };
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Computes UEA and fetches its nonce if deployed; returns 0 otherwise.
|
|
852
|
-
*/
|
|
853
|
-
getUeaNonceForExecution() {
|
|
854
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
855
|
-
const UEA = this.computeUEAOffchain();
|
|
856
|
-
const [code] = yield Promise.all([
|
|
857
|
-
this.pushClient.publicClient.getCode({ address: UEA }),
|
|
858
|
-
]);
|
|
859
|
-
return code !== undefined ? yield this.getUEANonce(UEA) : BigInt(0);
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
/**
|
|
863
|
-
* Returns UEA deployment status and nonce (0 if not deployed).
|
|
864
|
-
*/
|
|
865
|
-
getUeaStatusAndNonce() {
|
|
866
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
867
|
-
const UEA = this.computeUEAOffchain();
|
|
868
|
-
const [code] = yield Promise.all([
|
|
869
|
-
this.pushClient.publicClient.getCode({ address: UEA }),
|
|
870
|
-
]);
|
|
871
|
-
const deployed = code !== undefined;
|
|
872
|
-
const nonce = deployed ? yield this.getUEANonce(UEA) : BigInt(0);
|
|
873
|
-
return { deployed, nonce };
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Builds UniversalPayload for the gateway and computes the native gas deposit.
|
|
878
|
-
*/
|
|
879
|
-
buildGatewayPayloadAndGas(execute, nonce) {
|
|
880
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
881
|
-
var _a, _b;
|
|
882
|
-
const gasEstimate = execute.gasLimit || BigInt(1e7);
|
|
883
|
-
const payloadValue = (_a = execute.value) !== null && _a !== void 0 ? _a : BigInt(0);
|
|
884
|
-
const gasAmount = (_b = execute.value) !== null && _b !== void 0 ? _b : BigInt(0);
|
|
885
|
-
const universalPayload = {
|
|
886
|
-
to: execute.to,
|
|
887
|
-
value: payloadValue,
|
|
888
|
-
data: execute.data || '0x',
|
|
889
|
-
gasLimit: gasEstimate,
|
|
890
|
-
maxFeePerGas: execute.maxFeePerGas || BigInt(1e10),
|
|
891
|
-
maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
|
|
892
|
-
nonce,
|
|
893
|
-
deadline: execute.deadline || BigInt(9999999999),
|
|
894
|
-
vType: tx_1.VerificationType.universalTxVerification,
|
|
895
|
-
};
|
|
896
|
-
return { payload: universalPayload, gasAmount };
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
638
|
/********************************** HELPER FUNCTIONS **************************************************/
|
|
900
639
|
/**
|
|
901
640
|
* Transforms a TransactionReceipt to UniversalTxReceipt format
|
|
@@ -1116,32 +855,6 @@ class Orchestrator {
|
|
|
1116
855
|
// invoke the user-provided callback
|
|
1117
856
|
this.progressHook(hookPayload);
|
|
1118
857
|
}
|
|
1119
|
-
// Emit countdown updates while waiting for EVM confirmations
|
|
1120
|
-
waitForEvmConfirmationsWithCountdown(evmClient, txHash, confirmations, timeoutMs) {
|
|
1121
|
-
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1122
|
-
// initial emit
|
|
1123
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_03, confirmations);
|
|
1124
|
-
const start = Date.now();
|
|
1125
|
-
// Wait for receipt to get included block
|
|
1126
|
-
const receipt = yield evmClient.publicClient.waitForTransactionReceipt({
|
|
1127
|
-
hash: txHash,
|
|
1128
|
-
});
|
|
1129
|
-
const targetBlock = receipt.blockNumber + BigInt(confirmations);
|
|
1130
|
-
// Poll blocks and emit remaining confirmations
|
|
1131
|
-
// eslint-disable-next-line no-constant-condition
|
|
1132
|
-
while (true) {
|
|
1133
|
-
const currentBlock = yield evmClient.publicClient.getBlockNumber();
|
|
1134
|
-
if (currentBlock >= targetBlock)
|
|
1135
|
-
return;
|
|
1136
|
-
const remaining = Number(targetBlock - currentBlock);
|
|
1137
|
-
this.executeProgressHook(progress_hook_types_1.PROGRESS_HOOK.SEND_TX_06_03, remaining);
|
|
1138
|
-
if (Date.now() - start > timeoutMs) {
|
|
1139
|
-
throw new Error(`Timeout: transaction ${txHash} not confirmed with ${confirmations} confirmations within ${timeoutMs} ms`);
|
|
1140
|
-
}
|
|
1141
|
-
yield new Promise((r) => setTimeout(r, 12000));
|
|
1142
|
-
}
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
858
|
}
|
|
1146
859
|
exports.Orchestrator = Orchestrator;
|
|
1147
860
|
//# sourceMappingURL=orchestrator.js.map
|