@pushchain/core 6.0.19 → 6.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/package.json +1 -1
- package/src/lib/cache/cache.js +2 -0
- package/src/lib/constants/abi/index.d.ts +1 -0
- package/src/lib/constants/abi/index.js +8 -1
- package/src/lib/constants/abi/pc20.evm.d.ts +217 -0
- package/src/lib/constants/abi/pc20.evm.js +150 -0
- package/src/lib/constants/abi/prc20.evm.d.ts +172 -0
- package/src/lib/constants/abi/prc20.evm.js +97 -0
- package/src/lib/constants/abi/universalGatewayV0.json +1 -1
- package/src/lib/constants/chain.js +38 -8
- package/src/lib/constants/selectors.js +2 -2
- package/src/lib/constants/tokens.js +4 -3
- package/src/lib/formatters.js +16 -6
- package/src/lib/generated/uexecutor/v1/query.js +2 -4
- package/src/lib/generated/uexecutor/v1/types.d.ts +14 -0
- package/src/lib/generated/uexecutor/v1/types.js +90 -47
- package/src/lib/generated/uexecutor/v2/query.js +2 -4
- package/src/lib/generated/uexecutor/v2/types.d.ts +20 -0
- package/src/lib/generated/uexecutor/v2/types.js +49 -33
- package/src/lib/generated/v1/tx.js +30 -37
- package/src/lib/index.d.ts +4 -1
- package/src/lib/index.js +21 -3
- package/src/lib/internal/buffer.js +1 -2
- package/src/lib/orchestrator/cea-utils.js +73 -83
- package/src/lib/orchestrator/internals/account-manager.js +130 -139
- package/src/lib/orchestrator/internals/cascade.d.ts +0 -6
- package/src/lib/orchestrator/internals/cascade.js +1184 -1059
- package/src/lib/orchestrator/internals/confirmation.js +138 -148
- package/src/lib/orchestrator/internals/error-decoder.js +1 -1
- package/src/lib/orchestrator/internals/errors.js +12 -3
- package/src/lib/orchestrator/internals/execute-funds-only.d.ts +2 -2
- package/src/lib/orchestrator/internals/execute-funds-only.js +297 -259
- package/src/lib/orchestrator/internals/execute-funds-payload.d.ts +2 -2
- package/src/lib/orchestrator/internals/execute-funds-payload.js +220 -220
- package/src/lib/orchestrator/internals/execute-standard.d.ts +0 -8
- package/src/lib/orchestrator/internals/execute-standard.js +339 -342
- package/src/lib/orchestrator/internals/gas-calculator.js +497 -520
- package/src/lib/orchestrator/internals/gas-usd-sizer.js +101 -110
- package/src/lib/orchestrator/internals/gateway-client.js +102 -103
- package/src/lib/orchestrator/internals/helpers.js +30 -27
- package/src/lib/orchestrator/internals/inbound-tracker.js +234 -238
- package/src/lib/orchestrator/internals/outbound-sync.js +463 -452
- package/src/lib/orchestrator/internals/outbound-tracker.js +27 -34
- package/src/lib/orchestrator/internals/payload-builder.d.ts +2 -2
- package/src/lib/orchestrator/internals/payload-builder.js +119 -100
- package/src/lib/orchestrator/internals/pc-usd-oracle.js +121 -129
- package/src/lib/orchestrator/internals/pc20/address-codec.d.ts +31 -0
- package/src/lib/orchestrator/internals/pc20/address-codec.js +124 -0
- package/src/lib/orchestrator/internals/pc20/chain-namespace.d.ts +68 -0
- package/src/lib/orchestrator/internals/pc20/chain-namespace.js +136 -0
- package/src/lib/orchestrator/internals/pc20/errors.d.ts +160 -0
- package/src/lib/orchestrator/internals/pc20/errors.js +236 -0
- package/src/lib/orchestrator/internals/pc20/export.d.ts +172 -0
- package/src/lib/orchestrator/internals/pc20/export.js +412 -0
- package/src/lib/orchestrator/internals/pc20/gate.d.ts +67 -0
- package/src/lib/orchestrator/internals/pc20/gate.js +184 -0
- package/src/lib/orchestrator/internals/pc20/resolver.d.ts +187 -0
- package/src/lib/orchestrator/internals/pc20/resolver.js +658 -0
- package/src/lib/orchestrator/internals/pc20/svm.d.ts +189 -0
- package/src/lib/orchestrator/internals/pc20/svm.js +286 -0
- package/src/lib/orchestrator/internals/pc20/tracking.d.ts +46 -0
- package/src/lib/orchestrator/internals/pc20/tracking.js +109 -0
- package/src/lib/orchestrator/internals/preflight.js +1 -1
- package/src/lib/orchestrator/internals/progress-route-hooks.js +2 -2
- package/src/lib/orchestrator/internals/push-chain-tx.js +319 -331
- package/src/lib/orchestrator/internals/quote.js +90 -94
- package/src/lib/orchestrator/internals/rescue.js +76 -79
- package/src/lib/orchestrator/internals/response-builder.d.ts +28 -1
- package/src/lib/orchestrator/internals/response-builder.js +817 -701
- package/src/lib/orchestrator/internals/route-handlers.d.ts +7 -15
- package/src/lib/orchestrator/internals/route-handlers.js +1512 -1178
- package/src/lib/orchestrator/internals/signing.js +78 -83
- package/src/lib/orchestrator/internals/svm-bridge.d.ts +2 -2
- package/src/lib/orchestrator/internals/svm-bridge.js +161 -93
- package/src/lib/orchestrator/internals/svm-helpers.d.ts +15 -1
- package/src/lib/orchestrator/internals/svm-helpers.js +68 -24
- package/src/lib/orchestrator/internals/svm-rent.d.ts +19 -1
- package/src/lib/orchestrator/internals/svm-rent.js +163 -141
- package/src/lib/orchestrator/internals/tx-transformer.js +26 -23
- package/src/lib/orchestrator/internals/uea-manager.js +89 -86
- package/src/lib/orchestrator/max-pc-for-gas.js +5 -6
- package/src/lib/orchestrator/orchestrator.js +217 -200
- package/src/lib/orchestrator/orchestrator.types.d.ts +121 -1
- package/src/lib/orchestrator/orchestrator.types.js +19 -0
- package/src/lib/orchestrator/payload-builders.d.ts +2 -2
- package/src/lib/orchestrator/payload-builders.js +26 -24
- package/src/lib/orchestrator/route-detector.js +26 -9
- package/src/lib/orchestrator/svm-idl/ix-encoder.js +1 -2
- package/src/lib/orchestrator/svm-idl/normalize-address.js +2 -2
- package/src/lib/orchestrator/svm-idl/resolve.js +1 -2
- package/src/lib/price-fetch/price-fetch.js +67 -68
- package/src/lib/progress-hook/progress-hook.js +124 -72
- package/src/lib/push-chain/push-chain.js +171 -153
- package/src/lib/push-client/push-client.js +223 -237
- package/src/lib/universal/account/account.js +349 -365
- package/src/lib/universal/signer/signer.d.ts +2 -1
- package/src/lib/universal/signer/signer.js +315 -299
- package/src/lib/universal-tx-detector/auto-detect.js +55 -60
- package/src/lib/universal-tx-detector/cascade.js +160 -172
- package/src/lib/universal-tx-detector/child-inbounds.js +67 -75
- package/src/lib/universal-tx-detector/classify.js +2 -3
- package/src/lib/universal-tx-detector/detector-svm.js +139 -147
- package/src/lib/universal-tx-detector/detector.js +145 -157
- package/src/lib/universal-tx-detector/normalize.js +7 -7
- package/src/lib/utils/external-tx-hash.js +1 -2
- package/src/lib/utils.d.ts +44 -0
- package/src/lib/utils.js +762 -683
- package/src/lib/vm-client/evm-client.js +186 -202
- package/src/lib/vm-client/svm-client.d.ts +1 -1
- package/src/lib/vm-client/svm-client.js +220 -224
- package/src/lib/vm-client/vm-client.types.d.ts +14 -2
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.computeUniversalTxId = computeUniversalTxId;
|
|
7
7
|
exports.extractAllUniversalSubTxIds = extractAllUniversalSubTxIds;
|
|
8
8
|
exports.extractUniversalSubTxIdFromTx = extractUniversalSubTxIdFromTx;
|
|
9
|
-
const tslib_1 = require("tslib");
|
|
10
9
|
const viem_1 = require("viem");
|
|
11
10
|
const chain_1 = require("../../constants/chain");
|
|
12
11
|
const context_1 = require("./context");
|
|
@@ -23,42 +22,36 @@ function computeUniversalTxId(pushNetwork, pushChainTxHash) {
|
|
|
23
22
|
// ============================================================================
|
|
24
23
|
// UTX ID Extraction from Cosmos Events
|
|
25
24
|
// ============================================================================
|
|
26
|
-
function extractAllUniversalSubTxIds(ctx, pushChainTxHash) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
: `0x${utxIdAttr.value}`;
|
|
44
|
-
subTxIds.push(id);
|
|
45
|
-
}
|
|
25
|
+
async function extractAllUniversalSubTxIds(ctx, pushChainTxHash) {
|
|
26
|
+
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] Fetching Cosmos tx for: ${pushChainTxHash}`);
|
|
27
|
+
try {
|
|
28
|
+
const cosmosTx = await ctx.pushClient.getCosmosTx(pushChainTxHash);
|
|
29
|
+
if (!cosmosTx?.events) {
|
|
30
|
+
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] No events in Cosmos tx`);
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
const subTxIds = [];
|
|
34
|
+
for (const event of cosmosTx.events) {
|
|
35
|
+
if (event.type === 'outbound_created') {
|
|
36
|
+
const utxIdAttr = event.attributes?.find((attr) => attr.key === 'utx_id');
|
|
37
|
+
if (utxIdAttr?.value) {
|
|
38
|
+
const id = utxIdAttr.value.startsWith('0x')
|
|
39
|
+
? utxIdAttr.value
|
|
40
|
+
: `0x${utxIdAttr.value}`;
|
|
41
|
+
subTxIds.push(id);
|
|
46
42
|
}
|
|
47
43
|
}
|
|
48
|
-
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] Found ${subTxIds.length} sub-tx IDs: ${subTxIds.join(', ')}`);
|
|
49
|
-
return subTxIds;
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
53
|
-
return [];
|
|
54
44
|
}
|
|
55
|
-
|
|
45
|
+
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] Found ${subTxIds.length} sub-tx IDs: ${subTxIds.join(', ')}`);
|
|
46
|
+
return subTxIds;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
(0, context_1.printLog)(ctx, `[extractAllUniversalSubTxIds] Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
56
52
|
}
|
|
57
|
-
function extractUniversalSubTxIdFromTx(ctx, pushChainTxHash) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const ids = yield extractAllUniversalSubTxIds(ctx, pushChainTxHash);
|
|
61
|
-
return (_a = ids[0]) !== null && _a !== void 0 ? _a : null;
|
|
62
|
-
});
|
|
53
|
+
async function extractUniversalSubTxIdFromTx(ctx, pushChainTxHash) {
|
|
54
|
+
const ids = await extractAllUniversalSubTxIds(ctx, pushChainTxHash);
|
|
55
|
+
return ids[0] ?? null;
|
|
63
56
|
}
|
|
64
57
|
//# sourceMappingURL=outbound-tracker.js.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* buildMulticallPayloadData: Encodes UEA_MULTICALL selector + abi-encoded calls
|
|
6
6
|
* buildGatewayPayloadAndGas: Constructs UniversalPayload + gateway request for fund flows
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { LegacyExecuteParams, MultiCall, UniversalTxRequest } from '../orchestrator.types';
|
|
9
9
|
import type { OrchestratorContext } from './context';
|
|
10
10
|
export declare function buildUniversalTxRequest(signerAddress: `0x${string}`, { recipient, token, amount, payload, }: {
|
|
11
11
|
recipient: `0x${string}`;
|
|
@@ -17,7 +17,7 @@ export declare function buildMulticallPayloadData(ctx: OrchestratorContext, to:
|
|
|
17
17
|
/**
|
|
18
18
|
* Builds the universal payload and gateway request for sendFunds / sendTxWithFunds flows.
|
|
19
19
|
*/
|
|
20
|
-
export declare function buildGatewayPayloadAndGas(ctx: OrchestratorContext, execute:
|
|
20
|
+
export declare function buildGatewayPayloadAndGas(ctx: OrchestratorContext, execute: LegacyExecuteParams, nonce: bigint, type: 'sendFunds' | 'sendTxWithFunds', fundsValue?: bigint): Promise<{
|
|
21
21
|
payload: never;
|
|
22
22
|
gasAmount: bigint;
|
|
23
23
|
req: UniversalTxRequest;
|
|
@@ -10,7 +10,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.buildUniversalTxRequest = buildUniversalTxRequest;
|
|
11
11
|
exports.buildMulticallPayloadData = buildMulticallPayloadData;
|
|
12
12
|
exports.buildGatewayPayloadAndGas = buildGatewayPayloadAndGas;
|
|
13
|
-
const tslib_1 = require("tslib");
|
|
14
13
|
const viem_1 = require("viem");
|
|
15
14
|
const tx_1 = require("../../generated/v1/tx");
|
|
16
15
|
const payload_builders_1 = require("../payload-builders");
|
|
@@ -73,106 +72,126 @@ function buildMulticallPayloadData(ctx, to, data) {
|
|
|
73
72
|
/**
|
|
74
73
|
* Builds the universal payload and gateway request for sendFunds / sendTxWithFunds flows.
|
|
75
74
|
*/
|
|
76
|
-
function buildGatewayPayloadAndGas(ctx, execute, nonce, type, fundsValue) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
75
|
+
async function buildGatewayPayloadAndGas(ctx, execute, nonce, type, fundsValue) {
|
|
76
|
+
const gasEstimate = execute.gasLimit || BigInt(1e7);
|
|
77
|
+
const gasAmount = execute.value ?? BigInt(0);
|
|
78
|
+
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
79
|
+
/**
|
|
80
|
+
* `req.recipient` for the gateway request.
|
|
81
|
+
*
|
|
82
|
+
* Normally `address(0)`, the protocol's "attribute funds to the caller's
|
|
83
|
+
* UEA" sentinel. It is only ever read on routes that resolve it — the chain
|
|
84
|
+
* overwrites `recipient` with zero for non-CEA payload-type inbounds
|
|
85
|
+
* (`x/uexecutor/types/inbound.go`), and the gateway's ERC20 route sends any
|
|
86
|
+
* excess native value down the GAS path, where zero is handled.
|
|
87
|
+
*
|
|
88
|
+
* A PC20 burn is the exception. `UniversalGateway._routePC20Tx` forwards the
|
|
89
|
+
* post-fee native value as a *FUNDS* request (not GAS, unlike the ERC20
|
|
90
|
+
* route) while copying this `recipient` verbatim. A FUNDS inbound deposits
|
|
91
|
+
* straight to `inbound.Recipient`, so a zero there makes the chain mint the
|
|
92
|
+
* prepaid gas to `address(0)` and revert — the deposit is silently lost.
|
|
93
|
+
* Verified by eth_call: `depositPRC20Token(pETH, amount, 0x0)` reverts,
|
|
94
|
+
* the same call with the UEA succeeds.
|
|
95
|
+
*
|
|
96
|
+
* Naming the UEA explicitly is a no-op for the PC20 burn event itself (the
|
|
97
|
+
* chain zeroes it for that leg regardless) and makes the native leg credit
|
|
98
|
+
* the account the gateway already intends: "route excess native value as a
|
|
99
|
+
* standard FUNDS transfer to caller's UEA".
|
|
100
|
+
*/
|
|
101
|
+
const requestRecipient = execute._pc20?.direction === 'import' ? ueaAddress : viem_1.zeroAddress;
|
|
102
|
+
if (type === 'sendTxWithFunds') {
|
|
103
|
+
if (!execute.funds?.token)
|
|
104
|
+
throw new Error(`Invalid ${execute.funds?.token}`);
|
|
105
|
+
const multicallData = (0, payload_builders_1.buildExecuteMulticall)({
|
|
106
|
+
execute,
|
|
107
|
+
ueaAddress,
|
|
108
|
+
});
|
|
109
|
+
const universalPayload = {
|
|
110
|
+
to: viem_1.zeroAddress,
|
|
111
|
+
value: execute.value ?? BigInt(0),
|
|
112
|
+
data: buildMulticallPayloadData(ctx, execute.to, multicallData),
|
|
113
|
+
gasLimit: gasEstimate,
|
|
114
|
+
maxFeePerGas: execute.maxFeePerGas || BigInt(1e10),
|
|
115
|
+
maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
|
|
116
|
+
nonce,
|
|
117
|
+
deadline: execute.deadline || BigInt(9999999999),
|
|
118
|
+
vType: tx_1.VerificationType.universalTxVerification,
|
|
119
|
+
};
|
|
120
|
+
(0, context_1.printLog)(ctx, '(universalPayload) ' + universalPayload);
|
|
121
|
+
let tokenAddress = execute.funds?.token?.address;
|
|
122
|
+
if (execute.funds?.token?.address ===
|
|
123
|
+
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee') {
|
|
124
|
+
tokenAddress = viem_1.zeroAddress;
|
|
113
125
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
});
|
|
168
|
-
(0, context_1.printLog)(ctx, 'sendFunds — final req: ' + JSON.stringify({
|
|
169
|
-
recipient: viem_1.zeroAddress,
|
|
170
|
-
token: tokenAddress,
|
|
171
|
-
amount: (_6 = (_5 = execute.funds) === null || _5 === void 0 ? void 0 : _5.amount) === null || _6 === void 0 ? void 0 : _6.toString(),
|
|
172
|
-
payloadLength: encodedPayload.length,
|
|
173
|
-
}, null, 2));
|
|
174
|
-
return { payload: universalPayload, gasAmount, req };
|
|
126
|
+
const req = buildUniversalTxRequest(ctx.universalSigner.account.address, {
|
|
127
|
+
recipient: requestRecipient,
|
|
128
|
+
token: tokenAddress,
|
|
129
|
+
amount: execute.funds?.amount,
|
|
130
|
+
payload: (0, signing_1.encodeUniversalPayload)(universalPayload),
|
|
131
|
+
});
|
|
132
|
+
return { payload: universalPayload, gasAmount, req };
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (!fundsValue)
|
|
136
|
+
throw new Error('fundsValue property must not be empty');
|
|
137
|
+
const multicallData = (0, payload_builders_1.buildExecuteMulticall)({
|
|
138
|
+
execute,
|
|
139
|
+
ueaAddress,
|
|
140
|
+
});
|
|
141
|
+
(0, context_1.printLog)(ctx, 'sendFunds — execute params: ' + JSON.stringify({
|
|
142
|
+
to: execute.to,
|
|
143
|
+
value: execute.value?.toString() ?? 'undefined',
|
|
144
|
+
data: execute.data ?? 'undefined',
|
|
145
|
+
fundsAmount: execute.funds?.amount?.toString(),
|
|
146
|
+
fundsToken: execute.funds?.token?.symbol,
|
|
147
|
+
tokenMechanism: execute.funds?.token?.mechanism,
|
|
148
|
+
tokenAddress: execute.funds?.token?.address,
|
|
149
|
+
gasLimit: execute.gasLimit?.toString() ?? 'undefined',
|
|
150
|
+
}, null, 2));
|
|
151
|
+
(0, context_1.printLog)(ctx, 'sendFunds — multicallData: ' + JSON.stringify(multicallData, (_, v) => typeof v === 'bigint' ? v.toString() : v, 2) + ' (length: ' + multicallData.length + ')');
|
|
152
|
+
const multicallPayloadData = buildMulticallPayloadData(ctx, execute.to, multicallData);
|
|
153
|
+
(0, context_1.printLog)(ctx, 'sendFunds — multicallPayloadData (first 66 chars): ' + multicallPayloadData.slice(0, 66) + ' (full length: ' + multicallPayloadData.length + ')');
|
|
154
|
+
const universalPayload = {
|
|
155
|
+
to: viem_1.zeroAddress,
|
|
156
|
+
value: execute.value ?? BigInt(0),
|
|
157
|
+
data: multicallPayloadData,
|
|
158
|
+
gasLimit: gasEstimate,
|
|
159
|
+
maxFeePerGas: execute.maxFeePerGas || BigInt(1e10),
|
|
160
|
+
maxPriorityFeePerGas: execute.maxPriorityFeePerGas || BigInt(0),
|
|
161
|
+
nonce,
|
|
162
|
+
deadline: execute.deadline || BigInt(9999999999),
|
|
163
|
+
vType: tx_1.VerificationType.universalTxVerification,
|
|
164
|
+
};
|
|
165
|
+
(0, context_1.printLog)(ctx, 'sendFunds — universalPayload (pre-encode): ' + JSON.stringify({
|
|
166
|
+
to: viem_1.zeroAddress,
|
|
167
|
+
value: (execute.value ?? BigInt(0)).toString(),
|
|
168
|
+
data: multicallPayloadData,
|
|
169
|
+
gasLimit: gasEstimate.toString(),
|
|
170
|
+
maxFeePerGas: (execute.maxFeePerGas || BigInt(1e10)).toString(),
|
|
171
|
+
maxPriorityFeePerGas: (execute.maxPriorityFeePerGas || BigInt(0)).toString(),
|
|
172
|
+
nonce: nonce.toString(),
|
|
173
|
+
deadline: (execute.deadline || BigInt(9999999999)).toString(),
|
|
174
|
+
}, null, 2));
|
|
175
|
+
let tokenAddress = execute.funds?.token?.address;
|
|
176
|
+
if (execute.funds?.token?.address ===
|
|
177
|
+
'0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee') {
|
|
178
|
+
tokenAddress = viem_1.zeroAddress;
|
|
175
179
|
}
|
|
176
|
-
|
|
180
|
+
const encodedPayload = (0, signing_1.encodeUniversalPayload)(universalPayload);
|
|
181
|
+
(0, context_1.printLog)(ctx, 'sendFunds — encodedPayload (first 66 chars): ' + encodedPayload.slice(0, 66) + ' (full length: ' + encodedPayload.length + ')');
|
|
182
|
+
const req = buildUniversalTxRequest(ctx.universalSigner.account.address, {
|
|
183
|
+
recipient: requestRecipient,
|
|
184
|
+
token: tokenAddress,
|
|
185
|
+
amount: execute.funds?.amount,
|
|
186
|
+
payload: encodedPayload,
|
|
187
|
+
});
|
|
188
|
+
(0, context_1.printLog)(ctx, 'sendFunds — final req: ' + JSON.stringify({
|
|
189
|
+
recipient: requestRecipient,
|
|
190
|
+
token: tokenAddress,
|
|
191
|
+
amount: execute.funds?.amount?.toString(),
|
|
192
|
+
payloadLength: encodedPayload.length,
|
|
193
|
+
}, null, 2));
|
|
194
|
+
return { payload: universalPayload, gasAmount, req };
|
|
195
|
+
}
|
|
177
196
|
}
|
|
178
197
|
//# sourceMappingURL=payload-builder.js.map
|
|
@@ -5,7 +5,6 @@ exports.getPcUsdPrice = getPcUsdPrice;
|
|
|
5
5
|
exports.pcToUsd = pcToUsd;
|
|
6
6
|
exports.usdToPc = usdToPc;
|
|
7
7
|
exports.__resetPcUsdCache = __resetPcUsdCache;
|
|
8
|
-
const tslib_1 = require("tslib");
|
|
9
8
|
/**
|
|
10
9
|
* Per-route $PC/USD oracle.
|
|
11
10
|
*
|
|
@@ -116,7 +115,7 @@ const ZERO_ADDR = '0x0000000000000000000000000000000000000000';
|
|
|
116
115
|
// ============================================================================
|
|
117
116
|
// Cache (module-level, 30s TTL — mirrors price-fetch.ts)
|
|
118
117
|
// ============================================================================
|
|
119
|
-
const PRICE_CACHE_TTL_MS =
|
|
118
|
+
const PRICE_CACHE_TTL_MS = 30_000;
|
|
120
119
|
const pcUsdPriceCache = new Map();
|
|
121
120
|
// ============================================================================
|
|
122
121
|
// Public API
|
|
@@ -126,150 +125,143 @@ const pcUsdPriceCache = new Map();
|
|
|
126
125
|
* Returns 0 on any failure — caller is expected to fall back to
|
|
127
126
|
* pushClient.pushToUSDC (the hardcoded $0.10 rate).
|
|
128
127
|
*/
|
|
129
|
-
function getPcUsdPrice(ctx, originChain) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
128
|
+
async function getPcUsdPrice(ctx, originChain) {
|
|
129
|
+
const cached = pcUsdPriceCache.get(originChain);
|
|
130
|
+
if (cached && Date.now() < cached.expiry) {
|
|
131
|
+
return cached.price;
|
|
132
|
+
}
|
|
133
|
+
const stableKey = ORIGIN_TO_STABLE[originChain];
|
|
134
|
+
if (!stableKey) {
|
|
135
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — no stable token mapped for origin ${originChain}; returning 0`);
|
|
136
|
+
return BigInt(0);
|
|
137
|
+
}
|
|
138
|
+
const pushChain = (0, helpers_1.getPushChainForNetwork)(ctx.pushNetwork);
|
|
139
|
+
const quoterAddress = chain_1.CHAIN_INFO[pushChain]?.dex?.uniV3QuoterV2;
|
|
140
|
+
if (!quoterAddress || quoterAddress.startsWith('0xTBD')) {
|
|
141
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — no QuoterV2 configured for ${pushChain}; returning 0`);
|
|
142
|
+
return BigInt(0);
|
|
143
|
+
}
|
|
144
|
+
const stableAddress = chain_1.SYNTHETIC_PUSH_ERC20[ctx.pushNetwork]?.[stableKey];
|
|
145
|
+
if (!stableAddress || stableAddress.startsWith('0xTBD')) {
|
|
146
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — no ${stableKey} mapped on ${ctx.pushNetwork}; returning 0`);
|
|
147
|
+
return BigInt(0);
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const gatewayPcAddress = (0, helpers_1.getUniversalGatewayPCAddress)();
|
|
151
|
+
const universalCoreAddress = await ctx.pushClient.readContract({
|
|
152
|
+
address: gatewayPcAddress,
|
|
153
|
+
abi: abi_1.UNIVERSAL_GATEWAY_PC,
|
|
154
|
+
functionName: 'universalCore',
|
|
155
|
+
args: [],
|
|
156
|
+
});
|
|
157
|
+
const [wpcAddress, factoryAddress, defaultFeeTier] = await Promise.all([
|
|
158
|
+
ctx.pushClient.readContract({
|
|
159
|
+
address: universalCoreAddress,
|
|
160
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
161
|
+
functionName: 'WPC',
|
|
162
|
+
args: [],
|
|
163
|
+
}),
|
|
164
|
+
ctx.pushClient.readContract({
|
|
165
|
+
address: universalCoreAddress,
|
|
166
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
167
|
+
functionName: 'uniswapV3Factory',
|
|
168
|
+
args: [],
|
|
169
|
+
}),
|
|
170
|
+
ctx.pushClient.readContract({
|
|
171
|
+
address: universalCoreAddress,
|
|
172
|
+
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
173
|
+
functionName: 'defaultFeeTier',
|
|
174
|
+
args: [stableAddress],
|
|
175
|
+
}),
|
|
176
|
+
]);
|
|
177
|
+
if (!wpcAddress) {
|
|
178
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — missing WPC; returning 0`);
|
|
150
179
|
return BigInt(0);
|
|
151
180
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
ctx.pushClient.readContract({
|
|
168
|
-
address: universalCoreAddress,
|
|
169
|
-
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
170
|
-
functionName: 'uniswapV3Factory',
|
|
171
|
-
args: [],
|
|
172
|
-
}),
|
|
173
|
-
ctx.pushClient.readContract({
|
|
174
|
-
address: universalCoreAddress,
|
|
175
|
-
abi: UNIVERSAL_CORE_SWAP_HELPERS_ABI,
|
|
176
|
-
functionName: 'defaultFeeTier',
|
|
177
|
-
args: [stableAddress],
|
|
178
|
-
}),
|
|
179
|
-
]);
|
|
180
|
-
if (!wpcAddress) {
|
|
181
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice — missing WPC; returning 0`);
|
|
182
|
-
return BigInt(0);
|
|
183
|
-
}
|
|
184
|
-
// UniversalCore's defaultFeeTier is set only for gas tokens (pETH*, pSOL).
|
|
185
|
-
// For stables, probe the factory for the first tier with a live pool.
|
|
186
|
-
let feeTier = defaultFeeTier;
|
|
187
|
-
if (!feeTier) {
|
|
188
|
-
for (const candidate of STABLE_FEE_TIER_FALLBACKS) {
|
|
189
|
-
const pool = yield ctx.pushClient.readContract({
|
|
190
|
-
address: factoryAddress,
|
|
191
|
-
abi: UNISWAP_V3_FACTORY_ABI,
|
|
192
|
-
functionName: 'getPool',
|
|
193
|
-
args: [wpcAddress, stableAddress, candidate],
|
|
194
|
-
});
|
|
195
|
-
if (pool && pool !== ZERO_ADDR) {
|
|
196
|
-
feeTier = candidate;
|
|
197
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice — resolved fee tier ${candidate} via factory probe for WPC/${stableKey}`);
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
181
|
+
// UniversalCore's defaultFeeTier is set only for gas tokens (pETH*, pSOL).
|
|
182
|
+
// For stables, probe the factory for the first tier with a live pool.
|
|
183
|
+
let feeTier = defaultFeeTier;
|
|
184
|
+
if (!feeTier) {
|
|
185
|
+
for (const candidate of STABLE_FEE_TIER_FALLBACKS) {
|
|
186
|
+
const pool = await ctx.pushClient.readContract({
|
|
187
|
+
address: factoryAddress,
|
|
188
|
+
abi: UNISWAP_V3_FACTORY_ABI,
|
|
189
|
+
functionName: 'getPool',
|
|
190
|
+
args: [wpcAddress, stableAddress, candidate],
|
|
191
|
+
});
|
|
192
|
+
if (pool && pool !== ZERO_ADDR) {
|
|
193
|
+
feeTier = candidate;
|
|
194
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — resolved fee tier ${candidate} via factory probe for WPC/${stableKey}`);
|
|
195
|
+
break;
|
|
200
196
|
}
|
|
201
197
|
}
|
|
202
|
-
if (!feeTier) {
|
|
203
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice — no WPC/${stableKey} pool found at any fee tier; returning 0`);
|
|
204
|
-
return BigInt(0);
|
|
205
|
-
}
|
|
206
|
-
// Quote: 1 WPC (1e18) → X stable (DEFAULT_STABLE_DECIMALS)
|
|
207
|
-
const oneWpc = (0, viem_1.parseUnits)('1', 18);
|
|
208
|
-
const result = yield ctx.pushClient.readContract({
|
|
209
|
-
address: quoterAddress,
|
|
210
|
-
abi: QUOTER_V2_ABI,
|
|
211
|
-
functionName: 'quoteExactInputSingle',
|
|
212
|
-
args: [
|
|
213
|
-
{
|
|
214
|
-
tokenIn: wpcAddress,
|
|
215
|
-
tokenOut: stableAddress,
|
|
216
|
-
amountIn: oneWpc,
|
|
217
|
-
fee: feeTier,
|
|
218
|
-
sqrtPriceLimitX96: BigInt(0),
|
|
219
|
-
},
|
|
220
|
-
],
|
|
221
|
-
});
|
|
222
|
-
const stableOut = result[0];
|
|
223
|
-
if (stableOut === BigInt(0)) {
|
|
224
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice — quoter returned 0 for WPC→${stableKey}`);
|
|
225
|
-
return BigInt(0);
|
|
226
|
-
}
|
|
227
|
-
// Normalize stableOut (DEFAULT_STABLE_DECIMALS) to 8-decimal USD.
|
|
228
|
-
// If stable decimals > 8, divide; otherwise multiply.
|
|
229
|
-
const decDelta = 8 - DEFAULT_STABLE_DECIMALS;
|
|
230
|
-
const price = decDelta >= 0
|
|
231
|
-
? stableOut * BigInt(Math.pow(10, decDelta))
|
|
232
|
-
: stableOut / BigInt(Math.pow(10, -decDelta));
|
|
233
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice — origin=${originChain} stable=${stableKey} quote: 1 WPC = ${stableOut.toString()} (${DEFAULT_STABLE_DECIMALS}d) = ${price.toString()} (1e8 USD)`);
|
|
234
|
-
pcUsdPriceCache.set(originChain, {
|
|
235
|
-
price,
|
|
236
|
-
expiry: Date.now() + PRICE_CACHE_TTL_MS,
|
|
237
|
-
});
|
|
238
|
-
return price;
|
|
239
198
|
}
|
|
240
|
-
|
|
241
|
-
(0, context_1.printLog)(ctx, `getPcUsdPrice —
|
|
199
|
+
if (!feeTier) {
|
|
200
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — no WPC/${stableKey} pool found at any fee tier; returning 0`);
|
|
201
|
+
return BigInt(0);
|
|
202
|
+
}
|
|
203
|
+
// Quote: 1 WPC (1e18) → X stable (DEFAULT_STABLE_DECIMALS)
|
|
204
|
+
const oneWpc = (0, viem_1.parseUnits)('1', 18);
|
|
205
|
+
const result = await ctx.pushClient.readContract({
|
|
206
|
+
address: quoterAddress,
|
|
207
|
+
abi: QUOTER_V2_ABI,
|
|
208
|
+
functionName: 'quoteExactInputSingle',
|
|
209
|
+
args: [
|
|
210
|
+
{
|
|
211
|
+
tokenIn: wpcAddress,
|
|
212
|
+
tokenOut: stableAddress,
|
|
213
|
+
amountIn: oneWpc,
|
|
214
|
+
fee: feeTier,
|
|
215
|
+
sqrtPriceLimitX96: BigInt(0),
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
});
|
|
219
|
+
const stableOut = result[0];
|
|
220
|
+
if (stableOut === BigInt(0)) {
|
|
221
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — quoter returned 0 for WPC→${stableKey}`);
|
|
242
222
|
return BigInt(0);
|
|
243
223
|
}
|
|
244
|
-
|
|
224
|
+
// Normalize stableOut (DEFAULT_STABLE_DECIMALS) to 8-decimal USD.
|
|
225
|
+
// If stable decimals > 8, divide; otherwise multiply.
|
|
226
|
+
const decDelta = 8 - DEFAULT_STABLE_DECIMALS;
|
|
227
|
+
const price = decDelta >= 0
|
|
228
|
+
? stableOut * BigInt(10 ** decDelta)
|
|
229
|
+
: stableOut / BigInt(10 ** -decDelta);
|
|
230
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — origin=${originChain} stable=${stableKey} quote: 1 WPC = ${stableOut.toString()} (${DEFAULT_STABLE_DECIMALS}d) = ${price.toString()} (1e8 USD)`);
|
|
231
|
+
pcUsdPriceCache.set(originChain, {
|
|
232
|
+
price,
|
|
233
|
+
expiry: Date.now() + PRICE_CACHE_TTL_MS,
|
|
234
|
+
});
|
|
235
|
+
return price;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
(0, context_1.printLog)(ctx, `getPcUsdPrice — failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
239
|
+
return BigInt(0);
|
|
240
|
+
}
|
|
245
241
|
}
|
|
246
242
|
/**
|
|
247
243
|
* Convert a nPUSH (18-dec) amount to USD (8-dec) using the per-route oracle.
|
|
248
244
|
* Falls back to the fixed pushToUSDC rate if the oracle returns 0.
|
|
249
245
|
*/
|
|
250
|
-
function pcToUsd(ctx, pcAmount, originChain) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
return (pcAmount * price) / oneWpc;
|
|
258
|
-
});
|
|
246
|
+
async function pcToUsd(ctx, pcAmount, originChain) {
|
|
247
|
+
const price = await getPcUsdPrice(ctx, originChain);
|
|
248
|
+
if (price === BigInt(0)) {
|
|
249
|
+
return ctx.pushClient.pushToUSDC(pcAmount);
|
|
250
|
+
}
|
|
251
|
+
const oneWpc = (0, viem_1.parseUnits)('1', 18);
|
|
252
|
+
return (pcAmount * price) / oneWpc;
|
|
259
253
|
}
|
|
260
254
|
/**
|
|
261
255
|
* Convert a USD (8-dec) amount to nPUSH (18-dec) using the per-route oracle.
|
|
262
256
|
* Falls back to the fixed usdcToPush rate if the oracle returns 0.
|
|
263
257
|
*/
|
|
264
|
-
function usdToPc(ctx, usdAmount, originChain) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
return (usdAmount * oneWpc + (price - BigInt(1))) / price;
|
|
272
|
-
});
|
|
258
|
+
async function usdToPc(ctx, usdAmount, originChain) {
|
|
259
|
+
const price = await getPcUsdPrice(ctx, originChain);
|
|
260
|
+
if (price === BigInt(0)) {
|
|
261
|
+
return ctx.pushClient.usdcToPush(usdAmount);
|
|
262
|
+
}
|
|
263
|
+
const oneWpc = (0, viem_1.parseUnits)('1', 18);
|
|
264
|
+
return (usdAmount * oneWpc + (price - BigInt(1))) / price;
|
|
273
265
|
}
|
|
274
266
|
/**
|
|
275
267
|
* Test-only: clear the module-level cache. Unit tests mock `readContract`
|