A professional-grade NFT platform for luxury goods authentication and loyalty rewards, built on the Stacks blockchain using Clarity 4.
LuxuryGoods enables luxury brands to issue NFTs as digital certificates of authenticity and loyalty rewards to their customers. Each NFT represents a verified purchase of a luxury item and can unlock exclusive benefits, discounts, and rewards.
- π« Claim-based minting with signature verification
- π₯ Token burning for redemption scenarios
- β Approval system for delegated transfers
- π¨ Dynamic metadata with configurable base URI
- π Transferrability controls for soulbound scenarios
- π Campaign tracking with optional caps
- π‘οΈ Professional error handling and validation
- Blockchain: Stacks (Bitcoin Layer 2)
- Smart Contract Language: Clarity 4 (Epoch 3.0)
- Testing Framework: Vitest with @stacks/clarinet-sdk
- Development Tools: Clarinet, TypeScript
Before you begin, ensure you have the following installed:
git clone <repository-url>
cd LuxuryGoodssnpm installclarinet checknpm run testnpm run test:reportnpm run test:watchThe main NFT contract implementing SIP-009 NFT standard with custom extensions.
-
claim- Mint a new NFT with signature verification(claim (cid uint) (verify-id uint) (cap uint) (recipient principal) (signature (buff 65))) -
transfer- Transfer NFT to another address(transfer (token-id uint) (sender principal) (recipient principal))
-
burn- Destroy an NFT (owner only)(burn (token-id uint))
-
set-approval- Approve an operator for transfers(set-approval (token-id uint) (operator principal))
-
set-base-uri- Update metadata base URI(set-base-uri (new-uri (string-ascii 256))) -
set-transferrable- Enable/disable transfers(set-transferrable (new-state bool))
-
set-contract-owner- Transfer contract ownership(set-contract-owner (new-owner principal))
-
set-signer-key- Update signature verification key(set-signer-key (new-key (buff 33)))
get-name- Returns "LuxuryNFT"get-symbol- Returns "LUXE"get-token-count- Total minted tokensget-token-uri- Metadata URI for a tokenget-token-owner- Owner of a tokenget-token-operator- Approved operator for a tokenget-campaign-stats- Number of tokens minted for a campaignis-verify-id-used- Check if a verify-id has been usedget-base-uri- Current base URIget-contract-address- Contract's principal address
| Code | Constant | Description |
|---|---|---|
| u100 | ERR-OWNER-ONLY | Caller is not the contract owner |
| u101 | ERR-NOT-TOKEN-OWNER | Caller is not the token owner |
| u102 | ERR-INVALID-SIGNATURE | Invalid signature or verify-id already used |
| u103 | ERR-CAP-REACHED | Campaign minting cap reached |
| u104 | ERR-INVALID-SIGNER-KEY | Invalid signer public key |
| u105 | ERR-NON-TRANSFERRABLE | Transfers are disabled |
| u106 | ERR-INVALID-ADDRESS | Invalid principal address |
| u107 | ERR-NOT-APPROVED | Caller not approved for operation |
| u108 | ERR-TOKEN-NOT-FOUND | Token does not exist |
| u109 | ERR-CANNOT-BURN | Token burning failed |
nftTrait.clar- Standard SIP-009 NFT traitnftApprovable-trait.clar- Extended trait with approval system
The contract uses a campaign-based minting system:
- Campaign ID (cid): Identifies a specific marketing campaign or product line
- Verify ID: Unique identifier for each claim (prevents double-claiming)
- Cap: Optional limit on NFTs per campaign (0 = unlimited)
- Signature: Cryptographic proof from authorized signer
sequenceDiagram
participant Customer
participant Backend
participant Contract
Customer->>Backend: Purchase luxury item
Backend->>Backend: Generate verify-id & signature
Backend->>Customer: Return claim parameters
Customer->>Contract: Call claim()
Contract->>Contract: Verify signature
Contract->>Contract: Check cap & verify-id
Contract->>Customer: Mint NFT
stateDiagram-v2
[*] --> Claimed: claim()
Claimed --> Transferred: transfer()
Transferred --> Transferred: transfer()
Claimed --> Approved: set-approval()
Approved --> Transferred: transfer() by operator
Claimed --> Burned: burn()
Transferred --> Burned: burn()
Burned --> [*]
The project is configured for Clarity 4:
[contracts.LuxuryNFT]
path = 'contracts/LuxuryNFT.clar'
clarity_version = 3
epoch = 3.0Uses the latest Stacks ecosystem dependencies:
{
"@stacks/clarinet-sdk": "^3.10.0",
"@stacks/transactions": "^6.12.0"
}// Set the signer public key for verification
const signerKey = Cl.bufferFromHex("02...");
simnet.callPublicFn("LuxuryNFT", "set-signer-key", [signerKey], deployer);
// Set metadata base URI
const baseUri = Cl.stringAscii("https://metadata.luxurygoods.com/");
simnet.callPublicFn("LuxuryNFT", "set-base-uri", [baseUri], deployer);const campaignId = Cl.uint(1);
const verifyId = Cl.uint(12345);
const cap = Cl.uint(1000);
const recipient = Cl.standardPrincipal("ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM");
const signature = Cl.bufferFromHex("...");
const result = simnet.callPublicFn(
"LuxuryNFT",
"claim",
[campaignId, verifyId, cap, recipient, signature],
recipient
);const tokenId = Cl.uint(1);
const sender = Cl.standardPrincipal("ST1...");
const recipient = Cl.standardPrincipal("ST2...");
const result = simnet.callPublicFn(
"LuxuryNFT",
"transfer",
[tokenId, sender, recipient],
sender
);const tokenId = Cl.uint(1);
const result = simnet.callPublicFn("LuxuryNFT", "burn", [tokenId], owner);- Luxury Item Authentication: Issue NFTs as digital certificates of authenticity
- Loyalty Programs: Reward customers with collectible NFTs
- Exclusive Access: Gate content or events based on NFT ownership
- Resale Verification: Track provenance on secondary markets
- Redemption: Burn NFTs to claim physical rewards or discounts
- Signature verification is currently commented out in production code for testing
- Enable signature verification before mainnet deployment
- Store signer private keys securely (HSM recommended)
- Implement proper key rotation mechanisms
- Consider multi-sig for contract ownership
- Audit contracts before production deployment
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
ISC License - See LICENSE file for details
- Built with Clarinet by Hiro Systems
- Powered by Stacks Blockchain
- Implements SIP-009 NFT Standard
For questions or support, please open an issue on GitHub.
Built with β€οΈ for the luxury goods industry