Skip to content

Commit

Permalink
fix: Encrypt and decrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
AricRedemption committed Jan 22, 2024
1 parent 6cf1141 commit 8b4a6b0
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 123 deletions.
10 changes: 9 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { useRoute ,useRouter} from 'vue-router'
import { computed, Ref, inject } from 'vue'
import passwordManager from '@/lib/password'
import { API_NET, API_TARGET, Wallet } from 'meta-contract'
// setup vue-query
import { useQueryClient } from '@tanstack/vue-query'
Expand All @@ -15,6 +16,13 @@ import TheHeader from './components/headers/TheHeader.vue'
import SecondaryHeader from './components/headers/SecondaryHeader.vue'
const route = useRoute()
const router = useRouter()
// 查询有否设置密码
passwordManager.has().then(hasPassword=>{
const following = hasPassword ? '/wallet' : '/wallet/set-password'
router.push(following)
})
const queryClient = useQueryClient()
queryClient.setDefaultOptions({
Expand Down
15 changes: 8 additions & 7 deletions src/lib/btc-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { isTaprootInput } from 'bitcoinjs-lib/src/psbt/bip371'

import { raise } from './helpers'
import { Output } from 'bitcoinjs-lib/src/transaction'
import { encrypt } from './crypto'

export const DUST_UTXO_VALUE = 546
const TX_EMPTY_SIZE = 4 + 1 + 1 + 4
Expand Down Expand Up @@ -55,12 +56,12 @@ function outputBytes(output: PsbtTxOutput) {
(output.script
? output.script.length
: output.address?.startsWith('bc1') || output.address?.startsWith('tb1')
? output.address?.length === 42
? TX_OUTPUT_SEGWIT
: TX_OUTPUT_SEGWIT_SCRIPTHASH
: output.address?.startsWith('3') || output.address?.startsWith('2')
? TX_OUTPUT_SCRIPTHASH
: TX_OUTPUT_PUBKEYHASH)
? output.address?.length === 42
? TX_OUTPUT_SEGWIT
: TX_OUTPUT_SEGWIT_SCRIPTHASH
: output.address?.startsWith('3') || output.address?.startsWith('2')
? TX_OUTPUT_SCRIPTHASH
: TX_OUTPUT_PUBKEYHASH)
)
}

