Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add transfer method to tip002 #3632

Merged
merged 6 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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