Skip to content

Commit

Permalink
fix: ft token send and inscribe api
Browse files Browse the repository at this point in the history
  • Loading branch information
AricRedemption committed Apr 26, 2024
1 parent fa6173e commit e3ddb53
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 155 deletions.
6 changes: 4 additions & 2 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { network } from '@/lib/network'
import actions from './data/query-actions'
import browser from 'webextension-polyfill'
import exActions from './data/extension-actions'
import { getCurrentWalletId, hasWallets } from './lib/wallet'
import { getAddress, getCurrentAccountId } from './lib/account'
import { NOTIFICATION_HEIGHT, NOTIFICATION_WIDTH } from './data/config'
import { getCurrentWalletId, hasWallets, getCurrentWallet } from './lib/wallet'
import { Chain } from '@metalet/utxo-wallet-service'

// const browser = window.browser as typeof chromex
browser.runtime.onMessage.addListener(async (msg, sender) => {
Expand Down Expand Up @@ -80,7 +81,8 @@ browser.runtime.onMessage.addListener(async (msg, sender) => {
if (actionName === 'InscribeTransfer') {
const rawUrl = 'popup.html#/wallet/inscribe'
let popupUrl = browser.runtime.getURL(rawUrl)
const address = await getAddress('btc')
const wallet = await getCurrentWallet(Chain.BTC)
const address = wallet.getAddress()
popupUrl += `/${msg.params}/${address}`
let top = 0
let left = 0
Expand Down
2 changes: 1 addition & 1 deletion src/components/AssetLogo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const { logo, chain, symbol } = defineProps<{
chain?: Chain
symbol: string
type: 'network' | 'activity'
flow?: 'Send' | 'Receive'
flow?: 'Send' | 'Receive' | 'Transfer'
}>()
</script>

Expand Down
2 changes: 0 additions & 2 deletions src/lib/actions/btc/sign-message.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { getPrivateKey } from '@/lib/account'
import { getCurrentWallet } from '@/lib/wallet'
import { Chain } from '@metalet/utxo-wallet-service'
import { Message, PrivateKey } from 'bitcore-lib'

export async function process(message: string): Promise<string> {
const wallet = await getCurrentWallet(Chain.BTC)
Expand Down
1 change: 0 additions & 1 deletion src/lib/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ export const payTransactions = async (
}

const addressObj = new mvc.Address(address, network)
console.log({ addressObj })
// find out the total amount of the transaction (total output minus total input)
const totalOutput = tx.outputs.reduce((acc, output) => acc + output.satoshis, 0)
const totalInput = tx.inputs.reduce((acc, input) => acc + input.output!.satoshis, 0)
Expand Down
4 changes: 2 additions & 2 deletions src/lib/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const prettifyTxId = (txId: string, useDigits = 6) => {
return `${txId.slice(0, useDigits)}...${txId.slice(-useDigits)}`
}

export const prettifyAddress = (txId: string, useDigits = 6) => {
return `${txId.slice(0, useDigits)}...${txId.slice(-useDigits)}`
export const prettifyAddress = (address: string, useDigits = 6) => {
return `${address.slice(0, useDigits)}...${address.slice(-useDigits)}`
}

export const prettifyBalance = (balance: number, symbol: string = 'SPACE'): string => {
Expand Down
1 change: 1 addition & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const goToTab = (path: string, created = false) => {
router.push(path)
} else {
window.open(`${window.location.href.split('#')[0]}#${path}`, '_blank')
window.close()
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/pages/wallet/BRC20.vue
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ watch(assetUSD, (_assetUSD) => {
</div>

<div class="flex items-center justify-center gap-x-2">
<RouterLink to="javascript:void(0);" class="btn-blue-light">
<RouterLink to="javascript:void(0);" class="btn-blue-light" v-if="false">
<img :src="MintPNG" alt="Mint" />
<span>Mint</span>
</RouterLink>
Expand Down
1 change: 0 additions & 1 deletion src/pages/wallet/Send.vue
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ async function send() {
<div class="space-y-4 w-full">
<FlexBox d="col" ai="center" :gap="3">
<AssetLogo :logo="asset?.logo" :symbol="symbol" :chain="asset.chain" type="network" class="w-15" />

<div class="text-base">{{ symbol }}</div>
</FlexBox>

Expand Down
226 changes: 133 additions & 93 deletions src/pages/wallet/SendToken.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
<script lang="ts" setup>
import Decimal from 'decimal.js'
import { ref, computed } from 'vue'
import { useRoute } from 'vue-router'
import { getTags } from '@/data/assets'
import { getNetwork } from '@/lib/network'
import { useRoute, useRouter } from 'vue-router'
import { API_NET, FtManager } from 'meta-contract'
import { CircleStackIcon } from '@heroicons/vue/24/solid'
import { useMVCTokenQuery } from '@/queries/tokens'
import { useQueryClient } from '@tanstack/vue-query'
import { getNetwork } from '@/lib/network'
import { prettifyTokenBalance } from '@/lib/formatters'
import { getAddress, getCurrentAccount, getPrivateKey } from '@/lib/account'
import LoadingIcon from '@/components/LoadingIcon.vue'
import type { TransactionResult } from '@/global-types'
import { useMVCTokenQuery } from '@/queries/tokens'
import Modal from '@/components/Modal.vue'
import { useChainWalletsStore } from '@/stores/ChainWalletsStore'
import { AssetLogo, Divider, FlexBox, Button } from '@/components'
import TransactionResultModal from './components/TransactionResultModal.vue'
import { Drawer, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader } from '@/components/ui/drawer'
const route = useRoute()
const router = useRouter()
const symbol = ref(route.params.symbol as string)
const genesis = ref(route.params.genesis as string)
const address = ref(route.params.address as string)
const queryClient = useQueryClient()
const { currentMVCWallet } = useChainWalletsStore()
const error = ref<Error>()
const tags = computed(() => {
if (asset.value) {
return getTags(asset.value)
}
})
const queryClient = useQueryClient()
// 用户拥有的代币资产
const { isLoading, data: asset } = useMVCTokenQuery(address, genesis, {
enabled: computed(() => !!address.value && !genesis.value),
enabled: computed(() => !!address.value && !!genesis.value),
})
const balance = computed(() => {
if (asset.value) {
return new Decimal(asset.value.balance!.total).div(10 ** asset.value.decimal).toNumber()
}
})
// form
Expand All @@ -51,7 +63,7 @@ async function send() {
operationLock.value = true
const privateKey = await getPrivateKey('mvc')
const privateKey = currentMVCWallet.value!.getPrivateKey()
const network = await getNetwork()
Expand Down Expand Up @@ -92,7 +104,6 @@ async function send() {
})
.catch((err) => {
isOpenConfirmModal.value = false
error.value = err.message
if (err instanceof Error) {
if (err.message === 'Too many token-utxos, should merge them to continue.') {
transactionResult.value = {
Expand All @@ -101,36 +112,34 @@ async function send() {
message: err.message,
confirmText: 'Merge',
}
} else {
transactionResult.value = {
router: 'ft-merge',
status: 'failed',
message: err.message,
confirmText: 'Merge',
}
}
} else {
transactionResult.value = {
status: 'failed',
message: err.message,
message: err?.message || err,
}
}
isOpenResultModal.value = true
})
if (transferRes && transferRes.txid) {
isOpenConfirmModal.value = false
transactionResult.value = {
chain: 'mvc',
status: 'success',
txId: transferRes.txid,
fromAddress: address.value,
toAdddress: recipient.value,
amount: amountInSats.value,
token: {
symbol: asset.value!.symbol,
decimal: asset.value!.decimal,
router.replace({
name: 'SendSuccess',
params: {
txId: transferRes.txid,
chain: 'mvc',
symbol: symbol.value,
amount: amount.value,
address: recipient.value,
},
}
isOpenResultModal.value = true
// 刷新query
queryClient.invalidateQueries({
queryKey: ['tokens', { address: address.value }],
})
}
Expand All @@ -139,77 +148,108 @@ async function send() {
</script>

<template>
<div class="mt-8 flex flex-col items-center gap-y-8" v-if="asset && genesis">
<div class="space-y-6 h-full relative" v-if="asset && genesis">
<TransactionResultModal v-model:is-open-result="isOpenResultModal" :result="transactionResult" />
<img :src="asset?.logo" alt="" class="h-16 w-16 rounded-xl" v-if="asset?.logo" />
<CircleStackIcon class="h-10 w-10 text-gray-300 transition-all group-hover:text-blue-500" v-else />

<div class="space-y-3 self-stretch">
<!-- address input -->
<input class="main-input w-full !rounded-xl !p-4 text-sm" placeholder="Recipient's address" v-model="recipient" />
<div class="space-y-4">
<FlexBox d="col" ai="center">
<AssetLogo :logo="asset?.logo" :symbol="symbol" :chain="asset.chain" type="network" class="w-15" />

<div class="mt-3 text-base">{{ symbol }}</div>

<!-- amount input -->
<div class="relative">
<input class="main-input w-full !rounded-xl !py-4 !pl-4 !pr-12 text-sm" placeholder="Amount" v-model="amount" />
<!-- unit -->
<div
class="absolute right-0 top-0 flex h-full items-center justify-center text-right text-xs text-gray-500"
v-if="asset?.symbol"
:key="tag.name"
v-for="tag in tags"
:style="`background-color:${tag.bg};color:${tag.color};`"
:class="['px-1', 'py-0.5', 'rounded', 'text-xs', 'inline-block', 'mt-2']"
>
<div class="border-l border-solid border-gray-500 px-4 py-1">{{ asset.symbol }}</div>
{{ tag.name }}
</div>
</div>

<!-- balance -->
<div class="flex items-center gap-x-2 text-xs text-gray-500">
<div>Your Balance:</div>
<div v-if="isLoading">--</div>
<div v-else-if="asset">
{{ prettifyTokenBalance(asset.balance?.total || 0, asset.decimal) + ' ' + asset.symbol }}
</div>
</div>
</FlexBox>

<Divider />
</div>

<!-- send -->
<button class="main-btn-bg w-full rounded-lg py-3 text-sm text-sky-100" @click="popConfirm">Send</button>

<Modal v-model:is-open="isOpenConfirmModal" title="Confirm">
<template #title>
<div class="text-black-primary text-center">Confirm Send</div>
</template>

<template #body>
<div class="mt-4 space-y-4">
<div class="space-y-1">
<div class="label">Amount</div>
<div class="value">{{ amount }} {{ asset?.symbol }}</div>
</div>
<div class="space-y-1">
<div class="label">Recipient Address</div>
<div class="value break-all text-sm">{{ recipient }}</div>
</div>
<!-- <div class="space-y-1">
<div class="label">Network Fee</div>
<div class="value">100 SPACE</div>
</div> -->
</div>
</template>
<div class="space-y-2">
<div>Receiver</div>
<textarea
v-model="recipient"
class="w-full rounded-lg p-3 text-xs border border-gray-soft focus:border-blue-primary focus:outline-none break-all"
/>
</div>
<div class="space-y-2">
<FlexBox ai="center" jc="between">
<span>Amount</span>
<span class="text-gray-primary text-xs">
<span>Balance:</span>
<span v-if="balance">{{ balance }} {{ symbol }}</span>
<span v-else>--</span>
</span>
</FlexBox>
<input
min="0"
type="number"
step="0.00001"
:max="asset.balance!.total"
v-model="amount"
class="mt-2 w-full rounded-lg p-3 text-xs border border-gray-soft focus:border-blue-primary focus:outline-none"
/>
</div>

<template #control>
<div v-if="operationLock">
<div class="w-full py-3 text-center text-sm text-gray-500">Operating...</div>
</div>
<div class="grid grid-cols-2 gap-x-4" v-else>
<button
class="w-full rounded-lg border border-primary-blue bg-white py-3 text-sm text-gray-700"
@click="isOpenConfirmModal = false"
>
Cancel
</button>
<button class="main-btn-bg w-full rounded-lg py-3 text-sm text-sky-100" @click="send">Confirm</button>
<Button
type="primary"
@click="isOpenConfirmModal = true"
:disabled="!recipient"
class="absolute bottom-4 left-1/2 -translate-x-1/2 w-61.5 h-12"
:class="!recipient || operationLock ? 'opacity-50 cursor-not-allowed' : undefined"
>
<FlexBox ai="center" :gap="1" v-if="operationLock">
<LoadingIcon />
<span>Loading...</span>
</FlexBox>
<span v-else>Next</span>
</Button>

<Drawer v-model:open="isOpenConfirmModal">
<DrawerContent class="bg-white">
<DrawerHeader>
<FlexBox d="col" ai="center" :gap="4">
<AssetLogo :logo="asset?.logo" :symbol="symbol" :chain="asset.chain" type="network" class="w-15" />
<div class="text-base">{{ amount }} {{ symbol }}</div>
</FlexBox>
</DrawerHeader>
<Divider class="mt-2" />
<div class="p-4 space-y-4 text-ss">
<FlexBox ai="center" jc="between">
<div class="text-gray-primary">From</div>
<div class="break-all w-[228px]">{{ address }}</div>
</FlexBox>
<FlexBox ai="center" jc="between">
<div class="text-gray-primary">To</div>
<div class="break-all w-[228px]">{{ recipient }}</div>
</FlexBox>
<FlexBox ai="center" jc="between">
<div class="text-gray-primary">Amount</div>
<div class="break-all">{{ amount }} {{ symbol }}</div>
</FlexBox>
</div>
</template>
</Modal>
<DrawerFooter>
<FlexBox ai="center" jc="center" :gap="2">
<DrawerClose>
<Button type="light" class="w-[119px] h-12">Cancel</Button>
</DrawerClose>
<Button
@click="send"
type="primary"
:class="['w-[119px] h-12', { 'opacity-50 cursor-not-allowed space-x-1': operationLock }]"
>
<LoadingIcon v-if="operationLock" />
<span>Confirm</span>
</Button>
</FlexBox>
</DrawerFooter>
</DrawerContent>
</Drawer>
</div>
<div v-else class="text-center text-gray-primary w-full py-3 text-base">Token can not found.</div>
</template>
Expand Down
11 changes: 5 additions & 6 deletions src/pages/wallet/Transfer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ const toInscribe = () => {
<div>
<div class="text-sm">Inscribe Transfer</div>
<div class="text-gray-primary text-xs">You have to inscribe a TRANSFER inscription first.</div>
<FlexBox
ai="center"
jc="center"
class="bg-gray-secondary text-sm rounded-md h-12 mt-3 cursor-pointer"
<div
@click="toInscribe"
class="flex items-center justify-center gap-2 bg-gray-secondary text-sm rounded-md h-12 mt-3 cursor-pointer border border-blue-primary bg-[rgba(23, 26, 255, 0.05)]"
>
Available {{ tickersData.tokenBalance.availableBalance }} {{ symbol }}
</FlexBox>
<span class="text-gray-primary">Available</span>
<span>{{ tickersData.tokenBalance.availableBalance }} {{ symbol }}</span>
</div>
</div>
</FlexBox>
</template>
Loading

0 comments on commit e3ddb53

Please sign in to comment.