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

[Feature] Coin Transfer #98

Merged
merged 24 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
80c5112
Changes info icon on the wallet view
soaresa Mar 17, 2022
bbcc91d
Updates Cargo.lock file
soaresa Mar 17, 2022
c764b6c
Fixes balance info for different locales than en-US
soaresa Mar 17, 2022
37044ca
Adds persistence to locale preference
soaresa Mar 18, 2022
5d83d8b
Changes app name from Carpe to carpe
soaresa Mar 22, 2022
086f5a3
Inits account events on account switch
soaresa Mar 24, 2022
f37cbbf
Fixes displaying events of an account off chain
soaresa Mar 24, 2022
72f9387
Adds optimistic account switch
soaresa Mar 28, 2022
51277b2
Unsubscribes Miner subscriptions onDestroy
soaresa Mar 29, 2022
9ac4665
Optimizes Miner components subscriptions
soaresa Mar 29, 2022
00ca089
UX - Adds tower state skeleton
soaresa Mar 29, 2022
622f542
Fixes wallet components memory leak
soaresa Mar 30, 2022
f476886
Adds coin transfer - WIP
soaresa Mar 31, 2022
37ebe5e
Do not notify initial account selection
soaresa Apr 1, 2022
6281b46
Transfers coins
soaresa Apr 1, 2022
a75e984
Coin transfer adjustments
soaresa Apr 4, 2022
c6e6606
Translates onboard and transfer buttons
soaresa Apr 4, 2022
fd49fd4
Fixes modal close on success
soaresa Apr 4, 2022
21baa75
Fixes onboard modal close onSucess
soaresa Apr 4, 2022
f7fc414
Fixes events pagination vertical alignment
soaresa Apr 4, 2022
b877ff8
Fixes check sender vs receiver addresses
soaresa Apr 5, 2022
e963391
Adds sent payments to be displayed on the events tab
soaresa Apr 5, 2022
5e04895
Adds wallet skeleton
soaresa Apr 5, 2022
352d2eb
Removes viewport from components to avoid vertical scroll bar
soaresa Apr 5, 2022
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
166 changes: 83 additions & 83 deletions src-tauri/Cargo.lock

Large diffs are not rendered by default.

29 changes: 23 additions & 6 deletions src-tauri/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,24 @@ pub fn get_balance(account: AccountAddress) -> Result<u64, CarpeError>{
bal.parse::<u64>().map_err(|_|{ CarpeError::misc(&format!("Could not get balance from account: {}", account))})
}

pub fn get_events(account: AccountAddress) -> Result<Vec<EventView>, CarpeError> {
pub fn get_payment_events(account: AccountAddress) -> Result<Vec<EventView>, CarpeError> {
// get payments received
match get_events(account, 0) {
Ok(mut received) => {
// get payments sent
match get_events(account, 1) {
Ok(mut sent) => {
received.append(&mut sent);
Ok(received)
},
Err(e) => Err(CarpeError::misc(&e.msg))
}
},
Err(e) => Err(CarpeError::misc(&e.msg))
}
}

pub fn get_events(account: AccountAddress, event_key: u64) -> Result<Vec<EventView>, CarpeError> {
let node = get_node_obj()?;

let limit = 1000;
Expand All @@ -41,7 +58,7 @@ pub fn get_events(account: AccountAddress) -> Result<Vec<EventView>, CarpeError>

while events_count == limit {
let result = node.client.get_events(
EventKey::new_from_address(&account, 0),
EventKey::new_from_address(&account, event_key),
start,
limit
);
Expand All @@ -62,20 +79,20 @@ pub fn get_events(account: AccountAddress) -> Result<Vec<EventView>, CarpeError>
match error {
Some(e) => {
if e.to_string().contains("DB corrupt") {
return try_again_get_events(account, &node)
return try_again_get_events(account, event_key, &node)
}
Err(CarpeError::misc(&format!("Could not query account events, message: {:?}", e)))
},
None => {
if ret.is_empty() {
return try_again_get_events(account, &node)
return try_again_get_events(account, event_key, &node)
}
Ok(ret)
}
}
}

fn try_again_get_events(account: AccountAddress, current_node: &Node) -> Result<Vec<EventView>, CarpeError> {
fn try_again_get_events(account: AccountAddress, event_key: u64, current_node: &Node) -> Result<Vec<EventView>, CarpeError> {
match remove_node(current_node.client.url().unwrap().to_string()) {
Err(e) => {
if e.to_string().contains("Cannot remove last node") {
Expand All @@ -84,6 +101,6 @@ fn try_again_get_events(account: AccountAddress, current_node: &Node) -> Result<
Err(CarpeError::misc(&format!("Could not query account events, message: {:?}", e)))
}
},
Ok(_) => get_events(account)
Ok(_) => get_events(account, event_key)
}
}
33 changes: 30 additions & 3 deletions src-tauri/src/commands/tx.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! transaction scripts

use diem_types::transaction::authenticator::AuthenticationKey;

use txs::commands::{create_account_cmd::create_from_auth_and_coin, demo_cmd};
use diem_types::{
transaction::authenticator::AuthenticationKey,
account_address::AccountAddress
};
use txs::commands::{create_account_cmd::create_from_auth_and_coin, demo_cmd, transfer_cmd};
use crate::{carpe_error::CarpeError, configs};


Expand Down Expand Up @@ -67,3 +69,28 @@ pub fn wallet_type(type_int: u8) -> Result<String, CarpeError> {
))),
}
}

