@pushchain/core 6.0.27-alpha.3 → 6.0.27-alpha.5

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 (90) hide show
  1. package/AGW.md +35 -6
  2. package/CHANGELOG.md +13 -0
  3. package/MARKETPLACE.md +206 -0
  4. package/package.json +2 -1
  5. package/src/lib/agentic/codec/rules.js +74 -69
  6. package/src/lib/agentic/codec/universal.js +15 -3
  7. package/src/lib/agentic/constants.d.ts +36 -1
  8. package/src/lib/agentic/constants.js +14 -1
  9. package/src/lib/agentic/contracts/reader.d.ts +21 -0
  10. package/src/lib/agentic/contracts/reader.js +3 -0
  11. package/src/lib/agentic/error-messages.d.ts +3 -0
  12. package/src/lib/agentic/error-messages.js +127 -0
  13. package/src/lib/agentic/errors.d.ts +12 -3
  14. package/src/lib/agentic/errors.js +76 -0
  15. package/src/lib/agentic/management/common.js +6 -0
  16. package/src/lib/agentic/management/destination.d.ts +5 -0
  17. package/src/lib/agentic/management/destination.js +32 -0
  18. package/src/lib/agentic/management/prepare.js +80 -55
  19. package/src/lib/agentic/management/svm-public.js +13 -4
  20. package/src/lib/agentic/presets/index.js +8 -9
  21. package/src/lib/agentic/presets/routes.d.ts +1 -1
  22. package/src/lib/agentic/presets/routes.js +6 -7
  23. package/src/lib/agentic/presets/types.d.ts +1 -6
  24. package/src/lib/agentic/public-rule.js +18 -2
  25. package/src/lib/constants/index.d.ts +35 -0
  26. package/src/lib/index.d.ts +4 -0
  27. package/src/lib/index.js +6 -2
  28. package/src/lib/job/job.d.ts +35 -0
  29. package/src/lib/job/job.js +382 -0
  30. package/src/lib/job/types.d.ts +94 -0
  31. package/src/lib/job/types.js +3 -0
  32. package/src/lib/job/watch.d.ts +3 -0
  33. package/src/lib/job/watch.js +169 -0
  34. package/src/lib/job-spec/codec.d.ts +18 -0
  35. package/src/lib/job-spec/codec.js +348 -0
  36. package/src/lib/job-spec/constants.d.ts +32 -0
  37. package/src/lib/job-spec/constants.js +36 -0
  38. package/src/lib/job-spec/helpers.d.ts +19 -0
  39. package/src/lib/job-spec/helpers.js +138 -0
  40. package/src/lib/job-spec/index.d.ts +14 -0
  41. package/src/lib/job-spec/index.js +17 -0
  42. package/src/lib/job-spec/preview.d.ts +8 -0
  43. package/src/lib/job-spec/preview.js +298 -0
  44. package/src/lib/job-spec/read.d.ts +20 -0
  45. package/src/lib/job-spec/read.js +224 -0
  46. package/src/lib/job-spec/schema.d.ts +290 -0
  47. package/src/lib/job-spec/schema.js +70 -0
  48. package/src/lib/job-spec/types.d.ts +139 -0
  49. package/src/lib/job-spec/types.js +3 -0
  50. package/src/lib/market/contracts/AgenticCommerce.d.ts +1026 -0
  51. package/src/lib/market/contracts/AgenticCommerce.js +1317 -0
  52. package/src/lib/market/contracts/RulesBindingHook.d.ts +235 -0
  53. package/src/lib/market/contracts/RulesBindingHook.js +314 -0
  54. package/src/lib/market/contracts/UniversalMarketplace.d.ts +1770 -0
  55. package/src/lib/market/contracts/UniversalMarketplace.js +2295 -0
  56. package/src/lib/market/contracts/UniversalMarketplaceErrors.d.ts +309 -0
  57. package/src/lib/market/contracts/UniversalMarketplaceErrors.js +416 -0
  58. package/src/lib/market/contracts/UniversalMarketplaceRules.d.ts +241 -0
  59. package/src/lib/market/contracts/UniversalMarketplaceRules.js +323 -0
  60. package/src/lib/market/data.d.ts +8 -0
  61. package/src/lib/market/data.js +60 -0
  62. package/src/lib/market/deployment.d.ts +14 -0
  63. package/src/lib/market/deployment.js +23 -0
  64. package/src/lib/market/deposit.d.ts +24 -0
  65. package/src/lib/market/deposit.js +271 -0
  66. package/src/lib/market/errors.d.ts +13 -0
  67. package/src/lib/market/errors.js +81 -0
  68. package/src/lib/market/history.d.ts +6 -0
  69. package/src/lib/market/history.js +83 -0
  70. package/src/lib/market/index.d.ts +4 -0
  71. package/src/lib/market/index.js +12 -0
  72. package/src/lib/market/kernel-wire.d.ts +15 -0
  73. package/src/lib/market/kernel-wire.js +41 -0
  74. package/src/lib/market/market.d.ts +55 -0
  75. package/src/lib/market/market.js +635 -0
  76. package/src/lib/market/rules.d.ts +106 -0
  77. package/src/lib/market/rules.js +293 -0
  78. package/src/lib/market/runtime.d.ts +35 -0
  79. package/src/lib/market/runtime.js +130 -0
  80. package/src/lib/market/types.d.ts +180 -0
  81. package/src/lib/market/types.js +3 -0
  82. package/src/lib/orchestrator/internals/errors.d.ts +9 -2
  83. package/src/lib/orchestrator/internals/errors.js +9 -2
  84. package/src/lib/orchestrator/internals/push-chain-tx.js +17 -3
  85. package/src/lib/push-chain/push-chain.d.ts +44 -1
  86. package/src/lib/push-chain/push-chain.js +23 -3
  87. package/src/lib/read-state/read-params.d.ts +9 -0
  88. package/src/lib/read-state/read-params.js +5 -1
  89. package/src/lib/utils.d.ts +15 -0
  90. package/src/lib/utils.js +4 -0
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.int256 = int256;
4
+ exports.flattenLogic = flattenLogic;
5
+ exports.buildJobSpec = buildJobSpec;
6
+ exports.buildJobSpecTemplate = buildJobSpecTemplate;
7
+ exports.encodeJobSpec = encodeJobSpec;
8
+ exports.decodeJobSpec = decodeJobSpec;
9
+ const viem_1 = require("viem");
10
+ const errors_1 = require("../market/errors");
11
+ const constants_1 = require("./constants");
12
+ const schema_1 = require("./schema");
13
+ const read_1 = require("./read");
14
+ const originalLogic = new WeakMap();
15
+ const fail = (message, code = 'INVALID_JOB_SPEC') => {
16
+ throw new errors_1.JobSpecError(code, message);
17
+ };
18
+ const fingerprint = (x) => JSON.stringify(x, (_, v) => (typeof v === 'bigint' ? v.toString() : v));
19
+ function int256(value, what = 'Target') {
20
+ if (typeof value !== 'bigint' ||
21
+ value < -(BigInt(1) << BigInt(255)) ||
22
+ value >= BigInt(1) << BigInt(255))
23
+ fail(`${what} must fit int256.`);
24
+ return value;
25
+ }
26
+ function count(values, max, what, min = 1) {
27
+ if (!Array.isArray(values) || values.length < min || values.length > max)
28
+ fail(`${what} must contain ${min}..${max} entries.`, `TOO_MANY_${what.toUpperCase()}`);
29
+ }
30
+ function timestamp(n) {
31
+ if (!Number.isSafeInteger(n) || n < 0)
32
+ fail('Timestamps must be nonnegative safe integers.');
33
+ }
34
+ function enumIndex(values, value, name) {
35
+ const i = values.indexOf(value);
36
+ if (i < 0)
37
+ fail(`Unknown ${name}.`);
38
+ return i;
39
+ }
40
+ function flattenLogic(tree, checkCount) {
41
+ const nodes = [];
42
+ const active = new Set();
43
+ function visit(t) {
44
+ if (!t || active.has(t) || nodes.length >= 32)
45
+ fail('Logic is cyclic or exceeds 32 operators.', 'BAD_TREE');
46
+ active.add(t);
47
+ const index = nodes.length;
48
+ const kind = enumIndex(constants_1.LOGIC_KINDS, t.kind, 'logic kind');
49
+ if (!Array.isArray(t.of) || !t.of.length || t.of.length > 255)
50
+ fail('Logic operators need 1..255 operands.', 'BAD_TREE');
51
+ const k = t.kind === 'AT_LEAST' ? t.k ?? 0 : 0;
52
+ if (!Number.isInteger(k) ||
53
+ (t.kind === 'AT_LEAST' && (k < 1 || k > t.of.length)) ||
54
+ (t.kind !== 'AT_LEAST' && t.k !== undefined && t.k !== 0))
55
+ fail('Invalid AT_LEAST threshold.', 'BAD_TREE');
56
+ const n = { kind, checks: [], children: [], k: k };
57
+ nodes.push(n);
58
+ for (const item of t.of) {
59
+ if (typeof item === 'number') {
60
+ if (!Number.isInteger(item) ||
61
+ item < 0 ||
62
+ item >= checkCount ||
63
+ n.checks.includes(item))
64
+ fail('Dangling or duplicated check index.', 'BAD_TREE');
65
+ n.checks.push(item);
66
+ }
67
+ else
68
+ n.children.push(visit(item));
69
+ }
70
+ active.delete(t);
71
+ return index;
72
+ }
73
+ visit(tree);
74
+ const saved = originalLogic.get(tree);
75
+ return saved?.fingerprint === fingerprint(tree) ? saved.wire : nodes;
76
+ }
77
+ function nestLogic(nodes, checkCount) {
78
+ count(nodes, 32, 'logic');
79
+ const reached = new Set();
80
+ let expanded = 0;
81
+ function visit(index, depth) {
82
+ if (++expanded > 512 || depth > 32)
83
+ fail('Stored logic is too large to describe as a tree.', 'BAD_TREE');
84
+ const n = nodes[index];
85
+ if (!n || !constants_1.LOGIC_KINDS[n.kind])
86
+ fail('Unknown stored logic kind.', 'BAD_TREE');
87
+ reached.add(index);
88
+ if (n.checks.some((i) => !Number.isInteger(i) || i < 0 || i >= checkCount) ||
89
+ new Set(n.checks).size !== n.checks.length)
90
+ fail('Invalid stored check reference.', 'BAD_TREE');
91
+ if (n.children.some((i) => i <= index || i >= nodes.length) ||
92
+ new Set(n.children).size !== n.children.length)
93
+ fail('Invalid stored child reference.', 'BAD_TREE');
94
+ const t = {
95
+ kind: constants_1.LOGIC_KINDS[n.kind],
96
+ of: [...n.checks, ...n.children.map((i) => visit(i, depth + 1))],
97
+ ...(n.kind === 2 ? { k: n.k } : {}),
98
+ };
99
+ if (n.kind !== 2 && n.k !== 0)
100
+ fail('Unexpected threshold on stored logic.', 'BAD_TREE');
101
+ return t;
102
+ }
103
+ const tree = visit(0, 0);
104
+ if (reached.size !== nodes.length)
105
+ fail('Stored logic has unreachable operators.', 'BAD_TREE');
106
+ // Preserve an unchanged, valid topological order instead of rewriting signed bytes.
107
+ originalLogic.set(tree, { fingerprint: fingerprint(tree), wire: nodes });
108
+ flattenLogic(tree, checkCount);
109
+ return tree;
110
+ }
111
+ function normalizeReads(values) {
112
+ count(values, 16, 'reads');
113
+ return values.map((input) => {
114
+ const wrapper = input;
115
+ const source = 'read' in input ? wrapper.read : input;
116
+ const read = {
117
+ ...source,
118
+ field: [...(wrapper.field ?? [0])],
119
+ minConfirmations: wrapper.minConfirmations ?? 1,
120
+ ...(source.fills ? { fills: source.fills.map((f) => ({ ...f })) } : {}),
121
+ };
122
+ (0, read_1.inheritReadLabel)(source, read);
123
+ return read;
124
+ });
125
+ }
126
+ function validate(spec) {
127
+ count(spec.reads, 16, 'reads');
128
+ count(spec.checks, 16, 'checks');
129
+ enumIndex(constants_1.MUTABILITIES, spec.allowedMutability, 'allowedMutability');
130
+ const template = 'params' in spec;
131
+ if (template) {
132
+ count(spec.params, 16, 'params', 0);
133
+ for (const p of spec.params)
134
+ if (int256(p.min) > int256(p.max))
135
+ fail('Parameter minimum exceeds its maximum.');
136
+ }
137
+ else {
138
+ timestamp(spec.executeBy);
139
+ timestamp(spec.failFinalAt);
140
+ if (spec.failFinalAt <= spec.executeBy ||
141
+ !/^0x[\da-f]{64}$/i.test(spec.origin))
142
+ fail('Invalid JobSpec timing or origin.');
143
+ }
144
+ for (const r of spec.reads) {
145
+ (0, read_1.validateJobRead)(r);
146
+ if (!Number.isInteger(r.minConfirmations) ||
147
+ r.minConfirmations < 1 ||
148
+ r.minConfirmations > 65535)
149
+ fail('Read confirmations must be 1..65535.');
150
+ const words = new Set();
151
+ for (const f of r.fills ?? []) {
152
+ if (!template)
153
+ fail('A complete JobSpec cannot contain placeholders.', 'UNFILLED_PLACEHOLDER');
154
+ if (!Number.isInteger(f.word) ||
155
+ f.word < 0 ||
156
+ f.word > 255 ||
157
+ f.word * 32 + 32 > (r.args.length - 2) / 2 ||
158
+ words.has(f.word))
159
+ fail('Invalid or duplicate fill word.');
160
+ words.add(f.word);
161
+ if (!['WALLET', 'PARAM'].includes(f.source))
162
+ fail('Unknown fill source.');
163
+ if (f.source === 'PARAM' &&
164
+ (!Number.isInteger(f.param) ||
165
+ (f.param ?? -1) < 0 ||
166
+ (f.param ?? -1) >= spec.params.length))
167
+ fail('Fill parameter is out of range.');
168
+ }
169
+ }
170
+ for (const c of spec.checks) {
171
+ if (!Number.isInteger(c.read) || c.read < 0 || c.read >= spec.reads.length)
172
+ fail('Check read index is out of range.');
173
+ enumIndex(constants_1.EVALUATIONS, c.evaluation, 'evaluation');
174
+ enumIndex(constants_1.OPERATIONS, c.operation, 'operation');
175
+ if (c.evaluation === 'BOOLEAN' && c.operation !== 'EQUAL')
176
+ fail('BOOLEAN checks use EQUAL.');
177
+ if (typeof c.target === 'bigint')
178
+ int256(c.target);
179
+ else if (!template)
180
+ fail('Complete JobSpec targets must be resolved integers.', 'UNFILLED_PLACEHOLDER');
181
+ else
182
+ targetWire(c.target, spec.params.length);
183
+ }
184
+ flattenLogic(spec.logic, spec.checks.length);
185
+ }
186
+ function targetWire(target, params) {
187
+ if (typeof target === 'bigint')
188
+ return { source: 0, value: int256(target) };
189
+ if (target === constants_1.PRINCIPAL)
190
+ return { source: 1, value: BigInt(10000) };
191
+ if (target === 'agentic:wallet')
192
+ return { source: 3, value: BigInt(0) };
193
+ if (target && typeof target === 'object' && 'principalBps' in target) {
194
+ if (int256(target.principalBps) <= BigInt(0))
195
+ fail('principalBps must be positive.');
196
+ return { source: 1, value: target.principalBps };
197
+ }
198
+ if (target &&
199
+ typeof target === 'object' &&
200
+ 'param' in target &&
201
+ Number.isInteger(target.param) &&
202
+ target.param >= 0 &&
203
+ target.param < params)
204
+ return { source: 2, value: BigInt(target.param) };
205
+ return fail('Unknown or out-of-range template target.');
206
+ }
207
+ function buildJobSpec(options) {
208
+ const spec = {
209
+ reads: normalizeReads(options.reads),
210
+ checks: options.checks.map((c) => ({ ...c })),
211
+ logic: typeof options.logic === 'string'
212
+ ? { kind: options.logic, of: options.checks.map((_, i) => i) }
213
+ : options.logic,
214
+ allowedMutability: options.allowedMutability ?? 'NONE',
215
+ origin: options.origin ?? viem_1.zeroHash,
216
+ executeBy: options.executeBy,
217
+ failFinalAt: options.failFinalAt,
218
+ };
219
+ validate(spec);
220
+ if (options.expiredAt !== undefined) {
221
+ timestamp(options.expiredAt);
222
+ if (options.failFinalAt >= options.expiredAt)
223
+ fail('failFinalAt must precede job expiry.', 'FAIL_WINDOW_THIN');
224
+ }
225
+ return spec;
226
+ }
227
+ function buildJobSpecTemplate(options) {
228
+ const t = {
229
+ reads: normalizeReads(options.reads),
230
+ checks: options.checks.map((c) => ({ ...c })),
231
+ logic: typeof options.logic === 'string'
232
+ ? { kind: options.logic, of: options.checks.map((_, i) => i) }
233
+ : options.logic,
234
+ allowedMutability: options.allowedMutability ?? 'NONE',
235
+ params: (options.params ?? []).map((p) => ({ ...p })),
236
+ };
237
+ validate(t);
238
+ return t;
239
+ }
240
+ function encodeJobSpec(spec) {
241
+ validate(spec);
242
+ const base = {
243
+ reads: spec.reads.map(({ fills, ...r }) => 'params' in spec
244
+ ? {
245
+ ...r,
246
+ fills: (fills ?? []).map((f) => ({
247
+ word: f.word,
248
+ source: f.source === 'WALLET' ? 0 : 1,
249
+ param: f.param ?? 0,
250
+ })),
251
+ }
252
+ : r),
253
+ logic: flattenLogic(spec.logic, spec.checks.length),
254
+ allowedMutability: constants_1.MUTABILITIES.indexOf(spec.allowedMutability),
255
+ };
256
+ const checks = spec.checks.map((c) => ({
257
+ read: c.read,
258
+ evaluation: constants_1.EVALUATIONS.indexOf(c.evaluation),
259
+ operation: constants_1.OPERATIONS.indexOf(c.operation),
260
+ ...('params' in spec
261
+ ? targetWire(c.target, spec.params.length)
262
+ : { target: c.target }),
263
+ }));
264
+ const value = 'params' in spec
265
+ ? { ...base, checks, params: spec.params }
266
+ : {
267
+ ...base,
268
+ checks,
269
+ origin: spec.origin,
270
+ executeBy: BigInt(spec.executeBy),
271
+ failFinalAt: BigInt(spec.failFinalAt),
272
+ };
273
+ return (0, viem_1.encodeAbiParameters)([('params' in spec ? schema_1.JOB_TEMPLATE_PARAM : schema_1.JOB_SPEC_PARAM)], [value]);
274
+ }
275
+ /** Known callers pass the format; inference requires one canonical validated decode. */
276
+ function decodeJobSpec(bytes, options) {
277
+ if (!(0, viem_1.isHex)(bytes) || bytes.length > 524290)
278
+ fail('Invalid or oversized JobSpec encoding.');
279
+ const valid = [];
280
+ for (const template of options?.format
281
+ ? [options.format === 'template']
282
+ : [false, true]) {
283
+ try {
284
+ const w = (0, viem_1.decodeAbiParameters)([(template ? schema_1.JOB_TEMPLATE_PARAM : schema_1.JOB_SPEC_PARAM)], bytes)[0];
285
+ const reads = w.reads.map(({ fills: rawFills, ...r }) => ({
286
+ ...r,
287
+ ...(template
288
+ ? {
289
+ fills: (rawFills ?? []).map((f) => {
290
+ if (f.source > 1 || (f.source === 0 && f.param !== 0))
291
+ fail('Invalid stored fill.');
292
+ return {
293
+ word: f.word,
294
+ source: f.source === 0 ? 'WALLET' : 'PARAM',
295
+ ...(f.source === 1 ? { param: f.param } : {}),
296
+ };
297
+ }),
298
+ }
299
+ : {}),
300
+ }));
301
+ const checks = w.checks.map((c) => {
302
+ const common = {
303
+ read: c.read,
304
+ evaluation: constants_1.EVALUATIONS[c.evaluation],
305
+ operation: constants_1.OPERATIONS[c.operation],
306
+ };
307
+ if (!template)
308
+ return { ...common, target: c.target };
309
+ const t = c;
310
+ const target = t.source === 0
311
+ ? t.value
312
+ : t.source === 1
313
+ ? t.value === BigInt(10000)
314
+ ? constants_1.PRINCIPAL
315
+ : { principalBps: t.value }
316
+ : t.source === 2
317
+ ? { param: Number(t.value) }
318
+ : t.source === 3 && t.value === BigInt(0)
319
+ ? 'agentic:wallet'
320
+ : fail('Unknown template target.');
321
+ return { ...common, target };
322
+ });
323
+ const common = {
324
+ reads,
325
+ checks,
326
+ logic: nestLogic(w.logic, checks.length),
327
+ allowedMutability: constants_1.MUTABILITIES[w.allowedMutability],
328
+ };
329
+ const spec = (template
330
+ ? { ...common, params: w.params }
331
+ : {
332
+ ...common,
333
+ origin: w.origin,
334
+ executeBy: Number(w.executeBy),
335
+ failFinalAt: Number(w.failFinalAt),
336
+ });
337
+ if (encodeJobSpec(spec).toLowerCase() === bytes.toLowerCase())
338
+ valid.push(spec);
339
+ }
340
+ catch {
341
+ /* Wrong shape, unsupported wire, malformed enums or noncanonical bytes. */
342
+ }
343
+ }
344
+ if (valid.length !== 1)
345
+ fail('The bytes do not identify one supported canonical deployed-v2 JobSpec format.', 'UNSUPPORTED_JOB_SPEC');
346
+ return valid[0];
347
+ }
348
+ //# sourceMappingURL=codec.js.map
@@ -0,0 +1,32 @@
1
+ export declare const JOB_VOCABULARY: Readonly<{
2
+ EVALUATION: Readonly<{
3
+ readonly BOOLEAN: "BOOLEAN";
4
+ readonly COMPARE: "COMPARE";
5
+ readonly NUMBER: "NUMBER";
6
+ readonly PERCENTAGE: "PERCENTAGE";
7
+ }>;
8
+ OPERATION: Readonly<{
9
+ readonly EQUAL: "EQUAL";
10
+ readonly NOT_EQUAL: "NOT_EQUAL";
11
+ readonly GREATER_THAN: "GREATER_THAN";
12
+ readonly GREATER_OR_EQUAL: "GREATER_OR_EQUAL";
13
+ readonly LESS_THAN: "LESS_THAN";
14
+ readonly LESS_OR_EQUAL: "LESS_OR_EQUAL";
15
+ }>;
16
+ LOGIC: Readonly<{
17
+ readonly ALL: "ALL";
18
+ readonly ANY: "ANY";
19
+ readonly AT_LEAST: "AT_LEAST";
20
+ }>;
21
+ ALLOWED_MUTABILITY: Readonly<{
22
+ readonly NONE: "NONE";
23
+ readonly CLIENT: "CLIENT";
24
+ readonly PROVIDER: "PROVIDER";
25
+ readonly BOTH: "BOTH";
26
+ }>;
27
+ }>;
28
+ export declare const PRINCIPAL: "agentic:principal";
29
+ export declare const EVALUATIONS: ("BOOLEAN" | "COMPARE" | "NUMBER" | "PERCENTAGE")[];
30
+ export declare const OPERATIONS: ("EQUAL" | "NOT_EQUAL" | "GREATER_THAN" | "GREATER_OR_EQUAL" | "LESS_THAN" | "LESS_OR_EQUAL")[];
31
+ export declare const LOGIC_KINDS: ("ALL" | "ANY" | "AT_LEAST")[];
32
+ export declare const MUTABILITIES: ("NONE" | "CLIENT" | "PROVIDER" | "BOTH")[];
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MUTABILITIES = exports.LOGIC_KINDS = exports.OPERATIONS = exports.EVALUATIONS = exports.PRINCIPAL = exports.JOB_VOCABULARY = void 0;
4
+ exports.JOB_VOCABULARY = Object.freeze({
5
+ EVALUATION: Object.freeze({
6
+ BOOLEAN: 'BOOLEAN',
7
+ COMPARE: 'COMPARE',
8
+ NUMBER: 'NUMBER',
9
+ PERCENTAGE: 'PERCENTAGE',
10
+ }),
11
+ OPERATION: Object.freeze({
12
+ EQUAL: 'EQUAL',
13
+ NOT_EQUAL: 'NOT_EQUAL',
14
+ GREATER_THAN: 'GREATER_THAN',
15
+ GREATER_OR_EQUAL: 'GREATER_OR_EQUAL',
16
+ LESS_THAN: 'LESS_THAN',
17
+ LESS_OR_EQUAL: 'LESS_OR_EQUAL',
18
+ }),
19
+ LOGIC: Object.freeze({
20
+ ALL: 'ALL',
21
+ ANY: 'ANY',
22
+ AT_LEAST: 'AT_LEAST',
23
+ }),
24
+ ALLOWED_MUTABILITY: Object.freeze({
25
+ NONE: 'NONE',
26
+ CLIENT: 'CLIENT',
27
+ PROVIDER: 'PROVIDER',
28
+ BOTH: 'BOTH',
29
+ }),
30
+ });
31
+ exports.PRINCIPAL = 'agentic:principal';
32
+ exports.EVALUATIONS = Object.values(exports.JOB_VOCABULARY.EVALUATION);
33
+ exports.OPERATIONS = Object.values(exports.JOB_VOCABULARY.OPERATION);
34
+ exports.LOGIC_KINDS = Object.values(exports.JOB_VOCABULARY.LOGIC);
35
+ exports.MUTABILITIES = Object.values(exports.JOB_VOCABULARY.ALLOWED_MUTABILITY);
36
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,19 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import type { JobSpec, JobSpecTemplate } from './types';
3
+ export declare function resolveJobSpec(template: JobSpecTemplate, ctx: {
4
+ principal: bigint;
5
+ params: bigint[];
6
+ accounts: Record<string, Address>;
7
+ origin: Hex;
8
+ executeBy: number;
9
+ settleWindow: number;
10
+ }): JobSpec;
11
+ export declare function describeJobSpec(spec: JobSpec | JobSpecTemplate, options?: {
12
+ principal?: bigint;
13
+ decimals?: Record<Address, number>;
14
+ }): {
15
+ checks: string[];
16
+ logic: string;
17
+ timing: string;
18
+ };
19
+ export declare function specOrigin(marketplace: Address, cardId: bigint, version: bigint, principal: bigint): Hex;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveJobSpec = resolveJobSpec;
4
+ exports.describeJobSpec = describeJobSpec;
5
+ exports.specOrigin = specOrigin;
6
+ const viem_1 = require("viem");
7
+ const codec_1 = require("./codec");
8
+ const constants_1 = require("./constants");
9
+ const errors_1 = require("../market/errors");
10
+ const read_1 = require("./read");
11
+ function resolveJobSpec(template, ctx) {
12
+ (0, codec_1.encodeJobSpec)(template);
13
+ if (ctx.params.length !== template.params.length ||
14
+ ctx.params.some((n, i) => (0, codec_1.int256)(n) < template.params[i].min || n > template.params[i].max))
15
+ throw new errors_1.JobSpecError('PARAM_OUT_OF_RANGE', 'The job parameters do not match the template bounds.');
16
+ const account = (read) => {
17
+ const r = template.reads[read];
18
+ const a = ctx.accounts[`${r.chainNamespace}:${r.chainId}`];
19
+ if (!a)
20
+ throw new errors_1.JobSpecError('UNFILLED_PLACEHOLDER', 'Resolve the wallet account on every read chain.');
21
+ return (0, viem_1.getAddress)(a);
22
+ };
23
+ const reads = template.reads.map((r, i) => {
24
+ let args = r.args;
25
+ for (const f of r.fills ?? []) {
26
+ const value = f.source === 'WALLET'
27
+ ? BigInt(account(i))
28
+ : BigInt.asUintN(256, ctx.params[f.param ?? 0]);
29
+ const at = 2 + f.word * 64;
30
+ args = (args.slice(0, at) +
31
+ (0, viem_1.toHex)(value, { size: 32 }).slice(2) +
32
+ args.slice(at + 64));
33
+ }
34
+ const read = { ...r };
35
+ delete read.fills;
36
+ const resolved = { ...read, args };
37
+ (0, read_1.inheritReadLabel)(r, resolved);
38
+ return resolved;
39
+ });
40
+ const checks = template.checks.map((c) => {
41
+ const t = c.target;
42
+ const target = typeof t === 'bigint'
43
+ ? t
44
+ : t === constants_1.PRINCIPAL
45
+ ? ctx.principal
46
+ : t === 'agentic:wallet'
47
+ ? BigInt(account(c.read))
48
+ : 'param' in t
49
+ ? ctx.params[t.param]
50
+ : (() => {
51
+ const product = ctx.principal * t.principalBps;
52
+ if (product >= BigInt(1) << BigInt(256))
53
+ throw new errors_1.JobSpecError('TARGET_OVERFLOW', 'The principal-based target overflows uint256.');
54
+ return product / BigInt(10000);
55
+ })();
56
+ return { ...c, target: (0, codec_1.int256)(target) };
57
+ });
58
+ const spec = {
59
+ reads,
60
+ checks,
61
+ logic: template.logic,
62
+ allowedMutability: template.allowedMutability,
63
+ origin: ctx.origin,
64
+ executeBy: ctx.executeBy,
65
+ failFinalAt: ctx.executeBy + ctx.settleWindow,
66
+ };
67
+ (0, codec_1.encodeJobSpec)(spec);
68
+ return spec;
69
+ }
70
+ const words = {
71
+ EQUAL: 'equals',
72
+ NOT_EQUAL: 'does not equal',
73
+ GREATER_THAN: 'is greater than',
74
+ GREATER_OR_EQUAL: 'is at least',
75
+ LESS_THAN: 'is less than',
76
+ LESS_OR_EQUAL: 'is at most',
77
+ };
78
+ function describeJobSpec(spec, options) {
79
+ (0, codec_1.encodeJobSpec)(spec);
80
+ if (options?.principal !== undefined && (0, codec_1.int256)(options.principal) < BigInt(0))
81
+ throw new errors_1.JobSpecError('INVALID_DESCRIPTION_OPTIONS', 'Principal must be nonnegative.');
82
+ const decimals = new Map();
83
+ for (const [address, value] of Object.entries(options?.decimals ?? {})) {
84
+ if (!Number.isInteger(value) || value < 0 || value > 255)
85
+ throw new errors_1.JobSpecError('INVALID_DESCRIPTION_OPTIONS', 'Token decimals must be integers from 0 to 255.');
86
+ try {
87
+ decimals.set((0, viem_1.getAddress)(address).toLowerCase(), value);
88
+ }
89
+ catch (cause) {
90
+ throw new errors_1.JobSpecError('INVALID_DESCRIPTION_OPTIONS', 'Decimals must be keyed by token address.', undefined, cause);
91
+ }
92
+ }
93
+ function logic(t) {
94
+ return `${t.kind === 'ALL' ? 'All' : t.kind === 'ANY' ? 'Any' : `At least ${t.k}`} of (${t.of
95
+ .map((x) => (typeof x === 'number' ? `check ${x + 1}` : logic(x)))
96
+ .join(', ')})`;
97
+ }
98
+ return {
99
+ checks: spec.checks.map((c) => {
100
+ const r = spec.reads[c.read];
101
+ const t = c.target;
102
+ const resolvedTarget = typeof t === 'bigint'
103
+ ? t
104
+ : t === constants_1.PRINCIPAL
105
+ ? options?.principal ?? 'principal'
106
+ : t === 'agentic:wallet'
107
+ ? 'the wallet on this chain'
108
+ : 'param' in t
109
+ ? `parameter ${t.param + 1}`
110
+ : options?.principal !== undefined
111
+ ? (options.principal * t.principalBps) / BigInt(10000)
112
+ : `${t.principalBps} basis points of principal`;
113
+ const precision = decimals.get(r.target.toLowerCase());
114
+ const target = typeof resolvedTarget === 'bigint'
115
+ ? c.evaluation === 'PERCENTAGE'
116
+ ? `${(0, viem_1.formatUnits)(resolvedTarget, 2)}% (${resolvedTarget} bps)`
117
+ : precision !== undefined && c.evaluation !== 'BOOLEAN'
118
+ ? `${(0, viem_1.formatUnits)(resolvedTarget, precision)} (${resolvedTarget} raw units; ${precision} decimals)`
119
+ : `${resolvedTarget} (raw units)`
120
+ : `${resolvedTarget}${c.evaluation === 'PERCENTAGE' ? ' bps' : ' (raw units)'}`;
121
+ const name = (0, read_1.jobReadLabel)(r);
122
+ return `Read ${c.read + 1}: ${r.target} ${name ? name + ' ' : ''}${r.selector} on ${r.chainNamespace}:${r.chainId}, field [${r.field.join(',')}], ${c.evaluation} ${words[c.operation]} ${target}.`;
123
+ }),
124
+ logic: logic(spec.logic),
125
+ timing: 'executeBy' in spec
126
+ ? `Execute by ${new Date(spec.executeBy * 1000).toISOString()}; failure is final after ${new Date(spec.failFinalAt * 1000).toISOString()}.`
127
+ : '',
128
+ };
129
+ }
130
+ function specOrigin(marketplace, cardId, version, principal) {
131
+ // Imported here to keep the public helpers independent of client state.
132
+ return (0, viem_1.keccak256)(('0x' +
133
+ [
134
+ marketplace.slice(2).padStart(64, '0'),
135
+ ...[cardId, version, principal].map((n) => (0, viem_1.toHex)(n, { size: 32 }).slice(2)),
136
+ ].join('')));
137
+ }
138
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1,14 @@
1
+ import { buildJobSpec, buildJobSpecTemplate, encodeJobSpec, decodeJobSpec } from './codec';
2
+ import { describeJobSpec } from './helpers';
3
+ import { prepareJobRead } from './read';
4
+ import { previewJobSpec } from './preview';
5
+ export declare const jobSpecUtils: Readonly<{
6
+ buildJobSpec: typeof buildJobSpec;
7
+ buildJobSpecTemplate: typeof buildJobSpecTemplate;
8
+ encodeJobSpec: typeof encodeJobSpec;
9
+ decodeJobSpec: typeof decodeJobSpec;
10
+ describeJobSpec: typeof describeJobSpec;
11
+ prepareRead: typeof prepareJobRead;
12
+ previewJobSpec: typeof previewJobSpec;
13
+ }>;
14
+ export type * from './types';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jobSpecUtils = void 0;
4
+ const codec_1 = require("./codec");
5
+ const helpers_1 = require("./helpers");
6
+ const read_1 = require("./read");
7
+ const preview_1 = require("./preview");
8
+ exports.jobSpecUtils = Object.freeze({
9
+ buildJobSpec: codec_1.buildJobSpec,
10
+ buildJobSpecTemplate: codec_1.buildJobSpecTemplate,
11
+ encodeJobSpec: codec_1.encodeJobSpec,
12
+ decodeJobSpec: codec_1.decodeJobSpec,
13
+ describeJobSpec: helpers_1.describeJobSpec,
14
+ prepareRead: read_1.prepareJobRead,
15
+ previewJobSpec: preview_1.previewJobSpec,
16
+ });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,8 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import type { CHAIN } from '../constants/enums';
3
+ import type { JobRead, JobSpec, JobSpecTemplate, JobSpecPreview, PreviewJobSpecOptions } from './types';
4
+ /** @internal Bind the real client's configured CEA resolver without exposing its runtime. */
5
+ export declare function bindJobPreviewAccounts(universal: object, resolve: (wallet: Address, chain: CHAIN) => Promise<Address>): void;
6
+ /** Follow the deployed V2 type codes; uint values above int256.max cannot be compared. */
7
+ export declare function decodeJobAnswer(read: JobRead, data: Hex): bigint;
8
+ export declare function previewJobSpec(subject: JobSpec | JobSpecTemplate, options: PreviewJobSpecOptions): Promise<JobSpecPreview>;