Skip to main content

iota_types/stardust/output/
alias.rs

1// Copyright (c) 2024 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use iota_sdk_types::{Address, Identifier, ObjectData, StructTag, TypeTag};
5use serde::{Deserialize, Serialize};
6use serde_with::serde_as;
7
8use crate::{balance::Balance, collection_types::Bag, error::IotaError, id::UID, object::Object};
9
10pub const ALIAS_MODULE_NAME: Identifier = Identifier::from_static("alias");
11pub const ALIAS_OUTPUT_MODULE_NAME: Identifier = Identifier::from_static("alias_output");
12pub const ALIAS_OUTPUT_STRUCT_NAME: Identifier = Identifier::from_static("AliasOutput");
13pub const ALIAS_STRUCT_NAME: Identifier = Identifier::from_static("Alias");
14pub const ALIAS_DYNAMIC_OBJECT_FIELD_KEY: &[u8] = b"alias";
15pub const ALIAS_DYNAMIC_OBJECT_FIELD_KEY_TYPE: &str = "vector<u8>";
16
17#[serde_as]
18#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
19pub struct Alias {
20    /// The ID of the Alias = hash of the Output ID that created the Alias
21    /// Output in Stardust. This is the AliasID from Stardust.
22    pub id: UID,
23
24    /// The last State Controller address assigned before the migration.
25    pub legacy_state_controller: Address,
26    /// A counter increased by 1 every time the alias was state transitioned.
27    pub state_index: u32,
28    /// State metadata that can be used to store additional information.
29    pub state_metadata: Option<Vec<u8>>,
30
31    /// The sender feature.
32    pub sender: Option<Address>,
33    /// The metadata feature.
34    pub metadata: Option<Vec<u8>>,
35
36    /// The immutable issuer feature.
37    pub immutable_issuer: Option<Address>,
38    /// The immutable metadata feature.
39    pub immutable_metadata: Option<Vec<u8>>,
40}
41
42impl Alias {
43    /// Returns the struct tag that represents the fully qualified path of an
44    /// [`Alias`] in its move package.
45    pub fn tag() -> StructTag {
46        StructTag::new(
47            Address::STARDUST,
48            ALIAS_MODULE_NAME,
49            ALIAS_STRUCT_NAME,
50            Vec::new(),
51        )
52    }
53}
54
55#[serde_as]
56#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
57pub struct AliasOutput {
58    /// This is a "random" UID, not the AliasID from Stardust.
59    pub id: UID,
60
61    /// The amount of coins held by the output.
62    pub balance: Balance,
63    /// The `Bag` holds native tokens, key-ed by the stringified type of the
64    /// asset. Example: key: "0xabcded::soon::SOON", value:
65    /// Balance<0xabcded::soon::SOON>.
66    pub native_tokens: Bag,
67}
68
69impl AliasOutput {
70    /// Returns the struct tag that represents the fully qualified path of an
71    /// [`AliasOutput`] in its move package.
72    pub fn tag(type_param: TypeTag) -> StructTag {
73        StructTag::new(
74            Address::STARDUST,
75            ALIAS_OUTPUT_MODULE_NAME,
76            ALIAS_OUTPUT_STRUCT_NAME,
77            vec![type_param],
78        )
79    }
80
81    /// Create an `AliasOutput` from BCS bytes.
82    pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
83        bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
84            error: format!("Unable to deserialize AliasOutput object: {err:?}"),
85        })
86    }
87
88    pub fn is_alias_output(s: &StructTag) -> bool {
89        s.address() == Address::STARDUST
90            && s.module() == &ALIAS_OUTPUT_MODULE_NAME
91            && s.name() == &ALIAS_OUTPUT_STRUCT_NAME
92    }
93}
94
95impl TryFrom<&Object> for AliasOutput {
96    type Error = IotaError;
97    fn try_from(object: &Object) -> Result<Self, Self::Error> {
98        match &object.data {
99            ObjectData::Struct(o) => {
100                if AliasOutput::is_alias_output(o.struct_tag()) {
101                    return AliasOutput::from_bcs_bytes(o.contents());
102                }
103            }
104            ObjectData::Package(_) => {}
105        }
106
107        Err(IotaError::Type {
108            error: format!("Object type is not an AliasOutput: {object:?}"),
109        })
110    }
111}