@4mica/sdk 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/dist/client/recipient.d.ts +2 -1
  3. package/dist/client/recipient.js +3 -1
  4. package/dist/contract.js +26 -10
  5. package/dist/guarantee.d.ts +1 -1
  6. package/dist/guarantee.js +9 -4
  7. package/dist/models.d.ts +4 -0
  8. package/dist/models.js +3 -0
  9. package/dist/payment.d.ts +2 -1
  10. package/dist/payment.js +2 -1
  11. package/dist/signing.d.ts +4 -0
  12. package/dist/signing.js +4 -0
  13. package/dist/validation.d.ts +2 -2
  14. package/dist/validation.js +4 -2
  15. package/dist/x402/index.d.ts +1 -1
  16. package/dist/x402/index.js +4 -2
  17. package/dist/x402/models.d.ts +1 -0
  18. package/package.json +4 -2
  19. package/dist/abi/core4mica.json +0 -1605
  20. package/dist/abi/erc20.json +0 -187
  21. package/dist/client.d.ts +0 -56
  22. package/dist/client.js +0 -258
  23. package/dist/src/abi/core4mica.json +0 -1605
  24. package/dist/src/abi/erc20.json +0 -187
  25. package/dist/src/bls.d.ts +0 -5
  26. package/dist/src/bls.js +0 -45
  27. package/dist/src/client.d.ts +0 -55
  28. package/dist/src/client.js +0 -214
  29. package/dist/src/config.d.ts +0 -21
  30. package/dist/src/config.js +0 -76
  31. package/dist/src/contract.d.ts +0 -33
  32. package/dist/src/contract.js +0 -121
  33. package/dist/src/errors.d.ts +0 -17
  34. package/dist/src/errors.js +0 -31
  35. package/dist/src/guarantee.d.ts +0 -3
  36. package/dist/src/guarantee.js +0 -66
  37. package/dist/src/index.d.ts +0 -11
  38. package/dist/src/index.js +0 -27
  39. package/dist/src/models.d.ts +0 -119
  40. package/dist/src/models.js +0 -132
  41. package/dist/src/rpc.d.ts +0 -30
  42. package/dist/src/rpc.js +0 -122
  43. package/dist/src/signing.d.ts +0 -16
  44. package/dist/src/signing.js +0 -102
  45. package/dist/src/utils.d.ts +0 -8
  46. package/dist/src/utils.js +0 -78
  47. package/dist/src/x402.d.ts +0 -77
  48. package/dist/src/x402.js +0 -214
  49. package/dist/tests/config.test.d.ts +0 -1
  50. package/dist/tests/config.test.js +0 -26
  51. package/dist/tests/guarantee.test.d.ts +0 -1
  52. package/dist/tests/guarantee.test.js +0 -26
  53. package/dist/tests/rpc.test.d.ts +0 -1
  54. package/dist/tests/rpc.test.js +0 -44
  55. package/dist/tests/signing.test.d.ts +0 -1
  56. package/dist/tests/signing.test.js +0 -25
  57. package/dist/tests/utils.test.d.ts +0 -1
  58. package/dist/tests/utils.test.js +0 -25
  59. package/dist/tests/x402.test.d.ts +0 -1
  60. package/dist/tests/x402.test.js +0 -65
  61. package/dist/x402.d.ts +0 -78
  62. package/dist/x402.js +0 -231
package/README.md CHANGED
@@ -294,7 +294,7 @@ Notes:
294
294
 
295
295
  #### RecipientClient Methods
296
296
 
297
- - `createTab(userAddress, recipientAddress, erc20Token?, ttl?)`
297
+ - `createTab(userAddress, recipientAddress, erc20Token?, ttl?, guaranteeVersion?)`
298
298
  - `getTabPaymentStatus(tabId)`
299
299
  - `issuePaymentGuarantee(claims, signature, scheme)` — accepts V1 or V2 claims
300
300
  - `verifyPaymentGuarantee(cert)`
