@orangecheck/agent-core 0.1.0 → 0.2.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.
- package/dist/canonical.d.mts +5 -2
- package/dist/canonical.d.ts +5 -2
- package/dist/canonical.js +22 -0
- package/dist/canonical.js.map +1 -1
- package/dist/canonical.mjs +20 -1
- package/dist/canonical.mjs.map +1 -1
- package/dist/index.d.mts +15 -5
- package/dist/index.d.ts +15 -5
- package/dist/index.js +180 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +176 -22
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.mts +29 -3
- package/dist/types.d.ts +29 -3
- package/dist/types.js.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +72 -69
- package/src/canonical.ts +23 -0
- package/src/index.ts +6 -0
- package/src/test-vectors.test.ts +358 -12
- package/src/types.ts +53 -2
- package/src/verify.ts +263 -32
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAEO,IAAM,gBAAA,GAAmB","file":"types.js","sourcesContent":["// Wire types for OC Agent v1 envelopes. See SPEC.md §4, §5, §9.\n\nexport const ENVELOPE_VERSION = 1 as const;\n\nexport type EnvelopeKind
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAEO,IAAM,gBAAA,GAAmB","file":"types.js","sourcesContent":["// Wire types for OC Agent v1 envelopes. See SPEC.md §4, §5, §9.\n\nexport const ENVELOPE_VERSION = 1 as const;\n\nexport type EnvelopeKind =\n | 'agent-delegation'\n | 'agent-action'\n | 'agent-revocation'\n | 'agent-subdelegation';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared building blocks\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ActorRef {\n /** mainnet Bitcoin address (P2WPKH, P2TR, or P2PKH). */\n address: string;\n alg: 'bip322';\n}\n\nexport interface Signature {\n alg: 'bip322';\n pubkey: string; // equals the producing actor's address\n value: string; // base64 BIP-322 signature over hex(id)\n}\n\nexport type RevocationHolder = 'principal' | 'agent';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Delegation (SPEC §4)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DelegationBond {\n /** Non-negative sats declared as bonded at issuance time. */\n sats: number;\n /** SHA-256 hex of the OrangeCheck canonical message signed by principal.address. */\n attestation_id: string;\n}\n\nexport interface DelegationRevocationRef {\n /** Who MAY publish a revocation. Default [\"principal\"]. */\n holders: RevocationHolder[];\n /** Optional Nostr-addressable pointer to a published revocation. Non-cryptographic. */\n ref: string | null;\n}\n\nexport interface DelegationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-delegation';\n id: string; // 64-hex sha256(canonical_message)\n principal: ActorRef;\n agent: ActorRef;\n /** Sorted lexicographically in the canonical message; stored in sorted order on the envelope too. */\n scopes: string[];\n bond: DelegationBond | null;\n issued_at: string; // ISO 8601 UTC\n expires_at: string; // ISO 8601 UTC\n nonce: string; // 32-hex random\n revocation: DelegationRevocationRef;\n sig: Signature;\n}\n\nexport interface DelegationCanonicalInput {\n principal: string;\n agent: string;\n scopes: string[]; // pre-canonicalized, pre-sorted\n bond_sats: number;\n /** 64-hex attestation id or the literal string \"none\". */\n bond_attestation: string;\n issued_at: string;\n expires_at: string;\n nonce: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Agent-action (SPEC §5) — strict extension of OC Stamp\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ActionContent {\n hash: string; // \"sha256:<64-hex>\"\n length: number;\n mime: string;\n ref: string | null;\n}\n\nexport interface ActionOts {\n status: 'pending' | 'confirmed';\n proof: string;\n calendars: string[];\n block_height: number | null;\n block_hash: string | null;\n upgraded_at: string | null;\n}\n\nexport interface ActionEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-action';\n id: string;\n content: ActionContent;\n signer: ActorRef; // agent\n signed_at: string;\n delegation_id: string; // 64-hex\n scope_exercised: string; // a sub-scope of some granted scope\n ots: ActionOts | null;\n sig: Signature;\n}\n\nexport interface ActionCanonicalInput {\n address: string; // agent address\n content_hash: string;\n content_length: number;\n content_mime: string;\n signed_at: string;\n delegation_id: string;\n scope_exercised: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sub-delegation (SUB-DELEGATION.md, v1.1)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SubdelegationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-subdelegation';\n id: string; // 64-hex sha256(canonical_message)\n parent_id: string; // 64-hex; the immediate parent envelope's id\n /** The sub-principal — equal to parent.agent.address. */\n principal: ActorRef;\n /** The recipient sub-agent. */\n agent: ActorRef;\n /** Each scope MUST be a sub-scope of some scope on the parent. */\n scopes: string[];\n issued_at: string; // ISO 8601 UTC; >= parent.issued_at\n expires_at: string; // ISO 8601 UTC; <= parent.expires_at\n nonce: string; // 32-hex random\n revocation: DelegationRevocationRef;\n sig: Signature;\n}\n\nexport interface SubdelegationCanonicalInput {\n parent_id: string;\n principal: string;\n agent: string;\n scopes: string[]; // pre-canonicalized, pre-sorted\n issued_at: string;\n expires_at: string;\n nonce: string;\n}\n\n/** Either a root or a sub envelope; chain links walk up to a root delegation. */\nexport type ChainLink = DelegationEnvelope | SubdelegationEnvelope;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Revocation (SPEC §9)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface RevocationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-revocation';\n id: string;\n delegation_id: string;\n signer: ActorRef;\n /** Short ASCII rationale, <= 128 bytes. Empty string if omitted. */\n reason: string;\n signed_at: string;\n ots: ActionOts | null;\n sig: Signature;\n}\n\nexport interface RevocationCanonicalInput {\n address: string;\n delegation_id: string;\n reason: string;\n signed_at: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Error codes (SPEC §11)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type AgentErrorCode =\n | 'E_UNSUPPORTED_VERSION'\n | 'E_MALFORMED'\n | 'E_BAD_ID'\n | 'E_BAD_SIG'\n | 'E_BAD_SCOPE_GRAMMAR'\n | 'E_NOT_YET_VALID'\n | 'E_EXPIRED'\n | 'E_REVOKED'\n | 'E_DELEGATION_MISMATCH'\n | 'E_AGENT_MISMATCH'\n | 'E_OUT_OF_WINDOW'\n | 'E_SCOPE_DENIED'\n | 'E_BAD_ACTION_STAMP'\n | 'E_NO_BOND'\n | 'E_BOND_UNMET'\n | 'E_BOND_UNVERIFIED'\n | 'E_REVOKER_UNAUTHORIZED'\n | 'E_CALENDAR_UNREACHABLE'\n | 'E_SUBDELEGATION_DEPTH_EXCEEDED'\n | 'E_SUBDELEGATION_PRINCIPAL_MISMATCH'\n | 'E_SUBDELEGATION_EXPIRES_EXTENDED'\n | 'E_SUBDELEGATION_SCOPE_ESCALATED';\n\nexport interface VerifyOk<T> {\n ok: true;\n envelope: T;\n canonicalMessage: string;\n id: string;\n}\n\nexport interface VerifyErr {\n ok: false;\n code: AgentErrorCode;\n message: string;\n}\n\nexport type VerifyDelegationResult = VerifyOk<DelegationEnvelope> | VerifyErr;\nexport type VerifyRevocationResult = VerifyOk<RevocationEnvelope> | VerifyErr;\nexport type VerifySubdelegationResult = VerifyOk<SubdelegationEnvelope> | VerifyErr;\n\nexport interface VerifyActionOkExtra {\n /** The ROOT delegation rooting the authority chain. */\n delegation: DelegationEnvelope;\n /**\n * The sub-delegation chain `[S_1, …, S_leaf]`. Empty when the action cites\n * the root directly. The action's authority leaf is\n * `chain[chain.length - 1] ?? delegation`.\n */\n chain: SubdelegationEnvelope[];\n scopeExercised: string;\n anchor:\n | { status: 'none' }\n | { status: 'pending' }\n | { status: 'confirmed'; blockHeight: number; blockHash: string; verified: boolean };\n}\n\nexport type VerifyActionResult =\n | (VerifyOk<ActionEnvelope> & VerifyActionOkExtra)\n | VerifyErr;\n"]}
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAEO,IAAM,gBAAA,GAAmB","file":"types.mjs","sourcesContent":["// Wire types for OC Agent v1 envelopes. See SPEC.md §4, §5, §9.\n\nexport const ENVELOPE_VERSION = 1 as const;\n\nexport type EnvelopeKind
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";AAEO,IAAM,gBAAA,GAAmB","file":"types.mjs","sourcesContent":["// Wire types for OC Agent v1 envelopes. See SPEC.md §4, §5, §9.\n\nexport const ENVELOPE_VERSION = 1 as const;\n\nexport type EnvelopeKind =\n | 'agent-delegation'\n | 'agent-action'\n | 'agent-revocation'\n | 'agent-subdelegation';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared building blocks\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ActorRef {\n /** mainnet Bitcoin address (P2WPKH, P2TR, or P2PKH). */\n address: string;\n alg: 'bip322';\n}\n\nexport interface Signature {\n alg: 'bip322';\n pubkey: string; // equals the producing actor's address\n value: string; // base64 BIP-322 signature over hex(id)\n}\n\nexport type RevocationHolder = 'principal' | 'agent';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Delegation (SPEC §4)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface DelegationBond {\n /** Non-negative sats declared as bonded at issuance time. */\n sats: number;\n /** SHA-256 hex of the OrangeCheck canonical message signed by principal.address. */\n attestation_id: string;\n}\n\nexport interface DelegationRevocationRef {\n /** Who MAY publish a revocation. Default [\"principal\"]. */\n holders: RevocationHolder[];\n /** Optional Nostr-addressable pointer to a published revocation. Non-cryptographic. */\n ref: string | null;\n}\n\nexport interface DelegationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-delegation';\n id: string; // 64-hex sha256(canonical_message)\n principal: ActorRef;\n agent: ActorRef;\n /** Sorted lexicographically in the canonical message; stored in sorted order on the envelope too. */\n scopes: string[];\n bond: DelegationBond | null;\n issued_at: string; // ISO 8601 UTC\n expires_at: string; // ISO 8601 UTC\n nonce: string; // 32-hex random\n revocation: DelegationRevocationRef;\n sig: Signature;\n}\n\nexport interface DelegationCanonicalInput {\n principal: string;\n agent: string;\n scopes: string[]; // pre-canonicalized, pre-sorted\n bond_sats: number;\n /** 64-hex attestation id or the literal string \"none\". */\n bond_attestation: string;\n issued_at: string;\n expires_at: string;\n nonce: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Agent-action (SPEC §5) — strict extension of OC Stamp\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ActionContent {\n hash: string; // \"sha256:<64-hex>\"\n length: number;\n mime: string;\n ref: string | null;\n}\n\nexport interface ActionOts {\n status: 'pending' | 'confirmed';\n proof: string;\n calendars: string[];\n block_height: number | null;\n block_hash: string | null;\n upgraded_at: string | null;\n}\n\nexport interface ActionEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-action';\n id: string;\n content: ActionContent;\n signer: ActorRef; // agent\n signed_at: string;\n delegation_id: string; // 64-hex\n scope_exercised: string; // a sub-scope of some granted scope\n ots: ActionOts | null;\n sig: Signature;\n}\n\nexport interface ActionCanonicalInput {\n address: string; // agent address\n content_hash: string;\n content_length: number;\n content_mime: string;\n signed_at: string;\n delegation_id: string;\n scope_exercised: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sub-delegation (SUB-DELEGATION.md, v1.1)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SubdelegationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-subdelegation';\n id: string; // 64-hex sha256(canonical_message)\n parent_id: string; // 64-hex; the immediate parent envelope's id\n /** The sub-principal — equal to parent.agent.address. */\n principal: ActorRef;\n /** The recipient sub-agent. */\n agent: ActorRef;\n /** Each scope MUST be a sub-scope of some scope on the parent. */\n scopes: string[];\n issued_at: string; // ISO 8601 UTC; >= parent.issued_at\n expires_at: string; // ISO 8601 UTC; <= parent.expires_at\n nonce: string; // 32-hex random\n revocation: DelegationRevocationRef;\n sig: Signature;\n}\n\nexport interface SubdelegationCanonicalInput {\n parent_id: string;\n principal: string;\n agent: string;\n scopes: string[]; // pre-canonicalized, pre-sorted\n issued_at: string;\n expires_at: string;\n nonce: string;\n}\n\n/** Either a root or a sub envelope; chain links walk up to a root delegation. */\nexport type ChainLink = DelegationEnvelope | SubdelegationEnvelope;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Revocation (SPEC §9)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface RevocationEnvelope {\n v: typeof ENVELOPE_VERSION;\n kind: 'agent-revocation';\n id: string;\n delegation_id: string;\n signer: ActorRef;\n /** Short ASCII rationale, <= 128 bytes. Empty string if omitted. */\n reason: string;\n signed_at: string;\n ots: ActionOts | null;\n sig: Signature;\n}\n\nexport interface RevocationCanonicalInput {\n address: string;\n delegation_id: string;\n reason: string;\n signed_at: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Error codes (SPEC §11)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type AgentErrorCode =\n | 'E_UNSUPPORTED_VERSION'\n | 'E_MALFORMED'\n | 'E_BAD_ID'\n | 'E_BAD_SIG'\n | 'E_BAD_SCOPE_GRAMMAR'\n | 'E_NOT_YET_VALID'\n | 'E_EXPIRED'\n | 'E_REVOKED'\n | 'E_DELEGATION_MISMATCH'\n | 'E_AGENT_MISMATCH'\n | 'E_OUT_OF_WINDOW'\n | 'E_SCOPE_DENIED'\n | 'E_BAD_ACTION_STAMP'\n | 'E_NO_BOND'\n | 'E_BOND_UNMET'\n | 'E_BOND_UNVERIFIED'\n | 'E_REVOKER_UNAUTHORIZED'\n | 'E_CALENDAR_UNREACHABLE'\n | 'E_SUBDELEGATION_DEPTH_EXCEEDED'\n | 'E_SUBDELEGATION_PRINCIPAL_MISMATCH'\n | 'E_SUBDELEGATION_EXPIRES_EXTENDED'\n | 'E_SUBDELEGATION_SCOPE_ESCALATED';\n\nexport interface VerifyOk<T> {\n ok: true;\n envelope: T;\n canonicalMessage: string;\n id: string;\n}\n\nexport interface VerifyErr {\n ok: false;\n code: AgentErrorCode;\n message: string;\n}\n\nexport type VerifyDelegationResult = VerifyOk<DelegationEnvelope> | VerifyErr;\nexport type VerifyRevocationResult = VerifyOk<RevocationEnvelope> | VerifyErr;\nexport type VerifySubdelegationResult = VerifyOk<SubdelegationEnvelope> | VerifyErr;\n\nexport interface VerifyActionOkExtra {\n /** The ROOT delegation rooting the authority chain. */\n delegation: DelegationEnvelope;\n /**\n * The sub-delegation chain `[S_1, …, S_leaf]`. Empty when the action cites\n * the root directly. The action's authority leaf is\n * `chain[chain.length - 1] ?? delegation`.\n */\n chain: SubdelegationEnvelope[];\n scopeExercised: string;\n anchor:\n | { status: 'none' }\n | { status: 'pending' }\n | { status: 'confirmed'; blockHeight: number; blockHash: string; verified: boolean };\n}\n\nexport type VerifyActionResult =\n | (VerifyOk<ActionEnvelope> & VerifyActionOkExtra)\n | VerifyErr;\n"]}
|
package/package.json
CHANGED
|
@@ -1,75 +1,78 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
2
|
+
"name": "@orangecheck/agent-core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "OC Agent canonical messages, envelope formats (delegation/action/revocation), scope grammar, and verification. See https://github.com/orangecheck/oc-agent-protocol.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bitcoin",
|
|
7
|
+
"agent",
|
|
8
|
+
"authority",
|
|
9
|
+
"delegation",
|
|
10
|
+
"bip322",
|
|
11
|
+
"oc-agent",
|
|
12
|
+
"orangecheck"
|
|
13
|
+
],
|
|
14
|
+
"author": "OrangeCheck",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/orangecheck/oc-packages.git",
|
|
19
|
+
"directory": "agent-core"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/orangecheck/oc-agent-protocol",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/orangecheck/oc-agent-protocol/issues"
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"module": "./dist/index.mjs",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"require": "./dist/index.js"
|
|
20
33
|
},
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
"./canonical": {
|
|
35
|
+
"types": "./dist/canonical.d.ts",
|
|
36
|
+
"import": "./dist/canonical.mjs",
|
|
37
|
+
"require": "./dist/canonical.js"
|
|
24
38
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
".": {
|
|
30
|
-
"types": "./dist/index.d.ts",
|
|
31
|
-
"import": "./dist/index.mjs",
|
|
32
|
-
"require": "./dist/index.js"
|
|
33
|
-
},
|
|
34
|
-
"./canonical": {
|
|
35
|
-
"types": "./dist/canonical.d.ts",
|
|
36
|
-
"import": "./dist/canonical.mjs",
|
|
37
|
-
"require": "./dist/canonical.js"
|
|
38
|
-
},
|
|
39
|
-
"./scope": {
|
|
40
|
-
"types": "./dist/scope.d.ts",
|
|
41
|
-
"import": "./dist/scope.mjs",
|
|
42
|
-
"require": "./dist/scope.js"
|
|
43
|
-
},
|
|
44
|
-
"./types": {
|
|
45
|
-
"types": "./dist/types.d.ts",
|
|
46
|
-
"import": "./dist/types.mjs",
|
|
47
|
-
"require": "./dist/types.js"
|
|
48
|
-
}
|
|
39
|
+
"./scope": {
|
|
40
|
+
"types": "./dist/scope.d.ts",
|
|
41
|
+
"import": "./dist/scope.mjs",
|
|
42
|
+
"require": "./dist/scope.js"
|
|
49
43
|
},
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"LICENSE"
|
|
55
|
-
],
|
|
56
|
-
"scripts": {
|
|
57
|
-
"build": "tsup",
|
|
58
|
-
"dev": "tsup --watch",
|
|
59
|
-
"type-check": "tsc --noEmit",
|
|
60
|
-
"test": "vitest run",
|
|
61
|
-
"test:watch": "vitest",
|
|
62
|
-
"clean": "rm -rf dist",
|
|
63
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
64
|
-
},
|
|
65
|
-
"dependencies": {
|
|
66
|
-
"@noble/hashes": "^1.5.0",
|
|
67
|
-
"@orangecheck/stamp-core": "^0.1.1"
|
|
68
|
-
},
|
|
69
|
-
"devDependencies": {
|
|
70
|
-
"@types/node": "^22.10.2",
|
|
71
|
-
"tsup": "^8.3.5",
|
|
72
|
-
"typescript": "^5.7.2",
|
|
73
|
-
"vitest": "^3.2.4"
|
|
44
|
+
"./types": {
|
|
45
|
+
"types": "./dist/types.d.ts",
|
|
46
|
+
"import": "./dist/types.mjs",
|
|
47
|
+
"require": "./dist/types.js"
|
|
74
48
|
}
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"src",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE"
|
|
55
|
+
],
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsup",
|
|
58
|
+
"dev": "tsup --watch",
|
|
59
|
+
"type-check": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"clean": "rm -rf dist",
|
|
63
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"@noble/hashes": "^1.5.0",
|
|
67
|
+
"@orangecheck/stamp-core": "^0.1.1"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/node": "^22.10.2",
|
|
71
|
+
"tsup": "^8.3.5",
|
|
72
|
+
"typescript": "^5.7.2",
|
|
73
|
+
"vitest": "^3.2.4"
|
|
74
|
+
},
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
}
|
|
75
78
|
}
|
package/src/canonical.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
DelegationEnvelope,
|
|
20
20
|
RevocationCanonicalInput,
|
|
21
21
|
RevocationEnvelope,
|
|
22
|
+
SubdelegationCanonicalInput,
|
|
22
23
|
} from './types.js';
|
|
23
24
|
|
|
24
25
|
export { canonicalize, hexEncode };
|
|
@@ -94,6 +95,20 @@ export function revocationCanonicalMessage(input: RevocationCanonicalInput): str
|
|
|
94
95
|
].join('\n');
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
export function subdelegationCanonicalMessage(input: SubdelegationCanonicalInput): string {
|
|
99
|
+
const scopeField = input.scopes.join(',');
|
|
100
|
+
return [
|
|
101
|
+
'oc-agent:subdelegation:v1',
|
|
102
|
+
`parent_id: ${input.parent_id}`,
|
|
103
|
+
`principal: ${input.principal}`,
|
|
104
|
+
`agent: ${input.agent}`,
|
|
105
|
+
`scopes: ${scopeField}`,
|
|
106
|
+
`issued_at: ${input.issued_at}`,
|
|
107
|
+
`expires_at: ${input.expires_at}`,
|
|
108
|
+
`nonce: ${input.nonce}`,
|
|
109
|
+
].join('\n');
|
|
110
|
+
}
|
|
111
|
+
|
|
97
112
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
98
113
|
// Bytes + ids
|
|
99
114
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -110,6 +125,10 @@ export function revocationCanonicalBytes(input: RevocationCanonicalInput): Uint8
|
|
|
110
125
|
return new TextEncoder().encode(revocationCanonicalMessage(input));
|
|
111
126
|
}
|
|
112
127
|
|
|
128
|
+
export function subdelegationCanonicalBytes(input: SubdelegationCanonicalInput): Uint8Array {
|
|
129
|
+
return new TextEncoder().encode(subdelegationCanonicalMessage(input));
|
|
130
|
+
}
|
|
131
|
+
|
|
113
132
|
export function computeDelegationId(input: DelegationCanonicalInput): string {
|
|
114
133
|
return hexEncode(sha256(delegationCanonicalBytes(input)));
|
|
115
134
|
}
|
|
@@ -122,6 +141,10 @@ export function computeRevocationId(input: RevocationCanonicalInput): string {
|
|
|
122
141
|
return hexEncode(sha256(revocationCanonicalBytes(input)));
|
|
123
142
|
}
|
|
124
143
|
|
|
144
|
+
export function computeSubdelegationId(input: SubdelegationCanonicalInput): string {
|
|
145
|
+
return hexEncode(sha256(subdelegationCanonicalBytes(input)));
|
|
146
|
+
}
|
|
147
|
+
|
|
125
148
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
126
149
|
// Envelope canonicalization (SPEC §6; RFC 8785 + scope-sorting)
|
|
127
150
|
// ─────────────────────────────────────────────────────────────────────────────
|
package/src/index.ts
CHANGED
|
@@ -8,12 +8,15 @@ export {
|
|
|
8
8
|
delegationCanonicalMessage,
|
|
9
9
|
actionCanonicalMessage,
|
|
10
10
|
revocationCanonicalMessage,
|
|
11
|
+
subdelegationCanonicalMessage,
|
|
11
12
|
delegationCanonicalBytes,
|
|
12
13
|
actionCanonicalBytes,
|
|
13
14
|
revocationCanonicalBytes,
|
|
15
|
+
subdelegationCanonicalBytes,
|
|
14
16
|
computeDelegationId,
|
|
15
17
|
computeActionId,
|
|
16
18
|
computeRevocationId,
|
|
19
|
+
computeSubdelegationId,
|
|
17
20
|
canonicalizeDelegation,
|
|
18
21
|
canonicalizeAction,
|
|
19
22
|
canonicalizeRevocation,
|
|
@@ -35,11 +38,14 @@ export {
|
|
|
35
38
|
verifyDelegation,
|
|
36
39
|
verifyAction,
|
|
37
40
|
verifyRevocation,
|
|
41
|
+
verifySubdelegation,
|
|
38
42
|
AgentError,
|
|
43
|
+
DEFAULT_MAX_CHAIN_DEPTH,
|
|
39
44
|
} from './verify.js';
|
|
40
45
|
export type {
|
|
41
46
|
VerifyBase,
|
|
42
47
|
VerifyDelegationInput,
|
|
43
48
|
VerifyActionInput,
|
|
44
49
|
VerifyRevocationInput,
|
|
50
|
+
VerifySubdelegationInput,
|
|
45
51
|
} from './verify.js';
|