@pushchain/core 6.0.27-alpha.2 → 6.0.27-alpha.4

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 (99) hide show
  1. package/AGW.md +83 -7
  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/prc20-metadata.d.ts +1 -1
  10. package/src/lib/agentic/contracts/prc20-metadata.js +11 -5
  11. package/src/lib/agentic/contracts/reader.d.ts +21 -0
  12. package/src/lib/agentic/contracts/reader.js +3 -0
  13. package/src/lib/agentic/error-messages.d.ts +3 -0
  14. package/src/lib/agentic/error-messages.js +125 -0
  15. package/src/lib/agentic/errors.d.ts +12 -3
  16. package/src/lib/agentic/errors.js +76 -0
  17. package/src/lib/agentic/management/common.js +6 -0
  18. package/src/lib/agentic/management/destination.d.ts +5 -0
  19. package/src/lib/agentic/management/destination.js +32 -0
  20. package/src/lib/agentic/management/prepare.js +80 -55
  21. package/src/lib/agentic/management/svm-public.js +13 -4
  22. package/src/lib/agentic/presets/catalog.d.ts +2 -0
  23. package/src/lib/agentic/presets/catalog.js +9 -0
  24. package/src/lib/agentic/presets/default-policy.d.ts +9 -0
  25. package/src/lib/agentic/presets/default-policy.js +85 -0
  26. package/src/lib/agentic/presets/default-tokens.d.ts +4 -0
  27. package/src/lib/agentic/presets/default-tokens.js +39 -0
  28. package/src/lib/agentic/presets/index.js +47 -22
  29. package/src/lib/agentic/presets/routes.d.ts +9 -0
  30. package/src/lib/agentic/presets/routes.js +50 -0
  31. package/src/lib/agentic/presets/types.d.ts +24 -8
  32. package/src/lib/agentic/public-rule.js +13 -2
  33. package/src/lib/constants/index.d.ts +35 -0
  34. package/src/lib/index.d.ts +4 -0
  35. package/src/lib/index.js +6 -2
  36. package/src/lib/job/job.d.ts +35 -0
  37. package/src/lib/job/job.js +382 -0
  38. package/src/lib/job/types.d.ts +94 -0
  39. package/src/lib/job/types.js +3 -0
  40. package/src/lib/job/watch.d.ts +3 -0
  41. package/src/lib/job/watch.js +169 -0
  42. package/src/lib/job-spec/codec.d.ts +18 -0
  43. package/src/lib/job-spec/codec.js +348 -0
  44. package/src/lib/job-spec/constants.d.ts +32 -0
  45. package/src/lib/job-spec/constants.js +36 -0
  46. package/src/lib/job-spec/helpers.d.ts +19 -0
  47. package/src/lib/job-spec/helpers.js +138 -0
  48. package/src/lib/job-spec/index.d.ts +14 -0
  49. package/src/lib/job-spec/index.js +17 -0
  50. package/src/lib/job-spec/preview.d.ts +8 -0
  51. package/src/lib/job-spec/preview.js +298 -0
  52. package/src/lib/job-spec/read.d.ts +20 -0
  53. package/src/lib/job-spec/read.js +224 -0
  54. package/src/lib/job-spec/schema.d.ts +290 -0
  55. package/src/lib/job-spec/schema.js +70 -0
  56. package/src/lib/job-spec/types.d.ts +139 -0
  57. package/src/lib/job-spec/types.js +3 -0
  58. package/src/lib/market/contracts/AgenticCommerce.d.ts +1026 -0
  59. package/src/lib/market/contracts/AgenticCommerce.js +1317 -0
  60. package/src/lib/market/contracts/RulesBindingHook.d.ts +235 -0
  61. package/src/lib/market/contracts/RulesBindingHook.js +314 -0
  62. package/src/lib/market/contracts/UniversalMarketplace.d.ts +1770 -0
  63. package/src/lib/market/contracts/UniversalMarketplace.js +2295 -0
  64. package/src/lib/market/contracts/UniversalMarketplaceErrors.d.ts +309 -0
  65. package/src/lib/market/contracts/UniversalMarketplaceErrors.js +416 -0
  66. package/src/lib/market/contracts/UniversalMarketplaceRules.d.ts +241 -0
  67. package/src/lib/market/contracts/UniversalMarketplaceRules.js +323 -0
  68. package/src/lib/market/data.d.ts +8 -0
  69. package/src/lib/market/data.js +60 -0
  70. package/src/lib/market/deployment.d.ts +14 -0
  71. package/src/lib/market/deployment.js +23 -0
  72. package/src/lib/market/deposit.d.ts +24 -0
  73. package/src/lib/market/deposit.js +271 -0
  74. package/src/lib/market/errors.d.ts +13 -0
  75. package/src/lib/market/errors.js +81 -0
  76. package/src/lib/market/history.d.ts +6 -0
  77. package/src/lib/market/history.js +83 -0
  78. package/src/lib/market/index.d.ts +4 -0
  79. package/src/lib/market/index.js +12 -0
  80. package/src/lib/market/kernel-wire.d.ts +15 -0
  81. package/src/lib/market/kernel-wire.js +41 -0
  82. package/src/lib/market/market.d.ts +55 -0
  83. package/src/lib/market/market.js +635 -0
  84. package/src/lib/market/rules.d.ts +106 -0
  85. package/src/lib/market/rules.js +293 -0
  86. package/src/lib/market/runtime.d.ts +35 -0
  87. package/src/lib/market/runtime.js +130 -0
  88. package/src/lib/market/types.d.ts +180 -0
  89. package/src/lib/market/types.js +3 -0
  90. package/src/lib/orchestrator/internals/errors.d.ts +9 -2
  91. package/src/lib/orchestrator/internals/errors.js +9 -2
  92. package/src/lib/orchestrator/internals/push-chain-tx.js +17 -3
  93. package/src/lib/push-chain/push-chain.d.ts +44 -1
  94. package/src/lib/push-chain/push-chain.js +23 -3
  95. package/src/lib/read-state/read-params.d.ts +9 -0
  96. package/src/lib/read-state/read-params.js +5 -1
  97. package/src/lib/universal/prc20-address.js +18 -4
  98. package/src/lib/utils.d.ts +15 -0
  99. package/src/lib/utils.js +4 -0
