@pushchain/core 5.1.4 → 5.1.5-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/index.d.ts +1 -1
- package/src/lib/orchestrator/internals/cascade.js +68 -25
- package/src/lib/orchestrator/internals/execute-funds-payload.js +4 -4
- package/src/lib/orchestrator/internals/execute-standard.js +55 -7
- package/src/lib/orchestrator/internals/gas-calculator.d.ts +10 -0
- package/src/lib/orchestrator/internals/gas-calculator.js +95 -3
- package/src/lib/orchestrator/internals/gateway-client.js +6 -6
- package/src/lib/orchestrator/internals/response-builder.js +24 -1
- package/src/lib/orchestrator/internals/route-handlers.js +27 -43
- package/src/lib/orchestrator/orchestrator.types.d.ts +13 -23
- package/src/lib/orchestrator/route-detector.js +0 -3
- package/src/lib/orchestrator/svm-idl/build-payload.d.ts +11 -0
- package/src/lib/orchestrator/svm-idl/build-payload.js +36 -0
- package/src/lib/orchestrator/svm-idl/ix-encoder.d.ts +3 -0
- package/src/lib/orchestrator/svm-idl/ix-encoder.js +47 -0
- package/src/lib/orchestrator/svm-idl/registry.d.ts +10 -0
- package/src/lib/orchestrator/svm-idl/registry.js +36 -0
- package/src/lib/orchestrator/svm-idl/resolve.d.ts +14 -0
- package/src/lib/orchestrator/svm-idl/resolve.js +85 -0
- package/src/lib/progress-hook/progress-hook.js +40 -0
- package/src/lib/progress-hook/progress-hook.types.d.ts +5 -0
- package/src/lib/progress-hook/progress-hook.types.js +6 -0
- package/src/lib/push-chain/push-chain.js +14 -4
- package/src/lib/universal/account/account.d.ts +13 -0
- package/src/lib/universal/account/account.js +1 -0
- package/src/lib/utils.d.ts +20 -1
- package/src/lib/utils.js +28 -0
|
@@ -35,6 +35,7 @@ const utils_1 = require("../../utils");
|
|
|
35
35
|
const price_fetch_1 = require("../../price-fetch/price-fetch");
|
|
36
36
|
const route_detector_1 = require("../route-detector");
|
|
37
37
|
const cea_utils_1 = require("../cea-utils");
|
|
38
|
+
const build_payload_1 = require("../svm-idl/build-payload");
|
|
38
39
|
const payload_builders_1 = require("../payload-builders");
|
|
39
40
|
const selectors_1 = require("../../constants/selectors");
|
|
40
41
|
const erc20_evm_1 = require("../../constants/abi/erc20.evm");
|
|
@@ -393,22 +394,15 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
393
394
|
const targetChain = target.chain;
|
|
394
395
|
const targetAddress = target.address; // 0x-prefixed, 32 bytes
|
|
395
396
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
396
|
-
const hasSvmExecute =
|
|
397
|
+
const { svmPayload, targetBytes, hasExecute: hasSvmExecute, } = (0, build_payload_1.buildSvmPayloadFromParams)({
|
|
398
|
+
data: params.data,
|
|
399
|
+
to: target,
|
|
400
|
+
senderUea: ueaAddress,
|
|
401
|
+
});
|
|
397
402
|
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — target: ${targetAddress}, chain: ${targetChain}, ` +
|
|
398
403
|
`hasSvmExecute: ${hasSvmExecute}, value: ${(_b = (_a = params.value) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '0'}`);
|
|
399
|
-
// --- Build SVM payload ---
|
|
400
|
-
let svmPayload = '0x'; // empty for withdraw (SOL/SPL)
|
|
401
404
|
if (hasSvmExecute) {
|
|
402
|
-
|
|
403
|
-
const exec = params.svmExecute;
|
|
404
|
-
svmPayload = (0, payload_builders_1.encodeSvmExecutePayload)({
|
|
405
|
-
targetProgram: exec.targetProgram,
|
|
406
|
-
accounts: exec.accounts,
|
|
407
|
-
ixData: exec.ixData,
|
|
408
|
-
instructionId: 2,
|
|
409
|
-
});
|
|
410
|
-
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — encoded execute payload: ${(svmPayload.length - 2) / 2} bytes, ` +
|
|
411
|
-
`${exec.accounts.length} accounts`);
|
|
405
|
+
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — encoded execute payload: ${(svmPayload.length - 2) / 2} bytes`);
|
|
412
406
|
}
|
|
413
407
|
// --- Determine PRC-20 token and burn amount ---
|
|
414
408
|
let prc20Token = selectors_1.ZERO_ADDRESS;
|
|
@@ -439,13 +433,8 @@ function executeUoaToCeaSvm(ctx, params, target, executeFn) {
|
|
|
439
433
|
burnAmount = BigInt(0);
|
|
440
434
|
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — EXECUTE-only: using PRC-20 ${prc20Token} with zero burn amount`);
|
|
441
435
|
}
|
|
442
|
-
// --- Determine target bytes ---
|
|
443
|
-
// For withdraw: target is the Solana recipient pubkey
|
|
444
|
-
// For execute: target is the target Solana program
|
|
445
|
-
const targetBytes = hasSvmExecute
|
|
446
|
-
? params.svmExecute.targetProgram
|
|
447
|
-
: targetAddress;
|
|
448
436
|
// --- Build outbound request ---
|
|
437
|
+
// targetBytes: for execute = program id (resolver output); for withdraw = to.address
|
|
449
438
|
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_d = params.gasLimit) !== null && _d !== void 0 ? _d : BigInt(0), svmPayload, ueaAddress // revert recipient is the UEA
|
|
450
439
|
);
|
|
451
440
|
(0, context_1.printLog)(ctx, `executeUoaToCeaSvm — outbound request: ${JSON.stringify({
|
|
@@ -972,7 +961,7 @@ function executeCeaToCea(ctx, params, executeFn) {
|
|
|
972
961
|
*/
|
|
973
962
|
function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
974
963
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
975
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l
|
|
964
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
976
965
|
const ueaAddress = (0, uea_manager_1.computeUEAOffchain)(ctx);
|
|
977
966
|
switch (route) {
|
|
978
967
|
case route_detector_1.TransactionRoute.UOA_TO_PUSH: {
|
|
@@ -995,20 +984,15 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
995
984
|
const target = params.to;
|
|
996
985
|
// Branch: SVM vs EVM
|
|
997
986
|
if ((0, payload_builders_1.isSvmChain)(target.chain)) {
|
|
998
|
-
// SVM: build SVM payload (binary or empty for withdraw)
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
ixData: params.svmExecute.ixData,
|
|
1005
|
-
instructionId: 2,
|
|
1006
|
-
});
|
|
1007
|
-
}
|
|
1008
|
-
const targetBytes = (_b = (_a = params.svmExecute) === null || _a === void 0 ? void 0 : _a.targetProgram) !== null && _b !== void 0 ? _b : target.address;
|
|
987
|
+
// SVM: build SVM payload (binary or empty for withdraw) via IDL resolver
|
|
988
|
+
const { svmPayload: payload, targetBytes, hasExecute, } = (0, build_payload_1.buildSvmPayloadFromParams)({
|
|
989
|
+
data: params.data,
|
|
990
|
+
to: target,
|
|
991
|
+
senderUea: ueaAddress,
|
|
992
|
+
});
|
|
1009
993
|
let prc20Token = selectors_1.ZERO_ADDRESS;
|
|
1010
994
|
let burnAmount = BigInt(0);
|
|
1011
|
-
if ((
|
|
995
|
+
if ((_a = params.funds) === null || _a === void 0 ? void 0 : _a.amount) {
|
|
1012
996
|
const token = params.funds.token;
|
|
1013
997
|
if (token) {
|
|
1014
998
|
prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
|
|
@@ -1019,15 +1003,15 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1019
1003
|
prc20Token = (0, helpers_1.getNativePRC20ForChain)(target.chain, ctx.pushNetwork);
|
|
1020
1004
|
burnAmount = params.value;
|
|
1021
1005
|
}
|
|
1022
|
-
else if (
|
|
1006
|
+
else if (hasExecute) {
|
|
1023
1007
|
prc20Token = (0, helpers_1.getNativePRC20ForChain)(target.chain, ctx.pushNetwork);
|
|
1024
1008
|
burnAmount = BigInt(1);
|
|
1025
1009
|
}
|
|
1026
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (
|
|
1010
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_b = params.gasLimit) !== null && _b !== void 0 ? _b : BigInt(0), payload, ueaAddress);
|
|
1027
1011
|
return { payload, gatewayRequest: outboundReq };
|
|
1028
1012
|
}
|
|
1029
1013
|
// EVM path: Resolve CEA address first (needed for self-transfer check)
|
|
1030
|
-
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, target.chain, (
|
|
1014
|
+
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, target.chain, (_c = ctx.rpcUrls[target.chain]) === null || _c === void 0 ? void 0 : _c[0]);
|
|
1031
1015
|
// Build CEA outbound payload
|
|
1032
1016
|
const multicalls = [];
|
|
1033
1017
|
if (params.data) {
|
|
@@ -1060,7 +1044,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1060
1044
|
const payload = (0, payload_builders_1.buildCeaMulticallPayload)(multicalls);
|
|
1061
1045
|
let prc20Token = selectors_1.ZERO_ADDRESS;
|
|
1062
1046
|
let burnAmount = BigInt(0);
|
|
1063
|
-
if ((
|
|
1047
|
+
if ((_d = params.funds) === null || _d === void 0 ? void 0 : _d.amount) {
|
|
1064
1048
|
const token = params.funds.token;
|
|
1065
1049
|
if (token) {
|
|
1066
1050
|
prc20Token = push_chain_1.PushChain.utils.tokens.getPRC20Address(token);
|
|
@@ -1068,13 +1052,13 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1068
1052
|
}
|
|
1069
1053
|
}
|
|
1070
1054
|
const targetBytes = ceaAddress;
|
|
1071
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (
|
|
1055
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(targetBytes, prc20Token, burnAmount, (_e = params.gasLimit) !== null && _e !== void 0 ? _e : BigInt(0), payload, ueaAddress);
|
|
1072
1056
|
return { payload, gatewayRequest: outboundReq };
|
|
1073
1057
|
}
|
|
1074
1058
|
case route_detector_1.TransactionRoute.CEA_TO_PUSH: {
|
|
1075
1059
|
// Route 3: CEA -> Push Chain
|
|
1076
1060
|
// Build CEA multicall (approve + sendUniversalTxFromCEA) and wrap in outbound
|
|
1077
|
-
if (!((
|
|
1061
|
+
if (!((_f = params.from) === null || _f === void 0 ? void 0 : _f.chain)) {
|
|
1078
1062
|
throw new Error('Route 3 (CEA -> Push) requires from.chain');
|
|
1079
1063
|
}
|
|
1080
1064
|
const sourceChain = params.from.chain;
|
|
@@ -1089,7 +1073,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1089
1073
|
const gatewayProgramHex = ('0x' + Buffer.from(programPk.toBytes()).toString('hex'));
|
|
1090
1074
|
let drainAmount = BigInt(0);
|
|
1091
1075
|
let tokenMintHex;
|
|
1092
|
-
if (((
|
|
1076
|
+
if (((_g = params.funds) === null || _g === void 0 ? void 0 : _g.amount) && params.funds.amount > BigInt(0)) {
|
|
1093
1077
|
drainAmount = params.funds.amount;
|
|
1094
1078
|
const token = params.funds.token;
|
|
1095
1079
|
if (token && token.address) {
|
|
@@ -1114,10 +1098,10 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1114
1098
|
});
|
|
1115
1099
|
// burnAmount = 1 (minimum for precompile; drain amount lives inside the ixData)
|
|
1116
1100
|
const burnAmount = BigInt(1);
|
|
1117
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, (
|
|
1101
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(gatewayProgramHex, prc20Token, burnAmount, (_h = params.gasLimit) !== null && _h !== void 0 ? _h : BigInt(0), svmPayload, ueaAddress);
|
|
1118
1102
|
return { payload: svmPayload, gatewayRequest: outboundReq };
|
|
1119
1103
|
}
|
|
1120
|
-
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (
|
|
1104
|
+
const { cea: ceaAddress } = yield (0, cea_utils_1.getCEAAddress)(ueaAddress, sourceChain, (_j = ctx.rpcUrls[sourceChain]) === null || _j === void 0 ? void 0 : _j[0]);
|
|
1121
1105
|
// CEA auto-deploys on-chain: Vault.finalizeUniversalTx calls CEAFactory.deployCEA()
|
|
1122
1106
|
// if CEA doesn't exist yet. No SDK-side blocking needed.
|
|
1123
1107
|
const gatewayAddr = chain_1.UNIVERSAL_GATEWAY_ADDRESSES[sourceChain];
|
|
@@ -1128,7 +1112,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1128
1112
|
const ceaMulticalls = [];
|
|
1129
1113
|
let tokenAddress = selectors_1.ZERO_ADDRESS;
|
|
1130
1114
|
let amount = BigInt(0);
|
|
1131
|
-
if ((
|
|
1115
|
+
if ((_k = params.funds) === null || _k === void 0 ? void 0 : _k.amount) {
|
|
1132
1116
|
const token = params.funds.token;
|
|
1133
1117
|
if (token) {
|
|
1134
1118
|
if (token.mechanism === 'native') {
|
|
@@ -1192,7 +1176,7 @@ function buildPayloadForRoute(ctx, params, route, nonce) {
|
|
|
1192
1176
|
// Route 3: CEA uses its own pre-existing balance — no PRC-20 burn needed.
|
|
1193
1177
|
// burnAmount = 0 makes this a payload-only outbound relay.
|
|
1194
1178
|
const burnAmount = BigInt(0);
|
|
1195
|
-
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, (
|
|
1179
|
+
const outboundReq = (0, payload_builders_1.buildOutboundRequest)(ceaAddress, prc20Token, burnAmount, (_l = params.gasLimit) !== null && _l !== void 0 ? _l : BigInt(0), ceaPayload, ueaAddress);
|
|
1196
1180
|
return { payload: ceaPayload, gatewayRequest: outboundReq };
|
|
1197
1181
|
}
|
|
1198
1182
|
default:
|
|
@@ -110,7 +110,7 @@ export type ExecuteParams = {
|
|
|
110
110
|
* Internal: Minimum fee-locking deposit in USD (8 decimals).
|
|
111
111
|
* Overrides the default $1 floor when the caller needs a larger deposit
|
|
112
112
|
* (e.g., Route 2 needs enough UPC for the outbound swap).
|
|
113
|
-
* Still capped at $
|
|
113
|
+
* Still capped at $1000 by lockFee.
|
|
114
114
|
* @internal
|
|
115
115
|
*/
|
|
116
116
|
_minimumDepositUsd?: bigint;
|
|
@@ -138,7 +138,10 @@ export interface UniversalTxResponse {
|
|
|
138
138
|
wait: () => Promise<UniversalTxReceipt>;
|
|
139
139
|
/**
|
|
140
140
|
* Register a progress callback for events during wait().
|
|
141
|
-
* Call this BEFORE calling wait() to receive tracking events
|
|
141
|
+
* Call this BEFORE calling wait() to receive tracking events, including
|
|
142
|
+
* the SEND-TX-08-xx / SEND-TX-99-03/04/05 external chain polling events
|
|
143
|
+
* emitted on outbound routes. Registering after wait() resolves will
|
|
144
|
+
* replay the pre-execution event buffer but miss outbound polling events.
|
|
142
145
|
* @param callback - Function called with each progress event
|
|
143
146
|
*/
|
|
144
147
|
progressHook: (callback: (event: import('../progress-hook/progress-hook.types').ProgressEvent) => void) => void;
|
|
@@ -291,16 +294,9 @@ export type UniversalExecuteParams = Omit<ExecuteParams, 'to'> & {
|
|
|
291
294
|
* - ChainTarget: External chain target (Routes 2, 3, 4)
|
|
292
295
|
*/
|
|
293
296
|
to: UniversalTo;
|
|
294
|
-
/**
|
|
295
|
-
* SVM-specific: CPI execution parameters for Solana targets (Route 2).
|
|
296
|
-
* When present, the outbound transaction will execute a Cross-Program Invocation
|
|
297
|
-
* on the specified Solana program with the given accounts and instruction data.
|
|
298
|
-
* Only applicable when `to.chain` is a Solana chain.
|
|
299
|
-
*/
|
|
300
|
-
svmExecute?: SvmExecuteParams;
|
|
301
297
|
/**
|
|
302
298
|
* When true, sends MIGRATION_SELECTOR as raw CEA payload (no multicall wrapping).
|
|
303
|
-
* Used for CEA contract upgrades. Incompatible with value/funds/data
|
|
299
|
+
* Used for CEA contract upgrades. Incompatible with value/funds/data.
|
|
304
300
|
* Only applicable for Route 2 (UOA_TO_CEA) on EVM chains.
|
|
305
301
|
*/
|
|
306
302
|
migration?: boolean;
|
|
@@ -329,18 +325,6 @@ export interface SvmExecutePayloadFields {
|
|
|
329
325
|
/** Instruction ID: 2 = execute (default) */
|
|
330
326
|
instructionId?: number;
|
|
331
327
|
}
|
|
332
|
-
/**
|
|
333
|
-
* User-facing parameters for CPI execution on a Solana program via Route 2.
|
|
334
|
-
* Passed as `svmExecute` in UniversalExecuteParams when targeting SVM chains.
|
|
335
|
-
*/
|
|
336
|
-
export interface SvmExecuteParams {
|
|
337
|
-
/** Target Solana program to CPI into (32 bytes, 0x-prefixed hex) */
|
|
338
|
-
targetProgram: `0x${string}`;
|
|
339
|
-
/** Accounts required for the CPI call */
|
|
340
|
-
accounts: SvmGatewayAccountMeta[];
|
|
341
|
-
/** Raw instruction data for the target program */
|
|
342
|
-
ixData: Uint8Array;
|
|
343
|
-
}
|
|
344
328
|
/**
|
|
345
329
|
* Request structure for sendUniversalTxOutbound on Push Chain
|
|
346
330
|
* Used for Routes 2, 3, 4 (outbound from Push)
|
|
@@ -534,8 +518,14 @@ export interface CascadeTrackOptions {
|
|
|
534
518
|
pollingIntervalMs?: number;
|
|
535
519
|
/** Total timeout (default: 600000ms = 10 min) */
|
|
536
520
|
timeout?: number;
|
|
537
|
-
/**
|
|
521
|
+
/** Per-hop progress callback */
|
|
538
522
|
progressHook?: (event: CascadeProgressEvent) => void;
|
|
523
|
+
/**
|
|
524
|
+
* Unified ProgressEvent stream for SEND-TX-08/99_03-05 telemetry.
|
|
525
|
+
* Fires per outbound hop during external chain polling. Use alongside
|
|
526
|
+
* `progressHook` — they emit complementary views of the same events.
|
|
527
|
+
*/
|
|
528
|
+
eventHook?: (event: import('../progress-hook/progress-hook.types').ProgressEvent) => void;
|
|
539
529
|
}
|
|
540
530
|
/**
|
|
541
531
|
* Progress event emitted during cascade tracking
|
|
@@ -249,9 +249,6 @@ function validateRouteParams(params, context) {
|
|
|
249
249
|
if (params.data) {
|
|
250
250
|
throw new RouteValidationError('migration is incompatible with data');
|
|
251
251
|
}
|
|
252
|
-
if (params.svmExecute) {
|
|
253
|
-
throw new RouteValidationError('migration is incompatible with svmExecute');
|
|
254
|
-
}
|
|
255
252
|
if (isChainTarget(params.to) && (0, payload_builders_1.isSvmChain)(params.to.chain)) {
|
|
256
253
|
throw new RouteValidationError('migration is not supported on SVM chains');
|
|
257
254
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ChainTarget } from '../orchestrator.types';
|
|
2
|
+
export interface SvmPayloadBundle {
|
|
3
|
+
svmPayload: `0x${string}`;
|
|
4
|
+
targetBytes: `0x${string}`;
|
|
5
|
+
hasExecute: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function buildSvmPayloadFromParams(params: {
|
|
8
|
+
data?: `0x${string}` | unknown;
|
|
9
|
+
to: ChainTarget;
|
|
10
|
+
senderUea: `0x${string}`;
|
|
11
|
+
}): SvmPayloadBundle;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildSvmPayloadFromParams = buildSvmPayloadFromParams;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const payload_builders_1 = require("../payload-builders");
|
|
6
|
+
const resolve_1 = require("./resolve");
|
|
7
|
+
function buildSvmPayloadFromParams(params) {
|
|
8
|
+
const hasExecute = typeof params.data === 'string' &&
|
|
9
|
+
params.data.startsWith('0x') &&
|
|
10
|
+
params.data.length > 2;
|
|
11
|
+
if (!hasExecute) {
|
|
12
|
+
return {
|
|
13
|
+
svmPayload: '0x',
|
|
14
|
+
targetBytes: params.to.address,
|
|
15
|
+
hasExecute: false,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const resolved = (0, resolve_1.resolveSvmCall)({
|
|
19
|
+
programAddress: params.to.address,
|
|
20
|
+
data: (0, viem_1.hexToBytes)(params.data),
|
|
21
|
+
senderUea: params.senderUea,
|
|
22
|
+
targetChain: params.to.chain,
|
|
23
|
+
});
|
|
24
|
+
const svmPayload = (0, payload_builders_1.encodeSvmExecutePayload)({
|
|
25
|
+
targetProgram: resolved.targetProgram,
|
|
26
|
+
accounts: resolved.accounts,
|
|
27
|
+
ixData: resolved.ixData,
|
|
28
|
+
instructionId: 2,
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
svmPayload,
|
|
32
|
+
targetBytes: resolved.targetProgram,
|
|
33
|
+
hasExecute: true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=build-payload.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.encodeAnchorIxData = encodeAnchorIxData;
|
|
4
|
+
exports.isAnchorIdl = isAnchorIdl;
|
|
5
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
6
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
7
|
+
const buffer_1 = require("buffer");
|
|
8
|
+
function encodeAnchorIxData(idl, functionName, positionalArgs = []) {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
const ix = findInstruction(idl, functionName);
|
|
11
|
+
if (!ix) {
|
|
12
|
+
throw new Error(`Instruction '${functionName}' not found in IDL '${(_b = (_a = idl.metadata) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'unknown'}'`);
|
|
13
|
+
}
|
|
14
|
+
if (positionalArgs.length !== ix.args.length) {
|
|
15
|
+
throw new Error(`Arg count mismatch for '${ix.name}': IDL expects ${ix.args.length}, got ${positionalArgs.length}`);
|
|
16
|
+
}
|
|
17
|
+
const named = {};
|
|
18
|
+
for (let i = 0; i < ix.args.length; i++) {
|
|
19
|
+
named[ix.args[i].name] = normalizeArg(positionalArgs[i], ix.args[i]);
|
|
20
|
+
}
|
|
21
|
+
const coder = new anchor_1.BorshInstructionCoder(idl);
|
|
22
|
+
return new Uint8Array(coder.encode(ix.name, named));
|
|
23
|
+
}
|
|
24
|
+
function findInstruction(idl, name) {
|
|
25
|
+
const snake = name.replace(/([A-Z])/g, (_, c) => '_' + c.toLowerCase());
|
|
26
|
+
const camel = name.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
27
|
+
return idl.instructions.find((i) => i.name === name || i.name === snake || i.name === camel);
|
|
28
|
+
}
|
|
29
|
+
function normalizeArg(value, field) {
|
|
30
|
+
if (typeof value === 'bigint') {
|
|
31
|
+
return new anchor_1.BN(value.toString());
|
|
32
|
+
}
|
|
33
|
+
if (field.type === 'pubkey' &&
|
|
34
|
+
typeof value === 'string' &&
|
|
35
|
+
value.startsWith('0x') &&
|
|
36
|
+
value.length === 66) {
|
|
37
|
+
return new web3_js_1.PublicKey(buffer_1.Buffer.from(value.slice(2), 'hex'));
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function isAnchorIdl(value) {
|
|
42
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
43
|
+
return false;
|
|
44
|
+
const maybe = value;
|
|
45
|
+
return Array.isArray(maybe['instructions']) && typeof maybe['address'] === 'string';
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ix-encoder.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Idl } from '@coral-xyz/anchor';
|
|
2
|
+
type AddressKey = `0x${string}`;
|
|
3
|
+
export declare function registerIdl(programAddress: string, idl: unknown): void;
|
|
4
|
+
export declare function getIdl(programAddress: string): Idl | undefined;
|
|
5
|
+
export declare function getRegisteredIdls(): Array<{
|
|
6
|
+
address: AddressKey;
|
|
7
|
+
idl: Idl;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function clearRegistry(): void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerIdl = registerIdl;
|
|
4
|
+
exports.getIdl = getIdl;
|
|
5
|
+
exports.getRegisteredIdls = getRegisteredIdls;
|
|
6
|
+
exports.clearRegistry = clearRegistry;
|
|
7
|
+
const ix_encoder_1 = require("./ix-encoder");
|
|
8
|
+
const store = new Map();
|
|
9
|
+
function normalizeKey(address) {
|
|
10
|
+
if (typeof address !== 'string' || !address.startsWith('0x')) {
|
|
11
|
+
throw new Error(`registerIdl: programAddress must be 0x-prefixed 32-byte hex, got '${address}'`);
|
|
12
|
+
}
|
|
13
|
+
const body = address.slice(2);
|
|
14
|
+
if (body.length !== 64 || !/^[0-9a-fA-F]+$/.test(body)) {
|
|
15
|
+
throw new Error(`registerIdl: programAddress must be 32 bytes (66 chars incl. 0x), got length ${address.length}`);
|
|
16
|
+
}
|
|
17
|
+
return ('0x' + body.toLowerCase());
|
|
18
|
+
}
|
|
19
|
+
function registerIdl(programAddress, idl) {
|
|
20
|
+
const key = normalizeKey(programAddress);
|
|
21
|
+
if (!(0, ix_encoder_1.isAnchorIdl)(idl)) {
|
|
22
|
+
throw new Error(`registerIdl: idl for ${programAddress} is not a recognized Anchor IDL (missing 'instructions' or 'address')`);
|
|
23
|
+
}
|
|
24
|
+
store.set(key, idl);
|
|
25
|
+
}
|
|
26
|
+
function getIdl(programAddress) {
|
|
27
|
+
const key = normalizeKey(programAddress);
|
|
28
|
+
return store.get(key);
|
|
29
|
+
}
|
|
30
|
+
function getRegisteredIdls() {
|
|
31
|
+
return Array.from(store.entries()).map(([address, idl]) => ({ address, idl }));
|
|
32
|
+
}
|
|
33
|
+
function clearRegistry() {
|
|
34
|
+
store.clear();
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CHAIN } from '../../constants/enums';
|
|
2
|
+
import type { SvmGatewayAccountMeta } from '../orchestrator.types';
|
|
3
|
+
export interface ResolveInput {
|
|
4
|
+
programAddress: `0x${string}`;
|
|
5
|
+
data: Uint8Array;
|
|
6
|
+
senderUea: `0x${string}`;
|
|
7
|
+
targetChain: CHAIN;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolvedSvmCall {
|
|
10
|
+
targetProgram: `0x${string}`;
|
|
11
|
+
accounts: SvmGatewayAccountMeta[];
|
|
12
|
+
ixData: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveSvmCall(input: ResolveInput): ResolvedSvmCall;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveSvmCall = resolveSvmCall;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const buffer_1 = require("buffer");
|
|
6
|
+
const account_1 = require("../../universal/account/account");
|
|
7
|
+
const registry_1 = require("./registry");
|
|
8
|
+
const CEA_AUTHORITY_NAMES = new Set([
|
|
9
|
+
'cea_authority',
|
|
10
|
+
'ceaAuthority',
|
|
11
|
+
'cea',
|
|
12
|
+
'cea_signer',
|
|
13
|
+
'ceaSigner',
|
|
14
|
+
]);
|
|
15
|
+
function resolveSvmCall(input) {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const idl = (0, registry_1.getIdl)(input.programAddress);
|
|
18
|
+
if (!idl) {
|
|
19
|
+
throw new Error(`resolveSvmCall: no IDL registered for ${input.programAddress}. ` +
|
|
20
|
+
`Call PushChain.utils.svm.registerIdl(${input.programAddress}, idl) first.`);
|
|
21
|
+
}
|
|
22
|
+
if (input.data.length < 8) {
|
|
23
|
+
throw new Error('resolveSvmCall: data must be at least 8 bytes (Anchor discriminator)');
|
|
24
|
+
}
|
|
25
|
+
const disc = input.data.slice(0, 8);
|
|
26
|
+
const ix = idl.instructions.find((i) => buffer_1.Buffer.from(i.discriminator).equals(buffer_1.Buffer.from(disc)));
|
|
27
|
+
if (!ix) {
|
|
28
|
+
throw new Error(`resolveSvmCall: no instruction in IDL '${(_b = (_a = idl.metadata) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : idl.address}' matches discriminator [${Array.from(disc).join(',')}]`);
|
|
29
|
+
}
|
|
30
|
+
const programPk = new web3_js_1.PublicKey(buffer_1.Buffer.from(input.programAddress.slice(2), 'hex'));
|
|
31
|
+
const { address: ceaPdaHex } = (0, account_1.deriveSvmCeaPda)(input.senderUea, input.targetChain, true);
|
|
32
|
+
const accounts = [];
|
|
33
|
+
for (const item of ix.accounts) {
|
|
34
|
+
if ('accounts' in item) {
|
|
35
|
+
throw new Error(`resolveSvmCall: nested account group '${item.name}' in '${ix.name}' not supported`);
|
|
36
|
+
}
|
|
37
|
+
const flat = item;
|
|
38
|
+
const pubkey = resolveAccountPubkey(flat, programPk, ceaPdaHex, ix.name);
|
|
39
|
+
accounts.push({ pubkey, isWritable: Boolean(flat.writable) });
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
targetProgram: input.programAddress,
|
|
43
|
+
accounts,
|
|
44
|
+
ixData: input.data,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function resolveAccountPubkey(spec, programPk, ceaPdaHex, ixName) {
|
|
48
|
+
if (spec.address) {
|
|
49
|
+
return pkToHex(new web3_js_1.PublicKey(spec.address));
|
|
50
|
+
}
|
|
51
|
+
if (spec.pda) {
|
|
52
|
+
const seeds = resolveConstSeeds(spec.pda.seeds, spec.name, ixName);
|
|
53
|
+
const programForPda = spec.pda.program
|
|
54
|
+
? new web3_js_1.PublicKey(resolveConstSeedValue(spec.pda.program, spec.name, ixName))
|
|
55
|
+
: programPk;
|
|
56
|
+
const [pda] = web3_js_1.PublicKey.findProgramAddressSync(seeds, programForPda);
|
|
57
|
+
return pkToHex(pda);
|
|
58
|
+
}
|
|
59
|
+
if (CEA_AUTHORITY_NAMES.has(spec.name)) {
|
|
60
|
+
return ceaPdaHex;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`resolveSvmCall: cannot resolve account '${spec.name}' in '${ixName}'. ` +
|
|
63
|
+
`Add 'address' or 'pda.seeds' to the IDL, or rename to a CEA convention (cea_authority).`);
|
|
64
|
+
}
|
|
65
|
+
function resolveConstSeeds(seeds, accountName, ixName) {
|
|
66
|
+
return seeds.map((seed, idx) => {
|
|
67
|
+
if (seed.kind !== 'const') {
|
|
68
|
+
throw new Error(`resolveSvmCall: non-const PDA seed (kind='${seed.kind}') on account '${accountName}' in '${ixName}' not supported yet`);
|
|
69
|
+
}
|
|
70
|
+
if (!Array.isArray(seed.value)) {
|
|
71
|
+
throw new Error(`resolveSvmCall: const seed at index ${idx} on '${accountName}' is malformed`);
|
|
72
|
+
}
|
|
73
|
+
return buffer_1.Buffer.from(seed.value);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function resolveConstSeedValue(seed, accountName, ixName) {
|
|
77
|
+
if (seed.kind !== 'const' || !Array.isArray(seed.value)) {
|
|
78
|
+
throw new Error(`resolveSvmCall: only const program-seed supported on '${accountName}' in '${ixName}'`);
|
|
79
|
+
}
|
|
80
|
+
return buffer_1.Buffer.from(seed.value);
|
|
81
|
+
}
|
|
82
|
+
function pkToHex(pk) {
|
|
83
|
+
return ('0x' + buffer_1.Buffer.from(pk.toBytes()).toString('hex'));
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -158,6 +158,25 @@ const RAW_HOOKS = {
|
|
|
158
158
|
response: null,
|
|
159
159
|
level: 'INFO',
|
|
160
160
|
}),
|
|
161
|
+
// External chain polling (08-x) — emitted from .wait() / cascade.waitForAll()
|
|
162
|
+
// after Push Chain tx success, while the SDK polls the relay for the
|
|
163
|
+
// external chain tx hash on outbound routes.
|
|
164
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01]: (destinationChain) => ({
|
|
165
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_01,
|
|
166
|
+
title: 'Awaiting External Chain',
|
|
167
|
+
message: destinationChain
|
|
168
|
+
? `Waiting for relay to dispatch to ${destinationChain}...`
|
|
169
|
+
: 'Waiting for relay to dispatch to external chain...',
|
|
170
|
+
response: null,
|
|
171
|
+
level: 'INFO',
|
|
172
|
+
}),
|
|
173
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02]: (elapsedMs) => ({
|
|
174
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_08_02,
|
|
175
|
+
title: 'Polling External Chain',
|
|
176
|
+
message: `Polling relay for external transaction hash (elapsed: ${Math.round(elapsedMs / 1000)}s)`,
|
|
177
|
+
response: null,
|
|
178
|
+
level: 'INFO',
|
|
179
|
+
}),
|
|
161
180
|
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01]: (txResponse) => ({
|
|
162
181
|
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01,
|
|
163
182
|
title: 'Push Chain Tx Success',
|
|
@@ -172,6 +191,27 @@ const RAW_HOOKS = {
|
|
|
172
191
|
response: null,
|
|
173
192
|
level: 'ERROR',
|
|
174
193
|
}),
|
|
194
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03]: (details) => ({
|
|
195
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_03,
|
|
196
|
+
title: 'External Chain Tx Confirmed',
|
|
197
|
+
message: `External tx confirmed on ${details.destinationChain}: ${details.externalTxHash}`,
|
|
198
|
+
response: details,
|
|
199
|
+
level: 'SUCCESS',
|
|
200
|
+
}),
|
|
201
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04]: (elapsedMs) => ({
|
|
202
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_04,
|
|
203
|
+
title: 'External Chain Tx Timeout',
|
|
204
|
+
message: `Timed out waiting for external chain tx after ${Math.round(elapsedMs / 1000)}s. Push Chain tx succeeded; the relay may still be processing.`,
|
|
205
|
+
response: null,
|
|
206
|
+
level: 'WARNING',
|
|
207
|
+
}),
|
|
208
|
+
[progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05]: (errorMessage) => ({
|
|
209
|
+
id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_05,
|
|
210
|
+
title: 'External Chain Tx Failed',
|
|
211
|
+
message: errorMessage,
|
|
212
|
+
response: null,
|
|
213
|
+
level: 'ERROR',
|
|
214
|
+
}),
|
|
175
215
|
// UEA Migration hooks
|
|
176
216
|
[progress_hook_types_1.PROGRESS_HOOK.UEA_MIG_01]: () => ({
|
|
177
217
|
id: progress_hook_types_1.PROGRESS_HOOK.UEA_MIG_01,
|
|
@@ -34,8 +34,13 @@ export declare enum PROGRESS_HOOK {
|
|
|
34
34
|
SEND_TX_06_05 = "SEND-TX-06-05",// Syncing with Push Chain
|
|
35
35
|
SEND_TX_06_06 = "SEND-TX-06-06",// Funds Credited on Push Chain (was 06_05)
|
|
36
36
|
SEND_TX_07 = "SEND-TX-07",// Broadcasting to Push Chain
|
|
37
|
+
SEND_TX_08_01 = "SEND-TX-08-01",// Awaiting External Chain
|
|
38
|
+
SEND_TX_08_02 = "SEND-TX-08-02",// Polling External Chain
|
|
37
39
|
SEND_TX_99_01 = "SEND-TX-99-01",
|
|
38
40
|
SEND_TX_99_02 = "SEND-TX-99-02",
|
|
41
|
+
SEND_TX_99_03 = "SEND-TX-99-03",// External Chain Tx Confirmed (SUCCESS)
|
|
42
|
+
SEND_TX_99_04 = "SEND-TX-99-04",// External Chain Tx Timeout (WARNING)
|
|
43
|
+
SEND_TX_99_05 = "SEND-TX-99-05",// External Chain Tx Failed (ERROR)
|
|
39
44
|
UEA_MIG_01 = "UEA-MIG-01",
|
|
40
45
|
UEA_MIG_02 = "UEA-MIG-02",
|
|
41
46
|
UEA_MIG_03 = "UEA-MIG-03",
|
|
@@ -28,9 +28,15 @@ var PROGRESS_HOOK;
|
|
|
28
28
|
PROGRESS_HOOK["SEND_TX_06_06"] = "SEND-TX-06-06";
|
|
29
29
|
// 07-x: Execution / broadcasting flow
|
|
30
30
|
PROGRESS_HOOK["SEND_TX_07"] = "SEND-TX-07";
|
|
31
|
+
// 08-x: External chain polling (after Push Chain tx success, outbound routes)
|
|
32
|
+
PROGRESS_HOOK["SEND_TX_08_01"] = "SEND-TX-08-01";
|
|
33
|
+
PROGRESS_HOOK["SEND_TX_08_02"] = "SEND-TX-08-02";
|
|
31
34
|
// 99-x: Final outcome
|
|
32
35
|
PROGRESS_HOOK["SEND_TX_99_01"] = "SEND-TX-99-01";
|
|
33
36
|
PROGRESS_HOOK["SEND_TX_99_02"] = "SEND-TX-99-02";
|
|
37
|
+
PROGRESS_HOOK["SEND_TX_99_03"] = "SEND-TX-99-03";
|
|
38
|
+
PROGRESS_HOOK["SEND_TX_99_04"] = "SEND-TX-99-04";
|
|
39
|
+
PROGRESS_HOOK["SEND_TX_99_05"] = "SEND-TX-99-05";
|
|
34
40
|
// UEA Migration hooks
|
|
35
41
|
PROGRESS_HOOK["UEA_MIG_01"] = "UEA-MIG-01";
|
|
36
42
|
PROGRESS_HOOK["UEA_MIG_02"] = "UEA-MIG-02";
|
|
@@ -396,15 +396,25 @@ class PushChain {
|
|
|
396
396
|
*/
|
|
397
397
|
validatedUniversalSigner, (_c = options === null || options === void 0 ? void 0 : options.network) !== null && _c !== void 0 ? _c : enums_1.PUSH_NETWORK.TESTNET_DONUT, (_d = options === null || options === void 0 ? void 0 : options.rpcUrls) !== null && _d !== void 0 ? _d : {}, (_e = options === null || options === void 0 ? void 0 : options.printTraces) !== null && _e !== void 0 ? _e : false, options === null || options === void 0 ? void 0 : options.progressHook);
|
|
398
398
|
const instance = new _a(orchestrator, validatedUniversalSigner, blockExplorers, isReadOnly);
|
|
399
|
-
// Background fetch account status (non-blocking, 30s timeout)
|
|
400
|
-
//
|
|
399
|
+
// Background fetch account status (non-blocking, 30s timeout).
|
|
400
|
+
// The timer must be cleared once the race settles — otherwise the
|
|
401
|
+
// unref'd setTimeout keeps the Node event loop alive for the full
|
|
402
|
+
// 30s after the caller's work is done, making scripts appear "stuck".
|
|
401
403
|
const ACCOUNT_STATUS_TIMEOUT = 30000;
|
|
404
|
+
let accountStatusTimer;
|
|
402
405
|
instance.accountStatusReady = Promise.race([
|
|
403
406
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
404
407
|
instance.getAccountStatus().then(() => { }),
|
|
405
|
-
new Promise((_, reject) =>
|
|
406
|
-
|
|
408
|
+
new Promise((_, reject) => {
|
|
409
|
+
accountStatusTimer = setTimeout(() => reject(new Error('Account status fetch timed out')), ACCOUNT_STATUS_TIMEOUT);
|
|
410
|
+
}),
|
|
411
|
+
])
|
|
412
|
+
.catch(() => {
|
|
407
413
|
// Silently ignore — lazy check in execute() will retry if needed
|
|
414
|
+
})
|
|
415
|
+
.finally(() => {
|
|
416
|
+
if (accountStatusTimer)
|
|
417
|
+
clearTimeout(accountStatusTimer);
|
|
408
418
|
});
|
|
409
419
|
// Let execute() await the background fetch instead of re-fetching
|
|
410
420
|
orchestrator.accountStatusReadyPromise = instance.accountStatusReady;
|
|
@@ -68,6 +68,19 @@ export declare function convertExecutorToOrigin(executorAddress: string, options
|
|
|
68
68
|
/** @internal Skip deprecation warning for SDK-internal calls */
|
|
69
69
|
_internal?: boolean;
|
|
70
70
|
}): Promise<OriginAccountInfo>;
|
|
71
|
+
/**
|
|
72
|
+
* Derive the SVM CEA (PDA) for a UEA address on a Solana-based chain.
|
|
73
|
+
*
|
|
74
|
+
* Solana doesn't use a CEAFactory contract — instead, the CEA is a
|
|
75
|
+
* Program Derived Address (PDA) with seeds: ["push_identity", ueaBytes]
|
|
76
|
+
* and the SVM gateway program as the program ID.
|
|
77
|
+
*
|
|
78
|
+
* @param ueaAddress - The UEA (or Push EOA) hex address (20 bytes).
|
|
79
|
+
* @param targetChain - The SVM target chain.
|
|
80
|
+
* @param skipNetworkCheck - Whether to skip deployment status check.
|
|
81
|
+
* @returns The derived 32-byte Solana PDA address (as 0x-prefixed hex) and deployment status.
|
|
82
|
+
*/
|
|
83
|
+
export declare function deriveSvmCeaPda(ueaAddress: `0x${string}`, targetChain: CHAIN, skipNetworkCheck: boolean): DerivedExecutorAccount;
|
|
71
84
|
/**
|
|
72
85
|
* Derive the executor account (UEA or CEA) for a given account.
|
|
73
86
|
*
|