KidLisp Keeps v4 Production Plan #
Prepared: February 10, 2026
Current Status: v3 in mainnet staging (KT1JEVyKjsMLts63e4CNaMUywWTPgeQ41Smi)
Target: v4 production deployment with 10% royalties
Executive Summary #
✅ GOOD NEWS: Attribution is working correctly in v3!
The current system uses client-side wallet signing (prepare mode) which makes users the firstMinter on TzKT/objkt.com. The token_creators bigmap preserves creator identity for metadata edits. This is exactly how it should work.
⚠️ CRITICAL GAP: No royalty support
Without royalties, creators earn $0 on secondary sales. objkt.com enforces royalties via standard TZIP-21 metadata - we just need to add the fields.
v4 Core Features #
1. 10% Royalty Support (ESSENTIAL) #
Add royalty metadata to every minted token:
# In keep() entrypoint - add to token_info
"royalties": stringToBytes(JSON.stringify({
"decimals": 4,
"shares": {
[creator_wallet]: "1000" // 10% = 1000/10000 basis points
}
}))
Why This Matters:
- 10 XTZ sale = 1 XTZ to creator, 8.75 XTZ to seller, 0.25 XTZ to objkt
- Without royalties: 10 XTZ sale = 0 XTZ to creator, 9.75 XTZ to seller
- Creators lose ~90% of NFT revenue potential
Implementation Effort: 1-2 days
- Modify keeps_fa2_v3.py (add royalty field to token_info)
- Update keep-mint.mjs (add royalty to metadata JSON)
- Update keep-update.mjs (preserve royalty on edits)
- Test on Ghostnet → verify on objkt.com
2. Emergency Pause (HIGH PRIORITY) #
# Add to contract storage
self.data.paused = False
# Admin entrypoints
@sp.entrypoint
def pause(self):
assert self.is_administrator_(), "FA2_NOT_ADMIN"
self.data.paused = True
@sp.entrypoint
def unpause(self):
assert self.is_administrator_(), "FA2_NOT_ADMIN"
self.data.paused = False
# Modify keep() entrypoint
def keep(self, params):
assert not self.data.paused, "CONTRACT_PAUSED"
# ... rest of logic
Why This Matters:
- Security vulnerability discovered? Pause minting immediately
- IPFS infrastructure down? Pause until fixed
- Spam attack? Pause and investigate
- Without pause: Exploits continue until contract replaced
Implementation Effort: 4 hours
3. Admin Transfer (CUSTOMER SERVICE) #
@sp.entrypoint
def admin_transfer(self, params):
"""Emergency transfer for customer service"""
sp.cast(params, sp.record(
token_id=sp.nat,
from_=sp.address,
to_=sp.address
))
assert self.is_administrator_(), "FA2_NOT_ADMIN"
current_owner = self.data.ledger[params.token_id]
assert current_owner == params.from_, "INVALID_CURRENT_OWNER"
self.data.ledger[params.token_id] = params.to_
Use Cases:
- User minted to wrong wallet by mistake
- User lost private keys (with verification)
- Customer service dispute resolution
Implementation Effort: 2 hours
Attribution Analysis ✅ #
Current Flow (v3 - WORKING CORRECTLY) #
1. User: keep $cow
2. Server: /api/keep-mint?mode=prepare
- Validates user owns piece
- Generates bundle + uploads to IPFS
- Returns Michelson params for contract call
3. User: Wallet signs transaction
- User becomes firstMinter (TzKT field)
- Contract stores user in token_creators[tokenId]
- objkt.com reads firstMinter for "Created by" ✅
4. Server: /api/keep-confirm
- Records mint in MongoDB
Proof from Code:
- keep-mint.mjs:888-890 - Comments explicitly state objkt.com uses firstMinter
- keep-mint.mjs:515-527 - Validates wallet matches linked address (prevents hijacking)
- keep-mint.mjs:970 -
ownerAddress = creatorWalletAddress(user wallet used) - keep-update.mjs:206-214 - Fetches firstMinter from TzKT for edit authorization
- keeps_fa2_v3.py:173 -
token_creators[token_id] = params.owner(stores creator)
Conclusion: No attribution fixes needed! v3 is correctly designed.
Deployment Strategy #
Option 1: Fresh v4 (RECOMMENDED) #
Pros:
- Clean start with all features
- Royalties from token #0
- Only 1 token on v3 staging ($roz)
- Professional foundation
Cons:
- New contract address (update env vars)
- Need to re-mint $roz
Process:
# Week 1: Code v4
cd tezos
cp keeps_fa2_v3.py keeps_fa2_v4.py
# Add: royalty support, pause, admin_transfer
# Week 2: Ghostnet
python keeps_fa2_v4.py
node keeps.mjs deploy ghostnet
node keeps.mjs royalty:set 10 --network ghostnet
node keeps.mjs keep $test --network ghostnet
# Verify on https://ghostnet.objkt.com
# Week 3: Mainnet Staging
node keeps.mjs deploy mainnet --wallet staging
# Mint 5-10 test tokens
# Week 4: Production
node keeps.mjs deploy mainnet --wallet kidlisp
# Update KEEPS_CONTRACT env var
# Announce to users
Option 2: Continue v3 (NOT RECOMMENDED) #
Problem: No royalties = creators earn $0 on secondary sales
This is a deal-breaker for NFT adoption. Artists won't mint if they can't earn royalties.
CLI Enhancements #
Add to keeps.mjs:
# Royalty Management
node keeps.mjs royalty:set 10 # Set default to 10%
node keeps.mjs royalty:get # View current default
node keeps.mjs royalty:token <id> # View token-specific
# Emergency Controls
node keeps.mjs pause # Stop minting
node keeps.mjs unpause # Resume
node keeps.mjs status --full # Shows pause + royalty state
# Admin Operations
node keeps.mjs transfer:admin <id> <from> <to> # Customer service
node keeps.mjs metadata:sync <code> # Update from MongoDB
node keeps.mjs metadata:lock <id> # Freeze forever
# Analytics
node keeps.mjs stats # Contract statistics
node keeps.mjs stats:creator <address> # Tokens by creator
node keeps.mjs stats:royalties # Revenue report
Testing Checklist #
Ghostnet v4 Testing #
Mainnet Staging #
Production Launch #
Contract Changes Summary #
Storage Additions #
# NEW in v4
self.data.paused = False
self.data.default_royalty_bps = 1000 # 10%
New Entrypoints #
pause()- Admin only, emergency stopunpause()- Admin only, resumeset_default_royalty(bps)- Admin only, configure royaltyadmin_transfer(token_id, from_, to_)- Admin only, customer serviceget_royalties(token_id)- View, returns royalty config
Modified Entrypoints #
keep() changes:
- Line 87: Add
assert not self.data.paused, "CONTRACT_PAUSED" - After line 153: Add royalty field to token_info
edit_metadata() changes:
- Add pause check
- Preserve royalty fields
Success Metrics #
Technical #
User Experience #
Business #
- 100 mints in first month
- 10 unique creators in first week
- First royalty payment within 30 days
- 50% of tokens listed on objkt.com
Implementation Timeline #
Week 1: Code v4 Contract
- Create keeps_fa2_v4.py from v3
- Add royalty support (10% default)
- Add pause/unpause entrypoints
- Add admin_transfer entrypoint
- Write unit tests
Week 2: Ghostnet Testing
- Compile and deploy
- Configure royalty to 10%
- Mint 10 test tokens
- Verify objkt.com display
- Test pause functionality
- Test admin transfer
Week 3: API Updates
- Update keep-mint.mjs (add royalty metadata)
- Update keep-update.mjs (preserve royalties)
- Update keeps.mjs CLI (new commands)
- Test end-to-end flow
- Deploy to dev environment
Week 4: Mainnet Staging
- Deploy v4 to mainnet
- Mint canonical pieces
- Test secondary sales
- Verify royalty payments
- Monitor for issues
- Prepare production launch
Week 5: Production Launch
- Deploy v4 with kidlisp wallet
- Update KEEPS_CONTRACT env var
- Update MongoDB indexes
- Announce new contract
- Monitor first 24 hours
- Document lessons learned
Critical Files for Implementation #
-
tezos/keeps_fa2_v3.py → keeps_fa2_v4.py
- Add royalty fields to token_info
- Add pause storage + entrypoints
- Add admin_transfer entrypoint
-
system/netlify/functions/keep-mint.mjs
- Lines 913-946: Add royalty to metadataJson
- Add royalty bytes to onChainMetadata
-
system/netlify/functions/keep-update.mjs
- Lines 390-418: Preserve royalty in tokenInfo
-
tezos/keeps.mjs
- Add royalty management commands
- Add pause/unpause commands
- Add admin transfer command
-
tezos/KEEPS-LAUNCH-PLAN.md
- Update with v4 timeline
- Add v4 testing checklist
Risk Mitigation #
Risk: Storage costs increase #
Mitigation: Monitor TzKT, royalty fields are small (~100 bytes)
Risk: Pause abuse #
Mitigation: Multi-sig admin wallet, transparent announcements
Risk: Royalty calculation errors #
Mitigation: Test on Ghostnet with various percentages, cap at 25%
Risk: Admin transfer misuse #
Mitigation: Require written request, audit trail, monthly transparency report
Recommendation #
Deploy fresh v4 with royalties immediately.
Rationale:
- Only 1 token on v3 ($roz can be re-minted)
- Royalties are essential for creator monetization
- Emergency controls critical for production security
- Clean start establishes professional foundation
- v3 attribution system already perfect - just add royalties
Timeline: 4 weeks from code to production
Next Steps:
- Create keeps_fa2_v4.py (1-2 days)
- Test on Ghostnet (3-5 days)
- Update APIs (2-3 days)
- Deploy mainnet staging (1 week testing)
- Production launch (announce + monitor)
Questions? #
Contact: @jeffrey on aesthetic.computer Contract Issues: https://github.com/whistlegraph/aesthetic-computer/issues TzKT Explorer: https://tzkt.io objkt.com: https://objkt.com
Status: Ready to implement Approval: Pending user confirmation Expected Launch: March 2026