@carrot-foundation/schemas 0.1.56 → 0.1.57

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.
Files changed (26) hide show
  1. package/dist/index.cjs +514 -522
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +2007 -2255
  4. package/dist/index.d.ts +2007 -2255
  5. package/dist/index.js +507 -522
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/schemas/ipfs/collection/collection.example.json +5 -5
  9. package/schemas/ipfs/collection/collection.schema.json +2 -2
  10. package/schemas/ipfs/credit/credit.example.json +5 -5
  11. package/schemas/ipfs/credit/credit.schema.json +2 -2
  12. package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.example.json +72 -128
  13. package/schemas/ipfs/credit-purchase-receipt/credit-purchase-receipt.schema.json +268 -594
  14. package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.example.json +54 -102
  15. package/schemas/ipfs/credit-retirement-receipt/credit-retirement-receipt.schema.json +163 -369
  16. package/schemas/ipfs/gas-id/gas-id.example.json +5 -5
  17. package/schemas/ipfs/gas-id/gas-id.schema.json +2 -2
  18. package/schemas/ipfs/mass-id/mass-id.example.json +5 -5
  19. package/schemas/ipfs/mass-id/mass-id.schema.json +2 -2
  20. package/schemas/ipfs/mass-id-audit/mass-id-audit.example.json +5 -5
  21. package/schemas/ipfs/mass-id-audit/mass-id-audit.schema.json +2 -2
  22. package/schemas/ipfs/methodology/methodology.example.json +5 -5
  23. package/schemas/ipfs/methodology/methodology.schema.json +2 -2
  24. package/schemas/ipfs/recycled-id/recycled-id.example.json +5 -5
  25. package/schemas/ipfs/recycled-id/recycled-id.schema.json +2 -2
  26. package/schemas/schema-hashes.json +10 -10
package/dist/index.cjs CHANGED
@@ -29271,54 +29271,33 @@ var SummaryBaseSchema = zod.z.strictObject({
29271
29271
  total_certificates: PositiveIntegerSchema.meta({
29272
29272
  title: "Total Certificates",
29273
29273
  description: "Total number of certificates represented in the receipt"
29274
- }),
29275
- credit_symbols: uniqueArrayItems(
29276
- CreditTokenSymbolSchema,
29277
- "Credit symbols must be unique"
29278
- ).min(1).meta({
29279
- title: "Credit Symbols",
29280
- description: "Array of credit token symbols represented in the receipt"
29281
- }),
29282
- certificate_types: uniqueArrayItems(
29283
- RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]),
29284
- "Certificate types must be unique"
29285
- ).min(1).meta({
29286
- title: "Certificate Types",
29287
- description: "Array of certificate types represented in the receipt"
29288
- }),
29289
- collection_slugs: uniqueArrayItems(
29290
- CollectionSlugSchema,
29291
- "Collection slugs must be unique"
29292
- ).min(1).meta({
29293
- title: "Collection Slugs",
29294
- description: "Array of collection slugs represented in the receipt"
29295
29274
  })
29296
29275
  });
