Skip to content

Commit

Permalink
feat: add watch account
Browse files Browse the repository at this point in the history
  • Loading branch information
BBK912 committed Mar 3, 2024
1 parent 00d4541 commit bd7809d
Show file tree
Hide file tree
Showing 17 changed files with 146 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

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

14 changes: 13 additions & 1 deletion src-tauri/src/commands/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{carpe_error::CarpeError, configs::get_client};
use anyhow::anyhow;
use libra_query::account_queries::get_account_balance_libra;
use libra_types::{
exports::AccountAddress,
exports::{AccountAddress, AuthenticationKey},
legacy_types::{
makewhole_resource::CreditResource, makewhole_resource::MakeWholeResource,
tower::TowerProofHistoryView,
Expand Down Expand Up @@ -69,6 +69,18 @@ pub async fn get_seq_num(account: AccountAddress) -> Result<u64, CarpeError> {
Ok(res.into_inner().sequence_number)
}

pub async fn get_auth_key(account: AccountAddress) -> Result<AuthenticationKey, CarpeError> {
let client = get_client()?;
let res = client.get_account(account).await.map_err(|e| {
CarpeError::misc(&format!(
"Could not get authentication_key from account{}: {}",
account, e
))
})?;

Ok(res.into_inner().authentication_key)
}

#[tauri::command(async)]
pub async fn get_recovery_mode() -> Result<u64, CarpeError> {
let client = get_client()?;
Expand Down
8 changes: 8 additions & 0 deletions src-tauri/src/commands/wallets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,11 @@ pub fn get_private_key_from_os(address: AccountAddress) -> Result<String, CarpeE
let acc_struct = account_keys::get_account_from_private(&pk);
Ok(acc_struct.pri_key.to_encoded_string()?)
}

#[tauri::command(async)]
pub async fn add_watch_account(address: AccountAddress) -> Result<CarpeProfile, CarpeError> {
let authkey: AuthenticationKey = query::get_auth_key(address).await?;
configs_profile::set_account_profile(address, authkey).await?;
let core_profile = &Profile::new(authkey, address);
Ok(core_profile.into())
}
1 change: 1 addition & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ async fn main() {
commands::wallets::is_slow,
commands::wallets::set_slow_wallet,
commands::wallets::get_private_key_from_os,
commands::wallets::add_watch_account,
//////// Networks ////////
commands::preferences::refresh_upstream_peer_stats,
commands::networks::force_upstream,
Expand Down
2 changes: 2 additions & 0 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import DevMode from './components/dev/DevMode.svelte'
import AccountCreate from './components/wallet/AccountCreate.svelte'
import Keygen from './components/wallet/Keygen.svelte'
import AddWatchAccount from './components/wallet/AddWatchAccount.svelte'
import Transactions from './components/txs/Transactions.svelte'
import Events from './components/events/Events.svelte'
import About from './components/about/About.svelte'
Expand Down Expand Up @@ -130,6 +131,7 @@
<Route path={routes.wallet} component={Wallet} primary={false} />
<!-- <Route path="/add-account" component={AddAccount} primary={false} /> -->
<Route path={routes.accountFromMnem} component={AccountCreate} primary={false} />
<Route path={routes.addWatchAccount} component={AddWatchAccount} primary={false} />
<Route path={routes.keygen} component={Keygen} primary={false} />
<Route path={routes.miner} component={Miner} primary={false} />
<Route path={routes.transfer} component={Transactions} primary={false} />
Expand Down
1 change: 1 addition & 0 deletions src/components/Nav.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
routes.developer,
routes.keygen,
routes.accountFromMnem,
routes.addWatchAccount,
]
const location_store = useLocation()
Expand Down
4 changes: 2 additions & 2 deletions src/components/miner/ToggleMiner.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { minerLoopEnabled } from '../../modules/miner'
import { toggleMining } from '../../modules/miner_toggle'
import { signingAccount } from '../../modules/accounts';
let checking = false
const toggle = () => {
Expand All @@ -15,7 +15,7 @@
<div class="uk-text-center uk-margin" style="position: relative">
{#if !checking}
<label class="uk-switch">
<input type="checkbox" on:click={toggle} checked={$minerLoopEnabled} />
<input type="checkbox" on:click={toggle} checked={$minerLoopEnabled} disabled={$signingAccount.watch_only}/>
<div class="uk-switch-slider uk-switch-on-off round" />
</label>
{:else}
Expand Down
3 changes: 3 additions & 0 deletions src/components/settings/AccountSettings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import { raise_error } from '../../modules/carpeError'
import { notify_success } from '../../modules/carpeNotify'
import { responses } from '../../modules/debug'
import { watchAccounts } from '../../modules/accounts'
const removeAccounts = async () => {
invoke('remove_accounts', {})
.then((res: string) => {
responses.set(res)
notify_success('Accounts removed successfully')
watchAccounts.set([])
localStorage.removeItem('watchAccounts')
refreshAccounts()
})
.catch((e) => {
Expand Down
13 changes: 8 additions & 5 deletions src/components/txs/Transactions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
let account: CarpeProfile
let unsubs
onMount(async () => {
unsubs = signingAccount.subscribe((obj) => (account = obj))
unsubs = signingAccount.subscribe((obj) => {
account = obj
watchOnly = obj.watch_only
})
})
let receiver: string
Expand All @@ -29,7 +32,7 @@
let errorMessage = ''
let waitingTxs = false
let waitingConfirmation = false
let watchOnly = false
const re = /[a-fA-F0-9]{32}/i
let isReceiverValid = true
Expand Down Expand Up @@ -160,7 +163,7 @@
<div class="uk-form-controls">
<input
id="receiver-text"
disabled={waitingTxs}
disabled={waitingTxs || watchOnly}
class="uk-input"
type="text"
placeholder={$_('txs.transfer.receiver_placeholder')}
Expand All @@ -176,7 +179,7 @@
<!-- add mask -->
<input
id="amount-text"
disabled={waitingTxs}
disabled={waitingTxs || watchOnly}
class="uk-input"
type="text"
placeholder={$_('txs.transfer.amount_placeholder')}
Expand All @@ -196,7 +199,7 @@
</button>
<button
on:click={() => (waitingConfirmation = true)}
disabled={waitingTxs || !isValidAmount || !isReceiverValid}
disabled={waitingTxs || !isValidAmount || !isReceiverValid || watchOnly}
class="uk-button uk-button-primary"
>
{waitingTxs ? $_('txs.transfer.await') : $_('txs.transfer.btn_next')}
Expand Down
10 changes: 8 additions & 2 deletions src/components/wallet/AccountsList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
: ""}
on:click={() => setAccount(a.account)}
> -->
<td class="uk-transition-toggle">
{#if a.account == $signingAccount.account}
<td >
<span class="uk-transition-toggle">
{#if a.account == $signingAccount.account}
{#if $minerLoopEnabled}
<IconMining />
{:else}
Expand All @@ -65,6 +66,11 @@
on:click={toggleOptions}
/>
{/if}
</span>

{#if a.watch_only}
<span class="uk-align-right" uk-icon="eye"></span>
{/if}
</td>
<!-- <td
on:click={() => setAccount(a.account)}
Expand Down
36 changes: 36 additions & 0 deletions src/components/wallet/AddWatchAccount.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import { _ } from 'svelte-i18n'
import { addWatchAccount } from '../../modules/accountActions'
let address: string
const initAccount = (address: string) => {
addWatchAccount(address.trim())
}
</script>

<main>
<div class="uk-margin">
<p>{$_('wallet.add_watch_account.description')}</p>
<form id="account-form" on:submit|preventDefault={() => {}}>
<fieldset class="uk-fieldset">
<div class="uk-margin uk-inline-block uk-width-1-1">
<input
class="uk-input"
type="text"
placeholder={$_('wallet.add_watch_account.placeholder')}
bind:value={address}
/>
</div>
</fieldset>
</form>

<button
class="uk-button uk-button-primary"
type="button"
on:click|preventDefault={initAccount(address)}
>
Submit Now
</button>
</div>
</main>
3 changes: 3 additions & 0 deletions src/components/wallet/CreateAccountLinks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<Link to={routes.accountFromMnem}>
<button class="uk-button uk-button-default">{$_('wallet.btn_restore_account')}</button>
</Link>
<Link to={routes.addWatchAccount}>
<button class="uk-button uk-button-default">{$_('wallet.btn_add_watch_account')}</button>
</Link>

</div>
</main>
5 changes: 5 additions & 0 deletions src/lang/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"carpe": "CARPE",
"btn_new_account": "New Account",
"btn_restore_account": "Restore Account",
"btn_add_watch_account": "Watch Account",
"newbie_message": "Looks like you don't have any accounts",
"reminder_create": {
"card_title": "Onboarding",
Expand Down Expand Up @@ -83,6 +84,10 @@
"placeholder": "Private Key",
"accordion_title": "advanced: use private key"
},
"add_watch_account": {
"description": "Add account to \"watch\" without a signing key (read only).",
"placeholder": "address"
},
"account_switcher": {
"select_account": "Settings",
"switch_account": "Switch Account",
Expand Down
59 changes: 46 additions & 13 deletions src/modules/accountActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
migrateInProgress,
migrateSuccess,
canMigrate,
watchAccounts,
} from './accounts'
import type { CarpeProfile, SlowWalletBalance } from './accounts'
import { navigate } from 'svelte-navigator'
Expand All @@ -35,6 +36,10 @@ export const getAccounts = async () => {
// first make sure we don't have empty accounts
invoke('get_all_accounts')
.then((result: CarpeProfile[]) => {
const watchList = get(watchAccounts)
result.map((item) => {
item.watch_only = watchList.includes(item.account)
})
allAccounts.set(result)
})
.catch((e) => raise_error(e, true, 'get_all_accounts'))
Expand All @@ -48,6 +53,12 @@ export const refreshAccounts = async () => {
.then((result: [CarpeProfile]) => {
// TODO make this the correct return type
isRefreshingAccounts.set(false)

const watchList = get(watchAccounts)
result.map((item) => {
item.watch_only = watchList.includes(item.account)
})

allAccounts.set(result)
const currentAccount = get(signingAccount)
if (currentAccount) {
Expand Down Expand Up @@ -85,19 +96,7 @@ export const addAccount = async (init_type: InitType, secret: string) => {
// submit
return invoke(method_name, arg_obj)
.then(async (res: CarpeProfile) => {
// set as init so we don't get sent back to Newbie account creation.
isInit.set(true)
responses.set(JSON.stringify(res))
// cannot switch profile with miner running
if (!get(minerLoopEnabled)) {
signingAccount.set(res)
}
await initNetwork()
// only navigate away once we have refreshed the accounts including balances
notify_success(`Account Added: ${res.nickname}`)

refreshAccounts()
setTimeout(() => navigate('wallet'), 10)
await onAccountAdd(res)
return res
})
.catch((error) => {
Expand Down Expand Up @@ -349,3 +348,37 @@ export function getPrivateKey(address: string, callback = null) {
raise_error(e, false, 'get_private_key')
})
}

export function addWatchAccount(address: string) {
invoke('add_watch_account', {
address,
})
.then(async (res: CarpeProfile) => {
let list = get(watchAccounts)
list = Array.from(new Set([...list, res.account]))
watchAccounts.set(list)
localStorage.setItem('watchAccounts', JSON.stringify(list))
res.watch_only = true
await onAccountAdd(res)
})
.catch((e: CarpeError) => {
notify_error('Unable to parse AccountAddress')
raise_error(e, true, 'add_watch_account')
})
}

async function onAccountAdd(res: CarpeProfile) {
// set as init so we don't get sent back to Newbie account creation.
isInit.set(true)
responses.set(JSON.stringify(res))
// cannot switch profile with miner running
if (!get(minerLoopEnabled)) {
signingAccount.set(res)
}
await initNetwork()
// only navigate away once we have refreshed the accounts including balances
notify_success(`Account Added: ${res.nickname}`)

await refreshAccounts()
setTimeout(() => navigate('wallet'), 10)
}
5 changes: 5 additions & 0 deletions src/modules/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface CarpeProfile {
on_chain?: boolean
balance?: SlowWalletBalance
locale?: string // TODO: refactor, tauri now offers locale of the OS
watch_only?: boolean
}
export interface SlowWalletBalance {
unlocked: number
Expand All @@ -20,6 +21,7 @@ export const new_account = (account: string, authkey: string, nickname: string):
nickname: nickname,
on_chain: false,
balance: { unlocked: 0, total: 0 },
watch_only: false,
}
}

Expand All @@ -36,6 +38,9 @@ export const canMigrate = writable<boolean>(false)
export const migrateSuccess = writable<boolean>()
export const migrateInProgress = writable<boolean>()

const localeWatchAccounts = JSON.parse(localStorage.getItem('watchAccounts') || '[]')
export const watchAccounts = writable<string[]>(localeWatchAccounts)

export const formatAccount = (acc: string): string => {
return acc.replace('00000000000000000000000000000000', '')
}
1 change: 1 addition & 0 deletions src/modules/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const routes = {
home: '/',
wallet: '/wallet',
addAccount: '/add-account',
addWatchAccount: '/add-wathc-account',
accountFromMnem: '/account-from-mnem',
keygen: '/keygen',
miner: '/miner',
Expand Down
3 changes: 3 additions & 0 deletions src/style/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ input:checked + .uk-switch-slider:before {
input:checked + .uk-switch-slider.uk-switch-on-off {
background-color: #32d296 !important;
}
input:disabled + .uk-switch-slider.uk-switch-on-off {
cursor: not-allowed;
}

/* Style Modifier */
.uk-switch-slider.uk-switch-big:before {
Expand Down

0 comments on commit bd7809d

Please sign in to comment.