auto-mint
Mint and distribute tokens to recipients at collection creation time using MsgTransferTokens
Auto-Mint
Instruction text for agents that use the Auto-Mint skill, loaded by bb dev skills auto-mint and the MCP get_skill_instructions tool.
Try it
Paste this into Claude Code, Codex, or Cursor with the BitBadges MCP server wired. The agent loads the skill, builds, verifies, and hands back a link to review and sign.
Load the auto-mint skill and build me one: mint and distribute tokens to recipients at collection creation time using MsgTransferTokens. Use the session tools, run validate, review, and simulate in parallel, fix anything critical, then call get_review_url and give me the link.From a shell, bb dev skills auto-mint prints the same instructions.
Summary
Post-creation minting: adds MsgTransferTokens messages to the transaction so tokens are distributed immediately after collection creation.
- Transaction can contain MsgUniversalUpdateCollection plus one or more MsgTransferTokens messages
- All transfer messages use collectionId: "0" to reference the just-created collection
- prioritizedApprovals must always be specified (use [] if none needed)
- from: "Mint" for minting new tokens, bb1... address for peer-to-peer transfers
- The signing user (creator) is the initiator, collection must have an approval allowing this
- All numbers as strings, "1" not 1
- Prefer predeterminedBalances with x0 increments over maxNumTransfers for better frontend UX
When to use:
- User asks to mint tokens to themselves or others at creation time
- Initial distribution or pre-allocation of tokens
- Manager-only collections where the manager should receive all tokens immediately
When not to use:
- Public mint collections (users mint later via approval)
- Subscription collections (users mint on subscribe)
- Smart tokens (users deposit IBC coins to mint)
- Any collection where minting happens post-creation through approvals
Instructions
Auto-Mint: Post-Creation Transfers
A transaction can contain the collection creation message (MsgUniversalUpdateCollection) plus one or more MsgTransferTokens messages. All use collectionId: "0" to reference the just-created collection.
MsgTransferTokens Structure
{
"typeUrl": "/tokenization.MsgTransferTokens",
"value": {
"creator": "bb1...",
"transfers": [{
"from": "Mint",
"toAddresses": ["bb1recipientaddress..."],
"balances": [{
"amount": "1",
"tokenIds": [{ "start": "1", "end": "1" }],
"ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }]
}],
"prioritizedApprovals": [{
"approvalId": "the-mint-approval-id",
"approvalLevel": "collection"
}]
}]
}
}{
"typeUrl": "/tokenization.MsgTransferTokens",
"value": {
"creator": "bb1...",
"collectionId": "0",
"transfers": [{
"from": "Mint",
"toAddresses": ["bb1recipientaddress..."],
"balances": [{
"amount": "1",
"tokenIds": [{ "start": "1", "end": "1" }],
"ownershipTimes": [{ "start": "1", "end": "18446744073709551615" }]
}],
"prioritizedApprovals": [{
"approvalId": "the-mint-approval-id",
"approvalLevel": "collection",
"approverAddress": "",
"version": "0"
}],
"onlyCheckPrioritizedCollectionApprovals": false,
"onlyCheckPrioritizedIncomingApprovals": false,
"onlyCheckPrioritizedOutgoingApprovals": false,
"memo": ""
}]
}
}When to add a transfer message
- User asks to mint tokens to themselves or others at creation time
- User wants initial distribution or pre-allocation of tokens
- Manager-only collections where the manager should receive all tokens immediately
- Any scenario where tokens should exist in wallets right after collection creation
When not to add a transfer message
- Public mint collections (users mint later via the approval)
- Subscription collections (users mint on subscribe)
- Smart tokens (users deposit IBC coins to mint)
- Any collection where minting happens post-creation through approvals
Critical transfer rules
- prioritizedApprovals must be specified, even if empty []. Match the approvalId to one of the collection's collectionApprovals.
- from: "Mint" for minting new tokens. Use a bb1... address for peer-to-peer transfers.
- The signing user (creator) is the initiator, the collection must have an approval that allows this address as initiatedBy.
- collectionId: "0" is auto-set, it references the collection created by message[0] in the same transaction.
- All numbers as strings, "1" not 1.
- Prefer predeterminedBalances for one-time or fixed-use approvals. Use incrementedBalances with x0 increments (incrementTokenIdsBy: "0", incrementOwnershipTimesBy: "0") instead of relying solely on maxNumTransfers. The frontend auto-detects predeterminedBalances and shows users the exact tokens they will receive, providing much better UX. Avoid manualBalances; incrementedBalances with x0 increments is preferred.
Time-Dependent Ownership
For expiring tokens, calculate timestamps:
- Current time: use get_current_timestamp tool (milliseconds since epoch)
- Example: 5 minutes from now = current timestamp + (5 * 60 * 1000)
{
"ownershipTimes": [{
"start": "1706000000000",
"end": "1706000300000"
}]
}Session-based patch operations
- add_transfer: { op: "add_transfer", transfer: { transfers: [...] } }, appends a MsgTransferTokens to the transaction
- remove_transfer: { op: "remove_transfer", index: 0 }, removes transfer message by index (0-based among transfer messages)
- update_transfer: { op: "update_transfer", index: 0, changes: {...} }, deep-merges changes into the transfer message
Common mistakes
- Don't forget to add prioritizedApprovals in MsgTransferTokens, even if empty ([]), this field must be present or the transfer fails.
- Don't forget that the collection must have a mint approval that allows the creator as initiatedBy.
- Don't add transfer messages for subscription, smart token, or public mint collections, minting happens post-creation through approvals.