Skip to content

Commit

Permalink
feat: add transfer method to tip002 (#3632)
Browse files Browse the repository at this point in the history
  • Loading branch information
stringhandler authored Nov 30, 2021
1 parent 75aa0a3 commit 143eac2
Show file tree
Hide file tree
Showing 43 changed files with 996 additions and 221 deletions.
35 changes: 24 additions & 11 deletions applications/tari_app_grpc/proto/validator_node.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ package tari.rpc;
service ValidatorNode {
rpc GetMetadata(GetMetadataRequest) returns (GetMetadataResponse);
rpc GetTokenData(GetTokenDataRequest) returns (GetTokenDataResponse);
rpc ExecuteInstruction(ExecuteInstructionRequest) returns (ExecuteInstructionResponse);
// rpc ExecuteInstruction(ExecuteInstructionRequest) returns (ExecuteInstructionResponse);
rpc InvokeReadMethod(InvokeReadMethodRequest) returns (InvokeReadMethodResponse);
rpc InvokeMethod(InvokeMethodRequest) returns (InvokeMethodResponse);
}

message GetMetadataRequest {
Expand All @@ -54,27 +55,39 @@ message GetTokenDataResponse {

}

message ExecuteInstructionRequest{
//message ExecuteInstructionRequest{
// bytes asset_public_key = 1;
// uint32 template_id = 2;
// string method = 3;
// bytes args = 4;
//// bytes token_id = 5;
//// bytes signature = 6;
//}
//
//message ExecuteInstructionResponse {
// string status = 1;
// optional bytes result = 2;
//}

message InvokeReadMethodRequest{
bytes asset_public_key = 1;
uint32 template_id = 2;
string method = 3;
bytes args = 4;
// bytes token_id = 5;
// bytes signature = 6;
}

message ExecuteInstructionResponse {
string status = 1;
optional bytes result = 2;
message InvokeReadMethodResponse {
optional bytes result = 1;
}

message InvokeReadMethodRequest{
message InvokeMethodRequest{
bytes asset_public_key = 1;
uint32 template_id = 2;
string method = 3;
bytes args = 4;
bytes args = 4;
}

message InvokeReadMethodResponse {
optional bytes result = 1;
message InvokeMethodResponse {
string status = 1;
optional bytes result = 2;
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,44 @@ impl GrpcValidatorNodeClient {
.invoke_read_method(req)
.await
.map(|resp| resp.into_inner())
.map_err(|e| CollectiblesError::ClientRequestError {
source: e,
request: "invoke_read_method".to_string(),
.map_err(|e| {
dbg!(&e);

CollectiblesError::ClientRequestError {
source: e,
request: "invoke_read_method".to_string(),
}
})?;
dbg!(&response);
Ok(response.result)
}

pub async fn invoke_method(
&mut self,
asset_public_key: PublicKey,
template_id: u32,
method: String,
args: Vec<u8>,
) -> Result<Option<Vec<u8>>, CollectiblesError> {
let req = grpc::InvokeMethodRequest {
asset_public_key: Vec::from(asset_public_key.as_bytes()),
template_id,
method,
args,
};
dbg!(&req);
let response = self
.client
.invoke_method(req)
.await
.map(|resp| resp.into_inner())
.map_err(|e| {
dbg!(&e);

CollectiblesError::ClientRequestError {
source: e,
request: "invoke_method".to_string(),
}
})?;
dbg!(&response);
Ok(response.result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@

use crate::{
app_state::ConcurrentAppState,
providers::KeyManagerProvider,
status::Status,
storage::{
models::{asset_row::AssetRow, asset_wallet_row::AssetWalletRow},
AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage, StorageTransaction,
models::{address_row::AddressRow, asset_row::AssetRow, asset_wallet_row::AssetWalletRow},
AddressesTableGateway, AssetWalletsTableGateway, AssetsTableGateway, CollectiblesStorage,
StorageTransaction,
},
};
use prost::Message;
Expand Down Expand Up @@ -94,34 +96,54 @@ pub(crate) async fn asset_wallets_get_balance(
dbg!(&asset_public_key);
let asset_public_key = PublicKey::from_hex(&asset_public_key)?;

let owner = PublicKey::default();
let wallet_id = state
.current_wallet_id()
.await
.ok_or_else(Status::unauthorized)?;

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 total = 0;

let mut client = state.connect_validator_node_client().await?;
let args = tip002::BalanceOfRequest {
owner: Vec::from(owner.as_bytes()),
};
dbg!(&args);
let mut args_bytes = vec![];
args.encode(&mut args_bytes)?;
// let req = grpc::InvokeReadMethodRequest{
// asset_public_key: Vec::from(asset_public_key.as_bytes()),
// template_id: 2,
// method: "BalanceOf",
// args
// };
for owner in addresses {
let args = tip002::BalanceOfRequest {
owner: Vec::from(owner.public_key.as_bytes()),
};
dbg!(&args);
let mut args_bytes = vec![];
args.encode(&mut args_bytes)?;
// let req = grpc::InvokeReadMethodRequest{
// asset_public_key: Vec::from(asset_public_key.as_bytes()),
// template_id: 2,
// method: "BalanceOf",
// args
// };

let resp = client
.invoke_read_method(asset_public_key, 2, "BalanceOf".to_string(), args_bytes)
.await?;
let resp = client
.invoke_read_method(
asset_public_key.clone(),
2,
"BalanceOf".to_string(),
args_bytes,
)
.await?;

dbg!(&resp);
match resp {
Some(resp) => {
let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?;
Ok(proto_resp.balance)
dbg!(&resp);
match resp {
Some(resp) => {
let proto_resp: tip002::BalanceOfResponse = Message::decode(&*resp)?;
total += proto_resp.balance;
}
None => (),
}
None => Ok(0),
}
Ok(total)
}

#[tauri::command]
Expand All @@ -140,3 +162,116 @@ pub(crate) async fn asset_wallets_list(
}
Ok(result)
}

#[tauri::command]
pub(crate) async fn asset_wallets_create_address(
asset_public_key: String,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<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 transaction = db.create_transaction()?;
let asset_id = db
.assets()
.find_by_public_key(&asset_public_key, &transaction)?
.id;
let asset_wallet_row =
db.asset_wallets()
.find_by_asset_and_wallet(asset_id, wallet_id, &transaction)?;

let (key_manager_path, _, address_public_key) = state
.key_manager()
.await
.generate_asset_address(wallet_id, &asset_public_key, None, &transaction)
.map_err(|e| Status::internal(format!("could not generate address key: {}", e)))?;
let address = AddressRow {
id: Uuid::new_v4(),
asset_wallet_id: asset_wallet_row.id,
name: None,
public_key: address_public_key,
key_manager_path: key_manager_path.clone(),
};
dbg!(&address);
db.addresses().insert(&address, &transaction)?;
transaction.commit()?;
Ok(address)
}

#[tauri::command]
pub(crate) async fn asset_wallets_get_latest_address(
asset_public_key: String,
state: tauri::State<'_, ConcurrentAppState>,
) -> Result<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_id = db.assets().find_by_public_key(&asset_public_key, &tx)?.id;
let addresses = db
.addresses()
.find_by_asset_and_wallet(asset_id, wallet_id, &tx)?;
Ok(
addresses
.into_iter()
.last()
.ok_or_else(|| Status::not_found("Address".to_string()))?,
)
}

#[tauri::command]
pub(crate) async fn asset_wallets_send_to(
asset_public_key: String,
amount: u64,
to_address: 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 to_public_key = PublicKey::from_hex(&to_address)?;
let args;
let db = state.create_db().await?;

let tx = db.create_transaction()?;
let asset_id = db.assets().find_by_public_key(&asset_public_key, &tx)?.id;
// TODO: Get addresses with balance
let addresses = db
.addresses()
.find_by_asset_and_wallet(asset_id, wallet_id, &tx)?;

let from_address = Vec::from(
addresses
.first()
.ok_or_else(|| Status::not_found("address".to_string()))?
.public_key
.as_bytes(),
);
args = tip002::TransferRequest {
to: Vec::from(to_public_key.as_bytes()),
amount,
from: from_address.clone(),
caller: from_address,
};

let mut args_bytes = vec![];
args.encode(&mut args_bytes)?;
let mut client = state.connect_validator_node_client().await?;

let resp = client
.invoke_method(asset_public_key, 2, "transfer".to_string(), args_bytes)
.await?;

dbg!(&resp);
Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ pub(crate) async fn assets_create(
let address = AddressRow {
id: Uuid::new_v4(),
asset_wallet_id: asset_wallet_row.id,
name: "Issuer wallet".to_string(),
name: Some("Issuer wallet".to_string()),
public_key: asset_public_key,
key_manager_path: key_manager_path.clone(),
};
Expand Down
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 @@ -38,6 +38,9 @@ fn main() {
commands::asset_wallets::asset_wallets_create,
commands::asset_wallets::asset_wallets_list,
commands::asset_wallets::asset_wallets_get_balance,
commands::asset_wallets::asset_wallets_get_latest_address,
commands::asset_wallets::asset_wallets_create_address,
commands::asset_wallets::asset_wallets_send_to,
commands::keys::next_asset_public_key,
commands::wallets::wallets_create,
commands::wallets::wallets_list,
Expand Down
Loading

0 comments on commit 143eac2

Please sign in to comment.