From 7c1fb6f55a48e3c918159992111893ffbce095be Mon Sep 17 00:00:00 2001 From: apporc Date: Tue, 10 Sep 2024 18:29:08 +0800 Subject: [PATCH 01/10] Staking: Remove usage of exclamation in staking --- .../(staking)/staking/stake/state.svelte.ts | 40 ++++++++++-------- .../(staking)/staking/unstake/state.svelte.ts | 29 ++++++++----- .../(account)/(staking)/staking/utils.ts | 41 +++++++++--------- .../staking/withdraw/state.svelte.ts | 42 +++++++++++-------- 4 files changed, 85 insertions(+), 67 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts index 22f527bb0..8536fe673 100644 --- a/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts @@ -25,14 +25,14 @@ export class StakeState { public txid: string = $state(''); public stakable: Asset = $derived( - this.account && this.network ? getStakableBalance(this.network!, this.account) : defaultQuantity + this.account && this.network ? getStakableBalance(this.network, this.account) : defaultQuantity ); - public apy: string = $derived(getAPY(this.network)); + public apy: string = $derived(this.network ? getAPY(this.network) : '0'); public estimateYield: Asset = $derived( this.network ? Asset.from( (this.assetValue.value * parseFloat(this.apy)) / 100, - this.network!.chain.systemToken!.symbol + this.network.chain.systemToken!.symbol ) : defaultQuantity ); @@ -42,7 +42,7 @@ export class StakeState { } get zeroValue() { - return Asset.from(0, this.network!.chain.systemToken!.symbol); + return this.network ? Asset.from(0, this.network.chain.systemToken!.symbol) : defaultQuantity; } sync(network: NetworkState, account: AccountState, wharf: WharfState) { @@ -61,15 +61,17 @@ export class StakeState { this.txid = ''; } - if (this.assetValue.symbol !== this.network!.chain.systemToken!.symbol) { + if (this.network && this.assetValue.symbol !== this.network.chain.systemToken!.symbol) { this.input?.set(this.zeroValue); } if (wharf !== this.wharf) { this.wharf = wharf; } - this.minValue = Asset.fromUnits(1, this.network!.chain.systemToken!.symbol).value; - this.maxValue = this.account ? getStakableBalance(this.network!, this.account).value : 0; + if (this.network) { + this.minValue = Asset.fromUnits(1, this.network.chain.systemToken!.symbol).value; + this.maxValue = this.account ? getStakableBalance(this.network, this.account).value : 0; + } } setMaxValue() { @@ -77,17 +79,21 @@ export class StakeState { } async transact() { - const deposit = this.network!.contracts.system.action('deposit', { - owner: this.account!.name!, - amount: this.assetValue! - }); - const buyrex = this.network!.contracts.system.action('buyrex', { - from: this.account!.name!, - amount: this.assetValue! - }); - try { - const result = await this.wharf!.transact({ + if (!this.network || !this.account || !this.account.name || !this.wharf || !this.assetValue) { + throw new Error("Can't sign, data not ready"); + } + + const deposit = this.network.contracts.system.action('deposit', { + owner: this.account.name, + amount: this.assetValue + }); + const buyrex = this.network.contracts.system.action('buyrex', { + from: this.account.name, + amount: this.assetValue + }); + + const result = await this.wharf.transact({ actions: [deposit, buyrex] }); diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts index 83d26d36e..b31105805 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts @@ -25,7 +25,9 @@ export class UnstakeState { public txid: string = $state(''); public unstakable: Asset = $derived( - this.account ? getUnstakableBalance(this.network!, this.account) : defaultQuantity + this.account && this.network + ? getUnstakableBalance(this.network, this.account) + : defaultQuantity ); constructor(network: NetworkState) { @@ -33,7 +35,7 @@ export class UnstakeState { } get zeroValue() { - return Asset.from(0, this.network!.chain.systemToken!.symbol); + return this.network ? Asset.from(0, this.network.chain.systemToken!.symbol) : defaultQuantity; } sync(network: NetworkState, account: AccountState, wharf: WharfState) { @@ -52,15 +54,17 @@ export class UnstakeState { this.txid = ''; } - if (this.assetValue.symbol !== this.network!.chain.systemToken!.symbol) { + if (this.network && this.assetValue.symbol !== this.network.chain.systemToken!.symbol) { this.input?.set(this.zeroValue); } if (wharf !== this.wharf) { this.wharf = wharf; } - this.minValue = Asset.fromUnits(1, this.network!.chain.systemToken!.symbol).value; - this.maxValue = this.account ? getUnstakableBalance(this.network!, this.account).value : 0; + if (this.network) { + this.minValue = Asset.fromUnits(1, this.network.chain.systemToken!.symbol).value; + this.maxValue = this.account ? getUnstakableBalance(this.network, this.account).value : 0; + } } setMaxValue() { @@ -68,13 +72,16 @@ export class UnstakeState { } async transact() { - const mvfrsavings = this.network!.contracts.system.action('mvfrsavings', { - owner: this.account!.name!, - rex: this.network!.tokenToRex(this.assetValue!) - }); - try { - const result = await this.wharf!.transact({ + if (!this.network || !this.account || !this.account.name || !this.assetValue || !this.wharf) { + throw new Error("Can't sign, data not ready"); + } + const mvfrsavings = this.network.contracts.system.action('mvfrsavings', { + owner: this.account.name, + rex: this.network.tokenToRex(this.assetValue) + }); + + const result = await this.wharf.transact({ actions: [mvfrsavings] }); diff --git a/src/routes/[network]/(account)/(staking)/staking/utils.ts b/src/routes/[network]/(account)/(staking)/staking/utils.ts index f3b0fa01e..ddaa2f156 100644 --- a/src/routes/[network]/(account)/(staking)/staking/utils.ts +++ b/src/routes/[network]/(account)/(staking)/staking/utils.ts @@ -26,8 +26,8 @@ export function getStakableBalance(network: NetworkState, account: AccountState) export function getStakedBalance(network: NetworkState, account: AccountState): Asset { let staked = Asset.fromUnits(0, network.chain.systemToken!.symbol); - if (account && account.loaded) { - const rexInfo = account.account!.data.rex_info; + if (account && account.loaded && account.account) { + const rexInfo = account.account.data.rex_info; if (rexInfo) { staked = network.rexToToken(rexInfo.rex_balance); } @@ -41,10 +41,10 @@ export function getClaimableBalance( unstaking: Array ): Asset { // withdrawable(rex_fund) + claimable - let claimable: Asset = Asset.from(0, network!.chain.systemToken!.symbol); + let claimable: Asset = Asset.from(0, network.chain.systemToken!.symbol); - if (account && account.loaded) { - const rexInfo = account.account!.data.rex_info; + if (account && account.loaded && account.account) { + const rexInfo = account.account.data.rex_info; if (rexInfo) { let matured = Int64.from(0); const sum: Int64 = unstaking @@ -55,7 +55,7 @@ export function getClaimableBalance( } if (matured.gt(Int64.from(0))) { - claimable = Asset.fromUnits(matured, network!.chain.systemToken!.symbol); + claimable = Asset.fromUnits(matured, network.chain.systemToken!.symbol); } } } @@ -74,8 +74,8 @@ export function getUnstakingBalances( ): Array { // matured_rex + claimable buckets let records: Array = []; - if (account && account.loaded) { - const rexInfo = account.account!.data.rex_info; + if (account && account.loaded && account.account) { + const rexInfo = account.account.data.rex_info; if (rexInfo) { if (rexInfo.matured_rex && rexInfo.matured_rex.gt(Int64.from(0))) { // add matured into balances @@ -92,15 +92,17 @@ export function getUnstakingBalances( const fiveYearsFromNow = new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 5; const now = new Date(); for (const maturity of rexInfo.rex_maturities) { - const date = new Date(maturity.first!.toString()); - records.push({ - date, - balance: network.rexToToken( - Asset.fromUnits(maturity.second!, rexInfo.rex_balance.symbol) - ), - claimable: +date < +now, - savings: +date > +fiveYearsFromNow - }); + if (maturity.first && maturity.second) { + const date = new Date(maturity.first.toString()); + records.push({ + date, + balance: network.rexToToken( + Asset.fromUnits(maturity.second, rexInfo.rex_balance.symbol) + ), + claimable: +date < +now, + savings: +date > +fiveYearsFromNow + }); + } } } } @@ -112,10 +114,7 @@ export function getUnstakableBalance(network: NetworkState, account: AccountStat return savings ? savings.balance : Asset.from(0, network.chain.systemToken!.symbol); } -export function getAPY(network: NetworkState | undefined): string { - if (!network) { - return '0'; - } +export function getAPY(network: NetworkState): string { const annualReward = 31250000; const totalStaked = Number(network.rexstate!.total_lendable.value); return ((annualReward / totalStaked) * 100).toFixed(2); diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts index 34d942c84..1a57f2999 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts @@ -29,7 +29,7 @@ export class WithdrawState { ); public withdrawable: Asset = $derived( this.account && this.network - ? getWithdrawableBalance(this.network!, this.account) + ? getWithdrawableBalance(this.network, this.account) : defaultQuantity ); public total: Asset = $derived( @@ -67,24 +67,30 @@ export class WithdrawState { } async transact() { - const actions = []; - if (this.claimable) { - actions.push( - this.network!.contracts.system.action('sellrex', { - from: this.account!.name!, - rex: this.network!.tokenToRex(this.claimable) - }) - ); - } - actions.push( - this.network!.contracts.system.action('withdraw', { - owner: this.account!.name!, - amount: this.withdrawable! - }) - ); - try { - const result = await this.wharf!.transact({ + if (!this.network || !this.account || !this.account.name || !this.wharf) { + throw new Error("Can't sign, data not ready"); + } + + const actions = []; + if (this.claimable) { + actions.push( + this.network.contracts.system.action('sellrex', { + from: this.account.name, + rex: this.network.tokenToRex(this.claimable) + }) + ); + } + if (this.withdrawable) { + actions.push( + this.network.contracts.system.action('withdraw', { + owner: this.account.name, + amount: this.withdrawable + }) + ); + } + + const result = await this.wharf.transact({ actions }); From 0c81c5b00422c338bebb4c916937c5ac120a284a Mon Sep 17 00:00:00 2001 From: apporc Date: Tue, 10 Sep 2024 21:23:46 +0800 Subject: [PATCH 02/10] Staking: Use transaction component --- .../(account)/(staking)/staking/stake/+page.svelte | 11 ++--------- .../(account)/(staking)/staking/unstake/+page.svelte | 11 ++--------- .../(account)/(staking)/staking/withdraw/+page.svelte | 11 ++--------- 3 files changed, 6 insertions(+), 27 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte index f58df239c..75a2fc6a1 100644 --- a/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte @@ -6,6 +6,7 @@ import AssetInput from '$lib/components/input/asset.svelte'; import Button from '$lib/components/button/button.svelte'; import Label from '$lib/components/input/label.svelte'; + import Transaction from '$lib/components/transaction.svelte'; import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext, untrack } from 'svelte'; @@ -22,15 +23,7 @@ {#if stakeState.txid} -
-

Transaction Complete

-

success

-

- - {stakeState.txid} - -

-
+ {:else if stakeState.error}

Transaction Error

diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte index a84fe0c66..9a02df2ec 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte @@ -6,6 +6,7 @@ import AssetInput from '$lib/components/input/asset.svelte'; import Button from '$lib/components/button/button.svelte'; import Label from '$lib/components/input/label.svelte'; + import Transaction from '$lib/components/transaction.svelte'; import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; @@ -22,15 +23,7 @@ {#if unstakeState.txid} -
-

Transaction Complete

-

success

-

- - {unstakeState.txid} - -

-
+ {:else if unstakeState.error}

Transaction Error

diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte index eb7d62882..bef21c35d 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte @@ -7,6 +7,7 @@ import Button from '$lib/components/button/button.svelte'; import Label from '$lib/components/input/label.svelte'; import PageHeader from '$lib/components/pageheader.svelte'; + import Transaction from '$lib/components/transaction.svelte'; import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; @@ -24,15 +25,7 @@ {#if withdrawState.txid} -
-

Transaction Complete

-

success

-

- - {withdrawState.txid} - -

-
+ {:else if withdrawState.error}

Transaction Error

From 09e46b33bd9df16648f448eb2618247abbe8c7cb Mon Sep 17 00:00:00 2001 From: apporc Date: Tue, 10 Sep 2024 21:41:16 +0800 Subject: [PATCH 03/10] Staking: Use Table component --- .../(account)/(staking)/staking/+page.svelte | 35 +------------ .../(staking)/staking/unstaking.svelte | 51 +++++++++++++++++++ .../(staking)/staking/withdraw/+page.svelte | 31 +---------- 3 files changed, 55 insertions(+), 62 deletions(-) create mode 100644 src/routes/[network]/(account)/(staking)/staking/unstaking.svelte diff --git a/src/routes/[network]/(account)/(staking)/staking/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/+page.svelte index 8cd019fb1..b6fa544ec 100644 --- a/src/routes/[network]/(account)/(staking)/staking/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/+page.svelte @@ -9,6 +9,7 @@ import type { UnstakingRecord, WithdrawableBalance } from './utils'; import { getStakedBalance, getUnstakingBalances, getAPY } from './utils'; + import UnstakingBalances from './unstaking.svelte'; const context = getContext('state'); const { data } = $props(); @@ -46,39 +47,7 @@ > - - - - - - - - - - - {#each unstaking as record} - {#if !record.savings} - - - - {/if} - {/each} - -
AmountDate available
{record.balance}{record.date - ? record.date.toLocaleDateString(undefined, { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric' - }) - : '--'} -
- -
+ diff --git a/src/routes/[network]/(account)/(staking)/staking/unstaking.svelte b/src/routes/[network]/(account)/(staking)/staking/unstaking.svelte new file mode 100644 index 000000000..baf281eb9 --- /dev/null +++ b/src/routes/[network]/(account)/(staking)/staking/unstaking.svelte @@ -0,0 +1,51 @@ + + + + + + + + + Amount + Date available + + + + {#each records as record} + {#if !record.savings} + + {record.balance} + + {record.date + ? record.date.toLocaleDateString(undefined, { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }) + : '--'} + + + {/if} + {/each} + + + {#if href} + + {/if} + diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte index bef21c35d..f63c7c2a5 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte @@ -13,6 +13,7 @@ import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; import { WithdrawState } from './state.svelte'; + import UnstakingBalances from '../unstaking.svelte'; const context = getContext('state'); const { data } = $props(); @@ -43,35 +44,7 @@ > - - - - - - - - - - {#each withdrawState.unstaking as record} - {#if !record.savings} - - - - {/if} - {/each} - -
AmountDate available
{record.balance}{record.date - ? record.date.toLocaleDateString(undefined, { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric' - }) - : '--'} -
-
+
{/if} From 3ff0d3907d78b1e8565281d0ec08770d8d3c5552 Mon Sep 17 00:00:00 2001 From: apporc Date: Wed, 11 Sep 2024 16:56:17 +0800 Subject: [PATCH 04/10] Staking: add rexfund --- src/lib/state/client/account.svelte.ts | 26 ++++-- src/lib/types.ts | 1 + .../(staking)/staking/unstake/state.svelte.ts | 10 ++- .../(account)/(staking)/staking/utils.ts | 89 ++++++++++--------- .../[network]/api/account/[[name]]/+server.ts | 7 +- 5 files changed, 78 insertions(+), 55 deletions(-) diff --git a/src/lib/state/client/account.svelte.ts b/src/lib/state/client/account.svelte.ts index 83c85c5e1..46e5bf728 100644 --- a/src/lib/state/client/account.svelte.ts +++ b/src/lib/state/client/account.svelte.ts @@ -21,7 +21,8 @@ const defaultDataSources = { get_account: undefined, light_account: [], delegated: [], - rex: undefined + rex: undefined, + rexfund: undefined }; export class AccountState { @@ -79,7 +80,8 @@ export class AccountState { get_account: json.account_data, light_account: json.balances, delegated: json.delegated, - rex: json.rex + rex: json.rex, + rexfund: json.rexfund }; this.account = new Account({ client: this.network.client, @@ -192,13 +194,19 @@ export function getBalance(network: NetworkState, sources: DataSources): Balance total.units.add(delegatedTokens.units); } - // Add any staked (REX) tokens to total balance based on current value - if (sources.rex) { - if (network.config.features.rex && network.rexstate) { - const rex = network.rexToToken(sources.rex.rex_balance); - // const rex = convertRexToToken(sources.rex.rex_balance, network.rexstate); - staked.units.add(rex.units); - total.units.add(rex.units); + if (network.config.features.rex) { + // Add any staked (REX) tokens to total balance based on current value + if (sources.rex) { + if (network.rexstate) { + const rex = network.rexToToken(sources.rex.rex_balance); + staked.units.add(rex.units); + total.units.add(rex.units); + } + } + // Add rex fund to total balance based on current value + if (sources.rexfund && sources.rexfund.balance) { + staked.units.add(sources.rexfund.balance.units); + total.units.add(sources.rexfund.balance.units); } } diff --git a/src/lib/types.ts b/src/lib/types.ts index 9515c36c6..dd03ada3f 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -36,6 +36,7 @@ export interface DataSources { light_account: LightAPIBalanceResponse[]; delegated: SystemContract.Types.delegated_bandwidth[]; rex?: SystemContract.Types.rex_balance; + rexfund?: SystemContract.Types.rex_fund; } export interface LightAPIBalanceRow { diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts index b31105805..8f454edc9 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts @@ -4,7 +4,8 @@ import type { NetworkState } from '$lib/state/network.svelte'; import type { WharfState } from '$lib/state/client/wharf.svelte'; import AssetInput from '$lib/components/input/asset.svelte'; -import { defaultQuantity, getUnstakableBalance } from '../utils'; +import type { UnstakingRecord } from '../utils'; +import { defaultQuantity, getUnstakableBalance, getUnstakingBalances } from '../utils'; export class UnstakeState { public input: AssetInput | undefined = $state(); @@ -24,9 +25,12 @@ export class UnstakeState { public error: string = $state(''); public txid: string = $state(''); + public unstaking: Array = $derived( + this.account && this.network ? getUnstakingBalances(this.network, this.account) : [] + ); public unstakable: Asset = $derived( this.account && this.network - ? getUnstakableBalance(this.network, this.account) + ? getUnstakableBalance(this.network, this.account, this.unstaking) : defaultQuantity ); @@ -63,7 +67,7 @@ export class UnstakeState { if (this.network) { this.minValue = Asset.fromUnits(1, this.network.chain.systemToken!.symbol).value; - this.maxValue = this.account ? getUnstakableBalance(this.network, this.account).value : 0; + this.maxValue = this.unstakable.value; } } diff --git a/src/routes/[network]/(account)/(staking)/staking/utils.ts b/src/routes/[network]/(account)/(staking)/staking/utils.ts index ddaa2f156..888b6318e 100644 --- a/src/routes/[network]/(account)/(staking)/staking/utils.ts +++ b/src/routes/[network]/(account)/(staking)/staking/utils.ts @@ -25,47 +25,46 @@ export function getStakableBalance(network: NetworkState, account: AccountState) } export function getStakedBalance(network: NetworkState, account: AccountState): Asset { - let staked = Asset.fromUnits(0, network.chain.systemToken!.symbol); - if (account && account.loaded && account.account) { - const rexInfo = account.account.data.rex_info; - if (rexInfo) { - staked = network.rexToToken(rexInfo.rex_balance); + let staked = Int64.from(0); + if (account && account.loaded) { + if (account.account?.data.rex_info) { + staked.add(network.rexToToken(account.account.data.rex_info.rex_balance).units); + } + if (account.sources.rexfund) { + staked.add(Asset.from(account.sources.rexfund.balance).units); } } - return staked; + return Asset.fromUnits(staked, network.chain.systemToken!.symbol); } export function getClaimableBalance( network: NetworkState, account: AccountState, - unstaking: Array + unstaking: Array | undefined ): Asset { - // withdrawable(rex_fund) + claimable - let claimable: Asset = Asset.from(0, network.chain.systemToken!.symbol); + // claimable buckets, rex to be sold + let claimable = Int64.from(0); - if (account && account.loaded && account.account) { - const rexInfo = account.account.data.rex_info; - if (rexInfo) { - let matured = Int64.from(0); - const sum: Int64 = unstaking - .filter((r) => r.claimable) - .reduce((acc, r) => acc.adding(r.balance.units), Int64.from(0)); - if (sum) { - matured.add(sum); - } + if (!unstaking) { + unstaking = getUnstakingBalances(network, account); + } - if (matured.gt(Int64.from(0))) { - claimable = Asset.fromUnits(matured, network.chain.systemToken!.symbol); - } - } + const sum: Int64 = unstaking + .filter((r) => r.claimable) + .reduce((acc, r) => acc.adding(r.balance.units), Int64.from(0)); + if (sum) { + claimable.add(sum); } - return claimable; + return Asset.fromUnits(claimable, network.chain.systemToken!.symbol); } export function getWithdrawableBalance(network: NetworkState, account: AccountState): Asset { - // TODO: add rex fund - return Asset.from(0, network.chain.systemToken!.symbol); + let withdrawable = Int64.from(0); + if (account && account.loaded && account.sources.rexfund && account.sources.rexfund.balance) { + withdrawable.add(Asset.from(account.sources.rexfund.balance).units); + } + return Asset.fromUnits(withdrawable, network.chain.systemToken!.symbol); } export function getUnstakingBalances( @@ -74,21 +73,22 @@ export function getUnstakingBalances( ): Array { // matured_rex + claimable buckets let records: Array = []; - if (account && account.loaded && account.account) { + if (account && account.loaded && account.account?.data.rex_info) { const rexInfo = account.account.data.rex_info; - if (rexInfo) { - if (rexInfo.matured_rex && rexInfo.matured_rex.gt(Int64.from(0))) { - // add matured into balances - records.push({ - date: undefined, - balance: network.rexToToken( - Asset.fromUnits(rexInfo.matured_rex, rexInfo.rex_balance.symbol) - ), - claimable: true, - savings: false - }); - } + if (rexInfo.matured_rex && rexInfo.matured_rex.gt(Int64.from(0))) { + // construct matured as one rex bucket + records.push({ + date: undefined, + balance: network.rexToToken( + Asset.fromUnits(rexInfo.matured_rex, rexInfo.rex_balance.symbol) + ), + claimable: true, + savings: false + }); + } + if (rexInfo.rex_maturities) { + // transform real rex buckets const fiveYearsFromNow = new Date().getTime() + 1000 * 60 * 60 * 24 * 365 * 5; const now = new Date(); for (const maturity of rexInfo.rex_maturities) { @@ -109,8 +109,15 @@ export function getUnstakingBalances( return records; } -export function getUnstakableBalance(network: NetworkState, account: AccountState): Asset { - const savings = getUnstakingBalances(network, account).find((r) => r.savings); +export function getUnstakableBalance( + network: NetworkState, + account: AccountState, + unstaking: Array | undefined +): Asset { + if (!unstaking) { + unstaking = getUnstakingBalances(network, account); + } + const savings = unstaking.find((r) => r.savings); return savings ? savings.balance : Asset.from(0, network.chain.systemToken!.symbol); } diff --git a/src/routes/[network]/api/account/[[name]]/+server.ts b/src/routes/[network]/api/account/[[name]]/+server.ts index 5d18f372f..7ed52ac5e 100644 --- a/src/routes/[network]/api/account/[[name]]/+server.ts +++ b/src/routes/[network]/api/account/[[name]]/+server.ts @@ -26,17 +26,19 @@ export async function GET({ fetch, params }) { Promise, Promise, Promise, + Promise, Promise ] = [ network.client.v1.chain.get_account(params.name), systemContract.table('delband').all({ scope: params.name }), systemContract.table('rexbal').get(params.name), + systemContract.table('rexfund').get(params.name), loadBalances(network, params.name, fetch) ]; try { const headers = getCacheHeaders(5); - const [account_data, delegated, rex, balances] = await Promise.all(requests); + const [account_data, delegated, rexbal, rexfund, balances] = await Promise.all(requests); // If no response from the light API, add the core liquid balance as a default if (!balances.length && chain.systemToken) { @@ -54,7 +56,8 @@ export async function GET({ fetch, params }) { account_data, balances, delegated, - rex + rex: rexbal, + rexfund: rexfund }, { headers } ); From 74f89805cc89e50979ca3536e416ced43dfc8ebc Mon Sep 17 00:00:00 2001 From: apporc Date: Wed, 11 Sep 2024 17:07:23 +0800 Subject: [PATCH 05/10] Staking: avoid pill group overlap with account selector --- .../[network]/(account)/(staking)/staking/+layout.svelte | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/+layout.svelte b/src/routes/[network]/(account)/(staking)/staking/+layout.svelte index 845cd74fb..c3fb6f3fa 100644 --- a/src/routes/[network]/(account)/(staking)/staking/+layout.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/+layout.svelte @@ -34,10 +34,8 @@ - - - - + + {@render children()} From 88248b0a512dde8a404cfbe8e805b3d6fe9ae5f7 Mon Sep 17 00:00:00 2001 From: apporc Date: Wed, 11 Sep 2024 17:58:35 +0800 Subject: [PATCH 06/10] Staking: fix withdraw value --- .../(account)/(staking)/staking/withdraw/state.svelte.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts index 1a57f2999..30969d727 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts @@ -81,11 +81,11 @@ export class WithdrawState { }) ); } - if (this.withdrawable) { + if (this.total) { actions.push( this.network.contracts.system.action('withdraw', { owner: this.account.name, - amount: this.withdrawable + amount: this.total }) ); } From ff0284149f0a29c74f209bdead511dde0444e17e Mon Sep 17 00:00:00 2001 From: apporc Date: Mon, 23 Sep 2024 16:31:45 +0800 Subject: [PATCH 07/10] Staking: remove todo --- src/routes/[network]/(account)/(staking)/staking/utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/utils.ts b/src/routes/[network]/(account)/(staking)/staking/utils.ts index 888b6318e..fd48c7495 100644 --- a/src/routes/[network]/(account)/(staking)/staking/utils.ts +++ b/src/routes/[network]/(account)/(staking)/staking/utils.ts @@ -18,8 +18,6 @@ export function getStakableBalance(network: NetworkState, account: AccountState) if (account.balance && account.balance.liquid) { balance.add(account.balance.liquid.units); } - - // TODO: add rexfund } return Asset.fromUnits(balance, network.chain.systemToken!.symbol); } From cd22972a50d37331dcde5b8867f5c0c70d378f76 Mon Sep 17 00:00:00 2001 From: apporc Date: Tue, 24 Sep 2024 11:51:15 +0800 Subject: [PATCH 08/10] Staking: change state to manager --- .../(staking)/staking/stake/+page.svelte | 48 +++++++++---------- .../{state.svelte.ts => manager.svelte.ts} | 2 +- .../(staking)/staking/unstake/+page.svelte | 44 ++++++++--------- .../{state.svelte.ts => manager.svelte.ts} | 2 +- .../(staking)/staking/withdraw/+page.svelte | 20 ++++---- .../{state.svelte.ts => manager.svelte.ts} | 2 +- 6 files changed, 59 insertions(+), 59 deletions(-) rename src/routes/[network]/(account)/(staking)/staking/stake/{state.svelte.ts => manager.svelte.ts} (99%) rename src/routes/[network]/(account)/(staking)/staking/unstake/{state.svelte.ts => manager.svelte.ts} (98%) rename src/routes/[network]/(account)/(staking)/staking/withdraw/{state.svelte.ts => manager.svelte.ts} (98%) diff --git a/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte index 75a2fc6a1..ede95eb67 100644 --- a/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/stake/+page.svelte @@ -10,21 +10,21 @@ import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext, untrack } from 'svelte'; - import { StakeState } from './state.svelte'; + import { StakeManager } from './manager.svelte'; const context = getContext('state'); const { data } = $props(); - let stakeState: StakeState = $state(new StakeState(data.network)); + let manager: StakeManager = $state(new StakeManager(data.network)); $effect(() => { - stakeState.sync(data.network, context.account, context.wharf); + manager.sync(data.network, context.account, context.wharf); }); -{#if stakeState.txid} - -{:else if stakeState.error} +{#if manager.txid} + +{:else if manager.error}

Transaction Error

There was an error submitting your transaction.

@@ -37,28 +37,28 @@ - {#if !stakeState.assetValid} - {#if !stakeState.assetValidPrecision} + {#if !manager.assetValid} + {#if !manager.assetValidPrecision}

Invalid number, too many decimal places.

{/if} - {#if !stakeState.assetValidMaximum} + {#if !manager.assetValidMaximum}

Amount exceeds available balance.

{/if} {/if} @@ -67,9 +67,9 @@ Available: {manager.stakable} @@ -81,11 +81,11 @@

Minimum lockup

21 Days

~APY

-

{stakeState.apy}%

+

{manager.apy}%

You will stake

-

{stakeState.assetValid ? stakeState.assetValue : ''}

+

{manager.assetValid ? manager.assetValue : ''}

Estimated Yield(per year)

-

{stakeState.assetValid ? stakeState.estimateYield : ''}

+

{manager.assetValid ? manager.estimateYield : ''}

diff --git a/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/stake/manager.svelte.ts similarity index 99% rename from src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts rename to src/routes/[network]/(account)/(staking)/staking/stake/manager.svelte.ts index 8536fe673..8a3f1c3c6 100644 --- a/src/routes/[network]/(account)/(staking)/staking/stake/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/stake/manager.svelte.ts @@ -6,7 +6,7 @@ import AssetInput from '$lib/components/input/asset.svelte'; import { defaultQuantity, getStakableBalance, getAPY } from '../utils'; -export class StakeState { +export class StakeManager { public input: AssetInput | undefined = $state(); public network: NetworkState | undefined = $state(); public account: AccountState | undefined = $state(); diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte index 9a02df2ec..49d09d389 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte @@ -10,21 +10,21 @@ import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; - import { UnstakeState } from './state.svelte'; + import { UnstakeManager } from './state.svelte'; const context = getContext('state'); const { data } = $props(); - let unstakeState: UnstakeState = $state(new UnstakeState(data.network)); + let manager: UnstakeManager = $state(new UnstakeManager(data.network)); $effect(() => { - unstakeState.sync(data.network, context.account, context.wharf); + manager.sync(data.network, context.account, context.wharf); }); -{#if unstakeState.txid} - -{:else if unstakeState.error} +{#if manager.txid} + +{:else if manager.error}

Transaction Error

There was an error submitting your transaction.

@@ -37,29 +37,29 @@ - {#if !unstakeState.assetValid} - {#if !unstakeState.assetValidPrecision} + {#if !manager.assetValid} + {#if !manager.assetValidPrecision}

Invalid number, too many decimal places.

{/if} - {#if !unstakeState.assetValidMaximum} + {#if !manager.assetValidMaximum}

Amount exceeds available balance.

{/if} {/if} @@ -68,9 +68,9 @@ Available: {manager.unstakable} @@ -80,7 +80,7 @@

In 21 days you can claim

-

{unstakeState.assetValid ? unstakeState.assetValue : ''}

+

{manager.assetValid ? manager.assetValue : ''}

Lockup

21 Days

diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/unstake/manager.svelte.ts similarity index 98% rename from src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts rename to src/routes/[network]/(account)/(staking)/staking/unstake/manager.svelte.ts index 8f454edc9..6bc62ae97 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/manager.svelte.ts @@ -7,7 +7,7 @@ import AssetInput from '$lib/components/input/asset.svelte'; import type { UnstakingRecord } from '../utils'; import { defaultQuantity, getUnstakableBalance, getUnstakingBalances } from '../utils'; -export class UnstakeState { +export class UnstakeManager { public input: AssetInput | undefined = $state(); public network: NetworkState | undefined = $state(); public account: AccountState | undefined = $state(); diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte index f63c7c2a5..4dfa8102f 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte @@ -12,22 +12,22 @@ import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; - import { WithdrawState } from './state.svelte'; + import { WithdrawManager } from './state.svelte'; import UnstakingBalances from '../unstaking.svelte'; const context = getContext('state'); const { data } = $props(); - let withdrawState: WithdrawState = $state(new WithdrawState(data.network)); + let manager: WithdrawManager = $state(new WithdrawManager(data.network)); $effect(() => { - withdrawState.sync(data.network, context.account, context.wharf); + manager.sync(data.network, context.account, context.wharf); }); -{#if withdrawState.txid} - -{:else if withdrawState.error} +{#if manager.txid} + +{:else if manager.error}

Transaction Error

There was an error submitting your transaction.

@@ -35,16 +35,16 @@ {:else} - + - + {/if} diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts similarity index 98% rename from src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts rename to src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts index 30969d727..999aec1d0 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/state.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts @@ -11,7 +11,7 @@ import { getWithdrawableBalance } from '../utils'; -export class WithdrawState { +export class WithdrawManger { public network: NetworkState | undefined = $state(); public account: AccountState | undefined = $state(); public wharf: WharfState | undefined = $state(); From 0194b5f10ea41ec78b04c8f12ec557e887234d32 Mon Sep 17 00:00:00 2001 From: apporc Date: Tue, 24 Sep 2024 11:51:46 +0800 Subject: [PATCH 09/10] Staking: make format --- .github/workflows/check.yml | 1 - .../[network]/(account)/(staking)/staking/+layout.svelte | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4ee11b62a..740fe7b62 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -24,4 +24,3 @@ jobs: - uses: oven-sh/setup-bun@v2 - run: bun install - run: bunx tsc --noemit - diff --git a/src/routes/[network]/(account)/(staking)/staking/+layout.svelte b/src/routes/[network]/(account)/(staking)/staking/+layout.svelte index c3fb6f3fa..60ccafcac 100644 --- a/src/routes/[network]/(account)/(staking)/staking/+layout.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/+layout.svelte @@ -34,8 +34,8 @@ - - + + {@render children()} From e5ffd5d4c7f87cd4d99241e1215eced150e7f389 Mon Sep 17 00:00:00 2001 From: Aaron Cox Date: Tue, 1 Oct 2024 15:38:20 -0700 Subject: [PATCH 10/10] Fixed names --- .../[network]/(account)/(staking)/staking/unstake/+page.svelte | 2 +- .../[network]/(account)/(staking)/staking/withdraw/+page.svelte | 2 +- .../(account)/(staking)/staking/withdraw/manager.svelte.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte index 49d09d389..67ec4b5af 100644 --- a/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/unstake/+page.svelte @@ -10,7 +10,7 @@ import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; - import { UnstakeManager } from './state.svelte'; + import { UnstakeManager } from './manager.svelte'; const context = getContext('state'); const { data } = $props(); diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte index 4dfa8102f..56930235a 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/+page.svelte @@ -12,7 +12,7 @@ import * as m from '$lib/paraglide/messages.js'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; - import { WithdrawManager } from './state.svelte'; + import { WithdrawManager } from './manager.svelte'; import UnstakingBalances from '../unstaking.svelte'; const context = getContext('state'); diff --git a/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts b/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts index 999aec1d0..4085b0161 100644 --- a/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts +++ b/src/routes/[network]/(account)/(staking)/staking/withdraw/manager.svelte.ts @@ -11,7 +11,7 @@ import { getWithdrawableBalance } from '../utils'; -export class WithdrawManger { +export class WithdrawManager { public network: NetworkState | undefined = $state(); public account: AccountState | undefined = $state(); public wharf: WharfState | undefined = $state();