Overview
The Receipt contract (identipay::receipt) implements on-chain transaction receipts that are minted atomically during settlement and transferred to the buyer’s stealth address.
Receipts contain:
- Plaintext: Merchant address, intent hash, timestamp
- Encrypted: Item details, amounts, merchant name, order ID
- Buyer: Using their stealth private key
- Merchant: Using their private key + ephemeral public key (ECDH)
Source Code
Location:contracts/sources/receipt.move:6
Data Structures
ReceiptObject
On-chain receipt object minted during atomic settlement.Sui object identifier (unique receipt ID)
Merchant’s Sui address (plaintext — needed for settlement routing)
SHA3-256 hash of the canonicalized intent (plaintext — needed for verification)
AES-256-GCM ciphertext of the receipt payload (items, amounts, merchant name)
12-byte GCM nonce for decryption
Ephemeral public key E = e*G (for merchant ECDH decryption)
Settlement timestamp in epoch milliseconds
ReceiptMinted
Event emitted when a receipt is minted.Unique object ID of the receipt
Merchant who issued the receipt
Intent hash this receipt corresponds to
Minting timestamp (epoch ms)
Public Functions
mint_receipt
Mint a new receipt. Called by the settlement module during atomic execution. Function Signature:Merchant’s Sui address
SHA3-256 hash of the intent
AES-256-GCM ciphertext of receipt data
12-byte GCM nonce (must be exactly 12 bytes)
Ephemeral X25519 public key (must be exactly 32 bytes)
The minted receipt object
EInvalidNonceLength(0): Nonce is not 12 bytesEInvalidEphemeralPubkey(1): Ephemeral pubkey is not 32 bytesEEmptyPayload(2): Encrypted payload is emptyEEmptyIntentHash(3): Intent hash is empty
public(package) — only callable by the settlement module.
Location: receipt.move:52-83
Accessors
merchant
intent_hash
id
timestamp
receipt.move:109-112
Encryption Scheme
Receipts use AES-256-GCM authenticated encryption with ECDH key derivation.Key Derivation
Key Derivation
Derive AES key:
aes_key = HKDF-SHA256(S, salt="identipay-receipt", info="", length=32)Encryption
Encrypt payload:
ciphertext = AES-256-GCM(key=aes_key, nonce=random(12), plaintext=receipt_json, aad="")Decryption
Buyer:- Derive stealth private key
dfrom stealth address - Compute
S = d * G_merchant(same shared secret) - Derive
aes_key = HKDF-SHA256(S, ...) - Decrypt:
plaintext = AES-256-GCM-Decrypt(aes_key, nonce, ciphertext)
- Use stored merchant private key
k_merchant - Compute
S = k_merchant * E - Derive
aes_key = HKDF-SHA256(S, ...) - Decrypt:
plaintext = AES-256-GCM-Decrypt(aes_key, nonce, ciphertext)
Receipt Payload Format
The encrypted payload is a JSON object:Usage Example
Privacy Guarantees
On-Chain Privacy
On-Chain Privacy
On-chain observers see only ciphertext. Item details, amounts, and merchant name are hidden.
Buyer Privacy
Buyer Privacy
Receipt is transferred to a one-time stealth address. On-chain observers cannot link it to the buyer’s identity.
Merchant Visibility
Merchant Visibility
Merchants can decrypt all receipts they issued (for accounting, dispute resolution). This is by design.
Third-Party Exclusion
Third-Party Exclusion
Only the buyer and merchant can decrypt the receipt. No third party (including contract deployer) has access.
Security Considerations
Authenticated Encryption: AES-GCM provides both confidentiality and authenticity. The authentication tag prevents tampering with the ciphertext.
Key Derivation: HKDF-SHA256 derives the AES key from the ECDH shared secret. This ensures different receipts use different keys even with the same shared secret (via different ephemeral keys).
Dispute Resolution
Receipts enable dispute resolution while preserving privacy:- Buyer files dispute: Buyer claims they didn’t receive items
- Merchant decrypts receipt: Merchant uses their private key to decrypt the receipt on-chain
- Proof of transaction: Merchant provides decrypted receipt showing items, amounts, order ID
- On-chain verification: Anyone can verify the ciphertext matches on-chain data
- Resolution: Dispute resolver (DAO, escrow) makes decision based on evidence
Related Modules
Settlement
Mints receipts during atomic settlement
Warranty
Optional warranty linked to receipt
Trust Registry
Provides merchant public key for encryption
