@vantic/sdk 0.1.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.
Files changed (59) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +42 -0
  3. package/dist/adapters.d.ts +66 -0
  4. package/dist/adapters.d.ts.map +1 -0
  5. package/dist/adapters.js +67 -0
  6. package/dist/adapters.js.map +1 -0
  7. package/dist/credential.d.ts +51 -0
  8. package/dist/credential.d.ts.map +1 -0
  9. package/dist/credential.js +78 -0
  10. package/dist/credential.js.map +1 -0
  11. package/dist/crypto.d.ts +27 -0
  12. package/dist/crypto.d.ts.map +1 -0
  13. package/dist/crypto.js +103 -0
  14. package/dist/crypto.js.map +1 -0
  15. package/dist/did.d.ts +54 -0
  16. package/dist/did.d.ts.map +1 -0
  17. package/dist/did.js +152 -0
  18. package/dist/did.js.map +1 -0
  19. package/dist/envelope.d.ts +23 -0
  20. package/dist/envelope.d.ts.map +1 -0
  21. package/dist/envelope.js +31 -0
  22. package/dist/envelope.js.map +1 -0
  23. package/dist/gate.d.ts +48 -0
  24. package/dist/gate.d.ts.map +1 -0
  25. package/dist/gate.js +46 -0
  26. package/dist/gate.js.map +1 -0
  27. package/dist/guard.d.ts +53 -0
  28. package/dist/guard.d.ts.map +1 -0
  29. package/dist/guard.js +76 -0
  30. package/dist/guard.js.map +1 -0
  31. package/dist/index.d.ts +19 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +19 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/mcp-server.d.ts +23 -0
  36. package/dist/mcp-server.d.ts.map +1 -0
  37. package/dist/mcp-server.js +141 -0
  38. package/dist/mcp-server.js.map +1 -0
  39. package/dist/mcp.d.ts +3 -0
  40. package/dist/mcp.d.ts.map +1 -0
  41. package/dist/mcp.js +5 -0
  42. package/dist/mcp.js.map +1 -0
  43. package/dist/receipt.d.ts +24 -0
  44. package/dist/receipt.d.ts.map +1 -0
  45. package/dist/receipt.js +41 -0
  46. package/dist/receipt.js.map +1 -0
  47. package/dist/revocation.d.ts +23 -0
  48. package/dist/revocation.d.ts.map +1 -0
  49. package/dist/revocation.js +30 -0
  50. package/dist/revocation.js.map +1 -0
  51. package/dist/types.d.ts +98 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +6 -0
  54. package/dist/types.js.map +1 -0
  55. package/dist/verify.d.ts +24 -0
  56. package/dist/verify.d.ts.map +1 -0
  57. package/dist/verify.js +124 -0
  58. package/dist/verify.js.map +1 -0
  59. package/package.json +39 -0
