1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
//! Defines the required context traits for ICS-721 to interact with host
//! machine.
use ibc_core::host::types::identifiers::{ChannelId, PortId};
use ibc_core::primitives::prelude::*;
use ibc_core::primitives::Signer;
use crate::types::error::NftTransferError;
use crate::types::{
ClassData, ClassId, ClassUri, Memo, PrefixedClassId, TokenData, TokenId, TokenUri,
};
pub trait NftContext {
/// Get the class ID of the token
fn get_class_id(&self) -> &ClassId;
/// Get the token ID
fn get_id(&self) -> &TokenId;
/// Get the token URI
fn get_uri(&self) -> Option<&TokenUri>;
/// Get the token Data
fn get_data(&self) -> Option<&TokenData>;
}
pub trait NftClassContext {
/// Get the class ID
fn get_id(&self) -> &ClassId;
/// Get the class URI
fn get_uri(&self) -> Option<&ClassUri>;
/// Get the class Data
fn get_data(&self) -> Option<&ClassData>;
}
/// Read-only methods required in NFT transfer validation context.
pub trait NftTransferValidationContext {
type AccountId: TryFrom<Signer> + PartialEq;
type Nft: NftContext;
type NftClass: NftClassContext;
/// get_port returns the portID for the transfer module.
fn get_port(&self) -> Result<PortId, NftTransferError>;
/// Returns Ok() if the host chain supports sending NFTs.
fn can_send_nft(&self) -> Result<(), NftTransferError>;
/// Returns Ok() if the host chain supports receiving NFTs.
fn can_receive_nft(&self) -> Result<(), NftTransferError>;
/// Validates that the NFT can be created or updated successfully.
///
/// Note: some existing ICS-721 implementations may not strictly adhere to
/// the ICS-721 class data structure. The
/// [`ClassData`] associated with this
/// implementation can take any valid JSON format. If your project requires
/// ICS-721 format for the `ClassData`, ensure correctness by checking with
/// [`parse_as_ics721_data()`](crate::types::Data::parse_as_ics721_data).
fn create_or_update_class_validate(
&self,
class_id: &PrefixedClassId,
class_uri: Option<&ClassUri>,
class_data: Option<&ClassData>,
) -> Result<(), NftTransferError>;
/// Validates that the tokens can be escrowed successfully.
///
/// The owner of the NFT should be checked in this validation.
/// `memo` field allows to incorporate additional contextual details in the
/// escrow validation.
fn escrow_nft_validate(
&self,
from_account: &Self::AccountId,
port_id: &PortId,
channel_id: &ChannelId,
class_id: &PrefixedClassId,
token_id: &TokenId,
memo: &Memo,
) -> Result<(), NftTransferError>;
/// Validates that the NFT can be unescrowed successfully.
fn unescrow_nft_validate(
&self,
to_account: &Self::AccountId,
port_id: &PortId,
channel_id: &ChannelId,
class_id: &PrefixedClassId,
token_id: &TokenId,
) -> Result<(), NftTransferError>;
/// Validates the receiver account and the NFT input
///
/// Note: some existing ICS-721 implementations may not strictly adhere to
/// the ICS-721 token data structure. The
/// [`TokenData`] associated with this
/// implementation can take any valid JSON format. If your project requires
/// ICS-721 format for `TokenData`, ensure correctness by checking with
/// [`parse_as_ics721_data()`](crate::types::Data::parse_as_ics721_data).
fn mint_nft_validate(
&self,
account: &Self::AccountId,
class_id: &PrefixedClassId,
token_id: &TokenId,
token_uri: Option<&TokenUri>,
token_data: Option<&TokenData>,
) -> Result<(), NftTransferError>;
/// Validates the sender account and the coin input before burning.
///
/// The owner of the NFT should be checked in this validation.
/// `memo` field allows to incorporate additional contextual details in the
/// burn validation.
fn burn_nft_validate(
&self,
account: &Self::AccountId,
class_id: &PrefixedClassId,
token_id: &TokenId,
memo: &Memo,
) -> Result<(), NftTransferError>;
/// Returns a hash of the prefixed class ID and the token ID.
/// Implement only if the host chain supports hashed class ID and token ID.
fn token_hash_string(
&self,
_class_id: &PrefixedClassId,
_token_id: &TokenId,
) -> Option<String> {
None
}
/// Returns the NFT
fn get_nft(
&self,
class_id: &PrefixedClassId,
token_id: &TokenId,
) -> Result<Self::Nft, NftTransferError>;
/// Returns the NFT class
fn get_nft_class(&self, class_id: &PrefixedClassId)
-> Result<Self::NftClass, NftTransferError>;
}
/// Read-write methods required in NFT transfer execution context.
pub trait NftTransferExecutionContext: NftTransferValidationContext {
/// Creates a new NFT Class identified by classId. If the class ID already exists, it updates the class metadata.
fn create_or_update_class_execute(
&self,
class_id: &PrefixedClassId,
class_uri: Option<&ClassUri>,
class_data: Option<&ClassData>,
) -> Result<(), NftTransferError>;
/// Executes the escrow of the NFT in a user account.
///
/// `memo` field allows to incorporate additional contextual details in the
/// escrow execution.
fn escrow_nft_execute(
&mut self,
from_account: &Self::AccountId,
port_id: &PortId,
channel_id: &ChannelId,
class_id: &PrefixedClassId,
token_id: &TokenId,
memo: &Memo,
) -> Result<(), NftTransferError>;
/// Executes the unescrow of the NFT in a user account.
fn unescrow_nft_execute(
&mut self,
to_account: &Self::AccountId,
port_id: &PortId,
channel_id: &ChannelId,
class_id: &PrefixedClassId,
token_id: &TokenId,
) -> Result<(), NftTransferError>;
/// Executes minting of the NFT in a user account.
fn mint_nft_execute(
&mut self,
account: &Self::AccountId,
class_id: &PrefixedClassId,
token_id: &TokenId,
token_uri: Option<&TokenUri>,
token_data: Option<&TokenData>,
) -> Result<(), NftTransferError>;
/// Executes burning of the NFT in a user account.
///
/// `memo` field allows to incorporate additional contextual details in the
/// burn execution.
fn burn_nft_execute(
&mut self,
account: &Self::AccountId,
class_id: &PrefixedClassId,
token_id: &TokenId,
memo: &Memo,
) -> Result<(), NftTransferError>;
}