Skip to content

MsgUpdateCollection updates an existing collection's fields with update flags. Manager only, permissions enforced.

Updates fields of an existing collection. Only the current manager can sign it, and every change must be allowed by the permissions that were in effect before the message.

Example

bash
bb tx tokenization update-collection ./update-collection.json --from alice --chain-id bitbadges-1
ts
import { BitBadgesSigningClient, GenericCosmosAdapter, MsgUpdateCollection } from 'bitbadges';

const adapter = await GenericCosmosAdapter.fromMnemonic(process.env.MNEMONIC!, 'bitbadges-1');
const client = new BitBadgesSigningClient({ adapter, network: 'mainnet' });

// Grow the collection to 200 token IDs and point their metadata at the same URI.
const msg = new MsgUpdateCollection({
  creator: 'bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d',
  collectionId: 1n,
  updateValidTokenIds: true,
  validTokenIds: [{ start: 1n, end: 200n }],
  updateCollectionPermissions: false,
  collectionPermissions: {
  },
  updateManager: false,
  manager: '',
  updateCollectionMetadata: false,
  collectionMetadata: { uri: '', customData: '' },
  updateTokenMetadata: true,
  tokenMetadata: [
    {
      uri: 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json',
      customData: '',
      tokenIds: [{ start: 1n, end: 200n }]
    }
  ],
  updateCustomData: false,
  customData: '',
  updateCollectionApprovals: false,
  collectionApprovals: [],
  updateStandards: false,
  standards: [],
  updateIsArchived: false,
  isArchived: false,
  mintEscrowCoinsToTransfer: [],
  cosmosCoinWrapperPathsToAdd: [],
  aliasPathsToAdd: []
});

const result = await client.signAndBroadcast([msg]);
console.log(result.txHash, result.success);
import { BitBadgesSigningClient, GenericCosmosAdapter, MsgUpdateCollection } from 'bitbadges';

const adapter = await GenericCosmosAdapter.fromMnemonic(process.env.MNEMONIC!, 'bitbadges-1');
const client = new BitBadgesSigningClient({ adapter, network: 'mainnet' });

// Grow the collection to 200 token IDs and point their metadata at the same URI.
const msg = new MsgUpdateCollection({
  creator: 'bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d',
  collectionId: 1n,
  updateValidTokenIds: true,
  validTokenIds: [{ start: 1n, end: 200n }],
  updateCollectionPermissions: false,
  collectionPermissions: {
    canDeleteCollection: [],
    canArchiveCollection: [],
    canUpdateStandards: [],
    canUpdateCustomData: [],
    canUpdateManager: [],
    canUpdateCollectionMetadata: [],
    canUpdateValidTokenIds: [],
    canUpdateTokenMetadata: [],
    canUpdateCollectionApprovals: [],
    canAddMoreAliasPaths: [],
    canAddMoreCosmosCoinWrapperPaths: []
  },
  updateManager: false,
  manager: '',
  updateCollectionMetadata: false,
  collectionMetadata: { uri: '', customData: '' },
  updateTokenMetadata: true,
  tokenMetadata: [
    {
      uri: 'ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json',
      customData: '',
      tokenIds: [{ start: 1n, end: 200n }]
    }
  ],
  updateCustomData: false,
  customData: '',
  updateCollectionApprovals: false,
  collectionApprovals: [],
  updateStandards: false,
  standards: [],
  updateIsArchived: false,
  isArchived: false,
  mintEscrowCoinsToTransfer: [],
  cosmosCoinWrapperPathsToAdd: [],
  aliasPathsToAdd: []
});

