@agenticprimitives/agreements 0.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/dist/index.d.ts +110 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
- package/spec.md +5 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @agenticprimitives/agreements
|
|
2
|
+
|
|
3
|
+
**Two agents strike a deal. The chain should be able to prove the deal existed and how it ended — without ever learning what it was.** Most on-chain agreement records leak by design: parties, terms, schedules, all readable forever. This package is the SDK for `AgreementRegistry.sol`, a commitment-only registry — the chain stores keccak commitments over the party set, issuer, terms, and schedule, plus a status machine (`ACTIVE → COMPLETED / DISPUTED / REVOKED`). The human-readable agreement is a W3C verifiable credential held off chain by the parties; the chain holds only enough to anchor and adjudicate it.
|
|
4
|
+
|
|
5
|
+
Status transitions are as strict as registration is private: the contract recomputes the transition digest from the commitment, target status, and nullifier on chain, and requires party signatures over that recomputed value — never a caller-supplied hash, and never an issuer-only revoke.
|
|
6
|
+
|
|
7
|
+
> Part of [agenticprimitives](../../README.md) — the trust substrate for the agent economy: one canonical Smart Agent identity with custody, delegation, naming, credentials, and audit evidence designed as one system.
|
|
8
|
+
|
|
9
|
+
## What ships today
|
|
10
|
+
|
|
11
|
+
The W1 foundational slice — commitment math, typehashes, and payload shapes the contract relies on:
|
|
12
|
+
|
|
13
|
+
- **Commitment math** — `computeAgreementCommitment(...)` (spec 241 §3), `partySetCommitment(party1, party2)`, `issuerCommitment(issuer)`, `bytesCommitment(value)` for terms/schedule hashes.
|
|
14
|
+
- **`STATUS`** — discriminators matching `AgreementRegistry.STATUS_*` (`NONE` / `ACTIVE` / `COMPLETED` / `DISPUTED` / `REVOKED`).
|
|
15
|
+
- **`TRANSITION_TYPEHASH` + `transitionDigest(...)`** — the digest parties sign for a status transition. `updateStatus` recomputes it on chain (RW1-3, [ADR-0027](../../docs/architecture/decisions/0027-canonical-authority-binding.md)); `chainId` and the registry address are bound against cross-chain replay (AGR-1).
|
|
16
|
+
- **`AGREEMENT_ISSUER_TYPEHASH` + `issuerAttestationDigest(...)`** — the issuer's registration attestation, recomputed and verified on chain (SC-1).
|
|
17
|
+
- **`nullifierFor(...)`** — per-transition one-shot nullifier derivation.
|
|
18
|
+
- **Payload shapes** — `AgreementIssuancePayload`, `StatusUpdatePayload` (including the RW1-2 revealed-party fields the contract uses to recompute the commitment and check each signer is a party).
|
|
19
|
+
|
|
20
|
+
Every typehash MUST byte-equal its `AgreementRegistry.sol` constant — enforced by the cross-stack `check:eip712-typehash-equality` CI gate.
|
|
21
|
+
|
|
22
|
+
Planned for later waves per the [W1 implementation wave plan](../../docs/architecture/w1-implementation-wave-plan.md): the `AgreementCredential` shape (PD-22), `AgreementRegistryClient` read client, and the joint-assertion gateway helper that lets [`attestations`](../attestations) verify an agreement back-pointer before asserting on it.
|
|
23
|
+
|
|
24
|
+
## How it's different
|
|
25
|
+
|
|
26
|
+
Against EAS-style attestation registries and e-signature platforms:
|
|
27
|
+
|
|
28
|
+
1. **Commitment-only on chain.** No party addresses, no terms, no schedule in `register(...)` calldata — a static-analysis regression test enforces it (AR-12). Even timestamps are epoch-bucketed (spec 241 §3.4). Attestation registries publish the claim; this registry publishes only its shadow.
|
|
29
|
+
2. **The chain recomputes; it never trusts.** Transition digests and issuer attestations are recomputed on chain from revealed components — a leaked signature cannot be replayed against a different agreement, status, chain, or registry deployment.
|
|
30
|
+
3. **No issuer-only exit.** Completion, dispute, and revocation follow the bilateral / either-party matrix of spec 241 §5.4.1. The issuer who notarized the agreement cannot unilaterally kill it (D-18).
|
|
31
|
+
4. **Contracts and SDK are one artifact.** Typehash parity is CI-gated, so the client cannot drift from the chain — the failure mode that quietly breaks stitched signing stacks.
|
|
32
|
+
|
|
33
|
+
## Status
|
|
34
|
+
|
|
35
|
+
**Foundational (W1) — code shipped; not production enforcement.** The commitment math, typehashes, and payload shapes above are real and gate-checked; the credential shape, read client, and gateway land in Wave 4 per the [wave plan](../../docs/architecture/w1-implementation-wave-plan.md). See [AUDIT.md](./AUDIT.md).
|
|
36
|
+
|
|
37
|
+
> Testnet/pilot-ready. Production launch is gated on the public checklist in the root README — including third-party contract audit and governance key rotation. Track every security finding live in [`docs/audits/findings.yaml`](../../docs/audits/findings.yaml).
|
|
38
|
+
|
|
39
|
+
**Owns spine layers:** layer 8.
|
|
40
|
+
**Authoritative spec:** [`specs/241-agreement-commitment-registry.md`](../../specs/241-agreement-commitment-registry.md) — see `spec.md` for the symlink. Bounded surface: `CLAUDE.md` + `capability.manifest.json`.
|
|
41
|
+
|
|
42
|
+
## Build
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm --filter @agenticprimitives/agreements typecheck
|
|
46
|
+
pnpm --filter @agenticprimitives/agreements test
|
|
47
|
+
pnpm --filter @agenticprimitives/agreements build
|
|
48
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agenticprimitives/agreements — Commitment-only AgreementRegistry SDK +
|
|
3
|
+
* AgreementCredential shape (PD-22).
|
|
4
|
+
*
|
|
5
|
+
* Authoritative spec: specs/241-agreement-commitment-registry.md
|
|
6
|
+
*/
|
|
7
|
+
import type { Address, Hex } from '@agenticprimitives/types';
|
|
8
|
+
export declare const PACKAGE_NAME = "@agenticprimitives/agreements";
|
|
9
|
+
export declare const PACKAGE_STATUS: "w1-foundational";
|
|
10
|
+
export declare const SPEC_REF = "specs/241-agreement-commitment-registry.md";
|
|
11
|
+
export type Hex32 = `0x${string}`;
|
|
12
|
+
/** Status discriminators matching `AgreementRegistry.STATUS_*`. */
|
|
13
|
+
export declare const STATUS: {
|
|
14
|
+
readonly NONE: 0;
|
|
15
|
+
readonly ACTIVE: 1;
|
|
16
|
+
readonly COMPLETED: 2;
|
|
17
|
+
readonly DISPUTED: 3;
|
|
18
|
+
readonly REVOKED: 4;
|
|
19
|
+
};
|
|
20
|
+
export type AgreementStatus = (typeof STATUS)[keyof typeof STATUS];
|
|
21
|
+
/**
|
|
22
|
+
* RW1-3 (ADR-0027) — canonical transition typehash. MUST byte-equal
|
|
23
|
+
* `AgreementRegistry.TRANSITION_TYPEHASH`; enforced by the cross-stack
|
|
24
|
+
* typehash-equality gate (`check:eip712-typehash-equality`).
|
|
25
|
+
*/
|
|
26
|
+
export declare const TRANSITION_TYPEHASH: Hex32;
|
|
27
|
+
/**
|
|
28
|
+
* Recompute the transition digest the parties sign (RW1-3). Equals the contract's
|
|
29
|
+
* `keccak256(abi.encode(TRANSITION_TYPEHASH, agreementCommitment, toStatus, nullifier, chainId,
|
|
30
|
+
* verifyingContract))` — the on-chain `updateStatus` recomputes the same digest and verifies the party
|
|
31
|
+
* signatures against it. AGR-1: `chainId` + the registry address are bound (anti cross-chain/replay).
|
|
32
|
+
*/
|
|
33
|
+
export declare function transitionDigest(args: {
|
|
34
|
+
agreementCommitment: Hex32;
|
|
35
|
+
toStatus: AgreementStatus;
|
|
36
|
+
nullifier: Hex32;
|
|
37
|
+
chainId: bigint;
|
|
38
|
+
verifyingContract: Address;
|
|
39
|
+
}): Hex32;
|
|
40
|
+
/**
|
|
41
|
+
* SC-1 (audit 2026-06-09) — canonical issuer-attestation typehash. MUST byte-equal
|
|
42
|
+
* `AgreementRegistry.AGREEMENT_ISSUER_TYPEHASH`; locked by the cross-stack typehash-equality gate.
|
|
43
|
+
*/
|
|
44
|
+
export declare const AGREEMENT_ISSUER_TYPEHASH: Hex32;
|
|
45
|
+
/**
|
|
46
|
+
* Recompute the digest the issuer signs (SC-1). Equals the contract's
|
|
47
|
+
* `keccak256(abi.encode(AGREEMENT_ISSUER_TYPEHASH, agreementCommitment, schemaHash, issuer, chainId,
|
|
48
|
+
* verifyingContract))` — `register` recomputes the same digest and verifies the issuer signature
|
|
49
|
+
* against it (no caller-supplied attestation hash). Bind `chainId` + the registry address.
|
|
50
|
+
*/
|
|
51
|
+
export declare function issuerAttestationDigest(args: {
|
|
52
|
+
agreementCommitment: Hex32;
|
|
53
|
+
schemaHash: Hex32;
|
|
54
|
+
issuer: Address;
|
|
55
|
+
chainId: bigint;
|
|
56
|
+
verifyingContract: Address;
|
|
57
|
+
}): Hex32;
|
|
58
|
+
/** Recompute the commitment per spec 241 §3 (AR-01). */
|
|
59
|
+
export declare function computeAgreementCommitment(args: {
|
|
60
|
+
partySetCommitment: Hex32;
|
|
61
|
+
issuerCommitment: Hex32;
|
|
62
|
+
termsCommitment: Hex32;
|
|
63
|
+
scheduleCommitment: Hex32;
|
|
64
|
+
salt: bigint;
|
|
65
|
+
}): Hex32;
|
|
66
|
+
/** Canonical party commitment: keccak256(abi.encodePacked(party1, party2)) — order-sensitive. */
|
|
67
|
+
export declare function partySetCommitment(party1: Address, party2: Address): Hex32;
|
|
68
|
+
/** Issuer commitment: keccak256(abi.encodePacked(issuer)). */
|
|
69
|
+
export declare function issuerCommitment(issuer: Address): Hex32;
|
|
70
|
+
/** Canonical hash of an arbitrary string for terms / schedule commitments. */
|
|
71
|
+
export declare function bytesCommitment(value: string): Hex32;
|
|
72
|
+
/** Nullifier derivation helper (per-mandate one-shot). */
|
|
73
|
+
export declare function nullifierFor(args: {
|
|
74
|
+
agreementCommitment: Hex32;
|
|
75
|
+
toStatus: AgreementStatus;
|
|
76
|
+
party: Address;
|
|
77
|
+
secret: Hex32;
|
|
78
|
+
}): Hex32;
|
|
79
|
+
export interface AgreementIssuancePayload {
|
|
80
|
+
schemaHash: Hex32;
|
|
81
|
+
issuer: Address;
|
|
82
|
+
issuerSignature: Hex;
|
|
83
|
+
agreementCommitment: Hex32;
|
|
84
|
+
partySetCommitment: Hex32;
|
|
85
|
+
issuerCommitment: Hex32;
|
|
86
|
+
termsCommitment: Hex32;
|
|
87
|
+
scheduleCommitment: Hex32;
|
|
88
|
+
salt: bigint;
|
|
89
|
+
}
|
|
90
|
+
export interface StatusUpdatePayload {
|
|
91
|
+
agreementCommitment: Hex32;
|
|
92
|
+
toStatus: AgreementStatus;
|
|
93
|
+
nullifier: Hex32;
|
|
94
|
+
/** Signatures over the recomputed {@link transitionDigest} (RW1-3) — the
|
|
95
|
+
* contract no longer accepts a caller-supplied `transitionStructHash`. */
|
|
96
|
+
signature1: Hex;
|
|
97
|
+
signature2: Hex;
|
|
98
|
+
signer1: Address;
|
|
99
|
+
signer2: Address;
|
|
100
|
+
/** RW1-2 (ADR-0027): the revealed parties + commitment components. The
|
|
101
|
+
* contract recomputes the agreement commitment from these and requires each
|
|
102
|
+
* signer to be one of the two parties. */
|
|
103
|
+
party1: Address;
|
|
104
|
+
party2: Address;
|
|
105
|
+
issuerCommitment: Hex32;
|
|
106
|
+
termsCommitment: Hex32;
|
|
107
|
+
scheduleCommitment: Hex32;
|
|
108
|
+
commitmentSalt: bigint;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agenticprimitives/agreements — Commitment-only AgreementRegistry SDK +
|
|
3
|
+
* AgreementCredential shape (PD-22).
|
|
4
|
+
*
|
|
5
|
+
* Authoritative spec: specs/241-agreement-commitment-registry.md
|
|
6
|
+
*/
|
|
7
|
+
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
8
|
+
import { utf8ToBytes } from '@noble/hashes/utils.js';
|
|
9
|
+
export const PACKAGE_NAME = '@agenticprimitives/agreements';
|
|
10
|
+
export const PACKAGE_STATUS = 'w1-foundational';
|
|
11
|
+
export const SPEC_REF = 'specs/241-agreement-commitment-registry.md';
|
|
12
|
+
/** Status discriminators matching `AgreementRegistry.STATUS_*`. */
|
|
13
|
+
export const STATUS = {
|
|
14
|
+
NONE: 0,
|
|
15
|
+
ACTIVE: 1,
|
|
16
|
+
COMPLETED: 2,
|
|
17
|
+
DISPUTED: 3,
|
|
18
|
+
REVOKED: 4,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* RW1-3 (ADR-0027) — canonical transition typehash. MUST byte-equal
|
|
22
|
+
* `AgreementRegistry.TRANSITION_TYPEHASH`; enforced by the cross-stack
|
|
23
|
+
* typehash-equality gate (`check:eip712-typehash-equality`).
|
|
24
|
+
*/
|
|
25
|
+
export const TRANSITION_TYPEHASH = toHex32(keccak_256(
|
|
26
|
+
// AGR-1 (audit 2026-06-10): bind chainId + verifyingContract so a transition signature can't be
|
|
27
|
+
// replayed cross-chain or on a redeployed registry.
|
|
28
|
+
utf8ToBytes('AgreementTransition(bytes32 agreementCommitment,uint8 toStatus,bytes32 nullifier,uint256 chainId,address verifyingContract)')));
|
|
29
|
+
/**
|
|
30
|
+
* Recompute the transition digest the parties sign (RW1-3). Equals the contract's
|
|
31
|
+
* `keccak256(abi.encode(TRANSITION_TYPEHASH, agreementCommitment, toStatus, nullifier, chainId,
|
|
32
|
+
* verifyingContract))` — the on-chain `updateStatus` recomputes the same digest and verifies the party
|
|
33
|
+
* signatures against it. AGR-1: `chainId` + the registry address are bound (anti cross-chain/replay).
|
|
34
|
+
*/
|
|
35
|
+
export function transitionDigest(args) {
|
|
36
|
+
const buf = new Uint8Array(6 * 32);
|
|
37
|
+
writeHex32(buf, 0, TRANSITION_TYPEHASH);
|
|
38
|
+
writeHex32(buf, 32, args.agreementCommitment);
|
|
39
|
+
// uint8 toStatus, abi-encoded as a left-padded 32-byte word.
|
|
40
|
+
buf[95] = args.toStatus & 0xff;
|
|
41
|
+
writeHex32(buf, 96, args.nullifier);
|
|
42
|
+
writeUint256(buf, 128, args.chainId);
|
|
43
|
+
writeAddressLeftPadded(buf, 160, args.verifyingContract);
|
|
44
|
+
return toHex32(keccak_256(buf));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* SC-1 (audit 2026-06-09) — canonical issuer-attestation typehash. MUST byte-equal
|
|
48
|
+
* `AgreementRegistry.AGREEMENT_ISSUER_TYPEHASH`; locked by the cross-stack typehash-equality gate.
|
|
49
|
+
*/
|
|
50
|
+
export const AGREEMENT_ISSUER_TYPEHASH = toHex32(keccak_256(utf8ToBytes('AgreementIssuerAttestation(bytes32 agreementCommitment,bytes32 schemaHash,address issuer,uint256 chainId,address verifyingContract)')));
|
|
51
|
+
/**
|
|
52
|
+
* Recompute the digest the issuer signs (SC-1). Equals the contract's
|
|
53
|
+
* `keccak256(abi.encode(AGREEMENT_ISSUER_TYPEHASH, agreementCommitment, schemaHash, issuer, chainId,
|
|
54
|
+
* verifyingContract))` — `register` recomputes the same digest and verifies the issuer signature
|
|
55
|
+
* against it (no caller-supplied attestation hash). Bind `chainId` + the registry address.
|
|
56
|
+
*/
|
|
57
|
+
export function issuerAttestationDigest(args) {
|
|
58
|
+
const buf = new Uint8Array(6 * 32);
|
|
59
|
+
writeHex32(buf, 0, AGREEMENT_ISSUER_TYPEHASH);
|
|
60
|
+
writeHex32(buf, 32, args.agreementCommitment);
|
|
61
|
+
writeHex32(buf, 64, args.schemaHash);
|
|
62
|
+
writeAddressLeftPadded(buf, 96, args.issuer);
|
|
63
|
+
writeUint256(buf, 128, args.chainId);
|
|
64
|
+
writeAddressLeftPadded(buf, 160, args.verifyingContract);
|
|
65
|
+
return toHex32(keccak_256(buf));
|
|
66
|
+
}
|
|
67
|
+
/** Recompute the commitment per spec 241 §3 (AR-01). */
|
|
68
|
+
export function computeAgreementCommitment(args) {
|
|
69
|
+
const buf = new Uint8Array(5 * 32);
|
|
70
|
+
writeHex32(buf, 0, args.partySetCommitment);
|
|
71
|
+
writeHex32(buf, 32, args.issuerCommitment);
|
|
72
|
+
writeHex32(buf, 64, args.termsCommitment);
|
|
73
|
+
writeHex32(buf, 96, args.scheduleCommitment);
|
|
74
|
+
writeUint256(buf, 128, args.salt);
|
|
75
|
+
return toHex32(keccak_256(buf));
|
|
76
|
+
}
|
|
77
|
+
/** Canonical party commitment: keccak256(abi.encodePacked(party1, party2)) — order-sensitive. */
|
|
78
|
+
export function partySetCommitment(party1, party2) {
|
|
79
|
+
const buf = new Uint8Array(40);
|
|
80
|
+
writeAddressTight(buf, 0, party1);
|
|
81
|
+
writeAddressTight(buf, 20, party2);
|
|
82
|
+
return toHex32(keccak_256(buf));
|
|
83
|
+
}
|
|
84
|
+
/** Issuer commitment: keccak256(abi.encodePacked(issuer)). */
|
|
85
|
+
export function issuerCommitment(issuer) {
|
|
86
|
+
const buf = new Uint8Array(20);
|
|
87
|
+
writeAddressTight(buf, 0, issuer);
|
|
88
|
+
return toHex32(keccak_256(buf));
|
|
89
|
+
}
|
|
90
|
+
/** Canonical hash of an arbitrary string for terms / schedule commitments. */
|
|
91
|
+
export function bytesCommitment(value) {
|
|
92
|
+
return toHex32(keccak_256(utf8ToBytes(value)));
|
|
93
|
+
}
|
|
94
|
+
/** Nullifier derivation helper (per-mandate one-shot). */
|
|
95
|
+
export function nullifierFor(args) {
|
|
96
|
+
const buf = new Uint8Array(32 + 1 + 32 + 32);
|
|
97
|
+
writeHex32(buf, 0, args.agreementCommitment);
|
|
98
|
+
buf[32] = args.toStatus;
|
|
99
|
+
writeAddressLeftPadded(buf, 33, args.party);
|
|
100
|
+
writeHex32(buf, 65, args.secret);
|
|
101
|
+
return toHex32(keccak_256(buf));
|
|
102
|
+
}
|
|
103
|
+
// ─── Helpers ──────────────────────────────────────────────────────────
|
|
104
|
+
function toHex32(b) {
|
|
105
|
+
let hex = '0x';
|
|
106
|
+
for (const v of b)
|
|
107
|
+
hex += v.toString(16).padStart(2, '0');
|
|
108
|
+
return hex;
|
|
109
|
+
}
|
|
110
|
+
function writeAddressTight(buf, offset, addr) {
|
|
111
|
+
const clean = addr.toLowerCase().replace(/^0x/, '');
|
|
112
|
+
for (let i = 0; i < 20; i++) {
|
|
113
|
+
buf[offset + i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function writeAddressLeftPadded(buf, offset, addr) {
|
|
117
|
+
const clean = addr.toLowerCase().replace(/^0x/, '');
|
|
118
|
+
for (let i = 0; i < 20; i++) {
|
|
119
|
+
buf[offset + 12 + i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function writeHex32(buf, offset, h) {
|
|
123
|
+
const clean = h.toLowerCase().replace(/^0x/, '').padStart(64, '0');
|
|
124
|
+
for (let i = 0; i < 32; i++) {
|
|
125
|
+
buf[offset + i] = parseInt(clean.substring(i * 2, i * 2 + 2), 16);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function writeUint256(buf, offset, n) {
|
|
129
|
+
let v = n;
|
|
130
|
+
for (let i = 31; i >= 0; i--) {
|
|
131
|
+
buf[offset + i] = Number(v & 0xffn);
|
|
132
|
+
v = v >> 8n;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticprimitives/agreements",
|
|
3
|
+
"version": "0.0.0-alpha.3",
|
|
4
|
+
"description": "Commitment-only AgreementRegistry SDK. Owns AgreementCredential shape (PD-22) + commitment math + bilateral status transitions + joint-assertion gateway.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
|
|
9
|
+
"directory": "packages/agreements"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/agreements",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/agentictrustlabs/agenticprimitives/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"dist",
|
|
27
|
+
"spec.md",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.build.json",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:unit": "vitest run test/unit --passWithNoTests",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"clean": "rm -rf dist"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"viem": "^2.52.2"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"vitest": "^4.1.8",
|
|
46
|
+
"viem": "^2.52.2"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"agentic",
|
|
50
|
+
"primitives",
|
|
51
|
+
"agreements"
|
|
52
|
+
],
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@agenticprimitives/types": "workspace:*",
|
|
55
|
+
"@agenticprimitives/verifiable-credentials": "workspace:*",
|
|
56
|
+
"@noble/hashes": "^2.2.0"
|
|
57
|
+
}
|
|
58
|
+
}
|