@@ -1,4 +1,5 @@
1
1
  import type { Address } from 'viem';
2
+ import type { PUSH_NETWORK } from '../../constants/enums';
2
3
  import type { Rule, RuleAsset, RuleCall, ForeignChainNamespace } from '../agentic.types';
3
4
  export type PresetCategory = 'DEXES' | 'LENDING' | 'STAKING' | 'PREDICTION';
4
5
  export interface Preset {
@@ -7,7 +8,7 @@ export interface Preset {
7
8
  name: string;
8
9
  chains: ForeignChainNamespace[];
9
10
  }
10
- /** An editable review-screen template; both identity and expiry are required by create. */
11
+ /** Presets generate expiry; optional fields retain editable-template compatibility. */
11
12
  export type PresetRuleTemplate = Omit<Rule, 'agent' | 'validUntil'> & {
12
13
  agent?: Address;
13
14
  validUntil?: number;
@@ -22,23 +23,29 @@ export interface PresetAsset {
22
23
  maxTotal?: bigint;
23
24
  }
24
25
  export interface PresetOptions {
25
- /** Explicit Push-PC gas budget per outbound; omitted = zero. */
26
+ /** Offline route/deployment checks; defaults to TESTNET_DONUT. */
27
+ network?: PUSH_NETWORK;
28
+ /** Push-PC budget ceiling per outbound; omitted uses the catalog policy (20 PC).
29
+ * Explicit zero is preserved. This is not the fee charged. */
26
30
  maxGasPerCall?: bigint;
27
31
  chainNamespace?: ForeignChainNamespace;
28
32
  agent?: Address;
33
+ /** Omitted: seven days from generation time. Explicit expiry is preserved. */
29
34
  validUntil?: number;
30
- /** DEX swaps with fewer than two tokens are zero-input-cap review templates.
31
- * Call get again with a complete pair to generate token pins and amount limits. */
35
+ /** Omitted: include the catalog's curated tokens and explicit spending policy.
36
+ * An explicit array replaces all defaults (including [] to select no tokens).
37
+ * Supplied assets retain zero for omitted caps; no policy is guessed for them.
38
+ * DEX swaps with fewer than two tokens remain zero-input-cap review templates. */
32
39
  assets?: PresetAsset[];
33
40
  }
34
41
  export interface ReadyPresetOptions extends PresetOptions {
35
42
  agent: Address;
36
- validUntil: number;
37
43
  }
38
- /** Offline configuration only: does not check deployment, reserves, balances or liquidity. */
44
+ /** Offline configuration/registry checks; chain state and balances are not checked. */
39
45
  export interface PresetConfigurationIssue {
40
- code: 'AGENT_REQUIRED' | 'EXPIRY_REQUIRED' | 'GAS_BUDGET_REQUIRED' | 'ASSETS_REQUIRED' | 'TOKEN_PAIR_REQUIRED' | 'NO_ENABLED_OPERATION';
46
+ code: 'AGENT_REQUIRED' | 'EXPIRY_REQUIRED' | 'GAS_BUDGET_REQUIRED' | 'ASSETS_REQUIRED' | 'TOKEN_PAIR_REQUIRED' | 'NO_ENABLED_OPERATION' | 'AGW_NETWORK_UNAVAILABLE' | 'DESTINATION_UNAVAILABLE' | 'BRIDGE_ASSET_UNAVAILABLE';
41
47
  message: string;
48
+ token?: string;
42
49
  }
43
50
  export interface PresetCallIssue {
44
51
  target: string;
@@ -51,12 +58,21 @@ export interface PresetCallIssue {
51
58
  export interface PresetChainReadiness {
52
59
  chainNamespace: ForeignChainNamespace;
53
60
  ready: boolean;
61
+ configurationReady: boolean;
62
+ /** Selected assets and caps, matching the returned rule assets. */
63
+ selectedAssets: RuleAsset[];
64
+ /** Registry presence only; grant preparation verifies exact on-chain identity. */
65
+ bridgeAssets: {
66
+ token: string;
67
+ status: 'registered' | 'unavailable';
68
+ prc20?: Address;
69
+ }[];
54
70
  issues: PresetConfigurationIssue[];
55
71
  /** Calls present in the rule but disabled by a zero amount/value maximum. */
56
72
  disabledCalls: PresetCallIssue[];
57
73
  /** Calls deliberately omitted, including operations with incompatible amount units. */
58
74
  excludedCalls: PresetCallIssue[];
59
- /** Known fixed-token/reserve addresses in this catalog, not selected defaults. */
75
+ /** Known catalog token addresses, including the curated default subset. */
60
76
  knownTokens: string[];
61
77
  /** Selected tokens with a zero Push-outbound budget; destination-held assets are separate. */
62
78
  zeroBridgeLimits: string[];
@@ -36,6 +36,7 @@ const selectors_1 = require("./codec/selectors");
36
36
  const abi_layout_1 = require("./codec/abi-layout");
37
37
  const defaults_1 = require("./codec/defaults");
38
38
  const svm_accounts_1 = require("./codec/svm-accounts");
39
+ const destination_1 = require("./management/destination");
39
40
  exports.WALLET = 'agentic:wallet';
40
41
  const PUBLIC_INPUT = Symbol('AGW public rule');
41
42
  /** Mark authored inputs for normalization after the wallet address is fixed. */
@@ -94,6 +95,11 @@ async function normalizePublicRule(input, wallet, runtime) {
94
95
  if ('format' in rule && rule.format === 'decoded')
95
96
  return input;
96
97
  const r = rule;
98
+ if (!(0, viem_1.isAddress)(r.agent, { strict: false }) || /^0x0{40}$/i.test(r.agent))
99
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'Enter a valid agent wallet address.', {
100
+ userMessage: 'Enter a valid agent wallet address.',
101
+ details: { field: 'agent' },
102
+ });
97
103
  rejectFields(r, [
98
104
  'target',
99
105
  'selector',
@@ -158,10 +164,15 @@ async function normalizePublicRule(input, wallet, runtime) {
158
164
  throw invalid('native rules do not carry assets or maxGasPerCall');
159
165
  const own = native
160
166
  ? wallet
161
- : (0, viem_1.getAddress)((await runtime.resolveCEA(wallet, r.chainNamespace)).cea);
167
+ : await (0, destination_1.resolveRuleDestination)(runtime, wallet, r.chainNamespace);
162
168
  const nativeActions = [];
163
169
  const calls = [];
164
- for (const call of r.allowedCalls) {
170
+ for (const [callIndex, call] of r.allowedCalls.entries()) {
171
+ if (!(0, viem_1.isAddress)(call.target, { strict: false }))
172
+ throw new errors_1.AgenticError(errors_1.AGENTIC_ERROR_CODE.INVALID_RULE, 'An allowed function has an invalid app address.', {
173
+ userMessage: 'An allowed function has an invalid app address. Select the app again.',
174
+ details: { field: `allowedCalls[${callIndex}].target`, callIndex },
175
+ });
165
176
  const pins = call.pins ?? [];
166
177
  const wirePins = [];
167
178
  const occupied = new Set();
@@ -111,6 +111,41 @@ export declare const CONSTANTS: {
111
111
  /** Checked v5 agentic wallet deployments by Push network (Donut only). */
112
112
  AGENTIC: Readonly<{
113
113
  WALLET: "agentic:wallet";
114
+ PRINCIPAL: "agentic:principal";
115
+ JOB: Readonly<{
116
+ ADDRESS: Readonly<{
117
+ 'eip155:42101': Readonly<{
118
+ KERNEL: "0x977cf1AC973E9eC4332791d531507575006157Ed";
119
+ HOOK: "0xDe7A94e510b6C571DE7880d441349689F73A32b3";
120
+ EVALUATOR: "0x1afC81396f1bb36F91f74506284952b81e4bd47c";
121
+ }>;
122
+ }>;
123
+ EVALUATION: Readonly<{
124
+ readonly BOOLEAN: "BOOLEAN";
125
+ readonly COMPARE: "COMPARE";
126
+ readonly NUMBER: "NUMBER";
127
+ readonly PERCENTAGE: "PERCENTAGE";
128
+ }>;
129
+ OPERATION: Readonly<{
130
+ readonly EQUAL: "EQUAL";
131
+ readonly NOT_EQUAL: "NOT_EQUAL";
132
+ readonly GREATER_THAN: "GREATER_THAN";
133
+ readonly GREATER_OR_EQUAL: "GREATER_OR_EQUAL";
134
+ readonly LESS_THAN: "LESS_THAN";
135
+ readonly LESS_OR_EQUAL: "LESS_OR_EQUAL";
136
+ }>;
137
+ LOGIC: Readonly<{
138
+ readonly ALL: "ALL";
139
+ readonly ANY: "ANY";
140
+ readonly AT_LEAST: "AT_LEAST";
141
+ }>;
142
+ ALLOWED_MUTABILITY: Readonly<{
143
+ readonly NONE: "NONE";
144
+ readonly CLIENT: "CLIENT";
145
+ readonly PROVIDER: "PROVIDER";
146
+ readonly BOTH: "BOTH";
147
+ }>;
148
+ }>;
114
149
  PRESETS: Readonly<{
115
150
  CATEGORY: Readonly<{
116
151
  DEXES: "DEXES";
@@ -1,4 +1,8 @@
1
1
  import { PushChain } from './push-chain/push-chain';
2
+ export { MarketError, JobError, JobSpecError } from './market';
3
+ export type { AgentCardRules, MarketAssetToken, MarketPin, AgentCard, AgentCardInput, AgentCardSummary, MarketNamespace, MarketPreviewOptions, MarketWriteOptions, MarketOpenOptions, MarketDepositOptions, MarketDepositResult, MarketDepositStep, JobPlan, OwnerIntent, } from './market';
4
+ export type { JobNamespace, Job, JobStatus, JobEvent, JobWatchCursor, JobWatchOptions, CreateJobOptions, FundJobOptions, } from './job/types';
5
+ export type { JobSpec, JobSpecTemplate, JobRead, PreparedJobRead, JobReadInput, JobCheck, JobCheckTemplate, LogicTree, Evaluation, Operation, LogicKind, AllowedMutability, PrincipalMarker, PrepareJobReadOptions, ExecuteJobReadOptions, BuildJobSpecOptions, BuildJobSpecTemplateOptions, JobSpecPreview, PreviewJobSpecOptions, } from './job-spec';
2
6
  export { CHAIN } from './constants/enums';
3
7
  export type { ConversionQuote } from './constants/tokens';
4
8
  export type { UniversalSigner, UniversalAccount, UniversalSignerSkeleton, SignAuthorizationParams, SignedAuthorization, DerivedExecutorAccount, ResolvedAccount, ResolvedControllerAccounts, AccountType, AccountRole, } from './universal/universal.types';
package/src/lib/index.js CHANGED
@@ -1,9 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReadTimeoutError = exports.ReadDecodeError = exports.UnsupportedReadDestinationError = exports.ReadHeightUnavailableError = exports.InvalidReadSpecError = exports.InvalidReadQueryError = exports.ReadStateError = exports.TERMINAL_READ_STATUSES = exports.CONTRACT_REQUEST_STATUS = exports.READ_OUTCOME = exports.READ_ERROR_CODE = exports.READ_STATUS = exports.UNIVERSAL_READ_STATUS = exports.buildErc20WithdrawalMulticall = exports.buildMigrationPayload = exports.isValidSolanaHexAddress = exports.isSvmChain = exports.encodeSvmExecutePayload = exports.getAllCEAAddresses = exports.getCEAFactoryAddress = exports.chainSupportsOutbound = exports.chainSupportsCEA = exports.isCEA = exports.getPushAccountForCEA = exports.getCEAAddress = exports.quoteMaxPCForGasCapFromNativeValue = exports.quoteMaxPCForGasCap = exports.MAX_PC_FOR_GAS_BUFFER_BPS_LIMIT = exports.DEFAULT_MAX_PC_FOR_GAS_BUFFER_BPS = exports.isChainTarget = exports.detectRoute = exports.TransactionRoute = exports.parseUEAVersion = exports.PC20UnsafeEmptyPayloadError = exports.PC20ExportRevertedError = exports.PC20WrapperPredictionUnavailableError = exports.PC20UnknownChainNamespaceError = exports.InsufficientPC20BalanceError = exports.UnsupportedPC20DestinationError = exports.PC20AmbiguousAddressError = exports.PC20ExpectedButPRC20Error = exports.InvalidPC20MetadataError = exports.PC20FactoryMismatchError = exports.PC20RegistryMismatchError = exports.PC20WrapperNotRegisteredError = exports.PC20TokenChainMismatchError = exports.InvalidPC20AddressError = exports.PC20Error = exports.isPC20Reference = exports.CHAIN = void 0;
4
- exports.PushChain = exports.AgenticRevertError = exports.AgenticError = exports.AGENTIC_ERROR_CODE = exports.PushChainBatchExecutionError = exports.PushChainExecutionError = exports.UNIVERSAL_READ_REGISTRY_EVM = exports.UNIVERSAL_CALLBACK_EVM = exports.toReadQuery = exports.toRequestIdHex = exports.inferResultShape = exports.sizeCallbackBudget = exports.toCallData = exports.validateReadSpec = exports.buildReadSpecFromPreflight = exports.parseFulfilOutcome = exports.parseReadRequestsFromReceipt = exports.decodeReadResult = exports.encodeReadQuery = exports.resolveDestination = exports.ReadRegistryUnavailableError = exports.ReadNotFoundError = void 0;
3
+ exports.ReadHeightUnavailableError = exports.InvalidReadSpecError = exports.InvalidReadQueryError = exports.ReadStateError = exports.TERMINAL_READ_STATUSES = exports.CONTRACT_REQUEST_STATUS = exports.READ_OUTCOME = exports.READ_ERROR_CODE = exports.READ_STATUS = exports.UNIVERSAL_READ_STATUS = exports.buildErc20WithdrawalMulticall = exports.buildMigrationPayload = exports.isValidSolanaHexAddress = exports.isSvmChain = exports.encodeSvmExecutePayload = exports.getAllCEAAddresses = exports.getCEAFactoryAddress = exports.chainSupportsOutbound = exports.chainSupportsCEA = exports.isCEA = exports.getPushAccountForCEA = exports.getCEAAddress = exports.quoteMaxPCForGasCapFromNativeValue = exports.quoteMaxPCForGasCap = exports.MAX_PC_FOR_GAS_BUFFER_BPS_LIMIT = exports.DEFAULT_MAX_PC_FOR_GAS_BUFFER_BPS = exports.isChainTarget = exports.detectRoute = exports.TransactionRoute = exports.parseUEAVersion = exports.PC20UnsafeEmptyPayloadError = exports.PC20ExportRevertedError = exports.PC20WrapperPredictionUnavailableError = exports.PC20UnknownChainNamespaceError = exports.InsufficientPC20BalanceError = exports.UnsupportedPC20DestinationError = exports.PC20AmbiguousAddressError = exports.PC20ExpectedButPRC20Error = exports.InvalidPC20MetadataError = exports.PC20FactoryMismatchError = exports.PC20RegistryMismatchError = exports.PC20WrapperNotRegisteredError = exports.PC20TokenChainMismatchError = exports.InvalidPC20AddressError = exports.PC20Error = exports.isPC20Reference = exports.CHAIN = exports.JobSpecError = exports.JobError = exports.MarketError = void 0;
4
+ exports.PushChain = exports.AgenticRevertError = exports.AgenticError = exports.AGENTIC_ERROR_CODE = exports.PushChainBatchExecutionError = exports.PushChainExecutionError = exports.UNIVERSAL_READ_REGISTRY_EVM = exports.UNIVERSAL_CALLBACK_EVM = exports.toReadQuery = exports.toRequestIdHex = exports.inferResultShape = exports.sizeCallbackBudget = exports.toCallData = exports.validateReadSpec = exports.buildReadSpecFromPreflight = exports.parseFulfilOutcome = exports.parseReadRequestsFromReceipt = exports.decodeReadResult = exports.encodeReadQuery = exports.resolveDestination = exports.ReadRegistryUnavailableError = exports.ReadNotFoundError = exports.ReadTimeoutError = exports.ReadDecodeError = exports.UnsupportedReadDestinationError = void 0;
5
5
  const push_chain_1 = require("./push-chain/push-chain");
6
6
  Object.defineProperty(exports, "PushChain", { enumerable: true, get: function () { return push_chain_1.PushChain; } });
7
+ var market_1 = require("./market");
8
+ Object.defineProperty(exports, "MarketError", { enumerable: true, get: function () { return market_1.MarketError; } });
9
+ Object.defineProperty(exports, "JobError", { enumerable: true, get: function () { return market_1.JobError; } });
10
+ Object.defineProperty(exports, "JobSpecError", { enumerable: true, get: function () { return market_1.JobSpecError; } });
7
11
  var enums_1 = require("./constants/enums");
8
12
  Object.defineProperty(exports, "CHAIN", { enumerable: true, get: function () { return enums_1.CHAIN; } });
9
13
  var orchestrator_types_1 = require("./orchestrator/orchestrator.types");
@@ -0,0 +1,35 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import { type StackRuntime } from '../market/runtime';
3
+ import type { CreateJobOptions, FundJobOptions, Job, JobEvent, JobNamespace, JobStatus, JobWriteOptions, JobWatchOptions } from './types';
4
+ export declare class JobNamespaceImpl implements JobNamespace {
5
+ private readonly rt;
6
+ constructor(rt: StackRuntime);
7
+ private raw;
8
+ private jobAt;
9
+ status(jobId: bigint): Promise<Job>;
10
+ list(options?: {
11
+ client?: Address;
12
+ provider?: Address;
13
+ status?: JobStatus;
14
+ fromJobId?: bigint;
15
+ }): Promise<{
16
+ jobs: Job[];
17
+ }>;
18
+ create(options: CreateJobOptions): Promise<{
19
+ jobId: bigint;
20
+ tx: import("../orchestrator/orchestrator.types").UniversalTxResponse;
21
+ }>;
22
+ private provider;
23
+ private open;
24
+ setBudget(jobId: bigint, budget: bigint, options?: JobWriteOptions & {
25
+ jobSpec?: Hex;
26
+ }): Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
27
+ fund(jobId: bigint, options?: FundJobOptions): Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
28
+ submit(jobId: bigint, options: JobWriteOptions & {
29
+ deliverable: Hex | string;
30
+ }): Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
31
+ cancel(jobId: bigint, options?: JobWriteOptions): Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
32
+ claimRefund(jobId: bigint, options?: JobWriteOptions): Promise<import("../orchestrator/orchestrator.types").UniversalTxResponse>;
33
+ verify(_jobId: bigint, _options?: JobWriteOptions): Promise<never>;
34
+ watch(jobId: bigint, callback: (event: JobEvent) => void, options?: JobWatchOptions): () => void;
35
+ }
@@ -0,0 +1,382 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobNamespaceImpl = void 0;
4
+ const viem_1 = require("viem");
5
+ const AgenticCommerce_1 = require("../market/contracts/AgenticCommerce");
6
+ const RulesBindingHook_1 = require("../market/contracts/RulesBindingHook");
7
+ const UniversalMarketplace_1 = require("../market/contracts/UniversalMarketplace");
8
+ const kernel_wire_1 = require("../market/kernel-wire");
9
+ const runtime_1 = require("../market/runtime");
10
+ const errors_1 = require("../market/errors");
11
+ const deployments_1 = require("../agentic/deployments");
12
+ const rules_1 = require("../agentic/reads/rules");
13
+ const snapshot_1 = require("../agentic/reads/snapshot");
14
+ const codec_1 = require("../job-spec/codec");
15
+ const watch_1 = require("./watch");
16
+ const STATES = [
17
+ 'Open',
18
+ 'Funded',
19
+ 'Submitted',
20
+ 'Completed',
21
+ 'Rejected',
22
+ 'Expired',
23
+ ];
24
+ function validId(jobId) {
25
+ if (typeof jobId !== 'bigint' || jobId < BigInt(1))
26
+ throw new errors_1.JobError('INVALID_JOB_ID', 'Job IDs are positive bigint values.');
27
+ }
28
+ function amount(n) {
29
+ if (typeof n !== 'bigint' || n < BigInt(0) || n >= BigInt(1) << BigInt(256))
30
+ throw new errors_1.JobError('INVALID_AMOUNT', 'The amount must fit uint256.');
31
+ }
32
+ class JobNamespaceImpl {
33
+ rt;
34
+ constructor(rt) {
35
+ this.rt = rt;
36
+ }
37
+ async raw(jobId, s) {
38
+ validId(jobId);
39
+ const j = await s.read((0, runtime_1.deployment)(this.rt).kernel, kernel_wire_1.KERNEL_READ_ABI, 'getJob', [jobId]);
40
+ if ((0, viem_1.getAddress)(j.client) === viem_1.zeroAddress || !STATES[j.status])
41
+ throw new errors_1.JobError('JOB_NOT_FOUND', 'This job does not exist.');
42
+ return j;
43
+ }
44
+ async jobAt(jobId, s) {
45
+ const d = (0, runtime_1.deployment)(this.rt);
46
+ const j = await this.raw(jobId, s);
47
+ const paymentToken = await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'paymentToken');
48
+ let spec;
49
+ let decodeError;
50
+ if (j.description !== '0x') {
51
+ try {
52
+ spec = (0, codec_1.decodeJobSpec)(j.description, { format: 'spec' });
53
+ }
54
+ catch (e) {
55
+ decodeError = e.message;
56
+ }
57
+ }
58
+ const rulesId = (0, viem_1.getAddress)(j.hook) === (0, viem_1.getAddress)(d.hook)
59
+ ? await s.read(d.hook, RulesBindingHook_1.RULES_HOOK_ABI, 'rulesOfJob', [jobId])
60
+ : undefined;
61
+ let deliverable;
62
+ if (j.status >= 2) {
63
+ const logs = await (0, snapshot_1.scanLogs)(this.rt.agw.reader, {
64
+ address: d.kernel,
65
+ event: (0, viem_1.getAbiItem)({ abi: AgenticCommerce_1.JOB_KERNEL_ABI, name: 'JobSubmitted' }),
66
+ args: { jobId },
67
+ }, this.rt.jobBlocks?.get(jobId) ?? d.startBlock, s.blockNumber);
68
+ if (logs.length > 1)
69
+ throw new errors_1.JobError('INCONSISTENT_READ', 'The job has multiple submission events.');
70
+ if (logs.length === 1) {
71
+ const event = (0, viem_1.decodeEventLog)({
72
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
73
+ eventName: 'JobSubmitted',
74
+ data: logs[0].data,
75
+ topics: logs[0].topics,
76
+ });
77
+ deliverable = event.args.deliverable;
78
+ }
79
+ }
80
+ return {
81
+ ...j,
82
+ jobId,
83
+ status: STATES[j.status],
84
+ paymentToken,
85
+ ...(deliverable ? { deliverable } : {}),
86
+ ...(rulesId && rulesId !== viem_1.zeroHash ? { rulesId } : {}),
87
+ ...(spec ? { jobSpec: { spec, bytes: j.description } } : {}),
88
+ ...(decodeError ? { jobSpecDecodeError: decodeError } : {}),
89
+ evaluation: {
90
+ available: false,
91
+ reason: (0, viem_1.getAddress)(j.evaluator) === (0, viem_1.getAddress)(d.evaluator)
92
+ ? 'MANUAL_EVALUATOR'
93
+ : 'UNVERIFIED_EVALUATOR',
94
+ },
95
+ };
96
+ }
97
+ async status(jobId) {
98
+ return this.jobAt(jobId, await (0, runtime_1.snapshot)(this.rt));
99
+ }
100
+ async list(options = {}) {
101
+ const s = await (0, runtime_1.snapshot)(this.rt);
102
+ const count = await s.read((0, runtime_1.deployment)(this.rt).kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'jobCounter');
103
+ const from = options.fromJobId ?? BigInt(1);
104
+ validId(from);
105
+ const jobs = [];
106
+ for (let i = from; i <= count; i += BigInt(8)) {
107
+ const rows = await Promise.all(Array.from({
108
+ length: Number(count - i + BigInt(1) > BigInt(8)
109
+ ? BigInt(8)
110
+ : count - i + BigInt(1)),
111
+ }, (_, n) => this.jobAt(i + BigInt(n), s)));
112
+ jobs.push(...rows.filter((j) => (!options.client ||
113
+ (0, viem_1.getAddress)(options.client) === (0, viem_1.getAddress)(j.client)) &&
114
+ (!options.provider ||
115
+ (0, viem_1.getAddress)(options.provider) === (0, viem_1.getAddress)(j.provider)) &&
116
+ (!options.status || options.status === j.status)));
117
+ }
118
+ return { jobs };
119
+ }
120
+ async create(options) {
121
+ options = { ...options };
122
+ const d = (0, runtime_1.deployment)(this.rt);
123
+ const s = await (0, runtime_1.snapshot)(this.rt);
124
+ const token = await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'paymentToken');
125
+ if ((0, viem_1.getAddress)(options.paymentToken) !== (0, viem_1.getAddress)(token))
126
+ throw new errors_1.JobError('TOKEN_MISMATCH', 'The job token must equal this kernel’s payment token.');
127
+ if (options.jobSpec) {
128
+ const spec = (0, codec_1.decodeJobSpec)(options.jobSpec, {
129
+ format: 'spec',
130
+ });
131
+ if (spec.allowedMutability !== 'NONE')
132
+ (0, errors_1.unavailable)('Mutable job criteria');
133
+ if (spec.origin !== viem_1.zeroHash)
134
+ throw new errors_1.JobError('INVALID_JOB_SPEC', 'A plain job must have a zero marketplace origin.');
135
+ if (spec.failFinalAt >= options.expiredAt)
136
+ throw new errors_1.JobError('INVALID_JOB_SPEC', 'The failure deadline must precede expiry.');
137
+ }
138
+ const min = await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'MIN_EXPIRY_WINDOW');
139
+ if (!Number.isSafeInteger(options.expiredAt) ||
140
+ options.expiredAt <= s.timestamp + Number(min) ||
141
+ options.expiredAt >= 2 ** 48)
142
+ throw new errors_1.JobError('EXPIRY_TOO_SHORT', 'Choose a future expiry beyond the kernel minimum window.');
143
+ const call = {
144
+ target: d.kernel,
145
+ value: BigInt(0),
146
+ data: (0, kernel_wire_1.encodeCreateJob)((0, viem_1.getAddress)(options.provider), (0, viem_1.getAddress)(options.evaluator), options.expiredAt, options, (0, viem_1.getAddress)(options.hook)),
147
+ };
148
+ const wallet = this.rt.wallet();
149
+ const tx = wallet
150
+ ? await (0, runtime_1.ownerBatch)(this.rt, wallet, [call], options.progressHook)
151
+ : await (0, runtime_1.write)(this.rt, call, options.progressHook, 'JOB', true);
152
+ const e = await (0, runtime_1.eventArgs)(this.rt, tx, d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'JobCreated');
153
+ if ((0, viem_1.getAddress)(e['client']) !== (0, viem_1.getAddress)(this.rt.account()))
154
+ throw new errors_1.JobError('RECEIPT_MISMATCH', 'The created job has a different client.', { txHash: tx.hash });
155
+ return { jobId: e['jobId'], tx };
156
+ }
157
+ provider(j) {
158
+ if ((0, viem_1.getAddress)(j.provider) !== (0, viem_1.getAddress)(this.rt.agw.signerPushAccount()))
159
+ throw new errors_1.JobError('NOT_PROVIDER', 'Connect this job’s provider.');
160
+ }
161
+ open(j, now) {
162
+ if (j.status !== 0 || j.expiredAt <= now)
163
+ throw new errors_1.JobError('WRONG_STATUS', 'The job must be Open and unexpired.');
164
+ }
165
+ async setBudget(jobId, budget, options = {}) {
166
+ if (options.jobSpec !== undefined)
167
+ (0, errors_1.unavailable)('Replacement JobSpec proposals');
168
+ amount(budget);
169
+ const s = await (0, runtime_1.snapshot)(this.rt);
170
+ const j = await this.raw(jobId, s);
171
+ this.provider(j);
172
+ this.open(j, s.timestamp);
173
+ const d = (0, runtime_1.deployment)(this.rt);
174
+ return (0, runtime_1.write)(this.rt, {
175
+ target: d.kernel,
176
+ value: BigInt(0),
177
+ data: (0, viem_1.encodeFunctionData)({
178
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
179
+ functionName: 'setBudget',
180
+ args: [jobId, budget, '0x'],
181
+ }),
182
+ }, options.progressHook, 'JOB', true);
183
+ }
184
+ async fund(jobId, options = {}) {
185
+ options = { ...options };
186
+ const rt = this.rt;
187
+ const d = (0, runtime_1.deployment)(rt);
188
+ const s = await (0, runtime_1.snapshot)(rt);
189
+ const j = await this.raw(jobId, s);
190
+ this.open(j, s.timestamp);
191
+ const gen = (0, deployments_1.currentGeneration)(rt.agw.network);
192
+ const isWallet = await s.read(gen.addresses.factory, gen.contracts.abis.factory, 'isWallet', [j.client]);
193
+ if (isWallet) {
194
+ const owner = await s.read(j.client, gen.contracts.abis.wallet, 'owner');
195
+ if ((0, viem_1.getAddress)(owner) !== (0, viem_1.getAddress)(rt.agw.signerPushAccount()))
196
+ throw new errors_1.JobError('NOT_CLIENT', 'Connect the job wallet’s owner.');
197
+ }
198
+ else if ((0, viem_1.getAddress)(j.client) !== (0, viem_1.getAddress)(rt.agw.signerPushAccount()))
199
+ throw new errors_1.JobError('NOT_CLIENT', 'Connect this job’s client.');
200
+ let expected = options.expectedBudget;
201
+ const cardId = await s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'cardOfJob', [jobId]);
202
+ let rulesId = options.rulesId;
203
+ if (cardId) {
204
+ const [version, view, recordedRules] = await Promise.all([
205
+ s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'cardVersionOfJob', [
206
+ jobId,
207
+ ]),
208
+ s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'getAgentCard', [cardId]),
209
+ s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'rulesOfJob', [jobId]),
210
+ ]);
211
+ if (rulesId && rulesId !== recordedRules)
212
+ throw new errors_1.JobError('RULES_MISMATCH', 'Use the permission recorded when this job was opened.');
213
+ rulesId = recordedRules;
214
+ if (expected === undefined && version === view.version)
215
+ expected = view.card.providerFee;
216
+ }
217
+ if (expected === undefined)
218
+ throw new errors_1.JobError('EXPECTED_BUDGET_REQUIRED', 'Pass the exact budget you reviewed; this SDK does not silently accept the latest provider quote.');
219
+ amount(expected);
220
+ if (expected !== j.budget)
221
+ throw new errors_1.JobError('BUDGET_MISMATCH', 'The provider’s current price differs from the budget you reviewed.', { expectedBudget: expected, currentBudget: j.budget });
222
+ let optParams = '0x';
223
+ if ((0, viem_1.getAddress)(j.hook) === (0, viem_1.getAddress)(d.hook)) {
224
+ if (!isWallet || !rulesId || !/^0x[\da-f]{64}$/i.test(rulesId))
225
+ throw new errors_1.JobError('RULES_REQUIRED', 'This rules hook needs an AGW client and its rulesId.');
226
+ const record = await (0, rules_1.getRule)(new snapshot_1.Snapshot(rt.agw.reader, s.blockNumber), gen, j.client, rulesId, rt.agw.pushChainNamespace);
227
+ if ((0, viem_1.getAddress)(record.agent) !== (0, viem_1.getAddress)(j.provider) ||
228
+ record.validUntil < j.expiredAt)
229
+ throw new errors_1.JobError('RULES_MISMATCH', 'The live rule must authorize this provider through the job expiry.');
230
+ if (await s.read(d.hook, RulesBindingHook_1.RULES_HOOK_ABI, 'activeJobOf', [j.client]))
231
+ throw new errors_1.JobError('WALLET_HAS_ACTIVE_JOB', 'This wallet already has a funded job under the rules hook.');
232
+ optParams = (0, viem_1.encodeAbiParameters)([{ type: 'bytes32' }], [rulesId]);
233
+ }
234
+ else if (rulesId)
235
+ throw new errors_1.JobError('HOOK_MISMATCH', 'A rulesId payload is supported only for the verified rules hook.');
236
+ const token = await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'paymentToken');
237
+ const calls = [];
238
+ if (expected > BigInt(0)) {
239
+ const [balance, allowance] = await Promise.all([
240
+ s.read(token, viem_1.erc20Abi, 'balanceOf', [j.client]),
241
+ s.read(token, viem_1.erc20Abi, 'allowance', [j.client, d.kernel]),
242
+ ]);
243
+ if (balance < expected)
244
+ throw new errors_1.JobError('INSUFFICIENT_FUNDS', 'The job client lacks the payment tokens required for escrow.');
245
+ if (allowance < expected) {
246
+ if (allowance > BigInt(0))
247
+ calls.push({
248
+ target: token,
249
+ value: BigInt(0),
250
+ data: (0, viem_1.encodeFunctionData)({
251
+ abi: viem_1.erc20Abi,
252
+ functionName: 'approve',
253
+ args: [d.kernel, BigInt(0)],
254
+ }),
255
+ });
256
+ calls.push({
257
+ target: token,
258
+ value: BigInt(0),
259
+ data: (0, viem_1.encodeFunctionData)({
260
+ abi: viem_1.erc20Abi,
261
+ functionName: 'approve',
262
+ args: [d.kernel, expected],
263
+ }),
264
+ });
265
+ }
266
+ }
267
+ calls.push({
268
+ target: d.kernel,
269
+ value: BigInt(0),
270
+ data: (0, viem_1.encodeFunctionData)({
271
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
272
+ functionName: 'fund',
273
+ args: [jobId, expected, optParams],
274
+ }),
275
+ });
276
+ if (isWallet)
277
+ return (0, runtime_1.ownerBatch)(rt, j.client, calls, options.progressHook);
278
+ if (calls.length === 1)
279
+ return (0, runtime_1.write)(rt, calls[0], options.progressHook, 'JOB', true);
280
+ if (rt.agw.isReadOnly)
281
+ throw new errors_1.JobError('READ_ONLY', 'Connect a signer to fund escrow.');
282
+ // No sequential fallback: allowance and acceptance must belong to one atomic batch.
283
+ return rt.agw.executeAtomicBatch({
284
+ to: d.kernel,
285
+ value: BigInt(0),
286
+ data: calls.map((c) => ({
287
+ to: c.target,
288
+ value: c.value,
289
+ data: c.data,
290
+ })),
291
+ }, { progressHook: options.progressHook });
292
+ }
293
+ async submit(jobId, options) {
294
+ options = { ...options };
295
+ const s = await (0, runtime_1.snapshot)(this.rt);
296
+ const j = await this.raw(jobId, s);
297
+ this.provider(j);
298
+ if (j.status !== 1 || j.expiredAt <= s.timestamp)
299
+ throw new errors_1.JobError('WRONG_STATUS', 'Only an unexpired Funded job can be submitted.');
300
+ const deliverable = /^0x[\da-f]{64}$/i.test(options.deliverable)
301
+ ? options.deliverable
302
+ : (0, viem_1.keccak256)((0, viem_1.stringToHex)(options.deliverable));
303
+ return (0, runtime_1.write)(this.rt, {
304
+ target: (0, runtime_1.deployment)(this.rt).kernel,
305
+ value: BigInt(0),
306
+ data: (0, viem_1.encodeFunctionData)({
307
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
308
+ functionName: 'submit',
309
+ args: [jobId, deliverable, '0x'],
310
+ }),
311
+ }, options.progressHook, 'JOB', true);
312
+ }
313
+ async cancel(jobId, options = {}) {
314
+ const rt = this.rt;
315
+ const d = (0, runtime_1.deployment)(rt);
316
+ const s = await (0, runtime_1.snapshot)(rt);
317
+ const j = await this.raw(jobId, s);
318
+ if (j.status !== 0)
319
+ throw new errors_1.JobError('WRONG_STATUS', 'Only an Open job can be cancelled by its client.');
320
+ const gen = (0, deployments_1.currentGeneration)(rt.agw.network);
321
+ const isWallet = await s.read(gen.addresses.factory, gen.contracts.abis.factory, 'isWallet', [j.client]);
322
+ const calls = [
323
+ {
324
+ target: d.kernel,
325
+ value: BigInt(0),
326
+ data: (0, viem_1.encodeFunctionData)({
327
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
328
+ functionName: 'reject',
329
+ args: [jobId, viem_1.zeroHash, '0x'],
330
+ }),
331
+ },
332
+ ];
333
+ if (isWallet) {
334
+ const wallet = await s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'agwOfJob', [jobId]);
335
+ const rulesId = await s.read(d.marketplace, UniversalMarketplace_1.MARKETPLACE_ABI, 'rulesOfJob', [jobId]);
336
+ if ((0, viem_1.getAddress)(wallet) === (0, viem_1.getAddress)(j.client) &&
337
+ rulesId !== viem_1.zeroHash &&
338
+ (await s.read(gen.addresses.sessionEngine, gen.contracts.abis.engine, 'isPermissionEnabled', [rulesId, j.client])))
339
+ calls.push({
340
+ target: j.client,
341
+ value: BigInt(0),
342
+ data: gen.contracts.encodeRevokeRules(rulesId),
343
+ });
344
+ return (0, runtime_1.ownerBatch)(rt, j.client, calls, options.progressHook);
345
+ }
346
+ if ((0, viem_1.getAddress)(j.client) !== (0, viem_1.getAddress)(rt.agw.signerPushAccount()))
347
+ throw new errors_1.JobError('NOT_CLIENT', 'Only the client can use this cancellation method.');
348
+ return (0, runtime_1.write)(rt, calls[0], options.progressHook, 'JOB', true);
349
+ }
350
+ async claimRefund(jobId, options = {}) {
351
+ const s = await (0, runtime_1.snapshot)(this.rt);
352
+ const j = await this.raw(jobId, s);
353
+ const d = (0, runtime_1.deployment)(this.rt);
354
+ if (![0, 1, 2].includes(j.status))
355
+ throw new errors_1.JobError('WRONG_STATUS', 'This job is already terminal.');
356
+ const grace = j.status === 2
357
+ ? Number(await s.read(d.kernel, AgenticCommerce_1.JOB_KERNEL_ABI, 'EVALUATOR_GRACE_PERIOD'))
358
+ : 0;
359
+ if (s.timestamp < j.expiredAt + grace)
360
+ throw new errors_1.JobError('REFUND_NOT_READY', 'The expiry or evaluator grace window has not elapsed.');
361
+ return (0, runtime_1.write)(this.rt, {
362
+ target: d.kernel,
363
+ value: BigInt(0),
364
+ data: (0, viem_1.encodeFunctionData)({
365
+ abi: AgenticCommerce_1.JOB_KERNEL_ABI,
366
+ functionName: 'claimRefund',
367
+ args: [jobId],
368
+ }),
369
+ }, options.progressHook, 'JOB', true);
370
+ }
371
+ async verify(_jobId, _options) {
372
+ void _jobId;
373
+ void _options;
374
+ return (0, errors_1.unavailable)('Automatic job verification; the configured evaluator is manual');
375
+ }
376
+ watch(jobId, callback, options = {}) {
377
+ validId(jobId);
378
+ return (0, watch_1.watchJob)(this.rt, jobId, callback, { ...options });
379
+ }
380
+ }
381
+ exports.JobNamespaceImpl = JobNamespaceImpl;
382
+ //# sourceMappingURL=job.js.map