@carrot-foundation/schemas 0.1.41 → 0.1.43
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.cjs +609 -615
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +325 -457
- package/dist/index.d.ts +325 -457
- package/dist/index.js +601 -614
- package/dist/index.js.map +1 -1
- package/package.json +10 -3
- package/schemas/ipfs/collection/collection.example.json +6 -6
- package/schemas/ipfs/collection/collection.schema.json +7 -6
- package/schemas/ipfs/credit/credit.example.json +6 -6
- package/schemas/ipfs/credit/credit.schema.json +7 -6
- package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.example.json +40 -24
- package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.schema.json +40 -50
- package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.example.json +39 -31
- package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.schema.json +41 -51
- package/schemas/ipfs/gas-id/gas-id.example.json +19 -19
- package/schemas/ipfs/gas-id/gas-id.schema.json +85 -594
- package/schemas/ipfs/mass-id/mass-id.example.json +12 -7
- package/schemas/ipfs/mass-id/mass-id.schema.json +31 -35
- package/schemas/ipfs/mass-id-audit/mass-id-audit.example.json +12 -12
- package/schemas/ipfs/mass-id-audit/mass-id-audit.schema.json +17 -16
- package/schemas/ipfs/methodology/methodology.example.json +10 -10
- package/schemas/ipfs/methodology/methodology.schema.json +8 -7
- package/schemas/ipfs/recycled-id/recycled-id.example.json +20 -20
- package/schemas/ipfs/recycled-id/recycled-id.schema.json +85 -545
- package/schemas/schema-hashes.json +41 -0
package/dist/index.cjs
CHANGED
|
@@ -3,82 +3,14 @@
|
|
|
3
3
|
var zod = require('zod');
|
|
4
4
|
require('fs');
|
|
5
5
|
require('path');
|
|
6
|
+
var crypto = require('crypto');
|
|
7
|
+
var canonicalize = require('canonicalize');
|
|
8
|
+
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var canonicalize__default = /*#__PURE__*/_interopDefault(canonicalize);
|
|
6
12
|
|
|
7
13
|
// src/mass-id/mass-id.attributes.ts
|
|
8
|
-
var nativeDateParse = Date.parse.bind(Date);
|
|
9
|
-
var ISO_TIMESTAMP_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
10
|
-
var UuidSchema = zod.z.uuidv4().meta({
|
|
11
|
-
title: "UUID V4",
|
|
12
|
-
description: "A universally unique identifier version 4",
|
|
13
|
-
examples: ["ad44dd3f-f176-4b98-bf78-5ee6e77d0530"]
|
|
14
|
-
});
|
|
15
|
-
var EthereumAddressSchema = zod.z.string().regex(
|
|
16
|
-
/^0x[a-f0-9]{40}$/,
|
|
17
|
-
"Must be a valid Ethereum address in lowercase hexadecimal format"
|
|
18
|
-
).meta({
|
|
19
|
-
title: "Ethereum Address",
|
|
20
|
-
description: "A valid Ethereum address in hexadecimal format",
|
|
21
|
-
examples: ["0x1234567890abcdef1234567890abcdef12345678"]
|
|
22
|
-
});
|
|
23
|
-
var IsoTimestampSchema = zod.z.string().regex(
|
|
24
|
-
ISO_TIMESTAMP_REGEX,
|
|
25
|
-
"Must be a valid ISO 8601 timestamp with timezone information"
|
|
26
|
-
).superRefine((value, ctx) => {
|
|
27
|
-
const parsed = nativeDateParse(value);
|
|
28
|
-
if (Number.isNaN(parsed)) {
|
|
29
|
-
ctx.addIssue({
|
|
30
|
-
code: "custom",
|
|
31
|
-
message: "Must be a valid ISO 8601 timestamp with timezone information"
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}).meta({
|
|
35
|
-
title: "ISO Timestamp",
|
|
36
|
-
description: "ISO 8601 formatted timestamp with timezone information",
|
|
37
|
-
examples: ["2024-12-05T11:02:47.000Z"]
|
|
38
|
-
});
|
|
39
|
-
var IsoDateSchema = zod.z.iso.date("Must be a valid ISO 8601 date (YYYY-MM-DD)").meta({
|
|
40
|
-
title: "ISO Date",
|
|
41
|
-
description: "ISO 8601 formatted date in YYYY-MM-DD format",
|
|
42
|
-
examples: ["2024-12-05"]
|
|
43
|
-
});
|
|
44
|
-
var UnixTimestampSchema = zod.z.number().int().positive().meta({
|
|
45
|
-
title: "Unix Timestamp",
|
|
46
|
-
description: "Unix timestamp in milliseconds since epoch (January 1, 1970 00:00:00 UTC)",
|
|
47
|
-
examples: [17040672e5]
|
|
48
|
-
});
|
|
49
|
-
var IsoCountryCodeSchema = zod.z.string().regex(/^[A-Z]{2}$/, "Must be a valid ISO 3166-1 alpha-2 country code").meta({
|
|
50
|
-
title: "ISO Country Code",
|
|
51
|
-
description: "Two-letter country code following ISO 3166-1 alpha-2 standard",
|
|
52
|
-
examples: ["BR", "US", "DE"]
|
|
53
|
-
});
|
|
54
|
-
var IsoAdministrativeDivisionCodeSchema = zod.z.string().regex(
|
|
55
|
-
/^[A-Z]{2}-[A-Z0-9]{1,3}$/,
|
|
56
|
-
"Must be a valid ISO 3166-2 administrative division code"
|
|
57
|
-
).meta({
|
|
58
|
-
title: "ISO Administrative Division Code",
|
|
59
|
-
description: "Administrative division code following ISO 3166-2 standard",
|
|
60
|
-
examples: ["BR-AP", "BR-ES", "US-CA"]
|
|
61
|
-
});
|
|
62
|
-
var LatitudeSchema = zod.z.number().min(-90).max(90).multipleOf(1e-3).meta({
|
|
63
|
-
title: "Latitude",
|
|
64
|
-
description: "Geographic latitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level)",
|
|
65
|
-
examples: [-0.02, -20.38, 40.713]
|
|
66
|
-
});
|
|
67
|
-
var LongitudeSchema = zod.z.number().min(-180).max(180).multipleOf(1e-3).meta({
|
|
68
|
-
title: "Longitude",
|
|
69
|
-
description: "Geographic longitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level)",
|
|
70
|
-
examples: [-51.06, -40.34, -74.006]
|
|
71
|
-
});
|
|
72
|
-
var NonNegativeFloatSchema = zod.z.number().min(0).meta({
|
|
73
|
-
title: "Non-Negative Float",
|
|
74
|
-
description: "Floating-point number that is zero or positive",
|
|
75
|
-
examples: [0, 45.2, 72.5]
|
|
76
|
-
});
|
|
77
|
-
var WeightKgSchema = NonNegativeFloatSchema.meta({
|
|
78
|
-
title: "Weight (kg)",
|
|
79
|
-
description: "Weight measurement in kilograms",
|
|
80
|
-
examples: [3e3, 1500, 500]
|
|
81
|
-
});
|
|
82
14
|
var NonEmptyStringSchema = zod.z.string().min(1, "Cannot be empty").meta({
|
|
83
15
|
title: "Non-Empty String",
|
|
84
16
|
description: "A string that contains at least one character",
|
|
@@ -109,14 +41,6 @@ var MethodologyNameSchema = NonEmptyStringSchema.max(100).meta({
|
|
|
109
41
|
description: "Name of the methodology used for certification",
|
|
110
42
|
examples: ["BOLD Recycling", "BOLD Carbon (CH\u2084)"]
|
|
111
43
|
});
|
|
112
|
-
var StringifiedTokenIdSchema = NonEmptyStringSchema.regex(
|
|
113
|
-
/^#\d+$/,
|
|
114
|
-
"Must match pattern #<token_id>"
|
|
115
|
-
).meta({
|
|
116
|
-
title: "Token ID",
|
|
117
|
-
description: "Token ID represented as #<token_id>",
|
|
118
|
-
example: "#123"
|
|
119
|
-
});
|
|
120
44
|
var SlugSchema = NonEmptyStringSchema.regex(
|
|
121
45
|
/^[a-z0-9-]+$/,
|
|
122
46
|
"Must contain only lowercase letters, numbers, and hyphens"
|
|
@@ -130,16 +54,6 @@ var CollectionSlugSchema = SlugSchema.meta({
|
|
|
130
54
|
description: "URL-friendly identifier for a collection",
|
|
131
55
|
examples: ["bold-cold-start-carazinho", "bold-brazil"]
|
|
132
56
|
});
|
|
133
|
-
var WasteTypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
134
|
-
title: "Waste Type",
|
|
135
|
-
description: "Category or type of waste material",
|
|
136
|
-
examples: ["Organic", "Plastic", "Metal"]
|
|
137
|
-
});
|
|
138
|
-
var WasteSubtypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
139
|
-
title: "Waste Subtype",
|
|
140
|
-
description: "Specific subcategory of waste within a waste type",
|
|
141
|
-
examples: ["Food, Food Waste and Beverages", "Domestic Sludge"]
|
|
142
|
-
});
|
|
143
57
|
var ParticipantRoleSchema = NonEmptyStringSchema.max(100).meta({
|
|
144
58
|
title: "Participant Role",
|
|
145
59
|
description: "Role that a participant plays in the waste management supply chain",
|
|
@@ -150,27 +64,38 @@ var ParticipantNameSchema = NonEmptyStringSchema.max(100).meta({
|
|
|
150
64
|
description: "Name of a participant in the waste management system",
|
|
151
65
|
examples: ["Enlatados Produ\xE7\xE3o", "Eco Reciclagem", "Green Tech Corp"]
|
|
152
66
|
});
|
|
153
|
-
var
|
|
154
|
-
title: "
|
|
155
|
-
description: "
|
|
156
|
-
examples: [
|
|
67
|
+
var WasteTypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
68
|
+
title: "Waste Type",
|
|
69
|
+
description: "Category or type of waste material",
|
|
70
|
+
examples: ["Organic", "Plastic", "Metal"]
|
|
157
71
|
});
|
|
158
|
-
var
|
|
159
|
-
title: "
|
|
160
|
-
description: "
|
|
161
|
-
examples: ["
|
|
72
|
+
var WasteSubtypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
73
|
+
title: "Waste Subtype",
|
|
74
|
+
description: "Specific subcategory of waste within a waste type",
|
|
75
|
+
examples: ["Food, Food Waste and Beverages", "Domestic Sludge"]
|
|
162
76
|
});
|
|
163
|
-
var
|
|
164
|
-
title: "
|
|
165
|
-
description: "
|
|
77
|
+
var CreditTypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
78
|
+
title: "Credit Type",
|
|
79
|
+
description: "Type of credit issued",
|
|
80
|
+
examples: ["Organic", "Carbon (CH\u2084)"]
|
|
166
81
|
});
|
|
167
|
-
var
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
82
|
+
var HexColorSchema = NonEmptyStringSchema.regex(
|
|
83
|
+
/^#[0-9A-F]{6}$/,
|
|
84
|
+
"Must be a hex color code with # prefix and uppercase"
|
|
85
|
+
).meta({
|
|
86
|
+
title: "Hex Color",
|
|
87
|
+
description: "Hexadecimal color code with hash prefix",
|
|
88
|
+
examples: ["#2D5A27", "#FF5733"]
|
|
89
|
+
});
|
|
90
|
+
var NonNegativeFloatSchema = zod.z.number().min(0).meta({
|
|
91
|
+
title: "Non-Negative Float",
|
|
92
|
+
description: "Floating-point number that is zero or positive",
|
|
93
|
+
examples: [0, 45.2, 72.5]
|
|
94
|
+
});
|
|
95
|
+
var WeightKgSchema = NonNegativeFloatSchema.meta({
|
|
96
|
+
title: "Weight (kg)",
|
|
97
|
+
description: "Weight measurement in kilograms",
|
|
98
|
+
examples: [3e3, 1500, 500]
|
|
174
99
|
});
|
|
175
100
|
var PercentageSchema = NonNegativeFloatSchema.max(100).meta({
|
|
176
101
|
title: "Percentage",
|
|
@@ -187,43 +112,107 @@ var PositiveIntegerSchema = zod.z.number().int().min(1).meta({
|
|
|
187
112
|
description: "Integer value that is greater than zero",
|
|
188
113
|
examples: [1, 123, 456]
|
|
189
114
|
});
|
|
190
|
-
var CreditTypeSchema = NonEmptyStringSchema.max(100).meta({
|
|
191
|
-
title: "Credit Type",
|
|
192
|
-
description: "Type of credit issued",
|
|
193
|
-
examples: ["Organic", "Carbon (CH\u2084)"]
|
|
194
|
-
});
|
|
195
115
|
var CreditAmountSchema = NonNegativeFloatSchema.meta({
|
|
196
116
|
title: "Credit Amount",
|
|
197
117
|
description: "Amount of credits issued"
|
|
198
118
|
});
|
|
199
|
-
var
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
119
|
+
var IsoTimestampSchema = zod.z.string().datetime({
|
|
120
|
+
message: "Must be a valid ISO 8601 timestamp with timezone information",
|
|
121
|
+
offset: true
|
|
122
|
+
}).meta({
|
|
123
|
+
title: "ISO Timestamp",
|
|
124
|
+
description: "ISO 8601 formatted timestamp with timezone information",
|
|
125
|
+
examples: ["2024-12-05T11:02:47.000Z"]
|
|
203
126
|
});
|
|
204
|
-
var
|
|
205
|
-
title: "
|
|
206
|
-
description: "
|
|
207
|
-
examples: [
|
|
127
|
+
var IsoDateSchema = zod.z.iso.date("Must be a valid ISO 8601 date (YYYY-MM-DD)").meta({
|
|
128
|
+
title: "ISO Date",
|
|
129
|
+
description: "ISO 8601 formatted date in YYYY-MM-DD format",
|
|
130
|
+
examples: ["2024-12-05"]
|
|
208
131
|
});
|
|
209
|
-
var
|
|
210
|
-
|
|
211
|
-
"
|
|
132
|
+
var UnixTimestampSchema = zod.z.number().int().positive().meta({
|
|
133
|
+
title: "Unix Timestamp",
|
|
134
|
+
description: "Unix timestamp in milliseconds since epoch (January 1, 1970 00:00:00 UTC)",
|
|
135
|
+
examples: [17040672e5]
|
|
136
|
+
});
|
|
137
|
+
var IsoCountryCodeSchema = zod.z.string().regex(/^[A-Z]{2}$/, "Must be a valid ISO 3166-1 alpha-2 country code").meta({
|
|
138
|
+
title: "ISO Country Code",
|
|
139
|
+
description: "Two-letter country code following ISO 3166-1 alpha-2 standard",
|
|
140
|
+
examples: ["BR", "US", "DE"]
|
|
141
|
+
});
|
|
142
|
+
var IsoAdministrativeDivisionCodeSchema = zod.z.string().regex(
|
|
143
|
+
/^[A-Z]{2}-[A-Z0-9]{1,3}$/,
|
|
144
|
+
"Must be a valid ISO 3166-2 administrative division code"
|
|
212
145
|
).meta({
|
|
213
|
-
title: "
|
|
214
|
-
description: "
|
|
215
|
-
examples: [
|
|
216
|
-
"ipfs://QmTy8w65yBXgyfG2ZBg5TrfB2hPjrDQH3RCQFJGkARStJb/mass-id-organic.png",
|
|
217
|
-
"ipfs://QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o"
|
|
218
|
-
]
|
|
146
|
+
title: "ISO Administrative Division Code",
|
|
147
|
+
description: "Administrative division code following ISO 3166-2 standard",
|
|
148
|
+
examples: ["BR-AP", "BR-ES", "US-CA"]
|
|
219
149
|
});
|
|
220
|
-
var
|
|
221
|
-
|
|
222
|
-
"
|
|
150
|
+
var LatitudeSchema = zod.z.number().min(-90).max(90).multipleOf(1e-3).meta({
|
|
151
|
+
title: "Latitude",
|
|
152
|
+
description: "Geographic latitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level)",
|
|
153
|
+
examples: [-0.02, -20.38, 40.713]
|
|
154
|
+
});
|
|
155
|
+
var LongitudeSchema = zod.z.number().min(-180).max(180).multipleOf(1e-3).meta({
|
|
156
|
+
title: "Longitude",
|
|
157
|
+
description: "Geographic longitude coordinate in decimal degrees with maximum 3 decimal places precision (~100m-1km accuracy for city-level)",
|
|
158
|
+
examples: [-51.06, -40.34, -74.006]
|
|
159
|
+
});
|
|
160
|
+
var BLOCKCHAIN_NETWORK_CONFIG = {
|
|
161
|
+
mainnet: { chain_id: 137, network_name: "Polygon" },
|
|
162
|
+
testnet: { chain_id: 80002, network_name: "Amoy" }
|
|
163
|
+
};
|
|
164
|
+
var ALLOWED_BLOCKCHAIN_NETWORKS = Object.values(
|
|
165
|
+
BLOCKCHAIN_NETWORK_CONFIG
|
|
166
|
+
);
|
|
167
|
+
var BLOCKCHAIN_CHAIN_IDS = [
|
|
168
|
+
BLOCKCHAIN_NETWORK_CONFIG.mainnet.chain_id,
|
|
169
|
+
BLOCKCHAIN_NETWORK_CONFIG.testnet.chain_id
|
|
170
|
+
];
|
|
171
|
+
var BLOCKCHAIN_NETWORK_NAMES = [
|
|
172
|
+
BLOCKCHAIN_NETWORK_CONFIG.mainnet.network_name,
|
|
173
|
+
BLOCKCHAIN_NETWORK_CONFIG.testnet.network_name
|
|
174
|
+
];
|
|
175
|
+
var EthereumAddressSchema = zod.z.string().regex(
|
|
176
|
+
/^0x[a-f0-9]{40}$/,
|
|
177
|
+
"Must be a valid Ethereum address in lowercase hexadecimal format"
|
|
223
178
|
).meta({
|
|
224
|
-
title: "
|
|
225
|
-
description: "
|
|
226
|
-
examples: ["
|
|
179
|
+
title: "Ethereum Address",
|
|
180
|
+
description: "A valid Ethereum address in hexadecimal format",
|
|
181
|
+
examples: ["0x1234567890abcdef1234567890abcdef12345678"]
|
|
182
|
+
});
|
|
183
|
+
var BlockchainChainIdSchema = zod.z.union([
|
|
184
|
+
zod.z.literal(BLOCKCHAIN_NETWORK_CONFIG.mainnet.chain_id),
|
|
185
|
+
zod.z.literal(BLOCKCHAIN_NETWORK_CONFIG.testnet.chain_id)
|
|
186
|
+
]).meta({
|
|
187
|
+
title: "Chain ID",
|
|
188
|
+
description: "Supported Polygon chain identifiers",
|
|
189
|
+
examples: BLOCKCHAIN_CHAIN_IDS
|
|
190
|
+
});
|
|
191
|
+
var BlockchainNetworkNameSchema = zod.z.enum(BLOCKCHAIN_NETWORK_NAMES).meta({
|
|
192
|
+
title: "Blockchain Network Name",
|
|
193
|
+
description: "Supported Polygon network names",
|
|
194
|
+
examples: BLOCKCHAIN_NETWORK_NAMES
|
|
195
|
+
});
|
|
196
|
+
var SmartContractAddressSchema = EthereumAddressSchema.meta({
|
|
197
|
+
title: "Smart Contract Address",
|
|
198
|
+
description: "Address of the smart contract"
|
|
199
|
+
});
|
|
200
|
+
var SmartContractSchema = zod.z.strictObject({
|
|
201
|
+
address: SmartContractAddressSchema,
|
|
202
|
+
chain_id: BlockchainChainIdSchema,
|
|
203
|
+
network_name: BlockchainNetworkNameSchema
|
|
204
|
+
}).meta({
|
|
205
|
+
title: "Smart Contract",
|
|
206
|
+
description: "Smart contract details for on-chain references"
|
|
207
|
+
});
|
|
208
|
+
var UuidSchema = zod.z.uuidv4().meta({
|
|
209
|
+
title: "UUID V4",
|
|
210
|
+
description: "A universally unique identifier version 4",
|
|
211
|
+
examples: ["ad44dd3f-f176-4b98-bf78-5ee6e77d0530"]
|
|
212
|
+
});
|
|
213
|
+
var ExternalIdSchema = UuidSchema.meta({
|
|
214
|
+
title: "External ID",
|
|
215
|
+
description: "UUID identifier for external system references"
|
|
227
216
|
});
|
|
228
217
|
var TokenIdSchema = NonEmptyStringSchema.regex(
|
|
229
218
|
/^\d+$/,
|
|
@@ -233,16 +222,16 @@ var TokenIdSchema = NonEmptyStringSchema.regex(
|
|
|
233
222
|
description: "Numeric identifier for blockchain tokens as string",
|
|
234
223
|
examples: ["456789", "1000000"]
|
|
235
224
|
});
|
|
236
|
-
var
|
|
237
|
-
|
|
238
|
-
"Must
|
|
225
|
+
var StringifiedTokenIdSchema = NonEmptyStringSchema.regex(
|
|
226
|
+
/^#\d+$/,
|
|
227
|
+
"Must match pattern #<token_id>"
|
|
239
228
|
).meta({
|
|
240
|
-
title: "
|
|
241
|
-
description: "
|
|
242
|
-
|
|
229
|
+
title: "Token ID",
|
|
230
|
+
description: "Token ID represented as #<token_id>",
|
|
231
|
+
example: "#123"
|
|
243
232
|
});
|
|
244
233
|
var Sha256HashSchema = zod.z.hash("sha256", {
|
|
245
|
-
error: "Must be a
|
|
234
|
+
error: "Must be a SHA256 hash as 32-byte hex string"
|
|
246
235
|
}).meta({
|
|
247
236
|
format: void 0,
|
|
248
237
|
title: "SHA-256 Hash",
|
|
@@ -251,18 +240,33 @@ var Sha256HashSchema = zod.z.hash("sha256", {
|
|
|
251
240
|
"87f633634cc4b02f628685651f0a29b7bfa22a0bd841f725c6772dd00a58d489"
|
|
252
241
|
]
|
|
253
242
|
});
|
|
254
|
-
var ExternalIdSchema = UuidSchema.meta({
|
|
255
|
-
title: "External ID",
|
|
256
|
-
description: "UUID identifier for external system references"
|
|
257
|
-
});
|
|
258
243
|
var ExternalUrlSchema = zod.z.url().meta({
|
|
259
244
|
title: "External URL",
|
|
260
245
|
description: "URL pointing to external resources",
|
|
246
|
+
examples: ["https://explore.carrot.eco/", "https://whitepaper.carrot.eco/"]
|
|
247
|
+
});
|
|
248
|
+
var ipfsUriPattern = /^ipfs:\/\/(?:Qm[1-9A-HJ-NP-Za-km-z]{44}|[bB][a-z2-7]{58,}|[zZ][1-9A-HJ-NP-Za-km-z]{48,})(?:\/[^\s]*)?$/;
|
|
249
|
+
var IpfsUriSchema = NonEmptyStringSchema.regex(
|
|
250
|
+
ipfsUriPattern,
|
|
251
|
+
"Must be a valid IPFS URI with CID"
|
|
252
|
+
).meta({
|
|
253
|
+
title: "IPFS URI",
|
|
254
|
+
description: "InterPlanetary File System URI pointing to distributed content",
|
|
261
255
|
examples: [
|
|
262
|
-
"
|
|
263
|
-
"
|
|
256
|
+
"ipfs://bafybeigdyrztvzl5cceubvaxob7iqh6f3f7s36c74ojav2xsz2uib2g3vm/mass-id-organic.png",
|
|
257
|
+
"ipfs://bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"
|
|
264
258
|
]
|
|
265
259
|
});
|
|
260
|
+
|
|
261
|
+
// src/shared/schemas/primitives/version.schema.ts
|
|
262
|
+
var SemanticVersionSchema = NonEmptyStringSchema.regex(
|
|
263
|
+
/^v?\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/,
|
|
264
|
+
"Must be a valid semantic version string"
|
|
265
|
+
).meta({
|
|
266
|
+
title: "Semantic Version",
|
|
267
|
+
description: "Version string following semantic versioning specification",
|
|
268
|
+
examples: ["0.1.0", "1.0.0", "2.1.3"]
|
|
269
|
+
});
|
|
266
270
|
var RecordSchemaTypeSchema = zod.z.enum([
|
|
267
271
|
"MassID",
|
|
268
272
|
"MassID Audit",
|
|
@@ -278,308 +282,26 @@ var RecordSchemaTypeSchema = zod.z.enum([
|
|
|
278
282
|
description: "Type of schema in the Carrot ecosystem",
|
|
279
283
|
examples: ["MassID", "RecycledID", "GasID"]
|
|
280
284
|
});
|
|
281
|
-
var TokenSymbolSchema = NonEmptyStringSchema.max(10).regex(
|
|
282
|
-
/^[A-Z0-9-]+$/,
|
|
283
|
-
"Must contain only uppercase letters, numbers, and hyphens"
|
|
284
|
-
).meta({
|
|
285
|
-
title: "Token Symbol",
|
|
286
|
-
description: "Symbol representing a token or cryptocurrency",
|
|
287
|
-
examples: ["MASS", "REC", "GAS"]
|
|
288
|
-
});
|
|
289
|
-
var CreditTokenSymbolSchema = TokenSymbolSchema.meta({
|
|
290
|
-
title: "Credit Token Symbol",
|
|
291
|
-
description: "Symbol of the credit token (e.g., C-CARB, C-BIOW)",
|
|
292
|
-
examples: ["C-CARB", "C-BIOW"]
|
|
293
|
-
});
|
|
294
|
-
function uniqueArrayItems(schema, errorMessage = "Array items must be unique") {
|
|
295
|
-
return zod.z.array(schema).refine((items) => new Set(items).size === items.length, {
|
|
296
|
-
message: errorMessage
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
function uniqueBy(schema, selector, errorMessage = "Items must be unique") {
|
|
300
|
-
return zod.z.array(schema).refine(
|
|
301
|
-
(items) => {
|
|
302
|
-
const values = items.map(selector);
|
|
303
|
-
return new Set(values).size === values.length;
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
message: errorMessage
|
|
307
|
-
}
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// src/shared/entities/participant.schema.ts
|
|
312
|
-
var ParticipantSchema = zod.z.strictObject({
|
|
313
|
-
id_hash: Sha256HashSchema.meta({
|
|
314
|
-
title: "Participant ID Hash",
|
|
315
|
-
description: "Anonymized identifier for the participant"
|
|
316
|
-
}),
|
|
317
|
-
name: ParticipantNameSchema.meta({
|
|
318
|
-
title: "Participant Name",
|
|
319
|
-
description: "Name of the participant"
|
|
320
|
-
}),
|
|
321
|
-
roles: uniqueArrayItems(
|
|
322
|
-
ParticipantRoleSchema,
|
|
323
|
-
"Participant roles must be unique"
|
|
324
|
-
).min(1).meta({
|
|
325
|
-
title: "Participant Roles",
|
|
326
|
-
description: "Roles of the participant in the waste management supply chain"
|
|
327
|
-
})
|
|
328
|
-
}).meta({
|
|
329
|
-
title: "Participant",
|
|
330
|
-
description: "A participant in the waste management supply chain"
|
|
331
|
-
});
|
|
332
|
-
var PrecisionLevelSchema = zod.z.enum(["city", "region", "country"]).meta({
|
|
333
|
-
title: "Coordinate Precision Level",
|
|
334
|
-
description: "Level of coordinate precision",
|
|
335
|
-
examples: ["city"]
|
|
336
|
-
});
|
|
337
|
-
var CoordinatesSchema = zod.z.strictObject({
|
|
338
|
-
latitude: LatitudeSchema,
|
|
339
|
-
longitude: LongitudeSchema,
|
|
340
|
-
precision_level: PrecisionLevelSchema
|
|
341
|
-
}).meta({
|
|
342
|
-
title: "Coordinates",
|
|
343
|
-
description: "GPS coordinates of the location"
|
|
344
|
-
});
|
|
345
|
-
var LocationSchema = zod.z.strictObject({
|
|
346
|
-
id_hash: Sha256HashSchema.meta({
|
|
347
|
-
title: "Location ID Hash",
|
|
348
|
-
description: "Anonymized identifier for the location"
|
|
349
|
-
}),
|
|
350
|
-
municipality: MunicipalitySchema,
|
|
351
|
-
administrative_division: AdministrativeDivisionSchema,
|
|
352
|
-
administrative_division_code: IsoAdministrativeDivisionCodeSchema.optional(),
|
|
353
|
-
country: CountryNameSchema,
|
|
354
|
-
country_code: IsoCountryCodeSchema,
|
|
355
|
-
responsible_participant_id_hash: Sha256HashSchema.meta({
|
|
356
|
-
title: "Responsible Participant ID Hash",
|
|
357
|
-
description: "Anonymized ID of the participant responsible for this location"
|
|
358
|
-
}),
|
|
359
|
-
coordinates: CoordinatesSchema
|
|
360
|
-
}).meta({
|
|
361
|
-
title: "Location",
|
|
362
|
-
description: "Geographic location with address and coordinate information"
|
|
363
|
-
});
|
|
364
|
-
var MethodologyComplianceSchema = zod.z.enum(["PASSED", "FAILED"]).meta({
|
|
365
|
-
title: "Methodology Compliance",
|
|
366
|
-
description: "Result of methodology compliance check",
|
|
367
|
-
examples: ["PASSED", "FAILED"]
|
|
368
|
-
});
|
|
369
|
-
var AuditReferenceSchema = zod.z.strictObject({
|
|
370
|
-
date: IsoDateSchema.meta({
|
|
371
|
-
title: "Audit Date",
|
|
372
|
-
description: "Date when the audit was completed"
|
|
373
|
-
}),
|
|
374
|
-
external_id: ExternalIdSchema.meta({
|
|
375
|
-
title: "Audit External ID",
|
|
376
|
-
description: "Unique identifier for the audit"
|
|
377
|
-
}),
|
|
378
|
-
external_url: ExternalUrlSchema.meta({
|
|
379
|
-
title: "Audit External URL",
|
|
380
|
-
description: "URL to view the audit on Carrot Explorer"
|
|
381
|
-
}),
|
|
382
|
-
methodology_compliance: MethodologyComplianceSchema.meta({
|
|
383
|
-
title: "Methodology Compliance",
|
|
384
|
-
description: "Result of methodology compliance check"
|
|
385
|
-
}),
|
|
386
|
-
rules_executed: NonNegativeIntegerSchema.meta({
|
|
387
|
-
title: "Rules Executed",
|
|
388
|
-
description: "Number of rules executed during the audit"
|
|
389
|
-
}),
|
|
390
|
-
report: IpfsUriSchema.meta({
|
|
391
|
-
title: "Audit Report",
|
|
392
|
-
description: "IPFS URI of the audit report"
|
|
393
|
-
})
|
|
394
|
-
}).meta({
|
|
395
|
-
title: "Audit Reference",
|
|
396
|
-
description: "Reference to an audit record"
|
|
397
|
-
});
|
|
398
|
-
var GasIDReferenceSchema = zod.z.strictObject({
|
|
399
|
-
external_id: ExternalIdSchema.meta({
|
|
400
|
-
title: "GasID External ID",
|
|
401
|
-
description: "Unique identifier for the GasID"
|
|
402
|
-
}),
|
|
403
|
-
token_id: TokenIdSchema.meta({
|
|
404
|
-
title: "GasID Token ID",
|
|
405
|
-
description: "NFT token ID of the GasID"
|
|
406
|
-
}),
|
|
407
|
-
external_url: ExternalUrlSchema.meta({
|
|
408
|
-
title: "GasID External URL",
|
|
409
|
-
description: "URL to view the GasID on Carrot Explorer"
|
|
410
|
-
}),
|
|
411
|
-
uri: IpfsUriSchema.meta({
|
|
412
|
-
title: "GasID IPFS URI",
|
|
413
|
-
description: "IPFS URI of the GasID record"
|
|
414
|
-
})
|
|
415
|
-
}).meta({
|
|
416
|
-
title: "GasID Reference",
|
|
417
|
-
description: "Reference to a GasID record"
|
|
418
|
-
});
|
|
419
|
-
var MassIDReferenceSchema = zod.z.strictObject({
|
|
420
|
-
external_id: ExternalIdSchema.meta({
|
|
421
|
-
title: "MassID External ID",
|
|
422
|
-
description: "Unique identifier for the MassID"
|
|
423
|
-
}),
|
|
424
|
-
token_id: TokenIdSchema.meta({
|
|
425
|
-
title: "MassID Token ID",
|
|
426
|
-
description: "NFT token ID of the MassID"
|
|
427
|
-
}),
|
|
428
|
-
external_url: ExternalUrlSchema.meta({
|
|
429
|
-
title: "MassID External URL",
|
|
430
|
-
description: "URL to view the MassID on Carrot Explorer"
|
|
431
|
-
}),
|
|
432
|
-
uri: IpfsUriSchema.meta({
|
|
433
|
-
title: "MassID IPFS URI",
|
|
434
|
-
description: "IPFS URI of the MassID record"
|
|
435
|
-
})
|
|
436
|
-
}).meta({
|
|
437
|
-
title: "MassID Reference",
|
|
438
|
-
description: "Reference to a MassID record"
|
|
439
|
-
});
|
|
440
|
-
var MethodologyReferenceSchema = zod.z.strictObject({
|
|
441
|
-
external_id: ExternalIdSchema.meta({
|
|
442
|
-
title: "Methodology External ID",
|
|
443
|
-
description: "Unique identifier for the methodology"
|
|
444
|
-
}),
|
|
445
|
-
name: NonEmptyStringSchema.min(5).max(150).meta({
|
|
446
|
-
title: "Methodology Name",
|
|
447
|
-
description: "Human-readable name of the methodology",
|
|
448
|
-
examples: ["BOLD Carbon (CH\u2084)", "BOLD Recycling"]
|
|
449
|
-
}),
|
|
450
|
-
version: SemanticVersionSchema.meta({
|
|
451
|
-
title: "Methodology Version",
|
|
452
|
-
description: "Version of the methodology"
|
|
453
|
-
}),
|
|
454
|
-
external_url: ExternalUrlSchema.meta({
|
|
455
|
-
title: "Methodology External URL",
|
|
456
|
-
description: "URL to view the methodology on Carrot Explorer"
|
|
457
|
-
}),
|
|
458
|
-
uri: IpfsUriSchema.optional().meta({
|
|
459
|
-
title: "Methodology IPFS URI",
|
|
460
|
-
description: "IPFS URI to the methodology record"
|
|
461
|
-
})
|
|
462
|
-
}).meta({
|
|
463
|
-
title: "Methodology Reference",
|
|
464
|
-
description: "Reference to a methodology record"
|
|
465
|
-
});
|
|
466
|
-
var WasteClassificationSchema = zod.z.strictObject({
|
|
467
|
-
primary_type: WasteTypeSchema.meta({
|
|
468
|
-
title: "Source Waste Primary Type",
|
|
469
|
-
description: "Primary type of the source waste"
|
|
470
|
-
}),
|
|
471
|
-
subtype: WasteSubtypeSchema.meta({
|
|
472
|
-
title: "Source Waste Subtype",
|
|
473
|
-
description: "Subtype of the source waste"
|
|
474
|
-
}),
|
|
475
|
-
net_weight_kg: WeightKgSchema.meta({
|
|
476
|
-
title: "Source Waste Net Weight",
|
|
477
|
-
description: "Net weight of the source waste"
|
|
478
|
-
})
|
|
479
|
-
}).meta({
|
|
480
|
-
title: "Waste Classification",
|
|
481
|
-
description: "Classification of the source waste (MassID)"
|
|
482
|
-
});
|
|
483
|
-
var AccreditedParticipantSchema = zod.z.strictObject({
|
|
484
|
-
participant_id: UuidSchema.meta({
|
|
485
|
-
title: "Participant ID",
|
|
486
|
-
description: "Unique identifier for the participant"
|
|
487
|
-
}),
|
|
488
|
-
name: ParticipantNameSchema.meta({
|
|
489
|
-
title: "Participant Name",
|
|
490
|
-
description: "Name of the participant"
|
|
491
|
-
}),
|
|
492
|
-
role: ParticipantRoleSchema.meta({
|
|
493
|
-
title: "Participant Role",
|
|
494
|
-
description: "Role of the participant in the supply chain"
|
|
495
|
-
}),
|
|
496
|
-
accreditation_id: UuidSchema.meta({
|
|
497
|
-
title: "Accreditation ID",
|
|
498
|
-
description: "Unique identifier for the participant accreditation"
|
|
499
|
-
}),
|
|
500
|
-
external_url: ExternalUrlSchema.meta({
|
|
501
|
-
title: "Participant Accreditation External URL",
|
|
502
|
-
description: "URL to view the participant accreditation on Carrot Explorer"
|
|
503
|
-
})
|
|
504
|
-
}).meta({
|
|
505
|
-
title: "Accredited Participant",
|
|
506
|
-
description: "Participant with valid accreditation in the supply chain"
|
|
507
|
-
});
|
|
508
|
-
var AccreditedParticipantsSchema = zod.z.array(AccreditedParticipantSchema).min(1).meta({
|
|
509
|
-
title: "Accredited Participants",
|
|
510
|
-
description: "List of participants with valid accreditations"
|
|
511
|
-
});
|
|
512
|
-
var RewardAllocationSchema = zod.z.strictObject({
|
|
513
|
-
participant_id: UuidSchema.meta({
|
|
514
|
-
title: "Participant ID",
|
|
515
|
-
description: "Unique identifier for the participant receiving the reward"
|
|
516
|
-
}),
|
|
517
|
-
participant_name: ParticipantNameSchema.meta({
|
|
518
|
-
title: "Participant Name",
|
|
519
|
-
description: "Name of the participant receiving the reward"
|
|
520
|
-
}),
|
|
521
|
-
role: ParticipantRoleSchema.meta({
|
|
522
|
-
title: "Participant Role",
|
|
523
|
-
description: "Role of the participant in the supply chain"
|
|
524
|
-
}),
|
|
525
|
-
reward_percentage: PercentageSchema.meta({
|
|
526
|
-
title: "Reward Percentage",
|
|
527
|
-
description: "Reward percentage allocated to the participant"
|
|
528
|
-
}),
|
|
529
|
-
large_business_discount_applied: zod.z.boolean().optional().meta({
|
|
530
|
-
title: "Large Business Discount Applied",
|
|
531
|
-
description: "Whether the large business discount was applied"
|
|
532
|
-
}),
|
|
533
|
-
effective_percentage: PercentageSchema.meta({
|
|
534
|
-
title: "Effective Percentage",
|
|
535
|
-
description: "Effective percentage of the reward after discounts"
|
|
536
|
-
})
|
|
537
|
-
}).meta({
|
|
538
|
-
title: "Reward Allocation",
|
|
539
|
-
description: "Reward allocation for a specific participant"
|
|
540
|
-
});
|
|
541
|
-
var DistributionNotesSchema = zod.z.strictObject({
|
|
542
|
-
large_business_discount_applied: NonEmptyStringSchema.optional().meta({
|
|
543
|
-
title: "Large Business Discount Applied",
|
|
544
|
-
description: "Description of the large business discount applied",
|
|
545
|
-
examples: [
|
|
546
|
-
"50% reduction applied to participants with >$4M annual revenue"
|
|
547
|
-
]
|
|
548
|
-
}),
|
|
549
|
-
redirected_rewards: NonEmptyStringSchema.optional().meta({
|
|
550
|
-
title: "Redirected Rewards",
|
|
551
|
-
description: "Description of the redirected rewards",
|
|
552
|
-
examples: [
|
|
553
|
-
"Discounted rewards from large businesses redirected to accredited NGOs"
|
|
554
|
-
]
|
|
555
|
-
})
|
|
556
|
-
}).meta({
|
|
557
|
-
title: "Distribution Notes",
|
|
558
|
-
description: "Additional notes about the reward distribution"
|
|
559
|
-
});
|
|
560
|
-
var ParticipantRewardsSchema = zod.z.strictObject({
|
|
561
|
-
distribution_basis: NonEmptyStringSchema.max(200).meta({
|
|
562
|
-
title: "Distribution Basis",
|
|
563
|
-
description: "Basis for the rewards distribution"
|
|
564
|
-
}),
|
|
565
|
-
reward_allocations: zod.z.array(RewardAllocationSchema).min(1).meta({
|
|
566
|
-
title: "Reward Allocations",
|
|
567
|
-
description: "Rewards percentage allocated to each participant"
|
|
568
|
-
}),
|
|
569
|
-
distribution_notes: DistributionNotesSchema.optional().meta({
|
|
570
|
-
title: "Distribution Notes",
|
|
571
|
-
description: "Additional notes about the reward distribution"
|
|
572
|
-
})
|
|
573
|
-
}).meta({
|
|
574
|
-
title: "Participant Rewards",
|
|
575
|
-
description: "Rewards distribution to participants"
|
|
285
|
+
var TokenSymbolSchema = NonEmptyStringSchema.max(10).regex(
|
|
286
|
+
/^[A-Z0-9-]+$/,
|
|
287
|
+
"Must contain only uppercase letters, numbers, and hyphens"
|
|
288
|
+
).meta({
|
|
289
|
+
title: "Token Symbol",
|
|
290
|
+
description: "Symbol representing a token or cryptocurrency",
|
|
291
|
+
examples: ["MASS", "REC", "GAS"]
|
|
576
292
|
});
|
|
577
|
-
var
|
|
578
|
-
title: "
|
|
579
|
-
description: "
|
|
293
|
+
var CreditTokenSymbolSchema = TokenSymbolSchema.meta({
|
|
294
|
+
title: "Credit Token Symbol",
|
|
295
|
+
description: "Symbol of the credit token (e.g., C-CARB, C-BIOW)",
|
|
296
|
+
examples: ["C-CARB", "C-BIOW"]
|
|
580
297
|
});
|
|
298
|
+
|
|
299
|
+
// src/shared/schemas/core/base.schema.ts
|
|
581
300
|
var SchemaInfoSchema = zod.z.strictObject({
|
|
582
|
-
hash:
|
|
301
|
+
hash: Sha256HashSchema.meta({
|
|
302
|
+
title: "Schema Hash",
|
|
303
|
+
description: "SHA-256 hash of the JSON Schema this record was validated against"
|
|
304
|
+
}),
|
|
583
305
|
type: RecordSchemaTypeSchema,
|
|
584
306
|
version: SemanticVersionSchema.meta({
|
|
585
307
|
title: "Schema Version",
|
|
@@ -636,11 +358,24 @@ var BaseIpfsSchema = zod.z.strictObject({
|
|
|
636
358
|
title: "Base IPFS Record",
|
|
637
359
|
description: "Base fields for all Carrot IPFS records, providing common structure for any JSON content stored in IPFS"
|
|
638
360
|
});
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
};
|
|
643
|
-
|
|
361
|
+
function uniqueArrayItems(schema, errorMessage = "Array items must be unique") {
|
|
362
|
+
return zod.z.array(schema).refine((items) => new Set(items).size === items.length, {
|
|
363
|
+
message: errorMessage
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
function uniqueBy(schema, selector, errorMessage = "Items must be unique") {
|
|
367
|
+
return zod.z.array(schema).refine(
|
|
368
|
+
(items) => {
|
|
369
|
+
const values = items.map(selector);
|
|
370
|
+
return new Set(values).size === values.length;
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
message: errorMessage
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// src/shared/schemas/core/nft.schema.ts
|
|
644
379
|
var NftSchemaTypeSchema = RecordSchemaTypeSchema.extract([
|
|
645
380
|
"MassID",
|
|
646
381
|
"RecycledID",
|
|
@@ -652,16 +387,10 @@ var NftSchemaTypeSchema = RecordSchemaTypeSchema.extract([
|
|
|
652
387
|
description: "Type of schema for NFT records"
|
|
653
388
|
});
|
|
654
389
|
var BlockchainReferenceSchema = zod.z.strictObject({
|
|
655
|
-
smart_contract_address:
|
|
656
|
-
|
|
657
|
-
}),
|
|
658
|
-
chain_id: BlockchainChainIdSchema.meta({
|
|
659
|
-
title: "Chain ID",
|
|
660
|
-
description: "Blockchain chain ID"
|
|
661
|
-
}),
|
|
390
|
+
smart_contract_address: SmartContractAddressSchema,
|
|
391
|
+
chain_id: BlockchainChainIdSchema,
|
|
662
392
|
network_name: BlockchainNetworkNameSchema,
|
|
663
393
|
token_id: TokenIdSchema.meta({
|
|
664
|
-
title: "Token ID",
|
|
665
394
|
description: "NFT token ID"
|
|
666
395
|
})
|
|
667
396
|
}).superRefine((value, ctx) => {
|
|
@@ -685,11 +414,11 @@ var BlockchainReferenceSchema = zod.z.strictObject({
|
|
|
685
414
|
description: "Blockchain-specific information for the NFT"
|
|
686
415
|
});
|
|
687
416
|
var ExternalLinkSchema = zod.z.strictObject({
|
|
688
|
-
label:
|
|
417
|
+
label: NonEmptyStringSchema.max(50).meta({
|
|
689
418
|
title: "Link Label",
|
|
690
419
|
description: "Display name for the external link"
|
|
691
420
|
}),
|
|
692
|
-
url:
|
|
421
|
+
url: ExternalUrlSchema.meta({
|
|
693
422
|
title: "Link URL",
|
|
694
423
|
description: "Direct URI to the linked resource"
|
|
695
424
|
}),
|
|
@@ -702,7 +431,7 @@ var ExternalLinkSchema = zod.z.strictObject({
|
|
|
702
431
|
description: "External link with label and description"
|
|
703
432
|
});
|
|
704
433
|
var NftAttributeSchema = zod.z.strictObject({
|
|
705
|
-
trait_type:
|
|
434
|
+
trait_type: NonEmptyStringSchema.max(50).meta({
|
|
706
435
|
title: "Trait Type",
|
|
707
436
|
description: "Name of the trait or attribute"
|
|
708
437
|
}),
|
|
@@ -730,7 +459,7 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
|
|
|
730
459
|
})
|
|
731
460
|
}),
|
|
732
461
|
blockchain: BlockchainReferenceSchema,
|
|
733
|
-
name:
|
|
462
|
+
name: NonEmptyStringSchema.max(100).meta({
|
|
734
463
|
title: "NFT Name",
|
|
735
464
|
description: "Full display name for this NFT, including extra context",
|
|
736
465
|
examples: [
|
|
@@ -739,12 +468,12 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
|
|
|
739
468
|
"GasID #789 \u2022 Methane \u2022 1000 m\xB3"
|
|
740
469
|
]
|
|
741
470
|
}),
|
|
742
|
-
short_name:
|
|
471
|
+
short_name: NonEmptyStringSchema.max(50).meta({
|
|
743
472
|
title: "Short Name",
|
|
744
473
|
description: "Compact name for UI summaries, tables, or tooltips",
|
|
745
474
|
examples: ["MassID #123", "RecycledID #456", "GasID #789"]
|
|
746
475
|
}),
|
|
747
|
-
description:
|
|
476
|
+
description: NonEmptyStringSchema.max(500).meta({
|
|
748
477
|
title: "Description",
|
|
749
478
|
description: "Human-readable summary of the NFT's role and context. Ideally, maximum 300 characters.",
|
|
750
479
|
examples: [
|
|
@@ -764,31 +493,17 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
|
|
|
764
493
|
title: "Animation URL",
|
|
765
494
|
description: "IPFS URI pointing to an animated or interactive media file",
|
|
766
495
|
examples: [
|
|
767
|
-
"ipfs://
|
|
768
|
-
"ipfs://
|
|
496
|
+
"ipfs://bafybeigdyrztvzl5cceubvaxob7iqh6f3f7s36c74ojav2xsz2uib2g3vm/mass-id-animation.mp4",
|
|
497
|
+
"ipfs://bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku/recycled-visualization.webm"
|
|
769
498
|
]
|
|
770
499
|
}),
|
|
771
500
|
external_links: uniqueBy(
|
|
772
501
|
ExternalLinkSchema,
|
|
773
502
|
(link) => link.url,
|
|
774
503
|
"External link URLs must be unique"
|
|
775
|
-
).
|
|
504
|
+
).optional().meta({
|
|
776
505
|
title: "External Links",
|
|
777
|
-
description: "Optional list of public resource links with labels"
|
|
778
|
-
examples: [
|
|
779
|
-
[
|
|
780
|
-
{
|
|
781
|
-
label: "Carrot Explorer",
|
|
782
|
-
url: "https://explore.carrot.eco/document/ad44dd3f-f176-4b98-bf78-5ee6e77d0530",
|
|
783
|
-
description: "Complete chain of custody and audit trail"
|
|
784
|
-
},
|
|
785
|
-
{
|
|
786
|
-
label: "Carrot White Paper",
|
|
787
|
-
url: "https://carrot.eco/whitepaper.pdf",
|
|
788
|
-
description: "Carrot Foundation technical and impact white paper"
|
|
789
|
-
}
|
|
790
|
-
]
|
|
791
|
-
]
|
|
506
|
+
description: "Optional list of public resource links with labels"
|
|
792
507
|
}),
|
|
793
508
|
attributes: uniqueBy(
|
|
794
509
|
NftAttributeSchema,
|
|
@@ -796,33 +511,7 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
|
|
|
796
511
|
"Attribute trait_type values must be unique"
|
|
797
512
|
).meta({
|
|
798
513
|
title: "NFT Attributes",
|
|
799
|
-
description: "List of visual traits and filterable attributes compatible with NFT marketplaces"
|
|
800
|
-
examples: [
|
|
801
|
-
[
|
|
802
|
-
{
|
|
803
|
-
trait_type: "Waste Type",
|
|
804
|
-
value: "Organic"
|
|
805
|
-
},
|
|
806
|
-
{
|
|
807
|
-
trait_type: "Waste Subtype",
|
|
808
|
-
value: "Food, Food Waste and Beverages"
|
|
809
|
-
},
|
|
810
|
-
{
|
|
811
|
-
trait_type: "Weight (kg)",
|
|
812
|
-
value: 3e3,
|
|
813
|
-
display_type: "number"
|
|
814
|
-
},
|
|
815
|
-
{
|
|
816
|
-
trait_type: "Origin Country",
|
|
817
|
-
value: "Brazil"
|
|
818
|
-
},
|
|
819
|
-
{
|
|
820
|
-
trait_type: "Pick-up Date",
|
|
821
|
-
value: "2024-12-05",
|
|
822
|
-
display_type: "date"
|
|
823
|
-
}
|
|
824
|
-
]
|
|
825
|
-
]
|
|
514
|
+
description: "List of visual traits and filterable attributes compatible with NFT marketplaces"
|
|
826
515
|
})
|
|
827
516
|
}).superRefine((value, ctx) => {
|
|
828
517
|
const environmentNetwork = value.environment?.blockchain_network;
|
|
@@ -848,16 +537,6 @@ var NftIpfsSchema = BaseIpfsSchema.safeExtend({
|
|
|
848
537
|
title: "NFT IPFS Record",
|
|
849
538
|
description: "NFT-specific fields for Carrot IPFS records"
|
|
850
539
|
});
|
|
851
|
-
function getSchemaBaseUrl() {
|
|
852
|
-
return `https://raw.githubusercontent.com/carrot-foundation/schemas/refs/tags/${getSchemaVersionOrDefault()}/schemas/ipfs`;
|
|
853
|
-
}
|
|
854
|
-
function buildSchemaUrl(schemaPath) {
|
|
855
|
-
const cleanPath = schemaPath.startsWith("/") ? schemaPath.slice(1) : schemaPath;
|
|
856
|
-
return `${getSchemaBaseUrl()}/${cleanPath}`;
|
|
857
|
-
}
|
|
858
|
-
function getSchemaVersionOrDefault() {
|
|
859
|
-
return "0.1.41";
|
|
860
|
-
}
|
|
861
540
|
var MethodologyAttributeSchema = NftAttributeSchema.safeExtend({
|
|
862
541
|
trait_type: zod.z.literal("Methodology"),
|
|
863
542
|
value: MethodologyNameSchema
|
|
@@ -920,117 +599,377 @@ var RecyclerAttributeSchema = NftAttributeSchema.safeExtend({
|
|
|
920
599
|
example: "Eco Reciclagem"
|
|
921
600
|
})
|
|
922
601
|
}).meta({
|
|
923
|
-
title: "Recycler Attribute",
|
|
924
|
-
description: "Recycler attribute"
|
|
602
|
+
title: "Recycler Attribute",
|
|
603
|
+
description: "Recycler attribute"
|
|
604
|
+
});
|
|
605
|
+
var MassIDTokenIdAttributeSchema = NftAttributeSchema.safeExtend({
|
|
606
|
+
trait_type: zod.z.literal("MassID"),
|
|
607
|
+
value: StringifiedTokenIdSchema.meta({
|
|
608
|
+
title: "MassID Token ID",
|
|
609
|
+
description: "Token ID of the source MassID NFT as #<token_id>"
|
|
610
|
+
})
|
|
611
|
+
}).meta({
|
|
612
|
+
title: "MassID Token ID Attribute",
|
|
613
|
+
description: "MassID token ID attribute"
|
|
614
|
+
});
|
|
615
|
+
var MassIDRecyclingDateAttributeSchema = NftAttributeSchema.omit({
|
|
616
|
+
max_value: true
|
|
617
|
+
}).safeExtend({
|
|
618
|
+
trait_type: zod.z.literal("MassID Recycling Date"),
|
|
619
|
+
value: UnixTimestampSchema.meta({
|
|
620
|
+
title: "MassID Recycling Date",
|
|
621
|
+
description: "Unix timestamp in milliseconds when the source waste was recycled"
|
|
622
|
+
}),
|
|
623
|
+
display_type: zod.z.literal("date")
|
|
624
|
+
}).meta({
|
|
625
|
+
title: "MassID Recycling Date Attribute",
|
|
626
|
+
description: "MassID recycling date attribute using Unix timestamp in milliseconds"
|
|
627
|
+
});
|
|
628
|
+
var MethodologyComplianceSchema = zod.z.enum(["PASSED", "FAILED"]).meta({
|
|
629
|
+
title: "Methodology Compliance",
|
|
630
|
+
description: "Result of methodology compliance check",
|
|
631
|
+
examples: ["PASSED", "FAILED"]
|
|
632
|
+
});
|
|
633
|
+
var AuditReferenceSchema = zod.z.strictObject({
|
|
634
|
+
date: IsoDateSchema.meta({
|
|
635
|
+
title: "Audit Date",
|
|
636
|
+
description: "Date when the audit was completed"
|
|
637
|
+
}),
|
|
638
|
+
external_id: ExternalIdSchema.meta({
|
|
639
|
+
title: "Audit External ID",
|
|
640
|
+
description: "Unique identifier for the audit"
|
|
641
|
+
}),
|
|
642
|
+
external_url: ExternalUrlSchema.meta({
|
|
643
|
+
title: "Audit External URL",
|
|
644
|
+
description: "URL to view the audit on Carrot Explorer"
|
|
645
|
+
}),
|
|
646
|
+
methodology_compliance: MethodologyComplianceSchema.meta({
|
|
647
|
+
title: "Methodology Compliance",
|
|
648
|
+
description: "Result of methodology compliance check"
|
|
649
|
+
}),
|
|
650
|
+
rules_executed: NonNegativeIntegerSchema.meta({
|
|
651
|
+
title: "Rules Executed",
|
|
652
|
+
description: "Number of rules executed during the audit"
|
|
653
|
+
}),
|
|
654
|
+
report: IpfsUriSchema.meta({
|
|
655
|
+
title: "Audit Report",
|
|
656
|
+
description: "IPFS URI of the audit report"
|
|
657
|
+
})
|
|
658
|
+
}).meta({
|
|
659
|
+
title: "Audit Reference",
|
|
660
|
+
description: "Reference to an audit record"
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
// src/shared/schemas/audit.schema.ts
|
|
664
|
+
var AuditRuleDefinitionSchema = zod.z.strictObject({
|
|
665
|
+
rule_id: UuidSchema.meta({
|
|
666
|
+
title: "Rule ID",
|
|
667
|
+
description: "Unique identifier for the audit rule"
|
|
668
|
+
}),
|
|
669
|
+
rule_slug: SlugSchema.meta({
|
|
670
|
+
title: "Rule Slug",
|
|
671
|
+
description: "URL-friendly identifier for the rule"
|
|
672
|
+
}),
|
|
673
|
+
rule_name: NonEmptyStringSchema.max(100).meta({
|
|
674
|
+
title: "Rule Name",
|
|
675
|
+
description: "Human-readable name of the rule",
|
|
676
|
+
examples: ["Waste Mass is Unique", "No Conflicting GasID or Credit"]
|
|
677
|
+
}),
|
|
678
|
+
description: zod.z.string().min(10).max(500).meta({
|
|
679
|
+
title: "Rule Description",
|
|
680
|
+
description: "Detailed description of what the rule validates and why it is necessary",
|
|
681
|
+
examples: [
|
|
682
|
+
"Validates that each MassID is unique within the system to prevent duplicate entries"
|
|
683
|
+
]
|
|
684
|
+
}),
|
|
685
|
+
source_code_url: zod.z.url().regex(/^https:\/\/github\.com\/.*$/, "Must be a GitHub URL").meta({
|
|
686
|
+
title: "Rule Source Code URL",
|
|
687
|
+
description: "GitHub URL pointing to the implementation source code for this rule",
|
|
688
|
+
examples: [
|
|
689
|
+
"https://github.com/carrot-foundation/methodologies/blob/main/bold-carbon/rules/waste-mass-unique.js"
|
|
690
|
+
]
|
|
691
|
+
}),
|
|
692
|
+
execution_order: PositiveIntegerSchema.meta({
|
|
693
|
+
title: "Rule Execution Order",
|
|
694
|
+
description: "Sequential order in which this rule must be executed"
|
|
695
|
+
})
|
|
696
|
+
}).meta({
|
|
697
|
+
title: "Audit Rule Definition",
|
|
698
|
+
description: "Definition of an audit rule that must be executed for methodology compliance"
|
|
699
|
+
});
|
|
700
|
+
var AuditRuleDefinitionsSchema = zod.z.array(AuditRuleDefinitionSchema).min(1).meta({
|
|
701
|
+
title: "Audit Rule Definitions",
|
|
702
|
+
description: "List of audit rules that must be executed to check methodology compliance"
|
|
703
|
+
});
|
|
704
|
+
var AuditRuleExecutionResultSchema = zod.z.strictObject({
|
|
705
|
+
rule_name: NonEmptyStringSchema.meta({
|
|
706
|
+
title: "Rule Name",
|
|
707
|
+
description: "Human-readable name of the audit rule"
|
|
708
|
+
}),
|
|
709
|
+
rule_id: UuidSchema.meta({
|
|
710
|
+
title: "Rule ID",
|
|
711
|
+
description: "Unique identifier for the rule"
|
|
712
|
+
}),
|
|
713
|
+
rule_slug: SlugSchema.meta({
|
|
714
|
+
title: "Rule Slug",
|
|
715
|
+
description: "URL-friendly identifier for the rule"
|
|
716
|
+
}),
|
|
717
|
+
execution_order: PositiveIntegerSchema.meta({
|
|
718
|
+
title: "Rule Execution Order",
|
|
719
|
+
description: "Sequential order in which this rule was executed"
|
|
720
|
+
}),
|
|
721
|
+
result: MethodologyComplianceSchema.meta({
|
|
722
|
+
title: "Rule Execution Result",
|
|
723
|
+
description: "Result of the rule execution"
|
|
724
|
+
}),
|
|
725
|
+
description: zod.z.string().min(1).max(2e3).meta({
|
|
726
|
+
title: "Rule Description",
|
|
727
|
+
description: "Detailed description of what this rule validates"
|
|
728
|
+
}),
|
|
729
|
+
rule_processor_checksum: NonEmptyStringSchema.max(200).meta({
|
|
730
|
+
title: "Rule Processor Checksum",
|
|
731
|
+
description: "Checksum for rule processor integrity verification"
|
|
732
|
+
}),
|
|
733
|
+
rule_source_code_version: NonEmptyStringSchema.max(200).meta({
|
|
734
|
+
title: "Rule Source Code Version",
|
|
735
|
+
description: "Version identifier for the rule source code"
|
|
736
|
+
})
|
|
737
|
+
}).meta({
|
|
738
|
+
title: "Audit Rule Execution Result",
|
|
739
|
+
description: "Detailed result of an audit rule execution"
|
|
740
|
+
});
|
|
741
|
+
var AuditRuleExecutionResultsSchema = zod.z.array(AuditRuleExecutionResultSchema).meta({
|
|
742
|
+
title: "Audit Rule Execution Results",
|
|
743
|
+
description: "Detailed results of each audit rule execution"
|
|
744
|
+
});
|
|
745
|
+
var ParticipantSchema = zod.z.strictObject({
|
|
746
|
+
id_hash: Sha256HashSchema.meta({
|
|
747
|
+
title: "Participant ID Hash",
|
|
748
|
+
description: "Anonymized identifier for the participant"
|
|
749
|
+
}),
|
|
750
|
+
name: ParticipantNameSchema,
|
|
751
|
+
roles: uniqueArrayItems(
|
|
752
|
+
ParticipantRoleSchema,
|
|
753
|
+
"Participant roles must be unique"
|
|
754
|
+
).min(1).meta({
|
|
755
|
+
title: "Participant Roles",
|
|
756
|
+
description: "Roles of the participant in the waste management supply chain"
|
|
757
|
+
})
|
|
758
|
+
}).meta({
|
|
759
|
+
title: "Participant",
|
|
760
|
+
description: "A participant in the waste management supply chain"
|
|
761
|
+
});
|
|
762
|
+
var PrecisionLevelSchema = zod.z.enum(["city", "region", "country"]).meta({
|
|
763
|
+
title: "Coordinate Precision Level",
|
|
764
|
+
description: "Level of coordinate precision",
|
|
765
|
+
examples: ["city"]
|
|
766
|
+
});
|
|
767
|
+
var CoordinatesSchema = zod.z.strictObject({
|
|
768
|
+
latitude: LatitudeSchema,
|
|
769
|
+
longitude: LongitudeSchema,
|
|
770
|
+
precision_level: PrecisionLevelSchema
|
|
771
|
+
}).meta({
|
|
772
|
+
title: "Coordinates",
|
|
773
|
+
description: "GPS coordinates of the location"
|
|
774
|
+
});
|
|
775
|
+
var LocationSchema = zod.z.strictObject({
|
|
776
|
+
id_hash: Sha256HashSchema.meta({
|
|
777
|
+
title: "Location ID Hash",
|
|
778
|
+
description: "Anonymized identifier for the location"
|
|
779
|
+
}),
|
|
780
|
+
municipality: MunicipalitySchema,
|
|
781
|
+
administrative_division: AdministrativeDivisionSchema,
|
|
782
|
+
administrative_division_code: IsoAdministrativeDivisionCodeSchema.optional(),
|
|
783
|
+
country: CountryNameSchema,
|
|
784
|
+
country_code: IsoCountryCodeSchema,
|
|
785
|
+
responsible_participant_id_hash: Sha256HashSchema.meta({
|
|
786
|
+
title: "Responsible Participant ID Hash",
|
|
787
|
+
description: "Anonymized ID of the participant responsible for this location"
|
|
788
|
+
}),
|
|
789
|
+
coordinates: CoordinatesSchema
|
|
790
|
+
}).meta({
|
|
791
|
+
title: "Location",
|
|
792
|
+
description: "Geographic location with address and coordinate information"
|
|
793
|
+
});
|
|
794
|
+
var GasIDReferenceSchema = zod.z.strictObject({
|
|
795
|
+
external_id: ExternalIdSchema.meta({
|
|
796
|
+
title: "GasID External ID",
|
|
797
|
+
description: "Unique identifier for the GasID"
|
|
798
|
+
}),
|
|
799
|
+
token_id: TokenIdSchema.meta({
|
|
800
|
+
title: "GasID Token ID",
|
|
801
|
+
description: "NFT token ID of the GasID"
|
|
802
|
+
}),
|
|
803
|
+
external_url: ExternalUrlSchema.meta({
|
|
804
|
+
title: "GasID External URL",
|
|
805
|
+
description: "URL to view the GasID on Carrot Explorer"
|
|
806
|
+
}),
|
|
807
|
+
uri: IpfsUriSchema.meta({
|
|
808
|
+
title: "GasID IPFS URI",
|
|
809
|
+
description: "IPFS URI of the GasID record"
|
|
810
|
+
})
|
|
811
|
+
}).meta({
|
|
812
|
+
title: "GasID Reference",
|
|
813
|
+
description: "Reference to a GasID record"
|
|
925
814
|
});
|
|
926
|
-
var
|
|
927
|
-
|
|
928
|
-
|
|
815
|
+
var MassIDReferenceSchema = zod.z.strictObject({
|
|
816
|
+
external_id: ExternalIdSchema.meta({
|
|
817
|
+
title: "MassID External ID",
|
|
818
|
+
description: "Unique identifier for the MassID"
|
|
819
|
+
}),
|
|
820
|
+
token_id: TokenIdSchema.meta({
|
|
929
821
|
title: "MassID Token ID",
|
|
930
|
-
description: "
|
|
822
|
+
description: "NFT token ID of the MassID"
|
|
823
|
+
}),
|
|
824
|
+
external_url: ExternalUrlSchema.meta({
|
|
825
|
+
title: "MassID External URL",
|
|
826
|
+
description: "URL to view the MassID on Carrot Explorer"
|
|
827
|
+
}),
|
|
828
|
+
uri: IpfsUriSchema.meta({
|
|
829
|
+
title: "MassID IPFS URI",
|
|
830
|
+
description: "IPFS URI of the MassID record"
|
|
931
831
|
})
|
|
932
832
|
}).meta({
|
|
933
|
-
title: "MassID
|
|
934
|
-
description: "
|
|
833
|
+
title: "MassID Reference",
|
|
834
|
+
description: "Reference to a MassID record"
|
|
935
835
|
});
|
|
936
|
-
var
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
value: UnixTimestampSchema.meta({
|
|
941
|
-
title: "MassID Recycling Date",
|
|
942
|
-
description: "Unix timestamp in milliseconds when the source waste was recycled"
|
|
836
|
+
var MethodologyReferenceSchema = zod.z.strictObject({
|
|
837
|
+
external_id: ExternalIdSchema.meta({
|
|
838
|
+
title: "Methodology External ID",
|
|
839
|
+
description: "Unique identifier for the methodology"
|
|
943
840
|
}),
|
|
944
|
-
|
|
841
|
+
name: NonEmptyStringSchema.min(5).max(150).meta({
|
|
842
|
+
title: "Methodology Name",
|
|
843
|
+
description: "Human-readable name of the methodology",
|
|
844
|
+
examples: ["BOLD Carbon (CH\u2084)", "BOLD Recycling"]
|
|
845
|
+
}),
|
|
846
|
+
version: SemanticVersionSchema.meta({
|
|
847
|
+
title: "Methodology Version",
|
|
848
|
+
description: "Version of the methodology"
|
|
849
|
+
}),
|
|
850
|
+
external_url: ExternalUrlSchema.meta({
|
|
851
|
+
title: "Methodology External URL",
|
|
852
|
+
description: "URL to view the methodology on Carrot Explorer"
|
|
853
|
+
}),
|
|
854
|
+
uri: IpfsUriSchema.optional().meta({
|
|
855
|
+
title: "Methodology IPFS URI",
|
|
856
|
+
description: "IPFS URI to the methodology record"
|
|
857
|
+
})
|
|
945
858
|
}).meta({
|
|
946
|
-
title: "
|
|
947
|
-
description: "
|
|
859
|
+
title: "Methodology Reference",
|
|
860
|
+
description: "Reference to a methodology record"
|
|
948
861
|
});
|
|
949
|
-
var
|
|
950
|
-
|
|
951
|
-
title: "
|
|
952
|
-
description: "
|
|
862
|
+
var WasteClassificationSchema = zod.z.strictObject({
|
|
863
|
+
primary_type: WasteTypeSchema.meta({
|
|
864
|
+
title: "Source Waste Primary Type",
|
|
865
|
+
description: "Primary type of the source waste"
|
|
953
866
|
}),
|
|
954
|
-
|
|
955
|
-
title: "
|
|
956
|
-
description: "
|
|
867
|
+
subtype: WasteSubtypeSchema.meta({
|
|
868
|
+
title: "Source Waste Subtype",
|
|
869
|
+
description: "Subtype of the source waste"
|
|
957
870
|
}),
|
|
958
|
-
|
|
959
|
-
title: "
|
|
960
|
-
description: "
|
|
961
|
-
|
|
871
|
+
net_weight_kg: WeightKgSchema.meta({
|
|
872
|
+
title: "Source Waste Net Weight",
|
|
873
|
+
description: "Net weight of the source waste"
|
|
874
|
+
})
|
|
875
|
+
}).meta({
|
|
876
|
+
title: "Waste Classification",
|
|
877
|
+
description: "Classification of the source waste (MassID)"
|
|
878
|
+
});
|
|
879
|
+
var AccreditedParticipantSchema = zod.z.strictObject({
|
|
880
|
+
participant_id: UuidSchema.meta({
|
|
881
|
+
title: "Participant ID",
|
|
882
|
+
description: "Unique identifier for the participant"
|
|
962
883
|
}),
|
|
963
|
-
|
|
964
|
-
title: "
|
|
965
|
-
description: "
|
|
966
|
-
examples: [
|
|
967
|
-
"Validates that each MassID is unique within the system to prevent duplicate entries"
|
|
968
|
-
]
|
|
884
|
+
name: ParticipantNameSchema.meta({
|
|
885
|
+
title: "Participant Name",
|
|
886
|
+
description: "Name of the participant"
|
|
969
887
|
}),
|
|
970
|
-
|
|
971
|
-
title: "
|
|
972
|
-
description: "
|
|
973
|
-
examples: [
|
|
974
|
-
"https://github.com/carrot-foundation/methodologies/blob/main/bold-carbon/rules/waste-mass-unique.js"
|
|
975
|
-
]
|
|
888
|
+
role: ParticipantRoleSchema.meta({
|
|
889
|
+
title: "Participant Role",
|
|
890
|
+
description: "Role of the participant in the supply chain"
|
|
976
891
|
}),
|
|
977
|
-
|
|
978
|
-
title: "
|
|
979
|
-
description: "
|
|
892
|
+
accreditation_id: UuidSchema.meta({
|
|
893
|
+
title: "Accreditation ID",
|
|
894
|
+
description: "Unique identifier for the participant accreditation"
|
|
895
|
+
}),
|
|
896
|
+
external_url: ExternalUrlSchema.meta({
|
|
897
|
+
title: "Participant Accreditation External URL",
|
|
898
|
+
description: "URL to view the participant accreditation on Carrot Explorer"
|
|
980
899
|
})
|
|
981
900
|
}).meta({
|
|
982
|
-
title: "
|
|
983
|
-
description: "
|
|
901
|
+
title: "Accredited Participant",
|
|
902
|
+
description: "Participant with valid accreditation in the supply chain"
|
|
984
903
|
});
|
|
985
|
-
var
|
|
986
|
-
title: "
|
|
987
|
-
description: "List of
|
|
904
|
+
var AccreditedParticipantsSchema = zod.z.array(AccreditedParticipantSchema).min(1).meta({
|
|
905
|
+
title: "Accredited Participants",
|
|
906
|
+
description: "List of participants with valid accreditations"
|
|
988
907
|
});
|
|
989
|
-
var
|
|
990
|
-
|
|
991
|
-
title: "
|
|
992
|
-
description: "
|
|
993
|
-
}),
|
|
994
|
-
rule_id: UuidSchema.meta({
|
|
995
|
-
title: "Rule ID",
|
|
996
|
-
description: "Unique identifier for the rule"
|
|
908
|
+
var RewardAllocationSchema = zod.z.strictObject({
|
|
909
|
+
participant_id: UuidSchema.meta({
|
|
910
|
+
title: "Participant ID",
|
|
911
|
+
description: "Unique identifier for the participant receiving the reward"
|
|
997
912
|
}),
|
|
998
|
-
|
|
999
|
-
title: "
|
|
1000
|
-
description: "
|
|
913
|
+
participant_name: ParticipantNameSchema.meta({
|
|
914
|
+
title: "Participant Name",
|
|
915
|
+
description: "Name of the participant receiving the reward"
|
|
1001
916
|
}),
|
|
1002
|
-
|
|
1003
|
-
title: "
|
|
1004
|
-
description: "
|
|
917
|
+
role: ParticipantRoleSchema.meta({
|
|
918
|
+
title: "Participant Role",
|
|
919
|
+
description: "Role of the participant in the supply chain"
|
|
1005
920
|
}),
|
|
1006
|
-
|
|
1007
|
-
title: "
|
|
1008
|
-
description: "
|
|
921
|
+
reward_percentage: PercentageSchema.meta({
|
|
922
|
+
title: "Reward Percentage",
|
|
923
|
+
description: "Reward percentage allocated to the participant"
|
|
1009
924
|
}),
|
|
1010
|
-
|
|
1011
|
-
title: "
|
|
1012
|
-
description: "
|
|
925
|
+
large_business_discount_applied: zod.z.boolean().optional().meta({
|
|
926
|
+
title: "Large Business Discount Applied",
|
|
927
|
+
description: "Whether the large business discount was applied"
|
|
1013
928
|
}),
|
|
1014
|
-
|
|
1015
|
-
title: "
|
|
1016
|
-
description: "
|
|
929
|
+
effective_percentage: PercentageSchema.meta({
|
|
930
|
+
title: "Effective Percentage",
|
|
931
|
+
description: "Effective percentage of the reward after discounts"
|
|
932
|
+
})
|
|
933
|
+
}).meta({
|
|
934
|
+
title: "Reward Allocation",
|
|
935
|
+
description: "Reward allocation for a specific participant"
|
|
936
|
+
});
|
|
937
|
+
var DistributionNotesSchema = zod.z.strictObject({
|
|
938
|
+
large_business_discount_applied: NonEmptyStringSchema.optional().meta({
|
|
939
|
+
title: "Large Business Discount Applied",
|
|
940
|
+
description: "Description of the large business discount applied",
|
|
941
|
+
examples: [
|
|
942
|
+
"50% reduction applied to participants with >$4M annual revenue"
|
|
943
|
+
]
|
|
1017
944
|
}),
|
|
1018
|
-
|
|
1019
|
-
title: "
|
|
1020
|
-
description: "
|
|
945
|
+
redirected_rewards: NonEmptyStringSchema.optional().meta({
|
|
946
|
+
title: "Redirected Rewards",
|
|
947
|
+
description: "Description of the redirected rewards",
|
|
948
|
+
examples: [
|
|
949
|
+
"Discounted rewards from large businesses redirected to accredited NGOs"
|
|
950
|
+
]
|
|
1021
951
|
})
|
|
1022
952
|
}).meta({
|
|
1023
|
-
title: "
|
|
1024
|
-
description: "
|
|
953
|
+
title: "Distribution Notes",
|
|
954
|
+
description: "Additional notes about the reward distribution"
|
|
1025
955
|
});
|
|
1026
|
-
var
|
|
1027
|
-
|
|
1028
|
-
|
|
956
|
+
var ParticipantRewardsSchema = zod.z.strictObject({
|
|
957
|
+
distribution_basis: NonEmptyStringSchema.max(200).meta({
|
|
958
|
+
title: "Distribution Basis",
|
|
959
|
+
description: "Basis for the rewards distribution"
|
|
960
|
+
}),
|
|
961
|
+
reward_allocations: zod.z.array(RewardAllocationSchema).min(1).meta({
|
|
962
|
+
title: "Reward Allocations",
|
|
963
|
+
description: "Rewards percentage allocated to each participant"
|
|
964
|
+
}),
|
|
965
|
+
distribution_notes: DistributionNotesSchema.optional().meta({
|
|
966
|
+
title: "Distribution Notes",
|
|
967
|
+
description: "Additional notes about the reward distribution"
|
|
968
|
+
})
|
|
969
|
+
}).meta({
|
|
970
|
+
title: "Participant Rewards",
|
|
971
|
+
description: "Rewards distribution to participants"
|
|
1029
972
|
});
|
|
1030
|
-
var EPSILON = 1e-9;
|
|
1031
|
-
function nearlyEqual(a, b, epsilon = EPSILON) {
|
|
1032
|
-
return Math.abs(a - b) <= epsilon;
|
|
1033
|
-
}
|
|
1034
973
|
var SummaryBaseSchema = zod.z.strictObject({
|
|
1035
974
|
total_certificates: PositiveIntegerSchema.meta({
|
|
1036
975
|
title: "Total Certificates",
|
|
@@ -1202,8 +1141,22 @@ function createReceiptCertificateSchema(params) {
|
|
|
1202
1141
|
...params.additionalShape
|
|
1203
1142
|
}).meta(params.meta);
|
|
1204
1143
|
}
|
|
1144
|
+
function getSchemaBaseUrl() {
|
|
1145
|
+
return `https://raw.githubusercontent.com/carrot-foundation/schemas/refs/tags/${getSchemaVersionOrDefault()}/schemas/ipfs`;
|
|
1146
|
+
}
|
|
1147
|
+
function buildSchemaUrl(schemaPath) {
|
|
1148
|
+
const cleanPath = schemaPath.startsWith("/") ? schemaPath.slice(1) : schemaPath;
|
|
1149
|
+
return `${getSchemaBaseUrl()}/${cleanPath}`;
|
|
1150
|
+
}
|
|
1151
|
+
function getSchemaVersionOrDefault() {
|
|
1152
|
+
return "0.1.43";
|
|
1153
|
+
}
|
|
1205
1154
|
|
|
1206
|
-
// src/shared/
|
|
1155
|
+
// src/shared/schema-validation.ts
|
|
1156
|
+
var EPSILON = 1e-9;
|
|
1157
|
+
function nearlyEqual(a, b, epsilon = EPSILON) {
|
|
1158
|
+
return Math.abs(a - b) <= epsilon;
|
|
1159
|
+
}
|
|
1207
1160
|
function buildMessage(message, value) {
|
|
1208
1161
|
return typeof message === "function" ? message(value) : message;
|
|
1209
1162
|
}
|
|
@@ -1352,6 +1305,20 @@ function validateAttributesForItems(params) {
|
|
|
1352
1305
|
}
|
|
1353
1306
|
});
|
|
1354
1307
|
}
|
|
1308
|
+
function canonicalizeForHash(value) {
|
|
1309
|
+
const canonical = canonicalize__default.default(value);
|
|
1310
|
+
if (canonical === void 0) {
|
|
1311
|
+
throw new TypeError("Value is not serializable to canonical JSON");
|
|
1312
|
+
}
|
|
1313
|
+
return canonical;
|
|
1314
|
+
}
|
|
1315
|
+
function hashCanonicalJson(canonicalJson) {
|
|
1316
|
+
return crypto.createHash("sha256").update(canonicalJson, "utf8").digest("hex");
|
|
1317
|
+
}
|
|
1318
|
+
function hashObject(value) {
|
|
1319
|
+
const canonical = canonicalizeForHash(value);
|
|
1320
|
+
return hashCanonicalJson(canonical);
|
|
1321
|
+
}
|
|
1355
1322
|
var IbamaWasteClassificationSchema = zod.z.string().regex(/^\d{2} \d{2} \d{2}\*?$/, "Invalid Ibama code format").meta({
|
|
1356
1323
|
title: "Ibama Classification Code",
|
|
1357
1324
|
description: "Ibama waste classification code in the format NN NN NN with required spaces and optional trailing *",
|
|
@@ -2122,8 +2089,17 @@ var GasIDIpfsSchema = NftIpfsSchema.safeExtend({
|
|
|
2122
2089
|
description: "GasID NFT schema type"
|
|
2123
2090
|
})
|
|
2124
2091
|
}),
|
|
2125
|
-
attributes: GasIDAttributesSchema,
|
|
2126
2092
|
data: GasIDDataSchema
|
|
2093
|
+
}).superRefine((value, ctx) => {
|
|
2094
|
+
const attributesResult = GasIDAttributesSchema.safeParse(value.attributes);
|
|
2095
|
+
if (!attributesResult.success) {
|
|
2096
|
+
attributesResult.error.issues.forEach((issue) => {
|
|
2097
|
+
ctx.addIssue({
|
|
2098
|
+
...issue,
|
|
2099
|
+
path: ["attributes", ...issue.path]
|
|
2100
|
+
});
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2127
2103
|
}).meta(GasIDIpfsSchemaMeta);
|
|
2128
2104
|
var RecycledIDAttributeMethodologySchema = MethodologyAttributeSchema;
|
|
2129
2105
|
var RecycledIDAttributeRecycledMassWeightSchema = NftAttributeSchema.safeExtend({
|
|
@@ -2202,8 +2178,19 @@ var RecycledIDIpfsSchema = NftIpfsSchema.safeExtend({
|
|
|
2202
2178
|
description: "RecycledID NFT schema type"
|
|
2203
2179
|
})
|
|
2204
2180
|
}),
|
|
2205
|
-
attributes: RecycledIDAttributesSchema,
|
|
2206
2181
|
data: RecycledIDDataSchema
|
|
2182
|
+
}).superRefine((value, ctx) => {
|
|
2183
|
+
const attributesResult = RecycledIDAttributesSchema.safeParse(
|
|
2184
|
+
value.attributes
|
|
2185
|
+
);
|
|
2186
|
+
if (!attributesResult.success) {
|
|
2187
|
+
attributesResult.error.issues.forEach((issue) => {
|
|
2188
|
+
ctx.addIssue({
|
|
2189
|
+
...issue,
|
|
2190
|
+
path: ["attributes", ...issue.path]
|
|
2191
|
+
});
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2207
2194
|
}).meta(RecycledIDIpfsSchemaMeta);
|
|
2208
2195
|
var CreditPurchaseReceiptCreditAttributeSchema = NftAttributeSchema.safeExtend({
|
|
2209
2196
|
trait_type: TokenSymbolSchema.meta({
|
|
@@ -3294,7 +3281,9 @@ var CollectionSchema = BaseIpfsSchema.safeExtend({
|
|
|
3294
3281
|
image: IpfsUriSchema.meta({
|
|
3295
3282
|
title: "Collection Image",
|
|
3296
3283
|
description: "IPFS URI pointing to the collection's visual representation",
|
|
3297
|
-
examples: [
|
|
3284
|
+
examples: [
|
|
3285
|
+
"ipfs://bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku/collection-icon.png"
|
|
3286
|
+
]
|
|
3298
3287
|
}),
|
|
3299
3288
|
description: zod.z.string().min(50).max(1e3).meta({
|
|
3300
3289
|
title: "Collection Description",
|
|
@@ -3336,7 +3325,9 @@ var CreditSchema = BaseIpfsSchema.safeExtend({
|
|
|
3336
3325
|
image: IpfsUriSchema.meta({
|
|
3337
3326
|
title: "Token Image",
|
|
3338
3327
|
description: "IPFS URI pointing to the token's visual representation image",
|
|
3339
|
-
examples: [
|
|
3328
|
+
examples: [
|
|
3329
|
+
"ipfs://bafybeigdyrztvzl5cceubvaxob7iqh6f3f7s36c74ojav2xsz2uib2g3vm/credit-icon.png"
|
|
3330
|
+
]
|
|
3340
3331
|
}),
|
|
3341
3332
|
description: zod.z.string().min(50).max(1e3).meta({
|
|
3342
3333
|
title: "Token Description",
|
|
@@ -3459,6 +3450,7 @@ var MassIDAuditSchema = BaseIpfsSchema.safeExtend({
|
|
|
3459
3450
|
data: MassIDAuditDataSchema
|
|
3460
3451
|
}).meta(MassIDAuditSchemaMeta);
|
|
3461
3452
|
|
|
3453
|
+
exports.ALLOWED_BLOCKCHAIN_NETWORKS = ALLOWED_BLOCKCHAIN_NETWORKS;
|
|
3462
3454
|
exports.AccreditedParticipantSchema = AccreditedParticipantSchema;
|
|
3463
3455
|
exports.AccreditedParticipantsSchema = AccreditedParticipantsSchema;
|
|
3464
3456
|
exports.AdministrativeDivisionSchema = AdministrativeDivisionSchema;
|
|
@@ -3467,6 +3459,7 @@ exports.AuditRuleDefinitionSchema = AuditRuleDefinitionSchema;
|
|
|
3467
3459
|
exports.AuditRuleDefinitionsSchema = AuditRuleDefinitionsSchema;
|
|
3468
3460
|
exports.AuditRuleExecutionResultSchema = AuditRuleExecutionResultSchema;
|
|
3469
3461
|
exports.AuditRuleExecutionResultsSchema = AuditRuleExecutionResultsSchema;
|
|
3462
|
+
exports.BLOCKCHAIN_NETWORK_CONFIG = BLOCKCHAIN_NETWORK_CONFIG;
|
|
3470
3463
|
exports.BaseIpfsSchema = BaseIpfsSchema;
|
|
3471
3464
|
exports.BlockchainChainIdSchema = BlockchainChainIdSchema;
|
|
3472
3465
|
exports.BlockchainNetworkNameSchema = BlockchainNetworkNameSchema;
|
|
@@ -3504,7 +3497,6 @@ exports.GasIDIpfsSchema = GasIDIpfsSchema;
|
|
|
3504
3497
|
exports.GasIDIpfsSchemaMeta = GasIDIpfsSchemaMeta;
|
|
3505
3498
|
exports.GasIDReferenceSchema = GasIDReferenceSchema;
|
|
3506
3499
|
exports.HexColorSchema = HexColorSchema;
|
|
3507
|
-
exports.HoursSchema = HoursSchema;
|
|
3508
3500
|
exports.IbamaWasteClassificationSchema = IbamaWasteClassificationSchema;
|
|
3509
3501
|
exports.IpfsUriSchema = IpfsUriSchema;
|
|
3510
3502
|
exports.IsoAdministrativeDivisionCodeSchema = IsoAdministrativeDivisionCodeSchema;
|
|
@@ -3532,7 +3524,6 @@ exports.MethodologyNameSchema = MethodologyNameSchema;
|
|
|
3532
3524
|
exports.MethodologyReferenceSchema = MethodologyReferenceSchema;
|
|
3533
3525
|
exports.MethodologySchema = MethodologySchema;
|
|
3534
3526
|
exports.MethodologySchemaMeta = MethodologySchemaMeta;
|
|
3535
|
-
exports.MinutesSchema = MinutesSchema;
|
|
3536
3527
|
exports.MunicipalitySchema = MunicipalitySchema;
|
|
3537
3528
|
exports.NftAttributeSchema = NftAttributeSchema;
|
|
3538
3529
|
exports.NftIpfsSchema = NftIpfsSchema;
|
|
@@ -3573,12 +3564,15 @@ exports.WasteSubtypeSchema = WasteSubtypeSchema;
|
|
|
3573
3564
|
exports.WasteTypeSchema = WasteTypeSchema;
|
|
3574
3565
|
exports.WeightKgSchema = WeightKgSchema;
|
|
3575
3566
|
exports.buildSchemaUrl = buildSchemaUrl;
|
|
3567
|
+
exports.canonicalizeForHash = canonicalizeForHash;
|
|
3576
3568
|
exports.createAttributeMap = createAttributeMap;
|
|
3577
3569
|
exports.createReceiptCertificateSchema = createReceiptCertificateSchema;
|
|
3578
3570
|
exports.createReceiptCollectionSchema = createReceiptCollectionSchema;
|
|
3579
3571
|
exports.createReceiptCreditSchema = createReceiptCreditSchema;
|
|
3580
3572
|
exports.getSchemaBaseUrl = getSchemaBaseUrl;
|
|
3581
3573
|
exports.getSchemaVersionOrDefault = getSchemaVersionOrDefault;
|
|
3574
|
+
exports.hashCanonicalJson = hashCanonicalJson;
|
|
3575
|
+
exports.hashObject = hashObject;
|
|
3582
3576
|
exports.nearlyEqual = nearlyEqual;
|
|
3583
3577
|
exports.uniqueArrayItems = uniqueArrayItems;
|
|
3584
3578
|
exports.uniqueBy = uniqueBy;
|