const result = await client.signAndBroadcast([msg]);
console.log(result.txHash, result.success);
json
{
  "creator": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "collectionId": "1",
  "updateValidTokenIds": true,
  "validTokenIds": [{ "start": "1", "end": "200" }],
  "manager": "",
  "collectionMetadata": { "uri": "", "customData": "" },
  "updateTokenMetadata": true,
  "tokenMetadata": [
    {
      "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json",
      "tokenIds": [{ "start": "1", "end": "200" }]
    }
  ]
}
{
  "creator": "bb1p0rrel3365scadq5k9pv0x0zp9j22js6dnw70d",
  "collectionId": "1",
  "updateValidTokenIds": true,
  "validTokenIds": [{ "start": "1", "end": "200" }],
  "updateCollectionPermissions": false,
  "collectionPermissions": {
    "canDeleteCollection": [],
    "canArchiveCollection": [],
    "canUpdateStandards": [],
    "canUpdateCustomData": [],
    "canUpdateManager": [],
    "canUpdateCollectionMetadata": [],
    "canUpdateValidTokenIds": [],
    "canUpdateTokenMetadata": [],
    "canUpdateCollectionApprovals": [],
    "canAddMoreAliasPaths": [],
    "canAddMoreCosmosCoinWrapperPaths": []
  },
  "updateManager": false,
  "manager": "",
  "updateCollectionMetadata": false,
  "collectionMetadata": { "uri": "", "customData": "" },
  "updateTokenMetadata": true,
  "tokenMetadata": [
    {
      "uri": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi/{id}.json",
      "customData": "",
      "tokenIds": [{ "start": "1", "end": "200" }]
    }
  ],
  "updateCustomData": false,
  "customData": "",
  "updateCollectionApprovals": false,
  "collectionApprovals": [],
  "updateStandards": false,
  "standards": [],
  "updateIsArchived": false,
  "isArchived": false,
  "mintEscrowCoinsToTransfer": [],
  "cosmosCoinWrapperPathsToAdd": [],
  "aliasPathsToAdd": []
}

Fields

Each updatable field pairs with an update* flag. When the flag is true the value replaces the stored value. When the flag is false the value is ignored, so placeholder data is safe.

FieldTypeRequiredDescription
creatorstringyesSigner. Must be the current manager.
collectionIdUintyesCollection to update.
updateValidTokenIds, validTokenIdsbool, UintRange[]noAdd token IDs. Must stay one range from 1. Only newly added IDs are checked against canUpdateValidTokenIds.
updateCollectionPermissions, collectionPermissionsbool, CollectionPermissionsnoNew permissions. Applied last; cannot re-open a permanently forbidden time.
updateManager, managerbool, stringnoNew manager. Checked against canUpdateManager.
updateCollectionMetadata, collectionMetadatabool, CollectionMetadatanoChecked against canUpdateCollectionMetadata.
updateTokenMetadata, tokenMetadatabool, TokenMetadata[]noChecked against canUpdateTokenMetadata for the affected token IDs.
updateCustomData, customDatabool, stringnoChecked against canUpdateCustomData.
updateCollectionApprovals, collectionApprovalsbool, CollectionApproval[]noFull replacement list. Checked against canUpdateCollectionApprovals.
updateStandards, standardsbool, string[]noChecked against canUpdateStandards.
updateIsArchived, isArchivedbool, boolnoChecked against canArchiveCollection when the value changes.
mintEscrowCoinsToTransferCoin[]noCoins sent from the creator to the mint escrow address.
cosmosCoinWrapperPathsToAddCosmosCoinWrapperPathAddObject[]noNeeds canAddMoreCosmosCoinWrapperPaths.
aliasPathsToAddAliasPathAddObject[]noNeeds canAddMoreAliasPaths.

There is no invariants field. Invariants are creation-only; set them with MsgCreateCollection.

Response

FieldTypeDescription
collectionIdUintThe updated collection.
approvalChangesApprovalChange[]Approvals created, edited, or deleted (only when updateCollectionApprovals is true).
reviewItemsstring[]Advisory notes.

Behavior

  • The handler forwards to MsgUniversalUpdateCollection with invariants omitted. Every rule there applies.
  • Permission checks use the permissions stored before the message. New permissions in the same message apply last, so they take effect from the next transaction.
  • The x/gov authority may sign in place of the manager.
  • An archived collection rejects every update except one that sets isArchived: false.
  • Collection approvals keep their version when unchanged. A new or changed approval gets an incremented version. Approvals that are not auto-scannable get mustPrioritize forced on.
  • mustOwnTokens entries with collectionId: "0" resolve to this collection.
  • Errors: ErrCollectionNotExists, ErrSenderIsNotManager, ErrCollectionIsArchived, plus the permission error for the field that was locked.

Edit this page on GitHub