29297
29276
  var CreditPurchaseReceiptSummarySchema = SummaryBaseSchema.extend({
29298
- total_usdc_amount: NonNegativeFloatSchema.meta({
29299
- title: "Total USDC Amount",
29277
+ total_amount_usdc: NonNegativeFloatSchema.meta({
29278
+ title: "Total Amount (USDC)",
29300
29279
  description: "Total amount paid in USDC for the purchase"
29301
29280
  }),
29302
29281
  total_credits: CreditAmountSchema.meta({
29303
29282
  title: "Total Credits",
29304
29283
  description: "Total amount of credits purchased"
29305
29284
  }),
29306
- purchase_date: IsoDateSchema.meta({
29307
- title: "Purchase Date",
29308
- description: "Date when the purchase was made (YYYY-MM-DD)"
29285
+ purchased_at: IsoDateTimeSchema.meta({
29286
+ title: "Purchased At",
29287
+ description: "ISO 8601 timestamp when the purchase was completed"
29309
29288
  })
29310
29289
  }).meta({
29311
29290
  title: "Credit Purchase Receipt Summary",
29312
29291
  description: "Summary totals for the credit purchase including amounts and collections represented"
29313
29292
  });
29314
29293
  var CreditRetirementReceiptSummarySchema = SummaryBaseSchema.extend({
29315
- total_retirement_amount: CreditAmountSchema.meta({
29316
- title: "Total Retirement Amount",
29294
+ total_credits_retired: CreditAmountSchema.meta({
29295
+ title: "Total Credits Retired",
29317
29296
  description: "Total amount of credits retired"
29318
29297
  }),
29319
- retirement_date: IsoDateSchema.meta({
29320
- title: "Retirement Date",
29321
- description: "Date when the retirement occurred (YYYY-MM-DD)"
29298
+ retired_at: IsoDateTimeSchema.meta({
29299
+ title: "Retired At",
29300
+ description: "ISO 8601 timestamp when the retirement occurred"
29322
29301
  })
29323
29302
  }).meta({
29324
29303
  title: "Credit Retirement Receipt Summary",
@@ -29342,14 +29321,17 @@ var ReceiptIdentitySchema = zod.z.strictObject({
29342
29321
  title: "Identity",
29343
29322
  description: "Participant identity information"
29344
29323
  });
29345
- var MassIdReferenceWithContractSchema = MassIDReferenceSchema.safeExtend({
29346
- smart_contract: SmartContractSchema
29324
+ var MassIDReferenceWithContractSchema = MassIDReferenceSchema.safeExtend({
29325
+ smart_contract_address: EthereumAddressSchema.meta({
29326
+ title: "Smart Contract Address",
29327
+ description: "Ethereum address of the smart contract"
29328
+ })
29347
29329
  }).meta({
29348
29330
  title: "MassID Reference with Smart Contract",
29349
- description: "Reference to a MassID record including smart contract details"
29331
+ description: "Reference to a MassID record with smart contract address"
29350
29332
  });
29351
29333
  function createReceiptCollectionSchema(params) {
29352
- const { amountKey, amountMeta, meta } = params;
29334
+ const { meta } = params;
29353
29335
  return zod.z.strictObject({
29354
29336
  slug: CollectionSlugSchema,
29355
29337
  external_id: ExternalIdSchema.meta({
@@ -29361,16 +29343,19 @@ function createReceiptCollectionSchema(params) {
29361
29343
  title: "Collection External URL",
29362
29344
  description: "External URL for the collection"
29363
29345
  }),
29364
- uri: IpfsUriSchema.meta({
29365
- title: "Collection URI",
29346
+ ipfs_uri: IpfsUriSchema.meta({
29347
+ title: "Collection IPFS URI",
29366
29348
  description: "IPFS URI for the collection metadata"
29367
29349
  }),
29368
- [amountKey]: CreditAmountSchema.meta(amountMeta)
29350
+ smart_contract_address: EthereumAddressSchema.meta({
29351
+ title: "Smart Contract Address",
29352
+ description: "Ethereum address of the smart contract"
29353
+ })
29369
29354
  }).meta(meta);
29370
29355
  }
29371
29356
  function createReceiptCreditSchema(params) {
29372
- const { amountKey, amountMeta, meta, retirementAmountMeta } = params;
29373
- const creditShape = {
29357
+ const { meta } = params;
29358
+ return zod.z.strictObject({
29374
29359
  slug: SlugSchema.meta({
29375
29360
  title: "Credit Slug",
29376
29361
  description: "URL-friendly identifier for the credit"
@@ -29387,24 +29372,52 @@ function createReceiptCreditSchema(params) {
29387
29372
  title: "Credit External URL",
29388
29373
  description: "External URL for the credit"
29389
29374
  }),
29390
- uri: IpfsUriSchema.meta({
29391
- title: "Credit URI",
29375
+ ipfs_uri: IpfsUriSchema.meta({
29376
+ title: "Credit IPFS URI",
29392
29377
  description: "IPFS URI for the credit details"
29393
29378
  }),
29394
- smart_contract: SmartContractSchema,
29395
- [amountKey]: CreditAmountSchema.meta(amountMeta)
29396
- };
29397
- if (retirementAmountMeta) {
29398
- creditShape.retirement_amount = CreditAmountSchema.optional().meta(retirementAmountMeta);
29399
- }
29400
- return zod.z.strictObject(creditShape).meta(meta);
29379
+ smart_contract_address: EthereumAddressSchema.meta({
29380
+ title: "Smart Contract Address",
29381
+ description: "Ethereum address of the smart contract"
29382
+ })
29383
+ }).meta(meta);
29401
29384
  }
29385
+ var CertificateCollectionItemPurchaseSchema = zod.z.strictObject({
29386
+ slug: CollectionSlugSchema.meta({
29387
+ title: "Collection Slug",
29388
+ description: "Slug of the collection"
29389
+ }),
29390
+ purchased_amount: CreditAmountSchema.meta({
29391
+ title: "Collection Purchased Amount",
29392
+ description: "Credits purchased from this collection for this certificate"
29393
+ }),
29394
+ retired_amount: CreditAmountSchema.meta({
29395
+ title: "Collection Retired Amount",
29396
+ description: "Credits retired from this collection for this certificate (0 if none)"
29397
+ })
29398
+ }).meta({
29399
+ title: "Certificate Collection Item (Purchase)",
29400
+ description: "Collection reference with purchased and retired amounts for a certificate in a purchase receipt"
29401
+ });
29402
+ var CertificateCollectionItemRetirementSchema = zod.z.strictObject({
29403
+ slug: CollectionSlugSchema.meta({
29404
+ title: "Collection Slug",
29405
+ description: "Slug of the collection"
29406
+ }),
29407
+ retired_amount: CreditAmountSchema.meta({
29408
+ title: "Collection Retired Amount",
29409
+ description: "Credits retired from this collection for this certificate"
29410
+ })
29411
+ }).meta({
29412
+ title: "Certificate Collection Item (Retirement)",
29413
+ description: "Collection reference with retired amount for a certificate in a retirement receipt"
29414
+ });
29402
29415
  var certificateBaseShape = {
29403
29416
  token_id: TokenIdSchema.meta({
29404
29417
  title: "Certificate Token ID",
29405
29418
  description: "Token ID of the certificate"
29406
29419
  }),
29407
- type: RecordSchemaTypeSchema.extract(["GasID", "RecycledID"]).meta({
29420
+ type: zod.z.enum(["GasID", "RecycledID"]).meta({
29408
29421
  title: "Certificate Type",
29409
29422
  description: "Type of certificate (e.g., GasID, RecycledID)"
29410
29423
  }),
@@ -29416,20 +29429,19 @@ var certificateBaseShape = {
29416
29429
  title: "Certificate External URL",
29417
29430
  description: "External URL for the certificate"
29418
29431
  }),
29419
- uri: IpfsUriSchema.meta({
29420
- title: "Certificate URI",
29432
+ ipfs_uri: IpfsUriSchema.meta({
29433
+ title: "Certificate IPFS URI",
29421
29434
  description: "IPFS URI for the certificate metadata"
29422
29435
  }),
29423
- smart_contract: SmartContractSchema,
29424
- collection_slug: CollectionSlugSchema.meta({
29425
- title: "Collection Slug",
29426
- description: "Slug of the collection this certificate belongs to"
29436
+ smart_contract_address: EthereumAddressSchema.meta({
29437
+ title: "Smart Contract Address",
29438
+ description: "Ethereum address of the smart contract"
29427
29439
  }),
29428
29440
  total_amount: CreditAmountSchema.meta({
29429
29441
  title: "Certificate Total Amount",
29430
29442
  description: "Total credits available in this certificate"
29431
29443
  }),
29432
- mass_id: MassIdReferenceWithContractSchema
29444
+ mass_id: MassIDReferenceWithContractSchema
29433
29445
  };
29434
29446
  function createReceiptCertificateSchema(params) {
29435
29447
  return zod.z.strictObject({
@@ -29445,7 +29457,7 @@ function buildSchemaUrl(schemaPath) {
29445
29457
  return `${getSchemaBaseUrl()}/${cleanPath}`;
29446
29458
  }
29447
29459
  function getSchemaVersionOrDefault() {
29448
- return "0.1.56";
29460
+ return "0.1.57";
29449
29461
  }
29450
29462
 
29451
29463
  // src/shared/schema-validation.ts
@@ -29601,6 +29613,104 @@ function validateAttributesForItems(params) {
29601
29613
  }
29602
29614
  });
29603
29615
  }
29616
+ function validateCertificateCollectionSlugs(params) {
29617
+ const {
29618
+ ctx,
29619
+ certificateCollections,
29620
+ validCollectionSlugs,
29621
+ certificateIndex,
29622
+ message = "certificate.collections[].slug must match a collection slug in collections"
29623
+ } = params;
29624
+ certificateCollections.forEach((collectionItem, collectionIndex) => {
29625
+ if (!validCollectionSlugs.has(collectionItem.slug)) {
29626
+ ctx.addIssue({
29627
+ code: "custom",
29628
+ message,
29629
+ path: [
29630
+ "certificates",
29631
+ certificateIndex,
29632
+ "collections",
29633
+ collectionIndex,
29634
+ "slug"
29635
+ ]
29636
+ });
29637
+ }
29638
+ });
29639
+ }
29640
+ function validateRetirementReceiptRequirement(params) {
29641
+ const {
29642
+ ctx,
29643
+ hasRetirementReceipt,
29644
+ totalRetiredAmount,
29645
+ messageWhenPresentButNoRetired = "retirement_receipt is present but no certificate has retired_amount greater than 0",
29646
+ messageWhenRetiredButNotPresent = "certificates with retired amounts > 0 require retirement_receipt"
29647
+ } = params;
29648
+ if (hasRetirementReceipt) {
29649
+ if (totalRetiredAmount === 0) {
29650
+ ctx.addIssue({
29651
+ code: "custom",
29652
+ message: messageWhenPresentButNoRetired,
29653
+ path: ["retirement_receipt"]
29654
+ });
29655
+ }
29656
+ } else if (totalRetiredAmount > 0) {
29657
+ ctx.addIssue({
29658
+ code: "custom",
29659
+ message: messageWhenRetiredButNotPresent,
29660
+ path: ["retirement_receipt"]
29661
+ });
29662
+ }
29663
+ }
29664
+ function validateCollectionsHaveRetiredAmounts(params) {
29665
+ const {
29666
+ ctx,
29667
+ collections,
29668
+ retiredTotalsBySlug,
29669
+ message = "collection must be referenced by at least one certificate with retired amounts > 0"
29670
+ } = params;
29671
+ collections.forEach((collection, index) => {
29672
+ const retiredTotal = retiredTotalsBySlug.get(String(collection.slug)) ?? 0;
29673
+ if (retiredTotal === 0) {
29674
+ ctx.addIssue({
29675
+ code: "custom",
29676
+ message,
29677
+ path: ["collections", index, "slug"]
29678
+ });
29679
+ }
29680
+ });
29681
+ }
29682
+ function validateCreditSlugExists(params) {
29683
+ const {
29684
+ ctx,
29685
+ creditSlug,
29686
+ validCreditSlugs,
29687
+ path,
29688
+ message = "credit_slug must match a credit slug in credits"
29689
+ } = params;
29690
+ if (!validCreditSlugs.has(creditSlug)) {
29691
+ ctx.addIssue({
29692
+ code: "custom",
29693
+ message,
29694
+ path
29695
+ });
29696
+ }
29697
+ }
29698
+ function validateCreditSymbolExists(params) {
29699
+ const {
29700
+ ctx,
29701
+ creditSymbol,
29702
+ validCreditSymbols,
29703
+ path,
29704
+ message = "credit_symbol must match a credit symbol in credits"
29705
+ } = params;
29706
+ if (!validCreditSymbols.has(creditSymbol)) {
29707
+ ctx.addIssue({
29708
+ code: "custom",
29709
+ message,
29710
+ path
29711
+ });
29712
+ }
29713
+ }
29604
29714
  function canonicalizeForHash(value) {
29605
29715
  const canonical = canonicalize__default.default(value);
29606
29716
  if (canonical === void 0) {
@@ -30382,9 +30492,9 @@ var CreditPurchaseReceiptTotalCreditsAttributeSchema = createNumericAttributeSch
30382
30492
  description: "Total number of credits purchased across all tokens",
30383
30493
  valueSchema: CreditAmountSchema
30384
30494
  });
30385
- var CreditPurchaseReceiptTotalUsdcAttributeSchema = createNumericAttributeSchema({
30386
- traitType: "Total USDC Amount",
30387
- title: "Total USDC Amount",
30495
+ var CreditPurchaseReceiptPurchasePriceAttributeSchema = createNumericAttributeSchema({
30496
+ traitType: "Total Amount (USDC)",
30497
+ title: "Total Amount (USDC)",
30388
30498
  description: "Total USDC amount paid for the purchase",
30389
30499
  valueSchema: CreditAmountSchema
30390
30500
  });
@@ -30399,43 +30509,48 @@ var CreditPurchaseReceiptCertificatesAttributeSchema = createNumericAttributeSch
30399
30509
  description: "Total number of certificates purchased",
30400
30510
  valueSchema: PositiveIntegerSchema
30401
30511
  });
30402
- var CreditPurchaseReceiptReceiverAttributeSchema = NftAttributeSchema.omit({
30512
+ var CreditPurchaseReceiptBuyerAttributeSchema = NftAttributeSchema.omit({
30403
30513
  display_type: true,
30404
30514
  max_value: true
30405
30515
  }).safeExtend({
30406
- trait_type: zod.z.literal("Receiver"),
30516
+ trait_type: zod.z.literal("Buyer"),
30407
30517
  value: NonEmptyStringSchema.max(100).meta({
30408
- title: "Receiver",
30409
- description: "Organization or individual receiving the credits from the purchase",
30518
+ title: "Buyer",
30519
+ description: "Organization or individual purchasing the credits",
30410
30520
  examples: ["EcoTech Solutions Inc."]
30411
30521
  })
30412
30522
  }).meta({
30413
- title: "Receiver Attribute",
30414
- description: "Attribute containing the receiver display name"
30523
+ title: "Buyer Attribute",
30524
+ description: "Attribute containing the buyer display name"
30415
30525
  });
30416
- var CreditPurchaseReceiptCollectionAttributeSchema = NftAttributeSchema.safeExtend({
30417
- trait_type: CollectionNameSchema,
30418
- value: CreditAmountSchema.meta({
30419
- title: "Credits from Collection",
30420
- description: "Amount of credits purchased from the collection"
30421
- }),
30422
- display_type: zod.z.literal("number")
30526
+ var CreditPurchaseReceiptRetirementDateAttributeSchema = createDateAttributeSchema({
30527
+ traitType: "Retirement Date",
30528
+ title: "Retirement Date",
30529
+ description: "Unix timestamp in milliseconds when credits were retired (if retirement occurred)"
30530
+ });
30531
+ var CreditPurchaseReceiptRetirementReceiptAttributeSchema = NftAttributeSchema.safeExtend({
30532
+ trait_type: zod.z.literal("Retirement Receipt"),
30533
+ value: StringifiedTokenIdSchema.meta({
30534
+ title: "Retirement Receipt Token ID",
30535
+ description: "Token ID of the retirement receipt NFT as #<token_id> (if retirement occurred)"
30536
+ })
30423
30537
  }).meta({
30424
- title: "Collection Attribute",
30425
- description: "Attribute representing the amount of credits purchased from a collection"
30538
+ title: "Retirement Receipt Attribute",
30539
+ description: "Retirement receipt token ID attribute"
30426
30540
  });
30427
30541
  var REQUIRED_CREDIT_PURCHASE_RECEIPT_ATTRIBUTES = [
30428
30542
  CreditPurchaseReceiptTotalCreditsAttributeSchema,
30429
- CreditPurchaseReceiptTotalUsdcAttributeSchema,
30543
+ CreditPurchaseReceiptPurchasePriceAttributeSchema,
30430
30544
  CreditPurchaseReceiptPurchaseDateAttributeSchema,
30431
30545
  CreditPurchaseReceiptCertificatesAttributeSchema
30432
30546
  ];
30433
30547
  var CONDITIONAL_CREDIT_PURCHASE_RECEIPT_ATTRIBUTES = [
30434
- CreditPurchaseReceiptReceiverAttributeSchema
30548
+ CreditPurchaseReceiptBuyerAttributeSchema,
30549
+ CreditPurchaseReceiptRetirementDateAttributeSchema,
30550
+ CreditPurchaseReceiptRetirementReceiptAttributeSchema
30435
30551
  ];
30436
30552
  var DYNAMIC_CREDIT_PURCHASE_RECEIPT_ATTRIBUTES = [
30437
- CreditPurchaseReceiptCreditAttributeSchema,
30438
- CreditPurchaseReceiptCollectionAttributeSchema
30553
+ CreditPurchaseReceiptCreditAttributeSchema
30439
30554
  ];
30440
30555
  var CreditPurchaseReceiptAttributesSchema = createOrderedAttributesSchema({
30441
30556
  required: REQUIRED_CREDIT_PURCHASE_RECEIPT_ATTRIBUTES,
@@ -30444,68 +30559,37 @@ var CreditPurchaseReceiptAttributesSchema = createOrderedAttributesSchema({
30444
30559
  ...DYNAMIC_CREDIT_PURCHASE_RECEIPT_ATTRIBUTES
30445
30560
  ],
30446
30561
  title: "Credit Purchase Receipt NFT Attribute Array",
30447
- description: "Attributes for credit purchase receipts including per-credit breakdowns, totals, receiver, purchase date, and per-collection amounts. Fixed required attributes: Total Credits Purchased, Total USDC Amount, Purchase Date, Certificates Purchased. Conditional attributes: Receiver (required when receiver.identity.name is provided). Dynamic attributes: Credit attributes (one per credit symbol in data.credits), Collection attributes (one per collection name in data.collections).",
30562
+ description: "Attributes for credit purchase receipts including per-credit breakdowns, totals, buyer, purchase date, and optional retirement info. Fixed required attributes: Total Credits Purchased, Total Amount (USDC), Purchase Date, Certificates Purchased. Conditional attributes: Buyer (required when buyer.identity.name is provided), Retirement Date (optional, when retirement_receipt is present), Retirement Receipt (optional, when retirement_receipt is present). Dynamic attributes: Credit attributes (one per credit symbol in data.credits).",
30448
30563
  uniqueBySelector: (attribute) => attribute.trait_type,
30449
30564
  requiredTraitTypes: [
30450
30565
  "Total Credits Purchased",
30451
- "Total USDC Amount",
30566
+ "Total Amount (USDC)",
30452
30567
  "Purchase Date",
30453
30568
  "Certificates Purchased"
30454
30569
  ]
30455
30570
  });
30456
30571
  var CreditPurchaseReceiptIdentitySchema = ReceiptIdentitySchema;
30457
- var CreditPurchaseReceiptReceiverSchema = zod.z.strictObject({
30572
+ var CreditPurchaseReceiptBuyerSchema = zod.z.strictObject({
30458
30573
  wallet_address: EthereumAddressSchema.meta({
30459
- title: "Receiver Wallet Address",
30460
- description: "Ethereum address of the receiver"
30574
+ title: "Buyer Wallet Address",
30575
+ description: "Ethereum address receiving the credits"
30461
30576
  }),
30462
- identity: CreditPurchaseReceiptIdentitySchema.optional()
30463
- }).meta({
30464
- title: "Receiver",
30465
- description: "Receiver wallet and optional identity information"
30466
- });
30467
- var CreditPurchaseReceiptBuyerSchema = zod.z.strictObject({
30468
- buyer_id: ExternalIdSchema.meta({
30577
+ id: ExternalIdSchema.optional().meta({
30469
30578
  title: "Buyer ID",
30470
30579
  description: "Unique identifier for the buyer"
30471
30580
  }),
30472
30581
  identity: CreditPurchaseReceiptIdentitySchema.optional()
30473
30582
  }).meta({
30474
30583
  title: "Buyer",
30475
- description: "Buyer identifier and optional identity information"
30476
- });
30477
- var CreditPurchaseReceiptPartiesSchema = zod.z.strictObject({
30478
- payer: EthereumAddressSchema.meta({
30479
- title: "Payer Wallet Address",
30480
- description: "Ethereum address paying for the purchase"
30481
- }),
30482
- receiver: CreditPurchaseReceiptReceiverSchema,
30483
- buyer: CreditPurchaseReceiptBuyerSchema.optional()
30484
- }).meta({
30485
- title: "Parties",
30486
- description: "Parties involved in the purchase including payer, receiver, and optional buyer"
30584
+ description: "Buyer information including wallet address, optional ID, and optional identity"
30487
30585
  });
30488
30586
  var CreditPurchaseReceiptCollectionSchema = createReceiptCollectionSchema({
30489
- amountKey: "credit_amount",
30490
- amountMeta: {
30491
- title: "Collection Credit Amount",
30492
- description: "Total credits purchased from this collection"
30493
- },
30494
30587
  meta: {
30495
30588
  title: "Collection",
30496
30589
  description: "Collection included in the purchase"
30497
30590
  }
30498
30591
  });
30499
30592
  var CreditPurchaseReceiptCreditSchema = createReceiptCreditSchema({
30500
- amountKey: "purchase_amount",
30501
- amountMeta: {
30502
- title: "Credit Purchase Amount",
30503
- description: "Total credits purchased for this credit type"
30504
- },
30505
- retirementAmountMeta: {
30506
- title: "Credit Retirement Amount",
30507
- description: "Credits retired immediately for this credit type during purchase"
30508
- },
30509
30593
  meta: {
30510
30594
  title: "Credit",
30511
30595
  description: "Credit token included in the purchase"
@@ -30513,18 +30597,18 @@ var CreditPurchaseReceiptCreditSchema = createReceiptCreditSchema({
30513
30597
  });
30514
30598
  var CreditPurchaseReceiptCertificateSchema = createReceiptCertificateSchema({
30515
30599
  additionalShape: {
30516
- purchased_amount: CreditAmountSchema.meta({
30517
- title: "Certificate Purchased Amount",
30518
- description: "Credits purchased from this certificate"
30519
- }),
30520
- retired_amount: CreditAmountSchema.meta({
30521
- title: "Certificate Retired Amount",
30522
- description: "Credits retired from this certificate during the purchase (0 if none)"
30523
- }),
30524
30600
  credit_slug: SlugSchema.meta({
30525
30601
  title: "Credit Slug",
30526
30602
  description: "Slug of the credit type for this certificate",
30527
30603
  examples: ["carbon", "organic"]
30604
+ }),
30605
+ collections: uniqueBy(
30606
+ CertificateCollectionItemPurchaseSchema,
30607
+ (item) => item.slug,
30608
+ "Collection slugs within certificate collections must be unique"
30609
+ ).min(1).meta({
30610
+ title: "Certificate Collections",
30611
+ description: "Collections associated with this certificate, each with purchased and retired amounts"
30528
30612
  })
30529
30613
  },
30530
30614
  meta: {
@@ -30533,15 +30617,10 @@ var CreditPurchaseReceiptCertificateSchema = createReceiptCertificateSchema({
30533
30617
  }
30534
30618
  });
30535
30619
  var CreditPurchaseReceiptParticipantRewardSchema = zod.z.strictObject({
30536
- id_hash: Sha256HashSchema.meta({
30620
+ participant_id_hash: Sha256HashSchema.meta({
30537
30621
  title: "Participant ID Hash",
30538
30622
  description: "Hash representing the participant identifier (SHA-256 hex string)"
30539
30623
  }),
30540
- participant_name: NonEmptyStringSchema.max(100).meta({
30541
- title: "Participant Name",
30542
- description: "Legal name of the participant receiving the reward",
30543
- examples: ["EcoTech Solutions Inc.", "Green Tech Corp"]
30544
- }),
30545
30624
  roles: uniqueArrayItems(
30546
30625
  ParticipantRoleSchema,
30547
30626
  "Participant roles must be unique"
@@ -30570,28 +30649,21 @@ var CreditPurchaseReceiptRetirementReceiptSchema = zod.z.strictObject({
30570
30649
  title: "Retirement Receipt External URL",
30571
30650
  description: "External URL for the retirement receipt"
30572
30651
  }),
30573
- uri: IpfsUriSchema.meta({
30574
- title: "Retirement Receipt URI",
30652
+ ipfs_uri: IpfsUriSchema.meta({
30653
+ title: "Retirement Receipt IPFS URI",
30575
30654
  description: "IPFS URI for the retirement receipt metadata"
30576
30655
  }),
30577
- smart_contract: SmartContractSchema
30656
+ smart_contract_address: EthereumAddressSchema.meta({
30657
+ title: "Smart Contract Address",
30658
+ description: "Ethereum address of the smart contract"
30659
+ })
30578
30660
  }).meta({
30579
30661
  title: "Retirement Receipt Reference",
30580
30662
  description: "Reference to the retirement receipt NFT"
30581
30663
  });
30582
- var CreditPurchaseReceiptRetirementSchema = zod.z.strictObject({
30583
- beneficiary_id: ExternalIdSchema.meta({
30584
- title: "Retirement Beneficiary ID",
30585
- description: "UUID identifying the beneficiary of the retirement (bytes16 normalized to UUID)"
30586
- }),
30587
- retirement_receipt: CreditPurchaseReceiptRetirementReceiptSchema.optional()
30588
- }).meta({
30589
- title: "Retirement",
30590
- description: "Immediate retirement details performed as part of purchase"
30591
- });
30592
30664
  var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
30593
30665
  summary: CreditPurchaseReceiptSummarySchema,
30594
- parties: CreditPurchaseReceiptPartiesSchema,
30666
+ buyer: CreditPurchaseReceiptBuyerSchema,
30595
30667
  collections: uniqueBy(
30596
30668
  CreditPurchaseReceiptCollectionSchema,
30597
30669
  (collection) => collection.slug,
@@ -30618,41 +30690,14 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
30618
30690
  }),
30619
30691
  participant_rewards: uniqueBy(
30620
30692
  CreditPurchaseReceiptParticipantRewardSchema,
30621
- (reward) => reward.id_hash,
30622
- "Participant id_hash must be unique"
30693
+ (reward) => reward.participant_id_hash,
30694
+ "Participant participant_id_hash must be unique"
30623
30695
  ).min(1).meta({
30624
30696
  title: "Participant Rewards",
30625
30697
  description: "Rewards distributed to participants in the supply chain for this purchase"
30626
30698
  }),
30627
- retirement: CreditPurchaseReceiptRetirementSchema.optional()
30699
+ retirement_receipt: CreditPurchaseReceiptRetirementReceiptSchema.optional()
30628
30700
  }).superRefine((data, ctx) => {
30629
- const retirementProvided = Boolean(data.retirement);
30630
- const creditsWithRetirement = data.credits.reduce(
30631
- (indices, credit, index) => {
30632
- const retirementAmount = Number(credit.retirement_amount ?? 0);
30633
- if (retirementAmount > 0) {
30634
- indices.push(index);
30635
- }
30636
- return indices;
30637
- },
30638
- []
30639
- );
30640
- if (retirementProvided && creditsWithRetirement.length === 0) {
30641
- ctx.addIssue({
30642
- code: "custom",
30643
- message: "retirement is present but no credit has retirement_amount greater than 0",
30644
- path: ["retirement"]
30645
- });
30646
- }
30647
- if (!retirementProvided && creditsWithRetirement.length > 0) {
30648
- creditsWithRetirement.forEach((index) => {
30649
- ctx.addIssue({
30650
- code: "custom",
30651
- message: "credit retirement_amount greater than 0 requires retirement details",
30652
- path: ["credits", index, "retirement_amount"]
30653
- });
30654
- });
30655
- }
30656
30701
  validateCountMatches({
30657
30702
  ctx,
30658
30703
  actualCount: data.certificates.length,
@@ -30666,140 +30711,82 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
30666
30711
  const creditSlugs = new Set(
30667
30712
  data.credits.map((credit) => String(credit.slug))
30668
30713
  );
30669
- const creditSymbols = new Set(
30670
- data.credits.map((credit) => String(credit.symbol))
30671
- );
30672
- const certificateTypes = new Set(
30673
- data.certificates.map((certificate) => String(certificate.type))
30674
- );
30675
- validateSummaryListMatchesData({
30676
- ctx,
30677
- summaryValues: data.summary.credit_symbols,
30678
- dataValues: creditSymbols,
30679
- summaryPath: ["summary", "credit_symbols"],
30680
- missingFromDataMessage: "summary.credit_symbols must reference symbols from credits",
30681
- missingFromSummaryMessage: "All credit symbols must be listed in summary.credit_symbols"
30682
- });
30683
- validateSummaryListMatchesData({
30684
- ctx,
30685
- summaryValues: data.summary.collection_slugs,
30686
- dataValues: collectionSlugs,
30687
- summaryPath: ["summary", "collection_slugs"],
30688
- missingFromDataMessage: "summary.collection_slugs must reference slugs from collections",
30689
- missingFromSummaryMessage: "All collection slugs must be listed in summary.collection_slugs"
30690
- });
30691
- validateSummaryListMatchesData({
30692
- ctx,
30693
- summaryValues: data.summary.certificate_types,
30694
- dataValues: certificateTypes,
30695
- summaryPath: ["summary", "certificate_types"],
30696
- missingFromDataMessage: "summary.certificate_types must reference types present in certificates",
30697
- missingFromSummaryMessage: "All certificate types must be listed in summary.certificate_types"
30698
- });
30699
30714
  const creditPurchaseTotalsBySlug = /* @__PURE__ */ new Map();
30700
30715
  const creditRetiredTotalsBySlug = /* @__PURE__ */ new Map();
30701
- const collectionTotalsBySlug = /* @__PURE__ */ new Map();
30716
+ const collectionPurchasedTotalsBySlug = /* @__PURE__ */ new Map();
30717
+ const collectionRetiredTotalsBySlug = /* @__PURE__ */ new Map();
30702
30718
  let totalCreditsFromCertificates = 0;
30703
30719
  data.certificates.forEach((certificate, index) => {
30704
- if (!collectionSlugs.has(certificate.collection_slug)) {
30705
- ctx.addIssue({
30706
- code: "custom",
30707
- message: "collection_slug must match a collection slug in collections",
30708
- path: ["certificates", index, "collection_slug"]
30709
- });
30710
- }
30711
- if (!creditSlugs.has(certificate.credit_slug)) {
30712
- ctx.addIssue({
30713
- code: "custom",
30714
- message: "credit_slug must match a credit slug in credits",
30715
- path: ["certificates", index, "credit_slug"]
30716
- });
30717
- }
30718
- if (certificate.retired_amount > certificate.purchased_amount) {
30719
- ctx.addIssue({
30720
- code: "custom",
30721
- message: "retired_amount cannot exceed purchased_amount",
30722
- path: ["certificates", index, "retired_amount"]
30723
- });
30724
- }
30725
- if (certificate.purchased_amount > certificate.total_amount) {
30720
+ validateCreditSlugExists({
30721
+ ctx,
30722
+ creditSlug: certificate.credit_slug,
30723
+ validCreditSlugs: creditSlugs,
30724
+ path: ["certificates", index, "credit_slug"]
30725
+ });
30726
+ let certificatePurchasedTotal = 0;
30727
+ let certificateRetiredTotal = 0;
30728
+ validateCertificateCollectionSlugs({
30729
+ ctx,
30730
+ certificateCollections: certificate.collections,
30731
+ validCollectionSlugs: collectionSlugs,
30732
+ certificateIndex: index
30733
+ });
30734
+ certificate.collections.forEach((collectionItem, collectionIndex) => {
30735
+ if (collectionItem.retired_amount > collectionItem.purchased_amount) {
30736
+ ctx.addIssue({
30737
+ code: "custom",
30738
+ message: "certificate.collections[].retired_amount cannot exceed purchased_amount",
30739
+ path: [
30740
+ "certificates",
30741
+ index,
30742
+ "collections",
30743
+ collectionIndex,
30744
+ "retired_amount"
30745
+ ]
30746
+ });
30747
+ }
30748
+ certificatePurchasedTotal += Number(collectionItem.purchased_amount);
30749
+ certificateRetiredTotal += Number(collectionItem.retired_amount);
30750
+ collectionPurchasedTotalsBySlug.set(
30751
+ collectionItem.slug,
30752
+ (collectionPurchasedTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.purchased_amount)
30753
+ );
30754
+ collectionRetiredTotalsBySlug.set(
30755
+ collectionItem.slug,
30756
+ (collectionRetiredTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.retired_amount)
30757
+ );
30758
+ });
30759
+ if (certificatePurchasedTotal > certificate.total_amount) {
30726
30760
  ctx.addIssue({
30727
30761
  code: "custom",
30728
- message: "purchased_amount cannot exceed total_amount",
30729
- path: ["certificates", index, "purchased_amount"]
30762
+ message: "Sum of certificate.collections[].purchased_amount cannot exceed certificate.total_amount",
30763
+ path: ["certificates", index]
30730
30764
  });
30731
30765
  }
30732
- totalCreditsFromCertificates += Number(certificate.purchased_amount);
30766
+ totalCreditsFromCertificates += certificatePurchasedTotal;
30733
30767
  creditPurchaseTotalsBySlug.set(
30734
30768
  String(certificate.credit_slug),
30735
- (creditPurchaseTotalsBySlug.get(certificate.credit_slug) ?? 0) + Number(certificate.purchased_amount)
30769
+ (creditPurchaseTotalsBySlug.get(certificate.credit_slug) ?? 0) + certificatePurchasedTotal
30736
30770
  );
30737
30771
  creditRetiredTotalsBySlug.set(
30738
30772
  String(certificate.credit_slug),
30739
- (creditRetiredTotalsBySlug.get(certificate.credit_slug) ?? 0) + Number(certificate.retired_amount)
30740
- );
30741
- collectionTotalsBySlug.set(
30742
- String(certificate.collection_slug),
30743
- (collectionTotalsBySlug.get(certificate.collection_slug) ?? 0) + Number(certificate.purchased_amount)
30773
+ (creditRetiredTotalsBySlug.get(certificate.credit_slug) ?? 0) + certificateRetiredTotal
30744
30774
  );
30745
30775
  });
30746
- const totalCreditsFromCollections = data.collections.reduce(
30747
- (sum, collection) => sum + Number(collection.credit_amount),
30748
- 0
30749
- );
30750
- const totalCreditsFromCredits = data.credits.reduce(
30751
- (sum, credit) => sum + Number(credit.purchase_amount),
30752
- 0
30753
- );
30776
+ const certificateCollectionRetiredTotal = Array.from(
30777
+ collectionRetiredTotalsBySlug.values()
30778
+ ).reduce((sum, amount) => sum + amount, 0);
30754
30779
  validateTotalMatches({
30755
30780
  ctx,
30756
30781
  actualTotal: totalCreditsFromCertificates,
30757
30782
  expectedTotal: data.summary.total_credits,
30758
30783
  path: ["summary", "total_credits"],
30759
- message: "summary.total_credits must equal sum of certificates.purchased_amount"
30784
+ message: "summary.total_credits must equal sum of certificate.collections[].purchased_amount"
30760
30785
  });
30761
- validateTotalMatches({
30786
+ validateRetirementReceiptRequirement({
30762
30787
  ctx,
30763
- actualTotal: totalCreditsFromCredits,
30764
- expectedTotal: data.summary.total_credits,
30765
- path: ["summary", "total_credits"],
30766
- message: "summary.total_credits must equal sum of credits.purchase_amount"
30767
- });
30768
- validateTotalMatches({
30769
- ctx,
30770
- actualTotal: totalCreditsFromCollections,
30771
- expectedTotal: data.summary.total_credits,
30772
- path: ["summary", "total_credits"],
30773
- message: "summary.total_credits must equal sum of collections.credit_amount"
30774
- });
30775
- data.credits.forEach((credit, index) => {
30776
- const purchasedTotal = creditPurchaseTotalsBySlug.get(String(credit.slug)) ?? 0;
30777
- if (!nearlyEqual(Number(credit.purchase_amount), purchasedTotal)) {
30778
- ctx.addIssue({
30779
- code: "custom",
30780
- message: "credit.purchase_amount must equal sum of certificate purchased_amount for the credit slug",
30781
- path: ["credits", index, "purchase_amount"]
30782
- });
30783
- }
30784
- const retiredTotal = creditRetiredTotalsBySlug.get(String(credit.slug)) ?? 0;
30785
- const retirementAmount = Number(credit.retirement_amount ?? 0);
30786
- if (!nearlyEqual(retirementAmount, retiredTotal)) {
30787
- ctx.addIssue({
30788
- code: "custom",
30789
- message: "credit.retirement_amount must equal sum of certificate retired_amount for the credit slug",
30790
- path: ["credits", index, "retirement_amount"]
30791
- });
30792
- }
30793
- });
30794
- data.collections.forEach((collection, index) => {
30795
- const purchasedTotal = collectionTotalsBySlug.get(String(collection.slug)) ?? 0;
30796
- if (!nearlyEqual(Number(collection.credit_amount), purchasedTotal)) {
30797
- ctx.addIssue({
30798
- code: "custom",
30799
- message: "collection.credit_amount must equal sum of certificate purchased_amount for the collection slug",
30800
- path: ["collections", index, "credit_amount"]
30801
- });
30802
- }
30788
+ hasRetirementReceipt: !!data.retirement_receipt,
30789
+ totalRetiredAmount: certificateCollectionRetiredTotal
30803
30790
  });
30804
30791
  const participantRewardTotal = data.participant_rewards.reduce(
30805
30792
  (sum, reward) => sum + Number(reward.usdc_amount),
@@ -30808,9 +30795,9 @@ var CreditPurchaseReceiptDataSchema = zod.z.strictObject({
30808
30795
  validateTotalMatches({
30809
30796
  ctx,
30810
30797
  actualTotal: participantRewardTotal,
30811
- expectedTotal: data.summary.total_usdc_amount,
30812
- path: ["summary", "total_usdc_amount"],
30813
- message: "summary.total_usdc_amount must equal sum of participant_rewards.usdc_amount"
30798
+ expectedTotal: data.summary.total_amount_usdc,
30799
+ path: ["summary", "total_amount_usdc"],
30800
+ message: "summary.total_amount_usdc must equal sum of participant_rewards.usdc_amount"
30814
30801
  });
30815
30802
  }).meta({
30816
30803
  title: "Credit Purchase Receipt Data",
@@ -30848,10 +30835,10 @@ var CreditPurchaseReceiptIpfsSchema = NftIpfsSchema.safeExtend({
30848
30835
  validateAttributeValue({
30849
30836
  ctx,
30850
30837
  attributeByTraitType,
30851
- traitType: "Total USDC Amount",
30852
- expectedValue: data.summary.total_usdc_amount,
30853
- missingMessage: 'Attribute "Total USDC Amount" is required',
30854
- mismatchMessage: 'Attribute "Total USDC Amount" must match data.summary.total_usdc_amount'
30838
+ traitType: "Total Amount (USDC)",
30839
+ expectedValue: data.summary.total_amount_usdc,
30840
+ missingMessage: 'Attribute "Total Amount (USDC)" is required',
30841
+ mismatchMessage: 'Attribute "Total Amount (USDC)" must match data.summary.total_amount_usdc'
30855
30842
  });
30856
30843
  validateAttributeValue({
30857
30844
  ctx,
@@ -30861,44 +30848,86 @@ var CreditPurchaseReceiptIpfsSchema = NftIpfsSchema.safeExtend({
30861
30848
  missingMessage: 'Attribute "Certificates Purchased" is required',
30862
30849
  mismatchMessage: 'Attribute "Certificates Purchased" must match data.summary.total_certificates'
30863
30850
  });
30864
- const receiverName = data.parties.receiver.identity?.name;
30865
- if (receiverName) {
30851
+ const buyerName = data.buyer.identity?.name;
30852
+ if (buyerName) {
30866
30853
  validateAttributeValue({
30867
30854
  ctx,
30868
30855
  attributeByTraitType,
30869
- traitType: "Receiver",
30870
- expectedValue: String(receiverName),
30871
- missingMessage: 'Attribute "Receiver" is required when receiver.identity.name is provided',
30872
- mismatchMessage: 'Attribute "Receiver" must match receiver.identity.name'
30856
+ traitType: "Buyer",
30857
+ expectedValue: String(buyerName),
30858
+ missingMessage: 'Attribute "Buyer" is required when buyer.identity.name is provided',
30859
+ mismatchMessage: 'Attribute "Buyer" must match buyer.identity.name'
30873
30860
  });
30874
30861
  }
30875
- validateDateAttribute({
30876
- ctx,
30877
- attributeByTraitType,
30878
- traitType: "Purchase Date",
30879
- dateValue: data.summary.purchase_date,
30880
- missingMessage: 'Attribute "Purchase Date" is required',
30881
- invalidDateMessage: "data.summary.purchase_date must be a valid date string",
30882
- mismatchMessage: 'Attribute "Purchase Date" must match data.summary.purchase_date as a Unix timestamp in milliseconds',
30883
- datePath: ["data", "summary", "purchase_date"]
30884
- });
30885
- validateAttributesForItems({
30886
- ctx,
30887
- attributeByTraitType,
30888
- items: data.credits,
30889
- traitSelector: (credit) => String(credit.symbol),
30890
- valueSelector: (credit) => Number(credit.purchase_amount),
30891
- missingMessage: (symbol) => `Attribute for credit symbol ${symbol} is required`,
30892
- mismatchMessage: (symbol) => `Attribute for credit symbol ${symbol} must match credit.purchase_amount`
30862
+ const purchaseDateAttribute = attributeByTraitType.get("Purchase Date");
30863
+ if (purchaseDateAttribute) {
30864
+ const dateMs = Date.parse(data.summary.purchased_at);
30865
+ if (Number.isNaN(dateMs)) {
30866
+ ctx.addIssue({
30867
+ code: "custom",
30868
+ message: "data.summary.purchased_at must be a valid ISO 8601 date-time string",
30869
+ path: ["data", "summary", "purchased_at"]
30870
+ });
30871
+ } else if (purchaseDateAttribute.value !== dateMs) {
30872
+ ctx.addIssue({
30873
+ code: "custom",
30874
+ message: 'Attribute "Purchase Date" must match data.summary.purchased_at as a Unix timestamp in milliseconds',
30875
+ path: ["attributes"]
30876
+ });
30877
+ }
30878
+ } else {
30879
+ ctx.addIssue({
30880
+ code: "custom",
30881
+ message: 'Attribute "Purchase Date" is required',
30882
+ path: ["attributes"]
30883
+ });
30884
+ }
30885
+ if (data.retirement_receipt) {
30886
+ const retirementReceiptAttribute = attributeByTraitType.get("Retirement Receipt");
30887
+ if (retirementReceiptAttribute) {
30888
+ const expectedTokenId = `#${data.retirement_receipt.token_id}`;
30889
+ if (retirementReceiptAttribute.value !== expectedTokenId) {
30890
+ ctx.addIssue({
30891
+ code: "custom",
30892
+ message: 'Attribute "Retirement Receipt" must match retirement_receipt.token_id as #<token_id> when present',
30893
+ path: ["attributes"]
30894
+ });
30895
+ }
30896
+ }
30897
+ }
30898
+ const creditTotalsBySymbol = /* @__PURE__ */ new Map();
30899
+ data.certificates.forEach((certificate) => {
30900
+ const credit = data.credits.find(
30901
+ (c) => c.slug === certificate.credit_slug
30902
+ );
30903
+ if (credit) {
30904
+ const certificatePurchasedTotal = certificate.collections.reduce(
30905
+ (sum, collection) => sum + Number(collection.purchased_amount),
30906
+ 0
30907
+ );
30908
+ const currentTotal = creditTotalsBySymbol.get(credit.symbol) ?? 0;
30909
+ creditTotalsBySymbol.set(
30910
+ credit.symbol,
30911
+ currentTotal + certificatePurchasedTotal
30912
+ );
30913
+ }
30893
30914
  });
30894
- validateAttributesForItems({
30895
- ctx,
30896
- attributeByTraitType,
30897
- items: data.collections,
30898
- traitSelector: (collection) => String(collection.name),
30899
- valueSelector: (collection) => Number(collection.credit_amount),
30900
- missingMessage: (name) => `Attribute for collection ${name} is required`,
30901
- mismatchMessage: (name) => `Attribute for collection ${name} must match collection.credit_amount`
30915
+ data.credits.forEach((credit) => {
30916
+ const expectedTotal = creditTotalsBySymbol.get(credit.symbol) ?? 0;
30917
+ const attribute = attributeByTraitType.get(credit.symbol);
30918
+ if (!attribute) {
30919
+ ctx.addIssue({
30920
+ code: "custom",
30921
+ message: `Attribute for credit symbol ${credit.symbol} is required`,
30922
+ path: ["attributes"]
30923
+ });
30924
+ } else if (Number(attribute.value) !== expectedTotal) {
30925
+ ctx.addIssue({
30926
+ code: "custom",
30927
+ message: `Attribute for credit symbol ${credit.symbol} must match sum of certificate.collections[].purchased_amount for the credit symbol`,
30928
+ path: ["attributes"]
30929
+ });
30930
+ }
30902
30931
  });
30903
30932
  }).meta(CreditPurchaseReceiptIpfsSchemaMeta);
30904
30933
  var CreditRetirementReceiptCreditAttributeSchema = NftAttributeSchema.safeExtend({
@@ -30951,16 +30980,20 @@ var CreditRetirementReceiptCertificatesAttributeSchema = createNumericAttributeS
30951
30980
  description: "Total number of certificates retired",
30952
30981
  valueSchema: PositiveIntegerSchema
30953
30982
  });
30954
- var CreditRetirementReceiptCollectionAttributeSchema = NftAttributeSchema.safeExtend({
30955
- trait_type: CollectionNameSchema,
30956
- value: CreditAmountSchema.meta({
30957
- title: "Credits from Collection",
30958
- description: "Amount of credits retired from the collection"
30959
- }),
30960
- display_type: zod.z.literal("number")
30983
+ var CreditRetirementReceiptPurchaseDateAttributeSchema = createDateAttributeSchema({
30984
+ traitType: "Purchase Date",
30985
+ title: "Purchase Date",
30986
+ description: "Unix timestamp in milliseconds when credits were purchased (if purchase_receipt is present)"
30987
+ });
30988
+ var CreditRetirementReceiptPurchaseReceiptAttributeSchema = NftAttributeSchema.safeExtend({
30989
+ trait_type: zod.z.literal("Purchase Receipt"),
30990
+ value: StringifiedTokenIdSchema.meta({
30991
+ title: "Purchase Receipt Token ID",
30992
+ description: "Token ID of the purchase receipt NFT as #<token_id> (if purchase_receipt is present)"
30993
+ })
30961
30994
  }).meta({
30962
- title: "Collection Attribute",
30963
- description: "Attribute representing the amount of credits retired from a collection"
30995
+ title: "Purchase Receipt Attribute",
30996
+ description: "Attribute representing the purchase receipt token ID"
30964
30997
  });
30965
30998
  var REQUIRED_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES = [
30966
30999
  CreditRetirementReceiptTotalCreditsAttributeSchema,
@@ -30969,11 +31002,12 @@ var REQUIRED_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES = [
30969
31002
  CreditRetirementReceiptCertificatesAttributeSchema
30970
31003
  ];
30971
31004
  var CONDITIONAL_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES = [
30972
- CreditRetirementReceiptCreditHolderAttributeSchema
31005
+ CreditRetirementReceiptCreditHolderAttributeSchema,
31006
+ CreditRetirementReceiptPurchaseDateAttributeSchema,
31007
+ CreditRetirementReceiptPurchaseReceiptAttributeSchema
30973
31008
  ];
30974
31009
  var DYNAMIC_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES = [
30975
- CreditRetirementReceiptCreditAttributeSchema,
30976
- CreditRetirementReceiptCollectionAttributeSchema
31010
+ CreditRetirementReceiptCreditAttributeSchema
30977
31011
  ];
30978
31012
  var CreditRetirementReceiptAttributesSchema = createOrderedAttributesSchema({
30979
31013
  required: REQUIRED_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES,
@@ -30982,7 +31016,7 @@ var CreditRetirementReceiptAttributesSchema = createOrderedAttributesSchema({
30982
31016
  ...DYNAMIC_CREDIT_RETIREMENT_RECEIPT_ATTRIBUTES
30983
31017
  ],
30984
31018
  title: "Credit Retirement Receipt NFT Attribute Array",
30985
- description: "Attributes for credit retirement receipts including per-credit breakdowns, totals, beneficiary, credit holder, retirement date, certificate count, and per-collection amounts. Fixed required attributes: Total Credits Retired, Beneficiary, Retirement Date, Certificates Retired. Conditional attributes: Credit Holder (required when credit_holder.identity.name is provided). Dynamic attributes: Credit attributes (one per credit symbol in data.credits), Collection attributes (one per collection name in data.collections).",
31019
+ description: "Attributes for credit retirement receipts including per-credit breakdowns, totals, beneficiary, credit holder, retirement date, certificate count, and optional purchase info. Fixed required attributes: Total Credits Retired, Beneficiary, Retirement Date, Certificates Retired. Conditional attributes: Credit Holder (required when credit_holder.identity.name is provided), Purchase Date (optional, when purchase_receipt is present), Purchase Receipt (optional, when purchase_receipt is present). Dynamic attributes: Credit attributes (one per credit symbol in data.credits).",
30986
31020
  uniqueBySelector: (attribute) => attribute.trait_type,
30987
31021
  requiredTraitTypes: [
30988
31022
  "Total Credits Retired",
@@ -31013,22 +31047,12 @@ var CreditRetirementReceiptCreditHolderSchema = zod.z.strictObject({
31013
31047
  description: "Credit holder wallet and optional identity information"
31014
31048
  });
31015
31049
  var CreditRetirementReceiptCollectionSchema = createReceiptCollectionSchema({
31016
- amountKey: "amount",
31017
- amountMeta: {
31018
- title: "Collection Retirement Amount",
31019
- description: "Total credits retired from this collection"
31020
- },
31021
31050
  meta: {
31022
31051
  title: "Collection",
31023
31052
  description: "Collection included in the retirement"
31024
31053
  }
31025
31054
  });
31026
31055
  var CreditRetirementReceiptCreditSchema = createReceiptCreditSchema({
31027
- amountKey: "amount",
31028
- amountMeta: {
31029
- title: "Credit Retirement Amount",
31030
- description: "Total credits retired for this credit type"
31031
- },
31032
31056
  meta: {
31033
31057
  title: "Credit",
31034
31058
  description: "Credit token retired in this receipt"
@@ -31070,11 +31094,14 @@ var CreditPurchaseReceiptReferenceSchema = zod.z.strictObject({
31070
31094
  title: "Purchase Receipt External URL",
31071
31095
  description: "External URL for the purchase receipt"
31072
31096
  }),
31073
- uri: IpfsUriSchema.meta({
31074
- title: "Purchase Receipt URI",
31097
+ ipfs_uri: IpfsUriSchema.meta({
31098
+ title: "Purchase Receipt IPFS URI",
31075
31099
  description: "IPFS URI for the purchase receipt metadata"
31076
31100
  }),
31077
- smart_contract: SmartContractSchema
31101
+ smart_contract_address: EthereumAddressSchema.meta({
31102
+ title: "Smart Contract Address",
31103
+ description: "Ethereum address of the smart contract"
31104
+ })
31078
31105
  }).meta({
31079
31106
  title: "Credit Purchase Receipt Reference",
31080
31107
  description: "Reference to the credit purchase receipt when retirement occurs during purchase"
@@ -31082,9 +31109,13 @@ var CreditPurchaseReceiptReferenceSchema = zod.z.strictObject({
31082
31109
  var CreditRetirementReceiptCertificateSchema = createReceiptCertificateSchema(
31083
31110
  {
31084
31111
  additionalShape: {
31085
- retired_amount: CreditAmountSchema.meta({
31086
- title: "Certificate Retired Amount",
31087
- description: "Credits retired from this certificate"
31112
+ collections: uniqueBy(
31113
+ CertificateCollectionItemRetirementSchema,
31114
+ (item) => item.slug,
31115
+ "Collection slugs within certificate collections must be unique"
31116
+ ).min(1).meta({
31117
+ title: "Certificate Collections",
31118
+ description: "Collections associated with this certificate, each with retired amounts"
31088
31119
  }),
31089
31120
  credits_retired: uniqueBy(
31090
31121
  CreditRetirementReceiptCertificateCreditSchema,
@@ -31134,15 +31165,15 @@ var CreditRetirementReceiptDataSchema = zod.z.strictObject({
31134
31165
  const creditSymbols = new Set(
31135
31166
  data.credits.map((credit) => String(credit.symbol))
31136
31167
  );
31168
+ const creditSlugs = new Set(
31169
+ data.credits.map((credit) => String(credit.slug))
31170
+ );
31137
31171
  const creditBySlug = new Map(
31138
31172
  data.credits.map((credit) => [credit.slug, credit])
31139
31173
  );
31140
31174
  const collectionSlugs = new Set(
31141
31175
  data.collections.map((collection) => String(collection.slug))
31142
31176
  );
31143
- const certificateTypes = new Set(
31144
- data.certificates.map((certificate) => String(certificate.type))
31145
- );
31146
31177
  validateCountMatches({
31147
31178
  ctx,
31148
31179
  actualCount: data.certificates.length,
@@ -31150,87 +31181,70 @@ var CreditRetirementReceiptDataSchema = zod.z.strictObject({
31150
31181
  path: ["summary", "total_certificates"],
31151
31182
  message: "summary.total_certificates must equal the number of certificates"
31152
31183
  });
31153
- validateSummaryListMatchesData({
31154
- ctx,
31155
- summaryValues: data.summary.credit_symbols,
31156
- dataValues: creditSymbols,
31157
- summaryPath: ["summary", "credit_symbols"],
31158
- missingFromDataMessage: "summary.credit_symbols must reference symbols from credits",
31159
- missingFromSummaryMessage: "All credit symbols must be listed in summary.credit_symbols"
31160
- });
31161
- validateSummaryListMatchesData({
31162
- ctx,
31163
- summaryValues: data.summary.collection_slugs,
31164
- dataValues: collectionSlugs,
31165
- summaryPath: ["summary", "collection_slugs"],
31166
- missingFromDataMessage: "summary.collection_slugs must reference slugs from collections",
31167
- missingFromSummaryMessage: "All collection slugs must be listed in summary.collection_slugs"
31168
- });
31169
- validateSummaryListMatchesData({
31170
- ctx,
31171
- summaryValues: data.summary.certificate_types,
31172
- dataValues: certificateTypes,
31173
- summaryPath: ["summary", "certificate_types"],
31174
- missingFromDataMessage: "summary.certificate_types must reference types present in certificates",
31175
- missingFromSummaryMessage: "All certificate types must be listed in summary.certificate_types"
31176
- });
31177
31184
  const creditTotalsBySymbol = /* @__PURE__ */ new Map();
31178
- const collectionTotalsBySlug = /* @__PURE__ */ new Map();
31185
+ const collectionRetiredTotalsBySlug = /* @__PURE__ */ new Map();
31179
31186
  let totalRetiredFromCertificates = 0;
31180
31187
  data.certificates.forEach((certificate, index) => {
31181
- if (!collectionSlugs.has(certificate.collection_slug)) {
31182
- ctx.addIssue({
31183
- code: "custom",
31184
- message: "collection_slug must match a collection slug in collections",
31185
- path: ["certificates", index, "collection_slug"]
31186
- });
31187
- }
31188
- if (certificate.retired_amount > certificate.total_amount) {
31188
+ const certificateCollectionRetiredTotal = certificate.collections.reduce(
31189
+ (sum, item) => sum + Number(item.retired_amount),
31190
+ 0
31191
+ );
31192
+ if (certificateCollectionRetiredTotal > certificate.total_amount) {
31189
31193
  ctx.addIssue({
31190
31194
  code: "custom",
31191
- message: "retired_amount cannot exceed total_amount",
31192
- path: ["certificates", index, "retired_amount"]
31195
+ message: "Sum of certificate.collections[].retired_amount cannot exceed certificate.total_amount",
31196
+ path: ["certificates", index]
31193
31197
  });
31194
31198
  }
31199
+ validateCertificateCollectionSlugs({
31200
+ ctx,
31201
+ certificateCollections: certificate.collections,
31202
+ validCollectionSlugs: collectionSlugs,
31203
+ certificateIndex: index
31204
+ });
31205
+ certificate.collections.forEach((collectionItem) => {
31206
+ collectionRetiredTotalsBySlug.set(
31207
+ collectionItem.slug,
31208
+ (collectionRetiredTotalsBySlug.get(collectionItem.slug) ?? 0) + Number(collectionItem.retired_amount)
31209
+ );
31210
+ });
31195
31211
  const creditsRetiredTotal = certificate.credits_retired.reduce(
31196
31212
  (sum, credit) => sum + Number(credit.amount),
31197
31213
  0
31198
31214
  );
31199
- if (!nearlyEqual(creditsRetiredTotal, certificate.retired_amount)) {
31215
+ if (!nearlyEqual(creditsRetiredTotal, certificateCollectionRetiredTotal)) {
31200
31216
  ctx.addIssue({
31201
31217
  code: "custom",
31202
- message: "certificates.credits_retired amounts must sum to certificates.retired_amount",
31218
+ message: "certificates.credits_retired amounts must sum to certificate.collections[].retired_amount",
31203
31219
  path: ["certificates", index, "credits_retired"]
31204
31220
  });
31205
31221
  }
31206
31222
  certificate.credits_retired.forEach((credit, creditIndex) => {
31207
31223
  const referencedCredit = creditBySlug.get(credit.credit_slug);
31208
- if (!referencedCredit) {
31209
- ctx.addIssue({
31210
- code: "custom",
31211
- message: "credit_slug must match a credit slug in credits",
31212
- path: [
31213
- "certificates",
31214
- index,
31215
- "credits_retired",
31216
- creditIndex,
31217
- "credit_slug"
31218
- ]
31219
- });
31220
- }
31221
- if (!creditSymbols.has(credit.credit_symbol)) {
31222
- ctx.addIssue({
31223
- code: "custom",
31224
- message: "credit_symbol must match a credit symbol in credits",
31225
- path: [
31226
- "certificates",
31227
- index,
31228
- "credits_retired",
31229
- creditIndex,
31230
- "credit_symbol"
31231
- ]
31232
- });
31233
- }
31224
+ validateCreditSlugExists({
31225
+ ctx,
31226
+ creditSlug: credit.credit_slug,
31227
+ validCreditSlugs: creditSlugs,
31228
+ path: [
31229
+ "certificates",
31230
+ index,
31231
+ "credits_retired",
31232
+ creditIndex,
31233
+ "credit_slug"
31234
+ ]
31235
+ });
31236
+ validateCreditSymbolExists({
31237
+ ctx,
31238
+ creditSymbol: credit.credit_symbol,
31239
+ validCreditSymbols: creditSymbols,
31240
+ path: [
31241
+ "certificates",
31242
+ index,
31243
+ "credits_retired",
31244
+ creditIndex,
31245
+ "credit_symbol"
31246
+ ]
31247
+ });
31234
31248
  if (referencedCredit && referencedCredit.symbol !== credit.credit_symbol) {
31235
31249
  ctx.addIssue({
31236
31250
  code: "custom",
@@ -31249,83 +31263,19 @@ var CreditRetirementReceiptDataSchema = zod.z.strictObject({
31249
31263
  (creditTotalsBySymbol.get(credit.credit_symbol) ?? 0) + credit.amount
31250
31264
  );
31251
31265
  });
31252
- collectionTotalsBySlug.set(
31253
- String(certificate.collection_slug),
31254
- (collectionTotalsBySlug.get(certificate.collection_slug) ?? 0) + Number(certificate.retired_amount)
31255
- );
31256
- totalRetiredFromCertificates += Number(certificate.retired_amount);
31257
- });
31258
- const totalRetiredFromCollections = data.collections.reduce(
31259
- (sum, collection) => sum + Number(collection.amount),
31260
- 0
31261
- );
31262
- const totalRetiredFromCredits = data.credits.reduce(
31263
- (sum, credit) => sum + Number(credit.amount),
31264
- 0
31265
- );
31266
- data.summary.credit_symbols.forEach((symbol) => {
31267
- if ((creditTotalsBySymbol.get(symbol) ?? 0) === 0) {
31268
- ctx.addIssue({
31269
- code: "custom",
31270
- message: "Each summary credit symbol must appear in certificates.credits_retired with a retired amount",
31271
- path: ["summary", "credit_symbols"]
31272
- });
31273
- }
31266
+ totalRetiredFromCertificates += certificateCollectionRetiredTotal;
31274
31267
  });
31275
31268
  validateTotalMatches({
31276
31269
  ctx,
31277
31270
  actualTotal: totalRetiredFromCertificates,
31278
- expectedTotal: data.summary.total_retirement_amount,
31279
- path: ["summary", "total_retirement_amount"],
31280
- message: "summary.total_retirement_amount must equal sum of certificates.retired_amount"
31271
+ expectedTotal: data.summary.total_credits_retired,
31272
+ path: ["summary", "total_credits_retired"],
31273
+ message: "summary.total_credits_retired must equal sum of certificate.collections[].retired_amount"
31281
31274
  });
31282
- validateTotalMatches({
31275
+ validateCollectionsHaveRetiredAmounts({
31283
31276
  ctx,
31284
- actualTotal: totalRetiredFromCredits,
31285
- expectedTotal: data.summary.total_retirement_amount,
31286
- path: ["summary", "total_retirement_amount"],
31287
- message: "summary.total_retirement_amount must equal sum of credits.amount"
31288
- });
31289
- validateTotalMatches({
31290
- ctx,
31291
- actualTotal: totalRetiredFromCollections,
31292
- expectedTotal: data.summary.total_retirement_amount,
31293
- path: ["summary", "total_retirement_amount"],
31294
- message: "summary.total_retirement_amount must equal sum of collections.amount"
31295
- });
31296
- data.credits.forEach((credit, index) => {
31297
- const retiredTotal = creditTotalsBySymbol.get(String(credit.symbol)) ?? 0;
31298
- if (!nearlyEqual(Number(credit.amount), retiredTotal)) {
31299
- ctx.addIssue({
31300
- code: "custom",
31301
- message: "credit.amount must equal sum of retired amounts for the credit symbol across certificates",
31302
- path: ["credits", index, "amount"]
31303
- });
31304
- }
31305
- });
31306
- data.collections.forEach((collection, index) => {
31307
- const retiredTotal = collectionTotalsBySlug.get(String(collection.slug)) ?? 0;
31308
- if (retiredTotal === 0) {
31309
- ctx.addIssue({
31310
- code: "custom",
31311
- message: "collection must be referenced by at least one certificate with retired_amount > 0",
31312
- path: ["collections", index, "slug"]
31313
- });
31314
- }
31315
- if (Number(collection.amount) <= 0) {
31316
- ctx.addIssue({
31317
- code: "custom",
31318
- message: "collection.amount must be greater than zero",
31319
- path: ["collections", index, "amount"]
31320
- });
31321
- }
31322
- if (!nearlyEqual(Number(collection.amount), retiredTotal)) {
31323
- ctx.addIssue({
31324
- code: "custom",
31325
- message: "collection.amount must equal sum of certificate retired_amount for the collection slug",
31326
- path: ["collections", index, "amount"]
31327
- });
31328
- }
31277
+ collections: data.collections,
31278
+ retiredTotalsBySlug: collectionRetiredTotalsBySlug
31329
31279
  });
31330
31280
  }).meta({
31331
31281
  title: "Credit Retirement Receipt Data",
@@ -31359,9 +31309,9 @@ var CreditRetirementReceiptIpfsSchema = CreditRetirementReceiptIpfsSchemaBase.sa
31359
31309
  ctx,
31360
31310
  attributeByTraitType,
31361
31311
  traitType: "Total Credits Retired",
31362
- expectedValue: data.summary.total_retirement_amount,
31312
+ expectedValue: data.summary.total_credits_retired,
31363
31313
  missingMessage: 'Attribute "Total Credits Retired" is required',
31364
- mismatchMessage: 'Attribute "Total Credits Retired" must match data.summary.total_retirement_amount'
31314
+ mismatchMessage: 'Attribute "Total Credits Retired" must match data.summary.total_credits_retired'
31365
31315
  });
31366
31316
  validateAttributeValue({
31367
31317
  ctx,
@@ -31390,33 +31340,68 @@ var CreditRetirementReceiptIpfsSchema = CreditRetirementReceiptIpfsSchemaBase.sa
31390
31340
  mismatchMessage: 'Attribute "Credit Holder" must match credit_holder.identity.name'
31391
31341
  });
31392
31342
  }
31393
- validateDateAttribute({
31394
- ctx,
31395
- attributeByTraitType,
31396
- traitType: "Retirement Date",
31397
- dateValue: data.summary.retirement_date,
31398
- missingMessage: 'Attribute "Retirement Date" is required',
31399
- invalidDateMessage: "data.summary.retirement_date must be a valid date string",
31400
- mismatchMessage: 'Attribute "Retirement Date" must match data.summary.retirement_date as a Unix timestamp in milliseconds',
31401
- datePath: ["data", "summary", "retirement_date"]
31402
- });
31403
- validateAttributesForItems({
31404
- ctx,
31405
- attributeByTraitType,
31406
- items: data.credits,
31407
- traitSelector: (credit) => String(credit.symbol),
31408
- valueSelector: (credit) => Number(credit.amount),
31409
- missingMessage: (symbol) => `Attribute for credit symbol ${symbol} is required`,
31410
- mismatchMessage: (symbol) => `Attribute for credit symbol ${symbol} must match credit.amount`
31343
+ const retirementDateAttribute = attributeByTraitType.get("Retirement Date");
31344
+ if (retirementDateAttribute) {
31345
+ const dateMs = Date.parse(data.summary.retired_at);
31346
+ if (Number.isNaN(dateMs)) {
31347
+ ctx.addIssue({
31348
+ code: "custom",
31349
+ message: "data.summary.retired_at must be a valid ISO 8601 date-time string",
31350
+ path: ["data", "summary", "retired_at"]
31351
+ });
31352
+ } else if (retirementDateAttribute.value !== dateMs) {
31353
+ ctx.addIssue({
31354
+ code: "custom",
31355
+ message: 'Attribute "Retirement Date" must match data.summary.retired_at as a Unix timestamp in milliseconds',
31356
+ path: ["attributes"]
31357
+ });
31358
+ }
31359
+ } else {
31360
+ ctx.addIssue({
31361
+ code: "custom",
31362
+ message: 'Attribute "Retirement Date" is required',
31363
+ path: ["attributes"]
31364
+ });
31365
+ }
31366
+ if (data.purchase_receipt) {
31367
+ const purchaseReceiptAttribute = attributeByTraitType.get("Purchase Receipt");
31368
+ if (purchaseReceiptAttribute) {
31369
+ const expectedTokenId = `#${data.purchase_receipt.token_id}`;
31370
+ if (purchaseReceiptAttribute.value !== expectedTokenId) {
31371
+ ctx.addIssue({
31372
+ code: "custom",
31373
+ message: 'Attribute "Purchase Receipt" must match purchase_receipt.token_id as #<token_id> when present',
31374
+ path: ["attributes"]
31375
+ });
31376
+ }
31377
+ }
31378
+ }
31379
+ const creditTotalsBySymbol = /* @__PURE__ */ new Map();
31380
+ data.certificates.forEach((certificate) => {
31381
+ certificate.credits_retired.forEach((creditRetired) => {
31382
+ const currentTotal = creditTotalsBySymbol.get(creditRetired.credit_symbol) ?? 0;
31383
+ creditTotalsBySymbol.set(
31384
+ creditRetired.credit_symbol,
31385
+ currentTotal + Number(creditRetired.amount)
31386
+ );
31387
+ });
31411
31388
  });
31412
- validateAttributesForItems({
31413
- ctx,
31414
- attributeByTraitType,
31415
- items: data.collections,
31416
- traitSelector: (collection) => String(collection.name),
31417
- valueSelector: (collection) => Number(collection.amount),
31418
- missingMessage: (name) => `Attribute for collection ${name} is required`,
31419
- mismatchMessage: (name) => `Attribute for collection ${name} must match collection.amount`
31389
+ data.credits.forEach((credit) => {
31390
+ const expectedTotal = creditTotalsBySymbol.get(credit.symbol) ?? 0;
31391
+ const attribute = attributeByTraitType.get(credit.symbol);
31392
+ if (!attribute) {
31393
+ ctx.addIssue({
31394
+ code: "custom",
31395
+ message: `Attribute for credit symbol ${credit.symbol} is required`,
31396
+ path: ["attributes"]
31397
+ });
31398
+ } else if (Number(attribute.value) !== expectedTotal) {
31399
+ ctx.addIssue({
31400
+ code: "custom",
31401
+ message: `Attribute for credit symbol ${credit.symbol} must match sum of certificate credits_retired amounts for the credit symbol`,
31402
+ path: ["attributes"]
31403
+ });
31404
+ }
31420
31405
  });
31421
31406
  }).meta(CreditRetirementReceiptIpfsSchemaMeta);
31422
31407
  var CollectionSchemaMeta = {
@@ -31605,6 +31590,8 @@ exports.BRAZIL_SUBDIVISION_CODES = BRAZIL_SUBDIVISION_CODES;
31605
31590
  exports.BaseIpfsSchema = BaseIpfsSchema;
31606
31591
  exports.BlockchainChainIdSchema = BlockchainChainIdSchema;
31607
31592
  exports.BlockchainNetworkNameSchema = BlockchainNetworkNameSchema;
31593
+ exports.CertificateCollectionItemPurchaseSchema = CertificateCollectionItemPurchaseSchema;
31594
+ exports.CertificateCollectionItemRetirementSchema = CertificateCollectionItemRetirementSchema;
31608
31595
  exports.CertificateIssuanceDateAttributeSchema = CertificateIssuanceDateAttributeSchema;
31609
31596
  exports.CitySchema = CitySchema;
31610
31597
  exports.CollectionNameSchema = CollectionNameSchema;
@@ -31666,8 +31653,8 @@ exports.MassIDIpfsSchema = MassIDIpfsSchema;
31666
31653
  exports.MassIDIpfsSchemaMeta = MassIDIpfsSchemaMeta;
31667
31654
  exports.MassIDRecyclingDateAttributeSchema = MassIDRecyclingDateAttributeSchema;
31668
31655
  exports.MassIDReferenceSchema = MassIDReferenceSchema;
31656
+ exports.MassIDReferenceWithContractSchema = MassIDReferenceWithContractSchema;
31669
31657
  exports.MassIDTokenIdAttributeSchema = MassIDTokenIdAttributeSchema;
31670
- exports.MassIdReferenceWithContractSchema = MassIdReferenceWithContractSchema;
31671
31658
  exports.MethodologyAttributeSchema = MethodologyAttributeSchema;
31672
31659
  exports.MethodologyDataSchema = MethodologyDataSchema;
31673
31660
  exports.MethodologyNameSchema = MethodologyNameSchema;
@@ -31736,9 +31723,14 @@ exports.uniqueArrayItems = uniqueArrayItems;
31736
31723
  exports.uniqueBy = uniqueBy;
31737
31724
  exports.validateAttributeValue = validateAttributeValue;
31738
31725
  exports.validateAttributesForItems = validateAttributesForItems;
31726
+ exports.validateCertificateCollectionSlugs = validateCertificateCollectionSlugs;
31727
+ exports.validateCollectionsHaveRetiredAmounts = validateCollectionsHaveRetiredAmounts;
31739
31728
  exports.validateCountMatches = validateCountMatches;
31729
+ exports.validateCreditSlugExists = validateCreditSlugExists;
31730
+ exports.validateCreditSymbolExists = validateCreditSymbolExists;
31740
31731
  exports.validateDateAttribute = validateDateAttribute;
31741
31732
  exports.validateLocationBrazilData = validateLocationBrazilData;
31733
+ exports.validateRetirementReceiptRequirement = validateRetirementReceiptRequirement;
31742
31734
  exports.validateSummaryListMatchesData = validateSummaryListMatchesData;
31743
31735
  exports.validateTotalMatches = validateTotalMatches;
31744
31736
  //# sourceMappingURL=index.cjs.map