@@ -14,11 +14,12 @@ export declare class RecipientClient {
14
14
  * @param recipientAddress - Address of the recipient.
15
15
  * @param erc20Token - ERC20 token address for the tab, or `null`/`undefined` for ETH.
16
16
  * @param ttl - Optional time-to-live in seconds.
17
+ * @param guaranteeVersion - Guarantee version for the version-scoped tab identity.
17
18
  * @returns `{ tabId, assetAddress, nextReqId }` — the tab ID, the asset address as stored
18
19
  * by the core (use this for all subsequent claims), and the first request ID to use.
19
20
  * @throws {@link RpcError} if the request fails.
20
21
  */
21
- createTab(userAddress: string, recipientAddress: string, erc20Token: string | undefined | null, ttl?: number | null): Promise<{
22
+ createTab(userAddress: string, recipientAddress: string, erc20Token: string | undefined | null, ttl?: number | null, guaranteeVersion?: number): Promise<{
22
23
  tabId: bigint;
23
24
  assetAddress: string;
24
25
  nextReqId: bigint;
@@ -28,16 +28,18 @@ class RecipientClient {
28
28
  * @param recipientAddress - Address of the recipient.
29
29
  * @param erc20Token - ERC20 token address for the tab, or `null`/`undefined` for ETH.
30
30
  * @param ttl - Optional time-to-live in seconds.
31
+ * @param guaranteeVersion - Guarantee version for the version-scoped tab identity.
31
32
  * @returns `{ tabId, assetAddress, nextReqId }` — the tab ID, the asset address as stored
32
33
  * by the core (use this for all subsequent claims), and the first request ID to use.
33
34
  * @throws {@link RpcError} if the request fails.
34
35
  */
35
- async createTab(userAddress, recipientAddress, erc20Token, ttl) {
36
+ async createTab(userAddress, recipientAddress, erc20Token, ttl, guaranteeVersion = 1) {
36
37
  const body = {
37
38
  user_address: (0, utils_1.normalizeAddress)(userAddress),
38
39
  recipient_address: (0, utils_1.normalizeAddress)(recipientAddress),
39
40
  erc20_token: erc20Token ? (0, utils_1.normalizeAddress)(erc20Token) : null,
40
41
  ttl: ttl ?? null,
42
+ guarantee_version: guaranteeVersion,
41
43
  };
42
44
  const result = await this.client.rpc.createPaymentTab(body);
43
45
  const record = result;
package/dist/contract.js CHANGED
@@ -7,6 +7,7 @@ const chain_1 = require("./chain");
7
7
  const errors_1 = require("./errors");
8
8
  const utils_1 = require("./utils");
9
9
  const DEFAULT_REMUNERATE_GAS_LIMIT = 8000000n;
10
+ const DEFAULT_PAY_TAB_ERC20_GAS_LIMIT = 300000n;
10
11
  const DEFAULT_MAX_FEE_PER_GAS = (0, viem_1.parseGwei)('0.1');
11
12
  const DEFAULT_MAX_PRIORITY_FEE_PER_GAS = (0, viem_1.parseGwei)('0.1');
12
13
  class ContractGateway {
@@ -89,10 +90,27 @@ class ContractGateway {
89
90
  async approveErc20(token, amount, waitOptions) {
90
91
  const { receipt } = this.splitWaitOptions(waitOptions);
91
92
  const erc20 = this.erc20(token);
92
- // spender address logic
93
93
  const spender = this.contract.address;
94
- const hash = await this.enqueueTx(() => erc20.write.approve([spender, (0, utils_1.parseU256)(amount)], this.defaultFeeParams()));
95
- return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
94
+ const targetAllowance = (0, utils_1.parseU256)(amount);
95
+ const sendApprove = async (value) => {
96
+ const hash = await this.enqueueTx(() => erc20.write.approve([spender, value], this.defaultFeeParams()));
97
+ const txReceipt = await this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
98
+ if (txReceipt.status !== 'success') {
99
+ throw new errors_1.ContractError(`approve transaction reverted: ${hash}`);
100
+ }
101
+ return txReceipt;
102
+ };
103
+ try {
104
+ return await sendApprove(targetAllowance);
105
+ }
106
+ catch (error) {
107
+ // Some ERC20s require resetting allowance to zero before setting a new value.
108
+ if (targetAllowance === 0n) {
109
+ throw error;
110
+ }
111
+ await sendApprove(0n);
112
+ return sendApprove(targetAllowance);
113
+ }
96
114
  }
97
115
  async deposit(amount, erc20Token, waitOptions) {
98
116
  const { receipt } = this.splitWaitOptions(waitOptions);
@@ -141,13 +159,11 @@ class ContractGateway {
141
159
  return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
142
160
  }
143
161
  async payTabErc20(tabId, amount, erc20Token, recipient, waitOptions) {
144
- const { receipt } = this.splitWaitOptions(waitOptions);
145
- const hash = await this.enqueueTx(() => this.contract.write.payTabInERC20Token([
146
- (0, utils_1.parseU256)(tabId),
147
- erc20Token,
148
- (0, utils_1.parseU256)(amount),
149
- recipient,
150
- ], this.defaultFeeParams()));
162
+ const { gas, receipt } = this.splitWaitOptions(waitOptions);
163
+ const hash = await this.enqueueTx(() => this.contract.write.payTabInERC20Token([(0, utils_1.parseU256)(tabId), erc20Token, (0, utils_1.parseU256)(amount), recipient], {
164
+ gas: gas ?? DEFAULT_PAY_TAB_ERC20_GAS_LIMIT,
165
+ ...this.defaultFeeParams(),
166
+ }));
151
167
  return this.publicClient.waitForTransactionReceipt({ hash, ...receipt });
152
168
  }
153
169
  async requestWithdrawal(amount, erc20Token, waitOptions) {
@@ -3,7 +3,7 @@ import { PaymentGuaranteeClaims } from './models';
3
3
  * ABI-encode a {@link PaymentGuaranteeClaims} object into a hex string.
4
4
  *
5
5
  * Produces the outer `(uint64 version, bytes innerClaims)` envelope format expected
6
- * by the Core4Mica contract. Supports V1 (10 fields) and V2 (18 fields with validation policy).
6
+ * by the Core4Mica contract. Supports V1 (10 fields) and V2 (19 fields with validation policy).
7
7
  *
8
8
  * @param claims - Decoded claims to encode. Must have `version` set to `1` or `2`.
9
9
  * @returns `0x`-prefixed hex string of the ABI-encoded envelope.
package/dist/guarantee.js CHANGED
@@ -22,7 +22,7 @@ const CLAIM_TYPES = [
22
22
  ];
23
23
  // V2 adds: validation_registry_address, validation_request_hash, validation_chain_id,
24
24
  // validator_address, validator_agent_id, min_validation_score,
25
- // validation_subject_hash, required_validation_tag (dynamic string)
25
+ // validation_subject_hash, job_hash, required_validation_tag (dynamic string)
26
26
  const CLAIM_TYPES_V2 = [
27
27
  { type: 'bytes32' }, // domain
28
28
  { type: 'uint256' }, // tab_id
@@ -41,6 +41,7 @@ const CLAIM_TYPES_V2 = [
41
41
  { type: 'uint256' }, // validator_agent_id
42
42
  { type: 'uint8' }, // min_validation_score
43
43
  { type: 'bytes32' }, // validation_subject_hash
44
+ { type: 'bytes32' }, // job_hash
44
45
  { type: 'string' }, // required_validation_tag (dynamic)
45
46
  ];
46
47
  const CLAIM_TYPES_V2_TUPLE = [
@@ -64,6 +65,7 @@ const CLAIM_TYPES_V2_TUPLE = [
64
65
  { name: 'validatorAgentId', type: 'uint256' },
65
66
  { name: 'minValidationScore', type: 'uint8' },
66
67
  { name: 'validationSubjectHash', type: 'bytes32' },
68
+ { name: 'jobHash', type: 'bytes32' },
67
69
  { name: 'requiredValidationTag', type: 'string' },
68
70
  ],
69
71
  },
@@ -85,7 +87,7 @@ function normalizeHexBytes(data) {
85
87
  * ABI-encode a {@link PaymentGuaranteeClaims} object into a hex string.
86
88
  *
87
89
  * Produces the outer `(uint64 version, bytes innerClaims)` envelope format expected
88
- * by the Core4Mica contract. Supports V1 (10 fields) and V2 (18 fields with validation policy).
90
+ * by the Core4Mica contract. Supports V1 (10 fields) and V2 (19 fields with validation policy).
89
91
  *
90
92
  * @param claims - Decoded claims to encode. Must have `version` set to `1` or `2`.
91
93
  * @returns `0x`-prefixed hex string of the ABI-encoded envelope.
@@ -134,6 +136,7 @@ function encodeGuaranteeClaims(claims) {
134
136
  validatorAgentId: p.validatorAgentId,
135
137
  minValidationScore: p.minValidationScore,
136
138
  validationSubjectHash: (0, utils_1.ensureHexPrefix)(p.validationSubjectHash),
139
+ jobHash: (0, utils_1.ensureHexPrefix)(p.jobHash),
137
140
  requiredValidationTag: p.requiredValidationTag,
138
141
  },
139
142
  ]);
@@ -228,7 +231,8 @@ function decodeV2Claims(encoded) {
228
231
  validatorAgentId: decoded[14],
229
232
  minValidationScore: decoded[15],
230
233
  validationSubjectHash: decoded[16],
231
- requiredValidationTag: decoded[17],
234
+ jobHash: decoded[17],
235
+ requiredValidationTag: decoded[18],
232
236
  });
233
237
  }
234
238
  catch (flatErr) {
@@ -237,7 +241,7 @@ function decodeV2Claims(encoded) {
237
241
  }
238
242
  }
239
243
  function buildDecodedV2Claims(decoded) {
240
- const { domain, tabId, reqId, user, recipient, amount, totalAmount, asset, timestamp, claimsVersion, validationRegistryAddress, validationRequestHash, validationChainId, validatorAddress, validatorAgentId, minValidationScore, validationSubjectHash, requiredValidationTag, } = decoded;
244
+ const { domain, tabId, reqId, user, recipient, amount, totalAmount, asset, timestamp, claimsVersion, validationRegistryAddress, validationRequestHash, validationChainId, validatorAddress, validatorAgentId, minValidationScore, validationSubjectHash, jobHash, requiredValidationTag, } = decoded;
241
245
  if (claimsVersion !== 2n) {
242
246
  throw new errors_1.VerificationError(`expected V2 claims version, got: ${claimsVersion}`);
243
247
  }
@@ -249,6 +253,7 @@ function buildDecodedV2Claims(decoded) {
249
253
  validatorAgentId: (0, utils_1.parseU256)(validatorAgentId),
250
254
  minValidationScore: Number(minValidationScore),
251
255
  validationSubjectHash: validationSubjectHash,
256
+ jobHash: jobHash,
252
257
  requiredValidationTag: requiredValidationTag,
253
258
  };
254
259
  return {
package/dist/models.d.ts CHANGED
@@ -47,6 +47,7 @@ export interface PaymentGuaranteeValidationPolicyV2 {
47
47
  validatorAgentId: bigint;
48
48
  minValidationScore: number;
49
49
  validationSubjectHash: string;
50
+ jobHash: string;
50
51
  requiredValidationTag: string;
51
52
  }
52
53
  /**
@@ -54,6 +55,7 @@ export interface PaymentGuaranteeValidationPolicyV2 {
54
55
  *
55
56
  * Compute `validationSubjectHash` via `computeValidationSubjectHash(baseClaims)` and
56
57
  * `validationRequestHash` via `computeValidationRequestHash(partialV2)` before constructing.
58
+ * The `jobHash` must be provided and included in the validation request hash.
57
59
  *
58
60
  * @throws {@link ValidationError} if `minValidationScore` is outside [1, 100].
59
61
  */
@@ -65,6 +67,7 @@ export declare class PaymentGuaranteeRequestClaimsV2 extends PaymentGuaranteeReq
65
67
  validatorAgentId: bigint;
66
68
  minValidationScore: number;
67
69
  validationSubjectHash: string;
70
+ jobHash: string;
68
71
  requiredValidationTag: string;
69
72
  constructor(init: {
70
73
  userAddress: string;
@@ -81,6 +84,7 @@ export declare class PaymentGuaranteeRequestClaimsV2 extends PaymentGuaranteeReq
81
84
  validatorAgentId: bigint;
82
85
  minValidationScore: number;
83
86
  validationSubjectHash: string;
87
+ jobHash: string;
84
88
  requiredValidationTag: string;
85
89
  });
86
90
  }
package/dist/models.js CHANGED
@@ -60,6 +60,7 @@ exports.PaymentGuaranteeRequestClaims = PaymentGuaranteeRequestClaims;
60
60
  *
61
61
  * Compute `validationSubjectHash` via `computeValidationSubjectHash(baseClaims)` and
62
62
  * `validationRequestHash` via `computeValidationRequestHash(partialV2)` before constructing.
63
+ * The `jobHash` must be provided and included in the validation request hash.
63
64
  *
64
65
  * @throws {@link ValidationError} if `minValidationScore` is outside [1, 100].
65
66
  */
@@ -71,6 +72,7 @@ class PaymentGuaranteeRequestClaimsV2 extends PaymentGuaranteeRequestClaims {
71
72
  validatorAgentId;
72
73
  minValidationScore;
73
74
  validationSubjectHash;
75
+ jobHash;
74
76
  requiredValidationTag;
75
77
  constructor(init) {
76
78
  super(init);
@@ -84,6 +86,7 @@ class PaymentGuaranteeRequestClaimsV2 extends PaymentGuaranteeRequestClaims {
84
86
  this.validatorAgentId = init.validatorAgentId;
85
87
  this.minValidationScore = init.minValidationScore;
86
88
  this.validationSubjectHash = (0, utils_1.ensureHexPrefix)(init.validationSubjectHash).toLowerCase();
89
+ this.jobHash = (0, utils_1.ensureHexPrefix)(init.jobHash).toLowerCase();
87
90
  this.requiredValidationTag = init.requiredValidationTag;
88
91
  }
89
92
  }
package/dist/payment.d.ts CHANGED
@@ -22,6 +22,7 @@ export interface PaymentPayloadClaimsV2 extends PaymentPayloadClaimsBase {
22
22
  validator_agent_id: string;
23
23
  min_validation_score: number;
24
24
  validation_subject_hash: string;
25
+ job_hash: string;
25
26
  required_validation_tag: string;
26
27
  }
27
28
  /** Assembled payment payload ready to be submitted to the core RPC `issueGuarantee` endpoint. */
@@ -41,7 +42,7 @@ export declare function serializePaymentClaims(claims: PaymentGuaranteeRequestCl
41
42
  /**
42
43
  * Serialize V2 payment claims to the wire format expected by the core RPC.
43
44
  *
44
- * Extends the V1 serialisation with the eight additional validation policy fields.
45
+ * Extends the V1 serialisation with the nine additional validation policy fields.
45
46
  *
46
47
  * @param claims - V2 payment guarantee request claims with validation policy.
47
48
  * @returns JSON-serialisable object with snake_case keys and hex-encoded `uint256` fields.
package/dist/payment.js CHANGED
@@ -27,7 +27,7 @@ function serializePaymentClaims(claims) {
27
27
  /**
28
28
  * Serialize V2 payment claims to the wire format expected by the core RPC.
29
29
  *
30
- * Extends the V1 serialisation with the eight additional validation policy fields.
30
+ * Extends the V1 serialisation with the nine additional validation policy fields.
31
31
  *
32
32
  * @param claims - V2 payment guarantee request claims with validation policy.
33
33
  * @returns JSON-serialisable object with snake_case keys and hex-encoded `uint256` fields.
@@ -43,6 +43,7 @@ function serializePaymentClaimsV2(claims) {
43
43
  validator_agent_id: (0, utils_1.serializeU256)(claims.validatorAgentId),
44
44
  min_validation_score: claims.minValidationScore,
45
45
  validation_subject_hash: claims.validationSubjectHash.toLowerCase(),
46
+ job_hash: claims.jobHash.toLowerCase(),
46
47
  required_validation_tag: claims.requiredValidationTag,
47
48
  };
48
49
  }
package/dist/signing.d.ts CHANGED
@@ -88,6 +88,9 @@ export declare const GUARANTEE_EIP712_TYPES_V2: {
88
88
  }, {
89
89
  readonly name: "validationSubjectHash";
90
90
  readonly type: "bytes32";
91
+ }, {
92
+ readonly name: "jobHash";
93
+ readonly type: "bytes32";
91
94
  }, {
92
95
  readonly name: "requiredValidationTag";
93
96
  readonly type: "string";
@@ -134,6 +137,7 @@ export type GuaranteeTypedDataV2 = {
134
137
  validatorAgentId: bigint;
135
138
  minValidationScore: number;
136
139
  validationSubjectHash: Hex;
140
+ jobHash: Hex;
137
141
  requiredValidationTag: string;
138
142
  };
139
143
  };
package/dist/signing.js CHANGED
@@ -52,6 +52,7 @@ exports.GUARANTEE_EIP712_TYPES_V2 = {
52
52
  { name: 'validatorAgentId', type: 'uint256' },
53
53
  { name: 'minValidationScore', type: 'uint8' },
54
54
  { name: 'validationSubjectHash', type: 'bytes32' },
55
+ { name: 'jobHash', type: 'bytes32' },
55
56
  { name: 'requiredValidationTag', type: 'string' },
56
57
  ],
57
58
  };
@@ -190,6 +191,7 @@ function buildGuaranteeTypedDataV2(params, claims) {
190
191
  validatorAgentId: claims.validatorAgentId,
191
192
  minValidationScore: claims.minValidationScore,
192
193
  validationSubjectHash: (0, utils_1.ensureHexPrefix)(claims.validationSubjectHash),
194
+ jobHash: (0, utils_1.ensureHexPrefix)(claims.jobHash),
193
195
  requiredValidationTag: claims.requiredValidationTag,
194
196
  },
195
197
  };
@@ -210,6 +212,7 @@ function encodeGuaranteeEip191V2(claims) {
210
212
  { type: 'uint256' },
211
213
  { type: 'uint8' },
212
214
  { type: 'bytes32' },
215
+ { type: 'bytes32' },
213
216
  { type: 'string' },
214
217
  ], [
215
218
  claims.userAddress,
@@ -230,6 +233,7 @@ function encodeGuaranteeEip191V2(claims) {
230
233
  (claims.validationSubjectHash.startsWith('0x')
231
234
  ? claims.validationSubjectHash
232
235
  : `0x${claims.validationSubjectHash}`),
236
+ (claims.jobHash.startsWith('0x') ? claims.jobHash : `0x${claims.jobHash}`),
233
237
  claims.requiredValidationTag,
234
238
  ]);
235
239
  }
@@ -3,7 +3,7 @@ import { PaymentGuaranteeRequestClaims, PaymentGuaranteeRequestClaimsV2 } from '
3
3
  /** Binding domain string used as a prefix when hashing validation subjects. */
4
4
  export declare const VALIDATION_SUBJECT_BINDING_DOMAIN = "4MICA_VALIDATION_SUBJECT_V1";
5
5
  /** Binding domain string used as a prefix when hashing validation requests. */
6
- export declare const VALIDATION_REQUEST_BINDING_DOMAIN = "4MICA_VALIDATION_REQUEST_V1";
6
+ export declare const VALIDATION_REQUEST_BINDING_DOMAIN = "4MICA_VALIDATION_REQUEST_V2";
7
7
  /**
8
8
  * Compute the `validationSubjectHash` for a V2 payment guarantee request.
9
9
  *
@@ -19,7 +19,7 @@ export declare function computeValidationSubjectHash(claims: PaymentGuaranteeReq
19
19
  * Compute the `validationRequestHash` for a V2 payment guarantee request.
20
20
  *
21
21
  * Binds the full validation policy (chain, registry, validator, score threshold,
22
- * subject hash, required tag) to a keccak256 hash prefixed by
22
+ * subject hash, required tag, job hash) to a keccak256 hash prefixed by
23
23
  * {@link VALIDATION_REQUEST_BINDING_DOMAIN}. This hash is included in the V2 claims
24
24
  * that are BLS-signed by the core service, allowing on-chain verification that the
25
25
  * validation policy was not tampered with.
@@ -8,7 +8,7 @@ const utils_1 = require("./utils");
8
8
  /** Binding domain string used as a prefix when hashing validation subjects. */
9
9
  exports.VALIDATION_SUBJECT_BINDING_DOMAIN = '4MICA_VALIDATION_SUBJECT_V1';
10
10
  /** Binding domain string used as a prefix when hashing validation requests. */
11
- exports.VALIDATION_REQUEST_BINDING_DOMAIN = '4MICA_VALIDATION_REQUEST_V1';
11
+ exports.VALIDATION_REQUEST_BINDING_DOMAIN = '4MICA_VALIDATION_REQUEST_V2';
12
12
  /**
13
13
  * Compute the `validationSubjectHash` for a V2 payment guarantee request.
14
14
  *
@@ -46,7 +46,7 @@ function computeValidationSubjectHash(claims) {
46
46
  * Compute the `validationRequestHash` for a V2 payment guarantee request.
47
47
  *
48
48
  * Binds the full validation policy (chain, registry, validator, score threshold,
49
- * subject hash, required tag) to a keccak256 hash prefixed by
49
+ * subject hash, required tag, job hash) to a keccak256 hash prefixed by
50
50
  * {@link VALIDATION_REQUEST_BINDING_DOMAIN}. This hash is included in the V2 claims
51
51
  * that are BLS-signed by the core service, allowing on-chain verification that the
52
52
  * validation policy was not tampered with.
@@ -68,6 +68,7 @@ function computeValidationRequestHash(claims) {
68
68
  { type: 'bytes32' },
69
69
  { type: 'uint8' },
70
70
  { type: 'bytes32' },
71
+ { type: 'bytes32' },
71
72
  ], [
72
73
  bindingDomain,
73
74
  BigInt(claims.validationChainId),
@@ -77,6 +78,7 @@ function computeValidationRequestHash(claims) {
77
78
  (0, utils_1.ensureHexPrefix)(claims.validationSubjectHash),
78
79
  claims.minValidationScore,
79
80
  tagHash,
81
+ (0, utils_1.ensureHexPrefix)(claims.jobHash),
80
82
  ]);
81
83
  return (0, viem_1.keccak256)(encoded);
82
84
  }
@@ -57,7 +57,7 @@ export declare class X402Flow {
57
57
  *
58
58
  * If `accepted.extra` contains all required validation policy fields
59
59
  * (`validationRegistryAddress`, `validatorAddress`, `validatorAgentId`,
60
- * `minValidationScore`, `validationChainId`), the claims are built as V2 with
60
+ * `minValidationScore`, `validationChainId`, `jobHash`), the claims are built as V2 with
61
61
  * the computed `validationSubjectHash` and `validationRequestHash`. Otherwise
62
62
  * falls back to V1 claims.
63
63
  *
@@ -26,7 +26,8 @@ function hasValidationPolicy(extra) {
26
26
  extra?.validatorAddress &&
27
27
  extra?.validatorAgentId !== undefined &&
28
28
  extra?.minValidationScore !== undefined &&
29
- extra?.validationChainId !== undefined);
29
+ extra?.validationChainId !== undefined &&
30
+ extra?.jobHash);
30
31
  }
31
32
  /**
32
33
  * Handles the x402 HTTP 402 payment protocol for 4Mica.
@@ -93,7 +94,7 @@ class X402Flow {
93
94
  *
94
95
  * If `accepted.extra` contains all required validation policy fields
95
96
  * (`validationRegistryAddress`, `validatorAddress`, `validatorAgentId`,
96
- * `minValidationScore`, `validationChainId`), the claims are built as V2 with
97
+ * `minValidationScore`, `validationChainId`, `jobHash`), the claims are built as V2 with
97
98
  * the computed `validationSubjectHash` and `validationRequestHash`. Otherwise
98
99
  * falls back to V1 claims.
99
100
  *
@@ -211,6 +212,7 @@ class X402Flow {
211
212
  validatorAgentId: (0, utils_1.parseU256)(extra.validatorAgentId),
212
213
  minValidationScore: extra.minValidationScore,
213
214
  validationSubjectHash,
215
+ jobHash: extra.jobHash,
214
216
  requiredValidationTag: extra.requiredValidationTag ?? '',
215
217
  });
216
218
  const validationRequestHash = (0, validation_1.computeValidationRequestHash)(partialClaims);
@@ -30,6 +30,7 @@ export interface PaymentRequirementsExtra {
30
30
  validatorAddress?: string;
31
31
  validatorAgentId?: string;
32
32
  minValidationScore?: number;
33
+ jobHash?: string;
33
34
  requiredValidationTag?: string;
34
35
  }
35
36
  export interface TabResponse {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4mica/sdk",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "TypeScript SDK for interacting with the 4Mica payment network",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,10 +39,12 @@
39
39
  "ethers"
40
40
  ],
41
41
  "scripts": {
42
- "build": "tsc -p tsconfig.build.json",
42
+ "clean": "node -e \"require('node:fs').rmSync('dist',{ recursive: true, force: true })\"",
43
+ "build": "npm run clean && tsc -p tsconfig.build.json",
43
44
  "test": "vitest run",
44
45
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
45
46
  "example:base-sepolia:x402-v2": "node_modules/.bin/tsx examples/base-sepolia-x402-facilitator-e2e.ts",
47
+ "example:manual:agents": "node_modules/.bin/tsx examples/manual-agents/demo.ts",
46
48
  "lint": "eslint . --ext .ts",
47
49
  "fmt": "prettier --check \"{src,tests}/**/*.{ts,js,json}\""
48
50
  },