Cosmos Coin Wrapper Paths
Cosmos Wrapper Paths enable wrapping between BitBadges tokens and native Cosmos SDK coin (x/bank) asset types, making tokens IBC-compatible. These paths automatically mint and burn tokens when transferring to/from specific wrapper addresses.
This is used to generate a 1:1 compatible mapping between our standard tokens and native Cosmos SDK coins. Note that this does not use an existing IBC denom, but rather creates a custom generated denomination.
Use cases could include:
Using our standard tokens for time-dependent logic but eventually making them native Cosmos SDK coins
Compatibility with existing Cosmos services and chains like Osmosis, Juno, etc.
Important: Since wrapper addresses are uncontrollable (no private keys), approval design requires careful consideration. You must override the wrapper address's user-level approvals where necessary using collection approvals to ensure wrapping/unwrapping functions properly.
Core Concept
Wrapper paths create special addresses that convert our standard tokens to native Cosmos SDK coins:
Wrapping: Send our standard tokens to wrapper address β receive native coins (tokens are burned, x/bank coins are minted)
Unwrapping: Send native coins to wrapper address β receive our standard tokens (x/bank coins are burned, tokens are minted)
// Collection with wrapper path
const collection: MsgCreateCollection = {
creator: 'bb1kj9kt5y64n5a8677fhjqnmcc24ht2vy9atmdls',
collectionId: '0', // 0 for new collection
validTokenIds: [{ start: 1n, end: 100n }],
cosmosCoinWrapperPathsToAdd: [
{
denom: 'utoken',
conversion: {
sideA: {
amount: '1', // Required: amount of wrapped coin
},
sideB: [
{
amount: 1n,
tokenIds: [{ start: 1n, end: 100n }],
ownershipTimes: [
{ start: 1n, end: 18446744073709551615n },
],
},
],
},
symbol: 'TOKEN',
denomUnits: [
{
decimals: 6n,
symbol: 'TOKEN',
isDefaultDisplay: true,
},
],
allowOverrideWithAnyValidToken: false,
metadata: { uri: '', customData: '' }, // Optional metadata
},
],
aliasPathsToAdd: [
{
denom: 'utoken-alias',
conversion: {
sideA: {
amount: '1', // Required: amount of wrapped coin
},
sideB: [
{
amount: 1n,
tokenIds: [{ start: 1n, end: 100n }],
ownershipTimes: [
{ start: 1n, end: 18446744073709551615n },
],
},
],
},
symbol: 'ALIAS',
denomUnits: [
{
decimals: 6n,
symbol: 'ALIAS',
isDefaultDisplay: true,
},
],
metadata: { uri: '', customData: '' }, // Optional metadata
},
],
// ... other fields
};Wrapper Paths vs Alias Paths
The system now distinguishes between two separate path types:
Cosmos Coin Wrapper Paths
Used for actual wrapping/unwrapping with minting and burning:
Purpose: Convert tokens to native Cosmos SDK coins and vice versa
Behavior: Tokens are burned when wrapping, coins are minted. Coins are burned when unwrapping, tokens are minted
Use case: IBC transfers, converting tokens to native coins for Cosmos ecosystem compatibility
Storage: Stored in
cosmosCoinWrapperPathsarrayFeatures: Includes
addressfield (wrapper address) andallowOverrideWithAnyValidTokenoption
Alias Paths
Used for compatibility with existing Cosmos SDK interfaces without actual wrapping:
Purpose: Alias denomination support (e.g.,
badgeslp:COLLECTION_ID:denom)Behavior: No minting/burning occurs, only an alias for information purposes
Use case: Compatibility with liquidity pools, DeFi protocols that expect
sdk.CoinformatStorage: Stored in
aliasPathsarray (separate from wrapper paths)See: Alias Compatibility for details
Note: Does not include
addressorallowOverrideWithAnyValidTokenfields
Wrapper Address Generation
Wrapper addresses are auto-generated based on the denom:
Note: The address is generated from the custom denom, not the full badges:collectionId:denom format.
Conversion Structure
Wrapper paths and alias paths use a structured conversion format to define the relationship between wrapped/alias units and badge tokens:
ConversionWithoutDenom
Used by wrapper paths and alias paths (denom stored separately):
Key Points:
sideA.amount: The amount of wrapped/alias coin units (required, must be specified)sideB: Array ofBalanceobjects that define the tokens involved in the conversionThe denom is stored at the path level, not in the conversion (hence "WithoutDenom")
Conversion rate:
sideA.amountwrapped/alias units =sideB[]tokens
Example:
If
sideA.amount = "1"andsideB = [{ amount: 1n, tokenIds: [...], ... }]Then:
1 wrapped coin = 1 token(1:1 conversion)
Example with different rate:
If
sideA.amount = "100"andsideB = [{ amount: 1n, tokenIds: [...], ... }]Then:
100 wrapped coins = 1 token(100:1 conversion)
Configuration Fields
Denom
The base denomination for the wrapped coin. The full Cosmos denomination will be badges:collectionId:denom. Note that badges: is different from the badgeslp: format used for aliases elsewhere.
Conversion
Defines the conversion rate between wrapped coins and tokens using a structured conversion format:
Conversion rate: conversion.sideA.amount wrapped coin = conversion.sideB[] tokens
Key Points:
sideA.amountis required and must be specified (cannot be "0" or nil)sideBcontains theBalances[]that define which tokens participate in wrappingThe denom is stored separately at the path level (not in the conversion)
Denomination Units
Multiple denomination units allow different display formats:
System:
utoken= base unit (0 decimals)mtoken= 1,000utoken(3 decimals)TOKEN= 1,000,000utoken(6 decimals, default display)
Note: Each DenomUnit now includes an optional metadata field of type PathMetadata for additional information.
Allow Override With Any Valid Token
When true, allows the wrapper to accept any SINGLE valid token ID from the collection's validTokenIds range:
How it works:
User transfers token ID 5 to wrapper
System validates token ID 5 is in
validTokenIdsSystem temporarily overrides
conversion.sideB[].tokenIdswith[{ start: 5n, end: 5n }]ignoring the values set in thesideBarrayConversion proceeds with token ID 5
{id} Placeholder Support
You can use {id} in the denom to dynamically replace it with the actual token ID:
Example: Transferring token ID 5 results in denom utoken5.
Metadata
Both wrapper paths and alias paths support optional metadata using the standard metadata structure:
The hosted JSON at the URI typically contains { name, image, description }, though the image is the primary use case. The on-chain symbol field is used for identification, not the metadata name.
Note: Metadata is optional. It's also available on DenomUnit objects for additional per-unit metadata.
Transferability Requirements
Wrapper addresses are subject to the same transferability requirements as any other address. You can user-gate, rate-limit, or apply custom logic:
Conversion Process
Token to Coin (Wrapping)
User transfers tokens to wrapper address
System processes denom (replaces
{id}if present, validates override if enabled)System burns tokens from user's balance
System mints equivalent native coins
Coins credited to user's account
Coin to Token (Unwrapping)
Unwrapping still uses MsgTransferTokens. You initiate a transfer on behalf of the wrapper address:
User initiates
MsgTransferTokenswith wrapper address asfromSystem processes denom (replaces
{id}if present, validates override if enabled)System burns native coins from wrapper address
System mints equivalent tokens
Tokens credited to user's balance
Use Cases
IBC Transfers
Enable cross-chain transfers of wrapped tokens:
DeFi Integration
Use wrapped tokens in Cosmos DeFi protocols:
Permission Control
Adding new cosmos coin wrapper paths to a collection is controlled by the canAddMoreCosmosCoinWrapperPaths permission. This permission allows you to control when managers can add new wrapper paths.
Default Behavior
Empty/Nil Permissions: When
canAddMoreCosmosCoinWrapperPathsis empty or nil, adding paths is allowed (neutral state)Migration: Collections migrated from v21 will have empty permissions, meaning adding paths is allowed by default
Permission Structure
The permission uses the ActionPermission type with time-based controls:
Usage Examples
Allow adding paths at all times:
Lock adding paths forever:
Allow adding paths only during specific period:
Permission Check
When using MsgUniversalUpdateCollection to add wrapper paths via cosmosCoinWrapperPathsToAdd, the system checks the canAddMoreCosmosCoinWrapperPaths permission before processing the paths. If the permission check fails, the transaction will be rejected with an appropriate error message.
Note: The permission is checked before paths are added, but the permission itself can be updated at the end of the transaction (if updateCollectionPermissions is set to true).
Differences from IBC Backed Paths
Minting
Minting/burning of new denom
No minting/burning (uses existing IBC)
Denom Source
Generated denom
Existing IBC denom
Configuration
Can add paths, no edits
Collection invariant
Mint Address
Enabled
Disabled
Last updated