@carrot-foundation/schemas 0.1.37 → 0.1.38

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 CHANGED
@@ -292,6 +292,7 @@ var RecordSchemaTypeSchema = zod.z.enum([
292
292
  "RecycledID",
293
293
  "GasID",
294
294
  "CreditPurchaseReceipt",
295
+ "CreditRetirementReceipt",
295
296
  "Methodology",
296
297
  "Credit",
297
298
  "Collection"
@@ -308,6 +309,11 @@ var TokenSymbolSchema = NonEmptyStringSchema.max(10).regex(
308
309
  description: "Symbol representing a token or cryptocurrency",
309
310
  examples: ["MASS", "REC", "GAS"]
310
311
  });
312
+ var CreditTokenSymbolSchema = TokenSymbolSchema.meta({
313
+ title: "Credit Token Symbol",
314
+ description: "Symbol of the credit token (e.g., C-CARB, C-BIOW)",
315
+ examples: ["C-CARB", "C-BIOW"]
316
+ });
311
317
  var RecordRelationshipTypeSchema = zod.z.enum([
312
318
  "collection",
313
319
  "credit",
@@ -316,6 +322,7 @@ var RecordRelationshipTypeSchema = zod.z.enum([
316
322
  "mass-id-audit",
317
323
  "methodology",
318
324
  "credit-purchase-receipt",
325
+ "credit-retirement-receipt",
319
326
  "recycled-id"
320
327
  ]).meta({
321
328
  title: "Relationship Type",
@@ -733,7 +740,8 @@ var NftSchemaTypeSchema = RecordSchemaTypeSchema.extract([
733
740
  "MassID",
734
741
  "RecycledID",
735
742
  "GasID",
736
- "CreditPurchaseReceipt"
743
+ "CreditPurchaseReceipt",
744
+ "CreditRetirementReceipt"
737
745
  ]).meta({
738
746
  title: "NFT Schema Type",
739
747
  description: "Type of schema for NFT records"
@@ -910,7 +918,7 @@ function buildSchemaUrl(schemaPath) {
910
918
  return `${getSchemaBaseUrl()}/${cleanPath}`;
911
919
  }
912
920
  function getSchemaVersionOrDefault() {
913
- return "0.1.37";
921
+ return "0.1.38";
914
922
  }
915
923
  var MethodologyAttributeSchema = NftAttributeSchema.safeExtend({
916
924
  trait_type: zod.z.literal("Methodology"),
@@ -1085,6 +1093,331 @@ var AuditRuleExecutionResultsSchema = zod.z.array(AuditRuleExecutionResultSchema
1085
1093
  title: "Audit Rule Execution Results",
1086
1094
  description: "Detailed results of each audit rule execution"
1087
1095
  });
1096
+ var EPSILON = 1e-9;
1097
+ function nearlyEqual(a, b, epsilon = EPSILON) {
1098
+ return Math.abs(a - b) <= epsilon;
1099
+ }
1100
+ var SummaryBaseSchema = zod.z.strictObject({
1101
+ total_certificates: PositiveIntegerSchema.meta({
1102
+ title: "Total Certificates",
1103
+ description: "Total number of certificates represented in the receipt"
1104
+ }),
1105
+ credit_symbols: uniqueArrayItems(
1106
+ CreditTokenSymbolSchema,
1107
+ "Credit symbols must be unique"
1108
+ ).min(1).meta({
1109
+ title: "Credit Symbols",
1110
+ description: "Array of credit token symbols represented in the receipt"
1111
+ }),
1112
+ certificate_types: uniqueArrayItems(
1113
+ RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]),
1114
+ "Certificate types must be unique"
1115
+ ).min(1).meta({
1116
+ title: "Certificate Types",
1117
+ description: "Array of certificate types represented in the receipt"
1118
+ }),
1119
+ collection_slugs: uniqueArrayItems(
1120
+ CollectionSlugSchema,
1121
+ "Collection slugs must be unique"
1122
+ ).min(1).meta({
1123
+ title: "Collection Slugs",
1124
+ description: "Array of collection slugs represented in the receipt"
1125
+ })
1126
+ });
1127
+ var CreditPurchaseReceiptSummarySchema = SummaryBaseSchema.extend({
1128
+ total_usdc_amount: NonNegativeFloatSchema.meta({
1129
+ title: "Total USDC Amount",
1130
+ description: "Total amount paid in USDC for the purchase"
1131
+ }),
1132
+ total_credits: CreditAmountSchema.meta({
1133
+ title: "Total Credits",
1134
+ description: "Total amount of credits purchased"
1135
+ }),
1136
+ purchase_date: IsoDateSchema.meta({
1137
+ title: "Purchase Date",
1138
+ description: "Date when the purchase was made (YYYY-MM-DD)"
1139
+ })
1140
+ }).meta({
1141
+ title: "Credit Purchase Receipt Summary",
1142
+ description: "Summary totals for the credit purchase including amounts and collections represented"
1143
+ });
1144
+ var CreditRetirementReceiptSummarySchema = SummaryBaseSchema.extend({
1145
+ total_retirement_amount: CreditAmountSchema.meta({
1146
+ title: "Total Retirement Amount",
1147
+ description: "Total amount of credits retired"
1148
+ }),
1149
+ retirement_date: IsoDateSchema.meta({
1150
+ title: "Retirement Date",
1151
+ description: "Date when the retirement occurred (YYYY-MM-DD)"
1152
+ })
1153
+ }).meta({
1154
+ title: "Credit Retirement Receipt Summary",
1155
+ description: "Summary totals for the credit retirement including amounts and collections represented"
1156
+ });
1157
+ var ReceiptIdentitySchema = zod.z.strictObject({
1158
+ name: ParticipantNameSchema.meta({
1159
+ title: "Identity Name",
1160
+ description: "Display name for the participant",
1161
+ examples: ["EcoTech Solutions Inc.", "Climate Action Corp"]
1162
+ }),
1163
+ external_id: ExternalIdSchema.meta({
1164
+ title: "Identity External ID",
1165
+ description: "External identifier for the participant"
1166
+ }),
1167
+ external_url: ExternalUrlSchema.meta({
1168
+ title: "Identity External URL",
1169
+ description: "External URL for the participant profile"
1170
+ })
1171
+ }).meta({
1172
+ title: "Identity",
1173
+ description: "Participant identity information"
1174
+ });
1175
+ var MassIdReferenceWithContractSchema = MassIDReferenceSchema.safeExtend({
1176
+ smart_contract: SmartContractSchema
1177
+ }).meta({
1178
+ title: "MassID Reference with Smart Contract",
1179
+ description: "Reference to a MassID record including smart contract details"
1180
+ });
1181
+ function createReceiptCollectionSchema(params) {
1182
+ const { amountKey, amountMeta, meta } = params;
1183
+ return zod.z.strictObject({
1184
+ slug: CollectionSlugSchema,
1185
+ external_id: ExternalIdSchema.meta({
1186
+ title: "Collection External ID",
1187
+ description: "External identifier for the collection"
1188
+ }),
1189
+ name: CollectionNameSchema,
1190
+ external_url: ExternalUrlSchema.meta({
1191
+ title: "Collection External URL",
1192
+ description: "External URL for the collection"
1193
+ }),
1194
+ uri: IpfsUriSchema.meta({
1195
+ title: "Collection URI",
1196
+ description: "IPFS URI for the collection metadata"
1197
+ }),
1198
+ [amountKey]: CreditAmountSchema.meta(amountMeta)
1199
+ }).meta(meta);
1200
+ }
1201
+ function createReceiptCreditSchema(params) {
1202
+ const { amountKey, amountMeta, meta, retirementAmountMeta } = params;
1203
+ const creditShape = {
1204
+ slug: SlugSchema.meta({
1205
+ title: "Credit Slug",
1206
+ description: "URL-friendly identifier for the credit"
1207
+ }),
1208
+ symbol: CreditTokenSymbolSchema.meta({
1209
+ title: "Credit Token Symbol",
1210
+ description: "Symbol of the credit token",
1211
+ examples: ["CARBON", "ORGANIC", "C-CARB", "C-BIOW"]
1212
+ }),
1213
+ external_id: ExternalIdSchema.meta({
1214
+ title: "Credit External ID",
1215
+ description: "External identifier for the credit"
1216
+ }),
1217
+ external_url: ExternalUrlSchema.meta({
1218
+ title: "Credit External URL",
1219
+ description: "External URL for the credit"
1220
+ }),
1221
+ uri: IpfsUriSchema.meta({
1222
+ title: "Credit URI",
1223
+ description: "IPFS URI for the credit details"
1224
+ }),
1225
+ smart_contract: SmartContractSchema,
1226
+ [amountKey]: CreditAmountSchema.meta(amountMeta)
1227
+ };
1228
+ if (retirementAmountMeta) {
1229
+ creditShape.retirement_amount = CreditAmountSchema.optional().meta(retirementAmountMeta);
1230
+ }
1231
+ return zod.z.strictObject(creditShape).meta(meta);
1232
+ }
1233
+ var certificateBaseShape = {
1234
+ token_id: TokenIdSchema.meta({
1235
+ title: "Certificate Token ID",
1236
+ description: "Token ID of the certificate"
1237
+ }),
1238
+ type: RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]).meta({
1239
+ title: "Certificate Type",
1240
+ description: "Type of certificate (e.g., GasID, RecycledID)"
1241
+ }),
1242
+ external_id: ExternalIdSchema.meta({
1243
+ title: "Certificate External ID",
1244
+ description: "External identifier for the certificate"
1245
+ }),
1246
+ external_url: ExternalUrlSchema.meta({
1247
+ title: "Certificate External URL",
1248
+ description: "External URL for the certificate"
1249
+ }),
1250
+ uri: IpfsUriSchema.meta({
1251
+ title: "Certificate URI",
1252
+ description: "IPFS URI for the certificate metadata"
1253
+ }),
1254
+ smart_contract: SmartContractSchema,
1255
+ collection_slug: CollectionSlugSchema.meta({
1256
+ title: "Collection Slug",
1257
+ description: "Slug of the collection this certificate belongs to"
1258
+ }),
1259
+ total_amount: CreditAmountSchema.meta({
1260
+ title: "Certificate Total Amount",
1261
+ description: "Total credits available in this certificate"
1262
+ }),
1263
+ mass_id: MassIdReferenceWithContractSchema
1264
+ };
1265
+ function createReceiptCertificateSchema(params) {
1266
+ return zod.z.strictObject({
1267
+ ...certificateBaseShape,
1268
+ ...params.additionalShape
1269
+ }).meta(params.meta);
1270
+ }
1271
+
1272
+ // src/shared/receipt/receipt.validation.ts
1273
+ function buildMessage(message, value) {
1274
+ return typeof message === "function" ? message(value) : message;
1275
+ }
1276
+ function createAttributeMap(attributes) {
1277
+ return new Map(
1278
+ attributes.map((attribute) => [attribute.trait_type, attribute])
1279
+ );
1280
+ }
1281
+ function validateSummaryListMatchesData(params) {
1282
+ const { ctx, summaryValues, dataValues, summaryPath } = params;
1283
+ const summarySet = new Set(summaryValues);
1284
+ const dataSet = new Set(dataValues);
1285
+ summarySet.forEach((value) => {
1286
+ if (!dataSet.has(value)) {
1287
+ ctx.addIssue({
1288
+ code: "custom",
1289
+ message: buildMessage(params.missingFromDataMessage, value),
1290
+ path: summaryPath
1291
+ });
1292
+ }
1293
+ });
1294
+ dataSet.forEach((value) => {
1295
+ if (!summarySet.has(value)) {
1296
+ ctx.addIssue({
1297
+ code: "custom",
1298
+ message: buildMessage(params.missingFromSummaryMessage, value),
1299
+ path: summaryPath
1300
+ });
1301
+ }
1302
+ });
1303
+ }
1304
+ function validateTotalMatches(params) {
1305
+ const { ctx, actualTotal, expectedTotal, path, message } = params;
1306
+ if (!nearlyEqual(actualTotal, expectedTotal)) {
1307
+ ctx.addIssue({
1308
+ code: "custom",
1309
+ message,
1310
+ path
1311
+ });
1312
+ }
1313
+ }
1314
+ function validateCountMatches(params) {
1315
+ const { ctx, actualCount, expectedCount, path, message } = params;
1316
+ if (actualCount !== expectedCount) {
1317
+ ctx.addIssue({
1318
+ code: "custom",
1319
+ message,
1320
+ path
1321
+ });
1322
+ }
1323
+ }
1324
+ function validateAttributeValue(params) {
1325
+ const {
1326
+ ctx,
1327
+ attributeByTraitType,
1328
+ traitType,
1329
+ expectedValue,
1330
+ missingMessage,
1331
+ mismatchMessage,
1332
+ path = ["attributes"]
1333
+ } = params;
1334
+ const attribute = attributeByTraitType.get(traitType);
1335
+ if (!attribute) {
1336
+ ctx.addIssue({
1337
+ code: "custom",
1338
+ message: missingMessage,
1339
+ path
1340
+ });
1341
+ return;
1342
+ }
1343
+ if (attribute.value !== expectedValue) {
1344
+ ctx.addIssue({
1345
+ code: "custom",
1346
+ message: mismatchMessage,
1347
+ path
1348
+ });
1349
+ }
1350
+ }
1351
+ function validateDateAttribute(params) {
1352
+ const {
1353
+ ctx,
1354
+ attributeByTraitType,
1355
+ traitType,
1356
+ dateValue,
1357
+ missingMessage,
1358
+ invalidDateMessage,
1359
+ mismatchMessage,
1360
+ attributePath = ["attributes"],
1361
+ datePath
1362
+ } = params;
1363
+ const attribute = attributeByTraitType.get(traitType);
1364
+ if (!attribute) {
1365
+ ctx.addIssue({
1366
+ code: "custom",
1367
+ message: missingMessage,
1368
+ path: attributePath
1369
+ });
1370
+ return;
1371
+ }
1372
+ const dateMs = Date.parse(`${dateValue}T00:00:00.000Z`);
1373
+ if (Number.isNaN(dateMs)) {
1374
+ ctx.addIssue({
1375
+ code: "custom",
1376
+ message: invalidDateMessage,
1377
+ path: datePath ?? attributePath
1378
+ });
1379
+ return;
1380
+ }
1381
+ if (attribute.value !== dateMs) {
1382
+ ctx.addIssue({
1383
+ code: "custom",
1384
+ message: mismatchMessage,
1385
+ path: attributePath
1386
+ });
1387
+ }
1388
+ }
1389
+ function validateAttributesForItems(params) {
1390
+ const {
1391
+ ctx,
1392
+ attributeByTraitType,
1393
+ items,
1394
+ traitSelector,
1395
+ valueSelector,
1396
+ missingMessage,
1397
+ mismatchMessage,
1398
+ path = ["attributes"]
1399
+ } = params;
1400
+ items.forEach((item) => {
1401
+ const traitType = traitSelector(item);
1402
+ const expectedValue = valueSelector(item);
1403
+ const attribute = attributeByTraitType.get(traitType);
1404
+ if (!attribute) {
1405
+ ctx.addIssue({
1406
+ code: "custom",
1407
+ message: missingMessage(traitType),
1408
+ path
1409
+ });
1410
+ return;
1411
+ }
1412
+ if (attribute.value !== expectedValue) {
1413
+ ctx.addIssue({
1414
+ code: "custom",
1415
+ message: mismatchMessage(traitType),
1416
+ path
1417
+ });
1418
+ }
1419
+ });
1420
+ }
1088
1421
 
1089
1422
  // src/mass-id/mass-id.attributes.ts
1090
1423
  var MassIDAttributeWasteTypeSchema = NftAttributeSchema.safeExtend({
@@ -1905,66 +2238,7 @@ var CreditPurchaseReceiptAttributesSchema = uniqueBy(
1905
2238
  title: "Credit Purchase Receipt NFT Attribute Array",
1906
2239
  description: "Attributes for credit purchase receipts including per-credit breakdowns, totals, receiver, purchase date, and per-collection amounts. Attributes must have unique trait types."
1907
2240
  });
1908
- var CreditPurchaseReceiptSummarySchema = zod.z.strictObject({
1909
- total_usdc_amount: NonNegativeFloatSchema.meta({
1910
- title: "Total USDC Amount",
1911
- description: "Total amount paid in USDC for the purchase"
1912
- }),
1913
- total_credits: CreditAmountSchema.meta({
1914
- title: "Total Credits",
1915
- description: "Total amount of credits purchased"
1916
- }),
1917
- total_certificates: PositiveIntegerSchema.meta({
1918
- title: "Total Certificates",
1919
- description: "Total number of certificates purchased"
1920
- }),
1921
- purchase_date: IsoDateSchema.meta({
1922
- title: "Purchase Date",
1923
- description: "Date when the purchase was made (YYYY-MM-DD)"
1924
- }),
1925
- credit_symbols: uniqueArrayItems(
1926
- TokenSymbolSchema,
1927
- "Credit symbols must be unique"
1928
- ).min(1).meta({
1929
- title: "Credit Symbols",
1930
- description: "Array of credit token symbols included in the purchase"
1931
- }),
1932
- certificate_types: uniqueArrayItems(
1933
- RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]),
1934
- "Certificate types must be unique"
1935
- ).min(1).meta({
1936
- title: "Certificate Types",
1937
- description: "Array of certificate types included in the purchase"
1938
- }),
1939
- collection_slugs: uniqueArrayItems(
1940
- CollectionSlugSchema,
1941
- "Collection slugs must be unique"
1942
- ).min(1).meta({
1943
- title: "Collection Slugs",
1944
- description: "Array of collection slugs represented in the purchase"
1945
- })
1946
- }).meta({
1947
- title: "Credit Purchase Receipt Summary",
1948
- description: "Summary totals for the credit purchase including amounts and collections represented"
1949
- });
1950
- var CreditPurchaseReceiptIdentitySchema = zod.z.strictObject({
1951
- name: ParticipantNameSchema.meta({
1952
- title: "Identity Name",
1953
- description: "Display name for the participant",
1954
- examples: ["EcoTech Solutions Inc."]
1955
- }),
1956
- external_id: ExternalIdSchema.meta({
1957
- title: "Identity External ID",
1958
- description: "External identifier for the participant"
1959
- }),
1960
- external_url: ExternalUrlSchema.meta({
1961
- title: "Identity External URL",
1962
- description: "External URL for the participant profile"
1963
- })
1964
- }).meta({
1965
- title: "Identity",
1966
- description: "Participant identity information"
1967
- });
2241
+ var CreditPurchaseReceiptIdentitySchema = ReceiptIdentitySchema;
1968
2242
  var CreditPurchaseReceiptReceiverSchema = zod.z.strictObject({
1969
2243
  wallet_address: EthereumAddressSchema.meta({
1970
2244
  title: "Receiver Wallet Address",
@@ -1996,123 +2270,52 @@ var CreditPurchaseReceiptPartiesSchema = zod.z.strictObject({
1996
2270
  title: "Parties",
1997
2271
  description: "Parties involved in the purchase including payer, receiver, and optional buyer"
1998
2272
  });
1999
- var CreditPurchaseReceiptCollectionSchema = zod.z.strictObject({
2000
- slug: CollectionSlugSchema,
2001
- external_id: ExternalIdSchema.meta({
2002
- title: "Collection External ID",
2003
- description: "External identifier for the collection"
2004
- }),
2005
- name: CollectionNameSchema,
2006
- external_url: ExternalUrlSchema.meta({
2007
- title: "Collection External URL",
2008
- description: "External URL for the collection"
2009
- }),
2010
- uri: IpfsUriSchema.meta({
2011
- title: "Collection URI",
2012
- description: "IPFS URI for the collection metadata"
2013
- }),
2014
- credit_amount: CreditAmountSchema.meta({
2273
+ var CreditPurchaseReceiptCollectionSchema = createReceiptCollectionSchema({
2274
+ amountKey: "credit_amount",
2275
+ amountMeta: {
2015
2276
  title: "Collection Credit Amount",
2016
2277
  description: "Total credits purchased from this collection"
2017
- })
2018
- }).meta({
2019
- title: "Collection",
2020
- description: "Collection included in the purchase"
2278
+ },
2279
+ meta: {
2280
+ title: "Collection",
2281
+ description: "Collection included in the purchase"
2282
+ }
2021
2283
  });
2022
- var CreditPurchaseReceiptCreditSchema = zod.z.strictObject({
2023
- slug: SlugSchema.meta({
2024
- title: "Credit Slug",
2025
- description: "URL-friendly identifier for the credit"
2026
- }),
2027
- symbol: TokenSymbolSchema.meta({
2028
- title: "Credit Token Symbol",
2029
- description: "Symbol of the credit token",
2030
- examples: ["C-CARB", "C-BIOW"]
2031
- }),
2032
- external_id: ExternalIdSchema.meta({
2033
- title: "Credit External ID",
2034
- description: "External identifier for the credit"
2035
- }),
2036
- external_url: ExternalUrlSchema.meta({
2037
- title: "Credit External URL",
2038
- description: "External URL for the credit"
2039
- }),
2040
- uri: IpfsUriSchema.meta({
2041
- title: "Credit URI",
2042
- description: "IPFS URI for the credit details"
2043
- }),
2044
- smart_contract: SmartContractSchema,
2045
- purchase_amount: CreditAmountSchema.meta({
2284
+ var CreditPurchaseReceiptCreditSchema = createReceiptCreditSchema({
2285
+ amountKey: "purchase_amount",
2286
+ amountMeta: {
2046
2287
  title: "Credit Purchase Amount",
2047
2288
  description: "Total credits purchased for this credit type"
2048
- }),
2049
- retirement_amount: CreditAmountSchema.optional().meta({
2289
+ },
2290
+ retirementAmountMeta: {
2050
2291
  title: "Credit Retirement Amount",
2051
2292
  description: "Credits retired immediately for this credit type during purchase"
2052
- })
2053
- }).meta({
2054
- title: "Credit",
2055
- description: "Credit token included in the purchase"
2293
+ },
2294
+ meta: {
2295
+ title: "Credit",
2296
+ description: "Credit token included in the purchase"
2297
+ }
2056
2298
  });
2057
- var MassIDReferenceWithContractSchema = MassIDReferenceSchema.omit({
2058
- external_id: true
2059
- }).safeExtend({
2060
- external_id: ExternalIdSchema.meta({
2061
- title: "MassID External ID",
2062
- description: "Unique identifier for the referenced MassID"
2063
- }),
2064
- smart_contract: SmartContractSchema
2065
- }).meta({
2066
- title: "MassID Reference with Smart Contract",
2067
- description: "Reference to a MassID record including smart contract details"
2068
- });
2069
- var CreditPurchaseReceiptCertificateSchema = zod.z.strictObject({
2070
- token_id: TokenIdSchema.meta({
2071
- title: "Certificate Token ID",
2072
- description: "Token ID of the certificate"
2073
- }),
2074
- type: RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]).meta({
2075
- title: "Certificate Type",
2076
- description: "Type of certificate (e.g., GasID, RecycledID)"
2077
- }),
2078
- external_id: ExternalIdSchema.meta({
2079
- title: "Certificate External ID",
2080
- description: "External identifier for the certificate"
2081
- }),
2082
- external_url: ExternalUrlSchema.meta({
2083
- title: "Certificate External URL",
2084
- description: "External URL for the certificate"
2085
- }),
2086
- uri: IpfsUriSchema.meta({
2087
- title: "Certificate URI",
2088
- description: "IPFS URI for the certificate metadata"
2089
- }),
2090
- smart_contract: SmartContractSchema,
2091
- collection_slug: CollectionSlugSchema.meta({
2092
- title: "Collection Slug",
2093
- description: "Slug of the collection this certificate belongs to"
2094
- }),
2095
- total_amount: CreditAmountSchema.meta({
2096
- title: "Certificate Total Amount",
2097
- description: "Total credits available in this certificate"
2098
- }),
2099
- purchased_amount: CreditAmountSchema.meta({
2100
- title: "Certificate Purchased Amount",
2101
- description: "Credits purchased from this certificate"
2102
- }),
2103
- retired_amount: CreditAmountSchema.meta({
2104
- title: "Certificate Retired Amount",
2105
- description: "Credits retired from this certificate during the purchase (0 if none)"
2106
- }),
2107
- credit_slug: SlugSchema.meta({
2108
- title: "Credit Slug",
2109
- description: "Slug of the credit type for this certificate",
2110
- examples: ["carbon", "organic"]
2111
- }),
2112
- mass_id: MassIDReferenceWithContractSchema
2113
- }).meta({
2114
- title: "Certificate",
2115
- description: "Certificate associated with the purchase"
2299
+ var CreditPurchaseReceiptCertificateSchema = createReceiptCertificateSchema({
2300
+ additionalShape: {
2301
+ purchased_amount: CreditAmountSchema.meta({
2302
+ title: "Certificate Purchased Amount",
2303
+ description: "Credits purchased from this certificate"
2304
+ }),
2305
+ retired_amount: CreditAmountSchema.meta({
2306
+ title: "Certificate Retired Amount",
2307
+ description: "Credits retired from this certificate during the purchase (0 if none)"
2308
+ }),
2309
+ credit_slug: SlugSchema.meta({
2310
+ title: "Credit Slug",
2311
+ description: "Slug of the credit type for this certificate",
2312
+ examples: ["carbon", "organic"]
2313
+ })
2314
+ },
2315
+ meta: {
2316
+ title: "Certificate",
2317
+ description: "Certificate associated with the purchase"
2318
+ }
2116
2319
  });
2117
2320
  var CreditPurchaseReceiptParticipantRewardSchema = zod.z.strictObject({
2118
2321
  id_hash: Sha256HashSchema.meta({
@@ -2170,10 +2373,6 @@ var CreditPurchaseReceiptRetirementSchema = zod.z.strictObject({
2170
2373
  title: "Retirement",
2171
2374
  description: "Immediate retirement details performed as part of purchase"
2172
2375
  });
2173
- var EPSILON = 1e-9;
2174
- function nearlyEqual(a, b) {
2175
- return Math.abs(a - b) <= EPSILON;
2176
- }
2177
2376
  var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2178
2377
  summary: CreditPurchaseReceiptSummarySchema,
2179
2378
  parties: CreditPurchaseReceiptPartiesSchema,
@@ -2214,7 +2413,8 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2214
2413
  const retirementProvided = Boolean(data.retirement);
2215
2414
  const creditsWithRetirement = data.credits.reduce(
2216
2415
  (indices, credit, index) => {
2217
- if ((credit.retirement_amount ?? 0) > 0) {
2416
+ const retirementAmount = Number(credit.retirement_amount ?? 0);
2417
+ if (retirementAmount > 0) {
2218
2418
  indices.push(index);
2219
2419
  }
2220
2420
  return indices;
@@ -2237,77 +2437,48 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2237
2437
  });
2238
2438
  });
2239
2439
  }
2440
+ validateCountMatches({
2441
+ ctx,
2442
+ actualCount: data.certificates.length,
2443
+ expectedCount: data.summary.total_certificates,
2444
+ path: ["summary", "total_certificates"],
2445
+ message: "summary.total_certificates must equal the number of certificates"
2446
+ });
2240
2447
  const collectionSlugs = new Set(
2241
- data.collections.map((collection) => collection.slug)
2448
+ data.collections.map((collection) => String(collection.slug))
2449
+ );
2450
+ const creditSlugs = new Set(
2451
+ data.credits.map((credit) => String(credit.slug))
2452
+ );
2453
+ const creditSymbols = new Set(
2454
+ data.credits.map((credit) => String(credit.symbol))
2242
2455
  );
2243
- const creditSlugs = new Set(data.credits.map((credit) => credit.slug));
2244
- const creditSymbols = new Set(data.credits.map((credit) => credit.symbol));
2245
- const summaryCreditSymbols = new Set(data.summary.credit_symbols);
2246
- const summaryCollectionSlugs = new Set(data.summary.collection_slugs);
2247
- const summaryCertificateTypes = new Set(data.summary.certificate_types);
2248
- if (data.summary.total_certificates !== data.certificates.length) {
2249
- ctx.addIssue({
2250
- code: "custom",
2251
- message: "summary.total_certificates must equal the number of certificates",
2252
- path: ["summary", "total_certificates"]
2253
- });
2254
- }
2255
- data.summary.credit_symbols.forEach((symbol) => {
2256
- if (!creditSymbols.has(symbol)) {
2257
- ctx.addIssue({
2258
- code: "custom",
2259
- message: "summary.credit_symbols must reference symbols from credits",
2260
- path: ["summary", "credit_symbols"]
2261
- });
2262
- }
2263
- });
2264
- creditSymbols.forEach((symbol) => {
2265
- if (!summaryCreditSymbols.has(symbol)) {
2266
- ctx.addIssue({
2267
- code: "custom",
2268
- message: "All credit symbols must be listed in summary.credit_symbols",
2269
- path: ["summary", "credit_symbols"]
2270
- });
2271
- }
2272
- });
2273
- data.summary.collection_slugs.forEach((slug) => {
2274
- if (!collectionSlugs.has(slug)) {
2275
- ctx.addIssue({
2276
- code: "custom",
2277
- message: "summary.collection_slugs must reference slugs from collections",
2278
- path: ["summary", "collection_slugs"]
2279
- });
2280
- }
2281
- });
2282
- collectionSlugs.forEach((slug) => {
2283
- if (!summaryCollectionSlugs.has(slug)) {
2284
- ctx.addIssue({
2285
- code: "custom",
2286
- message: "All collection slugs must be listed in summary.collection_slugs",
2287
- path: ["summary", "collection_slugs"]
2288
- });
2289
- }
2290
- });
2291
2456
  const certificateTypes = new Set(
2292
- data.certificates.map((certificate) => certificate.type)
2457
+ data.certificates.map((certificate) => String(certificate.type))
2293
2458
  );
2294
- data.summary.certificate_types.forEach((type) => {
2295
- if (!certificateTypes.has(type)) {
2296
- ctx.addIssue({
2297
- code: "custom",
2298
- message: "summary.certificate_types must reference types present in certificates",
2299
- path: ["summary", "certificate_types"]
2300
- });
2301
- }
2459
+ validateSummaryListMatchesData({
2460
+ ctx,
2461
+ summaryValues: data.summary.credit_symbols,
2462
+ dataValues: creditSymbols,
2463
+ summaryPath: ["summary", "credit_symbols"],
2464
+ missingFromDataMessage: "summary.credit_symbols must reference symbols from credits",
2465
+ missingFromSummaryMessage: "All credit symbols must be listed in summary.credit_symbols"
2302
2466
  });
2303
- certificateTypes.forEach((type) => {
2304
- if (!summaryCertificateTypes.has(type)) {
2305
- ctx.addIssue({
2306
- code: "custom",
2307
- message: "All certificate types must be listed in summary.certificate_types",
2308
- path: ["summary", "certificate_types"]
2309
- });
2310
- }
2467
+ validateSummaryListMatchesData({
2468
+ ctx,
2469
+ summaryValues: data.summary.collection_slugs,
2470
+ dataValues: collectionSlugs,
2471
+ summaryPath: ["summary", "collection_slugs"],
2472
+ missingFromDataMessage: "summary.collection_slugs must reference slugs from collections",
2473
+ missingFromSummaryMessage: "All collection slugs must be listed in summary.collection_slugs"
2474
+ });
2475
+ validateSummaryListMatchesData({
2476
+ ctx,
2477
+ summaryValues: data.summary.certificate_types,
2478
+ dataValues: certificateTypes,
2479
+ summaryPath: ["summary", "certificate_types"],
2480
+ missingFromDataMessage: "summary.certificate_types must reference types present in certificates",
2481
+ missingFromSummaryMessage: "All certificate types must be listed in summary.certificate_types"
2311
2482
  });
2312
2483
  const creditPurchaseTotalsBySlug = /* @__PURE__ */ new Map();
2313
2484
  const creditRetiredTotalsBySlug = /* @__PURE__ */ new Map();
@@ -2342,60 +2513,60 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2342
2513
  path: ["certificates", index, "purchased_amount"]
2343
2514
  });
2344
2515
  }
2345
- totalCreditsFromCertificates += certificate.purchased_amount;
2516
+ totalCreditsFromCertificates += Number(certificate.purchased_amount);
2346
2517
  creditPurchaseTotalsBySlug.set(
2347
- certificate.credit_slug,
2348
- (creditPurchaseTotalsBySlug.get(certificate.credit_slug) ?? 0) + certificate.purchased_amount
2518
+ String(certificate.credit_slug),
2519
+ (creditPurchaseTotalsBySlug.get(certificate.credit_slug) ?? 0) + Number(certificate.purchased_amount)
2349
2520
  );
2350
2521
  creditRetiredTotalsBySlug.set(
2351
- certificate.credit_slug,
2352
- (creditRetiredTotalsBySlug.get(certificate.credit_slug) ?? 0) + certificate.retired_amount
2522
+ String(certificate.credit_slug),
2523
+ (creditRetiredTotalsBySlug.get(certificate.credit_slug) ?? 0) + Number(certificate.retired_amount)
2353
2524
  );
2354
2525
  collectionTotalsBySlug.set(
2355
- certificate.collection_slug,
2356
- (collectionTotalsBySlug.get(certificate.collection_slug) ?? 0) + certificate.purchased_amount
2526
+ String(certificate.collection_slug),
2527
+ (collectionTotalsBySlug.get(certificate.collection_slug) ?? 0) + Number(certificate.purchased_amount)
2357
2528
  );
2358
2529
  });
2359
2530
  const totalCreditsFromCollections = data.collections.reduce(
2360
- (sum, collection) => sum + collection.credit_amount,
2531
+ (sum, collection) => sum + Number(collection.credit_amount),
2361
2532
  0
2362
2533
  );
2363
2534
  const totalCreditsFromCredits = data.credits.reduce(
2364
- (sum, credit) => sum + credit.purchase_amount,
2535
+ (sum, credit) => sum + Number(credit.purchase_amount),
2365
2536
  0
2366
2537
  );
2367
- if (!nearlyEqual(totalCreditsFromCertificates, data.summary.total_credits)) {
2368
- ctx.addIssue({
2369
- code: "custom",
2370
- message: "summary.total_credits must equal sum of certificates.purchased_amount",
2371
- path: ["summary", "total_credits"]
2372
- });
2373
- }
2374
- if (!nearlyEqual(totalCreditsFromCredits, data.summary.total_credits)) {
2375
- ctx.addIssue({
2376
- code: "custom",
2377
- message: "summary.total_credits must equal sum of credits.purchase_amount",
2378
- path: ["summary", "total_credits"]
2379
- });
2380
- }
2381
- if (!nearlyEqual(totalCreditsFromCollections, data.summary.total_credits)) {
2382
- ctx.addIssue({
2383
- code: "custom",
2384
- message: "summary.total_credits must equal sum of collections.credit_amount",
2385
- path: ["summary", "total_credits"]
2386
- });
2387
- }
2538
+ validateTotalMatches({
2539
+ ctx,
2540
+ actualTotal: totalCreditsFromCertificates,
2541
+ expectedTotal: data.summary.total_credits,
2542
+ path: ["summary", "total_credits"],
2543
+ message: "summary.total_credits must equal sum of certificates.purchased_amount"
2544
+ });
2545
+ validateTotalMatches({
2546
+ ctx,
2547
+ actualTotal: totalCreditsFromCredits,
2548
+ expectedTotal: data.summary.total_credits,
2549
+ path: ["summary", "total_credits"],
2550
+ message: "summary.total_credits must equal sum of credits.purchase_amount"
2551
+ });
2552
+ validateTotalMatches({
2553
+ ctx,
2554
+ actualTotal: totalCreditsFromCollections,
2555
+ expectedTotal: data.summary.total_credits,
2556
+ path: ["summary", "total_credits"],
2557
+ message: "summary.total_credits must equal sum of collections.credit_amount"
2558
+ });
2388
2559
  data.credits.forEach((credit, index) => {
2389
- const purchasedTotal = creditPurchaseTotalsBySlug.get(credit.slug) ?? 0;
2390
- if (!nearlyEqual(credit.purchase_amount, purchasedTotal)) {
2560
+ const purchasedTotal = creditPurchaseTotalsBySlug.get(String(credit.slug)) ?? 0;
2561
+ if (!nearlyEqual(Number(credit.purchase_amount), purchasedTotal)) {
2391
2562
  ctx.addIssue({
2392
2563
  code: "custom",
2393
2564
  message: "credit.purchase_amount must equal sum of certificate purchased_amount for the credit slug",
2394
2565
  path: ["credits", index, "purchase_amount"]
2395
2566
  });
2396
2567
  }
2397
- const retiredTotal = creditRetiredTotalsBySlug.get(credit.slug) ?? 0;
2398
- const retirementAmount = credit.retirement_amount ?? 0;
2568
+ const retiredTotal = creditRetiredTotalsBySlug.get(String(credit.slug)) ?? 0;
2569
+ const retirementAmount = Number(credit.retirement_amount ?? 0);
2399
2570
  if (!nearlyEqual(retirementAmount, retiredTotal)) {
2400
2571
  ctx.addIssue({
2401
2572
  code: "custom",
@@ -2405,8 +2576,8 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2405
2576
  }
2406
2577
  });
2407
2578
  data.collections.forEach((collection, index) => {
2408
- const purchasedTotal = collectionTotalsBySlug.get(collection.slug) ?? 0;
2409
- if (!nearlyEqual(collection.credit_amount, purchasedTotal)) {
2579
+ const purchasedTotal = collectionTotalsBySlug.get(String(collection.slug)) ?? 0;
2580
+ if (!nearlyEqual(Number(collection.credit_amount), purchasedTotal)) {
2410
2581
  ctx.addIssue({
2411
2582
  code: "custom",
2412
2583
  message: "collection.credit_amount must equal sum of certificate purchased_amount for the collection slug",
@@ -2415,16 +2586,16 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
2415
2586
  }
2416
2587
  });
2417
2588
  const participantRewardTotal = data.participant_rewards.reduce(
2418
- (sum, reward) => sum + reward.usdc_amount,
2589
+ (sum, reward) => sum + Number(reward.usdc_amount),
2419
2590
  0
2420
2591
  );
2421
- if (!nearlyEqual(participantRewardTotal, data.summary.total_usdc_amount)) {
2422
- ctx.addIssue({
2423
- code: "custom",
2424
- message: "summary.total_usdc_amount must equal sum of participant_rewards.usdc_amount",
2425
- path: ["summary", "total_usdc_amount"]
2426
- });
2427
- }
2592
+ validateTotalMatches({
2593
+ ctx,
2594
+ actualTotal: participantRewardTotal,
2595
+ expectedTotal: data.summary.total_usdc_amount,
2596
+ path: ["summary", "total_usdc_amount"],
2597
+ message: "summary.total_usdc_amount must equal sum of participant_rewards.usdc_amount"
2598
+ });
2428
2599
  }).meta({
2429
2600
  title: "Credit Purchase Receipt Data",
2430
2601
  description: "Complete data structure for a credit purchase receipt"
@@ -2449,133 +2620,595 @@ var CreditPurchaseReceiptIpfsSchema = NftIpfsSchema.safeExtend({
2449
2620
  }).superRefine((value, ctx) => {
2450
2621
  const attributes = value.attributes;
2451
2622
  const data = value.data;
2452
- const attributeByTraitType = new Map(
2453
- attributes.map((attribute) => [attribute.trait_type, attribute])
2454
- );
2455
- const totalCreditsAttribute = attributeByTraitType.get(
2456
- "Total Credits Purchased"
2457
- );
2458
- const totalCreditsAttr = totalCreditsAttribute;
2459
- if (!totalCreditsAttr) {
2460
- ctx.addIssue({
2461
- code: "custom",
2462
- message: 'Attribute "Total Credits Purchased" is required',
2463
- path: ["attributes"]
2464
- });
2465
- } else if (totalCreditsAttr.value !== data.summary.total_credits) {
2466
- ctx.addIssue({
2467
- code: "custom",
2468
- message: 'Attribute "Total Credits Purchased" must match data.summary.total_credits',
2469
- path: ["attributes"]
2623
+ const attributeByTraitType = createAttributeMap(attributes);
2624
+ validateAttributeValue({
2625
+ ctx,
2626
+ attributeByTraitType,
2627
+ traitType: "Total Credits Purchased",
2628
+ expectedValue: data.summary.total_credits,
2629
+ missingMessage: 'Attribute "Total Credits Purchased" is required',
2630
+ mismatchMessage: 'Attribute "Total Credits Purchased" must match data.summary.total_credits'
2631
+ });
2632
+ validateAttributeValue({
2633
+ ctx,
2634
+ attributeByTraitType,
2635
+ traitType: "Total USDC Amount",
2636
+ expectedValue: data.summary.total_usdc_amount,
2637
+ missingMessage: 'Attribute "Total USDC Amount" is required',
2638
+ mismatchMessage: 'Attribute "Total USDC Amount" must match data.summary.total_usdc_amount'
2639
+ });
2640
+ validateAttributeValue({
2641
+ ctx,
2642
+ attributeByTraitType,
2643
+ traitType: "Certificates Purchased",
2644
+ expectedValue: data.summary.total_certificates,
2645
+ missingMessage: 'Attribute "Certificates Purchased" is required',
2646
+ mismatchMessage: 'Attribute "Certificates Purchased" must match data.summary.total_certificates'
2647
+ });
2648
+ const receiverName = data.parties.receiver.identity?.name;
2649
+ if (receiverName) {
2650
+ validateAttributeValue({
2651
+ ctx,
2652
+ attributeByTraitType,
2653
+ traitType: "Receiver",
2654
+ expectedValue: String(receiverName),
2655
+ missingMessage: 'Attribute "Receiver" is required when receiver.identity.name is provided',
2656
+ mismatchMessage: 'Attribute "Receiver" must match receiver.identity.name'
2470
2657
  });
2471
2658
  }
2472
- const totalUsdcAttribute = attributeByTraitType.get("Total USDC Amount");
2473
- if (!totalUsdcAttribute) {
2474
- ctx.addIssue({
2475
- code: "custom",
2476
- message: 'Attribute "Total USDC Amount" is required',
2477
- path: ["attributes"]
2478
- });
2479
- } else if (totalUsdcAttribute.value !== data.summary.total_usdc_amount) {
2480
- ctx.addIssue({
2481
- code: "custom",
2482
- message: 'Attribute "Total USDC Amount" must match data.summary.total_usdc_amount',
2483
- path: ["attributes"]
2484
- });
2659
+ validateDateAttribute({
2660
+ ctx,
2661
+ attributeByTraitType,
2662
+ traitType: "Purchase Date",
2663
+ dateValue: data.summary.purchase_date,
2664
+ missingMessage: 'Attribute "Purchase Date" is required',
2665
+ invalidDateMessage: "data.summary.purchase_date must be a valid date string",
2666
+ mismatchMessage: 'Attribute "Purchase Date" must match data.summary.purchase_date as a Unix timestamp in milliseconds',
2667
+ datePath: ["data", "summary", "purchase_date"]
2668
+ });
2669
+ validateAttributesForItems({
2670
+ ctx,
2671
+ attributeByTraitType,
2672
+ items: data.credits,
2673
+ traitSelector: (credit) => String(credit.symbol),
2674
+ valueSelector: (credit) => Number(credit.purchase_amount),
2675
+ missingMessage: (symbol) => `Attribute for credit symbol ${symbol} is required`,
2676
+ mismatchMessage: (symbol) => `Attribute for credit symbol ${symbol} must match credit.purchase_amount`
2677
+ });
2678
+ validateAttributesForItems({
2679
+ ctx,
2680
+ attributeByTraitType,
2681
+ items: data.collections,
2682
+ traitSelector: (collection) => String(collection.name),
2683
+ valueSelector: (collection) => Number(collection.credit_amount),
2684
+ missingMessage: (name) => `Attribute for collection ${name} is required`,
2685
+ mismatchMessage: (name) => `Attribute for collection ${name} must match collection.credit_amount`
2686
+ });
2687
+ }).meta(CreditPurchaseReceiptIpfsSchemaMeta);
2688
+ var CreditRetirementReceiptCreditAttributeSchema = NftAttributeSchema.safeExtend({
2689
+ trait_type: CreditTokenSymbolSchema,
2690
+ value: CreditAmountSchema.meta({
2691
+ title: "Credit Retirement Amount",
2692
+ description: "Amount of credits retired for the token symbol"
2693
+ }),
2694
+ display_type: zod.z.literal("number")
2695
+ }).meta({
2696
+ title: "Credit Attribute",
2697
+ description: "Attribute representing retired amount per credit token symbol"
2698
+ });
2699
+ var CreditRetirementReceiptTotalCreditsAttributeSchema = NftAttributeSchema.safeExtend({
2700
+ trait_type: zod.z.literal("Total Credits Retired"),
2701
+ value: CreditAmountSchema.meta({
2702
+ title: "Total Credits Retired",
2703
+ description: "Total number of credits retired across all tokens"
2704
+ }),
2705
+ display_type: zod.z.literal("number")
2706
+ }).meta({
2707
+ title: "Total Credits Retired Attribute",
2708
+ description: "Aggregate credits retired attribute"
2709
+ });
2710
+ var CreditRetirementReceiptBeneficiaryAttributeSchema = NftAttributeSchema.safeExtend({
2711
+ trait_type: zod.z.literal("Beneficiary"),
2712
+ value: ParticipantNameSchema.meta({
2713
+ title: "Beneficiary",
2714
+ description: "Beneficiary receiving the retirement benefit",
2715
+ examples: ["Climate Action Corp"]
2716
+ })
2717
+ }).meta({
2718
+ title: "Beneficiary Attribute",
2719
+ description: "Attribute containing the beneficiary display name"
2720
+ });
2721
+ var CreditRetirementReceiptCreditHolderAttributeSchema = NftAttributeSchema.safeExtend({
2722
+ trait_type: zod.z.literal("Credit Holder"),
2723
+ value: ParticipantNameSchema.meta({
2724
+ title: "Credit Holder",
2725
+ description: "Entity that surrendered the credits",
2726
+ examples: ["EcoTech Solutions Inc."]
2727
+ })
2728
+ }).meta({
2729
+ title: "Credit Holder Attribute",
2730
+ description: "Attribute containing the credit holder display name"
2731
+ });
2732
+ var CreditRetirementReceiptRetirementDateAttributeSchema = NftAttributeSchema.safeExtend({
2733
+ trait_type: zod.z.literal("Retirement Date"),
2734
+ value: UnixTimestampSchema.meta({
2735
+ title: "Retirement Date",
2736
+ description: "Unix timestamp in milliseconds when the retirement was completed"
2737
+ }),
2738
+ display_type: zod.z.literal("date")
2739
+ }).meta({
2740
+ title: "Retirement Date Attribute",
2741
+ description: "Retirement date attribute using Unix timestamp in milliseconds"
2742
+ });
2743
+ var CreditRetirementReceiptCertificatesAttributeSchema = NftAttributeSchema.safeExtend({
2744
+ trait_type: zod.z.literal("Certificates Retired"),
2745
+ value: PositiveIntegerSchema.meta({
2746
+ title: "Certificates Retired",
2747
+ description: "Total number of certificates retired"
2748
+ }),
2749
+ display_type: zod.z.literal("number")
2750
+ }).meta({
2751
+ title: "Certificates Retired Attribute",
2752
+ description: "Attribute representing how many certificates were retired in total"
2753
+ });
2754
+ var CreditRetirementReceiptCollectionAttributeSchema = NftAttributeSchema.safeExtend({
2755
+ trait_type: CollectionNameSchema,
2756
+ value: CreditAmountSchema.meta({
2757
+ title: "Credits from Collection",
2758
+ description: "Amount of credits retired from the collection"
2759
+ }),
2760
+ display_type: zod.z.literal("number")
2761
+ }).meta({
2762
+ title: "Collection Attribute",
2763
+ description: "Attribute representing the amount of credits retired from a collection"
2764
+ });
2765
+ var CreditRetirementReceiptAttributesSchema = uniqueBy(
2766
+ zod.z.union([
2767
+ CreditRetirementReceiptCreditAttributeSchema,
2768
+ CreditRetirementReceiptTotalCreditsAttributeSchema,
2769
+ CreditRetirementReceiptBeneficiaryAttributeSchema,
2770
+ CreditRetirementReceiptCreditHolderAttributeSchema,
2771
+ CreditRetirementReceiptRetirementDateAttributeSchema,
2772
+ CreditRetirementReceiptCertificatesAttributeSchema,
2773
+ CreditRetirementReceiptCollectionAttributeSchema
2774
+ ]),
2775
+ (attribute) => attribute.trait_type,
2776
+ "Attribute trait_type values must be unique"
2777
+ ).min(6).meta({
2778
+ title: "Credit Retirement Receipt NFT Attribute Array",
2779
+ description: "Attributes for credit retirement receipts including per-credit breakdowns, totals, beneficiary, credit holder, retirement date, certificate count, and per-collection amounts. Attributes must have unique trait types."
2780
+ });
2781
+ var CreditRetirementReceiptIdentitySchema = ReceiptIdentitySchema;
2782
+ var CreditRetirementReceiptBeneficiarySchema = zod.z.strictObject({
2783
+ beneficiary_id: ExternalIdSchema.meta({
2784
+ title: "Retirement Beneficiary ID",
2785
+ description: "UUID identifying the beneficiary of the retirement (bytes16 normalized to UUID)"
2786
+ }),
2787
+ identity: CreditRetirementReceiptIdentitySchema
2788
+ }).meta({
2789
+ title: "Beneficiary",
2790
+ description: "Beneficiary receiving the retirement benefit"
2791
+ });
2792
+ var CreditRetirementReceiptCreditHolderSchema = zod.z.strictObject({
2793
+ wallet_address: EthereumAddressSchema.meta({
2794
+ title: "Credit Holder Wallet Address",
2795
+ description: "Ethereum address of the credit holder surrendering credits"
2796
+ }),
2797
+ identity: CreditRetirementReceiptIdentitySchema.optional()
2798
+ }).meta({
2799
+ title: "Credit Holder",
2800
+ description: "Credit holder wallet and optional identity information"
2801
+ });
2802
+ var CreditRetirementReceiptCollectionSchema = createReceiptCollectionSchema({
2803
+ amountKey: "amount",
2804
+ amountMeta: {
2805
+ title: "Collection Retirement Amount",
2806
+ description: "Total credits retired from this collection"
2807
+ },
2808
+ meta: {
2809
+ title: "Collection",
2810
+ description: "Collection included in the retirement"
2485
2811
  }
2486
- const certificatesAttribute = attributeByTraitType.get(
2487
- "Certificates Purchased"
2488
- );
2489
- if (!certificatesAttribute) {
2490
- ctx.addIssue({
2491
- code: "custom",
2492
- message: 'Attribute "Certificates Purchased" is required',
2493
- path: ["attributes"]
2494
- });
2495
- } else if (certificatesAttribute.value !== data.summary.total_certificates) {
2496
- ctx.addIssue({
2497
- code: "custom",
2498
- message: 'Attribute "Certificates Purchased" must match data.summary.total_certificates',
2499
- path: ["attributes"]
2500
- });
2812
+ });
2813
+ var CreditRetirementReceiptCreditSchema = createReceiptCreditSchema({
2814
+ amountKey: "amount",
2815
+ amountMeta: {
2816
+ title: "Credit Retirement Amount",
2817
+ description: "Total credits retired for this credit type"
2818
+ },
2819
+ meta: {
2820
+ title: "Credit",
2821
+ description: "Credit token retired in this receipt"
2501
2822
  }
2502
- const receiverAttribute = attributeByTraitType.get("Receiver");
2503
- if (data.parties.receiver.identity?.name && !receiverAttribute) {
2504
- ctx.addIssue({
2505
- code: "custom",
2506
- message: 'Attribute "Receiver" is required when receiver.identity.name is provided',
2507
- path: ["attributes"]
2508
- });
2509
- } else if (receiverAttribute && data.parties.receiver.identity?.name && receiverAttribute.value !== data.parties.receiver.identity.name) {
2510
- ctx.addIssue({
2511
- code: "custom",
2512
- message: 'Attribute "Receiver" must match receiver.identity.name',
2513
- path: ["attributes"]
2514
- });
2823
+ });
2824
+ var CreditRetirementReceiptCertificateCreditSchema = zod.z.strictObject({
2825
+ credit_symbol: CreditTokenSymbolSchema.meta({
2826
+ title: "Credit Token Symbol",
2827
+ description: "Symbol of the credit token retired from the certificate"
2828
+ }),
2829
+ credit_slug: SlugSchema.meta({
2830
+ title: "Credit Slug",
2831
+ description: "Slug of the credit type retired from the certificate",
2832
+ examples: ["carbon", "organic"]
2833
+ }),
2834
+ amount: CreditAmountSchema.meta({
2835
+ title: "Retired Credit Amount",
2836
+ description: "Credits retired of this type from the certificate"
2837
+ }),
2838
+ external_id: ExternalIdSchema.meta({
2839
+ title: "Retired Credit External ID",
2840
+ description: "External identifier for the retired credit entry"
2841
+ }),
2842
+ external_url: ExternalUrlSchema.meta({
2843
+ title: "Retired Credit External URL",
2844
+ description: "External URL for the retired credit entry"
2845
+ })
2846
+ }).meta({
2847
+ title: "Certificate Credit Retirement",
2848
+ description: "Credit retirement breakdown for a certificate"
2849
+ });
2850
+ var CreditPurchaseReceiptReferenceSchema = zod.z.strictObject({
2851
+ token_id: TokenIdSchema.meta({
2852
+ title: "Purchase Receipt Token ID",
2853
+ description: "Token ID of the credit purchase receipt"
2854
+ }),
2855
+ external_id: ExternalIdSchema.meta({
2856
+ title: "Purchase Receipt External ID",
2857
+ description: "External identifier for the purchase receipt"
2858
+ }),
2859
+ external_url: ExternalUrlSchema.meta({
2860
+ title: "Purchase Receipt External URL",
2861
+ description: "External URL for the purchase receipt"
2862
+ }),
2863
+ uri: IpfsUriSchema.meta({
2864
+ title: "Purchase Receipt URI",
2865
+ description: "IPFS URI for the purchase receipt metadata"
2866
+ }),
2867
+ smart_contract: SmartContractSchema
2868
+ }).meta({
2869
+ title: "Credit Purchase Receipt Reference",
2870
+ description: "Reference to the credit purchase receipt when retirement occurs during purchase"
2871
+ });
2872
+ var CreditRetirementReceiptCertificateSchema = createReceiptCertificateSchema(
2873
+ {
2874
+ additionalShape: {
2875
+ retired_amount: CreditAmountSchema.meta({
2876
+ title: "Certificate Retired Amount",
2877
+ description: "Credits retired from this certificate"
2878
+ }),
2879
+ credits_retired: uniqueBy(
2880
+ CreditRetirementReceiptCertificateCreditSchema,
2881
+ (credit) => credit.credit_symbol,
2882
+ "Credit symbols within credits_retired must be unique"
2883
+ ).min(1).meta({
2884
+ title: "Credits Retired",
2885
+ description: "Breakdown of credits retired from this certificate by symbol"
2886
+ })
2887
+ },
2888
+ meta: {
2889
+ title: "Certificate",
2890
+ description: "Certificate associated with the retirement"
2891
+ }
2515
2892
  }
2516
- const purchaseDateAttribute = attributeByTraitType.get("Purchase Date");
2517
- const purchaseDateAttr = purchaseDateAttribute;
2518
- if (!purchaseDateAttr) {
2519
- ctx.addIssue({
2520
- code: "custom",
2521
- message: 'Attribute "Purchase Date" is required',
2522
- path: ["attributes"]
2523
- });
2524
- } else {
2525
- const purchaseDateMs = Date.parse(
2526
- `${data.summary.purchase_date}T00:00:00.000Z`
2527
- );
2528
- if (Number.isNaN(purchaseDateMs)) {
2893
+ );
2894
+ var CreditRetirementReceiptDataSchema = zod.z.strictObject({
2895
+ summary: CreditRetirementReceiptSummarySchema,
2896
+ beneficiary: CreditRetirementReceiptBeneficiarySchema,
2897
+ credit_holder: CreditRetirementReceiptCreditHolderSchema,
2898
+ collections: uniqueBy(
2899
+ CreditRetirementReceiptCollectionSchema,
2900
+ (collection) => collection.slug,
2901
+ "Collection slugs must be unique"
2902
+ ).min(1).meta({
2903
+ title: "Collections",
2904
+ description: "Collections included in the retirement"
2905
+ }),
2906
+ credits: uniqueBy(
2907
+ CreditRetirementReceiptCreditSchema,
2908
+ (credit) => credit.slug,
2909
+ "Credit slugs must be unique"
2910
+ ).min(1).meta({
2911
+ title: "Credits",
2912
+ description: "Credits included in the retirement"
2913
+ }),
2914
+ certificates: uniqueBy(
2915
+ CreditRetirementReceiptCertificateSchema,
2916
+ (certificate) => certificate.token_id,
2917
+ "Certificate token_ids must be unique"
2918
+ ).min(1).meta({
2919
+ title: "Certificates",
2920
+ description: "Certificates retired in this receipt"
2921
+ }),
2922
+ purchase_receipt: CreditPurchaseReceiptReferenceSchema.optional()
2923
+ }).superRefine((data, ctx) => {
2924
+ const creditSymbols = new Set(
2925
+ data.credits.map((credit) => String(credit.symbol))
2926
+ );
2927
+ const creditBySlug = new Map(
2928
+ data.credits.map((credit) => [credit.slug, credit])
2929
+ );
2930
+ const collectionSlugs = new Set(
2931
+ data.collections.map((collection) => String(collection.slug))
2932
+ );
2933
+ const certificateTypes = new Set(
2934
+ data.certificates.map((certificate) => String(certificate.type))
2935
+ );
2936
+ validateCountMatches({
2937
+ ctx,
2938
+ actualCount: data.certificates.length,
2939
+ expectedCount: data.summary.total_certificates,
2940
+ path: ["summary", "total_certificates"],
2941
+ message: "summary.total_certificates must equal the number of certificates"
2942
+ });
2943
+ validateSummaryListMatchesData({
2944
+ ctx,
2945
+ summaryValues: data.summary.credit_symbols,
2946
+ dataValues: creditSymbols,
2947
+ summaryPath: ["summary", "credit_symbols"],
2948
+ missingFromDataMessage: "summary.credit_symbols must reference symbols from credits",
2949
+ missingFromSummaryMessage: "All credit symbols must be listed in summary.credit_symbols"
2950
+ });
2951
+ validateSummaryListMatchesData({
2952
+ ctx,
2953
+ summaryValues: data.summary.collection_slugs,
2954
+ dataValues: collectionSlugs,
2955
+ summaryPath: ["summary", "collection_slugs"],
2956
+ missingFromDataMessage: "summary.collection_slugs must reference slugs from collections",
2957
+ missingFromSummaryMessage: "All collection slugs must be listed in summary.collection_slugs"
2958
+ });
2959
+ validateSummaryListMatchesData({
2960
+ ctx,
2961
+ summaryValues: data.summary.certificate_types,
2962
+ dataValues: certificateTypes,
2963
+ summaryPath: ["summary", "certificate_types"],
2964
+ missingFromDataMessage: "summary.certificate_types must reference types present in certificates",
2965
+ missingFromSummaryMessage: "All certificate types must be listed in summary.certificate_types"
2966
+ });
2967
+ const creditTotalsBySymbol = /* @__PURE__ */ new Map();
2968
+ const collectionTotalsBySlug = /* @__PURE__ */ new Map();
2969
+ let totalRetiredFromCertificates = 0;
2970
+ data.certificates.forEach((certificate, index) => {
2971
+ if (!collectionSlugs.has(certificate.collection_slug)) {
2529
2972
  ctx.addIssue({
2530
2973
  code: "custom",
2531
- message: "data.summary.purchase_date must be a valid date string",
2532
- path: ["data", "summary", "purchase_date"]
2974
+ message: "collection_slug must match a collection slug in collections",
2975
+ path: ["certificates", index, "collection_slug"]
2533
2976
  });
2534
- } else if (purchaseDateAttr.value !== purchaseDateMs) {
2977
+ }
2978
+ if (certificate.retired_amount > certificate.total_amount) {
2535
2979
  ctx.addIssue({
2536
2980
  code: "custom",
2537
- message: 'Attribute "Purchase Date" must match data.summary.purchase_date as a Unix timestamp in milliseconds',
2538
- path: ["attributes"]
2981
+ message: "retired_amount cannot exceed total_amount",
2982
+ path: ["certificates", index, "retired_amount"]
2539
2983
  });
2540
2984
  }
2541
- }
2542
- data.credits.forEach((credit) => {
2543
- const creditAttribute = attributeByTraitType.get(credit.symbol);
2544
- if (!creditAttribute) {
2985
+ const creditsRetiredTotal = certificate.credits_retired.reduce(
2986
+ (sum, credit) => sum + Number(credit.amount),
2987
+ 0
2988
+ );
2989
+ if (!nearlyEqual(creditsRetiredTotal, certificate.retired_amount)) {
2545
2990
  ctx.addIssue({
2546
2991
  code: "custom",
2547
- message: `Attribute for credit symbol ${credit.symbol} is required`,
2548
- path: ["attributes"]
2992
+ message: "certificates.credits_retired amounts must sum to certificates.retired_amount",
2993
+ path: ["certificates", index, "credits_retired"]
2994
+ });
2995
+ }
2996
+ certificate.credits_retired.forEach((credit, creditIndex) => {
2997
+ const referencedCredit = creditBySlug.get(credit.credit_slug);
2998
+ if (!referencedCredit) {
2999
+ ctx.addIssue({
3000
+ code: "custom",
3001
+ message: "credit_slug must match a credit slug in credits",
3002
+ path: [
3003
+ "certificates",
3004
+ index,
3005
+ "credits_retired",
3006
+ creditIndex,
3007
+ "credit_slug"
3008
+ ]
3009
+ });
3010
+ }
3011
+ if (!creditSymbols.has(credit.credit_symbol)) {
3012
+ ctx.addIssue({
3013
+ code: "custom",
3014
+ message: "credit_symbol must match a credit symbol in credits",
3015
+ path: [
3016
+ "certificates",
3017
+ index,
3018
+ "credits_retired",
3019
+ creditIndex,
3020
+ "credit_symbol"
3021
+ ]
3022
+ });
3023
+ }
3024
+ if (referencedCredit && referencedCredit.symbol !== credit.credit_symbol) {
3025
+ ctx.addIssue({
3026
+ code: "custom",
3027
+ message: "credit_symbol must match the symbol for the referenced credit_slug",
3028
+ path: [
3029
+ "certificates",
3030
+ index,
3031
+ "credits_retired",
3032
+ creditIndex,
3033
+ "credit_symbol"
3034
+ ]
3035
+ });
3036
+ }
3037
+ creditTotalsBySymbol.set(
3038
+ credit.credit_symbol,
3039
+ (creditTotalsBySymbol.get(credit.credit_symbol) ?? 0) + credit.amount
3040
+ );
3041
+ });
3042
+ collectionTotalsBySlug.set(
3043
+ String(certificate.collection_slug),
3044
+ (collectionTotalsBySlug.get(certificate.collection_slug) ?? 0) + Number(certificate.retired_amount)
3045
+ );
3046
+ totalRetiredFromCertificates += Number(certificate.retired_amount);
3047
+ });
3048
+ const totalRetiredFromCollections = data.collections.reduce(
3049
+ (sum, collection) => sum + Number(collection.amount),
3050
+ 0
3051
+ );
3052
+ const totalRetiredFromCredits = data.credits.reduce(
3053
+ (sum, credit) => sum + Number(credit.amount),
3054
+ 0
3055
+ );
3056
+ data.summary.credit_symbols.forEach((symbol) => {
3057
+ if ((creditTotalsBySymbol.get(symbol) ?? 0) === 0) {
3058
+ ctx.addIssue({
3059
+ code: "custom",
3060
+ message: "Each summary credit symbol must appear in certificates.credits_retired with a retired amount",
3061
+ path: ["summary", "credit_symbols"]
2549
3062
  });
2550
- return;
2551
3063
  }
2552
- if (creditAttribute.value !== credit.purchase_amount) {
3064
+ });
3065
+ validateTotalMatches({
3066
+ ctx,
3067
+ actualTotal: totalRetiredFromCertificates,
3068
+ expectedTotal: data.summary.total_retirement_amount,
3069
+ path: ["summary", "total_retirement_amount"],
3070
+ message: "summary.total_retirement_amount must equal sum of certificates.retired_amount"
3071
+ });
3072
+ validateTotalMatches({
3073
+ ctx,
3074
+ actualTotal: totalRetiredFromCredits,
3075
+ expectedTotal: data.summary.total_retirement_amount,
3076
+ path: ["summary", "total_retirement_amount"],
3077
+ message: "summary.total_retirement_amount must equal sum of credits.amount"
3078
+ });
3079
+ validateTotalMatches({
3080
+ ctx,
3081
+ actualTotal: totalRetiredFromCollections,
3082
+ expectedTotal: data.summary.total_retirement_amount,
3083
+ path: ["summary", "total_retirement_amount"],
3084
+ message: "summary.total_retirement_amount must equal sum of collections.amount"
3085
+ });
3086
+ data.credits.forEach((credit, index) => {
3087
+ const retiredTotal = creditTotalsBySymbol.get(String(credit.symbol)) ?? 0;
3088
+ if (!nearlyEqual(Number(credit.amount), retiredTotal)) {
2553
3089
  ctx.addIssue({
2554
3090
  code: "custom",
2555
- message: `Attribute for credit symbol ${credit.symbol} must match credit.purchase_amount`,
2556
- path: ["attributes"]
3091
+ message: "credit.amount must equal sum of retired amounts for the credit symbol across certificates",
3092
+ path: ["credits", index, "amount"]
2557
3093
  });
2558
3094
  }
2559
3095
  });
2560
- data.collections.forEach((collection) => {
2561
- const collectionAttribute = attributeByTraitType.get(collection.name);
2562
- if (!collectionAttribute) {
3096
+ data.collections.forEach((collection, index) => {
3097
+ const retiredTotal = collectionTotalsBySlug.get(String(collection.slug)) ?? 0;
3098
+ if (retiredTotal === 0) {
2563
3099
  ctx.addIssue({
2564
3100
  code: "custom",
2565
- message: `Attribute for collection ${collection.name} is required`,
2566
- path: ["attributes"]
3101
+ message: "collection must be referenced by at least one certificate with retired_amount > 0",
3102
+ path: ["collections", index, "slug"]
2567
3103
  });
2568
- return;
2569
3104
  }
2570
- if (collectionAttribute.value !== collection.credit_amount) {
3105
+ if (Number(collection.amount) <= 0) {
2571
3106
  ctx.addIssue({
2572
3107
  code: "custom",
2573
- message: `Attribute for collection ${collection.name} must match collection.credit_amount`,
2574
- path: ["attributes"]
3108
+ message: "collection.amount must be greater than zero",
3109
+ path: ["collections", index, "amount"]
3110
+ });
3111
+ }
3112
+ if (!nearlyEqual(Number(collection.amount), retiredTotal)) {
3113
+ ctx.addIssue({
3114
+ code: "custom",
3115
+ message: "collection.amount must equal sum of certificate retired_amount for the collection slug",
3116
+ path: ["collections", index, "amount"]
2575
3117
  });
2576
3118
  }
2577
3119
  });
2578
- }).meta(CreditPurchaseReceiptIpfsSchemaMeta);
3120
+ }).meta({
3121
+ title: "Credit Retirement Receipt Data",
3122
+ description: "Complete data structure for a credit retirement receipt"
3123
+ });
3124
+ var CreditRetirementReceiptIpfsSchemaBase = NftIpfsSchema.omit({
3125
+ original_content_hash: true
3126
+ });
3127
+ var CreditRetirementReceiptIpfsSchemaMeta = {
3128
+ title: "CreditRetirementReceipt NFT IPFS Record",
3129
+ description: "Complete CreditRetirementReceipt NFT IPFS record including attributes and credit retirement data",
3130
+ $id: buildSchemaUrl(
3131
+ "credit-retirement-receipt/credit-retirement-receipt.schema.json"
3132
+ ),
3133
+ version: getSchemaVersionOrDefault()
3134
+ };
3135
+ var CreditRetirementReceiptIpfsSchema = CreditRetirementReceiptIpfsSchemaBase.safeExtend({
3136
+ schema: CreditRetirementReceiptIpfsSchemaBase.shape.schema.safeExtend({
3137
+ type: zod.z.literal("CreditRetirementReceipt").meta({
3138
+ title: "CreditRetirementReceipt Schema Type",
3139
+ description: "CreditRetirementReceipt NFT schema type"
3140
+ })
3141
+ }),
3142
+ attributes: CreditRetirementReceiptAttributesSchema,
3143
+ data: CreditRetirementReceiptDataSchema
3144
+ }).superRefine((value, ctx) => {
3145
+ const attributes = value.attributes;
3146
+ const data = value.data;
3147
+ const attributeByTraitType = createAttributeMap(attributes);
3148
+ validateAttributeValue({
3149
+ ctx,
3150
+ attributeByTraitType,
3151
+ traitType: "Total Credits Retired",
3152
+ expectedValue: data.summary.total_retirement_amount,
3153
+ missingMessage: 'Attribute "Total Credits Retired" is required',
3154
+ mismatchMessage: 'Attribute "Total Credits Retired" must match data.summary.total_retirement_amount'
3155
+ });
3156
+ validateAttributeValue({
3157
+ ctx,
3158
+ attributeByTraitType,
3159
+ traitType: "Certificates Retired",
3160
+ expectedValue: data.summary.total_certificates,
3161
+ missingMessage: 'Attribute "Certificates Retired" is required',
3162
+ mismatchMessage: 'Attribute "Certificates Retired" must match data.summary.total_certificates'
3163
+ });
3164
+ validateAttributeValue({
3165
+ ctx,
3166
+ attributeByTraitType,
3167
+ traitType: "Beneficiary",
3168
+ expectedValue: String(data.beneficiary.identity.name),
3169
+ missingMessage: 'Attribute "Beneficiary" is required',
3170
+ mismatchMessage: 'Attribute "Beneficiary" must match beneficiary.identity.name'
3171
+ });
3172
+ const creditHolderName = data.credit_holder.identity?.name;
3173
+ if (creditHolderName) {
3174
+ validateAttributeValue({
3175
+ ctx,
3176
+ attributeByTraitType,
3177
+ traitType: "Credit Holder",
3178
+ expectedValue: String(creditHolderName),
3179
+ missingMessage: 'Attribute "Credit Holder" is required when credit_holder.identity.name is provided',
3180
+ mismatchMessage: 'Attribute "Credit Holder" must match credit_holder.identity.name'
3181
+ });
3182
+ }
3183
+ validateDateAttribute({
3184
+ ctx,
3185
+ attributeByTraitType,
3186
+ traitType: "Retirement Date",
3187
+ dateValue: data.summary.retirement_date,
3188
+ missingMessage: 'Attribute "Retirement Date" is required',
3189
+ invalidDateMessage: "data.summary.retirement_date must be a valid date string",
3190
+ mismatchMessage: 'Attribute "Retirement Date" must match data.summary.retirement_date as a Unix timestamp in milliseconds',
3191
+ datePath: ["data", "summary", "retirement_date"]
3192
+ });
3193
+ validateAttributesForItems({
3194
+ ctx,
3195
+ attributeByTraitType,
3196
+ items: data.credits,
3197
+ traitSelector: (credit) => String(credit.symbol),
3198
+ valueSelector: (credit) => Number(credit.amount),
3199
+ missingMessage: (symbol) => `Attribute for credit symbol ${symbol} is required`,
3200
+ mismatchMessage: (symbol) => `Attribute for credit symbol ${symbol} must match credit.amount`
3201
+ });
3202
+ validateAttributesForItems({
3203
+ ctx,
3204
+ attributeByTraitType,
3205
+ items: data.collections,
3206
+ traitSelector: (collection) => String(collection.name),
3207
+ valueSelector: (collection) => Number(collection.amount),
3208
+ missingMessage: (name) => `Attribute for collection ${name} is required`,
3209
+ mismatchMessage: (name) => `Attribute for collection ${name} must match collection.amount`
3210
+ });
3211
+ }).meta(CreditRetirementReceiptIpfsSchemaMeta);
2579
3212
  var CollectionSchemaMeta = {
2580
3213
  title: "Collection IPFS Record",
2581
3214
  description: "Collection metadata stored in IPFS, extending the base schema with collection-specific fields required for NFT collection definitions in Carrot's ecosystem",
@@ -2782,11 +3415,19 @@ exports.CreditPurchaseReceiptAttributesSchema = CreditPurchaseReceiptAttributesS
2782
3415
  exports.CreditPurchaseReceiptDataSchema = CreditPurchaseReceiptDataSchema;
2783
3416
  exports.CreditPurchaseReceiptIpfsSchema = CreditPurchaseReceiptIpfsSchema;
2784
3417
  exports.CreditPurchaseReceiptIpfsSchemaMeta = CreditPurchaseReceiptIpfsSchemaMeta;
3418
+ exports.CreditPurchaseReceiptSummarySchema = CreditPurchaseReceiptSummarySchema;
3419
+ exports.CreditRetirementReceiptAttributesSchema = CreditRetirementReceiptAttributesSchema;
3420
+ exports.CreditRetirementReceiptDataSchema = CreditRetirementReceiptDataSchema;
3421
+ exports.CreditRetirementReceiptIpfsSchema = CreditRetirementReceiptIpfsSchema;
3422
+ exports.CreditRetirementReceiptIpfsSchemaMeta = CreditRetirementReceiptIpfsSchemaMeta;
3423
+ exports.CreditRetirementReceiptSummarySchema = CreditRetirementReceiptSummarySchema;
2785
3424
  exports.CreditSchema = CreditSchema;
2786
3425
  exports.CreditSchemaMeta = CreditSchemaMeta;
3426
+ exports.CreditTokenSymbolSchema = CreditTokenSymbolSchema;
2787
3427
  exports.CreditTypeAttributeSchema = CreditTypeAttributeSchema;
2788
3428
  exports.CreditTypeSchema = CreditTypeSchema;
2789
3429
  exports.DistributionNotesSchema = DistributionNotesSchema;
3430
+ exports.EPSILON = EPSILON;
2790
3431
  exports.EthereumAddressSchema = EthereumAddressSchema;
2791
3432
  exports.ExternalIdSchema = ExternalIdSchema;
2792
3433
  exports.ExternalUrlSchema = ExternalUrlSchema;
@@ -2817,6 +3458,7 @@ exports.MassIDIpfsSchemaMeta = MassIDIpfsSchemaMeta;
2817
3458
  exports.MassIDRecyclingDateAttributeSchema = MassIDRecyclingDateAttributeSchema;
2818
3459
  exports.MassIDReferenceSchema = MassIDReferenceSchema;
2819
3460
  exports.MassIDTokenIdAttributeSchema = MassIDTokenIdAttributeSchema;
3461
+ exports.MassIdReferenceWithContractSchema = MassIdReferenceWithContractSchema;
2820
3462
  exports.MethodologyAttributeSchema = MethodologyAttributeSchema;
2821
3463
  exports.MethodologyComplianceSchema = MethodologyComplianceSchema;
2822
3464
  exports.MethodologyDataSchema = MethodologyDataSchema;
@@ -2839,6 +3481,7 @@ exports.ParticipantRoleSchema = ParticipantRoleSchema;
2839
3481
  exports.ParticipantSchema = ParticipantSchema;
2840
3482
  exports.PercentageSchema = PercentageSchema;
2841
3483
  exports.PositiveIntegerSchema = PositiveIntegerSchema;
3484
+ exports.ReceiptIdentitySchema = ReceiptIdentitySchema;
2842
3485
  exports.RecordEnvironmentSchema = RecordEnvironmentSchema;
2843
3486
  exports.RecordRelationshipTypeSchema = RecordRelationshipTypeSchema;
2844
3487
  exports.RecordSchemaTypeSchema = RecordSchemaTypeSchema;
@@ -2865,9 +3508,20 @@ exports.WasteSubtypeSchema = WasteSubtypeSchema;
2865
3508
  exports.WasteTypeSchema = WasteTypeSchema;
2866
3509
  exports.WeightKgSchema = WeightKgSchema;
2867
3510
  exports.buildSchemaUrl = buildSchemaUrl;
3511
+ exports.createAttributeMap = createAttributeMap;
3512
+ exports.createReceiptCertificateSchema = createReceiptCertificateSchema;
3513
+ exports.createReceiptCollectionSchema = createReceiptCollectionSchema;
3514
+ exports.createReceiptCreditSchema = createReceiptCreditSchema;
2868
3515
  exports.getSchemaBaseUrl = getSchemaBaseUrl;
2869
3516
  exports.getSchemaVersionOrDefault = getSchemaVersionOrDefault;
3517
+ exports.nearlyEqual = nearlyEqual;
2870
3518
  exports.uniqueArrayItems = uniqueArrayItems;
2871
3519
  exports.uniqueBy = uniqueBy;
3520
+ exports.validateAttributeValue = validateAttributeValue;
3521
+ exports.validateAttributesForItems = validateAttributesForItems;
3522
+ exports.validateCountMatches = validateCountMatches;
3523
+ exports.validateDateAttribute = validateDateAttribute;
3524
+ exports.validateSummaryListMatchesData = validateSummaryListMatchesData;
3525
+ exports.validateTotalMatches = validateTotalMatches;
2872
3526
  //# sourceMappingURL=index.cjs.map
2873
3527
  //# sourceMappingURL=index.cjs.map