#[tauri::command(async)]
pub fn coin_transfer(
receiver: String,
amount: u64
) -> Result<String, CarpeError> {

let tx_params = configs::get_tx_params()
.map_err(|_| CarpeError::misc("Could not load tx params"))?;

let receiver_address: AccountAddress = receiver
.parse()
.map_err(|_| CarpeError::misc("Invalid receiver account address"))?;

match transfer_cmd::balance_transfer(receiver_address, amount, tx_params, None) {
Ok(r) => Ok(format!("Transfer success: {:?}", r)),
Err(e) => Err(CarpeError::misc(&format!(
"{:}",
match e.abort_code {
Some(code) => code,
None => 0
}
)))
}
}
5 changes: 2 additions & 3 deletions src-tauri/src/commands/wallets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::fs::{self, create_dir_all, File};
use std::io::prelude::*;

use super::get_balance;
use super::get_events;
use super::get_payment_events;
#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct Accounts {
pub accounts: Vec<AccountEntry>,
Expand Down Expand Up @@ -115,10 +115,9 @@ pub fn get_all_accounts() -> Result<Accounts, CarpeError> {
Ok(all)
}


#[tauri::command(async)]
pub fn get_account_events(account: AccountAddress) -> Result<Vec<EventView>, CarpeError> {
let events = get_events(account)?;
let events = get_payment_events(account)?;
Ok(events)
}

Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fn main() {
demo_tx,
create_user_account,
wallet_type,
coin_transfer,
//Tower
miner_once,
start_backlog_sender_listener,
Expand Down
47 changes: 32 additions & 15 deletions src/accountActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { raise_error } from './carpeError';
import { responses } from './debug';
import { minerLoopEnabled, tower} from "./miner";
import { notify_success, notify_error } from './carpeNotify';
import { AccountEntry, all_accounts, isInit, isRefreshingAccounts, mnem, signingAccount, accountEvents } from './accounts';
import { AccountEntry, all_accounts, isInit, isRefreshingAccounts, mnem, signingAccount, accountEvents, isAccountsLoaded } from './accounts';

export const loadAccounts = async () => {
// fetch data from local DB
Expand All @@ -15,12 +15,15 @@ export const loadAccounts = async () => {
if (get(signingAccount).account == "" && result.accounts.length > 0) {
// set initial signingAccount
let first = result.accounts[0];
setAccount(first.account);
setAccount(first.account, false);
} else {
/* TODO no accounts in the current network
signingAccount.set(new_account("", "", ""));
*/
}
if (!get(isAccountsLoaded)) {
isAccountsLoaded.set(true);
}
// fetch data from the chain
return refreshAccounts();
})
Expand All @@ -31,9 +34,7 @@ export const refreshAccounts = async () => {
isRefreshingAccounts.set(true);
return invoke('refresh_accounts')
.then((result: object) => { // TODO make this the correct return type

all_accounts.set(result.accounts);

result.accounts.forEach(el => {
tryRefreshSignerAccount(el);
});
Expand Down Expand Up @@ -69,7 +70,7 @@ export function findOneAccount(account: string): AccountEntry {
return found
}

export const setAccount = async (an_address: string) => {
export const setAccount = async (an_address: string, notifySucess = true) => {
if (get(signingAccount).account == an_address) {
return
}
Expand Down Expand Up @@ -98,7 +99,9 @@ export const setAccount = async (an_address: string) => {
})
.then((res) => {
responses.set(res);
notify_success("Account switched to " + a.nickname);
if (notifySucess) {
notify_success("Account switched to " + a.nickname);
}
})
.catch((e) => {
raise_error(e, false, "setAccount");
Expand All @@ -115,16 +118,26 @@ export function addNewAccount(account: AccountEntry) {
all_accounts.set(list);
}

export function checkAccountBalance(account: AccountEntry) {
invoke('query_balance', {account: account.account})
export function checkSigningAccountBalance() {
let selected = get(signingAccount);
invoke('query_balance', {account: selected.account})
.then((balance: number) => {
let list = get(all_accounts);
account.on_chain = true;
account.balance = Number(balance);
list.push(account);
// update signingAccount
selected.on_chain = true;
selected.balance = Number(balance);
signingAccount.set(selected);

// update all accounts set
let list = get(all_accounts).map(each => {
if (each.account == selected.account) {
each.on_chain = true;
each.balance = Number(balance);
}
return each;
});
all_accounts.set(list);
})
.catch((e) => raise_error(e, false, "checkAccountBalance"));
.catch((e) => raise_error(e, false, "checkSigningAccountBalance"));
}

export function getAccountEvents(account: AccountEntry, errorCallback = null) {
Expand All @@ -138,8 +151,12 @@ export function getAccountEvents(account: AccountEntry, errorCallback = null) {
.then((events: Array<T>) => {
let all = get(accountEvents);
all[address] = events
.filter(each => each.data.type == "receivedpayment" || each.data.type == "sentpayment")
.reverse();
.sort((a, b) => (a.transaction_version < b.transaction_version)
? 1
: (b.transaction_version < a.transaction_version)
? -1
: 0
);
accountEvents.set(all);
})
.catch(e => {
Expand Down
1 change: 1 addition & 0 deletions src/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ export const mnem = writable("");
export const isInit = writable(false);
export const isRefreshingAccounts = writable(false);
export const all_accounts = writable<AccountEntry[]>([]);
export const isAccountsLoaded = writable(false);
export const accountEvents = writable({}); // TODO define interface AccountEvent
27 changes: 27 additions & 0 deletions src/coinHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { get } from 'svelte/store';
import { locale } from 'svelte-i18n';

const scaleFactor = 1000000;
export function printCoins(amount) {
const scaled = unscaledCoins(amount);
const selectedLocale = get(locale);

return scaled.toLocaleString(selectedLocale, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
}

export function printUnscaledCoins(amount, min = 2, max = 6) {
const selectedLocale = get(locale);

return amount.toLocaleString(selectedLocale, {
minimumFractionDigits: min,
maximumFractionDigits: max,
});
}

export function unscaledCoins(amount) {
return amount / scaleFactor;
}

2 changes: 1 addition & 1 deletion src/components/events/Events.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
});
</script>

<main class="uk-height-viewport">
<main>
<div style="position:relative">
<div class="uk-flex uk-flex-center">
<h2 class="uk-text-light uk-text-muted uk-text-uppercase">{$_("events.account_events")}</h2>
Expand Down
27 changes: 11 additions & 16 deletions src/components/events/EventsTable.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script lang="ts">
/* Account events table with pagination */
import { get_locale } from "../../accountActions";
import PageNumber from "./PageNumber.svelte";
import { _ } from "svelte-i18n";
import PageNumber from "./PageNumber.svelte";
import { printCoins } from "../../coinHelpers";

export let events;

Expand Down Expand Up @@ -38,29 +38,19 @@
}
}

// TODO: move to tauri commands
function formatAmount(balance) {
const balanceScaled = balance / 1000000;

return balanceScaled.toLocaleString(get_locale(), {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
}

function formatEventType(type) {
const value = eventTypesDic[type];
return value || type;
}
</script>

<main class="uk-height-viewport">
<main>
<!-- Table -->
<table class="uk-table uk-table-divider">
<thead>
<tr>
<th class="uk-text-right">{$_("events.version")}</th>
<th class="uk-text-center">{$_("events.type")}</th>
<th class="uk-text-center" style="width: 98px">{$_("events.type")}</th>
<th class="uk-text-right">{$_("events.amount")}</th>
<th class="uk-text-center">{$_("events.sender")}</th>
<th class="uk-text-center">{$_("events.receiver")}</th>
Expand All @@ -71,7 +61,7 @@
<tr>
<td class="uk-text-right">{event.transaction_version}</td>
<td class="uk-text-center">{formatEventType(event.data.type)}</td>
<td class="uk-text-right">{formatAmount(event.data.amount.amount)}</td>
<td class="uk-text-right">{printCoins(event.data.amount.amount)}</td>
<td class="uk-text-center">{event.data.sender}</td>
<td class="uk-text-center">{event.data.receiver}</td>
</tr>
Expand Down Expand Up @@ -103,7 +93,7 @@
>
<span uk-icon="chevron-left"></span>
</a>
<div class="page-numbers-container uk-align-left">
<div class="page-numbers-container uk-align-left ">
<!-- Case 0 -->
{#if Object.keys(pages).length <= 7}
{#each Object.keys(pages) as number}
Expand Down Expand Up @@ -171,6 +161,8 @@
background-color: #F0F0F0;
}
.previous-page-btn {
display: flex;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 100%;
Expand All @@ -182,6 +174,8 @@
}

.next-page-btn {
display: flex;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 100%;
Expand All @@ -196,5 +190,6 @@
height: 20px;
padding: 5px;
margin: 0px;
line-height: 20px !important;
}
</style>
Loading