Skip to content

Commit

Permalink
feat: add 721 template stub (#3643)
Browse files Browse the repository at this point in the history
  • Loading branch information
stringhandler authored Dec 8, 2021
1 parent 143eac2 commit 5c276ee
Show file tree
Hide file tree
Showing 55 changed files with 1,571 additions and 614 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-- // Copyright 2021. The Tari Project
-- //
-- // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
-- // following conditions are met:
-- //
-- // 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
-- // disclaimer.
-- //
-- // 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
-- // following disclaimer in the documentation and/or other materials provided with the distribution.
-- //
-- // 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
-- // products derived from this software without specific prior written permission.
-- //
-- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-- // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-- // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

create table tip721_tokens (
id blob not null primary key,
address_id blob not null references addresses(id),
token_id BigInt not null,
is_deleted boolean not null,
token text not null
)
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,9 @@ pub(crate) async fn asset_wallets_get_balance(
.await?;

dbg!(&resp);
match resp {
Some(resp) => {
let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?;
total += proto_resp.balance;
}
None => (),
if let Some(resp) = resp {
let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?;
total += proto_resp.balance;
}
}
Ok(total)
Expand Down Expand Up @@ -194,7 +191,7 @@ pub(crate) async fn asset_wallets_create_address(
asset_wallet_id: asset_wallet_row.id,
name: None,
public_key: address_public_key,
key_manager_path: key_manager_path.clone(),
key_manager_path,
};
dbg!(&address);
db.addresses().insert(&address, &transaction)?;
Expand Down
2 changes: 2 additions & 0 deletions applications/tari_collectibles/src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ use crate::app_state::ConcurrentAppState;
pub mod asset_wallets;
pub mod assets;
pub mod keys;
pub mod tip004;
pub mod tip721;
pub mod wallets;

#[tauri::command]
Expand Down
135 changes: 135 additions & 0 deletions applications/tari_collectibles/src-tauri/src/commands/tip004/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2021. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::{
app_state::ConcurrentAppState,
status::Status,
storage::{
models::{address_row::AddressRow, tip721_token_row::Tip721TokenRow},
AddressesTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction,
Tip721TokensTableGateway,
},
};
use prost::Message;
use tari_common_types::types::PublicKey;
use tari_dan_common_types::proto::tips::tip004;
use tari_utilities::{hex::Hex, ByteArray};
use uuid::Uuid;

#[tauri::command]
pub(crate) async fn tip004_mint_token(
asset_public_key: String,
token: String,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<(), Status> {
let _wallet_id = state
.current_wallet_id()
.await
.ok_or_else(Status::unauthorized)?;
let asset_public_key = PublicKey::from_hex(&asset_public_key)?;
let mut client = state.connect_validator_node_client().await?;
let db = state.create_db().await?;
let tx = db.create_transaction()?;
let _asset = db.assets().find_by_public_key(&asset_public_key, &tx)?;
drop(tx);

// TODO: get signature
let args = tip004::MintRequest {
token,
owner: Vec::from(asset_public_key.as_bytes()),
};
let mut bytes = vec![];
args.encode(&mut bytes)?;
let result = client
.invoke_method(asset_public_key, 4, "mint".to_string(), bytes)
.await?;
dbg!(&result);
Ok(())
}

#[tauri::command]
pub(crate) async fn tip004_list_tokens(
asset_public_key: String,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<Vec<(Tip721TokenRow, AddressRow)>, Status> {
let wallet_id = state
.current_wallet_id()
.await
.ok_or_else(Status::unauthorized)?;
let asset_public_key = PublicKey::from_hex(&asset_public_key)?;
let db = state.create_db().await?;
let tx = db.create_transaction()?;
let asset = db.assets().find_by_public_key(&asset_public_key, &tx)?;
let addresses = db
.addresses()
.find_by_asset_and_wallet(asset.id, wallet_id, &tx)?;
let mut client = state.connect_validator_node_client().await?;
let mut token_ids = vec![];
for address in addresses {
let args = tip004::BalanceOfRequest {
owner: Vec::from(address.public_key.as_bytes()),
};
let result = client
.invoke_read_method(
asset_public_key.clone(),
4,
"balance_of".to_string(),
args.encode_to_vec(),
)
.await?;
dbg!(&result);
db.tip721_tokens().delete_all_for_address(address.id, &tx)?;
if let Some(result) = result {
let balance_of: tip004::BalanceOfResponse = Message::decode(&*result)?;
for index in 0..balance_of.num_tokens {
let args = tip004::TokenOfOwnerByIndexRequest {
owner: Vec::from(address.public_key.as_bytes()),
index,
};
let token_result = client
.invoke_read_method(
asset_public_key.clone(),
4,
"token_of_owner_by_index".to_string(),
args.encode_to_vec(),
)
.await?;
if let Some(token_result) = token_result {
let token_data: tip004::TokenOfOwnerByIndexResponse = Message::decode(&*token_result)?;

let token_row = Tip721TokenRow {
id: Uuid::new_v4(),
address_id: address.id,
token_id: token_data.token_id,
token: token_data.token.clone(),
};

db.tip721_tokens().insert(&token_row, &tx)?;
token_ids.push((token_row, address.clone()));
}
}
}
}
tx.commit()?;

Ok(token_ids)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2021. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::{
app_state::ConcurrentAppState,
status::Status,
storage::{AddressesTableGateway, AssetsTableGateway, CollectiblesStorage},
};
use prost::Message;
use tari_common_types::types::PublicKey;
use tari_dan_common_types::proto::tips::tip721;
use tari_utilities::{hex::Hex, ByteArray};
use uuid::Uuid;

#[tauri::command]
pub(crate) async fn tip721_transfer_from(
asset_public_key: String,
token_id: u64,
send_to_address: String,
from_address_id: Uuid,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<(), Status> {
let wallet_id = state
.current_wallet_id()
.await
.ok_or_else(Status::unauthorized)?;
let asset_public_key = PublicKey::from_hex(&asset_public_key)?;
let send_to_address = PublicKey::from_hex(&send_to_address)?;
let db = state.create_db().await?;
let tx = db.create_transaction()?;
let asset = db.assets().find_by_public_key(&asset_public_key, &tx)?;
let asset_addresses = db
.addresses()
.find_by_asset_and_wallet(asset.id, wallet_id, &tx)?;
let from_address = asset_addresses
.into_iter()
.find(|aa| aa.id == from_address_id)
.ok_or_else(|| Status::not_found("address".to_string()))?;
drop(tx);
let mut client = state.connect_validator_node_client().await?;
let transfer_request = tip721::TransferFromRequest {
from: Vec::from(from_address.public_key.as_bytes()),
to: Vec::from(send_to_address.as_bytes()),
token_id,
};
let transfer_request = transfer_request.encode_to_vec();

let res = client
.invoke_method(
asset_public_key.clone(),
721,
"transfer_from".to_string(),
transfer_request,
)
.await?;
dbg!(&res);
Ok(())
}
3 changes: 3 additions & 0 deletions applications/tari_collectibles/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ fn main() {
commands::asset_wallets::asset_wallets_create_address,
commands::asset_wallets::asset_wallets_send_to,
commands::keys::next_asset_public_key,
commands::tip004::tip004_mint_token,
commands::tip004::tip004_list_tokens,
commands::tip721::tip721_transfer_from,
commands::wallets::wallets_create,
commands::wallets::wallets_list,
commands::wallets::wallets_unlock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,25 @@ use tari_app_grpc::tari_rpc;

#[derive(Serialize, Deserialize)]
pub struct OutputFeatures {
template_ids_implemented: Vec<u32>,
template_parameters: Vec<TemplateParameter>,
}

impl From<tari_rpc::OutputFeatures> for OutputFeatures {
fn from(v: tari_rpc::OutputFeatures) -> Self {
let asset = v.asset.as_ref();
Self {
template_parameters: v
.asset
template_ids_implemented: asset
.map(|f| f.template_ids_implemented.clone())
.unwrap_or_default(),
template_parameters: asset
.map(|f| {
f.template_parameters
.into_iter()
.iter()
.map(|tp| TemplateParameter {
template_id: tp.template_id,
template_data_version: tp.template_data_version,
template_data: tp.template_data,
template_data: tp.template_data.clone(),
})
.collect()
})
Expand Down
12 changes: 12 additions & 0 deletions applications/tari_collectibles/src-tauri/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ table! {
}
}

table! {
tip721_tokens (id) {
id -> Binary,
address_id -> Binary,
token_id -> BigInt,
is_deleted -> Bool,
token -> Text,
}
}

table! {
wallets (id) {
id -> Binary,
Expand All @@ -68,6 +78,7 @@ joinable!(asset_wallets -> assets (asset_id));
joinable!(asset_wallets -> wallets (wallet_id));
joinable!(issued_assets -> wallets (wallet_id));
joinable!(tip002_address -> addresses (address_id));
joinable!(tip721_tokens -> addresses (address_id));

allow_tables_to_appear_in_same_query!(
addresses,
Expand All @@ -76,5 +87,6 @@ allow_tables_to_appear_in_same_query!(
issued_assets,
key_indices,
tip002_address,
tip721_tokens,
wallets,
);
10 changes: 9 additions & 1 deletion applications/tari_collectibles/src-tauri/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ mod storage_error;

use crate::storage::models::{
address_row::AddressRow, asset_row::AssetRow, asset_wallet_row::AssetWalletRow,
key_index_row::KeyIndexRow, tip002_address_row::Tip002AddressRow, wallet_row::WalletRow,
key_index_row::KeyIndexRow, tip002_address_row::Tip002AddressRow,
tip721_token_row::Tip721TokenRow, wallet_row::WalletRow,
};
pub use storage_error::StorageError;
use tari_common_types::types::PublicKey;
Expand All @@ -45,6 +46,7 @@ pub trait CollectiblesStorage {
type Tip002Addresses: Tip002AddressesTableGateway<Self::Transaction>;
type KeyIndices: KeyIndicesTableGateway<Self::Transaction>;
type Wallets: WalletsTableGateway<Self::Transaction>;
type Tip721Tokens: Tip721TokensTableGateway<Self::Transaction>;
type Transaction: StorageTransaction;

fn create_transaction(&self) -> Result<Self::Transaction, StorageError>;
Expand All @@ -53,6 +55,7 @@ pub trait CollectiblesStorage {
fn asset_wallets(&self) -> Self::AssetWallets;
fn issued_assets(&self) -> Self::IssuedAssets;
fn tip002_addresses(&self) -> Self::Tip002Addresses;
fn tip721_tokens(&self) -> Self::Tip721Tokens;
fn key_indices(&self) -> Self::KeyIndices;
fn wallets(&self) -> Self::Wallets;
}
Expand Down Expand Up @@ -122,3 +125,8 @@ pub trait IssuedAssetsTableGateway {}
pub trait Tip002AddressesTableGateway<T: StorageTransaction> {
fn insert(&self, row: &Tip002AddressRow, tx: &T) -> Result<(), StorageError>;
}

pub trait Tip721TokensTableGateway<T: StorageTransaction> {
fn insert(&self, row: &Tip721TokenRow, tx: &T) -> Result<(), StorageError>;
fn delete_all_for_address(&self, address_id: Uuid, tx: &T) -> Result<(), StorageError>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize};
use tari_common_types::types::PublicKey;
use uuid::Uuid;

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AddressRow {
pub id: Uuid,
pub asset_wallet_id: Uuid,
Expand Down
Loading

0 comments on commit 5c276ee

Please sign in to comment.