@carrot-foundation/schemas 0.5.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +88 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -103
- package/dist/index.d.ts +112 -103
- package/dist/index.js +88 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schemas/ipfs/collection/collection.example.json +3 -3
- package/schemas/ipfs/collection/collection.schema.json +4 -4
- package/schemas/ipfs/credit/credit.example.json +3 -3
- package/schemas/ipfs/credit/credit.schema.json +4 -4
- package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.example.json +8 -5
- package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.schema.json +34 -25
- package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.example.json +6 -5
- package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.schema.json +39 -24
- package/schemas/ipfs/gas-id/gas-id.example.json +4 -4
- package/schemas/ipfs/gas-id/gas-id.schema.json +7 -7
- package/schemas/ipfs/mass-id/mass-id.example.json +4 -4
- package/schemas/ipfs/mass-id/mass-id.schema.json +18 -18
- package/schemas/ipfs/mass-id-audit/mass-id-audit.example.json +3 -3
- package/schemas/ipfs/mass-id-audit/mass-id-audit.schema.json +4 -4
- package/schemas/ipfs/methodology/methodology.example.json +3 -3
- package/schemas/ipfs/methodology/methodology.schema.json +4 -4
- package/schemas/ipfs/recycled-id/recycled-id.example.json +4 -4
- package/schemas/ipfs/recycled-id/recycled-id.schema.json +7 -7
- package/schemas/schema-hashes.json +10 -10
package/dist/index.js
CHANGED
|
@@ -28136,12 +28136,11 @@ var StringifiedTokenIdSchema = NonEmptyStringSchema.regex(
|
|
|
28136
28136
|
examples: ["#456789", "#1000000"],
|
|
28137
28137
|
example: "#456789"
|
|
28138
28138
|
});
|
|
28139
|
-
var Sha256HashSchema = z.
|
|
28140
|
-
error: "Must be a
|
|
28139
|
+
var Sha256HashSchema = z.string().regex(/^[a-f0-9]{64}$/, {
|
|
28140
|
+
error: "Must be a SHA-256 hash as 32-byte lowercase hex string (no 0x prefix)"
|
|
28141
28141
|
}).meta({
|
|
28142
|
-
format: void 0,
|
|
28143
28142
|
title: "SHA-256 Hash",
|
|
28144
|
-
description: "SHA-256 cryptographic hash as hexadecimal string",
|
|
28143
|
+
description: "SHA-256 cryptographic hash as canonical lowercase hexadecimal string",
|
|
28145
28144
|
examples: [
|
|
28146
28145
|
"87f633634cc4b02f628685651f0a29b7bfa22a0bd841f725c6772dd00a58d489"
|
|
28147
28146
|
]
|
|
@@ -29383,9 +29382,9 @@ var CreditPurchaseReceiptSummarySchema = SummaryBaseSchema.safeExtend({
|
|
|
29383
29382
|
title: "Total Amount (USDC)",
|
|
29384
29383
|
description: "Total amount paid in USDC stablecoin for the credit purchase"
|
|
29385
29384
|
}),
|
|
29386
|
-
total_credits: CreditAmountSchema.meta({
|
|
29385
|
+
total_credits: CreditAmountSchema.gt(0).meta({
|
|
29387
29386
|
title: "Total Credits",
|
|
29388
|
-
description: "Total number of environmental impact credits purchased in this transaction"
|
|
29387
|
+
description: "Total number of environmental impact credits purchased in this transaction. Must be greater than 0."
|
|
29389
29388
|
}),
|
|
29390
29389
|
purchased_at: IsoDateTimeSchema.meta({
|
|
29391
29390
|
title: "Purchased At",
|
|
@@ -29396,9 +29395,9 @@ var CreditPurchaseReceiptSummarySchema = SummaryBaseSchema.safeExtend({
|
|
|
29396
29395
|
description: "Summary totals for the credit purchase including payment amount, credit quantity, certificate count, and timestamp"
|
|
29397
29396
|
});
|
|
29398
29397
|
var CreditRetirementReceiptSummarySchema = SummaryBaseSchema.safeExtend({
|
|
29399
|
-
total_credits_retired: CreditAmountSchema.meta({
|
|
29398
|
+
total_credits_retired: CreditAmountSchema.gt(0).meta({
|
|
29400
29399
|
title: "Total Credits Retired",
|
|
29401
|
-
description: "Total number of environmental impact credits permanently retired (removed from circulation)"
|
|
29400
|
+
description: "Total number of environmental impact credits permanently retired (removed from circulation). Must be greater than 0."
|
|
29402
29401
|
}),
|
|
29403
29402
|
retired_at: IsoDateTimeSchema.meta({
|
|
29404
29403
|
title: "Retired At",
|
|
@@ -29485,7 +29484,7 @@ function buildSchemaUrl(schemaPath) {
|
|
|
29485
29484
|
return `${getSchemaBaseUrl()}/${cleanPath}`;
|
|
29486
29485
|
}
|
|
29487
29486
|
function getSchemaVersionOrDefault() {
|
|
29488
|
-
return "0.
|
|
29487
|
+
return "2.0.0";
|
|
29489
29488
|
}
|
|
29490
29489
|
|
|
29491
29490
|
// src/shared/schema-validation.ts
|
|
@@ -31080,18 +31079,18 @@ var CreditPurchaseReceiptAttributesSchema = createOrderedAttributesSchema({
|
|
|
31080
31079
|
});
|
|
31081
31080
|
var CreditPurchaseReceiptIdentitySchema = ReceiptIdentitySchema;
|
|
31082
31081
|
var CreditPurchaseReceiptBuyerSchema = z.strictObject({
|
|
31083
|
-
|
|
31082
|
+
id_hash: Sha256HashSchema.meta({
|
|
31083
|
+
title: "Buyer ID Hash",
|
|
31084
|
+
description: "Anonymized pseudonymous identifier linking this buyer to off-chain records via a keyed hash"
|
|
31085
|
+
}),
|
|
31086
|
+
wallet_address: EthereumAddressSchema.optional().meta({
|
|
31084
31087
|
title: "Buyer Wallet Address",
|
|
31085
31088
|
description: "Ethereum address receiving the credits"
|
|
31086
31089
|
}),
|
|
31087
|
-
id: ExternalIdSchema.optional().meta({
|
|
31088
|
-
title: "Buyer ID",
|
|
31089
|
-
description: "Unique identifier for the buyer"
|
|
31090
|
-
}),
|
|
31091
31090
|
identity: CreditPurchaseReceiptIdentitySchema.optional()
|
|
31092
31091
|
}).meta({
|
|
31093
31092
|
title: "Buyer",
|
|
31094
|
-
description: "Buyer information including
|
|
31093
|
+
description: "Buyer information including hashed identifier, optional wallet address, and optional identity"
|
|
31095
31094
|
});
|
|
31096
31095
|
var CreditPurchaseReceiptCollectionSchema = createReceiptCollectionSchema({
|
|
31097
31096
|
meta: {
|
|
@@ -31107,13 +31106,17 @@ var CreditPurchaseReceiptCertificateSchema = CertificateReferenceBaseSchema.safe
|
|
|
31107
31106
|
credit_slug: CreditTokenSlugSchema.meta({
|
|
31108
31107
|
description: "Slug of the credit type for this certificate"
|
|
31109
31108
|
}),
|
|
31109
|
+
purchased_amount: CreditAmountSchema.meta({
|
|
31110
|
+
title: "Certificate Purchased Amount",
|
|
31111
|
+
description: "Total credits purchased from this certificate. Authoritative source for receipt totals; cross-checked against sum(collections[].purchased_amount) when collections are non-empty."
|
|
31112
|
+
}),
|
|
31110
31113
|
collections: uniqueBy(
|
|
31111
31114
|
CertificateCollectionItemPurchaseSchema,
|
|
31112
31115
|
(item) => item.slug,
|
|
31113
31116
|
"Collection slugs within certificate collections must be unique"
|
|
31114
|
-
).
|
|
31117
|
+
).meta({
|
|
31115
31118
|
title: "Certificate Collections",
|
|
31116
|
-
description: "Collections associated with this certificate, each with purchased and retired amounts"
|
|
31119
|
+
description: "Collections associated with this certificate, each with purchased and retired amounts. May be empty when this certificate is not assigned to any collection."
|
|
31117
31120
|
})
|
|
31118
31121
|
}).meta({
|
|
31119
31122
|
title: "Certificate",
|
|
@@ -31127,9 +31130,9 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31127
31130
|
CreditPurchaseReceiptCollectionSchema,
|
|
31128
31131
|
(collection) => collection.slug,
|
|
31129
31132
|
"Collection slugs must be unique"
|
|
31130
|
-
).
|
|
31133
|
+
).meta({
|
|
31131
31134
|
title: "Collections",
|
|
31132
|
-
description: "Impact collections referenced by this purchase, each identified by a unique slug"
|
|
31135
|
+
description: "Impact collections referenced by this purchase, each identified by a unique slug. May be empty when no certificate is assigned to a collection."
|
|
31133
31136
|
}),
|
|
31134
31137
|
credits: uniqueBy(
|
|
31135
31138
|
CreditPurchaseReceiptCreditSchema,
|
|
@@ -31159,12 +31162,10 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31159
31162
|
const collectionSlugs = new Set(
|
|
31160
31163
|
data.collections.map((collection) => String(collection.slug))
|
|
31161
31164
|
);
|
|
31165
|
+
const referencedCollectionSlugs = /* @__PURE__ */ new Set();
|
|
31162
31166
|
const creditSlugs = new Set(
|
|
31163
31167
|
data.credits.map((credit) => String(credit.slug))
|
|
31164
31168
|
);
|
|
31165
|
-
const creditPurchaseTotalsBySlug = /* @__PURE__ */ new Map();
|
|
31166
|
-
const creditRetiredTotalsBySlug = /* @__PURE__ */ new Map();
|
|
31167
|
-
const collectionPurchasedTotalsBySlug = /* @__PURE__ */ new Map();
|
|
31168
31169
|
const collectionRetiredTotalsBySlug = /* @__PURE__ */ new Map();
|
|
31169
31170
|
let totalCreditsFromCertificates = 0;
|
|
31170
31171
|
data.certificates.forEach((certificate, index) => {
|
|
@@ -31175,7 +31176,6 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31175
31176
|
path: ["certificates", index, "credit_slug"]
|
|
31176
31177
|
});
|
|
31177
31178
|
let certificatePurchasedTotal = 0;
|
|
31178
|
-
let certificateRetiredTotal = 0;
|
|
31179
31179
|
validateCertificateCollectionSlugs({
|
|
31180
31180
|
ctx,
|
|
31181
31181
|
certificateCollections: certificate.collections,
|
|
@@ -31183,6 +31183,7 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31183
31183
|
certificateIndex: index
|
|
31184
31184
|
});
|
|
31185
31185
|
certificate.collections.forEach((collectionItem, collectionIndex) => {
|
|
31186
|
+
referencedCollectionSlugs.add(String(collectionItem.slug));
|
|
31186
31187
|
if (collectionItem.retired_amount > collectionItem.purchased_amount) {
|
|
31187
31188
|
ctx.addIssue({
|
|
31188
31189
|
code: "custom",
|
|
@@ -31197,42 +31198,45 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31197
31198
|
});
|
|
31198
31199
|
}
|
|
31199
31200
|
certificatePurchasedTotal += Number(collectionItem.purchased_amount);
|
|
31200
|
-
certificateRetiredTotal += Number(collectionItem.retired_amount);
|
|
31201
|
-
collectionPurchasedTotalsBySlug.set(
|
|
31202
|
-
collectionItem.slug,
|
|
31203
|
-
(collectionPurchasedTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.purchased_amount)
|
|
31204
|
-
);
|
|
31205
31201
|
collectionRetiredTotalsBySlug.set(
|
|
31206
31202
|
collectionItem.slug,
|
|
31207
31203
|
(collectionRetiredTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.retired_amount)
|
|
31208
31204
|
);
|
|
31209
31205
|
});
|
|
31210
|
-
if (
|
|
31206
|
+
if (certificate.purchased_amount > certificate.total_amount) {
|
|
31211
31207
|
ctx.addIssue({
|
|
31212
31208
|
code: "custom",
|
|
31213
|
-
message: "
|
|
31214
|
-
path: ["certificates", index]
|
|
31209
|
+
message: "certificate.purchased_amount cannot exceed certificate.total_amount",
|
|
31210
|
+
path: ["certificates", index, "purchased_amount"]
|
|
31215
31211
|
});
|
|
31216
31212
|
}
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
31223
|
-
|
|
31224
|
-
|
|
31225
|
-
);
|
|
31213
|
+
if (certificate.collections.length > 0 && !nearlyEqual(certificatePurchasedTotal, certificate.purchased_amount)) {
|
|
31214
|
+
ctx.addIssue({
|
|
31215
|
+
code: "custom",
|
|
31216
|
+
message: "certificate.purchased_amount must equal sum of collections[].purchased_amount when collections are present",
|
|
31217
|
+
path: ["certificates", index, "purchased_amount"]
|
|
31218
|
+
});
|
|
31219
|
+
}
|
|
31220
|
+
totalCreditsFromCertificates += Number(certificate.purchased_amount);
|
|
31226
31221
|
});
|
|
31227
31222
|
const certificateCollectionRetiredTotal = Array.from(
|
|
31228
31223
|
collectionRetiredTotalsBySlug.values()
|
|
31229
31224
|
).reduce((sum, amount) => sum + amount, 0);
|
|
31225
|
+
data.collections.forEach((collection, collectionIndex) => {
|
|
31226
|
+
if (!referencedCollectionSlugs.has(String(collection.slug))) {
|
|
31227
|
+
ctx.addIssue({
|
|
31228
|
+
code: "custom",
|
|
31229
|
+
message: "collections must only include slugs referenced by certificates[].collections",
|
|
31230
|
+
path: ["collections", collectionIndex, "slug"]
|
|
31231
|
+
});
|
|
31232
|
+
}
|
|
31233
|
+
});
|
|
31230
31234
|
validateTotalMatches({
|
|
31231
31235
|
ctx,
|
|
31232
31236
|
actualTotal: totalCreditsFromCertificates,
|
|
31233
31237
|
expectedTotal: data.summary.total_credits,
|
|
31234
31238
|
path: ["summary", "total_credits"],
|
|
31235
|
-
message: "summary.total_credits must equal sum of
|
|
31239
|
+
message: "summary.total_credits must equal sum of certificates[].purchased_amount"
|
|
31236
31240
|
});
|
|
31237
31241
|
validateRetirementReceiptRequirement({
|
|
31238
31242
|
ctx,
|
|
@@ -31245,7 +31249,7 @@ var CreditPurchaseReceiptDataSchema = z.strictObject({
|
|
|
31245
31249
|
});
|
|
31246
31250
|
var CreditPurchaseReceiptIpfsSchemaMeta = {
|
|
31247
31251
|
title: "CreditPurchaseReceipt NFT IPFS Record",
|
|
31248
|
-
description: "Complete CreditPurchaseReceipt NFT IPFS record including purchase summary, buyer details, credit breakdowns, certificate allocations, and NFT display attributes",
|
|
31252
|
+
description: "Complete CreditPurchaseReceipt NFT IPFS record including purchase summary, buyer details, credit breakdowns, certificate allocations, and NFT display attributes. Supports both collection-assigned and no-collection variants.",
|
|
31249
31253
|
$id: buildSchemaUrl(
|
|
31250
31254
|
"credit-purchase-receipt/credit-purchase-receipt.schema.json"
|
|
31251
31255
|
),
|
|
@@ -31383,14 +31387,10 @@ var CreditPurchaseReceiptIpfsSchema = NftIpfsSchema.safeExtend({
|
|
|
31383
31387
|
});
|
|
31384
31388
|
return;
|
|
31385
31389
|
}
|
|
31386
|
-
const certificatePurchasedTotal = certificate.collections.reduce(
|
|
31387
|
-
(sum, collection) => sum + Number(collection.purchased_amount),
|
|
31388
|
-
0
|
|
31389
|
-
);
|
|
31390
31390
|
const currentTotal = creditTotalsBySymbol.get(credit.symbol) ?? 0;
|
|
31391
31391
|
creditTotalsBySymbol.set(
|
|
31392
31392
|
credit.symbol,
|
|
31393
|
-
currentTotal +
|
|
31393
|
+
currentTotal + Number(certificate.purchased_amount)
|
|
31394
31394
|
);
|
|
31395
31395
|
});
|
|
31396
31396
|
data.credits.forEach((credit) => {
|
|
@@ -31405,7 +31405,7 @@ var CreditPurchaseReceiptIpfsSchema = NftIpfsSchema.safeExtend({
|
|
|
31405
31405
|
} else if (Number(attribute.value) !== expectedTotal) {
|
|
31406
31406
|
ctx.addIssue({
|
|
31407
31407
|
code: "custom",
|
|
31408
|
-
message: `Attribute for credit symbol ${credit.symbol} must match sum of
|
|
31408
|
+
message: `Attribute for credit symbol ${credit.symbol} must match sum of certificates[].purchased_amount for the credit symbol`,
|
|
31409
31409
|
path: ["attributes"]
|
|
31410
31410
|
});
|
|
31411
31411
|
}
|
|
@@ -31507,24 +31507,32 @@ var CreditRetirementReceiptAttributesSchema = createOrderedAttributesSchema({
|
|
|
31507
31507
|
});
|
|
31508
31508
|
var CreditRetirementReceiptIdentitySchema = ReceiptIdentitySchema;
|
|
31509
31509
|
var CreditRetirementReceiptBeneficiarySchema = z.strictObject({
|
|
31510
|
-
|
|
31511
|
-
title: "
|
|
31512
|
-
description: "
|
|
31510
|
+
id_hash: Sha256HashSchema.meta({
|
|
31511
|
+
title: "Beneficiary ID Hash",
|
|
31512
|
+
description: "Anonymized pseudonymous identifier linking this beneficiary to off-chain records via a keyed hash"
|
|
31513
|
+
}),
|
|
31514
|
+
wallet_address: EthereumAddressSchema.optional().meta({
|
|
31515
|
+
title: "Beneficiary Wallet Address",
|
|
31516
|
+
description: "Ethereum address associated with the beneficiary, when available"
|
|
31513
31517
|
}),
|
|
31514
31518
|
identity: CreditRetirementReceiptIdentitySchema.optional()
|
|
31515
31519
|
}).meta({
|
|
31516
31520
|
title: "Beneficiary",
|
|
31517
|
-
description: "Beneficiary receiving the retirement benefit"
|
|
31521
|
+
description: "Beneficiary receiving the retirement benefit, identified by a hashed identifier with optional wallet address and identity"
|
|
31518
31522
|
});
|
|
31519
31523
|
var CreditRetirementReceiptCreditHolderSchema = z.strictObject({
|
|
31520
|
-
|
|
31524
|
+
id_hash: Sha256HashSchema.meta({
|
|
31525
|
+
title: "Credit Holder ID Hash",
|
|
31526
|
+
description: "Anonymized pseudonymous identifier linking this credit holder to off-chain records via a keyed hash"
|
|
31527
|
+
}),
|
|
31528
|
+
wallet_address: EthereumAddressSchema.optional().meta({
|
|
31521
31529
|
title: "Credit Holder Wallet Address",
|
|
31522
31530
|
description: "Ethereum address of the wallet that held and surrendered the credits"
|
|
31523
31531
|
}),
|
|
31524
31532
|
identity: CreditRetirementReceiptIdentitySchema.optional()
|
|
31525
31533
|
}).meta({
|
|
31526
31534
|
title: "Credit Holder",
|
|
31527
|
-
description: "Credit holder wallet and optional identity
|
|
31535
|
+
description: "Credit holder information including hashed identifier, optional wallet address, and optional identity"
|
|
31528
31536
|
});
|
|
31529
31537
|
var CreditRetirementReceiptCollectionSchema = createReceiptCollectionSchema({
|
|
31530
31538
|
meta: {
|
|
@@ -31564,9 +31572,9 @@ var CreditRetirementReceiptCertificateSchema = CertificateReferenceBaseSchema.sa
|
|
|
31564
31572
|
CertificateCollectionItemRetirementSchema,
|
|
31565
31573
|
(item) => item.slug,
|
|
31566
31574
|
"Collection slugs within certificate collections must be unique"
|
|
31567
|
-
).
|
|
31575
|
+
).meta({
|
|
31568
31576
|
title: "Certificate Collections",
|
|
31569
|
-
description: "Collections associated with this certificate, each with retired amounts"
|
|
31577
|
+
description: "Collections associated with this certificate, each with retired amounts. May be empty when this certificate is not assigned to any collection."
|
|
31570
31578
|
}),
|
|
31571
31579
|
credits_retired: uniqueBy(
|
|
31572
31580
|
CreditRetirementReceiptCertificateCreditSchema,
|
|
@@ -31588,9 +31596,9 @@ var CreditRetirementReceiptDataSchema = z.strictObject({
|
|
|
31588
31596
|
CreditRetirementReceiptCollectionSchema,
|
|
31589
31597
|
(collection) => collection.slug,
|
|
31590
31598
|
"Collection slugs must be unique"
|
|
31591
|
-
).
|
|
31599
|
+
).meta({
|
|
31592
31600
|
title: "Collections",
|
|
31593
|
-
description: "Impact collections referenced by this retirement, each identified by a unique slug"
|
|
31601
|
+
description: "Impact collections referenced by this retirement, each identified by a unique slug. May be empty when no certificate is assigned to a collection."
|
|
31594
31602
|
}),
|
|
31595
31603
|
credits: uniqueBy(
|
|
31596
31604
|
CreditRetirementReceiptCreditSchema,
|
|
@@ -31644,6 +31652,17 @@ var CreditRetirementReceiptDataSchema = z.strictObject({
|
|
|
31644
31652
|
path: ["certificates", index]
|
|
31645
31653
|
});
|
|
31646
31654
|
}
|
|
31655
|
+
const creditsRetiredTotal = certificate.credits_retired.reduce(
|
|
31656
|
+
(sum, credit) => sum + Number(credit.amount),
|
|
31657
|
+
0
|
|
31658
|
+
);
|
|
31659
|
+
if (creditsRetiredTotal > certificate.total_amount) {
|
|
31660
|
+
ctx.addIssue({
|
|
31661
|
+
code: "custom",
|
|
31662
|
+
message: "Sum of certificate.credits_retired[].amount cannot exceed certificate.total_amount",
|
|
31663
|
+
path: ["certificates", index, "credits_retired"]
|
|
31664
|
+
});
|
|
31665
|
+
}
|
|
31647
31666
|
validateCertificateCollectionSlugs({
|
|
31648
31667
|
ctx,
|
|
31649
31668
|
certificateCollections: certificate.collections,
|
|
@@ -31656,11 +31675,7 @@ var CreditRetirementReceiptDataSchema = z.strictObject({
|
|
|
31656
31675
|
(collectionRetiredTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.retired_amount)
|
|
31657
31676
|
);
|
|
31658
31677
|
});
|
|
31659
|
-
|
|
31660
|
-
(sum, credit) => sum + Number(credit.amount),
|
|
31661
|
-
0
|
|
31662
|
-
);
|
|
31663
|
-
if (!nearlyEqual(creditsRetiredTotal, certificateCollectionRetiredTotal)) {
|
|
31678
|
+
if (certificate.collections.length > 0 && !nearlyEqual(creditsRetiredTotal, certificateCollectionRetiredTotal)) {
|
|
31664
31679
|
ctx.addIssue({
|
|
31665
31680
|
code: "custom",
|
|
31666
31681
|
message: "certificates.credits_retired amounts must sum to certificate.collections[].retired_amount",
|
|
@@ -31711,27 +31726,29 @@ var CreditRetirementReceiptDataSchema = z.strictObject({
|
|
|
31711
31726
|
(creditTotalsBySymbol.get(credit.credit_symbol) ?? 0) + credit.amount
|
|
31712
31727
|
);
|
|
31713
31728
|
});
|
|
31714
|
-
totalRetiredFromCertificates +=
|
|
31729
|
+
totalRetiredFromCertificates += creditsRetiredTotal;
|
|
31715
31730
|
});
|
|
31716
31731
|
validateTotalMatches({
|
|
31717
31732
|
ctx,
|
|
31718
31733
|
actualTotal: totalRetiredFromCertificates,
|
|
31719
31734
|
expectedTotal: data.summary.total_credits_retired,
|
|
31720
31735
|
path: ["summary", "total_credits_retired"],
|
|
31721
|
-
message: "summary.total_credits_retired must equal sum of
|
|
31722
|
-
});
|
|
31723
|
-
validateCollectionsHaveRetiredAmounts({
|
|
31724
|
-
ctx,
|
|
31725
|
-
collections: data.collections,
|
|
31726
|
-
retiredTotalsBySlug: collectionRetiredTotalsBySlug
|
|
31736
|
+
message: "summary.total_credits_retired must equal sum of certificates[].credits_retired[].amount"
|
|
31727
31737
|
});
|
|
31738
|
+
if (data.collections.length > 0) {
|
|
31739
|
+
validateCollectionsHaveRetiredAmounts({
|
|
31740
|
+
ctx,
|
|
31741
|
+
collections: data.collections,
|
|
31742
|
+
retiredTotalsBySlug: collectionRetiredTotalsBySlug
|
|
31743
|
+
});
|
|
31744
|
+
}
|
|
31728
31745
|
}).meta({
|
|
31729
31746
|
title: "Credit Retirement Receipt Data",
|
|
31730
31747
|
description: "Complete data structure for a credit retirement receipt"
|
|
31731
31748
|
});
|
|
31732
31749
|
var CreditRetirementReceiptIpfsSchemaMeta = {
|
|
31733
31750
|
title: "CreditRetirementReceipt NFT IPFS Record",
|
|
31734
|
-
description: "Complete CreditRetirementReceipt NFT IPFS record including retirement summary, beneficiary and credit holder details (identity optional), credit breakdowns, certificate allocations, and NFT display attributes",
|
|
31751
|
+
description: "Complete CreditRetirementReceipt NFT IPFS record including retirement summary, beneficiary and credit holder details (identity optional), credit breakdowns, certificate allocations, and NFT display attributes. Supports both collection-assigned and no-collection variants.",
|
|
31735
31752
|
$id: buildSchemaUrl(
|
|
31736
31753
|
"credit-retirement-receipt/credit-retirement-receipt.schema.json"
|
|
31737
31754
|
),
|