package/dist/verify.js ADDED
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Verification & authorization — the core of the protocol (spec §6).
3
+ *
4
+ * `verifyChain` validates an envelope + its full receipt history (the dispute-evidence
5
+ * path). `authorize` checks a candidate action *before* it happens (the gateway path).
6
+ */
7
+ import { mandateHash, verifyMandateSignature } from "./envelope.js";
8
+ import { receiptHash, verifyReceiptSignature } from "./receipt.js";
9
+ /** Counterparty matcher: exact match or leading-wildcard domain suffix (`*.shop.example`). */
10
+ export function counterpartyAllowed(allowed, counterparty) {
11
+ if (!allowed || allowed.length === 0)
12
+ return true; // unconstrained
13
+ return allowed.some((pattern) => {
14
+ if (pattern === "*")
15
+ return true;
16
+ if (pattern.startsWith("*.")) {
17
+ const suffix = pattern.slice(1); // ".shop.example"
18
+ return counterparty.endsWith(suffix) && counterparty.length > suffix.length;
19
+ }
20
+ return pattern === counterparty;
21
+ });
22
+ }
23
+ /** Check a single action against the static scope rules (type / counterparty / per-txn cap). */
24
+ function scopeViolations(scope, action, label) {
25
+ const reasons = [];
26
+ if (scope.allowedActions && !scope.allowedActions.includes(action.type)) {
27
+ reasons.push(`${label}: action '${action.type}' not in allowedActions`);
28
+ }
29
+ if (!counterpartyAllowed(scope.allowedCounterparties, action.counterparty)) {
30
+ reasons.push(`${label}: counterparty '${action.counterparty}' not allowed`);
31
+ }
32
+ if (scope.maxPerTransaction != null && action.amount > scope.maxPerTransaction) {
33
+ reasons.push(`${label}: amount ${action.amount} exceeds maxPerTransaction ${scope.maxPerTransaction}`);
34
+ }
35
+ if (scope.budget && action.currency !== scope.budget.currency) {
36
+ reasons.push(`${label}: currency '${action.currency}' differs from budget currency '${scope.budget.currency}'`);
37
+ }
38
+ return reasons;
39
+ }
40
+ /** Sum non-failed spend within the budget window ending at `now`. */
41
+ function spendInWindow(scope, receipts, now) {
42
+ if (!scope.budget)
43
+ return 0;
44
+ const cutoff = now.getTime() - scope.budget.windowSeconds * 1000;
45
+ return receipts
46
+ .filter((r) => r.outcome !== "failed" && new Date(r.timestamp).getTime() >= cutoff)
47
+ .reduce((sum, r) => sum + r.action.amount, 0);
48
+ }
49
+ /** Validate envelope alone (signature, validity window, revocation). */
50
+ function envelopeReasons(env, opts) {
51
+ const now = opts.now ?? new Date();
52
+ const skew = (opts.clockSkewSeconds ?? 0) * 1000;
53
+ const reasons = [];
54
+ if (!verifyMandateSignature(env))
55
+ reasons.push("mandate: signature invalid or not signed by principal");
56
+ const start = new Date(env.issuedAt).getTime();
57
+ const end = new Date(env.expiresAt).getTime();
58
+ const t = now.getTime();
59
+ if (t < start - skew)
60
+ reasons.push("mandate: not yet valid (issuedAt in the future)");
61
+ if (t >= end + skew)
62
+ reasons.push("mandate: expired");
63
+ if (opts.isRevoked?.(env))
64
+ reasons.push("mandate: revoked");
65
+ return reasons;
66
+ }
67
+ /**
68
+ * Full verification of an envelope and its ordered receipt chain (spec §6).
69
+ * This is what a verifier runs on a dispute-evidence bundle.
70
+ */
71
+ export function verifyChain(env, receipts, opts = {}) {
72
+ const now = opts.now ?? new Date();
73
+ const reasons = envelopeReasons(env, opts);
74
+ const eHash = mandateHash(env);
75
+ let prevHash = null;
76
+ receipts.forEach((r, i) => {
77
+ const label = `receipt[${i}]`;
78
+ if (r.mandateId !== env.id)
79
+ reasons.push(`${label}: mandateId does not match mandate`);
80
+ if (r.mandateHash !== eHash)
81
+ reasons.push(`${label}: mandateHash mismatch (mandate was altered)`);
82
+ if (r.agent !== env.agent)
83
+ reasons.push(`${label}: agent does not match mandate`);
84
+ if (!verifyReceiptSignature(r))
85
+ reasons.push(`${label}: signature invalid or not signed by agent`);
86
+ if ((r.prevReceiptHash ?? null) !== prevHash)
87
+ reasons.push(`${label}: chain broken (prevReceiptHash mismatch)`);
88
+ reasons.push(...scopeViolations(env.scope, r.action, label));
89
+ prevHash = receiptHash(r);
90
+ });
91
+ let cumulativeSpend;
92
+ if (env.scope.budget) {
93
+ cumulativeSpend = spendInWindow(env.scope, receipts, now);
94
+ if (cumulativeSpend > env.scope.budget.amount) {
95
+ reasons.push(`budget exceeded: ${cumulativeSpend} > ${env.scope.budget.amount} ${env.scope.budget.currency} within ${env.scope.budget.windowSeconds}s window`);
96
+ }
97
+ }
98
+ return { ok: reasons.length === 0, reasons, cumulativeSpend };
99
+ }
100
+ /**
101
+ * Pre-transaction authorization (the gateway path). Given the envelope, the prior
102
+ * receipt chain, and a candidate action, decide whether the agent may proceed.
103
+ * Validates the envelope, the existing chain, the candidate's static scope, and the
104
+ * budget *including* the candidate.
105
+ */
106
+ export function authorize(env, priorReceipts, candidate, opts = {}) {
107
+ const now = opts.now ?? new Date();
108
+ // The existing state must itself be valid.
109
+ const base = verifyChain(env, priorReceipts, opts);
110
+ const reasons = [...base.reasons];
111
+ // Candidate's static scope.
112
+ reasons.push(...scopeViolations(env.scope, candidate, "candidate"));
113
+ // Budget including the candidate.
114
+ let cumulativeSpend = base.cumulativeSpend ?? 0;
115
+ if (env.scope.budget) {
116
+ const projected = spendInWindow(env.scope, priorReceipts, now) + candidate.amount;
117
+ cumulativeSpend = projected;
118
+ if (projected > env.scope.budget.amount) {
119
+ reasons.push(`candidate would exceed budget: ${projected} > ${env.scope.budget.amount} ${env.scope.budget.currency}`);
120
+ }
121
+ }
122
+ return { ok: reasons.length === 0, reasons, cumulativeSpend };
123
+ }
124
+ //# 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,39 @@
1
+ {
2
+ "name": "@vantic/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Vantic — a spending firewall and permission layer for AI agents: signed mandates, allowlists, and tamper-proof receipts for every money-moving action.",
5
+ "type": "module",
6
+ "license": "Apache-2.0",
7
+ "author": "Vantic Labs",
8
+ "engines": { "node": ">=18" },
9
+ "main": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "bin": { "vantic-mcp": "dist/mcp.js" },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ }
17
+ },
18
+ "files": ["dist/*.js", "dist/*.d.ts", "dist/*.d.ts.map", "dist/*.js.map", "!dist/demo.*", "!dist/*-demo.*", "README.md", "LICENSE"],
19
+ "publishConfig": { "access": "public" },
20
+ "repository": { "type": "git", "url": "git+https://github.com/vanticlabs/vantic.git" },
21
+ "homepage": "https://github.com/vanticlabs/vantic#readme",
22
+ "bugs": { "url": "https://github.com/vanticlabs/vantic/issues" },
23
+ "scripts": {
24
+ "build": "tsc",
25
+ "test": "node --test dist/test/",
26
+ "demo": "tsc && node dist/demo.js",
27
+ "guard-demo": "tsc && node dist/guard-demo.js",
28
+ "adapters-demo": "tsc && node dist/adapters-demo.js",
29
+ "identity-demo": "tsc && node dist/identity-demo.js",
30
+ "gate-demo": "tsc && node dist/gate-demo.js",
31
+ "mcp": "tsc && node dist/mcp.js",
32
+ "prepublishOnly": "tsc"
33
+ },
34
+ "keywords": ["ai-agents", "agentic-commerce", "delegation", "ed25519", "receipts", "mcp", "mcp-server", "did", "verifiable-credentials", "agent-payments", "prompt-injection"],
35
+ "devDependencies": {
36
+ "typescript": "^5.5.0",
37
+ "@types/node": "^20.0.0"
38
+ }
39
+ }