@pushchain/core 6.0.26 → 6.0.27-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.
Files changed (171) hide show
  1. package/AGW.md +226 -0
  2. package/CHANGELOG.md +18 -0
  3. package/README.md +2 -0
  4. package/package.json +7 -1
  5. package/src/lib/agentic/agentic.d.ts +23 -0
  6. package/src/lib/agentic/agentic.js +51 -0
  7. package/src/lib/agentic/agentic.types.d.ts +414 -0
  8. package/src/lib/agentic/agentic.types.js +3 -0
  9. package/src/lib/agentic/capabilities.d.ts +37 -0
  10. package/src/lib/agentic/capabilities.js +64 -0
  11. package/src/lib/agentic/chain.d.ts +3 -0
  12. package/src/lib/agentic/chain.js +15 -0
  13. package/src/lib/agentic/codec/abi-layout.d.ts +20 -0
  14. package/src/lib/agentic/codec/abi-layout.js +168 -0
  15. package/src/lib/agentic/codec/defaults.d.ts +51 -0
  16. package/src/lib/agentic/codec/defaults.js +53 -0
  17. package/src/lib/agentic/codec/ids.d.ts +35 -0
  18. package/src/lib/agentic/codec/ids.js +74 -0
  19. package/src/lib/agentic/codec/native.d.ts +73 -0
  20. package/src/lib/agentic/codec/native.js +341 -0
  21. package/src/lib/agentic/codec/pins.d.ts +20 -0
  22. package/src/lib/agentic/codec/pins.js +29 -0
  23. package/src/lib/agentic/codec/rules.d.ts +45 -0
  24. package/src/lib/agentic/codec/rules.js +110 -0
  25. package/src/lib/agentic/codec/selectors.d.ts +19 -0
  26. package/src/lib/agentic/codec/selectors.js +60 -0
  27. package/src/lib/agentic/codec/session.d.ts +54 -0
  28. package/src/lib/agentic/codec/session.js +65 -0
  29. package/src/lib/agentic/codec/svm-accounts.d.ts +35 -0
  30. package/src/lib/agentic/codec/svm-accounts.js +68 -0
  31. package/src/lib/agentic/codec/svm-idl.d.ts +11 -0
  32. package/src/lib/agentic/codec/svm-idl.js +226 -0
  33. package/src/lib/agentic/codec/svm-terms.d.ts +157 -0
  34. package/src/lib/agentic/codec/svm-terms.js +246 -0
  35. package/src/lib/agentic/codec/universal-terms.d.ts +82 -0
  36. package/src/lib/agentic/codec/universal-terms.js +43 -0
  37. package/src/lib/agentic/codec/universal.d.ts +14 -0
  38. package/src/lib/agentic/codec/universal.js +173 -0
  39. package/src/lib/agentic/constants.d.ts +12 -0
  40. package/src/lib/agentic/constants.js +16 -0
  41. package/src/lib/agentic/context.d.ts +29 -0
  42. package/src/lib/agentic/context.js +56 -0
  43. package/src/lib/agentic/contracts/abi/v6/agent-validator.d.ts +105 -0
  44. package/src/lib/agentic/contracts/abi/v6/agent-validator.js +149 -0
  45. package/src/lib/agentic/contracts/abi/v6/agw-factory.d.ts +1146 -0
  46. package/src/lib/agentic/contracts/abi/v6/agw-factory.js +1499 -0
  47. package/src/lib/agentic/contracts/abi/v6/agw.d.ts +1306 -0
  48. package/src/lib/agentic/contracts/abi/v6/agw.js +1713 -0
  49. package/src/lib/agentic/contracts/abi/v6/index.d.ts +6 -0
  50. package/src/lib/agentic/contracts/abi/v6/index.js +17 -0
  51. package/src/lib/agentic/contracts/abi/v6/smart-session.d.ts +1493 -0
  52. package/src/lib/agentic/contracts/abi/v6/smart-session.js +1965 -0
  53. package/src/lib/agentic/contracts/abi/v6/universal-rules-policy.d.ts +1661 -0
  54. package/src/lib/agentic/contracts/abi/v6/universal-rules-policy.js +2187 -0
  55. package/src/lib/agentic/contracts/donut-v6.d.ts +11 -0
  56. package/src/lib/agentic/contracts/donut-v6.js +15 -0
  57. package/src/lib/agentic/contracts/prc20-metadata.d.ts +26 -0
  58. package/src/lib/agentic/contracts/prc20-metadata.js +87 -0
  59. package/src/lib/agentic/contracts/reader.d.ts +35 -0
  60. package/src/lib/agentic/contracts/reader.js +16 -0
  61. package/src/lib/agentic/contracts/v6.d.ts +5739 -0
  62. package/src/lib/agentic/contracts/v6.js +343 -0
  63. package/src/lib/agentic/deployments.d.ts +61 -0
  64. package/src/lib/agentic/deployments.js +203 -0
  65. package/src/lib/agentic/errors.d.ts +65 -0
  66. package/src/lib/agentic/errors.js +84 -0
  67. package/src/lib/agentic/execution/guards.d.ts +9 -0
  68. package/src/lib/agentic/execution/guards.js +30 -0
  69. package/src/lib/agentic/execution/outbound.d.ts +55 -0
  70. package/src/lib/agentic/execution/outbound.js +187 -0
  71. package/src/lib/agentic/execution/send.d.ts +9 -0
  72. package/src/lib/agentic/execution/send.js +268 -0
  73. package/src/lib/agentic/execution/svm-instruction.d.ts +24 -0
  74. package/src/lib/agentic/execution/svm-instruction.js +40 -0
  75. package/src/lib/agentic/execution/svm-outbound.d.ts +18 -0
  76. package/src/lib/agentic/execution/svm-outbound.js +86 -0
  77. package/src/lib/agentic/execution/svm-payload.d.ts +18 -0
  78. package/src/lib/agentic/execution/svm-payload.js +136 -0
  79. package/src/lib/agentic/execution/svm-public.d.ts +5 -0
  80. package/src/lib/agentic/execution/svm-public.js +176 -0
  81. package/src/lib/agentic/execution/svm-quote.d.ts +11 -0
  82. package/src/lib/agentic/execution/svm-quote.js +24 -0
  83. package/src/lib/agentic/execution/svm-send.d.ts +44 -0
  84. package/src/lib/agentic/execution/svm-send.js +87 -0
  85. package/src/lib/agentic/index.d.ts +5 -0
  86. package/src/lib/agentic/index.js +10 -0
  87. package/src/lib/agentic/management/common.d.ts +29 -0
  88. package/src/lib/agentic/management/common.js +116 -0
  89. package/src/lib/agentic/management/create.d.ts +4 -0
  90. package/src/lib/agentic/management/create.js +138 -0
  91. package/src/lib/agentic/management/duplicates.d.ts +4 -0
  92. package/src/lib/agentic/management/duplicates.js +20 -0
  93. package/src/lib/agentic/management/label.d.ts +3 -0
  94. package/src/lib/agentic/management/label.js +17 -0
  95. package/src/lib/agentic/management/prepare.d.ts +7 -0
  96. package/src/lib/agentic/management/prepare.js +95 -0
  97. package/src/lib/agentic/management/rules-write.d.ts +42 -0
  98. package/src/lib/agentic/management/rules-write.js +279 -0
  99. package/src/lib/agentic/management/svm-context.d.ts +25 -0
  100. package/src/lib/agentic/management/svm-context.js +55 -0
  101. package/src/lib/agentic/management/svm-metadata.d.ts +10 -0
  102. package/src/lib/agentic/management/svm-metadata.js +56 -0
  103. package/src/lib/agentic/management/svm-public.d.ts +6 -0
  104. package/src/lib/agentic/management/svm-public.js +125 -0
  105. package/src/lib/agentic/management/svm.d.ts +27 -0
  106. package/src/lib/agentic/management/svm.js +150 -0
  107. package/src/lib/agentic/presets/catalog.d.ts +26 -0
  108. package/src/lib/agentic/presets/catalog.js +307 -0
  109. package/src/lib/agentic/presets/index.d.ts +5 -0
  110. package/src/lib/agentic/presets/index.js +265 -0
  111. package/src/lib/agentic/presets/types.d.ts +48 -0
  112. package/src/lib/agentic/presets/types.js +3 -0
  113. package/src/lib/agentic/public-rule.d.ts +9 -0
  114. package/src/lib/agentic/public-rule.js +326 -0
  115. package/src/lib/agentic/reads/checkpoints.d.ts +17 -0
  116. package/src/lib/agentic/reads/checkpoints.js +109 -0
  117. package/src/lib/agentic/reads/rules.d.ts +42 -0
  118. package/src/lib/agentic/reads/rules.js +302 -0
  119. package/src/lib/agentic/reads/snapshot.d.ts +28 -0
  120. package/src/lib/agentic/reads/snapshot.js +85 -0
  121. package/src/lib/agentic/reads/svm.d.ts +17 -0
  122. package/src/lib/agentic/reads/svm.js +52 -0
  123. package/src/lib/agentic/reads/wallets.d.ts +25 -0
  124. package/src/lib/agentic/reads/wallets.js +122 -0
  125. package/src/lib/agentic/response.d.ts +41 -0
  126. package/src/lib/agentic/response.js +358 -0
  127. package/src/lib/agentic/revert.d.ts +7 -0
  128. package/src/lib/agentic/revert.js +102 -0
  129. package/src/lib/agentic/runtime.d.ts +58 -0
  130. package/src/lib/agentic/runtime.js +104 -0
  131. package/src/lib/agentic/utils.d.ts +57 -0
  132. package/src/lib/agentic/utils.js +165 -0
  133. package/src/lib/agentic/wallet.d.ts +32 -0
  134. package/src/lib/agentic/wallet.js +130 -0
  135. package/src/lib/constants/enums.d.ts +6 -3
  136. package/src/lib/constants/enums.js +6 -3
  137. package/src/lib/constants/index.d.ts +61 -4
  138. package/src/lib/constants/index.js +17 -3
  139. package/src/lib/constants/read-state.d.ts +9 -0
  140. package/src/lib/constants/read-state.js +13 -1
  141. package/src/lib/index.d.ts +8 -2
  142. package/src/lib/index.js +9 -1
  143. package/src/lib/orchestrator/internals/errors.d.ts +7 -0
  144. package/src/lib/orchestrator/internals/errors.js +13 -1
  145. package/src/lib/orchestrator/internals/execute-standard.d.ts +3 -1
  146. package/src/lib/orchestrator/internals/execute-standard.js +3 -3
  147. package/src/lib/orchestrator/internals/outbound-sync.js +52 -7
  148. package/src/lib/orchestrator/internals/push-chain-tx.d.ts +1 -1
  149. package/src/lib/orchestrator/internals/push-chain-tx.js +13 -1
  150. package/src/lib/orchestrator/orchestrator.d.ts +3 -0
  151. package/src/lib/orchestrator/orchestrator.js +13 -1
  152. package/src/lib/orchestrator/orchestrator.types.d.ts +8 -0
  153. package/src/lib/orchestrator/route-detector.js +3 -2
  154. package/src/lib/orchestrator/svm-idl/resolve.d.ts +2 -0
  155. package/src/lib/orchestrator/svm-idl/resolve.js +11 -1
  156. package/src/lib/progress-hook/progress-hook.js +63 -0
  157. package/src/lib/progress-hook/progress-hook.types.d.ts +10 -1
  158. package/src/lib/progress-hook/progress-hook.types.js +10 -0
  159. package/src/lib/push-chain/push-chain.d.ts +57 -15
  160. package/src/lib/push-chain/push-chain.js +66 -7
  161. package/src/lib/read-state/destination.js +6 -1
  162. package/src/lib/read-state/read-params.d.ts +3 -3
  163. package/src/lib/read-state/read-params.js +3 -2
  164. package/src/lib/read-state/read-state.types.d.ts +3 -1
  165. package/src/lib/read-state/read-tracker.js +2 -2
  166. package/src/lib/read-state/spec-builder.js +1 -1
  167. package/src/lib/universal/prc20-address.d.ts +15 -0
  168. package/src/lib/universal/prc20-address.js +135 -0
  169. package/src/lib/utils.d.ts +6 -13
  170. package/src/lib/utils.js +5 -128
  171. package/src/lib/vm-client/evm-client.js +34 -20
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readCheckpoints = readCheckpoints;
4
+ exports.validateSequence = validateSequence;
5
+ const capabilities_1 = require("../capabilities");
6
+ const errors_1 = require("../errors");
7
+ const snapshot_1 = require("./snapshot");
8
+ const MAX_ATTEMPTS = 2;
9
+ /**
10
+ * w.checkpoints(): Checkpointed events in (block, tx, log) order, checked
11
+ * against the wallet's checkpointCount() at the same snapshot block.
12
+ * `sinceBlock` is inclusive. Evaluators should compare counts — one block can
13
+ * hold several ticks, and allowance pulls change balances without any tick.
14
+ */
15
+ async function readCheckpoints(reader, gen, wallet, sinceBlock) {
16
+ (0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.CHECKPOINTS);
17
+ let lastError;
18
+ for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
19
+ const snap = await snapshot_1.Snapshot.at(reader);
20
+ const count = BigInt(await snap.read(wallet, gen.contracts.abis.wallet, 'checkpointCount'));
21
+ const from = sinceBlock !== undefined && sinceBlock > gen.startBlock
22
+ ? sinceBlock
23
+ : gen.startBlock;
24
+ const filter = {
25
+ address: wallet,
26
+ event: gen.contracts.events.checkpointed,
27
+ };
28
+ let logs;
29
+ try {
30
+ logs = await (0, snapshot_1.scanLogs)(reader, filter, from, snap.blockNumber);
31
+ }
32
+ catch (cause) {
33
+ const retained = lowestRetainedHeight(cause);
34
+ // A fresh wallet may have its entire history after the RPC retention
35
+ // floor. Never treat truncation as success: the FULL sequence/count
36
+ // validation below must still prove every checkpoint is present.
37
+ if (sinceBlock !== undefined ||
38
+ retained === undefined ||
39
+ retained <= from ||
40
+ retained > snap.blockNumber)
41
+ throw cause;
42
+ logs = await (0, snapshot_1.scanLogs)(reader, filter, retained, snap.blockNumber);
43
+ }
44
+ const decoded = gen.contracts
45
+ .parseCheckpointed(logs, wallet)
46
+ .sort((a, b) => a.blockNumber !== b.blockNumber
47
+ ? a.blockNumber < b.blockNumber
48
+ ? -1
49
+ : 1
50
+ : a.transactionIndex !== b.transactionIndex
51
+ ? a.transactionIndex - b.transactionIndex
52
+ : a.logIndex - b.logIndex);
53
+ const problem = validateSequence(decoded.map((c) => c.seq), count, sinceBlock === undefined || from === gen.startBlock);
54
+ if (!problem) {
55
+ return {
56
+ count,
57
+ blockNumber: snap.blockNumber,
58
+ checkpoints: decoded.map(({ seq, kind, ref, blockNumber, txHash }) => ({
59
+ seq,
60
+ kind,
61
+ ref,
62
+ blockNumber,
63
+ txHash,
64
+ })),
65
+ };
66
+ }
67
+ lastError = new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INCONSISTENT_READ, problem, {
68
+ details: { wallet, count, blockNumber: snap.blockNumber },
69
+ });
70
+ }
71
+ throw lastError;
72
+ }
73
+ /** Sequence must be contiguous, end at `count`, and start at 1 for a full scan. */
74
+ function validateSequence(seqs, count, fullRange) {
75
+ for (let i = 1; i < seqs.length; i++) {
76
+ if (seqs[i] !== seqs[i - 1] + 1)
77
+ return `checkpoint sequence gap between ${seqs[i - 1]} and ${seqs[i]}`;
78
+ }
79
+ if (fullRange) {
80
+ if (BigInt(seqs.length) !== count) {
81
+ return `found ${seqs.length} Checkpointed events but checkpointCount() is ${count}`;
82
+ }
83
+ if (seqs.length > 0 && seqs[0] !== 1)
84
+ return `first checkpoint seq is ${seqs[0]}, expected 1`;
85
+ return null;
86
+ }
87
+ if (seqs.length > 0 && BigInt(seqs[seqs.length - 1]) !== count) {
88
+ return `last checkpoint seq ${seqs[seqs.length - 1]} does not match checkpointCount() ${count}`;
89
+ }
90
+ return null;
91
+ }
92
+ /** Recognize Donut/CometBFT's explicit pruning error, not arbitrary RPC failures. */
93
+ function lowestRetainedHeight(error) {
94
+ const visited = new Set();
95
+ for (let depth = 0; depth < 8 && error && typeof error === 'object' && !visited.has(error); depth++) {
96
+ visited.add(error);
97
+ const value = error;
98
+ for (const text of [value.message, value.details]) {
99
+ if (typeof text !== 'string')
100
+ continue;
101
+ const match = /height \d+ is not available, lowest height is (\d+)/.exec(text);
102
+ if (match)
103
+ return BigInt(match[1]);
104
+ }
105
+ error = value.cause;
106
+ }
107
+ return undefined;
108
+ }
109
+ //# sourceMappingURL=checkpoints.js.map
@@ -0,0 +1,42 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import type { AgenticGeneration } from '../deployments';
3
+ import type { RulesRecord } from '../agentic.types';
4
+ import { Snapshot } from './snapshot';
5
+ export interface ActiveRule {
6
+ rulesId: Hex;
7
+ /** agentOf(rulesId); zero means the engine no longer resolves it. */
8
+ agent: Address;
9
+ actionIds: readonly Hex[];
10
+ mode: number;
11
+ vm: number;
12
+ chainHash: Hex;
13
+ }
14
+ /** Enabled rule IDs with their agent and governed chain, all at one block. */
15
+ export declare function readActiveRules(snap: Snapshot, gen: AgenticGeneration, wallet: Address): Promise<ActiveRule[]>;
16
+ /** Map a stored chain hash back to its CAIP-2 string from known chains. */
17
+ export declare function chainFromHash(hash: Hex, pushChainNamespace: string): string | undefined;
18
+ /**
19
+ * Agent-door rule selection for one send (spec 2.a): enabled rules whose agent
20
+ * is the signer and whose chain is the destination, read uncached at one
21
+ * block. Expiry, caps and policy remain on-chain checks.
22
+ */
23
+ export declare function selectRuleForSend(snap: Snapshot, gen: AgenticGeneration, wallet: Address, agent: Address, destinationChain: string): Promise<ActiveRule>;
24
+ /** Decode one active rule into the public record. */
25
+ export declare function decodeActiveRule(snap: Snapshot, gen: AgenticGeneration, wallet: Address, rule: ActiveRule, pushChainNamespace: string): Promise<RulesRecord>;
26
+ /** Native spend counters for the update assertion. */
27
+ export declare function readNativeSpend(snap: Snapshot, gen: AgenticGeneration, wallet: Address, rule: ActiveRule, action?: Hex): Promise<{
28
+ configId: Hex;
29
+ valueSpent: bigint;
30
+ amountSpent: bigint;
31
+ callsUsed: number;
32
+ }>;
33
+ export declare function readUniversalSpend(snap: Snapshot, gen: AgenticGeneration, wallet: Address, rule: ActiveRule): Promise<{
34
+ configId: Hex;
35
+ expectedSpent: bigint[];
36
+ }>;
37
+ export declare function listRules(snap: Snapshot, gen: AgenticGeneration, wallet: Address, pushChainNamespace: string): Promise<RulesRecord[]>;
38
+ /**
39
+ * rules.get returns enabled records only. Unknown/revoked IDs are deliberately
40
+ * indistinguishable without historical reconstruction, which is outside v1.
41
+ */
42
+ export declare function getRule(snap: Snapshot, gen: AgenticGeneration, wallet: Address, rulesId: Hex, pushChainNamespace: string): Promise<RulesRecord>;
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readActiveRules = readActiveRules;
4
+ exports.chainFromHash = chainFromHash;
5
+ exports.selectRuleForSend = selectRuleForSend;
6
+ exports.decodeActiveRule = decodeActiveRule;
7
+ exports.readNativeSpend = readNativeSpend;
8
+ exports.readUniversalSpend = readUniversalSpend;
9
+ exports.listRules = listRules;
10
+ exports.getRule = getRule;
11
+ const svm_1 = require("./svm");
12
+ const prc20_metadata_1 = require("../contracts/prc20-metadata");
13
+ const viem_1 = require("viem");
14
+ const enums_1 = require("../../constants/enums");
15
+ const capabilities_1 = require("../capabilities");
16
+ const ids_1 = require("../codec/ids");
17
+ const native_1 = require("../codec/native");
18
+ const defaults_1 = require("../codec/defaults");
19
+ const public_rule_1 = require("../public-rule");
20
+ const errors_1 = require("../errors");
21
+ const prc20_metadata_2 = require("../contracts/prc20-metadata");
22
+ const rules_1 = require("../codec/rules");
23
+ const errors_2 = require("../errors");
24
+ const MODE_UNIVERSAL = 0;
25
+ const MODE_NATIVE = 1;
26
+ /** Enabled rule IDs with their agent and governed chain, all at one block. */
27
+ async function readActiveRules(snap, gen, wallet) {
28
+ const ids = await snap.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'getPermissionIDs', [wallet]);
29
+ return Promise.all(ids.map((id) => readActiveRule(snap, gen, wallet, id)));
30
+ }
31
+ async function readActiveRule(snap, gen, wallet, rulesId) {
32
+ const [agent, actionIds] = await Promise.all([
33
+ snap.read(wallet, gen.contracts.abis.wallet, 'agentOf', [rulesId]),
34
+ snap.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'getEnabledActions', [wallet, rulesId]),
35
+ ]);
36
+ if (actionIds.length === 0) {
37
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, `enabled rule ${rulesId} has no enabled actions`);
38
+ }
39
+ const modes = await Promise.all(actionIds.map((a) => snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getMode', [(0, ids_1.configId)(wallet, rulesId, a), wallet])));
40
+ const first = modes[0];
41
+ if (!modes.every((m) => m.initialized &&
42
+ m.chainHash === first.chainHash &&
43
+ m.mode === first.mode)) {
44
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, `rule ${rulesId} has uninitialized or mixed-chain policy configs`);
45
+ }
46
+ return {
47
+ rulesId,
48
+ agent: (0, viem_1.getAddress)(agent),
49
+ actionIds,
50
+ mode: Number(first.mode),
51
+ vm: Number(first.vm),
52
+ chainHash: first.chainHash,
53
+ };
54
+ }
55
+ /** Map a stored chain hash back to its CAIP-2 string from known chains. */
56
+ function chainFromHash(hash, pushChainNamespace) {
57
+ const known = [pushChainNamespace, ...Object.values(enums_1.CHAIN)];
58
+ return known.find((c) => (0, rules_1.chainHash)(c) === hash);
59
+ }
60
+ /**
61
+ * Agent-door rule selection for one send (spec 2.a): enabled rules whose agent
62
+ * is the signer and whose chain is the destination, read uncached at one
63
+ * block. Expiry, caps and policy remain on-chain checks.
64
+ */
65
+ async function selectRuleForSend(snap, gen, wallet, agent, destinationChain) {
66
+ const active = await readActiveRules(snap, gen, wallet);
67
+ const want = (0, rules_1.chainHash)(destinationChain);
68
+ const matches = active.filter((r) => r.agent === (0, viem_1.getAddress)(agent) && r.chainHash === want);
69
+ if (matches.length === 0) {
70
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.NO_RULES_FOR_CHAIN, `no enabled rule on ${wallet} names ${agent} for ${destinationChain}`, {
71
+ details: {
72
+ wallet,
73
+ agent,
74
+ destinationChain,
75
+ blockNumber: snap.blockNumber,
76
+ },
77
+ });
78
+ }
79
+ if (matches.length > 1) {
80
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.AMBIGUOUS_RULE, `${matches.length} enabled rules on ${wallet} name ${agent} for ${destinationChain}`, {
81
+ hint: 'Multiple enabled rules match this agent and chain. Inspect details.rulesIds and ask the owner to resolve the overlap; no transaction was submitted.',
82
+ details: { rulesIds: matches.map((m) => m.rulesId) },
83
+ });
84
+ }
85
+ return matches[0];
86
+ }
87
+ /** Decode one active rule into the public record. */
88
+ async function decodeActiveRule(snap, gen, wallet, rule, pushChainNamespace) {
89
+ if (rule.mode === MODE_UNIVERSAL) {
90
+ if (rule.vm === 1) {
91
+ (0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.UNIVERSAL_SVM_RULES);
92
+ const stored = await (0, svm_1.readSvmConfig)(snap, gen, wallet, rule, pushChainNamespace);
93
+ const cfg = stored.config;
94
+ const gas = await (0, prc20_metadata_1.readGasPrc20)(snap, stored.chainNamespace);
95
+ const assets = await Promise.all(cfg.assets.map(async (a) => ({
96
+ token: (0, viem_1.getAddress)(a.token) === gas
97
+ ? viem_1.zeroAddress
98
+ : await (0, prc20_metadata_1.readSvmSourceToken)(snap, a.token, stored.chainNamespace, gen.network),
99
+ maxPerCall: a.maxPerCall,
100
+ maxTotal: a.maxTotal,
101
+ })));
102
+ return {
103
+ rulesId: rule.rulesId,
104
+ enabled: true,
105
+ agent: rule.agent,
106
+ chainNamespace: stored.chainNamespace,
107
+ validUntil: Number(cfg.validUntil),
108
+ spent: {
109
+ kind: 'universal',
110
+ assets: assets.map((a, i) => ({
111
+ token: a.token,
112
+ spent: cfg.assets[i].spent,
113
+ })),
114
+ },
115
+ rule: {
116
+ format: 'decoded',
117
+ agent: rule.agent,
118
+ chainNamespace: stored.chainNamespace,
119
+ validUntil: Number(cfg.validUntil),
120
+ expectedCEA: cfg.expectedCEA,
121
+ gatewayProgram: cfg.gatewayProgram,
122
+ maxGasPerCall: cfg.maxGasPerCall,
123
+ assets,
124
+ ceaAccounts: cfg.ceaAccounts,
125
+ programs: cfg.programs,
126
+ pins: cfg.pins,
127
+ dataPins: cfg.dataPins,
128
+ },
129
+ };
130
+ }
131
+ if (rule.vm !== 0)
132
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.RULE_READ_FAILED, 'unknown universal VM');
133
+ (0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.UNIVERSAL_EVM_RULES);
134
+ const chain = chainFromHash(rule.chainHash, pushChainNamespace);
135
+ if (!chain || !chain.startsWith('eip155:'))
136
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.RULE_READ_FAILED, 'unknown EVM rule chain');
137
+ const cfg = await snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getConfig', [(0, ids_1.configId)(wallet, rule.rulesId, rule.actionIds[0]), wallet]);
138
+ if (!cfg.initialized)
139
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, 'uninitialized universal rule');
140
+ if (!cfg.assets.length ||
141
+ cfg.assets.length > 8 ||
142
+ !cfg.allowedCalls.length ||
143
+ cfg.allowedCalls.length > 32 ||
144
+ cfg.expectedCEA === viem_1.zeroAddress)
145
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, 'invalid stored universal rule shape');
146
+ const tokens = await Promise.all(cfg.assets.map((a) => (0, prc20_metadata_2.readOriginToken)(snap, a.token, chain)));
147
+ return {
148
+ rulesId: rule.rulesId,
149
+ enabled: true,
150
+ chainNamespace: chain,
151
+ agent: rule.agent,
152
+ validUntil: Number(cfg.validUntil),
153
+ spent: {
154
+ kind: 'universal',
155
+ assets: tokens.map((token, i) => ({
156
+ token,
157
+ spent: cfg.assets[i].spent,
158
+ })),
159
+ },
160
+ rule: {
161
+ agent: rule.agent,
162
+ chainNamespace: chain,
163
+ validUntil: Number(cfg.validUntil),
164
+ maxGasPerCall: cfg.maxGasPerCall,
165
+ assets: cfg.assets.map((a, i) => ({
166
+ token: tokens[i],
167
+ maxPerCall: a.maxPerCall,
168
+ maxTotal: a.maxTotal,
169
+ })),
170
+ allowedCalls: cfg.allowedCalls.map((c) => ({
171
+ target: c.target,
172
+ selector: c.selector,
173
+ maxValue: c.maxValue,
174
+ pins: [
175
+ ...c.pins.map((p) => p.op === 1
176
+ ? { arg: storedArg(p.offset), max: BigInt(p.value) }
177
+ : {
178
+ arg: storedArg(p.offset),
179
+ expected: p.value.toLowerCase() ===
180
+ `0x${cfg.expectedCEA
181
+ .slice(2)
182
+ .toLowerCase()
183
+ .padStart(64, '0')}`
184
+ ? public_rule_1.WALLET
185
+ : p.value,
186
+ }),
187
+ ...(c.hasBeneficiary
188
+ ? [{ arg: storedArg(c.beneficiaryOffset), expected: public_rule_1.WALLET }]
189
+ : []),
190
+ ],
191
+ })),
192
+ },
193
+ };
194
+ }
195
+ if (rule.mode !== MODE_NATIVE) {
196
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.RULE_READ_FAILED, `rule ${rule.rulesId} has unknown mode ${rule.mode}`);
197
+ }
198
+ // One stored config per action, read at the same block, in engine order.
199
+ const configs = await Promise.all(rule.actionIds.map((action) => snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getNativeConfig', [(0, ids_1.configId)(wallet, rule.rulesId, action), wallet])));
200
+ if (configs.some((c) => !c.initialized)) {
201
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, `native config for ${rule.rulesId} is not initialized`);
202
+ }
203
+ const decoded = (0, native_1.nativeActionTermsToRule)(configs, rule.agent);
204
+ if (configs.some((c) => c.maxValueTotal !== defaults_1.UINT256_MAX ||
205
+ Number(c.maxCalls) !== 0xffffffff ||
206
+ (c.amount.enabled && c.amount.maxTotal !== defaults_1.UINT256_MAX) ||
207
+ Number(c.validUntil) !== decoded.validUntil)) {
208
+ throw (0, errors_1.capabilityUnavailable)('nativeRuleRead', 'stored lifetime limits or differing action expiries cannot be represented by section-6 rules without losing constraints');
209
+ }
210
+ const allowedCalls = configs.map((c) => ({
211
+ target: (0, viem_1.getAddress)(c.target),
212
+ selector: c.selector === '0xffffffff' ? 'value-only' : c.selector,
213
+ maxValue: c.maxValuePerCall,
214
+ pins: [
215
+ ...c.pins.map((p) => p.op === 1
216
+ ? { arg: storedArg(p.offset), max: BigInt(p.value) }
217
+ : {
218
+ arg: storedArg(p.offset),
219
+ expected: p.value.toLowerCase() ===
220
+ `0x${wallet.slice(2).toLowerCase().padStart(64, '0')}`
221
+ ? public_rule_1.WALLET
222
+ : p.value,
223
+ }),
224
+ ...(c.amount.enabled
225
+ ? [{ arg: storedArg(c.amount.offset), max: c.amount.maxPerCall }]
226
+ : []),
227
+ ],
228
+ }));
229
+ const counters = configs.map((c, i) => ({
230
+ target: allowedCalls[i].target,
231
+ selector: allowedCalls[i].selector,
232
+ valueSpent: c.valueSpent,
233
+ amountSpent: c.amountSpent,
234
+ callsUsed: Number(c.callsUsed),
235
+ }));
236
+ if (rule.agent === (0, viem_1.getAddress)(`0x${'00'.repeat(20)}`)) {
237
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, `enabled rule ${rule.rulesId} does not resolve to an agent`);
238
+ }
239
+ return {
240
+ rulesId: rule.rulesId,
241
+ enabled: true,
242
+ chainNamespace: pushChainNamespace,
243
+ agent: rule.agent,
244
+ validUntil: decoded.validUntil,
245
+ rule: { agent: rule.agent, validUntil: decoded.validUntil, allowedCalls },
246
+ spent: counters.length === 1
247
+ ? {
248
+ kind: 'native',
249
+ valueSpent: counters[0].valueSpent,
250
+ amountSpent: counters[0].amountSpent,
251
+ callsUsed: counters[0].callsUsed,
252
+ }
253
+ : { kind: 'native', actions: counters },
254
+ };
255
+ }
256
+ /** Native spend counters for the update assertion. */
257
+ async function readNativeSpend(snap, gen, wallet, rule, action = rule.actionIds[0]) {
258
+ const id = (0, ids_1.configId)(wallet, rule.rulesId, action);
259
+ const cfg = await snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getNativeConfig', [id, wallet]);
260
+ return {
261
+ configId: id,
262
+ valueSpent: cfg.valueSpent,
263
+ amountSpent: cfg.amountSpent,
264
+ callsUsed: Number(cfg.callsUsed),
265
+ };
266
+ }
267
+ async function readUniversalSpend(snap, gen, wallet, rule) {
268
+ const id = (0, ids_1.configId)(wallet, rule.rulesId, rule.actionIds[0]);
269
+ const fn = rule.vm === 1 ? 'getSvmConfig' : 'getConfig';
270
+ const cfg = await snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, fn, [id, wallet]);
271
+ if (!cfg.initialized)
272
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.INCONSISTENT_READ, 'uninitialized universal spend config');
273
+ return { configId: id, expectedSpent: cfg.assets.map((a) => a.spent) };
274
+ }
275
+ async function listRules(snap, gen, wallet, pushChainNamespace) {
276
+ (0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.ACTIVE_RULE_READS);
277
+ const active = await readActiveRules(snap, gen, wallet);
278
+ const records = [];
279
+ for (const r of active)
280
+ records.push(await decodeActiveRule(snap, gen, wallet, r, pushChainNamespace));
281
+ return records;
282
+ }
283
+ /**
284
+ * rules.get returns enabled records only. Unknown/revoked IDs are deliberately
285
+ * indistinguishable without historical reconstruction, which is outside v1.
286
+ */
287
+ async function getRule(snap, gen, wallet, rulesId, pushChainNamespace) {
288
+ (0, capabilities_1.requireCapability)(gen.capabilities, capabilities_1.AgenticCapability.ACTIVE_RULE_READS);
289
+ const enabled = await snap.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'isPermissionEnabled', [rulesId, wallet]);
290
+ if (enabled) {
291
+ const active = await readActiveRule(snap, gen, wallet, rulesId);
292
+ return decodeActiveRule(snap, gen, wallet, active, pushChainNamespace);
293
+ }
294
+ throw new errors_2.AgenticError(errors_2.AGENTIC_ERROR_CODE.RULE_NOT_FOUND, `rule ${rulesId} is not enabled on ${wallet} (unknown or revoked; v1 has no rule history)`);
295
+ }
296
+ /** With a raw selector, arg denotes its ABI head-word position. */
297
+ function storedArg(offset) {
298
+ if (offset < 4 || (offset - 4) % 32 !== 0)
299
+ throw (0, errors_1.capabilityUnavailable)('argumentLayout', 'stored pin is not aligned to an ABI argument word');
300
+ return (offset - 4) / 32;
301
+ }
302
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1,28 @@
1
+ import type { AbiEvent, Address, Log } from 'viem';
2
+ import type { ChainReader } from '../contracts/reader';
3
+ import { type AgenticErrorCode } from '../errors';
4
+ /**
5
+ * All reads of one logical operation are pinned to a single block so dependent
6
+ * reads (enumerate IDs → per-ID config) observe one state. An RPC failure is
7
+ * surfaced as an error; it is never treated as "empty".
8
+ */
9
+ export declare class Snapshot {
10
+ readonly reader: ChainReader;
11
+ readonly blockNumber: bigint;
12
+ private readonly failCode;
13
+ constructor(reader: ChainReader, blockNumber: bigint, failCode?: AgenticErrorCode);
14
+ static at(reader: ChainReader, failCode?: AgenticErrorCode): Promise<Snapshot>;
15
+ read<T>(address: Address, abi: readonly unknown[], functionName: string, args?: readonly unknown[]): Promise<T>;
16
+ code(address: Address): Promise<boolean>;
17
+ }
18
+ /** Max block span per eth_getLogs request. */
19
+ export declare const LOG_PAGE_BLOCKS: bigint;
20
+ /**
21
+ * Paginated log scan [fromBlock, toBlock] inclusive. A failed page fails the
22
+ * whole scan; partial results are never returned.
23
+ */
24
+ export declare function scanLogs(reader: ChainReader, args: {
25
+ address: Address;
26
+ event: AbiEvent;
27
+ args?: Record<string, unknown>;
28
+ }, fromBlock: bigint, toBlock: bigint, page?: bigint): Promise<Log[]>;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LOG_PAGE_BLOCKS = exports.Snapshot = void 0;
4
+ exports.scanLogs = scanLogs;
5
+ const errors_1 = require("../errors");
6
+ /**
7
+ * All reads of one logical operation are pinned to a single block so dependent
8
+ * reads (enumerate IDs → per-ID config) observe one state. An RPC failure is
9
+ * surfaced as an error; it is never treated as "empty".
10
+ */
11
+ class Snapshot {
12
+ reader;
13
+ blockNumber;
14
+ failCode;
15
+ constructor(reader, blockNumber, failCode = errors_1.AGENTIC_ERROR_CODE.RULE_READ_FAILED) {
16
+ this.reader = reader;
17
+ this.blockNumber = blockNumber;
18
+ this.failCode = failCode;
19
+ }
20
+ static async at(reader, failCode = errors_1.AGENTIC_ERROR_CODE.RULE_READ_FAILED) {
21
+ let block;
22
+ try {
23
+ block = await reader.getBlockNumber();
24
+ }
25
+ catch (cause) {
26
+ throw new errors_1.AgenticError(failCode, 'could not read the current Push block number', { cause });
27
+ }
28
+ return new Snapshot(reader, block, failCode);
29
+ }
30
+ async read(address, abi, functionName, args = []) {
31
+ try {
32
+ return (await this.reader.readContract({
33
+ address,
34
+ abi,
35
+ functionName,
36
+ args,
37
+ blockNumber: this.blockNumber,
38
+ }));
39
+ }
40
+ catch (cause) {
41
+ throw new errors_1.AgenticError(this.failCode, `${functionName} read on ${address} failed at block ${this.blockNumber}`, {
42
+ cause,
43
+ details: { address, functionName, blockNumber: this.blockNumber },
44
+ });
45
+ }
46
+ }
47
+ async code(address) {
48
+ try {
49
+ const code = await this.reader.getCode({
50
+ address,
51
+ blockNumber: this.blockNumber,
52
+ });
53
+ return !!code && code !== '0x';
54
+ }
55
+ catch (cause) {
56
+ throw new errors_1.AgenticError(this.failCode, `getCode(${address}) failed`, {
57
+ cause,
58
+ });
59
+ }
60
+ }
61
+ }
62
+ exports.Snapshot = Snapshot;
63
+ /** Max block span per eth_getLogs request. */
64
+ // Donut's public RPC limits eth_getLogs ranges to a distance of 1,000 blocks.
65
+ exports.LOG_PAGE_BLOCKS = BigInt(1_000);
66
+ /**
67
+ * Paginated log scan [fromBlock, toBlock] inclusive. A failed page fails the
68
+ * whole scan; partial results are never returned.
69
+ */
70
+ async function scanLogs(reader, args, fromBlock, toBlock, page = exports.LOG_PAGE_BLOCKS) {
71
+ const out = [];
72
+ if (fromBlock > toBlock)
73
+ return out;
74
+ for (let start = fromBlock; start <= toBlock; start += page) {
75
+ const end = start + page - BigInt(1) > toBlock ? toBlock : start + page - BigInt(1);
76
+ try {
77
+ out.push(...(await reader.getLogs({ ...args, fromBlock: start, toBlock: end })));
78
+ }
79
+ catch (cause) {
80
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.RULE_READ_FAILED, `log scan for ${args.event.name} failed for blocks ${start}-${end}`, { cause });
81
+ }
82
+ }
83
+ return out;
84
+ }
85
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1,17 @@
1
+ /** Internal lossless SVM state shared by public reads and execution. */
2
+ import type { Address, Hex } from 'viem';
3
+ import type { AgenticGeneration } from '../deployments';
4
+ import type { SvmConfigRead } from '../contracts/v6';
5
+ import { type ActiveRule } from './rules';
6
+ import type { Snapshot } from './snapshot';
7
+ export interface SvmRuleSnapshot {
8
+ wallet: Address;
9
+ rulesId: Hex;
10
+ agent: Address;
11
+ chainNamespace: `solana:${string}`;
12
+ configId: Hex;
13
+ config: SvmConfigRead;
14
+ blockNumber: bigint;
15
+ }
16
+ export declare function readSvmRule(snap: Snapshot, gen: AgenticGeneration, wallet: Address, rulesId: Hex, pushChainNamespace: string): Promise<SvmRuleSnapshot>;
17
+ export declare function readSvmConfig(snap: Snapshot, gen: AgenticGeneration, wallet: Address, active: ActiveRule, pushChainNamespace: string): Promise<SvmRuleSnapshot>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readSvmRule = readSvmRule;
4
+ exports.readSvmConfig = readSvmConfig;
5
+ const errors_1 = require("../errors");
6
+ const ids_1 = require("../codec/ids");
7
+ const v6_1 = require("../contracts/v6");
8
+ const svm_terms_1 = require("../codec/svm-terms");
9
+ const rules_1 = require("./rules");
10
+ async function readSvmRule(snap, gen, wallet, rulesId, pushChainNamespace) {
11
+ const active = (await (0, rules_1.readActiveRules)(snap, gen, wallet)).find((r) => r.rulesId.toLowerCase() === rulesId.toLowerCase());
12
+ if (!active)
13
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.RULE_NOT_FOUND, `no enabled SVM rule ${rulesId} on ${wallet}`);
14
+ return readSvmConfig(snap, gen, wallet, active, pushChainNamespace);
15
+ }
16
+ async function readSvmConfig(snap, gen, wallet, active, pushChainNamespace) {
17
+ const chain = (0, rules_1.chainFromHash)(active.chainHash, pushChainNamespace);
18
+ const expectedAction = (0, ids_1.actionId)(gen.addresses.gateway, v6_1.SEND_OUTBOUND_SELECTOR);
19
+ if (active.mode !== 0 ||
20
+ active.vm !== 1 ||
21
+ !chain?.startsWith('solana:') ||
22
+ active.actionIds.length !== 1 ||
23
+ active.actionIds[0].toLowerCase() !== expectedAction.toLowerCase())
24
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INCONSISTENT_READ, 'rule is not a single gateway SVM action');
25
+ const id = (0, ids_1.configId)(wallet, active.rulesId, active.actionIds[0]);
26
+ const cfg = await snap.read(gen.addresses.rulesPolicy, gen.contracts.abis.policy, 'getSvmConfig', [id, wallet]);
27
+ try {
28
+ if (!cfg.initialized)
29
+ throw new Error('uninitialized SVM config');
30
+ // Stored expired rules remain readable. Grant-time validation still checks expiry.
31
+ (0, svm_terms_1.validateSvmTerms)(cfg, -1);
32
+ for (const cap of cfg.assets) {
33
+ if (typeof cap.spent !== 'bigint' ||
34
+ cap.spent < BigInt(0) ||
35
+ cap.spent > cap.maxTotal)
36
+ throw new Error('invalid stored asset counter');
37
+ }
38
+ }
39
+ catch (cause) {
40
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INCONSISTENT_READ, 'malformed stored SVM config', { cause });
41
+ }
42
+ return {
43
+ wallet,
44
+ rulesId: active.rulesId,
45
+ agent: active.agent,
46
+ chainNamespace: chain,
47
+ configId: id,
48
+ config: cfg,
49
+ blockNumber: snap.blockNumber,
50
+ };
51
+ }
52
+ //# sourceMappingURL=svm.js.map
@@ -0,0 +1,25 @@
1
+ import { type Address } from 'viem';
2
+ import type { AgenticGeneration } from '../deployments';
3
+ import type { ChainReader } from '../contracts/reader';
4
+ import type { WalletInfo, WalletSummary } from '../agentic.types';
5
+ import { Snapshot } from './snapshot';
6
+ export declare function walletCount(snap: Snapshot, gen: AgenticGeneration, owner: Address): Promise<bigint>;
7
+ /** client.agentic.derive: default index is the owner's next unused slot. */
8
+ export declare function deriveForOwner(reader: ChainReader, gen: AgenticGeneration, owner: Address, index?: number): Promise<{
9
+ address: Address;
10
+ index: number;
11
+ deployed: boolean;
12
+ }>;
13
+ export declare function rulesCount(snap: Snapshot, gen: AgenticGeneration, wallet: Address): Promise<number>;
14
+ /**
15
+ * client.agentic.list: every deployed slot plus the next undeployed slot
16
+ * (deployed=false, rulesCount=0), as in the spec example.
17
+ */
18
+ export declare function listForOwner(reader: ChainReader, gen: AgenticGeneration, owner: Address): Promise<WalletSummary[]>;
19
+ /** w.owner(): the owner as the wallet stores it. */
20
+ export declare function walletOwner(reader: ChainReader, gen: AgenticGeneration, wallet: Address): Promise<Address>;
21
+ /**
22
+ * w.info(). A deployed wallet is read from chain. An undeployed address is
23
+ * only describable when it is `signerIdentity`'s next predicted slot.
24
+ */
25
+ export declare function walletInfo(reader: ChainReader, gen: AgenticGeneration, wallet: Address, signerIdentity?: Address): Promise<WalletInfo>;