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};
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_OUTPUT_MODULE_NAME: Identifier = Identifier::from_static("alias_output");
11pub const ALIAS_OUTPUT_STRUCT_NAME: Identifier = Identifier::from_static("AliasOutput");
12pub const ALIAS_DYNAMIC_OBJECT_FIELD_KEY: &[u8] = b"alias";
13pub const ALIAS_DYNAMIC_OBJECT_FIELD_KEY_TYPE: &str = "vector<u8>";
14
15#[serde_as]
16#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
17pub struct Alias {
18    /// The ID of the Alias = hash of the Output ID that created the Alias
19    /// Output in Stardust. This is the AliasID from Stardust.
20    pub id: UID,
21
22    /// The last State Controller address assigned before the migration.
23    pub legacy_state_controller: Address,
24    /// A counter increased by 1 every time the alias was state transitioned.
25    pub state_index: u32,
26    /// State metadata that can be used to store additional information.
27    pub state_metadata: Option<Vec<u8>>,
28
29    /// The sender feature.
30    pub sender: Option<Address>,
31    /// The metadata feature.
32    pub metadata: Option<Vec<u8>>,
33
34    /// The immutable issuer feature.
35    pub immutable_issuer: Option<Address>,
36    /// The immutable metadata feature.
37    pub immutable_metadata: Option<Vec<u8>>,
38}
39
40#[serde_as]
41#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
42pub struct AliasOutput {
43    /// This is a "random" UID, not the AliasID from Stardust.
44    pub id: UID,
45
46    /// The amount of coins held by the output.
47    pub balance: Balance,
48    /// The `Bag` holds native tokens, key-ed by the stringified type of the
49    /// asset. Example: key: "0xabcded::soon::SOON", value:
50    /// Balance<0xabcded::soon::SOON>.
51    pub native_tokens: Bag,
52}
53
54impl AliasOutput {
55    /// Create an `AliasOutput` from BCS bytes.
56    pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
57        bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
58            error: format!("Unable to deserialize AliasOutput object: {err:?}"),
59        })
60    }
61
62    pub fn is_alias_output(s: &StructTag) -> bool {
63        s.address() == Address::STARDUST
64            && s.module() == &ALIAS_OUTPUT_MODULE_NAME
65            && s.name() == &ALIAS_OUTPUT_STRUCT_NAME
66    }
67}
68
69impl TryFrom<&Object> for AliasOutput {
70    type Error = IotaError;
71    fn try_from(object: &Object) -> Result<Self, Self::Error> {
72        match &object.data {
73            ObjectData::Struct(o) => {
74                if AliasOutput::is_alias_output(o.struct_tag()) {
75                    return AliasOutput::from_bcs_bytes(o.contents());
76                }
77            }
78            ObjectData::Package(_) => {}
79        }
80
81        Err(IotaError::Type {
82            error: format!("Object type is not an AliasOutput: {object:?}"),
83        })
84    }
85}