Skip to content

Commit

Permalink
feat: import contract armored
Browse files Browse the repository at this point in the history
  • Loading branch information
crisdut committed Aug 8, 2023
1 parent ea010b4 commit aa97e02
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 36 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ thiserror = "1.0"
tokio = { version = "1.28.2", features = ["macros", "sync"] }
zeroize = "1.6.0"
blake3 = "1.4.1"
base85 = "2.0.0"

[target.'cfg(target_arch = "wasm32")'.dependencies]
bdk = { version = "0.28.0", features = [
Expand Down
1 change: 1 addition & 0 deletions src/rgb/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ where
))
}
};

let genesis_strict = genesis_serialized.to_hex();
let genesis_legacy = match encode(
"rgb",
Expand Down
57 changes: 41 additions & 16 deletions src/rgb/import.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::str::FromStr;

use amplify::{
confinement::{Confined, U32},
hex::FromHex,
};
use bech32::{decode, FromBase32};
use rgb_schemata::{nia_rgb20, nia_schema, uda_rgb21, uda_schema};
use rgbstd::{
containers::Contract,
containers::{Bindle, Contract},
contract::Genesis,
interface::{rgb20, rgb21, IfacePair},
persistence::{Inventory, Stash, Stock},
Expand All @@ -31,22 +33,10 @@ where
R: ResolveHeight + ResolveTx,
R::Error: 'static,
{
let serialized = if contract.starts_with("rgb1") {
let (_, serialized, _) =
decode(contract).expect("invalid serialized contract (bech32m format)");
Vec::<u8>::from_base32(&serialized).expect("invalid hexadecimal contract (bech32m format)")
let contract = if contract.starts_with("-----BEGIN RGB CONTRACT-----") {
contract_from_armored(contract)
} else {
Vec::<u8>::from_hex(contract).expect("invalid hexadecimal contract (baid58 format)")
};

let confined: Confined<Vec<u8>, 0, { U32 }> =
Confined::try_from_iter(serialized.iter().copied())
.expect("invalid strict serialized data");

let contract = match Genesis::from_strict_serialized::<{ U32 }>(confined.clone()) {
Ok(genesis) => contract_from_genesis(genesis, asset_type, Some(stock)),
Err(_) => Contract::from_strict_serialized::<{ U32 }>(confined)
.expect("invalid strict contract data"),
contract_from_other_formats(contract, Some(asset_type), Some(stock))
};

let contract_id = contract.contract_id();
Expand All @@ -65,6 +55,41 @@ where
Ok(contract)
}

pub fn contract_from_armored(contract: &str) -> Contract {
Bindle::<Contract>::from_str(contract)
.expect("invalid serialized contract/genesis (base58 format)")
.unbindle()
}

pub fn contract_from_other_formats(
contract: &str,
asset_type: Option<AssetType>,
stock: Option<&mut Stock>,
) -> Contract {
let serialized = if contract.starts_with("rgb1") {
let (_, serialized, _) =
decode(contract).expect("invalid serialized contract/genesis (bech32m format)");
Vec::<u8>::from_base32(&serialized)
.expect("invalid hexadecimal contract/genesis (bech32m format)")
} else {
Vec::<u8>::from_hex(contract).expect("invalid hexadecimal contract/genesis")
};

let confined: Confined<Vec<u8>, 0, { U32 }> =
Confined::try_from_iter(serialized.iter().copied())
.expect("invalid strict serialized data");

match asset_type {
Some(asset_type) => {
let genesis = Genesis::from_strict_serialized::<{ U32 }>(confined)
.expect("invalid strict genesis data");
contract_from_genesis(genesis, asset_type, stock)
}
None => Contract::from_strict_serialized::<{ U32 }>(confined)
.expect("invalid strict contract data"),
}
}

pub fn contract_from_genesis(
genesis: Genesis,
asset_type: AssetType,
Expand Down
24 changes: 4 additions & 20 deletions src/rgb/prefetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,16 @@ pub async fn prefetch_resolver_rgb(
explorer: &mut ExplorerResolver,
asset_type: Option<AssetType>,
) {
use crate::rgb::import::contract_from_genesis;
use crate::rgb::import::{contract_from_armored, contract_from_other_formats};
use amplify::confinement::U32;
use rgbstd::contract::Genesis;

let esplora_client: EsploraBlockchain =
EsploraBlockchain::new(&explorer.explorer_url, 1).with_concurrency(6);
let serialized = if contract.starts_with("rgb1") {
let (_, serialized, _) =
decode(contract).expect("invalid serialized contract (bech32m format)");
Vec::<u8>::from_base32(&serialized).expect("invalid hexadecimal contract (bech32m format)")
let contract = if contract.starts_with("-----BEGIN RGB CONTRACT-----") {
contract_from_armored(contract)
} else {
Vec::<u8>::from_hex(contract).expect("invalid hexadecimal contract (baid58 format)")
};

let confined: Confined<Vec<u8>, 0, { U32 }> =
Confined::try_from_iter(serialized.iter().copied())
.expect("invalid strict serialized data");

let contract = match asset_type {
Some(asset_type) => match Genesis::from_strict_serialized::<{ U32 }>(confined.clone()) {
Ok(genesis) => contract_from_genesis(genesis, asset_type, None),
Err(_) => Contract::from_strict_serialized::<{ U32 }>(confined)
.expect("invalid strict contract data"),
},
_ => Contract::from_strict_serialized::<{ U32 }>(confined)
.expect("invalid strict contract data"),
contract_from_other_formats(contract, asset_type, None)
};

for anchor_bundle in contract.bundles {
Expand Down
19 changes: 19 additions & 0 deletions tests/rgb/integration/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ async fn allow_import_fungibles_from_genesis() -> anyhow::Result<()> {
Ok(())
}

#[tokio::test]
async fn allow_import_fungibles_from_contract() -> anyhow::Result<()> {
let issuer_resp = issuer_issue_contract("RGB20", 5, false, true, None).await;
assert!(issuer_resp.is_ok());

let another_vault = new_mnemonic(&SecretString("".to_string())).await?;

let sk = &another_vault.private.nostr_prv;
let contract_import = ImportRequest {
import: AssetType::RGB20,
data: issuer_resp?.contract.armored,
};

let import_resp = import(sk, contract_import).await;
assert!(import_resp.is_ok());

Ok(())
}

#[tokio::test]
async fn allow_import_fungibles_from_genesis_data() -> anyhow::Result<()> {
let issuer_keys = save_mnemonic(
Expand Down

0 comments on commit aa97e02

Please sign in to comment.