@orangecheck/agent-core 1.2.0 → 2.0.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/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AgentErrorCode, ActionEnvelope, DelegationEnvelope, SubdelegationEnvelope, RevocationEnvelope, ChainLink, VerifyActionResult, VerifyDelegationResult, VerifyRevocationResult, VerifySubdelegationResult, ActorRef, DelegationBond, DelegationRevocationRef, ScopesEncryptedEnvelope } from './types.mjs';
1
+ import { AgentErrorCode, RevocationEnvelope, ActionEnvelope, DelegationEnvelope, SubdelegationEnvelope, ChainLink, VerifyActionResult, VerifyDelegationResult, VerifyRevocationResult, VerifySubdelegationResult, ActorRef, DelegationBond, DelegationRevocationRef, ScopesEncryptedEnvelope } from './types.mjs';
2
2
  export { ActionCanonicalInput, ActionContent, ActionOts, DelegationCanonicalInput, ENVELOPE_VERSION, EnvelopeKind, RevocationCanonicalInput, RevocationHolder, Signature, SubdelegationCanonicalInput, VerifyActionOkExtra, VerifyErr, VerifyOk } from './types.mjs';
3
3
  export { actionCanonicalBytes, actionCanonicalMessage, canonicalActionBytes, canonicalDelegationBytes, canonicalRevocationBytes, canonicalizeAction, canonicalizeDelegation, canonicalizeRevocation, canonicalizeScopes, computeActionId, computeDelegationId, computeRevocationId, computeSubdelegationId, delegationCanonicalBytes, delegationCanonicalMessage, parseAndCanonicalizeScopes, revocationCanonicalBytes, revocationCanonicalMessage, sha256Hex, subdelegationCanonicalBytes, subdelegationCanonicalMessage } from './canonical.mjs';
4
4
  import { ValidationOptions } from './scope.mjs';
@@ -11,6 +11,8 @@ interface VerifyBase {
11
11
  verifyBip322?: (msg: string, signatureB64: string, address: string) => Promise<boolean>;
12
12
  skipSignatureVerification?: boolean;
13
13
  scopeMode?: ValidationOptions['mode'];
14
+ skipRevocationCheck?: boolean;
15
+ revocations?: RevocationEnvelope[];
14
16
  }
15
17
  declare class AgentError extends Error {
16
18
  code: AgentErrorCode;
@@ -31,7 +33,6 @@ interface VerifyActionInput extends VerifyBase {
31
33
  delegation: DelegationEnvelope;
32
34
  subdelegationChain?: SubdelegationEnvelope[];
33
35
  maxChainDepth?: number;
34
- revocations?: RevocationEnvelope[];
35
36
  content?: Uint8Array;
36
37
  verifyOtsAnchor?: (proofB64: string, blockHeight: number, blockHash: string) => Promise<boolean>;
37
38
  resolveAnchorBlockHeight?: (env: ActionEnvelope | RevocationEnvelope) => number | null;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AgentErrorCode, ActionEnvelope, DelegationEnvelope, SubdelegationEnvelope, RevocationEnvelope, ChainLink, VerifyActionResult, VerifyDelegationResult, VerifyRevocationResult, VerifySubdelegationResult, ActorRef, DelegationBond, DelegationRevocationRef, ScopesEncryptedEnvelope } from './types.js';
1
+ import { AgentErrorCode, RevocationEnvelope, ActionEnvelope, DelegationEnvelope, SubdelegationEnvelope, ChainLink, VerifyActionResult, VerifyDelegationResult, VerifyRevocationResult, VerifySubdelegationResult, ActorRef, DelegationBond, DelegationRevocationRef, ScopesEncryptedEnvelope } from './types.js';
2
2
  export { ActionCanonicalInput, ActionContent, ActionOts, DelegationCanonicalInput, ENVELOPE_VERSION, EnvelopeKind, RevocationCanonicalInput, RevocationHolder, Signature, SubdelegationCanonicalInput, VerifyActionOkExtra, VerifyErr, VerifyOk } from './types.js';
3
3
  export { actionCanonicalBytes, actionCanonicalMessage, canonicalActionBytes, canonicalDelegationBytes, canonicalRevocationBytes, canonicalizeAction, canonicalizeDelegation, canonicalizeRevocation, canonicalizeScopes, computeActionId, computeDelegationId, computeRevocationId, computeSubdelegationId, delegationCanonicalBytes, delegationCanonicalMessage, parseAndCanonicalizeScopes, revocationCanonicalBytes, revocationCanonicalMessage, sha256Hex, subdelegationCanonicalBytes, subdelegationCanonicalMessage } from './canonical.js';
4
4
  import { ValidationOptions } from './scope.js';
@@ -11,6 +11,8 @@ interface VerifyBase {
11
11
  verifyBip322?: (msg: string, signatureB64: string, address: string) => Promise<boolean>;
12
12
  skipSignatureVerification?: boolean;
13
13
  scopeMode?: ValidationOptions['mode'];
14
+ skipRevocationCheck?: boolean;
15
+ revocations?: RevocationEnvelope[];
14
16
  }
15
17
  declare class AgentError extends Error {
16
18
  code: AgentErrorCode;
@@ -31,7 +33,6 @@ interface VerifyActionInput extends VerifyBase {
31
33
  delegation: DelegationEnvelope;
32
34
  subdelegationChain?: SubdelegationEnvelope[];
33
35
  maxChainDepth?: number;
34
- revocations?: RevocationEnvelope[];
35
36
  content?: Uint8Array;
36
37
  verifyOtsAnchor?: (proofB64: string, blockHeight: number, blockHash: string) => Promise<boolean>;
37
38
  resolveAnchorBlockHeight?: (env: ActionEnvelope | RevocationEnvelope) => number | null;
package/dist/index.js CHANGED
@@ -497,6 +497,25 @@ async function verifyDelegation(input) {
497
497
  const ok = await input.verifyBip322(env.id, env.sig.value, env.principal.address);
498
498
  if (!ok) return err("E_BAD_SIG", "BIP-322 signature did not verify");
499
499
  }
500
+ if (!input.skipRevocationCheck && !input.revocations) {
501
+ return err(
502
+ "E_MALFORMED",
503
+ "verifyDelegation requires `revocations` (fetch kind-30085 by #delegation) or an explicit skipRevocationCheck:true to state that revocation is not being checked"
504
+ );
505
+ }
506
+ if (input.revocations) {
507
+ for (const rev of input.revocations) {
508
+ if (rev.delegation_id !== env.id) continue;
509
+ const rr = await verifyRevocation({
510
+ envelope: rev,
511
+ delegation: env,
512
+ verifyBip322: input.verifyBip322,
513
+ skipSignatureVerification: input.skipSignatureVerification
514
+ });
515
+ if (!rr.ok) continue;
516
+ return err("E_REVOKED", `delegation ${env.id} was revoked by ${rev.id}`);
517
+ }
518
+ }
500
519
  if (!input.skipTemporalCheck) {
501
520
  const now = input.now ?? /* @__PURE__ */ new Date();
502
521
  const issued = new Date(env.issued_at);
@@ -531,6 +550,12 @@ async function verifyAction(input) {
531
550
  scopeMode: input.scopeMode,
532
551
  skipTemporalCheck: true,
533
552
  // action window check dominates
553
+ // Revocation is evaluated ONCE, below, across every link in the chain
554
+ // (root + subdelegations) against the action's effective time — a
555
+ // per-link check here would use the wrong clock and would also
556
+ // double-report. Forward the caller's decision so this inner call does
557
+ // not trip the fail-closed guard.
558
+ skipRevocationCheck: true,
534
559
  ...input.decryptScopesWith ? { decryptScopesWith: input.decryptScopesWith } : {}
535
560
  });
536
561
  if (!dr.ok) return dr;
@@ -600,6 +625,12 @@ async function verifyAction(input) {
600
625
  return err("E_BAD_SCOPE_GRAMMAR", msg);
601
626
  }
602
627
  if (!accepted) return err("E_SCOPE_DENIED", `scope_exercised (${exercised}) not a sub-scope of any granted scope`);
628
+ if (!input.skipRevocationCheck && !input.revocations) {
629
+ return err(
630
+ "E_MALFORMED",
631
+ "verifyAction requires `revocations` (fetch kind-30085 by #delegation for every link in the chain) or an explicit skipRevocationCheck:true"
632
+ );
633
+ }
603
634
  if (input.revocations && input.revocations.length > 0) {
604
635
  const allLinks = [rootHydrated, ...hydratedChain];
605
636
  for (const link of allLinks) {