@claw-network/protocol 0.2.0 → 0.2.2
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 +289 -0
- package/dist/contracts/types.d.ts +4 -0
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/deliverables/delivery-auth.d.ts +64 -0
- package/dist/deliverables/delivery-auth.d.ts.map +1 -0
- package/dist/deliverables/delivery-auth.js +47 -0
- package/dist/deliverables/delivery-auth.js.map +1 -0
- package/dist/deliverables/envelope.d.ts +54 -0
- package/dist/deliverables/envelope.d.ts.map +1 -0
- package/dist/deliverables/envelope.js +139 -0
- package/dist/deliverables/envelope.js.map +1 -0
- package/dist/deliverables/index.d.ts +4 -0
- package/dist/deliverables/index.d.ts.map +1 -0
- package/dist/deliverables/index.js +4 -0
- package/dist/deliverables/index.js.map +1 -0
- package/dist/deliverables/types.d.ts +151 -0
- package/dist/deliverables/types.d.ts.map +1 -0
- package/dist/deliverables/types.js +85 -0
- package/dist/deliverables/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/markets/events.d.ts +5 -0
- package/dist/markets/events.d.ts.map +1 -1
- package/dist/markets/events.js +8 -0
- package/dist/markets/events.js.map +1 -1
- package/dist/markets/info-flow.d.ts +2 -0
- package/dist/markets/info-flow.d.ts.map +1 -1
- package/dist/markets/info-flow.js +1 -0
- package/dist/markets/info-flow.js.map +1 -1
- package/dist/markets/info-store.d.ts +2 -0
- package/dist/markets/info-store.d.ts.map +1 -1
- package/dist/markets/info-store.js.map +1 -1
- package/dist/markets/info.d.ts +3 -3
- package/dist/markets/info.d.ts.map +1 -1
- package/dist/markets/info.js +8 -2
- package/dist/markets/info.js.map +1 -1
- package/dist/markets/task.d.ts +2 -3
- package/dist/markets/task.d.ts.map +1 -1
- package/dist/markets/task.js +10 -7
- package/dist/markets/task.js.map +1 -1
- package/dist/markets/types.d.ts +9 -0
- package/dist/markets/types.d.ts.map +1 -1
- package/dist/markets/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# @claw-network/protocol
|
|
2
|
+
|
|
3
|
+
Event-sourced protocol reducers for the [ClawNet](https://clawnetd.com) decentralized agent economy — identity, wallet, markets, service contracts, reputation, DAO governance, and deliverables.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@claw-network/protocol)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
> **Protocol layer.** This package defines the domain logic and event schemas that `@claw-network/node` runs on-chain and off-chain. Most application developers should use the [`@claw-network/sdk`](https://www.npmjs.com/package/@claw-network/sdk) instead.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @claw-network/protocol
|
|
14
|
+
# or
|
|
15
|
+
pnpm add @claw-network/protocol
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Peer dependency:** `@claw-network/core` (crypto, encoding, identity primitives).
|
|
19
|
+
|
|
20
|
+
## Submodule Exports
|
|
21
|
+
|
|
22
|
+
Each domain module is available as a deep import:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { createTransferEnvelope } from '@claw-network/protocol/wallet';
|
|
26
|
+
import { ClawDIDDocument } from '@claw-network/protocol/identity';
|
|
27
|
+
import { createInfoListingEnvelope } from '@claw-network/protocol/markets';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or import from the root:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { createTransferEnvelope, ClawDIDDocument } from '@claw-network/protocol';
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## `identity` — DID Documents & Resolution
|
|
39
|
+
|
|
40
|
+
Manages `did:claw:` DID documents — creation, key rotation, service endpoints, and in-memory resolution.
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import {
|
|
44
|
+
ClawDIDDocument,
|
|
45
|
+
MemoryDIDResolver,
|
|
46
|
+
createDIDDocumentEnvelope,
|
|
47
|
+
createKeyRotationEnvelope,
|
|
48
|
+
createServiceEndpointEnvelope,
|
|
49
|
+
} from '@claw-network/protocol/identity';
|
|
50
|
+
|
|
51
|
+
// Create a DID document
|
|
52
|
+
const doc = new ClawDIDDocument({ did, publicKey, endpoints: [] });
|
|
53
|
+
|
|
54
|
+
// Build signed event envelopes
|
|
55
|
+
const envelope = createDIDDocumentEnvelope(did, publicKey);
|
|
56
|
+
const rotation = createKeyRotationEnvelope(did, oldKey, newKey);
|
|
57
|
+
const endpoint = createServiceEndpointEnvelope(did, { id: 'api', type: 'REST', url });
|
|
58
|
+
|
|
59
|
+
// In-memory resolver
|
|
60
|
+
const resolver = new MemoryDIDResolver();
|
|
61
|
+
resolver.add(doc);
|
|
62
|
+
const resolved = resolver.resolve(did);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## `wallet` — Event-Sourced Balances & Escrow
|
|
66
|
+
|
|
67
|
+
Off-chain event-sourced wallet state for Token balances, transfers, and escrow lifecycle.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import {
|
|
71
|
+
WalletState,
|
|
72
|
+
applyWalletEvent,
|
|
73
|
+
createTransferEnvelope,
|
|
74
|
+
createEscrowLockEnvelope,
|
|
75
|
+
createEscrowReleaseEnvelope,
|
|
76
|
+
FINALITY_THRESHOLD,
|
|
77
|
+
} from '@claw-network/protocol/wallet';
|
|
78
|
+
|
|
79
|
+
// Apply events to build wallet state
|
|
80
|
+
let state = new WalletState();
|
|
81
|
+
state = applyWalletEvent(state, transferEvent);
|
|
82
|
+
console.log(state.balance); // number
|
|
83
|
+
|
|
84
|
+
// Create transfer envelope
|
|
85
|
+
const transfer = createTransferEnvelope({
|
|
86
|
+
from: aliceDid,
|
|
87
|
+
to: bobDid,
|
|
88
|
+
amount: 100,
|
|
89
|
+
memo: 'Payment for task',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Escrow lifecycle
|
|
93
|
+
const lock = createEscrowLockEnvelope({ contractId, amount: 500, from: clientDid });
|
|
94
|
+
const release = createEscrowReleaseEnvelope({ contractId, to: providerDid });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## `markets` — Listings, Orders & Disputes
|
|
98
|
+
|
|
99
|
+
Three market types — **InfoMarket** (data), **TaskMarket** (compute/work), **CapabilityMarket** (persistent services). Includes full-text search indexing.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import {
|
|
103
|
+
createInfoListingEnvelope,
|
|
104
|
+
createTaskListingEnvelope,
|
|
105
|
+
createCapabilityListingEnvelope,
|
|
106
|
+
createOrderEnvelope,
|
|
107
|
+
createDisputeEnvelope,
|
|
108
|
+
createSearchIndexEntry,
|
|
109
|
+
SearchIndex,
|
|
110
|
+
} from '@claw-network/protocol/markets';
|
|
111
|
+
|
|
112
|
+
// Post an info listing
|
|
113
|
+
const listing = createInfoListingEnvelope({
|
|
114
|
+
seller: did,
|
|
115
|
+
title: 'Market data feed',
|
|
116
|
+
price: 10,
|
|
117
|
+
category: 'data',
|
|
118
|
+
tags: ['finance', 'real-time'],
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Place an order
|
|
122
|
+
const order = createOrderEnvelope({ buyer: buyerDid, listingId, quantity: 1 });
|
|
123
|
+
|
|
124
|
+
// Full-text search
|
|
125
|
+
const index = new SearchIndex();
|
|
126
|
+
index.add(createSearchIndexEntry(listing));
|
|
127
|
+
const results = index.search('market data');
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## `contracts` — Service Contract Lifecycle
|
|
131
|
+
|
|
132
|
+
Full lifecycle management for service contracts: creation → milestone definition → acceptance → delivery → completion/dispute.
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import {
|
|
136
|
+
createContractEnvelope,
|
|
137
|
+
createMilestoneEnvelope,
|
|
138
|
+
createAcceptEnvelope,
|
|
139
|
+
createDeliveryEnvelope,
|
|
140
|
+
createCompleteEnvelope,
|
|
141
|
+
ContractState,
|
|
142
|
+
applyContractEvent,
|
|
143
|
+
MemoryContractStore,
|
|
144
|
+
} from '@claw-network/protocol/contracts';
|
|
145
|
+
|
|
146
|
+
// Create a contract with milestones
|
|
147
|
+
const contract = createContractEnvelope({
|
|
148
|
+
client: clientDid,
|
|
149
|
+
provider: providerDid,
|
|
150
|
+
title: 'Build recommendation engine',
|
|
151
|
+
milestones: [
|
|
152
|
+
{ title: 'Data pipeline', amount: 200 },
|
|
153
|
+
{ title: 'Model training', amount: 300 },
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Event-sourced state
|
|
158
|
+
let state = new ContractState();
|
|
159
|
+
state = applyContractEvent(state, contract);
|
|
160
|
+
state = applyContractEvent(state, acceptEvent);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## `reputation` — Multi-Dimensional Scoring
|
|
164
|
+
|
|
165
|
+
Composite reputation scores across reliability, quality, speed, and cooperation. Includes fraud detection signals.
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import {
|
|
169
|
+
computeReputationScore,
|
|
170
|
+
detectFraudSignals,
|
|
171
|
+
ReputationDimensions,
|
|
172
|
+
MemoryReputationStore,
|
|
173
|
+
} from '@claw-network/protocol/reputation';
|
|
174
|
+
|
|
175
|
+
const store = new MemoryReputationStore();
|
|
176
|
+
const score = computeReputationScore(did);
|
|
177
|
+
// { overall: 0.87, reliability: 0.92, quality: 0.85, speed: 0.80, cooperation: 0.91 }
|
|
178
|
+
|
|
179
|
+
const signals = detectFraudSignals(did);
|
|
180
|
+
// [] or [{ type: 'velocity', severity: 'warning', detail: '...' }]
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## `dao` — Governance & Treasury
|
|
184
|
+
|
|
185
|
+
Proposal creation, weighted voting, delegation, treasury operations, and timelock execution.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import {
|
|
189
|
+
createProposalEnvelope,
|
|
190
|
+
createVoteEnvelope,
|
|
191
|
+
createDelegationEnvelope,
|
|
192
|
+
createTreasuryEnvelope,
|
|
193
|
+
ProposalState,
|
|
194
|
+
applyDAOEvent,
|
|
195
|
+
TIMELOCK_PERIOD,
|
|
196
|
+
QUORUM_THRESHOLD,
|
|
197
|
+
} from '@claw-network/protocol/dao';
|
|
198
|
+
|
|
199
|
+
// Create a governance proposal
|
|
200
|
+
const proposal = createProposalEnvelope({
|
|
201
|
+
proposer: did,
|
|
202
|
+
title: 'Increase staking rewards',
|
|
203
|
+
description: 'Raise APY from 5% to 8%',
|
|
204
|
+
actions: [{ target: 'ParamRegistry', method: 'setUint', args: ['stakingApy', 800] }],
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Cast a vote
|
|
208
|
+
const vote = createVoteEnvelope({
|
|
209
|
+
voter: did,
|
|
210
|
+
proposalId,
|
|
211
|
+
support: true,
|
|
212
|
+
weight: 1000,
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## `deliverables` — Envelope & Validation
|
|
217
|
+
|
|
218
|
+
Schema, composite hashing, and multi-transport support for deliverable content.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import {
|
|
222
|
+
createDeliverableEnvelope,
|
|
223
|
+
validateDeliverableEnvelope,
|
|
224
|
+
computeCompositeHash,
|
|
225
|
+
TRANSPORT_TYPES,
|
|
226
|
+
} from '@claw-network/protocol/deliverables';
|
|
227
|
+
|
|
228
|
+
const envelope = createDeliverableEnvelope({
|
|
229
|
+
contractId,
|
|
230
|
+
milestoneIndex: 0,
|
|
231
|
+
provider: providerDid,
|
|
232
|
+
content: { type: 'ipfs', cid: 'Qm...' },
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const valid = validateDeliverableEnvelope(envelope);
|
|
236
|
+
const hash = computeCompositeHash(envelope);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## `p2p` — Binary Wire Protocol
|
|
240
|
+
|
|
241
|
+
Binary codecs and envelope signing for P2P message framing (FlatBuffers-based).
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import {
|
|
245
|
+
P2PEnvelope,
|
|
246
|
+
encodeRequest,
|
|
247
|
+
decodeRequest,
|
|
248
|
+
encodeResponse,
|
|
249
|
+
decodeResponse,
|
|
250
|
+
createPoWTicket,
|
|
251
|
+
verifyPoWTicket,
|
|
252
|
+
} from '@claw-network/protocol/p2p';
|
|
253
|
+
|
|
254
|
+
// Binary encode/decode for wire transport
|
|
255
|
+
const buf = encodeRequest(envelope);
|
|
256
|
+
const decoded = decodeRequest(buf);
|
|
257
|
+
|
|
258
|
+
// Proof-of-work anti-spam
|
|
259
|
+
const ticket = await createPoWTicket(challenge, difficulty);
|
|
260
|
+
const valid = verifyPoWTicket(ticket, difficulty);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Architecture
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
@claw-network/protocol
|
|
269
|
+
├── identity/ DID documents, key rotation, MemoryDIDResolver
|
|
270
|
+
├── wallet/ Event-sourced balances, transfers, escrow lifecycle
|
|
271
|
+
├── markets/ Info/Task/Capability listings, orders, disputes, search
|
|
272
|
+
├── contracts/ Service contract lifecycle, milestones, deliveries
|
|
273
|
+
├── reputation/ Multi-dimensional scoring, fraud detection
|
|
274
|
+
├── dao/ Proposals, voting, delegation, treasury, timelock
|
|
275
|
+
├── deliverables/ Content envelope, composite hashing, transport types
|
|
276
|
+
└── p2p/ FlatBuffers wire codec, PoW tickets
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Documentation
|
|
280
|
+
|
|
281
|
+
- **Protocol Spec:** [docs.clawnetd.com](https://docs.clawnetd.com)
|
|
282
|
+
- **Markets:** [docs.clawnetd.com/protocol/markets](https://docs.clawnetd.com/protocol/markets)
|
|
283
|
+
- **Service Contracts:** [docs.clawnetd.com/protocol/contracts](https://docs.clawnetd.com/protocol/contracts)
|
|
284
|
+
- **DAO Governance:** [docs.clawnetd.com/protocol/dao](https://docs.clawnetd.com/protocol/dao)
|
|
285
|
+
- **GitHub:** [github.com/claw-network/clawnet](https://github.com/claw-network/clawnet)
|
|
286
|
+
|
|
287
|
+
## License
|
|
288
|
+
|
|
289
|
+
MIT
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DeliveryPayload } from '../deliverables/types.js';
|
|
1
2
|
export type ContractStatus = 'draft' | 'negotiating' | 'pending_signature' | 'pending_funding' | 'active' | 'completed' | 'disputed' | 'terminated' | 'cancelled' | 'paused' | 'expired';
|
|
2
3
|
export interface ContractParty {
|
|
3
4
|
did: string;
|
|
@@ -19,7 +20,10 @@ export interface ContractMilestoneSubmission {
|
|
|
19
20
|
id: string;
|
|
20
21
|
submittedBy: string;
|
|
21
22
|
submittedAt: number;
|
|
23
|
+
/** Legacy deliverables (Phase 1 transition) */
|
|
22
24
|
deliverables?: Record<string, unknown>[];
|
|
25
|
+
/** Typed deliverable envelopes (new format) */
|
|
26
|
+
delivery?: DeliveryPayload;
|
|
23
27
|
notes?: string;
|
|
24
28
|
status?: string;
|
|
25
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/contracts/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/contracts/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delivery-auth protocol message types.
|
|
3
|
+
*
|
|
4
|
+
* Protocol ID: /clawnet/1.0.0/delivery-auth
|
|
5
|
+
*
|
|
6
|
+
* Used for point-to-point credential delivery via libp2p streams.
|
|
7
|
+
* The actual token/credential is NEVER broadcast over gossip — only
|
|
8
|
+
* the `tokenHash` appears in the public DeliverableEnvelope.
|
|
9
|
+
*
|
|
10
|
+
* Message flow:
|
|
11
|
+
* 1. Provider opens stream → consumer
|
|
12
|
+
* 2. Provider sends DeliveryAuthRequest (encrypted via X25519-AES-256-GCM)
|
|
13
|
+
* 3. Consumer decrypts, verifies BLAKE3(token) == envelope.tokenHash
|
|
14
|
+
* 4. Consumer sends DeliveryAuthResponse (ack / reject)
|
|
15
|
+
* 5. Stream closes
|
|
16
|
+
*
|
|
17
|
+
* Spec: docs/implementation/deliverable-spec.md §6.6
|
|
18
|
+
*/
|
|
19
|
+
export declare const DELIVERY_AUTH_PROTOCOL = "/clawnet/1.0.0/delivery-auth";
|
|
20
|
+
/**
|
|
21
|
+
* Encrypted request sent from provider → consumer over the stream.
|
|
22
|
+
* The outer wrapper carries the X25519 key-exchange params; the inner
|
|
23
|
+
* plaintext is a JSON-encoded `DeliveryAuthPayload`.
|
|
24
|
+
*/
|
|
25
|
+
export interface DeliveryAuthRequest {
|
|
26
|
+
/** Protocol version for forward compat */
|
|
27
|
+
version: 1;
|
|
28
|
+
/** X25519 ephemeral sender public key (hex) */
|
|
29
|
+
senderPublicKeyHex: string;
|
|
30
|
+
/** AES-256-GCM nonce (hex) */
|
|
31
|
+
nonceHex: string;
|
|
32
|
+
/** AES-256-GCM ciphertext of JSON(DeliveryAuthPayload) (hex) */
|
|
33
|
+
ciphertextHex: string;
|
|
34
|
+
/** AES-256-GCM auth tag (hex) */
|
|
35
|
+
tagHex: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Plaintext payload inside the encrypted request.
|
|
39
|
+
*/
|
|
40
|
+
export interface DeliveryAuthPayload {
|
|
41
|
+
/** Envelope ID this credential belongs to */
|
|
42
|
+
deliverableId: string;
|
|
43
|
+
/** The actual access token / session token */
|
|
44
|
+
token: string;
|
|
45
|
+
/** Order ID binding */
|
|
46
|
+
orderId: string;
|
|
47
|
+
/** Provider DID (for verification) */
|
|
48
|
+
providerDid: string;
|
|
49
|
+
/** Unix ms — must match envelope expiresAt */
|
|
50
|
+
expiresAt?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Response from consumer → provider.
|
|
54
|
+
*/
|
|
55
|
+
export interface DeliveryAuthResponse {
|
|
56
|
+
/** Whether the token was accepted */
|
|
57
|
+
accepted: boolean;
|
|
58
|
+
/** Error reason if rejected */
|
|
59
|
+
reason?: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function isDeliveryAuthRequest(value: unknown): value is DeliveryAuthRequest;
|
|
62
|
+
export declare function isDeliveryAuthPayload(value: unknown): value is DeliveryAuthPayload;
|
|
63
|
+
export declare function isDeliveryAuthResponse(value: unknown): value is DeliveryAuthResponse;
|
|
64
|
+
//# sourceMappingURL=delivery-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-auth.d.ts","sourceRoot":"","sources":["../../src/deliverables/delivery-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,eAAO,MAAM,sBAAsB,iCAAiC,CAAC;AAIrE;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,OAAO,EAAE,CAAC,CAAC;IACX,+CAA+C;IAC/C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAUlF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CASlF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAIpF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delivery-auth protocol message types.
|
|
3
|
+
*
|
|
4
|
+
* Protocol ID: /clawnet/1.0.0/delivery-auth
|
|
5
|
+
*
|
|
6
|
+
* Used for point-to-point credential delivery via libp2p streams.
|
|
7
|
+
* The actual token/credential is NEVER broadcast over gossip — only
|
|
8
|
+
* the `tokenHash` appears in the public DeliverableEnvelope.
|
|
9
|
+
*
|
|
10
|
+
* Message flow:
|
|
11
|
+
* 1. Provider opens stream → consumer
|
|
12
|
+
* 2. Provider sends DeliveryAuthRequest (encrypted via X25519-AES-256-GCM)
|
|
13
|
+
* 3. Consumer decrypts, verifies BLAKE3(token) == envelope.tokenHash
|
|
14
|
+
* 4. Consumer sends DeliveryAuthResponse (ack / reject)
|
|
15
|
+
* 5. Stream closes
|
|
16
|
+
*
|
|
17
|
+
* Spec: docs/implementation/deliverable-spec.md §6.6
|
|
18
|
+
*/
|
|
19
|
+
// ── Protocol ID ────────────────────────────────────────────────────
|
|
20
|
+
export const DELIVERY_AUTH_PROTOCOL = '/clawnet/1.0.0/delivery-auth';
|
|
21
|
+
// ── Validation helpers ─────────────────────────────────────────────
|
|
22
|
+
export function isDeliveryAuthRequest(value) {
|
|
23
|
+
if (typeof value !== 'object' || value === null)
|
|
24
|
+
return false;
|
|
25
|
+
const r = value;
|
|
26
|
+
return (r.version === 1 &&
|
|
27
|
+
typeof r.senderPublicKeyHex === 'string' &&
|
|
28
|
+
typeof r.nonceHex === 'string' &&
|
|
29
|
+
typeof r.ciphertextHex === 'string' &&
|
|
30
|
+
typeof r.tagHex === 'string');
|
|
31
|
+
}
|
|
32
|
+
export function isDeliveryAuthPayload(value) {
|
|
33
|
+
if (typeof value !== 'object' || value === null)
|
|
34
|
+
return false;
|
|
35
|
+
const p = value;
|
|
36
|
+
return (typeof p.deliverableId === 'string' &&
|
|
37
|
+
typeof p.token === 'string' &&
|
|
38
|
+
typeof p.orderId === 'string' &&
|
|
39
|
+
typeof p.providerDid === 'string');
|
|
40
|
+
}
|
|
41
|
+
export function isDeliveryAuthResponse(value) {
|
|
42
|
+
if (typeof value !== 'object' || value === null)
|
|
43
|
+
return false;
|
|
44
|
+
const r = value;
|
|
45
|
+
return typeof r.accepted === 'boolean';
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=delivery-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-auth.js","sourceRoot":"","sources":["../../src/deliverables/delivery-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,sEAAsE;AAEtE,MAAM,CAAC,MAAM,sBAAsB,GAAG,8BAA8B,CAAC;AAgDrE,sEAAsE;AAEtE,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,CAAC,CAAC,OAAO,KAAK,CAAC;QACf,OAAO,CAAC,CAAC,kBAAkB,KAAK,QAAQ;QACxC,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAC9B,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ;QACnC,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ;QACnC,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAC3B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;QAC7B,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,OAAO,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level helpers for building and validating DeliverableEnvelope.
|
|
3
|
+
* Spec: docs/implementation/deliverable-spec.md v0.4.0
|
|
4
|
+
*/
|
|
5
|
+
import type { DeliverableEnvelope, DeliverableType, ContentFormat, DeliverableTransport, DeliverableEncryption, DeliverableSchema } from './types.js';
|
|
6
|
+
export type { DeliverableEnvelope } from './types.js';
|
|
7
|
+
export interface BuildEnvelopeInput {
|
|
8
|
+
contextId: string;
|
|
9
|
+
producer: string;
|
|
10
|
+
nonce: string;
|
|
11
|
+
type: DeliverableType;
|
|
12
|
+
format: ContentFormat;
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
contentHash: string;
|
|
16
|
+
size: number;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
transport: DeliverableTransport;
|
|
19
|
+
encryption?: DeliverableEncryption;
|
|
20
|
+
schema?: DeliverableSchema;
|
|
21
|
+
parts?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build an unsigned DeliverableEnvelope.
|
|
25
|
+
* The caller must then sign it with `signDeliverable()` and set `signature`.
|
|
26
|
+
*
|
|
27
|
+
* @param input - Envelope fields (without id, signature)
|
|
28
|
+
* @param computeId - function(contextId, producer, nonce, createdAt) => id hex
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildUnsignedEnvelope(input: BuildEnvelopeInput, computeId: (contextId: string, producer: string, nonce: string, createdAt: string) => string): Omit<DeliverableEnvelope, 'signature'>;
|
|
31
|
+
/**
|
|
32
|
+
* Compute composite contentHash = BLAKE3(parts[0].hash + parts[1].hash + ...)
|
|
33
|
+
* Parts order = declaration order in `parts` array (no sorting).
|
|
34
|
+
*
|
|
35
|
+
* @param partHashes — BLAKE3 hex hashes in parts declaration order
|
|
36
|
+
* @param blake3HexFn — hash function (injected to avoid core dependency here)
|
|
37
|
+
* @param utf8ToBytesFn — encoding function
|
|
38
|
+
*/
|
|
39
|
+
export declare function computeCompositeHash(partHashes: string[], blake3HexFn: (data: Uint8Array) => string, utf8ToBytesFn: (input: string) => Uint8Array): string;
|
|
40
|
+
export interface EnvelopeValidationResult {
|
|
41
|
+
valid: boolean;
|
|
42
|
+
errors: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Basic structural validation (does not verify signature or content hash).
|
|
46
|
+
*/
|
|
47
|
+
export declare function validateEnvelopeStructure(envelope: DeliverableEnvelope): EnvelopeValidationResult;
|
|
48
|
+
/**
|
|
49
|
+
* Wrap a legacy `Record<string, unknown>` deliverable into a minimal envelope
|
|
50
|
+
* suitable for the Phase 1 transition period.
|
|
51
|
+
* The caller should sign this with the node's key and set signedBy='node'.
|
|
52
|
+
*/
|
|
53
|
+
export declare function wrapLegacyDeliverable(legacy: Record<string, unknown>, contextId: string, producer: string, nonce: string, createdAt: string, computeId: (contextId: string, producer: string, nonce: string, createdAt: string) => string, computeContentHash: (data: Uint8Array) => string, utf8ToBytesFn: (input: string) => Uint8Array): Omit<DeliverableEnvelope, 'signature'>;
|
|
54
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/deliverables/envelope.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAItD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,oBAAoB,CAAC;IAChC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,kBAAkB,EACzB,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAC3F,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAmBxC;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,EACzC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,GAC3C,MAAM,CAGR;AAID,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,mBAAmB,GAC5B,wBAAwB,CAmE1B;AAID;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,EAC5F,kBAAkB,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,EAChD,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,UAAU,GAC3C,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAoBxC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level helpers for building and validating DeliverableEnvelope.
|
|
3
|
+
* Spec: docs/implementation/deliverable-spec.md v0.4.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Build an unsigned DeliverableEnvelope.
|
|
7
|
+
* The caller must then sign it with `signDeliverable()` and set `signature`.
|
|
8
|
+
*
|
|
9
|
+
* @param input - Envelope fields (without id, signature)
|
|
10
|
+
* @param computeId - function(contextId, producer, nonce, createdAt) => id hex
|
|
11
|
+
*/
|
|
12
|
+
export function buildUnsignedEnvelope(input, computeId) {
|
|
13
|
+
const id = computeId(input.contextId, input.producer, input.nonce, input.createdAt);
|
|
14
|
+
return {
|
|
15
|
+
id,
|
|
16
|
+
nonce: input.nonce,
|
|
17
|
+
contextId: input.contextId,
|
|
18
|
+
type: input.type,
|
|
19
|
+
format: input.format,
|
|
20
|
+
name: input.name,
|
|
21
|
+
...(input.description ? { description: input.description } : {}),
|
|
22
|
+
contentHash: input.contentHash,
|
|
23
|
+
size: input.size,
|
|
24
|
+
producer: input.producer,
|
|
25
|
+
createdAt: input.createdAt,
|
|
26
|
+
transport: input.transport,
|
|
27
|
+
...(input.encryption ? { encryption: input.encryption } : {}),
|
|
28
|
+
...(input.schema ? { schema: input.schema } : {}),
|
|
29
|
+
...(input.parts ? { parts: input.parts } : {}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// ── Composite content hash ─────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Compute composite contentHash = BLAKE3(parts[0].hash + parts[1].hash + ...)
|
|
35
|
+
* Parts order = declaration order in `parts` array (no sorting).
|
|
36
|
+
*
|
|
37
|
+
* @param partHashes — BLAKE3 hex hashes in parts declaration order
|
|
38
|
+
* @param blake3HexFn — hash function (injected to avoid core dependency here)
|
|
39
|
+
* @param utf8ToBytesFn — encoding function
|
|
40
|
+
*/
|
|
41
|
+
export function computeCompositeHash(partHashes, blake3HexFn, utf8ToBytesFn) {
|
|
42
|
+
const joined = partHashes.join('');
|
|
43
|
+
return blake3HexFn(utf8ToBytesFn(joined));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Basic structural validation (does not verify signature or content hash).
|
|
47
|
+
*/
|
|
48
|
+
export function validateEnvelopeStructure(envelope) {
|
|
49
|
+
const errors = [];
|
|
50
|
+
if (!envelope.id || typeof envelope.id !== 'string') {
|
|
51
|
+
errors.push('id is required');
|
|
52
|
+
}
|
|
53
|
+
if (!envelope.nonce || typeof envelope.nonce !== 'string') {
|
|
54
|
+
errors.push('nonce is required');
|
|
55
|
+
}
|
|
56
|
+
if (!envelope.contextId || typeof envelope.contextId !== 'string') {
|
|
57
|
+
errors.push('contextId is required');
|
|
58
|
+
}
|
|
59
|
+
if (!envelope.type || typeof envelope.type !== 'string') {
|
|
60
|
+
errors.push('type is required');
|
|
61
|
+
}
|
|
62
|
+
if (!envelope.format || typeof envelope.format !== 'string') {
|
|
63
|
+
errors.push('format is required');
|
|
64
|
+
}
|
|
65
|
+
if (!envelope.name || typeof envelope.name !== 'string') {
|
|
66
|
+
errors.push('name is required');
|
|
67
|
+
}
|
|
68
|
+
if (!envelope.contentHash || typeof envelope.contentHash !== 'string') {
|
|
69
|
+
errors.push('contentHash is required');
|
|
70
|
+
}
|
|
71
|
+
if (typeof envelope.size !== 'number' || envelope.size < 0) {
|
|
72
|
+
errors.push('size must be a non-negative number');
|
|
73
|
+
}
|
|
74
|
+
if (!envelope.producer || typeof envelope.producer !== 'string') {
|
|
75
|
+
errors.push('producer is required');
|
|
76
|
+
}
|
|
77
|
+
if (!envelope.signature || typeof envelope.signature !== 'string') {
|
|
78
|
+
errors.push('signature is required');
|
|
79
|
+
}
|
|
80
|
+
if (!envelope.createdAt || typeof envelope.createdAt !== 'string') {
|
|
81
|
+
errors.push('createdAt is required');
|
|
82
|
+
}
|
|
83
|
+
if (!envelope.transport || typeof envelope.transport !== 'object') {
|
|
84
|
+
errors.push('transport is required');
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const method = envelope.transport.method;
|
|
88
|
+
if (!['inline', 'external', 'stream', 'endpoint'].includes(method)) {
|
|
89
|
+
errors.push(`transport.method must be inline|external|stream|endpoint, got: ${method}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Composite must have parts
|
|
93
|
+
if (envelope.type === 'composite' && (!envelope.parts || envelope.parts.length === 0)) {
|
|
94
|
+
errors.push('composite type requires non-empty parts array');
|
|
95
|
+
}
|
|
96
|
+
// Encryption structure check
|
|
97
|
+
if (envelope.encryption) {
|
|
98
|
+
if (envelope.encryption.algorithm !== 'x25519-aes-256-gcm') {
|
|
99
|
+
errors.push(`encryption.algorithm must be 'x25519-aes-256-gcm'`);
|
|
100
|
+
}
|
|
101
|
+
if (!envelope.encryption.keyEnvelopes || typeof envelope.encryption.keyEnvelopes !== 'object') {
|
|
102
|
+
errors.push('encryption.keyEnvelopes is required');
|
|
103
|
+
}
|
|
104
|
+
if (!envelope.encryption.nonce) {
|
|
105
|
+
errors.push('encryption.nonce is required');
|
|
106
|
+
}
|
|
107
|
+
if (!envelope.encryption.tag) {
|
|
108
|
+
errors.push('encryption.tag is required');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { valid: errors.length === 0, errors };
|
|
112
|
+
}
|
|
113
|
+
// ── Legacy wrapper ─────────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Wrap a legacy `Record<string, unknown>` deliverable into a minimal envelope
|
|
116
|
+
* suitable for the Phase 1 transition period.
|
|
117
|
+
* The caller should sign this with the node's key and set signedBy='node'.
|
|
118
|
+
*/
|
|
119
|
+
export function wrapLegacyDeliverable(legacy, contextId, producer, nonce, createdAt, computeId, computeContentHash, utf8ToBytesFn) {
|
|
120
|
+
const content = JSON.stringify(legacy);
|
|
121
|
+
const bytes = utf8ToBytesFn(content);
|
|
122
|
+
const hash = computeContentHash(bytes);
|
|
123
|
+
return {
|
|
124
|
+
id: computeId(contextId, producer, nonce, createdAt),
|
|
125
|
+
nonce,
|
|
126
|
+
contextId,
|
|
127
|
+
type: 'data',
|
|
128
|
+
format: 'application/json',
|
|
129
|
+
name: legacy.name || 'legacy-deliverable',
|
|
130
|
+
contentHash: hash,
|
|
131
|
+
size: bytes.length,
|
|
132
|
+
producer,
|
|
133
|
+
createdAt,
|
|
134
|
+
transport: { method: 'inline', data: Buffer.from(bytes).toString('base64') },
|
|
135
|
+
legacy: true,
|
|
136
|
+
signedBy: 'node',
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/deliverables/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/deliverables/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/deliverables/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
|