Expand Down Expand Up @@ -89,7 +90,7 @@ export async function getTweakedPrivateKey() {
const network = await getNetwork()
const account = (await getCurrentAccount()) ?? raise('No current account')

const privateKey = deriveBtcPrivateKey(account.mnemonic, account.btc.path, network)
const privateKey = deriveBtcPrivateKey(encrypt(account.mnemonic), account.btc.path, network)
const xOnlyPublicKey = await getXOnlyPublicKey()
const tabTweaked = tapTweakHash(xOnlyPublicKey)

Expand Down
10 changes: 6 additions & 4 deletions src/lib/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const signTransaction = async (
{ txHex, scriptHex, inputIndex, satoshis, sigtype, path }: ToSignTransaction,
returnsTransaction: boolean = false
) => {
const mneObj = mvc.Mnemonic.fromString(account.mnemonic)
const mneObj = mvc.Mnemonic.fromString(encrypt(account.mnemonic))
const hdpk = mneObj.toHDPrivateKey('', network)
const rootPath = await getMvcRootPath()
// find out priv / pub according to path
Expand Down Expand Up @@ -136,7 +136,7 @@ export const signTransactions = async (
network: 'testnet' | 'mainnet',
toSignTransactions: ToSignTransaction[]
) => {
const mneObj = mvc.Mnemonic.fromString(account.mnemonic)
const mneObj = mvc.Mnemonic.fromString(encrypt(account.mnemonic))
const hdpk = mneObj.toHDPrivateKey('', network)
const rootPath = await getMvcRootPath()

Expand Down Expand Up @@ -502,10 +502,12 @@ function pickUtxo(utxos: SA_utxo[], amount: number) {
return candidateUtxos
}

const str = "metalet".split('').map(char => char.charCodeAt(0)).join('')

// 十六位十六进制数作为密钥
const SECRET_KEY = CryptoJS.enc.Utf8.parse("metalet.wallet");
const SECRET_KEY = CryptoJS.enc.Utf8.parse(str);
// 十六位十六进制数作为密钥偏移量
const SECRET_IV = CryptoJS.enc.Utf8.parse("metalet.wallet");
const SECRET_IV = CryptoJS.enc.Utf8.parse(str);

/**
* encrypt
Expand Down
9 changes: 4 additions & 5 deletions src/pages/migrate/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { setNetwork } from '@/lib/network'
import { deriveAllAddresses, type AddressType } from '@/lib/bip32-deriver'
import MetaletLogoImg from '@/assets/images/metalet-logo.png?url'
import { encrypt } from '@/lib/crypto'
const router = useRouter()
Expand All @@ -22,7 +23,7 @@ const importWallet = async () => {
// 比照查看有无该助记词的账号
const accounts = await getAccounts()
const accountsArr = Array.from(accounts.values())
const hasAccount = accountsArr.some((account) => account.mnemonic === mneStr)
const hasAccount = accountsArr.some((account) => account.mnemonic === encrypt(mneStr))
if (!hasAccount) {
// 迁移过程
Expand Down Expand Up @@ -111,10 +112,8 @@ const importWallet = async () => {

<div class="flex flex-col items-stretch pb-4">
<p class="mb-2 text-sm text-red-500" v-if="error">{{ error }}</p>
<button
class="gradient-bg rounded-md py-4 text-base font-bold leading-none tracking-wide text-blue-50"
@click="importWallet"
>
<button class="gradient-bg rounded-md py-4 text-base font-bold leading-none tracking-wide text-blue-50"
@click="importWallet">
OK
</button>
</div>
Expand Down
31 changes: 10 additions & 21 deletions src/pages/wallet/Backup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import passwordManager from '@/lib/password'
import { type Account, getCurrentAccount } from '@/lib/account'
import PasswordImg from '@/assets/images/password.svg?url'
import { decrypt } from '@/lib/crypto'
const router = useRouter()
Expand All @@ -22,7 +23,7 @@ const password = ref('')
const failed = ref(false)
const isCoveredMne = ref(true)
const mne = computed(() => account.value?.mnemonic)
const mne = computed(() => decrypt(account.value?.mnemonic))
// 按钮
const back = () => {
Expand Down Expand Up @@ -62,12 +63,8 @@ const next = async () => {
<div class="mt-12">
<h4 class="mb-2 text-sm">Password</h4>
<div class="relative">
<input
:type="passwordInputType"
class="w-full rounded-md border bg-gray-100 p-4 pr-12 text-sm text-gray-700"
:class="failed ? 'border-red-500' : 'border-transparent'"
v-model="password"
/>
<input :type="passwordInputType" class="w-full rounded-md border bg-gray-100 p-4 pr-12 text-sm text-gray-700"
:class="failed ? 'border-red-500' : 'border-transparent'" v-model="password" />
<div class="absolute right-0 top-0 flex h-full items-center pr-4">
<button class="" @click="isCovered = !isCovered">
<EyeIcon v-if="isCovered" class="h-5 w-5 text-gray-400 transition hover:text-blue-500" />
Expand Down Expand Up @@ -98,14 +95,10 @@ const next = async () => {
{{ mne }}
</div>

<div
class="absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-gray-100/30 backdrop-blur"
v-if="isCoveredMne"
>
<button
class="w- flex w-32 items-center justify-center gap-x-2 rounded-full border border-black py-2"
@click="isCoveredMne = false"
>
<div class="absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-gray-100/30 backdrop-blur"
v-if="isCoveredMne">
<button class="w- flex w-32 items-center justify-center gap-x-2 rounded-full border border-black py-2"
@click="isCoveredMne = false">
<EyeIcon class="h-5 w-5" />
<span>Show</span>
</button>
Expand All @@ -126,12 +119,8 @@ const next = async () => {
<!-- buttons -->
<div class="grid grid-cols-2 gap-x-2">
<button class="rounded-md border border-primary-blue py-4 text-base leading-none" @click="back">Back</button>
<button
class="gradient-bg rounded-md py-4 text-base leading-none text-white"
:class="!password && 'opacity-50 saturate-50'"
:disabled="!password"
@click="next"
>
<button class="gradient-bg rounded-md py-4 text-base leading-none text-white"
:class="!password && 'opacity-50 saturate-50'" :disabled="!password" @click="next">
Next
</button>
</div>
Expand Down
12 changes: 4 additions & 8 deletions src/pages/wallet/CheckBackup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { type Account, getCurrentAccount } from '@/lib/account'
import { encrypt } from '@/lib/crypto';
const router = useRouter()
Expand All @@ -22,7 +23,7 @@ const verify = async () => {
// 检查输入的助记词是否正确
const mnemonicStr = mnemonic.value
if (mnemonicStr !== account.value!.mnemonic) {
if (encrypt(mnemonicStr) !== account.value!.mnemonic) {
isValid.value = false
return
}
Expand All @@ -40,13 +41,8 @@ const verify = async () => {
Write down your seed phrase to make sure you have backed up your wallet.
</p>

<textarea
name=""
rows="5"
class="mt-8 w-full resize-none rounded-md border bg-gray-100 p-4"
:class="isValid ? 'border-transparent' : 'border-red-500'"
v-model="mnemonic"
></textarea>
<textarea name="" rows="5" class="mt-8 w-full resize-none rounded-md border bg-gray-100 p-4"
:class="isValid ? 'border-transparent' : 'border-red-500'" v-model="mnemonic"></textarea>
<p v-if="!isValid" class="mt-2 text-sm text-red-500">The seed phrase you entered is incorrect.</p>

<!-- buttons -->
Expand Down
103 changes: 34 additions & 69 deletions src/pages/wallet/Import.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import { ref, computed, Ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import passwordManager from '@/lib/password'
import {
RadioGroup,
RadioGroupOption,
Expand Down Expand Up @@ -99,8 +100,10 @@ const onSubmit = async () => {
await addAccount(account)
// 跳转到首页
router.push('/wallet')
// 查询有否设置密码
const hasPassword = await passwordManager.has()
const following = hasPassword ? '/wallet' : '/wallet/set-password'
router.push(following)
} catch (e) {
console.log(e)
error.value = 'Failed to import your wallet'
Expand Down Expand Up @@ -134,12 +137,10 @@ const onSubmit = async () => {
<RadioGroup v-model="selectedWordsLength">
<div class="flex items-center gap-x-2">
<RadioGroupOption v-slot="{ checked }" :value="length" v-for="length of wordsLengths" class="rounded">
<div
:class="[
checked ? 'bg-blue-100 text-blue-500' : 'text-gray-500',
'w-full cursor-pointer rounded-inherit px-2 py-0.5 text-center text-xs',
]"
>
<div :class="[
checked ? 'bg-blue-100 text-blue-500' : 'text-gray-500',
'w-full cursor-pointer rounded-inherit px-2 py-0.5 text-center text-xs',
]">
{{ `${length} words` }}
</div>
</RadioGroupOption>
Expand All @@ -149,15 +150,8 @@ const onSubmit = async () => {

<div class="grid grid-cols-3 gap-2">
<!-- input框 绑定粘贴事件 -->
<input
v-for="(word, index) in words"
:key="index"
type="text"
class="pit-input gradient-text font-bold"
:placeholder="(index + 1).toString()"
v-model="words[index]"
@paste.prevent="onPasteWords"
/>
<input v-for="(word, index) in words" :key="index" type="text" class="pit-input gradient-text font-bold"
:placeholder="(index + 1).toString()" v-model="words[index]" @paste.prevent="onPasteWords" />
</div>
</div>

Expand All @@ -169,14 +163,9 @@ const onSubmit = async () => {
<ChevronRightIcon :class="['h-4 w-4 text-gray-400 transition duration-200', open && 'rotate-90 transform']" />
</DisclosureButton>

<transition
enter-active-class="transition duration-100 ease-out"
enter-from-class="transform scale-95 opacity-0"
enter-to-class="transform scale-100 opacity-100"
leave-active-class="transition duration-75 ease-out"
leave-from-class="transform scale-100 opacity-100"
leave-to-class="transform scale-95 opacity-0"
>
<transition enter-active-class="transition duration-100 ease-out" enter-from-class="transform scale-95 opacity-0"
enter-to-class="transform scale-100 opacity-100" leave-active-class="transition duration-75 ease-out"
leave-from-class="transform scale-100 opacity-100" leave-to-class="transform scale-95 opacity-0">
<DisclosurePanel class="mt-1 space-y-2 rounded-lg bg-gray-100 p-4 text-sm text-gray-500 shadow-inner">
<h3 class="text-sm font-bold text-gray-900">What is a derivation path?</h3>
<p class="">
Expand All @@ -198,26 +187,18 @@ const onSubmit = async () => {
<span class="text-xs text-gray-500">BTC Path</span>

<SwitchGroup as="div" class="flex items-center mt-2">
<Switch
v-model="useSamePath"
class="group relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center rounded-full"
>
<Switch v-model="useSamePath"
class="group relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer items-center justify-center rounded-full">
<span class="sr-only">Use same path as MVC</span>
<span aria-hidden="true" class="pointer-events-none absolute h-full w-full rounded-md bg-white"></span>
<span
aria-hidden="true"
:class="[
useSamePath ? 'bg-btn-blue' : 'bg-gray-200',
'pointer-events-none absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out',
]"
></span>
<span
aria-hidden="true"
:class="[
useSamePath ? 'translate-x-5' : 'translate-x-0',
'pointer-events-none absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow ring-0 transition-transform duration-200 ease-in-out',
]"
></span>
<span aria-hidden="true" :class="[
useSamePath ? 'bg-btn-blue' : 'bg-gray-200',
'pointer-events-none absolute mx-auto h-4 w-9 rounded-full transition-colors duration-200 ease-in-out',
]"></span>
<span aria-hidden="true" :class="[
useSamePath ? 'translate-x-5' : 'translate-x-0',
'pointer-events-none absolute left-0 inline-block h-5 w-5 transform rounded-full border border-gray-200 bg-white shadow ring-0 transition-transform duration-200 ease-in-out',
]"></span>
</Switch>

<SwitchLabel as="span" class="ml-3 text-sm text-gray-500"> Use the same path as MVC </SwitchLabel>
Expand All @@ -226,35 +207,23 @@ const onSubmit = async () => {
<Listbox v-model="selectedScript" v-if="!useSamePath">
<div class="relative mt-4">
<ListboxButton
class="relative w-full cursor-default rounded-lg bg-[#f5f5f5] py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm"
>
class="relative w-full cursor-default rounded-lg bg-[#f5f5f5] py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm">
<span class="block truncate">{{ selectedScript.path }}</span>
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</ListboxButton>

<transition
leave-active-class="transition duration-100 ease-in"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<transition leave-active-class="transition duration-100 ease-in" leave-from-class="opacity-100"
leave-to-class="opacity-0">
<ListboxOptions
class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-[#f5f5f5] py-2 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
>
<ListboxOption
v-slot="{ selected }"
v-for="script in selectableScripts"
:key="script.name"
:value="script"
as="template"
>
class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-[#f5f5f5] py-2 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
<ListboxOption v-slot="{ selected }" v-for="script in selectableScripts" :key="script.name" :value="script"
as="template">
<li :class="['text-gray-900', 'relative cursor-pointer select-none py-1 pl-3 pr-4']">
<span :class="[selected ? 'font-medium' : 'font-normal', 'block truncate']">{{ script.path }}</span>
<span
v-if="selected"
class="absolute inset-y-2 right-2 flex h-5 w-5 items-center justify-center rounded-md bg-[#1E2BFF] text-white"
>
<span v-if="selected"
class="absolute inset-y-2 right-2 flex h-5 w-5 items-center justify-center rounded-md bg-[#1E2BFF] text-white">
<CheckIcon class="h-4 w-4" aria-hidden="true" />
</span>
</li>
Expand All @@ -267,12 +236,8 @@ const onSubmit = async () => {

<!-- ok -->
<div class="mt-32 flex items-center justify-center">
<button
class="main-btn-bg mt-8 grow rounded-md py-3 text-sm font-bold text-sky-50"
:class="[!finished && 'muted']"
:disabled="!finished"
@click="onSubmit"
>
<button class="main-btn-bg mt-8 grow rounded-md py-3 text-sm font-bold text-sky-50" :class="[!finished && 'muted']"
:disabled="!finished" @click="onSubmit">
OK
</button>
</div>
Expand Down
Loading

0 comments on commit 8b4a6b0

Please sign in to comment.