feat(traverse): improve native asset access (#259)
This commit is contained in:
parent
9669b5ce7e
commit
fb22d1b0e2
5 changed files with 118 additions and 80 deletions
|
|
@ -1,70 +1,95 @@
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::alonzo;
|
|
||||||
|
|
||||||
use crate::MultiEraAsset;
|
use crate::{MultiEraAsset, MultiEraPolicyAssets};
|
||||||
|
|
||||||
|
impl<'b> MultiEraPolicyAssets<'b> {
|
||||||
|
pub fn policy(&self) -> &Hash<28> {
|
||||||
|
match self {
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleMint(x, _) => x,
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleOutput(x, _) => x,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_output(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleOutput(_, _) => true,
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleMint(_, _) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_mint(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleMint(_, _) => true,
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleOutput(_, _) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assets(&self) -> Vec<MultiEraAsset> {
|
||||||
|
match self {
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleMint(p, x) => x
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| MultiEraAsset::AlonzoCompatibleMint(p, k, *v))
|
||||||
|
.collect(),
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleOutput(p, x) => x
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| MultiEraAsset::AlonzoCompatibleOutput(p, k, *v))
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn collect<'a, T>(&'a self) -> T
|
||||||
|
where
|
||||||
|
T: FromIterator<(&'a [u8], i128)>,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleMint(_, x) => {
|
||||||
|
x.iter().map(|(k, v)| (k.as_slice(), *v as i128)).collect()
|
||||||
|
}
|
||||||
|
MultiEraPolicyAssets::AlonzoCompatibleOutput(_, x) => {
|
||||||
|
x.iter().map(|(k, v)| (k.as_slice(), *v as i128)).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'b> MultiEraAsset<'b> {
|
impl<'b> MultiEraAsset<'b> {
|
||||||
pub fn collect_alonzo_compatible_output(source: &'b alonzo::Multiasset<u64>) -> Vec<Self> {
|
pub fn policy(&self) -> &Hash<28> {
|
||||||
source
|
|
||||||
.iter()
|
|
||||||
.flat_map(|(policy, assets)| {
|
|
||||||
assets.iter().map(|(name, amount)| {
|
|
||||||
MultiEraAsset::AlonzoCompatible(policy, name, *amount as i64)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn collect_alonzo_compatible_mint(source: &'b alonzo::Multiasset<i64>) -> Vec<Self> {
|
|
||||||
source
|
|
||||||
.iter()
|
|
||||||
.flat_map(|(policy, assets)| {
|
|
||||||
assets
|
|
||||||
.iter()
|
|
||||||
.map(|(name, amount)| MultiEraAsset::AlonzoCompatible(policy, name, *amount))
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn policy(&self) -> Option<&Hash<28>> {
|
|
||||||
match self {
|
match self {
|
||||||
Self::AlonzoCompatible(x, ..) => Some(*x),
|
MultiEraAsset::AlonzoCompatibleMint(x, ..) => x,
|
||||||
Self::Lovelace(_) => None,
|
MultiEraAsset::AlonzoCompatibleOutput(x, ..) => x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<&[u8]> {
|
pub fn name(&self) -> &[u8] {
|
||||||
match self {
|
match self {
|
||||||
Self::AlonzoCompatible(_, n, _) => Some(n.as_ref()),
|
MultiEraAsset::AlonzoCompatibleOutput(_, x, _) => x,
|
||||||
Self::Lovelace(_) => None,
|
MultiEraAsset::AlonzoCompatibleMint(_, x, _) => x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn coin(&self) -> i64 {
|
pub fn is_output(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::AlonzoCompatible(_, _, x) => *x,
|
MultiEraAsset::AlonzoCompatibleOutput(..) => true,
|
||||||
Self::Lovelace(x) => *x as i64,
|
MultiEraAsset::AlonzoCompatibleMint(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_alonzo(&self) -> Option<(&alonzo::PolicyId, &alonzo::AssetName, i64)> {
|
pub fn is_mint(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::AlonzoCompatible(a, b, c) => Some((*a, *b, *c)),
|
MultiEraAsset::AlonzoCompatibleMint(..) => true,
|
||||||
_ => None,
|
MultiEraAsset::AlonzoCompatibleOutput(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_subject(&self) -> Option<String> {
|
pub fn coin(&self) -> i128 {
|
||||||
match self {
|
match self {
|
||||||
Self::AlonzoCompatible(p, n, _) => Some(format!("{p}.{}", hex::encode(n.to_vec()))),
|
MultiEraAsset::AlonzoCompatibleOutput(_, _, x) => *x as i128,
|
||||||
_ => None,
|
MultiEraAsset::AlonzoCompatibleMint(_, _, x) => *x as i128,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ascii_name(&self) -> Option<String> {
|
pub fn to_ascii_name(&self) -> Option<String> {
|
||||||
match self {
|
let name = self.name();
|
||||||
Self::AlonzoCompatible(_, n, _) => String::from_utf8(n.to_vec()).ok(),
|
String::from_utf8(name.to_vec()).ok()
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use pallas_codec::utils::KeepRaw;
|
use pallas_codec::utils::{KeepRaw, KeyValuePairs};
|
||||||
use pallas_crypto::hash::Hash;
|
use pallas_crypto::hash::Hash;
|
||||||
use pallas_primitives::{alonzo, babbage, byron};
|
use pallas_primitives::{alonzo, babbage, byron};
|
||||||
|
|
||||||
|
|
@ -112,11 +112,24 @@ pub enum MultiEraMeta<'b> {
|
||||||
AlonzoCompatible(&'b alonzo::Metadata),
|
AlonzoCompatible(&'b alonzo::Metadata),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum MultiEraPolicyAssets<'b> {
|
||||||
|
AlonzoCompatibleMint(
|
||||||
|
&'b alonzo::PolicyId,
|
||||||
|
&'b KeyValuePairs<alonzo::AssetName, i64>,
|
||||||
|
),
|
||||||
|
AlonzoCompatibleOutput(
|
||||||
|
&'b alonzo::PolicyId,
|
||||||
|
&'b KeyValuePairs<alonzo::AssetName, u64>,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum MultiEraAsset<'b> {
|
pub enum MultiEraAsset<'b> {
|
||||||
Lovelace(u64),
|
AlonzoCompatibleOutput(&'b alonzo::PolicyId, &'b alonzo::AssetName, u64),
|
||||||
AlonzoCompatible(&'b alonzo::PolicyId, &'b alonzo::AssetName, i64),
|
AlonzoCompatibleMint(&'b alonzo::PolicyId, &'b alonzo::AssetName, i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@ impl<'b> MultiEraMeta<'b> {
|
||||||
|
|
||||||
pub fn collect<'a, T>(&'a self) -> T
|
pub fn collect<'a, T>(&'a self) -> T
|
||||||
where
|
where
|
||||||
T: FromIterator<(&'a alonzo::MetadatumLabel, &'a alonzo::Metadatum)>,
|
T: FromIterator<(alonzo::MetadatumLabel, &'a alonzo::Metadatum)>,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
MultiEraMeta::NotApplicable => std::iter::empty().collect(),
|
MultiEraMeta::NotApplicable => std::iter::empty().collect(),
|
||||||
MultiEraMeta::Empty => std::iter::empty().collect(),
|
MultiEraMeta::Empty => std::iter::empty().collect(),
|
||||||
MultiEraMeta::AlonzoCompatible(x) => x.iter().map(|(k, v)| (k, v)).collect(),
|
MultiEraMeta::AlonzoCompatible(x) => x.iter().map(|(k, v)| (*k, v)).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use pallas_addresses::{Address, ByronAddress, Error as AddressError};
|
||||||
use pallas_codec::minicbor;
|
use pallas_codec::minicbor;
|
||||||
use pallas_primitives::{alonzo, babbage, byron};
|
use pallas_primitives::{alonzo, babbage, byron};
|
||||||
|
|
||||||
use crate::{Era, MultiEraAsset, MultiEraOutput};
|
use crate::{Era, MultiEraOutput, MultiEraPolicyAssets};
|
||||||
|
|
||||||
impl<'b> MultiEraOutput<'b> {
|
impl<'b> MultiEraOutput<'b> {
|
||||||
pub fn from_byron(output: &'b byron::TxOut) -> Self {
|
pub fn from_byron(output: &'b byron::TxOut) -> Self {
|
||||||
|
|
@ -140,41 +140,32 @@ impl<'b> MultiEraOutput<'b> {
|
||||||
/// Returns a list of Asset structs where each one represent a native asset
|
/// Returns a list of Asset structs where each one represent a native asset
|
||||||
/// present in the output of the tx. ADA assets are not included in this
|
/// present in the output of the tx. ADA assets are not included in this
|
||||||
/// list.
|
/// list.
|
||||||
pub fn non_ada_assets(&self) -> Vec<MultiEraAsset> {
|
pub fn non_ada_assets(&self) -> Vec<MultiEraPolicyAssets> {
|
||||||
match self {
|
match self {
|
||||||
MultiEraOutput::Byron(_) => vec![],
|
MultiEraOutput::Byron(_) => vec![],
|
||||||
MultiEraOutput::Babbage(x) => match x.deref().deref() {
|
MultiEraOutput::Babbage(x) => match x.deref().deref() {
|
||||||
babbage::MintedTransactionOutput::Legacy(x) => match &x.amount {
|
babbage::MintedTransactionOutput::Legacy(x) => match &x.amount {
|
||||||
babbage::Value::Coin(_) => vec![],
|
babbage::Value::Coin(_) => vec![],
|
||||||
babbage::Value::Multiasset(_, x) => {
|
babbage::Value::Multiasset(_, x) => x
|
||||||
MultiEraAsset::collect_alonzo_compatible_output(x)
|
.iter()
|
||||||
}
|
.map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleOutput(k, v))
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
babbage::MintedTransactionOutput::PostAlonzo(x) => match &x.value {
|
babbage::MintedTransactionOutput::PostAlonzo(x) => match &x.value {
|
||||||
babbage::Value::Coin(_) => vec![],
|
babbage::Value::Coin(_) => vec![],
|
||||||
babbage::Value::Multiasset(_, x) => {
|
babbage::Value::Multiasset(_, x) => x
|
||||||
MultiEraAsset::collect_alonzo_compatible_output(x)
|
.iter()
|
||||||
}
|
.map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleOutput(k, v))
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MultiEraOutput::AlonzoCompatible(x) => match &x.amount {
|
MultiEraOutput::AlonzoCompatible(x) => match &x.amount {
|
||||||
alonzo::Value::Coin(_) => vec![],
|
alonzo::Value::Coin(_) => vec![],
|
||||||
alonzo::Value::Multiasset(_, x) => {
|
alonzo::Value::Multiasset(_, x) => x
|
||||||
MultiEraAsset::collect_alonzo_compatible_output(x)
|
.iter()
|
||||||
}
|
.map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleOutput(k, v))
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of all assets in the output
|
|
||||||
///
|
|
||||||
/// Returns a list of Asset structs where each one represent either ADA or a
|
|
||||||
/// native asset present in the output of the tx.
|
|
||||||
pub fn assets(&self) -> Vec<MultiEraAsset> {
|
|
||||||
[
|
|
||||||
vec![MultiEraAsset::Lovelace(self.lovelace_amount())],
|
|
||||||
self.non_ada_assets(),
|
|
||||||
]
|
|
||||||
.concat()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use pallas_primitives::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Era, MultiEraAsset, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraOutput, MultiEraSigners,
|
Era, MultiEraCert, MultiEraInput, MultiEraMeta, MultiEraOutput, MultiEraPolicyAssets,
|
||||||
MultiEraTx, MultiEraWithdrawals, OriginalHash,
|
MultiEraSigners, MultiEraTx, MultiEraWithdrawals, OriginalHash,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'b> MultiEraTx<'b> {
|
impl<'b> MultiEraTx<'b> {
|
||||||
|
|
@ -182,20 +182,22 @@ impl<'b> MultiEraTx<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mints(&self) -> Vec<MultiEraAsset> {
|
pub fn mints(&self) -> Vec<MultiEraPolicyAssets> {
|
||||||
match self {
|
match self {
|
||||||
MultiEraTx::AlonzoCompatible(x, _) => x
|
MultiEraTx::AlonzoCompatible(x, _) => x
|
||||||
.transaction_body
|
.transaction_body
|
||||||
.mint
|
.mint
|
||||||
.as_ref()
|
.iter()
|
||||||
.map(MultiEraAsset::collect_alonzo_compatible_mint)
|
.flat_map(|x| x.iter())
|
||||||
.unwrap_or_default(),
|
.map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleMint(k, v))
|
||||||
|
.collect(),
|
||||||
MultiEraTx::Babbage(x) => x
|
MultiEraTx::Babbage(x) => x
|
||||||
.transaction_body
|
.transaction_body
|
||||||
.mint
|
.mint
|
||||||
.as_ref()
|
.iter()
|
||||||
.map(MultiEraAsset::collect_alonzo_compatible_mint)
|
.flat_map(|x| x.iter())
|
||||||
.unwrap_or_default(),
|
.map(|(k, v)| MultiEraPolicyAssets::AlonzoCompatibleMint(k, v))
|
||||||
|
.collect(),
|
||||||
MultiEraTx::Byron(_) => vec![],
|
MultiEraTx::Byron(_) => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,6 +237,13 @@ impl<'b> MultiEraTx<'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn total_collateral(&self) -> Option<u64> {
|
||||||
|
match self {
|
||||||
|
MultiEraTx::Babbage(x) => x.transaction_body.total_collateral.clone(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the list of inputs consumed by the Tx
|
/// Returns the list of inputs consumed by the Tx
|
||||||
///
|
///
|
||||||
/// Helper method to abstract the logic of which inputs are consumed
|
/// Helper method to abstract the logic of which inputs are consumed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue