@vallum/contracts-metadata 0.0.0-prerelease

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 ADDED
@@ -0,0 +1,18 @@
1
+ # @vallum/contracts-metadata
2
+
3
+ Versioned contract template metadata registry for Vallum policy
4
+ allow-lists.
5
+
6
+ This package is local prerelease workspace code. It provides metadata and pure
7
+ evaluation helpers for approved contract templates such as `escrow_v1`,
8
+ `receipt_v1`, `pay_per_call_v1`, `data_license_v1`, `service_bounty_v1`,
9
+ `reputation_receipt_v1`, and `subscription_v1`; it does not deploy contracts,
10
+ verify providers, settle payments, operate reputation scoring, operate
11
+ recurring billing, or prove live package addresses.
12
+
13
+ ## Local checks
14
+
15
+ ```bash
16
+ npm run build -w @vallum/contracts-metadata
17
+ node --import tsx --test packages/contracts-metadata/src/*.test.ts
18
+ ```
@@ -0,0 +1,45 @@
1
+ export type ContractTemplateRiskCategory = "low" | "medium" | "high";
2
+ export interface ContractTemplateMetadata {
3
+ readonly templateId: string;
4
+ readonly version: string;
5
+ readonly packageId: string;
6
+ readonly module: string;
7
+ readonly entryFunctions: readonly string[];
8
+ readonly allowedActions: readonly string[];
9
+ readonly riskCategory: ContractTemplateRiskCategory;
10
+ readonly receiptEvents: readonly string[];
11
+ readonly requiredManifestFields: readonly string[];
12
+ readonly refundDisputeBehavior: string;
13
+ }
14
+ export interface ContractTemplateAction {
15
+ readonly templateId?: string;
16
+ readonly templateVersion?: string;
17
+ readonly packageId: string;
18
+ readonly module?: string;
19
+ readonly functionName: string;
20
+ }
21
+ export type ContractTemplateDecision = {
22
+ readonly allowed: true;
23
+ readonly template: ContractTemplateMetadata;
24
+ } | {
25
+ readonly allowed: false;
26
+ readonly reasonCode: "CONTRACT_TEMPLATE_NOT_REGISTERED" | "CONTRACT_TEMPLATE_VERSION_MISMATCH" | "CONTRACT_PACKAGE_NOT_REGISTERED" | "CONTRACT_MODULE_NOT_REGISTERED" | "CONTRACT_FUNCTION_NOT_REGISTERED";
27
+ readonly message: string;
28
+ };
29
+ export interface ContractTemplateRegistry {
30
+ readonly templates: readonly ContractTemplateMetadata[];
31
+ readonly findTemplate: (templateId: string, version: string) => ContractTemplateMetadata | undefined;
32
+ readonly findTemplateVersions: (templateId: string) => readonly ContractTemplateMetadata[];
33
+ }
34
+ export declare const escrowContractTemplateV1: ContractTemplateMetadata;
35
+ export declare const receiptContractTemplateV1: ContractTemplateMetadata;
36
+ export declare const payPerCallContractTemplateV1: ContractTemplateMetadata;
37
+ export declare const dataLicenseContractTemplateV1: ContractTemplateMetadata;
38
+ export declare const serviceBountyContractTemplateV1: ContractTemplateMetadata;
39
+ export declare const reputationReceiptContractTemplateV1: ContractTemplateMetadata;
40
+ export declare const subscriptionContractTemplateV1: ContractTemplateMetadata;
41
+ export declare const defaultContractTemplates: readonly [ContractTemplateMetadata, ContractTemplateMetadata, ContractTemplateMetadata, ContractTemplateMetadata, ContractTemplateMetadata, ContractTemplateMetadata, ContractTemplateMetadata];
42
+ export declare const defaultContractTemplateRegistry: ContractTemplateRegistry;
43
+ export declare function createContractTemplateRegistry(templates: readonly ContractTemplateMetadata[]): ContractTemplateRegistry;
44
+ export declare function evaluateContractTemplateAction(registry: ContractTemplateRegistry, action: ContractTemplateAction): ContractTemplateDecision;
45
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,140 @@
1
+ export const escrowContractTemplateV1 = {
2
+ templateId: "escrow_v1",
3
+ version: "1.0.0",
4
+ packageId: "0x2222222222222222222222222222222222222222222222222222222222222222",
5
+ module: "escrow",
6
+ entryFunctions: ["open_escrow", "release_escrow", "refund_escrow"],
7
+ allowedActions: ["open_escrow", "release_escrow", "refund_escrow"],
8
+ riskCategory: "medium",
9
+ receiptEvents: ["escrow_opened", "escrow_released", "escrow_refunded"],
10
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
11
+ refundDisputeBehavior: "Verifier release or expiry/refund state transition.",
12
+ };
13
+ export const receiptContractTemplateV1 = {
14
+ templateId: "receipt_v1",
15
+ version: "1.0.0",
16
+ packageId: "0x4444444444444444444444444444444444444444444444444444444444444444",
17
+ module: "receipt",
18
+ entryFunctions: ["create_receipt", "mark_released", "mark_refunded"],
19
+ allowedActions: ["create_receipt", "mark_released", "mark_refunded"],
20
+ riskCategory: "low",
21
+ receiptEvents: ["receipt_created", "receipt_released", "receipt_refunded"],
22
+ requiredManifestFields: ["agent", "owner", "action", "receipt"],
23
+ refundDisputeBehavior: "Records external escrow outcome without independently settling funds.",
24
+ };
25
+ export const payPerCallContractTemplateV1 = {
26
+ templateId: "pay_per_call_v1",
27
+ version: "1.0.0",
28
+ packageId: "0x5555555555555555555555555555555555555555555555555555555555555555",
29
+ module: "pay_per_call",
30
+ entryFunctions: ["request_call", "deliver", "refund"],
31
+ allowedActions: ["request_call", "deliver", "refund"],
32
+ riskCategory: "medium",
33
+ receiptEvents: ["pay_per_call_created", "submitted", "completed", "failed"],
34
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
35
+ refundDisputeBehavior: "Provider delivery after payment confirmation or refund/fail before result delivery.",
36
+ };
37
+ export const dataLicenseContractTemplateV1 = {
38
+ templateId: "data_license_v1",
39
+ version: "1.0.0",
40
+ packageId: "0x6666666666666666666666666666666666666666666666666666666666666666",
41
+ module: "data_license",
42
+ entryFunctions: ["request_license", "grant_access", "revoke_access"],
43
+ allowedActions: ["request_license", "grant_access", "revoke_access"],
44
+ riskCategory: "medium",
45
+ receiptEvents: ["data_license_created", "access_granted", "access_revoked", "failed"],
46
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
47
+ refundDisputeBehavior: "Provider grants scoped access after policy approval or revokes access with receipt evidence.",
48
+ };
49
+ export const serviceBountyContractTemplateV1 = {
50
+ templateId: "service_bounty_v1",
51
+ version: "1.0.0",
52
+ packageId: "0x7777777777777777777777777777777777777777777777777777777777777777",
53
+ module: "service_bounty",
54
+ entryFunctions: ["post_bounty", "complete_bounty", "release_bounty", "cancel_bounty"],
55
+ allowedActions: ["post_bounty", "complete_bounty", "release_bounty", "cancel_bounty"],
56
+ riskCategory: "medium",
57
+ receiptEvents: ["service_bounty_created", "submitted", "completed", "released", "failed"],
58
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
59
+ refundDisputeBehavior: "Provider completion proof followed by requester release, or cancellation/failure evidence.",
60
+ };
61
+ export const reputationReceiptContractTemplateV1 = {
62
+ templateId: "reputation_receipt_v1",
63
+ version: "1.0.0",
64
+ packageId: "0x8888888888888888888888888888888888888888888888888888888888888888",
65
+ module: "reputation_receipt",
66
+ entryFunctions: ["create_receipt", "attest_reputation", "fail_receipt"],
67
+ allowedActions: ["create_receipt", "attest_reputation", "fail_receipt"],
68
+ riskCategory: "medium",
69
+ receiptEvents: ["reputation_receipt_created", "submitted", "completed", "failed"],
70
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
71
+ refundDisputeBehavior: "Issuer attests local reputation evidence; failures are receipt evidence, not public scoring.",
72
+ };
73
+ export const subscriptionContractTemplateV1 = {
74
+ templateId: "subscription_v1",
75
+ version: "1.0.0",
76
+ packageId: "0x9999999999999999999999999999999999999999999999999999999999999998",
77
+ module: "subscription",
78
+ entryFunctions: ["start_subscription", "renew_subscription", "cancel_subscription", "fail_subscription"],
79
+ allowedActions: ["start_subscription", "renew_subscription", "cancel_subscription", "fail_subscription"],
80
+ riskCategory: "medium",
81
+ receiptEvents: ["subscription_created", "activated", "renewed", "canceled", "failed"],
82
+ requiredManifestFields: ["agent", "owner", "spend", "action", "counterparty", "receipt"],
83
+ refundDisputeBehavior: "Local entitlement evidence for activation, renewal, cancellation, or failed proof.",
84
+ };
85
+ export const defaultContractTemplates = [
86
+ escrowContractTemplateV1,
87
+ receiptContractTemplateV1,
88
+ payPerCallContractTemplateV1,
89
+ dataLicenseContractTemplateV1,
90
+ serviceBountyContractTemplateV1,
91
+ reputationReceiptContractTemplateV1,
92
+ subscriptionContractTemplateV1,
93
+ ];
94
+ export const defaultContractTemplateRegistry = createContractTemplateRegistry(defaultContractTemplates);
95
+ export function createContractTemplateRegistry(templates) {
96
+ const byTemplateVersion = new Map();
97
+ const byTemplate = new Map();
98
+ for (const template of templates) {
99
+ byTemplateVersion.set(templateKey(template.templateId, template.version), template);
100
+ const versions = byTemplate.get(template.templateId) ?? [];
101
+ versions.push(template);
102
+ byTemplate.set(template.templateId, versions);
103
+ }
104
+ return {
105
+ templates: Object.freeze([...templates]),
106
+ findTemplate(templateId, version) {
107
+ return byTemplateVersion.get(templateKey(templateId, version));
108
+ },
109
+ findTemplateVersions(templateId) {
110
+ return Object.freeze([...(byTemplate.get(templateId) ?? [])]);
111
+ },
112
+ };
113
+ }
114
+ export function evaluateContractTemplateAction(registry, action) {
115
+ if (!action.templateId || !action.templateVersion) {
116
+ return reject("CONTRACT_TEMPLATE_NOT_REGISTERED", "Contract action is missing template id or version metadata.");
117
+ }
118
+ const template = registry.findTemplate(action.templateId, action.templateVersion);
119
+ if (!template) {
120
+ const knownVersions = registry.findTemplateVersions(action.templateId);
121
+ return reject(knownVersions.length > 0 ? "CONTRACT_TEMPLATE_VERSION_MISMATCH" : "CONTRACT_TEMPLATE_NOT_REGISTERED", "Contract template id and version are not registered.");
122
+ }
123
+ if (template.packageId !== action.packageId) {
124
+ return reject("CONTRACT_PACKAGE_NOT_REGISTERED", "Contract package does not match approved template metadata.");
125
+ }
126
+ if (template.module !== action.module) {
127
+ return reject("CONTRACT_MODULE_NOT_REGISTERED", "Contract module does not match approved template metadata.");
128
+ }
129
+ if (!template.entryFunctions.includes(action.functionName)) {
130
+ return reject("CONTRACT_FUNCTION_NOT_REGISTERED", "Contract function does not match approved template metadata.");
131
+ }
132
+ return { allowed: true, template };
133
+ }
134
+ function templateKey(templateId, version) {
135
+ return `${templateId}@${version}`;
136
+ }
137
+ function reject(reasonCode, message) {
138
+ return { allowed: false, reasonCode, message };
139
+ }
140
+ //# sourceMappingURL=index.js.map
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@vallum/contracts-metadata",
3
+ "version": "0.0.0-prerelease",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "license": "Apache-2.0",
14
+ "description": "Versioned contract template metadata registry for Vallum policy allow-lists.",
15
+ "files": [
16
+ "dist/**/*.js",
17
+ "dist/**/*.d.ts",
18
+ "LICENSE",
19
+ "README.md"
20
+ ],
21
+ "sideEffects": false,
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.build.json"
24
+ },
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "tag": "next"
31
+ }
32
+ }