mpl_bubblegum/
lib.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use modular_bitfield::{bitfield, specifiers::B5};
3use types::{BubblegumEventType, LeafSchema, Version};
4
5mod generated;
6pub mod hash;
7mod traits;
8pub mod utils;
9
10pub use generated::programs::MPL_BUBBLEGUM_ID as ID;
11pub use generated::*;
12
13pub enum InstructionName {
14    Unknown,
15    MintV1,
16    Redeem,
17    CancelRedeem,
18    Transfer,
19    Delegate,
20    DecompressV1,
21    Compress,
22    Burn,
23    CreateTree,
24    VerifyCreator,
25    UnverifyCreator,
26    VerifyCollection,
27    UnverifyCollection,
28    SetAndVerifyCollection,
29    MintToCollectionV1,
30    SetDecompressibleState,
31    UpdateMetadata,
32    /// V2 instructions have been added that use `LeafSchema` V2.
33    /// See `mint_v2` below for more details on the new functionality.
34    BurnV2,
35    CollectV2,
36    CreateTreeV2,
37    DelegateAndFreezeV2,
38    DelegateV2,
39    FreezeV2,
40    MintV2,
41    SetCollectionV2,
42    SetNonTransferableV2,
43    ThawAndRevokeV2,
44    ThawV2,
45    TransferV2,
46    UnverifyCreatorV2,
47    UpdateAssetDataV2,
48    UpdateMetadataV2,
49    VerifyCreatorV2,
50}
51
52pub fn get_instruction_type(full_bytes: &[u8]) -> InstructionName {
53    let disc: [u8; 8] = {
54        let mut disc = [0; 8];
55        disc.copy_from_slice(&full_bytes[..8]);
56        disc
57    };
58    match disc {
59        [145, 98, 192, 118, 184, 147, 118, 104] => InstructionName::MintV1,
60        [153, 18, 178, 47, 197, 158, 86, 15] => InstructionName::MintToCollectionV1,
61        [111, 76, 232, 50, 39, 175, 48, 242] => InstructionName::CancelRedeem,
62        [184, 12, 86, 149, 70, 196, 97, 225] => InstructionName::Redeem,
63        [163, 52, 200, 231, 140, 3, 69, 186] => InstructionName::Transfer,
64        [90, 147, 75, 178, 85, 88, 4, 137] => InstructionName::Delegate,
65        [54, 85, 76, 70, 228, 250, 164, 81] => InstructionName::DecompressV1,
66        [116, 110, 29, 56, 107, 219, 42, 93] => InstructionName::Burn,
67        [82, 193, 176, 117, 176, 21, 115, 253] => InstructionName::Compress,
68        [165, 83, 136, 142, 89, 202, 47, 220] => InstructionName::CreateTree,
69        [52, 17, 96, 132, 71, 4, 85, 194] => InstructionName::VerifyCreator,
70        [107, 178, 57, 39, 105, 115, 112, 152] => InstructionName::UnverifyCreator,
71        [56, 113, 101, 253, 79, 55, 122, 169] => InstructionName::VerifyCollection,
72        [250, 251, 42, 106, 41, 137, 186, 168] => InstructionName::UnverifyCollection,
73        [235, 242, 121, 216, 158, 234, 180, 234] => InstructionName::SetAndVerifyCollection,
74        [82, 104, 152, 6, 149, 111, 100, 13] => InstructionName::SetDecompressibleState,
75        // `SetDecompressableState` instruction mapped to `SetDecompressibleState` instruction
76        [18, 135, 238, 168, 246, 195, 61, 115] => InstructionName::SetDecompressibleState,
77        [170, 182, 43, 239, 97, 78, 225, 186] => InstructionName::UpdateMetadata,
78        [115, 210, 34, 240, 232, 143, 183, 16] => InstructionName::BurnV2,
79        [21, 11, 159, 47, 4, 195, 106, 56] => InstructionName::CollectV2,
80        [55, 99, 95, 215, 142, 203, 227, 205] => InstructionName::CreateTreeV2,
81        [17, 229, 35, 218, 190, 241, 250, 123] => InstructionName::DelegateAndFreezeV2,
82        [95, 87, 125, 140, 181, 131, 128, 227] => InstructionName::DelegateV2,
83        [200, 151, 244, 102, 16, 195, 255, 3] => InstructionName::FreezeV2,
84        [120, 121, 23, 146, 173, 110, 199, 205] => InstructionName::MintV2,
85        [229, 35, 61, 91, 15, 14, 99, 160] => InstructionName::SetCollectionV2,
86        [181, 141, 206, 58, 242, 199, 152, 168] => InstructionName::SetNonTransferableV2,
87        [86, 214, 190, 37, 167, 4, 28, 116] => InstructionName::ThawAndRevokeV2,
88        [96, 133, 101, 93, 82, 220, 146, 191] => InstructionName::ThawV2,
89        [119, 40, 6, 235, 234, 221, 248, 49] => InstructionName::TransferV2,
90        [174, 112, 29, 142, 230, 100, 239, 7] => InstructionName::UnverifyCreatorV2,
91        [59, 56, 111, 43, 95, 14, 11, 61] => InstructionName::UpdateAssetDataV2,
92        [43, 103, 89, 42, 121, 242, 62, 72] => InstructionName::UpdateMetadataV2,
93        [85, 138, 140, 42, 22, 241, 118, 102] => InstructionName::VerifyCreatorV2,
94        _ => InstructionName::Unknown,
95    }
96}
97
98#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug, Clone)]
99pub struct LeafSchemaEvent {
100    pub event_type: BubblegumEventType,
101    pub version: Version,
102    pub schema: LeafSchema,
103    pub leaf_hash: [u8; 32],
104}
105
106impl LeafSchemaEvent {
107    pub fn new(version: Version, schema: LeafSchema, leaf_hash: [u8; 32]) -> Self {
108        Self {
109            event_type: BubblegumEventType::LeafSchemaEvent,
110            version,
111            schema,
112            leaf_hash,
113        }
114    }
115}
116
117/// Bitfield representation of asset flags.
118#[bitfield(bits = 8)]
119#[derive(Eq, PartialEq, Copy, Clone, Debug, Default)]
120pub struct Flags {
121    /// Frozen at the asset level by the leaf delegate.
122    pub asset_lvl_frozen: bool,
123    /// Frozen by the mpl-core collection permanent freeze delegate.
124    pub permanent_lvl_frozen: bool,
125    /// Set to permanently non-transferable (soulbound).
126    pub non_transferable: bool,
127    /// Unused flags for future asset-level usage.
128    pub empty_bits: B5,
129}
130
131/// Default flags for `LeafSchemaV2`.
132pub const DEFAULT_FLAGS: u8 = 0;