@pushchain/core 5.1.4-alpha.0 → 5.1.4-alpha.10
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 +7 -8
- package/src/lib/constants/abi/factoryV1.d.ts +59 -76
- package/src/lib/constants/abi/factoryV1.js +0 -517
- package/src/lib/constants/abi/feeLocker.evm.d.ts +15 -50
- package/src/lib/constants/abi/feeLocker.evm.js +0 -385
- package/src/lib/constants/abi/index.d.ts +1 -1
- package/src/lib/constants/abi/index.js +1 -2
- package/src/lib/constants/abi/prc20.evm.d.ts +0 -53
- package/src/lib/constants/abi/prc20.evm.js +1 -42
- package/src/lib/constants/abi/uea.svm.d.ts +21 -99
- package/src/lib/constants/abi/uea.svm.js +0 -299
- package/src/lib/constants/abi/universalGatewayV0.evm.d.ts +45 -104
- package/src/lib/constants/abi/universalGatewayV0.evm.js +0 -2149
- package/src/lib/index.d.ts +1 -1
- package/src/lib/orchestrator/internals/cascade.d.ts +4 -2
- package/src/lib/orchestrator/internals/cascade.js +34 -18
- package/src/lib/orchestrator/internals/execute-standard.js +5 -1
- package/src/lib/orchestrator/internals/gas-calculator.d.ts +17 -0
- package/src/lib/orchestrator/internals/gas-calculator.js +236 -1
- package/src/lib/orchestrator/internals/push-chain-tx.js +24 -1
- package/src/lib/orchestrator/internals/route-handlers.js +60 -62
- package/src/lib/orchestrator/orchestrator.d.ts +5 -3
- package/src/lib/orchestrator/orchestrator.js +2 -12
- package/src/lib/orchestrator/orchestrator.types.d.ts +8 -15
- package/src/lib/progress-hook/progress-hook.js +1 -1
- package/src/lib/push-chain/push-chain.d.ts +5 -6
- package/src/lib/push-chain/push-chain.js +4 -3
- package/src/lib/universal/account/account.d.ts +16 -8
- package/src/lib/universal/account/account.js +118 -73
- package/src/lib/universal/signer/signer.js +1 -1
- package/src/lib/universal/universal.types.d.ts +2 -2
- 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/bs58.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/internals/account-manager.js.map +0 -1
- package/src/lib/orchestrator/internals/cascade.js.map +0 -1
- package/src/lib/orchestrator/internals/confirmation.js.map +0 -1
- package/src/lib/orchestrator/internals/context.js.map +0 -1
- package/src/lib/orchestrator/internals/execute-funds-only.js.map +0 -1
- package/src/lib/orchestrator/internals/execute-funds-payload.js.map +0 -1
- package/src/lib/orchestrator/internals/execute-standard.js.map +0 -1
- package/src/lib/orchestrator/internals/gas-calculator.js.map +0 -1
- package/src/lib/orchestrator/internals/gateway-client.js.map +0 -1
- package/src/lib/orchestrator/internals/helpers.js.map +0 -1
- package/src/lib/orchestrator/internals/index.js.map +0 -1
- package/src/lib/orchestrator/internals/outbound-sync.js.map +0 -1
- package/src/lib/orchestrator/internals/outbound-tracker.js.map +0 -1
- package/src/lib/orchestrator/internals/payload-builder.js.map +0 -1
- package/src/lib/orchestrator/internals/push-chain-tx.js.map +0 -1
- package/src/lib/orchestrator/internals/quote.js.map +0 -1
- package/src/lib/orchestrator/internals/rescue.js.map +0 -1
- package/src/lib/orchestrator/internals/response-builder.js.map +0 -1
- package/src/lib/orchestrator/internals/route-handlers.js.map +0 -1
- package/src/lib/orchestrator/internals/signing.js.map +0 -1
- package/src/lib/orchestrator/internals/svm-bridge.js.map +0 -1
- package/src/lib/orchestrator/internals/svm-helpers.js.map +0 -1
- package/src/lib/orchestrator/internals/tx-transformer.js.map +0 -1
- package/src/lib/orchestrator/internals/uea-manager.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
package/src/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PushChain } from './push-chain/push-chain';
|
|
2
2
|
export type { ConversionQuote } from './constants/tokens';
|
|
3
3
|
export type { UniversalSigner, UniversalAccount, UniversalSignerSkeleton, DerivedExecutorAccount, ResolvedAccount, ResolvedControllerAccounts, AccountType, AccountRole, } from './universal/universal.types';
|
|
4
|
-
export type { ChainTarget, ChainSource, UniversalTo, TransactionRouteType, UniversalExecuteParams, UniversalOutboundTxRequest, PreparedUniversalTx,
|
|
4
|
+
export type { ChainTarget, ChainSource, UniversalTo, TransactionRouteType, UniversalExecuteParams, UniversalOutboundTxRequest, PreparedUniversalTx, CascadedTxResponse, CascadeHopInfo, CascadeTrackOptions, CascadeProgressEvent, CascadeCompletionResult, MultiChainTxResponse, OutboundTxDetails, WaitForOutboundOptions, SvmGatewayAccountMeta, SvmExecutePayloadFields, SvmExecuteParams, AccountStatus, UEAStatus, RescueFundsParams, } from './orchestrator/orchestrator.types';
|
|
5
5
|
export { parseUEAVersion } from './orchestrator/orchestrator.types';
|
|
6
6
|
export { TransactionRoute, detectRoute, isChainTarget } from './orchestrator/route-detector';
|
|
7
7
|
export { getCEAAddress, getPushAccountForCEA, isCEA, chainSupportsCEA, chainSupportsOutbound, getCEAFactoryAddress, getAllCEAAddresses, } from './orchestrator/cea-utils';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* getSegmentType, composeCascade, createCascadedBuilder, createChainedBuilder.
|
|
6
6
|
*/
|
|
7
7
|
import { TransactionRoute } from '../route-detector';
|
|
8
|
-
import type { HopDescriptor, CascadeSegment, CascadeSegmentType, PreparedUniversalTx,
|
|
8
|
+
import type { HopDescriptor, CascadeSegment, CascadeSegmentType, PreparedUniversalTx, CascadedTxResponse, CascadeHopInfo, UniversalTxResponse, UniversalExecuteParams, MultiCall, WaitForOutboundOptions, OutboundTxDetails } from '../orchestrator.types';
|
|
9
9
|
import type { OrchestratorContext } from './context';
|
|
10
10
|
export interface CascadeCallbacks {
|
|
11
11
|
executeFn: (params: any) => Promise<UniversalTxResponse>;
|
|
@@ -20,4 +20,6 @@ export declare function buildHopDescriptor(ctx: OrchestratorContext, params: Uni
|
|
|
20
20
|
export declare function classifyIntoSegments(hops: HopDescriptor[]): CascadeSegment[];
|
|
21
21
|
export declare function getSegmentType(route: string): CascadeSegmentType;
|
|
22
22
|
export declare function composeCascade(ctx: OrchestratorContext, segments: CascadeSegment[], ueaAddress: `0x${string}`, ueaBalance?: bigint, ueaNonce?: bigint): MultiCall[];
|
|
23
|
-
export declare function createCascadedBuilder(ctx: OrchestratorContext, preparedTxs: PreparedUniversalTx[], callbacks: CascadeCallbacks):
|
|
23
|
+
export declare function createCascadedBuilder(ctx: OrchestratorContext, preparedTxs: PreparedUniversalTx[], callbacks: CascadeCallbacks): {
|
|
24
|
+
send: () => Promise<CascadedTxResponse>;
|
|
25
|
+
};
|
|
@@ -37,16 +37,28 @@ function prepareTransaction(ctx, params, callbacks) {
|
|
|
37
37
|
clientChain: ctx.universalSigner.account.chain,
|
|
38
38
|
});
|
|
39
39
|
const route = (0, route_detector_1.detectRoute)(params);
|
|
40
|
-
//
|
|
40
|
+
// Push native EOA: block Route 1 — use sendTransaction() for direct Push calls
|
|
41
|
+
const signerChain = ctx.universalSigner.account.chain;
|
|
42
|
+
const isPushNativeEOA = (0, helpers_1.isPushChain)(signerChain);
|
|
43
|
+
if (isPushNativeEOA && route === route_detector_1.TransactionRoute.UOA_TO_PUSH) {
|
|
44
|
+
throw new Error('Push native accounts cannot use prepareTransaction for Push Chain transactions. ' +
|
|
45
|
+
'Use sendTransaction() instead for direct Push Chain calls.');
|
|
46
|
+
}
|
|
47
|
+
// Fetch UEA nonce (skip for Push native EOA — uses EVM nonce, not UEA contract nonce)
|
|
41
48
|
let nonce;
|
|
42
|
-
const deployedHintCascade = (_b = (_a = ctx.accountStatusCache) === null || _a === void 0 ? void 0 : _a.uea) === null || _b === void 0 ? void 0 : _b.deployed;
|
|
43
49
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
44
|
-
if (
|
|
45
|
-
nonce =
|
|
50
|
+
if (isPushNativeEOA) {
|
|
51
|
+
nonce = BigInt(0);
|
|
46
52
|
}
|
|
47
53
|
else {
|
|
48
|
-
const
|
|
49
|
-
|
|
54
|
+
const deployedHintCascade = (_b = (_a = ctx.accountStatusCache) === null || _a === void 0 ? void 0 : _a.uea) === null || _b === void 0 ? void 0 : _b.deployed;
|
|
55
|
+
if (deployedHintCascade) {
|
|
56
|
+
nonce = yield (0, uea_manager_1.getUEANonce)(ctx, ueaAddress);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const status = yield (0, uea_manager_1.getUeaStatusAndNonce)(ctx);
|
|
60
|
+
nonce = status.nonce;
|
|
61
|
+
}
|
|
50
62
|
}
|
|
51
63
|
// Build the payload based on route
|
|
52
64
|
const { payload, gatewayRequest } = yield (0, route_handlers_1.buildPayloadForRoute)(ctx, params, route, nonce);
|
|
@@ -62,8 +74,6 @@ function prepareTransaction(ctx, params, callbacks) {
|
|
|
62
74
|
nonce,
|
|
63
75
|
deadline,
|
|
64
76
|
_hop: hop,
|
|
65
|
-
thenOn: (nextTx) => createCascadedBuilder(ctx, [prepared, nextTx], callbacks),
|
|
66
|
-
send: () => callbacks.executeFn(params),
|
|
67
77
|
};
|
|
68
78
|
return prepared;
|
|
69
79
|
});
|
|
@@ -222,8 +232,13 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
222
232
|
burnAmount = params.value;
|
|
223
233
|
}
|
|
224
234
|
else if (params.data) {
|
|
235
|
+
// PAYLOAD-only (no value transfer): still need native PRC-20 token for
|
|
236
|
+
// chain namespace lookup + gas fees, but burn amount must be zero.
|
|
237
|
+
// Matches the direct executeUoaToCea path (route-handlers.ts).
|
|
238
|
+
// Using burnAmount=1 would trigger transferFrom on the PRC-20 token,
|
|
239
|
+
// which reverts when the UEA has no PRC-20 balance for that chain.
|
|
225
240
|
prc20Token = (0, helpers_1.getNativePRC20ForChain)(targetChain, ctx.pushNetwork);
|
|
226
|
-
burnAmount = BigInt(
|
|
241
|
+
burnAmount = BigInt(0);
|
|
227
242
|
}
|
|
228
243
|
// Query gas fee
|
|
229
244
|
let gasToken = selectors_1.ZERO_ADDRESS;
|
|
@@ -285,10 +300,12 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
285
300
|
gasToken = result.gasToken;
|
|
286
301
|
gasFee = result.gasFee;
|
|
287
302
|
}
|
|
288
|
-
return Object.assign(Object.assign({}, baseDescriptor), { sourceChain, ceaAddress: ceaPdaHex, isSvmTarget: true, prc20Token, burnAmount: amount
|
|
303
|
+
return Object.assign(Object.assign({}, baseDescriptor), { sourceChain, ceaAddress: ceaPdaHex, isSvmTarget: true, prc20Token, burnAmount: amount, gasToken,
|
|
289
304
|
gasFee });
|
|
290
305
|
}
|
|
291
|
-
const { cea: ceaAddress
|
|
306
|
+
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_h = ctx.rpcUrls[sourceChain]) === null || _h === void 0 ? void 0 : _h[0]);
|
|
307
|
+
// CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
|
|
308
|
+
// if CEA doesn't exist yet. No SDK-side blocking needed.
|
|
292
309
|
// Determine token/amount for the inbound
|
|
293
310
|
let tokenAddress = selectors_1.ZERO_ADDRESS;
|
|
294
311
|
let amount = BigInt(0);
|
|
@@ -321,7 +338,7 @@ function buildHopDescriptor(ctx, params, route, ueaAddress) {
|
|
|
321
338
|
}
|
|
322
339
|
return Object.assign(Object.assign({}, baseDescriptor), { sourceChain,
|
|
323
340
|
ceaAddress,
|
|
324
|
-
prc20Token, burnAmount: amount
|
|
341
|
+
prc20Token, burnAmount: amount, gasToken,
|
|
325
342
|
gasFee });
|
|
326
343
|
}
|
|
327
344
|
default:
|
|
@@ -553,15 +570,15 @@ function composeCascade(ctx, segments, ueaAddress, ueaBalance, ueaNonce) {
|
|
|
553
570
|
? new Uint8Array(Buffer.from(intermediatePayload.slice(2), 'hex'))
|
|
554
571
|
: undefined,
|
|
555
572
|
});
|
|
556
|
-
const
|
|
573
|
+
const svmBurnAmount = segment.totalBurnAmount || BigInt(0);
|
|
557
574
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, segment.prc20Token ||
|
|
558
|
-
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork),
|
|
575
|
+
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), svmBurnAmount, (_g = segment.gasLimit) !== null && _g !== void 0 ? _g : BigInt(0), svmPayload, ueaAddress);
|
|
559
576
|
const inboundGasFee = segment.gasFee || BigInt(0);
|
|
560
577
|
const outboundMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
561
578
|
prc20Token: segment.prc20Token ||
|
|
562
579
|
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork),
|
|
563
580
|
gasToken: segment.gasToken || selectors_1.ZERO_ADDRESS,
|
|
564
|
-
burnAmount,
|
|
581
|
+
burnAmount: svmBurnAmount,
|
|
565
582
|
gasFee: inboundGasFee,
|
|
566
583
|
nativeValueForGas: perOutboundNativeValue !== null && perOutboundNativeValue !== void 0 ? perOutboundNativeValue : inboundGasFee * BigInt(1000),
|
|
567
584
|
gatewayPcAddress,
|
|
@@ -628,13 +645,13 @@ function composeCascade(ctx, segments, ueaAddress, ueaBalance, ueaNonce) {
|
|
|
628
645
|
// Wrap CEA multicall in outbound from Push Chain
|
|
629
646
|
const ceaPayload = (0, payload_builders_1.buildCeaMulticallPayload)(ceaMulticalls);
|
|
630
647
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, segment.prc20Token ||
|
|
631
|
-
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), segment.totalBurnAmount || BigInt(
|
|
648
|
+
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork), segment.totalBurnAmount || BigInt(0), (_j = segment.gasLimit) !== null && _j !== void 0 ? _j : BigInt(0), ceaPayload, ueaAddress);
|
|
632
649
|
const inboundGasFee = segment.gasFee || BigInt(0);
|
|
633
650
|
const outboundMulticalls = (0, payload_builders_1.buildOutboundApprovalAndCall)({
|
|
634
651
|
prc20Token: segment.prc20Token ||
|
|
635
652
|
(0, helpers_1.getNativePRC20ForChain)(sourceChain, ctx.pushNetwork),
|
|
636
653
|
gasToken: segment.gasToken || selectors_1.ZERO_ADDRESS,
|
|
637
|
-
burnAmount: segment.totalBurnAmount || BigInt(
|
|
654
|
+
burnAmount: segment.totalBurnAmount || BigInt(0),
|
|
638
655
|
gasFee: inboundGasFee,
|
|
639
656
|
nativeValueForGas: perOutboundNativeValue !== null && perOutboundNativeValue !== void 0 ? perOutboundNativeValue : inboundGasFee * BigInt(1000),
|
|
640
657
|
gatewayPcAddress,
|
|
@@ -653,7 +670,6 @@ function composeCascade(ctx, segments, ueaAddress, ueaBalance, ueaNonce) {
|
|
|
653
670
|
// ============================================================================
|
|
654
671
|
function createCascadedBuilder(ctx, preparedTxs, callbacks) {
|
|
655
672
|
return {
|
|
656
|
-
thenOn: (nextTx) => createCascadedBuilder(ctx, [...preparedTxs, nextTx], callbacks),
|
|
657
673
|
send: () => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
658
674
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
659
675
|
// Extract HopDescriptors
|
|
@@ -198,7 +198,11 @@ function executeStandardPayload(ctx, execute, eventBuffer, getResponseCallbacks)
|
|
|
198
198
|
const fixedPushAmount = utils_1.Utils.helpers.parseUnits('0.001', 18);
|
|
199
199
|
const lockAmount = funds < requiredFunds ? fundDifference : fixedPushAmount;
|
|
200
200
|
const lockAmountInUSD = ctx.pushClient.pushToUSDC(lockAmount);
|
|
201
|
-
|
|
201
|
+
// Apply minimum deposit override (e.g., Route 2 needs enough UPC for outbound swap)
|
|
202
|
+
const effectiveLockAmountInUSD = execute._minimumDepositUsd && execute._minimumDepositUsd > lockAmountInUSD
|
|
203
|
+
? execute._minimumDepositUsd
|
|
204
|
+
: lockAmountInUSD;
|
|
205
|
+
const feeLockTxHashBytes = yield (0, gateway_client_1.lockFee)(ctx, effectiveLockAmountInUSD, universalPayload, req);
|
|
202
206
|
feeLockTxHash = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
|
|
203
207
|
verificationData = (0, viem_1.bytesToHex)(feeLockTxHashBytes);
|
|
204
208
|
const { vm } = chain_1.CHAIN_INFO[chain];
|
|
@@ -13,7 +13,15 @@ export declare function queryOutboundGasFee(ctx: OrchestratorContext, prc20Token
|
|
|
13
13
|
protocolFee: bigint;
|
|
14
14
|
nativeValueForGas: bigint;
|
|
15
15
|
gasPrice: bigint;
|
|
16
|
+
universalCoreAddress: `0x${string}`;
|
|
16
17
|
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Estimate the native WPC amount needed to swap for `gasFee` of `gasToken`
|
|
20
|
+
* by reading the Uniswap V3 pool price on Push Chain.
|
|
21
|
+
* Returns the estimated amount with a 2x safety buffer (excess is refunded by the contract).
|
|
22
|
+
* Falls back to a percentage of accountBalance if any on-chain query fails.
|
|
23
|
+
*/
|
|
24
|
+
export declare function estimateNativeValueForSwap(ctx: OrchestratorContext, universalCoreAddress: `0x${string}`, gasToken: `0x${string}`, gasFee: bigint, accountBalance: bigint): Promise<bigint>;
|
|
17
25
|
export declare function queryRescueGasFee(ctx: OrchestratorContext, prc20Token: `0x${string}`): Promise<{
|
|
18
26
|
gasToken: `0x${string}`;
|
|
19
27
|
gasFee: bigint;
|
|
@@ -28,3 +36,12 @@ export declare function calculateGasAmountFromAmountOutMinETH(ctx: OrchestratorC
|
|
|
28
36
|
}) => Promise<ConversionQuote>): Promise<{
|
|
29
37
|
gasAmount: bigint;
|
|
30
38
|
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Predicts how much UPC (WPC) the chain will deposit to the UEA from a given
|
|
41
|
+
* amount of locked native token (e.g., ETH on Sepolia). The chain converts
|
|
42
|
+
* locked ETH → pETH (PRC-20) → WPC via Uniswap V3 swap on Push Chain.
|
|
43
|
+
*
|
|
44
|
+
* Queries the same Uniswap V3 QuoterV2 the chain uses in execute_inbound_gas.go.
|
|
45
|
+
* Returns 0 on any failure (caller should fall back to other logic).
|
|
46
|
+
*/
|
|
47
|
+
export declare function estimateDepositFromLockedNative(ctx: OrchestratorContext, nativeAmountForLocker: bigint, prc20Token: `0x${string}`): Promise<bigint>;
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.ensureErc20Allowance = ensureErc20Allowance;
|
|
8
8
|
exports.queryOutboundGasFee = queryOutboundGasFee;
|
|
9
|
+
exports.estimateNativeValueForSwap = estimateNativeValueForSwap;
|
|
9
10
|
exports.queryRescueGasFee = queryRescueGasFee;
|
|
10
11
|
exports.calculateNativeAmountForDeposit = calculateNativeAmountForDeposit;
|
|
11
12
|
exports.calculateGasAmountFromAmountOutMinETH = calculateGasAmountFromAmountOutMinETH;
|
|
13
|
+
exports.estimateDepositFromLockedNative = estimateDepositFromLockedNative;
|
|
12
14
|
const tslib_1 = require("tslib");
|
|
13
15
|
const web3_js_1 = require("@solana/web3.js");
|
|
14
16
|
const viem_1 = require("viem");
|
|
@@ -24,6 +26,43 @@ const context_1 = require("./context");
|
|
|
24
26
|
const helpers_1 = require("./helpers");
|
|
25
27
|
/** Buffer multiplier for nativeValueForGas. Excess is refunded by swapAndBurnGas to the UEA. */
|
|
26
28
|
const GAS_FEE_BUFFER_MULTIPLIER = BigInt(1000000);
|
|
29
|
+
// Minimal ABIs for Uniswap V3 pool price estimation
|
|
30
|
+
const UNISWAP_V3_POOL_SLOT0_ABI = [
|
|
31
|
+
{
|
|
32
|
+
type: 'function',
|
|
33
|
+
name: 'slot0',
|
|
34
|
+
inputs: [],
|
|
35
|
+
outputs: [
|
|
36
|
+
{ name: 'sqrtPriceX96', type: 'uint160', internalType: 'uint160' },
|
|
37
|
+
{ name: 'tick', type: 'int24', internalType: 'int24' },
|
|
38
|
+
{ name: 'observationIndex', type: 'uint16', internalType: 'uint16' },
|
|
39
|
+
{ name: 'observationCardinality', type: 'uint16', internalType: 'uint16' },
|
|
40
|
+
{ name: 'observationCardinalityNext', type: 'uint16', internalType: 'uint16' },
|
|
41
|
+
{ name: 'feeProtocol', type: 'uint8', internalType: 'uint8' },
|
|
42
|
+
{ name: 'unlocked', type: 'bool', internalType: 'bool' },
|
|
43
|
+
],
|
|
44
|
+
stateMutability: 'view',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const UNISWAP_V3_FACTORY_ABI = [
|
|
48
|
+
{
|
|
49
|
+
type: 'function',
|
|
50
|
+
name: 'getPool',
|
|
51
|
+
inputs: [
|
|
52
|
+
{ name: 'tokenA', type: 'address', internalType: 'address' },
|
|
53
|
+
{ name: 'tokenB', type: 'address', internalType: 'address' },
|
|
54
|
+
{ name: 'fee', type: 'uint24', internalType: 'uint24' },
|
|
55
|
+
],
|
|
56
|
+
outputs: [{ name: 'pool', type: 'address', internalType: 'address' }],
|
|
57
|
+
stateMutability: 'view',
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
const UNIVERSAL_CORE_SWAP_HELPERS_ABI = [
|
|
61
|
+
{ type: 'function', name: 'WPC', inputs: [], outputs: [{ name: '', type: 'address', internalType: 'address' }], stateMutability: 'view' },
|
|
62
|
+
{ type: 'function', name: 'uniswapV3Factory', inputs: [], outputs: [{ name: '', type: 'address', internalType: 'address' }], stateMutability: 'view' },
|
|
63
|
+
{ type: 'function', name: 'defaultFeeTier', inputs: [{ name: '', type: 'address', internalType: 'address' }], outputs: [{ name: '', type: 'uint24', internalType: 'uint24' }], stateMutability: 'view' },
|
|
64
|
+
];
|
|
65
|
+
const ZERO_ADDR = '0x0000000000000000000000000000000000000000';
|
|
27
66
|
// ============================================================================
|
|
28
67
|
// ERC-20 Allowance
|
|
29
68
|
// ============================================================================
|
|
@@ -136,10 +175,113 @@ function queryOutboundGasFee(ctx, prc20Token, gasLimit) {
|
|
|
136
175
|
}
|
|
137
176
|
const nativeValueForGas = protocolFee + gasFee * GAS_FEE_BUFFER_MULTIPLIER;
|
|
138
177
|
(0, context_1.printLog)(ctx, `queryOutboundGasFee — [step 5] using 1000000x buffer: nativeValueForGas=${nativeValueForGas}`);
|
|
139
|
-
return { gasToken, gasFee, protocolFee, nativeValueForGas, gasPrice };
|
|
178
|
+
return { gasToken, gasFee, protocolFee, nativeValueForGas, gasPrice, universalCoreAddress };
|
|
140
179
|
});
|
|
141
180
|
}
|
|
142
181
|
// ============================================================================
|
|
182
|
+
// Uniswap V3 Pool Price Estimation
|
|
183
|
+
// ============================================================================
|
|
184
|
+
/**
|
|
185
|
+
* Estimate the native WPC amount needed to swap for `gasFee` of `gasToken`
|
|
186
|
+
* by reading the Uniswap V3 pool price on Push Chain.
|
|
187
|
+
* Returns the estimated amount with a 2x safety buffer (excess is refunded by the contract).
|
|
188
|
+
* Falls back to a percentage of accountBalance if any on-chain query fails.
|
|
189
|
+
*/
|
|
190
|
+
function estimateNativeValueForSwap(ctx, universalCoreAddress, gasToken, gasFee, accountBalance) {
|
|
191
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
192
|
+
const SWAP_BUFFER = BigInt(2); // 2x safety buffer; excess is refunded by swapAndBurnGas
|
|
193
|
+
const BALANCE_FALLBACK_DIVISOR = BigInt(10); // 10% of balance as fallback
|
|
194
|
+
const GAS_RESERVE = BigInt(3e18); // 3 UPC reserve for tx overhead
|
|
195
|
+
try {
|
|
196
|
+
// Read WPC, factory, and defaultFeeTier in parallel
|
|
197
|
+
const [wpcAddress, factoryAddress, feeTier] = yield Promise.all([
|
|
198
|
+
ctx.pushClient.readContract({
|
|
199
|
+
address: universalCoreAddress,
|
|
200
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
201
|
+
functionName: 'WPC',
|
|
202
|
+
args: [],
|
|
203
|
+
}),
|
|
204
|
+
ctx.pushClient.readContract({
|
|
205
|
+
address: universalCoreAddress,
|
|
206
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
207
|
+
functionName: 'uniswapV3Factory',
|
|
208
|
+
args: [],
|
|
209
|
+
}),
|
|
210
|
+
ctx.pushClient.readContract({
|
|
211
|
+
address: universalCoreAddress,
|
|
212
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
213
|
+
functionName: 'defaultFeeTier',
|
|
214
|
+
args: [gasToken],
|
|
215
|
+
}),
|
|
216
|
+
]);
|
|
217
|
+
if (!feeTier) {
|
|
218
|
+
(0, context_1.printLog)(ctx, `estimateNativeValueForSwap — no fee tier for gasToken, using balance fallback`);
|
|
219
|
+
return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
|
|
220
|
+
}
|
|
221
|
+
// Get pool address from factory
|
|
222
|
+
const poolAddress = yield ctx.pushClient.readContract({
|
|
223
|
+
address: factoryAddress,
|
|
224
|
+
abi: UNISWAP_V3_FACTORY_ABI,
|
|
225
|
+
functionName: 'getPool',
|
|
226
|
+
args: [wpcAddress, gasToken, feeTier],
|
|
227
|
+
});
|
|
228
|
+
if (poolAddress === ZERO_ADDR) {
|
|
229
|
+
(0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool not found, using balance fallback`);
|
|
230
|
+
return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
|
|
231
|
+
}
|
|
232
|
+
// Read slot0 for current price
|
|
233
|
+
const slot0 = yield ctx.pushClient.readContract({
|
|
234
|
+
address: poolAddress,
|
|
235
|
+
abi: UNISWAP_V3_POOL_SLOT0_ABI,
|
|
236
|
+
functionName: 'slot0',
|
|
237
|
+
args: [],
|
|
238
|
+
});
|
|
239
|
+
const sqrtPriceX96 = slot0[0];
|
|
240
|
+
if (!sqrtPriceX96 || sqrtPriceX96 === BigInt(0)) {
|
|
241
|
+
(0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool not initialized, using balance fallback`);
|
|
242
|
+
return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
|
|
243
|
+
}
|
|
244
|
+
// price (token1/token0 in raw units) = (sqrtPriceX96)² / 2¹⁹²
|
|
245
|
+
const Q192 = BigInt(1) << BigInt(192);
|
|
246
|
+
const priceNum = sqrtPriceX96 * sqrtPriceX96; // sqrtPrice² in Q192
|
|
247
|
+
// Uniswap V3 sorts tokens: token0 < token1 by address
|
|
248
|
+
const isGasTokenToken0 = gasToken.toLowerCase() < wpcAddress.toLowerCase();
|
|
249
|
+
let wpcNeeded;
|
|
250
|
+
if (isGasTokenToken0) {
|
|
251
|
+
// price = WPC_per_gasToken → wpcNeeded = gasFee * price
|
|
252
|
+
wpcNeeded = (gasFee * priceNum) / Q192;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// price = gasToken_per_WPC → wpcNeeded = gasFee / price
|
|
256
|
+
wpcNeeded = (gasFee * Q192) / priceNum;
|
|
257
|
+
}
|
|
258
|
+
const result = wpcNeeded * SWAP_BUFFER;
|
|
259
|
+
(0, context_1.printLog)(ctx, `estimateNativeValueForSwap — pool=${poolAddress}, sqrtPriceX96=${sqrtPriceX96}, ` +
|
|
260
|
+
`wpcNeeded=${wpcNeeded}, withBuffer(2x)=${result}`);
|
|
261
|
+
// Cap at (balance - reserve)
|
|
262
|
+
if (accountBalance > result + GAS_RESERVE) {
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
else if (accountBalance > GAS_RESERVE) {
|
|
266
|
+
return accountBalance - GAS_RESERVE;
|
|
267
|
+
}
|
|
268
|
+
return result; // let caller decide if balance is too low
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
(0, context_1.printLog)(ctx, `estimateNativeValueForSwap — failed: ${err instanceof Error ? err.message : String(err)}, using balance fallback`);
|
|
272
|
+
return balanceFallback(accountBalance, BALANCE_FALLBACK_DIVISOR, GAS_RESERVE);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
function balanceFallback(balance, divisor, reserve) {
|
|
277
|
+
const fraction = balance / divisor;
|
|
278
|
+
if (balance > fraction + reserve)
|
|
279
|
+
return fraction;
|
|
280
|
+
if (balance > reserve)
|
|
281
|
+
return balance - reserve;
|
|
282
|
+
return fraction;
|
|
283
|
+
}
|
|
284
|
+
// ============================================================================
|
|
143
285
|
// Rescue Gas Fee Query
|
|
144
286
|
// ============================================================================
|
|
145
287
|
function queryRescueGasFee(ctx, prc20Token) {
|
|
@@ -280,4 +422,97 @@ function calculateGasAmountFromAmountOutMinETH(ctx, gasTokenAddress, amountOutMi
|
|
|
280
422
|
return { gasAmount };
|
|
281
423
|
});
|
|
282
424
|
}
|
|
425
|
+
// ============================================================================
|
|
426
|
+
// Estimate UPC deposit from locked ETH via Uniswap V3 quote
|
|
427
|
+
// ============================================================================
|
|
428
|
+
/**
|
|
429
|
+
* Predicts how much UPC (WPC) the chain will deposit to the UEA from a given
|
|
430
|
+
* amount of locked native token (e.g., ETH on Sepolia). The chain converts
|
|
431
|
+
* locked ETH → pETH (PRC-20) → WPC via Uniswap V3 swap on Push Chain.
|
|
432
|
+
*
|
|
433
|
+
* Queries the same Uniswap V3 QuoterV2 the chain uses in execute_inbound_gas.go.
|
|
434
|
+
* Returns 0 on any failure (caller should fall back to other logic).
|
|
435
|
+
*/
|
|
436
|
+
function estimateDepositFromLockedNative(ctx, nativeAmountForLocker, prc20Token) {
|
|
437
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
438
|
+
var _a, _b;
|
|
439
|
+
try {
|
|
440
|
+
const pushChain = (0, helpers_1.getPushChainForNetwork)(ctx.pushNetwork);
|
|
441
|
+
const quoterAddress = (_b = (_a = chain_1.CHAIN_INFO[pushChain]) === null || _a === void 0 ? void 0 : _a.dex) === null || _b === void 0 ? void 0 : _b.uniV3QuoterV2;
|
|
442
|
+
if (!quoterAddress || quoterAddress.startsWith('0xTBD'))
|
|
443
|
+
return BigInt(0);
|
|
444
|
+
// Get UniversalCore → WPC address + fee tier (reuses existing ABI)
|
|
445
|
+
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
446
|
+
const universalCoreAddress = yield ctx.pushClient.readContract({
|
|
447
|
+
address: gatewayPcAddress,
|
|
448
|
+
abi: abi_1.UNIVERSAL_GATEWAY_PC,
|
|
449
|
+
functionName: 'UNIVERSAL_CORE',
|
|
450
|
+
args: [],
|
|
451
|
+
});
|
|
452
|
+
const [wpcAddress, feeTier] = yield Promise.all([
|
|
453
|
+
ctx.pushClient.readContract({
|
|
454
|
+
address: universalCoreAddress,
|
|
455
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
456
|
+
functionName: 'WPC',
|
|
457
|
+
args: [],
|
|
458
|
+
}),
|
|
459
|
+
ctx.pushClient.readContract({
|
|
460
|
+
address: universalCoreAddress,
|
|
461
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
462
|
+
functionName: 'defaultFeeTier',
|
|
463
|
+
args: [prc20Token],
|
|
464
|
+
}),
|
|
465
|
+
]);
|
|
466
|
+
if (!feeTier || !wpcAddress)
|
|
467
|
+
return BigInt(0);
|
|
468
|
+
// QuoterV2.quoteExactInputSingle — same call the chain relay makes
|
|
469
|
+
const QUOTER_ABI = [
|
|
470
|
+
{
|
|
471
|
+
type: 'function',
|
|
472
|
+
name: 'quoteExactInputSingle',
|
|
473
|
+
inputs: [
|
|
474
|
+
{
|
|
475
|
+
type: 'tuple',
|
|
476
|
+
components: [
|
|
477
|
+
{ name: 'tokenIn', type: 'address' },
|
|
478
|
+
{ name: 'tokenOut', type: 'address' },
|
|
479
|
+
{ name: 'amountIn', type: 'uint256' },
|
|
480
|
+
{ name: 'fee', type: 'uint24' },
|
|
481
|
+
{ name: 'sqrtPriceLimitX96', type: 'uint160' },
|
|
482
|
+
],
|
|
483
|
+
},
|
|
484
|
+
],
|
|
485
|
+
outputs: [
|
|
486
|
+
{ name: 'amountOut', type: 'uint256' },
|
|
487
|
+
{ name: 'sqrtPriceX96After', type: 'uint160' },
|
|
488
|
+
{ name: 'initializedTicksCrossed', type: 'uint32' },
|
|
489
|
+
{ name: 'gasEstimate', type: 'uint256' },
|
|
490
|
+
],
|
|
491
|
+
stateMutability: 'view',
|
|
492
|
+
},
|
|
493
|
+
];
|
|
494
|
+
const result = yield ctx.pushClient.readContract({
|
|
495
|
+
address: quoterAddress,
|
|
496
|
+
abi: QUOTER_ABI,
|
|
497
|
+
functionName: 'quoteExactInputSingle',
|
|
498
|
+
args: [
|
|
499
|
+
{
|
|
500
|
+
tokenIn: prc20Token,
|
|
501
|
+
tokenOut: wpcAddress,
|
|
502
|
+
amountIn: nativeAmountForLocker,
|
|
503
|
+
fee: feeTier,
|
|
504
|
+
sqrtPriceLimitX96: BigInt(0),
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
});
|
|
508
|
+
const amountOut = result[0];
|
|
509
|
+
(0, context_1.printLog)(ctx, `estimateDepositFromLockedNative — quote: ${nativeAmountForLocker.toString()} pETH → ${amountOut.toString()} WPC (fee tier: ${feeTier})`);
|
|
510
|
+
return amountOut;
|
|
511
|
+
}
|
|
512
|
+
catch (err) {
|
|
513
|
+
(0, context_1.printLog)(ctx, `estimateDepositFromLockedNative — failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
514
|
+
return BigInt(0);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
283
518
|
//# sourceMappingURL=gas-calculator.js.map
|
|
@@ -27,6 +27,7 @@ const context_1 = require("./context");
|
|
|
27
27
|
*/
|
|
28
28
|
function sendPushTx(ctx, execute, eventBuffer, transformFn) {
|
|
29
29
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
var _a, _b, _c;
|
|
30
31
|
if (Array.isArray(execute.data)) {
|
|
31
32
|
const PUSH_CHAIN_GAS_LIMIT = BigInt(500000);
|
|
32
33
|
const MAX_NONCE_RETRIES = 3;
|
|
@@ -73,7 +74,29 @@ function sendPushTx(ctx, execute, eventBuffer, transformFn) {
|
|
|
73
74
|
hash: lastTxHash,
|
|
74
75
|
});
|
|
75
76
|
if (receipt.status === 'reverted') {
|
|
76
|
-
|
|
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})`);
|
|
77
100
|
}
|
|
78
101
|
(0, context_1.printLog)(ctx, `sendPushTx — operation ${i + 1}/${calls.length} confirmed in block ${receipt.blockNumber}`);
|
|
79
102
|
nonce++;
|