Skip to content

Commit

Permalink
fix: Total balance calculation incorrect
Browse files Browse the repository at this point in the history
  • Loading branch information
AricRedemption committed Feb 22, 2024
1 parent c40464b commit b56be54
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 66 deletions.
4 changes: 2 additions & 2 deletions src/lib/actions/btc/inscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ export async function process({
const utxos = await getBtcUtxos(address)
const commitTxPrevOutputList = utxos.map((utxo) => ({
txId: utxo.txId,
vOut: utxo.vout,
amount: utxo.satoshi,
vOut: utxo.outputIndex,
amount: utxo.satoshis,
address,
}))
const signer = (await getSigner('btc')) as BIP32Interface
Expand Down
4 changes: 3 additions & 1 deletion src/lib/balance.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { computed, ref } from 'vue'
import { type Chain } from './account'

interface Asset {
chain: Chain
name: string
value: number
}
Expand All @@ -14,7 +16,7 @@ export const resetAssetList = () => {
}

export async function updateAsset(asset: Asset) {
const preAsset = assetList.value.find((assetItem) => assetItem.name === asset.name)
const preAsset = assetList.value.find((assetItem) => assetItem.name === asset.name && assetItem.chain === asset.chain)
if (!preAsset) {
assetList.value.push(asset)
} else {
Expand Down
3 changes: 0 additions & 3 deletions src/lib/btc-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ type PsbtInput = (typeof Psbt.prototype.data.inputs)[0]
function inputBytes(input: PsbtInput) {
// todo: script length
if (isTaprootInput(input)) {
console.log('taproot input')
return TX_INPUT_BASE + TX_INPUT_TAPROOT
}

Expand Down Expand Up @@ -98,8 +97,6 @@ export async function getTweakedPrivateKey() {

export async function getXOnlyPublicKey() {
const publicKeyStr = await getPublicKey('btc')
console.log({ publicKeyStr })

return Buffer.from(publicKeyStr, 'hex').subarray(1)
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const prettifyTxId = (txId: string, useDigits = 6) => {
export const prettifyBalance = (balance: number, symbol: string = 'SPACE'): string => {
if (!balance) return `0 ${symbol}`

return `${new Decimal(balance).dividedBy(1e8).toDecimalPlaces(8, Decimal.ROUND_HALF_UP)} ${symbol}`
return `${new Decimal(balance).dividedBy(1e8).toDecimalPlaces(8, Decimal.ROUND_HALF_UP).toNumber()} ${symbol}`
}

export const prettifyBalanceFixed = (balance: number, symbol: string = 'SPACE', toFixedNum: number): string => {
Expand Down
20 changes: 10 additions & 10 deletions src/lib/wallets/btc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class BtcWallet {
if (!utxos.length) {
throw new Error('your account currently has no available UTXO.')
}
utxos.sort((a, b) => b.satoshi - a.satoshi)
utxos.sort((a, b) => b.satoshis - a.satoshis)

const buildPsbt = async (selectedUtxos: UTXO[], change: Decimal) => {
const psbt = new Psbt({ network: btcNetwork })
Expand All @@ -44,7 +44,7 @@ export class BtcWallet {

psbt.addInput(payInput)
psbt.addOutput({
value: utxo.satoshi,
value: utxo.satoshis,
address: recipient,
})

Expand Down Expand Up @@ -104,15 +104,15 @@ export class BtcWallet {
if (!utxos.length) {
throw new Error('your account currently has no available UTXO.')
}
utxos.sort((a, b) => b.satoshi - a.satoshi)
utxos.sort((a, b) => b.satoshis - a.satoshis)

const buildPsbt = async (selectedUtxos: UTXO[], change: Decimal) => {
const psbt = new Psbt({ network: btcNetwork })

const payInput = await createPayInput({ utxo, payment, addressType })
psbt.addInput(payInput)
psbt.addOutput({
value: utxo.satoshi,
value: utxo.satoshis,
address: recipient,
})

Expand Down Expand Up @@ -202,7 +202,7 @@ async function getPsbtAndSelectUtxos(recipient: string, amount: Decimal, feeRate
const addressType = await getAddressType('btc')
const payment = await createPayment(addressType)
const utxos = (await getBtcUtxos(address)) || []
utxos.sort((a, b) => b.satoshi - a.satoshi)
utxos.sort((a, b) => b.satoshis - a.satoshis)

const buildPsbt = async (selectedUtxos: UTXO[], change: Decimal) => {
const psbt = new Psbt({ network: btcNetwork }).addOutput({
Expand Down Expand Up @@ -255,7 +255,7 @@ const selectUTXOs = (utxos: UTXO[], targetAmount: Decimal): UTXO[] => {
const selectedUtxos: typeof utxos = []
for (const utxo of utxos) {
selectedUtxos.push(utxo)
totalAmount = totalAmount.add(utxo.satoshi)
totalAmount = totalAmount.add(utxo.satoshis)

if (totalAmount.gte(targetAmount)) {
break
Expand Down Expand Up @@ -284,7 +284,7 @@ function calculateFee(psbt: Psbt, feeRate: number): number {
}

function getTotalSatoshi(utxos: UTXO[]): Decimal {
return utxos.reduce((total, utxo) => total.add(utxo.satoshi), new Decimal(0))
return utxos.reduce((total, utxo) => total.add(utxo.satoshis), new Decimal(0))
}

async function createPayInput({
Expand All @@ -301,17 +301,17 @@ async function createPayInput({

const payInput: any = {
hash: utxo.txId,
index: utxo.vout,
index: utxo.outputIndex,
}

if (['P2SH-P2WPKH', 'P2WPKH'].includes(addressType)) {
payInput['witnessUtxo'] = getWitnessUtxo(tx.outs[utxo.vout])
payInput['witnessUtxo'] = getWitnessUtxo(tx.outs[utxo.outputIndex])
}

if (['P2TR'].includes(addressType)) {
payInput['tapInternalKey'] = await getXOnlyPublicKey()

payInput['witnessUtxo'] = { value: utxo.satoshi, script: payment.output }
payInput['witnessUtxo'] = { value: utxo.satoshis, script: payment.output }
}

if (['P2PKH'].includes(addressType)) {
Expand Down
7 changes: 2 additions & 5 deletions src/pages/accounts/components/Item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { FEEB } from '@/data/config'
import EditName from './EditName.vue'
import { useRouter } from 'vue-router'
import { assetList } from '@/lib/balance'
import { getNetwork } from '@/lib/network'
import { Ref, computed, inject, ref } from 'vue'
import { shortestAddress } from '@/lib/formatters'
Expand Down Expand Up @@ -75,8 +74,6 @@ const connect = async () => {
const wif = await getPrivateKey()
wallet.value = new Wallet(wif, network as API_NET, FEEB, API_TARGET.MVC)
assetList.value = []
router.push('/wallet')
}
Expand Down Expand Up @@ -148,9 +145,9 @@ const openEditNameModal = ref(false)
<template v-if="showConnectButton">
<span v-if="isCurrent" class="text-sm text-gray-500 cursor-pointer" @click="connect">active</span>
<button
class="rounded-md bg-blue-100 px-2 py-1 text-sm text-blue-700 transition hover:bg-blue-200"
@click="connect"
v-else
@click="connect"
class="rounded-md bg-blue-100 px-2 py-1 text-sm text-blue-700 transition hover:bg-blue-200"
>
Connect
</button>
Expand Down
8 changes: 4 additions & 4 deletions src/pages/wallet/Asset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ const assetUSD = computed(() => {
})
watch(assetUSD, (_assetUSD) => {
if (_assetUSD) {
updateAsset({ name: asset.value!.symbol, value: _assetUSD.toNumber() })
if (asset.value && _assetUSD) {
updateAsset({ chain: asset.value.chain, name: asset.value.symbol, value: _assetUSD.toNumber() })
}
})
Expand Down Expand Up @@ -156,7 +156,7 @@ const toTransfer = () => {
</div>

<div class="text-[#909399] text-center">
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP)} USD` }}</span>
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()} USD` }}</span>
<span v-else>$-- USD</span>
</div>
</template>
Expand All @@ -171,7 +171,7 @@ const toTransfer = () => {
</span>
</div>
<div class="text-[#909399] text-center">
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP)} USD` }}</span>
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()} USD` }}</span>
<span v-else>$-- USD</span>
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/wallet/Inscribe.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const popConfirm = async () => {
return
}
const { fee, psbt, selecedtUTXOs } = data
inputUTXOs.value = selecedtUTXOs.map((utxo) => ({ address: address.value, value: utxo.satoshi }))
inputUTXOs.value = selecedtUTXOs.map((utxo) => ({ address: address.value, value: utxo.satoshis }))
const tx = psbt.extractTransaction()
outputUTXOs.value = psbt.txOutputs.map((out) => ({
address: out.address || '',
Expand Down
7 changes: 3 additions & 4 deletions src/pages/wallet/components/AssetItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import { ref, computed, watch } from 'vue'
import { updateAsset } from '@/lib/balance'
import { isOfficialToken } from '@/lib/assets'
import { useBalanceQuery } from '@/queries/balance'
import { prettifyTokenBalance } from '@/lib/formatters'
import { CheckBadgeIcon } from '@heroicons/vue/24/solid'
import { useExchangeRatesQuery } from '@/queries/exchange-rates'
import { type Asset, getTagInfo, type Tag } from '@/data/assets'
import { CheckBadgeIcon } from '@heroicons/vue/24/solid'
const { asset, address } = defineProps<{
asset: Asset
Expand Down Expand Up @@ -61,7 +60,7 @@ watch(
assetUSD,
(_assetUSD) => {
if (_assetUSD) {
updateAsset({ name: asset.symbol, value: _assetUSD.toNumber() })
updateAsset({ chain: asset.chain, name: asset.symbol, value: _assetUSD.toNumber() })
}
},
{ immediate: true }
Expand Down Expand Up @@ -105,7 +104,7 @@ watch(
>
<div class="text-black-primary font-bold text-base">{{ assetPrice }}</div>
<div :class="['text-sm font-normal text-gray-500']">
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP)} USD` }}</span>
<span v-if="assetUSD">{{ `$${assetUSD.toDecimalPlaces(2, Decimal.ROUND_HALF_UP).toNumber()} USD` }}</span>
<span v-else>$-- USD</span>
</div>
</div>
Expand Down
37 changes: 4 additions & 33 deletions src/queries/utxos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import { mvcApi, mempoolApi, metaletApiV3 } from './request'

export interface UTXO {
txId: string
vout: number
outputIndex?: number
satoshi: number
satoshis?: number
outputIndex: number
satoshis: number
confirmed: boolean
inscriptions:
| {
Expand Down Expand Up @@ -70,28 +68,10 @@ export interface UnisatUTXO {
}[]
}

function formatUnisatUTXO(utxo: UnisatUTXO & { confirmed: boolean }): UTXO {
return {
txId: utxo.txId,
vout: utxo.outputIndex,
satoshi: utxo.satoshis,
confirmed: utxo.confirmed,
inscriptions: utxo.inscriptions.map(({ id, num }) => ({ id, num })),
}
}

export async function getBtcUtxos(address: string): Promise<UTXO[]> {
const net = await await getNet()
return metaletApiV3<UTXO[]>('/address/btc-utxo')
.get({ net, address, unconfirmed: '1' })
.then((utxos) => {
utxos.forEach((utxo) => {
if (utxo?.satoshis !== undefined && utxo.satoshi === undefined) {
utxo.satoshi = utxo.satoshis
}
})
return utxos
})
}

// export async function getInscriptionUtxos(inscriptions: Inscription[]): Promise<UTXO[]> {
Expand All @@ -110,15 +90,6 @@ export async function getInscriptionUtxo(inscriptionId: string): Promise<UTXO> {
const net = await await getNet()
return await metaletApiV3<UTXO>('/inscription/utxo')
.get({ net, inscriptionId })
.then((utxo) => {
if (utxo?.satoshis !== undefined && utxo.satoshi === undefined) {
utxo.satoshi = utxo.satoshis
}
if (utxo?.outputIndex !== undefined && utxo.vout === undefined) {
utxo.vout = utxo.outputIndex
}
return utxo
})
}

export interface MempoolUtxo {
Expand All @@ -136,8 +107,8 @@ export interface MempoolUtxo {
function formatMempoolUTXO(utxo: MempoolUtxo): UTXO {
return {
txId: utxo.txid,
vout: utxo.vout,
satoshi: utxo.value,
outputIndex: utxo.vout,
satoshis: utxo.value,
confirmed: utxo.status.confirmed,
inscriptions: [],
}
Expand Down
10 changes: 8 additions & 2 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { IS_DEV } from '@/data/config'
import * as VueRouter from 'vue-router'

import { assetList } from '@/lib/balance'
import Wallet from './pages/wallet/Index.vue'
import { getStorage, useStorage } from './lib/storage'
import { getAccounts, getCurrentAccount, getLegacyAccounts, needsMigrationV2 } from './lib/account'
import { IS_DEV } from '@/data/config'

const routes = [
{ path: '/', redirect: '/wallet' },
Expand Down Expand Up @@ -334,6 +334,12 @@ router.beforeEach(async (to, from) => {
}
})

router.beforeEach(async (to, from) => {
if (to.path === '/wallet') {
assetList.value = []
}
})

// 检查账号状态;如果没有当前账号,跳转到账号页面
router.beforeEach(async (to, from) => {
// 如果是老用户(sync存储中有助记词),且该账号在localStorage中不存在,则说明需要迁移,跳转至新版本迁移页面
Expand Down

0 comments on commit b56be54

Please sign in to comment.