@peac/protocol 0.9.18
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 +23 -0
- package/dist/discovery.d.ts +19 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +120 -0
- package/dist/discovery.js.map +1 -0
- package/dist/headers.d.ts +24 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +46 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/issue.d.ts +75 -0
- package/dist/issue.d.ts.map +1 -0
- package/dist/issue.js +97 -0
- package/dist/issue.js.map +1 -0
- package/dist/verify.d.ts +48 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +169 -0
- package/dist/verify.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @peac/protocol
|
|
2
|
+
|
|
3
|
+
PEAC protocol implementation - receipt issuance and verification
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @peac/protocol
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
See [peacprotocol.org](https://peacprotocol.org) for full documentation.
|
|
14
|
+
|
|
15
|
+
## License
|
|
16
|
+
|
|
17
|
+
Apache-2.0
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
PEAC Protocol is an open source project stewarded by Originary and community contributors.
|
|
22
|
+
|
|
23
|
+
[Originary](https://www.originary.xyz) | [Docs](https://peacprotocol.org) | [GitHub](https://github.com/peacprotocol/peac)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PEAC discovery manifest parsing (/.well-known/peac.txt)
|
|
3
|
+
*/
|
|
4
|
+
import { PEACDiscovery } from '@peac/schema';
|
|
5
|
+
/**
|
|
6
|
+
* Parse a PEAC discovery manifest from YAML-like text
|
|
7
|
+
*
|
|
8
|
+
* @param text - PEAC discovery text (≤20 lines, ≤2000 bytes)
|
|
9
|
+
* @returns Parsed discovery manifest
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseDiscovery(text: string): PEACDiscovery;
|
|
12
|
+
/**
|
|
13
|
+
* Fetch and parse PEAC discovery from an issuer URL
|
|
14
|
+
*
|
|
15
|
+
* @param issuerUrl - Issuer URL (https://)
|
|
16
|
+
* @returns Parsed discovery manifest
|
|
17
|
+
*/
|
|
18
|
+
export declare function fetchDiscovery(issuerUrl: string): Promise<PEACDiscovery>;
|
|
19
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAA4B,MAAM,cAAc,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAkF1D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA0B9E"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PEAC discovery manifest parsing (/.well-known/peac.txt)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseDiscovery = parseDiscovery;
|
|
7
|
+
exports.fetchDiscovery = fetchDiscovery;
|
|
8
|
+
const schema_1 = require("@peac/schema");
|
|
9
|
+
/**
|
|
10
|
+
* Parse a PEAC discovery manifest from YAML-like text
|
|
11
|
+
*
|
|
12
|
+
* @param text - PEAC discovery text (≤20 lines, ≤2000 bytes)
|
|
13
|
+
* @returns Parsed discovery manifest
|
|
14
|
+
*/
|
|
15
|
+
function parseDiscovery(text) {
|
|
16
|
+
// Validate size
|
|
17
|
+
const bytes = new TextEncoder().encode(text).length;
|
|
18
|
+
if (bytes > schema_1.PEAC_DISCOVERY_MAX_BYTES) {
|
|
19
|
+
throw new Error(`Discovery manifest exceeds ${schema_1.PEAC_DISCOVERY_MAX_BYTES} bytes (got ${bytes})`);
|
|
20
|
+
}
|
|
21
|
+
const lines = text.trim().split('\n');
|
|
22
|
+
if (lines.length > 20) {
|
|
23
|
+
throw new Error(`Discovery manifest exceeds 20 lines (got ${lines.length})`);
|
|
24
|
+
}
|
|
25
|
+
const discovery = {
|
|
26
|
+
payments: [],
|
|
27
|
+
};
|
|
28
|
+
let inPayments = false;
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
const trimmed = line.trim();
|
|
31
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
32
|
+
continue; // Skip empty lines and comments
|
|
33
|
+
}
|
|
34
|
+
if (trimmed === 'payments:') {
|
|
35
|
+
inPayments = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (inPayments) {
|
|
39
|
+
// Support both "rail:" (new) and "scheme:" (deprecated) for backward compatibility
|
|
40
|
+
if (trimmed.startsWith('- rail:') || trimmed.startsWith('- scheme:')) {
|
|
41
|
+
const rail = trimmed.replace(/^- (rail|scheme):/, '').trim();
|
|
42
|
+
discovery.payments.push({ rail });
|
|
43
|
+
}
|
|
44
|
+
else if (trimmed.startsWith('info:')) {
|
|
45
|
+
const info = trimmed.replace('info:', '').trim();
|
|
46
|
+
if (discovery.payments.length > 0) {
|
|
47
|
+
discovery.payments[discovery.payments.length - 1].info = info;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (!trimmed.startsWith(' ') && trimmed.includes(':')) {
|
|
51
|
+
// New top-level key, exit payments section
|
|
52
|
+
inPayments = false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!inPayments && trimmed.includes(':')) {
|
|
56
|
+
const [key, ...valueParts] = trimmed.split(':');
|
|
57
|
+
const value = valueParts.join(':').trim();
|
|
58
|
+
switch (key.trim()) {
|
|
59
|
+
case 'version':
|
|
60
|
+
discovery.version = value;
|
|
61
|
+
break;
|
|
62
|
+
case 'issuer':
|
|
63
|
+
discovery.issuer = value;
|
|
64
|
+
break;
|
|
65
|
+
case 'verify':
|
|
66
|
+
discovery.verify = value;
|
|
67
|
+
break;
|
|
68
|
+
case 'jwks':
|
|
69
|
+
discovery.jwks = value;
|
|
70
|
+
break;
|
|
71
|
+
case 'aipref':
|
|
72
|
+
discovery.aipref = value;
|
|
73
|
+
break;
|
|
74
|
+
case 'slos':
|
|
75
|
+
discovery.slos = value;
|
|
76
|
+
break;
|
|
77
|
+
case 'security':
|
|
78
|
+
discovery.security = value;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Validate required fields
|
|
84
|
+
if (!discovery.version)
|
|
85
|
+
throw new Error('Missing required field: version');
|
|
86
|
+
if (!discovery.issuer)
|
|
87
|
+
throw new Error('Missing required field: issuer');
|
|
88
|
+
if (!discovery.verify)
|
|
89
|
+
throw new Error('Missing required field: verify');
|
|
90
|
+
if (!discovery.jwks)
|
|
91
|
+
throw new Error('Missing required field: jwks');
|
|
92
|
+
return discovery;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Fetch and parse PEAC discovery from an issuer URL
|
|
96
|
+
*
|
|
97
|
+
* @param issuerUrl - Issuer URL (https://)
|
|
98
|
+
* @returns Parsed discovery manifest
|
|
99
|
+
*/
|
|
100
|
+
async function fetchDiscovery(issuerUrl) {
|
|
101
|
+
if (!issuerUrl.startsWith('https://')) {
|
|
102
|
+
throw new Error('Issuer URL must be https://');
|
|
103
|
+
}
|
|
104
|
+
const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;
|
|
105
|
+
try {
|
|
106
|
+
const resp = await fetch(discoveryUrl, {
|
|
107
|
+
headers: { Accept: 'text/plain' },
|
|
108
|
+
signal: AbortSignal.timeout(5000),
|
|
109
|
+
});
|
|
110
|
+
if (!resp.ok) {
|
|
111
|
+
throw new Error(`Discovery fetch failed: ${resp.status}`);
|
|
112
|
+
}
|
|
113
|
+
const text = await resp.text();
|
|
114
|
+
return parseDiscovery(text);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
throw new Error(`Failed to fetch discovery from ${issuerUrl}: ${err instanceof Error ? err.message : String(err)}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP header utilities for PEAC receipts
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Set PEAC-Receipt header on a response
|
|
6
|
+
*
|
|
7
|
+
* @param headers - Headers object (e.g., Response.headers)
|
|
8
|
+
* @param receiptJws - JWS compact serialization
|
|
9
|
+
*/
|
|
10
|
+
export declare function setReceiptHeader(headers: Headers, receiptJws: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Get PEAC-Receipt header from a request/response
|
|
13
|
+
*
|
|
14
|
+
* @param headers - Headers object
|
|
15
|
+
* @returns JWS compact serialization, or null if not present
|
|
16
|
+
*/
|
|
17
|
+
export declare function getReceiptHeader(headers: Headers): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Set Vary: PEAC-Receipt header for caching
|
|
20
|
+
*
|
|
21
|
+
* @param headers - Response headers
|
|
22
|
+
*/
|
|
23
|
+
export declare function setVaryHeader(headers: Headers): void;
|
|
24
|
+
//# sourceMappingURL=headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAE3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAWpD"}
|
package/dist/headers.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HTTP header utilities for PEAC receipts
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.setReceiptHeader = setReceiptHeader;
|
|
7
|
+
exports.getReceiptHeader = getReceiptHeader;
|
|
8
|
+
exports.setVaryHeader = setVaryHeader;
|
|
9
|
+
const schema_1 = require("@peac/schema");
|
|
10
|
+
/**
|
|
11
|
+
* Set PEAC-Receipt header on a response
|
|
12
|
+
*
|
|
13
|
+
* @param headers - Headers object (e.g., Response.headers)
|
|
14
|
+
* @param receiptJws - JWS compact serialization
|
|
15
|
+
*/
|
|
16
|
+
function setReceiptHeader(headers, receiptJws) {
|
|
17
|
+
headers.set(schema_1.PEAC_RECEIPT_HEADER, receiptJws);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get PEAC-Receipt header from a request/response
|
|
21
|
+
*
|
|
22
|
+
* @param headers - Headers object
|
|
23
|
+
* @returns JWS compact serialization, or null if not present
|
|
24
|
+
*/
|
|
25
|
+
function getReceiptHeader(headers) {
|
|
26
|
+
return headers.get(schema_1.PEAC_RECEIPT_HEADER);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Set Vary: PEAC-Receipt header for caching
|
|
30
|
+
*
|
|
31
|
+
* @param headers - Response headers
|
|
32
|
+
*/
|
|
33
|
+
function setVaryHeader(headers) {
|
|
34
|
+
const existing = headers.get('Vary');
|
|
35
|
+
if (existing) {
|
|
36
|
+
// Append to existing Vary header
|
|
37
|
+
const varies = existing.split(',').map((v) => v.trim());
|
|
38
|
+
if (!varies.includes(schema_1.PEAC_RECEIPT_HEADER)) {
|
|
39
|
+
headers.set('Vary', `${existing}, ${schema_1.PEAC_RECEIPT_HEADER}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
headers.set('Vary', schema_1.PEAC_RECEIPT_HEADER);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headers.js","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAUH,4CAEC;AAQD,4CAEC;AAOD,sCAWC;AAtCD,yCAAmD;AAEnD;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,OAAgB,EAAE,UAAkB;IACnE,OAAO,CAAC,GAAG,CAAC,4BAAmB,EAAE,UAAU,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,4BAAmB,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,OAAgB;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,EAAE,CAAC;QACb,iCAAiC;QACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAAmB,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,QAAQ,KAAK,4BAAmB,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,4BAAmB,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PEAC Protocol Implementation
|
|
4
|
+
* Receipt issuance and verification with JWKS caching
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./issue"), exports);
|
|
22
|
+
__exportStar(require("./verify"), exports);
|
|
23
|
+
__exportStar(require("./headers"), exports);
|
|
24
|
+
__exportStar(require("./discovery"), exports);
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,2CAAyB;AACzB,4CAA0B;AAC1B,8CAA4B"}
|
package/dist/issue.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Receipt issuance
|
|
3
|
+
* Validates input, generates UUIDv7 rid, and signs with Ed25519
|
|
4
|
+
*/
|
|
5
|
+
import { PEACReceiptClaims, SubjectProfileSnapshot } from '@peac/schema';
|
|
6
|
+
/**
|
|
7
|
+
* Options for issuing a receipt
|
|
8
|
+
*/
|
|
9
|
+
export interface IssueOptions {
|
|
10
|
+
/** Issuer URL (https://) */
|
|
11
|
+
iss: string;
|
|
12
|
+
/** Audience / resource URL (https://) */
|
|
13
|
+
aud: string;
|
|
14
|
+
/** Amount in smallest currency unit */
|
|
15
|
+
amt: number;
|
|
16
|
+
/** ISO 4217 currency code (uppercase) */
|
|
17
|
+
cur: string;
|
|
18
|
+
/** Payment rail identifier */
|
|
19
|
+
rail: string;
|
|
20
|
+
/** Rail-specific payment reference */
|
|
21
|
+
reference: string;
|
|
22
|
+
/** Asset transferred (e.g., "USD", "USDC", "BTC") - defaults to currency if not provided */
|
|
23
|
+
asset?: string;
|
|
24
|
+
/** Environment ("live" or "test") - defaults to "test" */
|
|
25
|
+
env?: 'live' | 'test';
|
|
26
|
+
/** Network/rail identifier (optional, SHOULD for crypto) */
|
|
27
|
+
network?: string;
|
|
28
|
+
/** Facilitator reference (optional) */
|
|
29
|
+
facilitator_ref?: string;
|
|
30
|
+
/** Rail-specific evidence (opaque) - defaults to empty object if not provided */
|
|
31
|
+
evidence?: unknown;
|
|
32
|
+
/** Idempotency key (optional) */
|
|
33
|
+
idempotency_key?: string;
|
|
34
|
+
/** Rail-specific metadata (optional) */
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
/** Subject URI (optional) */
|
|
37
|
+
subject?: string;
|
|
38
|
+
/** Extensions (optional) */
|
|
39
|
+
ext?: PEACReceiptClaims['ext'];
|
|
40
|
+
/** Expiry timestamp (Unix seconds, optional) */
|
|
41
|
+
exp?: number;
|
|
42
|
+
/** Subject profile snapshot for envelope (v0.9.17+, optional) */
|
|
43
|
+
subject_snapshot?: SubjectProfileSnapshot;
|
|
44
|
+
/** Ed25519 private key (32 bytes) */
|
|
45
|
+
privateKey: Uint8Array;
|
|
46
|
+
/** Key ID (ISO 8601 timestamp) */
|
|
47
|
+
kid: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Result of issuing a receipt
|
|
51
|
+
*/
|
|
52
|
+
export interface IssueResult {
|
|
53
|
+
/** JWS compact serialization */
|
|
54
|
+
jws: string;
|
|
55
|
+
/** Validated subject snapshot (if provided) */
|
|
56
|
+
subject_snapshot?: SubjectProfileSnapshot;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Issue a PEAC receipt
|
|
60
|
+
*
|
|
61
|
+
* @param options - Receipt options
|
|
62
|
+
* @returns Issue result with JWS and optional subject_snapshot
|
|
63
|
+
*/
|
|
64
|
+
export declare function issue(options: IssueOptions): Promise<IssueResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Issue a PEAC receipt and return just the JWS string
|
|
67
|
+
*
|
|
68
|
+
* Convenience wrapper for common header-centric flows where only the JWS is needed.
|
|
69
|
+
* For access to validated subject_snapshot, use issue() instead.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Receipt options
|
|
72
|
+
* @returns JWS compact serialization
|
|
73
|
+
*/
|
|
74
|
+
export declare function issueJws(options: IssueOptions): Promise<string>;
|
|
75
|
+
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../src/issue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACL,iBAAiB,EAEjB,sBAAsB,EAEvB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IAEZ,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IAEZ,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IAEZ,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IAEZ,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IAEb,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAElB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,iCAAiC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAE/B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAE1C,qCAAqC;IACrC,UAAU,EAAE,UAAU,CAAC;IAEvB,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IAEZ,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2EvE;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrE"}
|
package/dist/issue.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Receipt issuance
|
|
4
|
+
* Validates input, generates UUIDv7 rid, and signs with Ed25519
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.issue = issue;
|
|
8
|
+
exports.issueJws = issueJws;
|
|
9
|
+
const uuidv7_1 = require("uuidv7");
|
|
10
|
+
const crypto_1 = require("@peac/crypto");
|
|
11
|
+
const schema_1 = require("@peac/schema");
|
|
12
|
+
/**
|
|
13
|
+
* Issue a PEAC receipt
|
|
14
|
+
*
|
|
15
|
+
* @param options - Receipt options
|
|
16
|
+
* @returns Issue result with JWS and optional subject_snapshot
|
|
17
|
+
*/
|
|
18
|
+
async function issue(options) {
|
|
19
|
+
// Validate URLs
|
|
20
|
+
if (!options.iss.startsWith('https://')) {
|
|
21
|
+
throw new Error('Issuer URL must start with https://');
|
|
22
|
+
}
|
|
23
|
+
if (!options.aud.startsWith('https://')) {
|
|
24
|
+
throw new Error('Audience URL must start with https://');
|
|
25
|
+
}
|
|
26
|
+
if (options.subject && !options.subject.startsWith('https://')) {
|
|
27
|
+
throw new Error('Subject URI must start with https://');
|
|
28
|
+
}
|
|
29
|
+
// Validate currency code
|
|
30
|
+
if (!/^[A-Z]{3}$/.test(options.cur)) {
|
|
31
|
+
throw new Error('Currency must be ISO 4217 uppercase (e.g., USD)');
|
|
32
|
+
}
|
|
33
|
+
// Validate amount
|
|
34
|
+
if (!Number.isInteger(options.amt) || options.amt < 0) {
|
|
35
|
+
throw new Error('Amount must be a non-negative integer');
|
|
36
|
+
}
|
|
37
|
+
// Validate expiry (if provided)
|
|
38
|
+
if (options.exp !== undefined) {
|
|
39
|
+
if (!Number.isInteger(options.exp) || options.exp < 0) {
|
|
40
|
+
throw new Error('Expiry must be a non-negative integer');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Generate UUIDv7 for receipt ID
|
|
44
|
+
const rid = (0, uuidv7_1.uuidv7)();
|
|
45
|
+
// Get current timestamp
|
|
46
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
47
|
+
// Build receipt claims
|
|
48
|
+
const claims = {
|
|
49
|
+
iss: options.iss,
|
|
50
|
+
aud: options.aud,
|
|
51
|
+
iat,
|
|
52
|
+
rid,
|
|
53
|
+
amt: options.amt,
|
|
54
|
+
cur: options.cur,
|
|
55
|
+
payment: {
|
|
56
|
+
rail: options.rail,
|
|
57
|
+
reference: options.reference,
|
|
58
|
+
amount: options.amt,
|
|
59
|
+
currency: options.cur,
|
|
60
|
+
asset: options.asset ?? options.cur, // Default asset to currency for backward compatibility
|
|
61
|
+
env: options.env ?? 'test', // Default to test environment for backward compatibility
|
|
62
|
+
evidence: options.evidence ?? {}, // Default to empty object for backward compatibility
|
|
63
|
+
...(options.network && { network: options.network }),
|
|
64
|
+
...(options.facilitator_ref && { facilitator_ref: options.facilitator_ref }),
|
|
65
|
+
...(options.idempotency_key && { idempotency_key: options.idempotency_key }),
|
|
66
|
+
...(options.metadata && { metadata: options.metadata }),
|
|
67
|
+
},
|
|
68
|
+
...(options.exp && { exp: options.exp }),
|
|
69
|
+
...(options.subject && { subject: { uri: options.subject } }),
|
|
70
|
+
...(options.ext && { ext: options.ext }),
|
|
71
|
+
};
|
|
72
|
+
// Validate claims with Zod
|
|
73
|
+
schema_1.ReceiptClaims.parse(claims);
|
|
74
|
+
// Validate subject_snapshot if provided (v0.9.17+)
|
|
75
|
+
// This validates schema and logs advisory PII warning if applicable
|
|
76
|
+
const validatedSnapshot = (0, schema_1.validateSubjectSnapshot)(options.subject_snapshot);
|
|
77
|
+
// Sign with Ed25519
|
|
78
|
+
const jws = await (0, crypto_1.sign)(claims, options.privateKey, options.kid);
|
|
79
|
+
return {
|
|
80
|
+
jws,
|
|
81
|
+
...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Issue a PEAC receipt and return just the JWS string
|
|
86
|
+
*
|
|
87
|
+
* Convenience wrapper for common header-centric flows where only the JWS is needed.
|
|
88
|
+
* For access to validated subject_snapshot, use issue() instead.
|
|
89
|
+
*
|
|
90
|
+
* @param options - Receipt options
|
|
91
|
+
* @returns JWS compact serialization
|
|
92
|
+
*/
|
|
93
|
+
async function issueJws(options) {
|
|
94
|
+
const result = await issue(options);
|
|
95
|
+
return result.jws;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../src/issue.ts"],"names":[],"mappings":"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"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Receipt verification with JWKS fetching and caching
|
|
3
|
+
*/
|
|
4
|
+
import { PEACReceiptClaims, SubjectProfileSnapshot } from '@peac/schema';
|
|
5
|
+
/**
|
|
6
|
+
* Verification result
|
|
7
|
+
*/
|
|
8
|
+
export interface VerifyResult {
|
|
9
|
+
/** Verification succeeded */
|
|
10
|
+
ok: true;
|
|
11
|
+
/** Receipt claims */
|
|
12
|
+
claims: PEACReceiptClaims;
|
|
13
|
+
/** Subject profile snapshot (v0.9.17+, if provided) */
|
|
14
|
+
subject_snapshot?: SubjectProfileSnapshot;
|
|
15
|
+
/** Performance metrics */
|
|
16
|
+
perf?: {
|
|
17
|
+
verify_ms: number;
|
|
18
|
+
jwks_fetch_ms?: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Verification failure
|
|
23
|
+
*/
|
|
24
|
+
export interface VerifyFailure {
|
|
25
|
+
/** Verification failed */
|
|
26
|
+
ok: false;
|
|
27
|
+
/** Error reason */
|
|
28
|
+
reason: string;
|
|
29
|
+
/** Error details */
|
|
30
|
+
details?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for verifying a receipt
|
|
34
|
+
*/
|
|
35
|
+
export interface VerifyOptions {
|
|
36
|
+
/** JWS compact serialization */
|
|
37
|
+
receiptJws: string;
|
|
38
|
+
/** Subject profile snapshot (v0.9.17+, optional envelope metadata) */
|
|
39
|
+
subject_snapshot?: SubjectProfileSnapshot;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Verify a PEAC receipt JWS
|
|
43
|
+
*
|
|
44
|
+
* @param optionsOrJws - Verify options or JWS compact serialization (for backwards compatibility)
|
|
45
|
+
* @returns Verification result or failure
|
|
46
|
+
*/
|
|
47
|
+
export declare function verifyReceipt(optionsOrJws: string | VerifyOptions): Promise<VerifyResult | VerifyFailure>;
|
|
48
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,iBAAiB,EAEjB,sBAAsB,EAEvB,MAAM,cAAc,CAAC;AA8BtB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,EAAE,EAAE,IAAI,CAAC;IAET,qBAAqB;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAE1B,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAE1C,0BAA0B;IAC1B,IAAI,CAAC,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,EAAE,EAAE,KAAK,CAAC;IAEV,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IAEf,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmGD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IAEnB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,GAAG,aAAa,GACnC,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC,CA6EvC"}
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Receipt verification with JWKS fetching and caching
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.verifyReceipt = verifyReceipt;
|
|
7
|
+
const crypto_1 = require("@peac/crypto");
|
|
8
|
+
const schema_1 = require("@peac/schema");
|
|
9
|
+
/**
|
|
10
|
+
* In-memory JWKS cache
|
|
11
|
+
* Maps issuer URL to { keys, expiresAt }
|
|
12
|
+
*/
|
|
13
|
+
const jwksCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Cache TTL (5 minutes)
|
|
16
|
+
*/
|
|
17
|
+
const CACHE_TTL_MS = 5 * 60 * 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch JWKS from issuer (SSRF-safe)
|
|
20
|
+
*/
|
|
21
|
+
async function fetchJWKS(issuerUrl) {
|
|
22
|
+
// SSRF protection: only allow https://
|
|
23
|
+
if (!issuerUrl.startsWith('https://')) {
|
|
24
|
+
throw new Error('Issuer URL must be https://');
|
|
25
|
+
}
|
|
26
|
+
// Construct JWKS URL from discovery
|
|
27
|
+
const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;
|
|
28
|
+
try {
|
|
29
|
+
const discoveryResp = await fetch(discoveryUrl, {
|
|
30
|
+
headers: { Accept: 'text/plain' },
|
|
31
|
+
// Timeout after 5 seconds
|
|
32
|
+
signal: AbortSignal.timeout(5000),
|
|
33
|
+
});
|
|
34
|
+
if (!discoveryResp.ok) {
|
|
35
|
+
throw new Error(`Discovery fetch failed: ${discoveryResp.status}`);
|
|
36
|
+
}
|
|
37
|
+
const discoveryText = await discoveryResp.text();
|
|
38
|
+
// Parse YAML-like discovery (simple key: value parsing)
|
|
39
|
+
const jwksLine = discoveryText.split('\n').find((line) => line.startsWith('jwks:'));
|
|
40
|
+
if (!jwksLine) {
|
|
41
|
+
throw new Error('No jwks field in discovery');
|
|
42
|
+
}
|
|
43
|
+
const jwksUrl = jwksLine.replace('jwks:', '').trim();
|
|
44
|
+
// SSRF protection: verify JWKS URL is also https://
|
|
45
|
+
if (!jwksUrl.startsWith('https://')) {
|
|
46
|
+
throw new Error('JWKS URL must be https://');
|
|
47
|
+
}
|
|
48
|
+
// Fetch JWKS
|
|
49
|
+
const jwksResp = await fetch(jwksUrl, {
|
|
50
|
+
headers: { Accept: 'application/json' },
|
|
51
|
+
signal: AbortSignal.timeout(5000),
|
|
52
|
+
});
|
|
53
|
+
if (!jwksResp.ok) {
|
|
54
|
+
throw new Error(`JWKS fetch failed: ${jwksResp.status}`);
|
|
55
|
+
}
|
|
56
|
+
const jwks = (await jwksResp.json());
|
|
57
|
+
return jwks;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
throw new Error(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get JWKS (from cache or fetch)
|
|
65
|
+
*/
|
|
66
|
+
async function getJWKS(issuerUrl) {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
// Check cache
|
|
69
|
+
const cached = jwksCache.get(issuerUrl);
|
|
70
|
+
if (cached && cached.expiresAt > now) {
|
|
71
|
+
return { jwks: cached.keys, fromCache: true };
|
|
72
|
+
}
|
|
73
|
+
// Fetch fresh JWKS
|
|
74
|
+
const jwks = await fetchJWKS(issuerUrl);
|
|
75
|
+
// Cache it
|
|
76
|
+
jwksCache.set(issuerUrl, {
|
|
77
|
+
keys: jwks,
|
|
78
|
+
expiresAt: now + CACHE_TTL_MS,
|
|
79
|
+
});
|
|
80
|
+
return { jwks, fromCache: false };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Convert JWK x coordinate to Ed25519 public key
|
|
84
|
+
*/
|
|
85
|
+
function jwkToPublicKey(jwk) {
|
|
86
|
+
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
|
|
87
|
+
throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported');
|
|
88
|
+
}
|
|
89
|
+
// Decode base64url x coordinate
|
|
90
|
+
const xBytes = Buffer.from(jwk.x, 'base64url');
|
|
91
|
+
if (xBytes.length !== 32) {
|
|
92
|
+
throw new Error('Ed25519 public key must be 32 bytes');
|
|
93
|
+
}
|
|
94
|
+
return new Uint8Array(xBytes);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Verify a PEAC receipt JWS
|
|
98
|
+
*
|
|
99
|
+
* @param optionsOrJws - Verify options or JWS compact serialization (for backwards compatibility)
|
|
100
|
+
* @returns Verification result or failure
|
|
101
|
+
*/
|
|
102
|
+
async function verifyReceipt(optionsOrJws) {
|
|
103
|
+
// Support both old (string) and new (options) signatures for backwards compatibility
|
|
104
|
+
const receiptJws = typeof optionsOrJws === 'string' ? optionsOrJws : optionsOrJws.receiptJws;
|
|
105
|
+
const inputSnapshot = typeof optionsOrJws === 'string' ? undefined : optionsOrJws.subject_snapshot;
|
|
106
|
+
const startTime = performance.now();
|
|
107
|
+
let jwksFetchTime;
|
|
108
|
+
try {
|
|
109
|
+
// Decode JWS to get issuer
|
|
110
|
+
const { header, payload } = (0, crypto_1.decode)(receiptJws);
|
|
111
|
+
// Validate claims structure
|
|
112
|
+
schema_1.ReceiptClaims.parse(payload);
|
|
113
|
+
// Check expiry
|
|
114
|
+
if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
|
|
115
|
+
return {
|
|
116
|
+
ok: false,
|
|
117
|
+
reason: 'expired',
|
|
118
|
+
details: `Receipt expired at ${new Date(payload.exp * 1000).toISOString()}`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// Fetch JWKS
|
|
122
|
+
const jwksFetchStart = performance.now();
|
|
123
|
+
const { jwks, fromCache } = await getJWKS(payload.iss);
|
|
124
|
+
if (!fromCache) {
|
|
125
|
+
jwksFetchTime = performance.now() - jwksFetchStart;
|
|
126
|
+
}
|
|
127
|
+
// Find key by kid
|
|
128
|
+
const jwk = jwks.keys.find((k) => k.kid === header.kid);
|
|
129
|
+
if (!jwk) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
reason: 'unknown_key',
|
|
133
|
+
details: `No key found with kid=${header.kid}`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// Convert JWK to public key
|
|
137
|
+
const publicKey = jwkToPublicKey(jwk);
|
|
138
|
+
// Verify signature
|
|
139
|
+
const result = await (0, crypto_1.verify)(receiptJws, publicKey);
|
|
140
|
+
if (!result.valid) {
|
|
141
|
+
return {
|
|
142
|
+
ok: false,
|
|
143
|
+
reason: 'invalid_signature',
|
|
144
|
+
details: 'Ed25519 signature verification failed',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// Validate subject_snapshot if provided (v0.9.17+)
|
|
148
|
+
// This validates schema and logs advisory PII warning if applicable
|
|
149
|
+
const validatedSnapshot = (0, schema_1.validateSubjectSnapshot)(inputSnapshot);
|
|
150
|
+
const verifyTime = performance.now() - startTime;
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
claims: payload,
|
|
154
|
+
...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),
|
|
155
|
+
perf: {
|
|
156
|
+
verify_ms: verifyTime,
|
|
157
|
+
...(jwksFetchTime && { jwks_fetch_ms: jwksFetchTime }),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
return {
|
|
163
|
+
ok: false,
|
|
164
|
+
reason: 'verification_error',
|
|
165
|
+
details: err instanceof Error ? err.message : String(err),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peac/protocol",
|
|
3
|
+
"version": "0.9.18",
|
|
4
|
+
"description": "PEAC protocol implementation - receipt issuance and verification",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/peacprotocol/peac.git",
|
|
10
|
+
"directory": "packages/protocol"
|
|
11
|
+
},
|
|
12
|
+
"author": "jithinraj <7850727+jithinraj@users.noreply.github.com>",
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/peacprotocol/peac/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/peacprotocol/peac#readme",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"clean": "rm -rf dist"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@peac/schema": "workspace:*",
|
|
33
|
+
"@peac/crypto": "workspace:*",
|
|
34
|
+
"uuidv7": "^0.6.3"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.10.0",
|
|
38
|
+
"typescript": "^5.3.3",
|
|
39
|
+
"vitest": "^1.1.0"
|
|
40
|
+
}
|
|
41
|
+
}
|