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