@pushchain/core 6.0.25 → 6.0.27-alpha.0
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/AGW.md +194 -0
- package/CHANGELOG.md +74 -0
- package/README.md +2 -0
- package/package.json +7 -1
- package/src/lib/agentic/agentic.d.ts +23 -0
- package/src/lib/agentic/agentic.js +51 -0
- package/src/lib/agentic/agentic.types.d.ts +409 -0
- package/src/lib/agentic/agentic.types.js +3 -0
- package/src/lib/agentic/capabilities.d.ts +37 -0
- package/src/lib/agentic/capabilities.js +64 -0
- package/src/lib/agentic/chain.d.ts +3 -0
- package/src/lib/agentic/chain.js +15 -0
- package/src/lib/agentic/codec/abi-layout.d.ts +15 -0
- package/src/lib/agentic/codec/abi-layout.js +121 -0
- package/src/lib/agentic/codec/defaults.d.ts +51 -0
- package/src/lib/agentic/codec/defaults.js +53 -0
- package/src/lib/agentic/codec/ids.d.ts +35 -0
- package/src/lib/agentic/codec/ids.js +74 -0
- package/src/lib/agentic/codec/native.d.ts +75 -0
- package/src/lib/agentic/codec/native.js +328 -0
- package/src/lib/agentic/codec/rules.d.ts +45 -0
- package/src/lib/agentic/codec/rules.js +110 -0
- package/src/lib/agentic/codec/selectors.d.ts +19 -0
- package/src/lib/agentic/codec/selectors.js +60 -0
- package/src/lib/agentic/codec/session.d.ts +54 -0
- package/src/lib/agentic/codec/session.js +65 -0
- package/src/lib/agentic/codec/svm-accounts.d.ts +35 -0
- package/src/lib/agentic/codec/svm-accounts.js +68 -0
- package/src/lib/agentic/codec/svm-idl.d.ts +11 -0
- package/src/lib/agentic/codec/svm-idl.js +226 -0
- package/src/lib/agentic/codec/svm-terms.d.ts +157 -0
- package/src/lib/agentic/codec/svm-terms.js +242 -0
- package/src/lib/agentic/codec/universal-terms.d.ts +67 -0
- package/src/lib/agentic/codec/universal-terms.js +41 -0
- package/src/lib/agentic/codec/universal.d.ts +14 -0
- package/src/lib/agentic/codec/universal.js +157 -0
- package/src/lib/agentic/constants.d.ts +11 -0
- package/src/lib/agentic/constants.js +15 -0
- package/src/lib/agentic/context.d.ts +29 -0
- package/src/lib/agentic/context.js +56 -0
- package/src/lib/agentic/contracts/abi/v5/agent-validator.d.ts +105 -0
- package/src/lib/agentic/contracts/abi/v5/agent-validator.js +149 -0
- package/src/lib/agentic/contracts/abi/v5/agw-factory.d.ts +847 -0
- package/src/lib/agentic/contracts/abi/v5/agw-factory.js +1108 -0
- package/src/lib/agentic/contracts/abi/v5/agw.d.ts +1211 -0
- package/src/lib/agentic/contracts/abi/v5/agw.js +1588 -0
- package/src/lib/agentic/contracts/abi/v5/index.d.ts +6 -0
- package/src/lib/agentic/contracts/abi/v5/index.js +17 -0
- package/src/lib/agentic/contracts/abi/v5/smart-session.d.ts +1493 -0
- package/src/lib/agentic/contracts/abi/v5/smart-session.js +1965 -0
- package/src/lib/agentic/contracts/abi/v5/universal-rules-policy.d.ts +1640 -0
- package/src/lib/agentic/contracts/abi/v5/universal-rules-policy.js +2160 -0
- package/src/lib/agentic/contracts/donut-v5.d.ts +11 -0
- package/src/lib/agentic/contracts/donut-v5.js +15 -0
- package/src/lib/agentic/contracts/prc20-metadata.d.ts +26 -0
- package/src/lib/agentic/contracts/prc20-metadata.js +87 -0
- package/src/lib/agentic/contracts/reader.d.ts +35 -0
- package/src/lib/agentic/contracts/reader.js +16 -0
- package/src/lib/agentic/contracts/v5.d.ts +5323 -0
- package/src/lib/agentic/contracts/v5.js +316 -0
- package/src/lib/agentic/deployments.d.ts +61 -0
- package/src/lib/agentic/deployments.js +203 -0
- package/src/lib/agentic/errors.d.ts +71 -0
- package/src/lib/agentic/errors.js +92 -0
- package/src/lib/agentic/execution/guards.d.ts +9 -0
- package/src/lib/agentic/execution/guards.js +30 -0
- package/src/lib/agentic/execution/outbound.d.ts +55 -0
- package/src/lib/agentic/execution/outbound.js +187 -0
- package/src/lib/agentic/execution/send.d.ts +9 -0
- package/src/lib/agentic/execution/send.js +276 -0
- package/src/lib/agentic/execution/svm-instruction.d.ts +24 -0
- package/src/lib/agentic/execution/svm-instruction.js +40 -0
- package/src/lib/agentic/execution/svm-outbound.d.ts +18 -0
- package/src/lib/agentic/execution/svm-outbound.js +86 -0
- package/src/lib/agentic/execution/svm-payload.d.ts +18 -0
- package/src/lib/agentic/execution/svm-payload.js +136 -0
- package/src/lib/agentic/execution/svm-public.d.ts +5 -0
- package/src/lib/agentic/execution/svm-public.js +182 -0
- package/src/lib/agentic/execution/svm-quote.d.ts +11 -0
- package/src/lib/agentic/execution/svm-quote.js +24 -0
- package/src/lib/agentic/execution/svm-send.d.ts +44 -0
- package/src/lib/agentic/execution/svm-send.js +90 -0
- package/src/lib/agentic/index.d.ts +5 -0
- package/src/lib/agentic/index.js +10 -0
- package/src/lib/agentic/management/common.d.ts +29 -0
- package/src/lib/agentic/management/common.js +114 -0
- package/src/lib/agentic/management/create.d.ts +16 -0
- package/src/lib/agentic/management/create.js +271 -0
- package/src/lib/agentic/management/duplicates.d.ts +4 -0
- package/src/lib/agentic/management/duplicates.js +20 -0
- package/src/lib/agentic/management/label.d.ts +3 -0
- package/src/lib/agentic/management/label.js +17 -0
- package/src/lib/agentic/management/prepare.d.ts +7 -0
- package/src/lib/agentic/management/prepare.js +95 -0
- package/src/lib/agentic/management/rules-write.d.ts +42 -0
- package/src/lib/agentic/management/rules-write.js +279 -0
- package/src/lib/agentic/management/svm-context.d.ts +25 -0
- package/src/lib/agentic/management/svm-context.js +55 -0
- package/src/lib/agentic/management/svm-metadata.d.ts +10 -0
- package/src/lib/agentic/management/svm-metadata.js +56 -0
- package/src/lib/agentic/management/svm-public.d.ts +6 -0
- package/src/lib/agentic/management/svm-public.js +125 -0
- package/src/lib/agentic/management/svm.d.ts +27 -0
- package/src/lib/agentic/management/svm.js +150 -0
- package/src/lib/agentic/presets/catalog.d.ts +21 -0
- package/src/lib/agentic/presets/catalog.js +10 -0
- package/src/lib/agentic/presets/index.d.ts +5 -0
- package/src/lib/agentic/presets/index.js +190 -0
- package/src/lib/agentic/presets/types.d.ts +44 -0
- package/src/lib/agentic/presets/types.js +3 -0
- package/src/lib/agentic/public-rule.d.ts +9 -0
- package/src/lib/agentic/public-rule.js +342 -0
- package/src/lib/agentic/reads/checkpoints.d.ts +17 -0
- package/src/lib/agentic/reads/checkpoints.js +109 -0
- package/src/lib/agentic/reads/rules.d.ts +42 -0
- package/src/lib/agentic/reads/rules.js +286 -0
- package/src/lib/agentic/reads/snapshot.d.ts +28 -0
- package/src/lib/agentic/reads/snapshot.js +85 -0
- package/src/lib/agentic/reads/svm.d.ts +17 -0
- package/src/lib/agentic/reads/svm.js +52 -0
- package/src/lib/agentic/reads/wallets.d.ts +25 -0
- package/src/lib/agentic/reads/wallets.js +122 -0
- package/src/lib/agentic/response.d.ts +41 -0
- package/src/lib/agentic/response.js +358 -0
- package/src/lib/agentic/revert.d.ts +7 -0
- package/src/lib/agentic/revert.js +102 -0
- package/src/lib/agentic/runtime.d.ts +58 -0
- package/src/lib/agentic/runtime.js +95 -0
- package/src/lib/agentic/utils.d.ts +57 -0
- package/src/lib/agentic/utils.js +165 -0
- package/src/lib/agentic/wallet.d.ts +32 -0
- package/src/lib/agentic/wallet.js +130 -0
- package/src/lib/constants/chain.js +1 -1
- package/src/lib/constants/enums.d.ts +6 -3
- package/src/lib/constants/enums.js +6 -3
- package/src/lib/constants/index.d.ts +65 -7
- package/src/lib/constants/index.js +18 -3
- package/src/lib/constants/read-state.d.ts +15 -2
- package/src/lib/constants/read-state.js +19 -3
- package/src/lib/index.d.ts +9 -3
- package/src/lib/index.js +11 -2
- package/src/lib/orchestrator/internals/errors.d.ts +7 -0
- package/src/lib/orchestrator/internals/errors.js +13 -1
- package/src/lib/orchestrator/internals/execute-standard.d.ts +3 -1
- package/src/lib/orchestrator/internals/execute-standard.js +3 -3
- package/src/lib/orchestrator/internals/outbound-sync.js +52 -7
- package/src/lib/orchestrator/internals/push-chain-tx.d.ts +1 -1
- package/src/lib/orchestrator/internals/push-chain-tx.js +13 -1
- package/src/lib/orchestrator/orchestrator.d.ts +3 -0
- package/src/lib/orchestrator/orchestrator.js +13 -1
- package/src/lib/orchestrator/orchestrator.types.d.ts +8 -0
- package/src/lib/orchestrator/route-detector.js +3 -2
- package/src/lib/orchestrator/svm-idl/resolve.d.ts +2 -0
- package/src/lib/orchestrator/svm-idl/resolve.js +11 -1
- package/src/lib/progress-hook/progress-hook.js +84 -0
- package/src/lib/progress-hook/progress-hook.types.d.ts +14 -2
- package/src/lib/progress-hook/progress-hook.types.js +13 -0
- package/src/lib/push-chain/push-chain.d.ts +58 -16
- package/src/lib/push-chain/push-chain.js +68 -8
- package/src/lib/push-client/push-client.d.ts +7 -0
- package/src/lib/push-client/push-client.js +41 -15
- package/src/lib/read-state/destination.js +6 -1
- package/src/lib/read-state/envelopes/evm.js +2 -3
- package/src/lib/read-state/envelopes/svm.js +11 -1
- package/src/lib/read-state/read-executor.js +4 -0
- package/src/lib/read-state/read-params.d.ts +71 -26
- package/src/lib/read-state/read-params.js +60 -15
- package/src/lib/read-state/read-state.types.d.ts +44 -1
- package/src/lib/read-state/read-state.types.js +23 -1
- package/src/lib/read-state/read-tracker.d.ts +6 -1
- package/src/lib/read-state/read-tracker.js +83 -17
- package/src/lib/read-state/registry.js +2 -3
- package/src/lib/read-state/result-decoder.js +6 -0
- package/src/lib/read-state/spec-builder.js +2 -2
- package/src/lib/read-state/svm-account.d.ts +20 -0
- package/src/lib/read-state/svm-account.js +114 -0
- package/src/lib/read-state/svm-pda.d.ts +13 -0
- package/src/lib/read-state/svm-pda.js +147 -0
- package/src/lib/universal/prc20-address.d.ts +15 -0
- package/src/lib/universal/prc20-address.js +135 -0
- package/src/lib/utils.d.ts +6 -13
- package/src/lib/utils.js +5 -128
- package/src/lib/vm-client/evm-client.js +34 -20
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgenticRevertError = exports.AgenticError = exports.AGENTIC_ERROR_CODE = void 0;
|
|
4
|
+
exports.capabilityUnavailable = capabilityUnavailable;
|
|
5
|
+
const errors_1 = require("../orchestrator/internals/errors");
|
|
6
|
+
/**
|
|
7
|
+
* Stable AGW error codes. The first groups are specified by the AGW SDK page
|
|
8
|
+
* (section 3.f); the remainder are SDK-owned codes that keep unsupported or
|
|
9
|
+
* unverified capabilities from being mistaken for success.
|
|
10
|
+
*/
|
|
11
|
+
exports.AGENTIC_ERROR_CODE = {
|
|
12
|
+
// create / rule validation (spec 3.f)
|
|
13
|
+
DUPLICATE_RULE: 'DUPLICATE_RULE',
|
|
14
|
+
AGENT_IS_OWNER: 'AGENT_IS_OWNER',
|
|
15
|
+
AMBIGUOUS_RULE: 'AMBIGUOUS_RULE',
|
|
16
|
+
TARGET_NOT_ON_RULE_CHAIN: 'TARGET_NOT_ON_RULE_CHAIN',
|
|
17
|
+
ASSET_CHAIN_MISMATCH: 'ASSET_CHAIN_MISMATCH',
|
|
18
|
+
// initialize with agenticWallet (spec 3.f)
|
|
19
|
+
NOT_OWNER_OR_AGENT: 'NOT_OWNER_OR_AGENT',
|
|
20
|
+
WALLET_NOT_DEPLOYED: 'WALLET_NOT_DEPLOYED',
|
|
21
|
+
NOT_AGENTIC_WALLET: 'NOT_AGENTIC_WALLET',
|
|
22
|
+
// rules.delete (spec 3.f)
|
|
23
|
+
DELETE_NEEDS_TARGET: 'DELETE_NEEDS_TARGET',
|
|
24
|
+
// sendTransaction (spec 3.f)
|
|
25
|
+
NO_RULES_FOR_CHAIN: 'NO_RULES_FOR_CHAIN',
|
|
26
|
+
FROM_NOT_ALLOWED: 'FROM_NOT_ALLOWED',
|
|
27
|
+
NOT_ALLOWED_IN_AGENTIC_MODE: 'NOT_ALLOWED_IN_AGENTIC_MODE',
|
|
28
|
+
// SDK-owned
|
|
29
|
+
INVALID_RULE: 'INVALID_RULE',
|
|
30
|
+
CAPABILITY_UNAVAILABLE: 'CAPABILITY_UNAVAILABLE',
|
|
31
|
+
READ_ONLY: 'READ_ONLY',
|
|
32
|
+
NOT_WALLET_OWNER: 'NOT_WALLET_OWNER',
|
|
33
|
+
RULE_NOT_FOUND: 'RULE_NOT_FOUND',
|
|
34
|
+
RULE_READ_FAILED: 'RULE_READ_FAILED',
|
|
35
|
+
INCONSISTENT_READ: 'INCONSISTENT_READ',
|
|
36
|
+
INDEX_RACE: 'INDEX_RACE',
|
|
37
|
+
CREATE_PARTIAL: 'CREATE_PARTIAL',
|
|
38
|
+
RECEIPT_MISMATCH: 'RECEIPT_MISMATCH',
|
|
39
|
+
RECEIPT_UNAVAILABLE: 'RECEIPT_UNAVAILABLE',
|
|
40
|
+
AGENT_GAS_INSUFFICIENT: 'AGENT_GAS_INSUFFICIENT',
|
|
41
|
+
WALLET_BALANCE_INSUFFICIENT: 'WALLET_BALANCE_INSUFFICIENT',
|
|
42
|
+
GATEWAY_ALLOWANCE_INSUFFICIENT: 'GATEWAY_ALLOWANCE_INSUFFICIENT',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Pre-signature AGW failure: invalid input, unsupported capability, failed
|
|
46
|
+
* eligibility or a read that cannot be trusted. Nothing was signed or sent
|
|
47
|
+
* unless `details` explicitly records committed hashes (CREATE_PARTIAL).
|
|
48
|
+
*/
|
|
49
|
+
class AgenticError extends Error {
|
|
50
|
+
code;
|
|
51
|
+
hint;
|
|
52
|
+
details;
|
|
53
|
+
cause;
|
|
54
|
+
constructor(code, message, opts = {}) {
|
|
55
|
+
super(message);
|
|
56
|
+
this.name = 'AgenticError';
|
|
57
|
+
this.code = code;
|
|
58
|
+
this.hint = opts.hint;
|
|
59
|
+
this.details = opts.details;
|
|
60
|
+
this.cause = opts.cause;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.AgenticError = AgenticError;
|
|
64
|
+
/**
|
|
65
|
+
* On-chain AGW, URP, factory or engine revert surfaced from an agentic send.
|
|
66
|
+
* Extends core's structured execution error so `instanceof
|
|
67
|
+
* PushChainExecutionError` keeps working, and keeps the underlying cause plus
|
|
68
|
+
* any batch recovery hashes.
|
|
69
|
+
*/
|
|
70
|
+
class AgenticRevertError extends errors_1.PushChainExecutionError {
|
|
71
|
+
agenticCode;
|
|
72
|
+
transactionHashes;
|
|
73
|
+
pendingTransactionHash;
|
|
74
|
+
constructor(message, opts = {}) {
|
|
75
|
+
super(message, {
|
|
76
|
+
decodedError: opts.decodedError,
|
|
77
|
+
gatewayTxHash: opts.gatewayTxHash,
|
|
78
|
+
cause: opts.cause,
|
|
79
|
+
});
|
|
80
|
+
this.name = 'AgenticRevertError';
|
|
81
|
+
this.agenticCode = opts.agenticCode;
|
|
82
|
+
this.transactionHashes = opts.transactionHashes
|
|
83
|
+
? [...opts.transactionHashes]
|
|
84
|
+
: undefined;
|
|
85
|
+
this.pendingTransactionHash = opts.pendingTransactionHash;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.AgenticRevertError = AgenticRevertError;
|
|
89
|
+
function capabilityUnavailable(capability, dependency, hint) {
|
|
90
|
+
return new AgenticError(exports.AGENTIC_ERROR_CODE.CAPABILITY_UNAVAILABLE, `AGW capability "${capability}" is not available: ${dependency}`, { hint, details: { capability, dependency } });
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AgenticError } from '../errors';
|
|
2
|
+
/** Methods the spec forbids on an agentic client (spec 2.a). */
|
|
3
|
+
export type ForbiddenAgenticMethod = 'prepareTransaction' | 'executeTransactions' | 'migrateCEA' | 'rescueFunds' | 'payGasWith';
|
|
4
|
+
export declare function notAllowedInAgenticMode(method: ForbiddenAgenticMethod | string): AgenticError;
|
|
5
|
+
/**
|
|
6
|
+
* Reject inputs that would execute from somewhere other than the wallet, or
|
|
7
|
+
* that agentic mode does not support, before any signature or RPC call.
|
|
8
|
+
*/
|
|
9
|
+
export declare function guardAgenticSendParams(params: unknown): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.notAllowedInAgenticMode = notAllowedInAgenticMode;
|
|
4
|
+
exports.guardAgenticSendParams = guardAgenticSendParams;
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
function notAllowedInAgenticMode(method) {
|
|
7
|
+
return new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.NOT_ALLOWED_IN_AGENTIC_MODE, `${method} is not available on a client initialized with agenticWallet`, {
|
|
8
|
+
hint: method === 'prepareTransaction' || method === 'executeTransactions'
|
|
9
|
+
? 'Use sendTransaction; cascades would run from the signer, not the wallet.'
|
|
10
|
+
: 'Use a client initialized without agenticWallet for signer-level operations.',
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reject inputs that would execute from somewhere other than the wallet, or
|
|
15
|
+
* that agentic mode does not support, before any signature or RPC call.
|
|
16
|
+
*/
|
|
17
|
+
function guardAgenticSendParams(params) {
|
|
18
|
+
if (!params || typeof params !== 'object') {
|
|
19
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'sendTransaction needs a transaction object');
|
|
20
|
+
}
|
|
21
|
+
const p = params;
|
|
22
|
+
if (p.from !== undefined && p.from !== null) {
|
|
23
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.FROM_NOT_ALLOWED, '`from` (Routes 3 and 4) is not allowed in agenticWallet mode', { hint: 'A CEA-originated call makes msg.sender a CEA, so the wallet door check would fail.' });
|
|
24
|
+
}
|
|
25
|
+
if (p.payGasWith !== undefined)
|
|
26
|
+
throw notAllowedInAgenticMode('payGasWith');
|
|
27
|
+
if (p.migration)
|
|
28
|
+
throw notAllowedInAgenticMode('migrateCEA');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Address, type Hex } from 'viem';
|
|
2
|
+
import { CHAIN } from '../../constants/enums';
|
|
3
|
+
import type { MoveableToken } from '../../constants/tokens';
|
|
4
|
+
import type { UniversalExecuteParams, UniversalOutboundTxRequest } from '../../orchestrator/orchestrator.types';
|
|
5
|
+
import type { AgenticGeneration } from '../deployments';
|
|
6
|
+
import type { Call } from '../contracts/v5';
|
|
7
|
+
import type { AgenticRuntime } from '../runtime';
|
|
8
|
+
/** URP MAX_ACTIONS_PER_REQUEST at v5. */
|
|
9
|
+
export declare const MAX_DESTINATION_CALLS = 10;
|
|
10
|
+
export interface DestinationCall {
|
|
11
|
+
to: Address;
|
|
12
|
+
value: bigint;
|
|
13
|
+
data: Hex;
|
|
14
|
+
}
|
|
15
|
+
export interface ComposedOutbound {
|
|
16
|
+
chain: CHAIN;
|
|
17
|
+
destinationAccount: Address;
|
|
18
|
+
destinationAccountDeployed: boolean;
|
|
19
|
+
token: Address;
|
|
20
|
+
amount: bigint;
|
|
21
|
+
/** PC the wallet attaches: protocolFee + maxPCForGas. */
|
|
22
|
+
value: bigint;
|
|
23
|
+
request: UniversalOutboundTxRequest;
|
|
24
|
+
/** The wallet's call into the gateway. */
|
|
25
|
+
gatewayCall: Call;
|
|
26
|
+
destinationCalls: DestinationCall[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The calls the wallet's destination account (CEA) executes, built exactly as
|
|
30
|
+
* core's Route 2 builds them for an ordinary account (buildR2CeaPayloadEvm):
|
|
31
|
+
* - explicit call arrays are used as given (the caller handles transfers);
|
|
32
|
+
* - with ERC-20 funds, a transfer(target, amount) is prepended to a single
|
|
33
|
+
* call, or is the whole payload for a transfer-only send;
|
|
34
|
+
* - native value (and native funds) goes to the target with the call, or as
|
|
35
|
+
* a value-only call; a value transfer to the CEA itself is skipped.
|
|
36
|
+
* Every encoded call names the requested target, so a response never reports
|
|
37
|
+
* a delivery the request does not instruct.
|
|
38
|
+
*/
|
|
39
|
+
export declare function destinationCalls(params: UniversalExecuteParams, ctx: {
|
|
40
|
+
cea: Address;
|
|
41
|
+
fundsToken?: MoveableToken;
|
|
42
|
+
}): DestinationCall[];
|
|
43
|
+
/**
|
|
44
|
+
* Compose the AGW-originated EVM outbound (Route 2 shape, wallet context):
|
|
45
|
+
* - recipient = empty bytes, revertRecipient = the AGW, maxPCForGas > 0
|
|
46
|
+
* - payload = UEA_MULTICALL ‖ abi.encode(Multicall[1..10]) executed by the AGW's CEA
|
|
47
|
+
* - value = protocolFee + maxPCForGas, paid from the AGW's PC
|
|
48
|
+
* The destination account is resolved from the AGW, never from the signer.
|
|
49
|
+
* The SDK never writes a gateway allowance on either door: the gateway pulls
|
|
50
|
+
* from an allowance the owner set separately with an ordinary send.
|
|
51
|
+
*/
|
|
52
|
+
export declare function composeOutbound(runtime: AgenticRuntime, gen: AgenticGeneration, wallet: Address, params: UniversalExecuteParams, opts: {
|
|
53
|
+
ruleAssets?: readonly Address[];
|
|
54
|
+
door: 'owner' | 'agent';
|
|
55
|
+
}): Promise<ComposedOutbound>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_DESTINATION_CALLS = void 0;
|
|
4
|
+
exports.destinationCalls = destinationCalls;
|
|
5
|
+
exports.composeOutbound = composeOutbound;
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const enums_1 = require("../../constants/enums");
|
|
8
|
+
const chain_1 = require("../../constants/chain");
|
|
9
|
+
const abi_1 = require("../../constants/abi");
|
|
10
|
+
const orchestrator_types_1 = require("../../orchestrator/orchestrator.types");
|
|
11
|
+
const route_handlers_1 = require("../../orchestrator/internals/route-handlers");
|
|
12
|
+
const capabilities_1 = require("../capabilities");
|
|
13
|
+
const v5_1 = require("../contracts/v5");
|
|
14
|
+
const errors_1 = require("../errors");
|
|
15
|
+
/** Includes first-use CEA deployment; explicit caller gas always takes precedence. */
|
|
16
|
+
const FIRST_USE_EVM_GAS_LIMIT = BigInt(2_000_000);
|
|
17
|
+
/** URP MAX_ACTIONS_PER_REQUEST at v5. */
|
|
18
|
+
exports.MAX_DESTINATION_CALLS = 10;
|
|
19
|
+
const MULTICALL_TUPLE = [
|
|
20
|
+
{
|
|
21
|
+
type: 'tuple[]',
|
|
22
|
+
components: [
|
|
23
|
+
{ name: 'to', type: 'address' },
|
|
24
|
+
{ name: 'value', type: 'uint256' },
|
|
25
|
+
{ name: 'data', type: 'bytes' },
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* The calls the wallet's destination account (CEA) executes, built exactly as
|
|
31
|
+
* core's Route 2 builds them for an ordinary account (buildR2CeaPayloadEvm):
|
|
32
|
+
* - explicit call arrays are used as given (the caller handles transfers);
|
|
33
|
+
* - with ERC-20 funds, a transfer(target, amount) is prepended to a single
|
|
34
|
+
* call, or is the whole payload for a transfer-only send;
|
|
35
|
+
* - native value (and native funds) goes to the target with the call, or as
|
|
36
|
+
* a value-only call; a value transfer to the CEA itself is skipped.
|
|
37
|
+
* Every encoded call names the requested target, so a response never reports
|
|
38
|
+
* a delivery the request does not instruct.
|
|
39
|
+
*/
|
|
40
|
+
function destinationCalls(params, ctx) {
|
|
41
|
+
const target = (0, viem_1.getAddress)(params.to.address);
|
|
42
|
+
if (Array.isArray(params.data)) {
|
|
43
|
+
return params.data.map((c) => ({
|
|
44
|
+
to: (0, viem_1.getAddress)(c.to),
|
|
45
|
+
value: c.value ?? BigInt(0),
|
|
46
|
+
data: c.data,
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
const amount = params.funds?.amount ?? BigInt(0);
|
|
50
|
+
const token = ctx.fundsToken;
|
|
51
|
+
const erc20 = amount > BigInt(0) && token && token.mechanism !== 'native';
|
|
52
|
+
const nativeFunds = amount > BigInt(0) && token?.mechanism === 'native' ? amount : BigInt(0);
|
|
53
|
+
const value = params.value ?? BigInt(0);
|
|
54
|
+
const calls = [];
|
|
55
|
+
if (erc20) {
|
|
56
|
+
calls.push({
|
|
57
|
+
to: (0, viem_1.getAddress)(token.address),
|
|
58
|
+
value: BigInt(0),
|
|
59
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
60
|
+
abi: abi_1.ERC20_EVM,
|
|
61
|
+
functionName: 'transfer',
|
|
62
|
+
args: [target, amount],
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const data = params.data && params.data !== '0x' ? params.data : undefined;
|
|
67
|
+
if (data) {
|
|
68
|
+
calls.push({ to: target, value: value + nativeFunds, data });
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
const forward = value > BigInt(0) ? value : nativeFunds;
|
|
72
|
+
if (forward > BigInt(0) && target !== ctx.cea) {
|
|
73
|
+
calls.push({ to: target, value: forward, data: '0x' });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return calls;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Compose the AGW-originated EVM outbound (Route 2 shape, wallet context):
|
|
80
|
+
* - recipient = empty bytes, revertRecipient = the AGW, maxPCForGas > 0
|
|
81
|
+
* - payload = UEA_MULTICALL ‖ abi.encode(Multicall[1..10]) executed by the AGW's CEA
|
|
82
|
+
* - value = protocolFee + maxPCForGas, paid from the AGW's PC
|
|
83
|
+
* The destination account is resolved from the AGW, never from the signer.
|
|
84
|
+
* The SDK never writes a gateway allowance on either door: the gateway pulls
|
|
85
|
+
* from an allowance the owner set separately with an ordinary send.
|
|
86
|
+
*/
|
|
87
|
+
async function composeOutbound(runtime, gen, wallet, params, opts) {
|
|
88
|
+
(0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.UNIVERSAL_EVM_OUTBOUND);
|
|
89
|
+
const target = params.to;
|
|
90
|
+
const chain = target.chain;
|
|
91
|
+
const info = chain_1.CHAIN_INFO[chain];
|
|
92
|
+
if (!info) {
|
|
93
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, `unknown destination chain ${String(chain)}`);
|
|
94
|
+
}
|
|
95
|
+
if (info.vm !== enums_1.VM.EVM) {
|
|
96
|
+
throw (0, errors_1.capabilityUnavailable)(capabilities_1.AgenticCapability.UNIVERSAL_SVM_RULES, 'This composer accepts EVM destinations; use the Solana instruction route');
|
|
97
|
+
}
|
|
98
|
+
const funds = params.funds;
|
|
99
|
+
if (funds && (0, orchestrator_types_1.isPC20Reference)(funds.token)) {
|
|
100
|
+
throw (0, errors_1.capabilityUnavailable)('pc20Outbound', 'PC20 tokens are not supported through an agentic wallet');
|
|
101
|
+
}
|
|
102
|
+
// An omitted funds.token means the destination chain's native token, as in Route 2.
|
|
103
|
+
const fundsToken = funds?.amount
|
|
104
|
+
? funds.token
|
|
105
|
+
? (0, route_handlers_1.resolveR2DestinationFundsToken)(funds.token, chain, runtime.network)
|
|
106
|
+
: {
|
|
107
|
+
symbol: 'native',
|
|
108
|
+
decimals: 18,
|
|
109
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
110
|
+
mechanism: 'native',
|
|
111
|
+
}
|
|
112
|
+
: undefined;
|
|
113
|
+
// Burn token and amount, as Route 2 sizes them for an ordinary account.
|
|
114
|
+
let token;
|
|
115
|
+
let amount = BigInt(0);
|
|
116
|
+
if (funds) {
|
|
117
|
+
token = runtime.resolvePrc20(funds.token, chain);
|
|
118
|
+
amount = funds.amount;
|
|
119
|
+
}
|
|
120
|
+
else if ((params.value ?? BigInt(0)) > BigInt(0)) {
|
|
121
|
+
token = runtime.resolvePrc20(undefined, chain);
|
|
122
|
+
amount = params.value;
|
|
123
|
+
}
|
|
124
|
+
else if (opts.ruleAssets?.length) {
|
|
125
|
+
token = (0, viem_1.getAddress)(opts.ruleAssets[0]);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
token = runtime.resolvePrc20(undefined, chain);
|
|
129
|
+
}
|
|
130
|
+
const resolved = await runtime.resolveCEA(wallet, chain);
|
|
131
|
+
const cea = (0, viem_1.getAddress)(resolved.cea);
|
|
132
|
+
const calls = destinationCalls(params, { cea, fundsToken });
|
|
133
|
+
if (calls.length === 0) {
|
|
134
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'this outbound carries no destination call; parking funds in the wallet’s destination account is not supported', {
|
|
135
|
+
hint: 'Name a recipient other than the wallet’s own destination account, or add calldata.',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (calls.length > exports.MAX_DESTINATION_CALLS) {
|
|
139
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, `at most ${exports.MAX_DESTINATION_CALLS} destination calls per outbound`);
|
|
140
|
+
}
|
|
141
|
+
if (opts.door === 'agent') {
|
|
142
|
+
const bare = calls.findIndex((c) => (c.data.length - 2) / 2 < 4);
|
|
143
|
+
if (bare >= 0) {
|
|
144
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, `destination call ${bare} has no function selector; the rules policy only admits allow-listed calls`, {
|
|
145
|
+
hint: 'A value-only destination transfer is not representable in an agent rule.',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const quote = await runtime.quoteOutbound(token, params.gasLimit ??
|
|
150
|
+
(resolved.isDeployed ? BigInt(0) : FIRST_USE_EVM_GAS_LIMIT), chain);
|
|
151
|
+
if (quote.nativeValueForGas <= BigInt(0)) {
|
|
152
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'outbound gas quote returned zero; URP rejects an uncapped gas swap');
|
|
153
|
+
}
|
|
154
|
+
const maxPCForGas = quote.nativeValueForGas;
|
|
155
|
+
const value = quote.protocolFee + maxPCForGas;
|
|
156
|
+
const payload = (0, viem_1.concat)([
|
|
157
|
+
v5_1.UEA_MULTICALL_PREFIX,
|
|
158
|
+
(0, viem_1.encodeAbiParameters)(MULTICALL_TUPLE, [calls]),
|
|
159
|
+
]);
|
|
160
|
+
const request = {
|
|
161
|
+
recipient: '0x',
|
|
162
|
+
token,
|
|
163
|
+
amount,
|
|
164
|
+
gasLimit: quote.gasLimitUsed,
|
|
165
|
+
gasPrice: BigInt(0),
|
|
166
|
+
maxPCForGas,
|
|
167
|
+
payload,
|
|
168
|
+
revertRecipient: wallet,
|
|
169
|
+
};
|
|
170
|
+
const data = (0, viem_1.encodeFunctionData)({
|
|
171
|
+
abi: abi_1.UNIVERSAL_GATEWAY_PC,
|
|
172
|
+
functionName: 'sendUniversalTxOutbound',
|
|
173
|
+
args: [request],
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
chain,
|
|
177
|
+
destinationAccount: cea,
|
|
178
|
+
destinationAccountDeployed: resolved.isDeployed,
|
|
179
|
+
token,
|
|
180
|
+
amount,
|
|
181
|
+
value,
|
|
182
|
+
request,
|
|
183
|
+
gatewayCall: { target: gen.addresses.gateway, value, data },
|
|
184
|
+
destinationCalls: calls,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=outbound.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExecuteParams, TransactionExecutionOptions, UniversalExecuteParams, UniversalTxResponse } from '../../orchestrator/orchestrator.types';
|
|
2
|
+
import type { AgenticExecutionContext } from '../context';
|
|
3
|
+
import type { AgenticRuntime } from '../runtime';
|
|
4
|
+
/**
|
|
5
|
+
* sendTransaction in agenticWallet mode. Owner door → execute; agent door →
|
|
6
|
+
* executeAsAgent under the one enabled rule for (signer, destination), looked
|
|
7
|
+
* up on every send. Everything is validated before the signer is asked.
|
|
8
|
+
*/
|
|
9
|
+
export declare function agenticSend(runtime: AgenticRuntime, actx: AgenticExecutionContext, params: UniversalExecuteParams | ExecuteParams, options?: TransactionExecutionOptions): Promise<UniversalTxResponse>;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agenticSend = agenticSend;
|
|
4
|
+
const svm_public_1 = require("./svm-public");
|
|
5
|
+
const viem_1 = require("viem");
|
|
6
|
+
const abi_1 = require("../../constants/abi");
|
|
7
|
+
const progress_hook_types_1 = require("../../progress-hook/progress-hook.types");
|
|
8
|
+
const route_detector_1 = require("../../orchestrator/route-detector");
|
|
9
|
+
const helpers_1 = require("../../orchestrator/internals/helpers");
|
|
10
|
+
const capabilities_1 = require("../capabilities");
|
|
11
|
+
const v5_1 = require("../contracts/v5");
|
|
12
|
+
const ids_1 = require("../codec/ids");
|
|
13
|
+
const errors_1 = require("../errors");
|
|
14
|
+
const common_1 = require("../management/common");
|
|
15
|
+
const rules_1 = require("../reads/rules");
|
|
16
|
+
const snapshot_1 = require("../reads/snapshot");
|
|
17
|
+
const response_1 = require("../response");
|
|
18
|
+
const guards_1 = require("./guards");
|
|
19
|
+
const outbound_1 = require("./outbound");
|
|
20
|
+
const MODE_UNIVERSAL = 0;
|
|
21
|
+
const VM_EVM = 0;
|
|
22
|
+
/** R1's own required-funds estimate when no gasLimit is given (execute-standard). */
|
|
23
|
+
const DEFAULT_GAS_ESTIMATE = BigInt(1e7);
|
|
24
|
+
/** Signer-level fields that legitimately carry over to the wrapped Push tx. */
|
|
25
|
+
function signerFields(p) {
|
|
26
|
+
const out = {};
|
|
27
|
+
if (p.gasLimit !== undefined && !(0, route_detector_1.isChainTarget)(p.to))
|
|
28
|
+
out.gasLimit = p.gasLimit;
|
|
29
|
+
if (p.maxFeePerGas !== undefined)
|
|
30
|
+
out.maxFeePerGas = p.maxFeePerGas;
|
|
31
|
+
if (p.maxPriorityFeePerGas !== undefined)
|
|
32
|
+
out.maxPriorityFeePerGas = p.maxPriorityFeePerGas;
|
|
33
|
+
if (p.nonce !== undefined)
|
|
34
|
+
out.nonce = p.nonce;
|
|
35
|
+
if (p.deadline !== undefined)
|
|
36
|
+
out.deadline = p.deadline;
|
|
37
|
+
if (p.feeLockTxHash !== undefined)
|
|
38
|
+
out.feeLockTxHash = p.feeLockTxHash;
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Spec 2.a gas rule: in agenticWallet mode an external signer's UEA must
|
|
43
|
+
* already hold the PC for its Push gas, except for the very first action
|
|
44
|
+
* while that UEA is undeployed (which takes the one-time origin fee lock).
|
|
45
|
+
* Mirrors R1's fee-lock condition so an underfunded UEA fails loudly here
|
|
46
|
+
* instead of silently locking origin funds on every action.
|
|
47
|
+
*/
|
|
48
|
+
async function enforceSignerGas(runtime, gasLimit) {
|
|
49
|
+
if (runtime.signerIsPushNative())
|
|
50
|
+
return;
|
|
51
|
+
if (!(await runtime.signerAccountDeployed()))
|
|
52
|
+
return;
|
|
53
|
+
const [gasPrice, balance] = await Promise.all([
|
|
54
|
+
runtime.getGasPrice(),
|
|
55
|
+
runtime.signerBalance(),
|
|
56
|
+
]);
|
|
57
|
+
const required = (gasLimit ?? DEFAULT_GAS_ESTIMATE) * gasPrice;
|
|
58
|
+
if (balance < required) {
|
|
59
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.AGENT_GAS_INSUFFICIENT, `the signer's UEA ${runtime.signerPushAccount()} holds ${balance} PC wei but needs ~${required} for Push gas`, {
|
|
60
|
+
hint: "The wallet's PC pays outbound fees, not the signer's gas. Top up the signer's UEA (PushChain.utils.account.deriveExecutorAccount) from a client without agenticWallet.",
|
|
61
|
+
details: { required, balance },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A ChainTarget naming the connected Push chain is a native send, exactly like
|
|
67
|
+
* a bare address (core's route detector treats it the same way). A ChainTarget
|
|
68
|
+
* naming a different Push network is refused rather than routed outbound.
|
|
69
|
+
*/
|
|
70
|
+
function normalizePushDestination(p, runtime) {
|
|
71
|
+
if (!(0, route_detector_1.isChainTarget)(p.to))
|
|
72
|
+
return p;
|
|
73
|
+
const chain = p.to.chain;
|
|
74
|
+
if (chain === (0, helpers_1.getPushChainForNetwork)(runtime.network)) {
|
|
75
|
+
return { ...p, to: (0, viem_1.getAddress)(p.to.address) };
|
|
76
|
+
}
|
|
77
|
+
if ((0, helpers_1.isPushChain)(chain)) {
|
|
78
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, `destination ${chain} is a Push chain other than the connected network (${runtime.network})`);
|
|
79
|
+
}
|
|
80
|
+
return p;
|
|
81
|
+
}
|
|
82
|
+
function toCalls(params) {
|
|
83
|
+
if (Array.isArray(params.data)) {
|
|
84
|
+
return params.data.map((c) => ({
|
|
85
|
+
target: (0, viem_1.getAddress)(c.to),
|
|
86
|
+
value: c.value ?? BigInt(0),
|
|
87
|
+
data: c.data,
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
return [
|
|
91
|
+
{
|
|
92
|
+
target: (0, viem_1.getAddress)(params.to),
|
|
93
|
+
value: params.value ?? BigInt(0),
|
|
94
|
+
data: (params.data ?? '0x'),
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* sendTransaction in agenticWallet mode. Owner door → execute; agent door →
|
|
100
|
+
* executeAsAgent under the one enabled rule for (signer, destination), looked
|
|
101
|
+
* up on every send. Everything is validated before the signer is asked.
|
|
102
|
+
*/
|
|
103
|
+
async function agenticSend(runtime, actx, params, options) {
|
|
104
|
+
(0, common_1.assertCanSign)(runtime, 'sendTransaction');
|
|
105
|
+
(0, guards_1.guardAgenticSendParams)(params);
|
|
106
|
+
const p = normalizePushDestination(params, runtime);
|
|
107
|
+
const hook = options?.progressHook ?? p.progressHook;
|
|
108
|
+
const gen = actx.generation;
|
|
109
|
+
const wallet = actx.wallet;
|
|
110
|
+
const outbound = (0, route_detector_1.isChainTarget)(p.to);
|
|
111
|
+
const destination = outbound
|
|
112
|
+
? p.to.chain
|
|
113
|
+
: runtime.pushChainNamespace;
|
|
114
|
+
if (!outbound && p.funds) {
|
|
115
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.NOT_ALLOWED_IN_AGENTIC_MODE, "`funds` on a Push-chain send would bridge from the signer; it does not move the wallet's tokens", {
|
|
116
|
+
hint: "Transfer the wallet's PRC20 with a token transfer call in `data`.",
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (outbound && destination.startsWith('solana:')) {
|
|
120
|
+
await enforceSignerGas(runtime, undefined);
|
|
121
|
+
return (0, svm_public_1.sendPublicSvm)(runtime, actx, p, options);
|
|
122
|
+
}
|
|
123
|
+
let wrappedData;
|
|
124
|
+
let agentBatch;
|
|
125
|
+
let nativeCalls;
|
|
126
|
+
let rulesId;
|
|
127
|
+
let logical;
|
|
128
|
+
let meta = {};
|
|
129
|
+
let outboundChain;
|
|
130
|
+
let destinationCalls;
|
|
131
|
+
if (actx.door === 'agent') {
|
|
132
|
+
(0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.AGENT_EXECUTE);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
(0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.OWNER_EXECUTE);
|
|
136
|
+
}
|
|
137
|
+
if (!outbound) {
|
|
138
|
+
const calls = toCalls(p);
|
|
139
|
+
if (calls.length === 0)
|
|
140
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'an empty call array cannot execute');
|
|
141
|
+
if (actx.door === 'owner') {
|
|
142
|
+
wrappedData = gen.contracts.encodeExecute(calls);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const snap = await snapshot_1.Snapshot.at(runtime.reader);
|
|
146
|
+
const rule = await (0, rules_1.selectRuleForSend)(snap, gen, wallet, actx.signerPushAccount, destination);
|
|
147
|
+
rulesId = rule.rulesId;
|
|
148
|
+
wrappedData = gen.contracts.encodeExecuteAsAgent(rule.rulesId, calls[0]);
|
|
149
|
+
if (calls.length > 1) {
|
|
150
|
+
agentBatch = calls.map((call) => ({
|
|
151
|
+
to: wallet,
|
|
152
|
+
value: BigInt(0),
|
|
153
|
+
data: gen.contracts.encodeExecuteAsAgent(rule.rulesId, call),
|
|
154
|
+
}));
|
|
155
|
+
nativeCalls = calls;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
logical =
|
|
159
|
+
calls.length === 1
|
|
160
|
+
? { to: calls[0].target, data: calls[0].data, value: calls[0].value }
|
|
161
|
+
: agentBatch
|
|
162
|
+
? { to: calls[0].target, data: calls[0].data, value: calls[0].value }
|
|
163
|
+
: { to: wallet, data: wrappedData, value: BigInt(0) };
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
let ruleAssets;
|
|
167
|
+
let expectedCEA;
|
|
168
|
+
const snap = await snapshot_1.Snapshot.at(runtime.reader);
|
|
169
|
+
if (actx.door === 'agent') {
|
|
170
|
+
const rule = await (0, rules_1.selectRuleForSend)(snap, gen, wallet, actx.signerPushAccount, destination);
|
|
171
|
+
if (rule.mode !== MODE_UNIVERSAL || rule.vm !== VM_EVM) {
|
|
172
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, `rule ${rule.rulesId} is not an EVM universal rule`);
|
|
173
|
+
}
|
|
174
|
+
rulesId = rule.rulesId;
|
|
175
|
+
const cfg = await snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getConfig', [
|
|
176
|
+
(0, ids_1.configId)(wallet, rule.rulesId, (0, ids_1.actionId)(gen.addresses.gateway, v5_1.SEND_OUTBOUND_SELECTOR)),
|
|
177
|
+
wallet,
|
|
178
|
+
]);
|
|
179
|
+
ruleAssets = cfg.assets.map((a) => (0, viem_1.getAddress)(a.token));
|
|
180
|
+
expectedCEA = (0, viem_1.getAddress)(cfg.expectedCEA);
|
|
181
|
+
}
|
|
182
|
+
const out = await (0, outbound_1.composeOutbound)(runtime, gen, wallet, p, {
|
|
183
|
+
ruleAssets,
|
|
184
|
+
door: actx.door,
|
|
185
|
+
});
|
|
186
|
+
outboundChain = out.chain;
|
|
187
|
+
meta = { route: 'UOA_TO_CEA', destinationAccount: out.destinationAccount };
|
|
188
|
+
const [walletPc, tokenBalance, allowance] = await Promise.all([
|
|
189
|
+
runtime.reader.getBalance({
|
|
190
|
+
address: wallet,
|
|
191
|
+
blockNumber: snap.blockNumber,
|
|
192
|
+
}),
|
|
193
|
+
out.amount > BigInt(0)
|
|
194
|
+
? snap.read(out.token, abi_1.ERC20_EVM, 'balanceOf', [wallet])
|
|
195
|
+
: Promise.resolve(BigInt(0)),
|
|
196
|
+
snap.read(out.token, abi_1.ERC20_EVM, 'allowance', [wallet, gen.addresses.gateway]),
|
|
197
|
+
]);
|
|
198
|
+
if (walletPc < out.value) {
|
|
199
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.WALLET_BALANCE_INSUFFICIENT, `wallet ${wallet} holds ${walletPc} PC wei; this outbound needs ${out.value} (protocol fee + gas cap)`, { hint: "Fund the wallet's PC with an ordinary send to its address." });
|
|
200
|
+
}
|
|
201
|
+
if (tokenBalance < out.amount) {
|
|
202
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.WALLET_BALANCE_INSUFFICIENT, `wallet ${wallet} holds ${tokenBalance} of ${out.token}; this outbound burns ${out.amount}`);
|
|
203
|
+
}
|
|
204
|
+
// Both doors only consume an allowance the owner set separately; the SDK
|
|
205
|
+
// never writes one (a write from a stale read could restore revoked authority).
|
|
206
|
+
if (out.amount > allowance) {
|
|
207
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.GATEWAY_ALLOWANCE_INSUFFICIENT, `the gateway may pull ${allowance} of ${out.token} from the wallet; this outbound needs ${out.amount}`, {
|
|
208
|
+
hint: 'Set a bounded allowance first with an owner-door send: approve(gateway, cap) on the token (approve(gateway, 0) removes it).',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (actx.door === 'agent') {
|
|
212
|
+
if (expectedCEA && expectedCEA !== out.destinationAccount) {
|
|
213
|
+
throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INCONSISTENT_READ, `rule ${rulesId} committed destination account ${expectedCEA}, but the wallet's account on ${out.chain} now derives to ${out.destinationAccount}`, {
|
|
214
|
+
hint: 'Destination-account derivation drift (obligation 13). The owner must regrant the rule.',
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
wrappedData = gen.contracts.encodeExecuteAsAgent(rulesId, out.gatewayCall);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
wrappedData = gen.contracts.encodeExecute([out.gatewayCall]);
|
|
221
|
+
}
|
|
222
|
+
destinationCalls = out.destinationCalls;
|
|
223
|
+
logical = (0, response_1.outboundResponseCall)(destinationCalls, {
|
|
224
|
+
to: out.gatewayCall.target,
|
|
225
|
+
data: out.gatewayCall.data,
|
|
226
|
+
value: out.gatewayCall.value,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
await enforceSignerGas(runtime, signerFields(p).gasLimit);
|
|
230
|
+
(0, common_1.emitAgentic)(runtime, hook, progress_hook_types_1.PROGRESS_HOOK.AGENTIC_TX_107, rulesId, outboundChain ?? destination, actx.door);
|
|
231
|
+
let resp;
|
|
232
|
+
try {
|
|
233
|
+
const sendOptions = hook ? { ...options, progressHook: hook } : options;
|
|
234
|
+
resp = agentBatch
|
|
235
|
+
? await runtime.executeAtomicBatch({
|
|
236
|
+
...signerFields(p),
|
|
237
|
+
to: wallet,
|
|
238
|
+
value: BigInt(0),
|
|
239
|
+
data: agentBatch,
|
|
240
|
+
}, sendOptions)
|
|
241
|
+
: await runtime.execute({
|
|
242
|
+
...signerFields(p),
|
|
243
|
+
to: wallet,
|
|
244
|
+
value: BigInt(0),
|
|
245
|
+
data: wrappedData,
|
|
246
|
+
}, sendOptions);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
const wrapped = (0, common_1.wrapSendError)(err);
|
|
250
|
+
(0, common_1.emitAgentic)(runtime, hook, progress_hook_types_1.PROGRESS_HOOK.AGENTIC_TX_199_02, 'sendTransaction', wrapped?.code ?? 'UNKNOWN', wrapped?.message ?? String(err), wrapped?.decodedError);
|
|
251
|
+
throw wrapped;
|
|
252
|
+
}
|
|
253
|
+
(0, response_1.adaptAgenticResponse)(resp, {
|
|
254
|
+
wallet,
|
|
255
|
+
door: actx.door,
|
|
256
|
+
rulesId,
|
|
257
|
+
chainNamespace: outboundChain ?? destination,
|
|
258
|
+
destinationAccount: meta.destinationAccount,
|
|
259
|
+
destinationCalls,
|
|
260
|
+
...(nativeCalls
|
|
261
|
+
? {
|
|
262
|
+
nativeCalls: nativeCalls.map((c) => ({
|
|
263
|
+
to: c.target,
|
|
264
|
+
data: c.data,
|
|
265
|
+
value: c.value,
|
|
266
|
+
})),
|
|
267
|
+
}
|
|
268
|
+
: {}),
|
|
269
|
+
logical,
|
|
270
|
+
route: meta.route,
|
|
271
|
+
chain: outboundChain,
|
|
272
|
+
});
|
|
273
|
+
(0, common_1.emitAgentic)(runtime, hook, progress_hook_types_1.PROGRESS_HOOK.AGENTIC_TX_199_01, 'sendTransaction', resp.hash);
|
|
274
|
+
return resp;
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=send.js.map
|