mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-26 09:46:15 -04:00
140 lines
4 KiB
Vue
140 lines
4 KiB
Vue
<template>
|
|
<div>
|
|
<n-card>
|
|
<n-grid cols="3" x-gap="12">
|
|
<n-gi span="1">
|
|
<n-form-item label="Language:">
|
|
<n-select
|
|
v-model:value="language"
|
|
:options="Object.keys(languages).map((label) => ({ label, value: label }))"
|
|
/>
|
|
</n-form-item>
|
|
</n-gi>
|
|
<n-gi span="2">
|
|
<n-form-item
|
|
label="Entropy (seed):"
|
|
:feedback="entropyValidation.message"
|
|
:validation-status="entropyValidation.status"
|
|
>
|
|
<n-input-group>
|
|
<n-input v-model:value="entropy" placeholder="Your string..." />
|
|
<n-button @click="refreshEntropy">
|
|
<n-icon size="22">
|
|
<Refresh />
|
|
</n-icon>
|
|
</n-button>
|
|
<n-button @click="copyEntropy">
|
|
<n-icon size="22">
|
|
<Copy />
|
|
</n-icon>
|
|
</n-button>
|
|
</n-input-group>
|
|
</n-form-item>
|
|
</n-gi>
|
|
</n-grid>
|
|
<n-form-item
|
|
label="Passphrase (mnemonic):"
|
|
:feedback="mnemonicValidation.message"
|
|
:validation-status="mnemonicValidation.status"
|
|
>
|
|
<n-input-group>
|
|
<n-input
|
|
v-model:value="passphrase"
|
|
style="text-align: center; flex: 1"
|
|
placeholder="Your mnemonic..."
|
|
autocomplete="off"
|
|
autocorrect="off"
|
|
autocapitalize="off"
|
|
spellcheck="false"
|
|
/>
|
|
|
|
<n-button @click="copyPassphrase">
|
|
<n-icon size="22" :component="Copy" />
|
|
</n-button>
|
|
</n-input-group>
|
|
</n-form-item>
|
|
</n-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useCopy } from '@/composable/copy';
|
|
import { useValidation } from '@/composable/validation';
|
|
import { isNotThrowing } from '@/utils/boolean';
|
|
import { withDefaultOnError } from '@/utils/defaults';
|
|
import {
|
|
chineseSimplifiedWordList,
|
|
chineseTraditionalWordList,
|
|
czechWordList,
|
|
englishWordList,
|
|
entropyToMnemonic,
|
|
frenchWordList,
|
|
generateEntropy,
|
|
italianWordList,
|
|
japaneseWordList,
|
|
koreanWordList,
|
|
mnemonicToEntropy,
|
|
portugueseWordList,
|
|
spanishWordList,
|
|
} from '@it-tools/bip39';
|
|
import { Copy, Refresh } from '@vicons/tabler';
|
|
import { computed, ref } from 'vue';
|
|
|
|
const languages = {
|
|
English: englishWordList,
|
|
'Chinese simplified': chineseSimplifiedWordList,
|
|
'Chinese traditional': chineseTraditionalWordList,
|
|
Czech: czechWordList,
|
|
French: frenchWordList,
|
|
Italian: italianWordList,
|
|
Japanese: japaneseWordList,
|
|
Korean: koreanWordList,
|
|
Portuguese: portugueseWordList,
|
|
Spanish: spanishWordList,
|
|
};
|
|
|
|
const entropy = ref(generateEntropy());
|
|
const passphraseInput = ref('');
|
|
|
|
const language = ref<keyof typeof languages>('English');
|
|
const passphrase = computed({
|
|
get() {
|
|
return withDefaultOnError(() => entropyToMnemonic(entropy.value, languages[language.value]), passphraseInput.value);
|
|
},
|
|
set(value: string) {
|
|
passphraseInput.value = value;
|
|
entropy.value = withDefaultOnError(() => mnemonicToEntropy(value, languages[language.value]), '');
|
|
},
|
|
});
|
|
|
|
const entropyValidation = useValidation({
|
|
source: entropy,
|
|
rules: [
|
|
{
|
|
validator: (value) => value === '' || (value.length <= 32 && value.length >= 16 && value.length % 4 === 0),
|
|
message: 'Entropy length should be >= 16, <= 32 and be a multiple of 4',
|
|
},
|
|
{
|
|
validator: (value) => /^[a-fA-F0-9]*$/.test(value),
|
|
message: 'Entropy should be an hexadecimal string',
|
|
},
|
|
],
|
|
});
|
|
|
|
const mnemonicValidation = useValidation({
|
|
source: passphrase,
|
|
rules: [
|
|
{
|
|
validator: (value) => isNotThrowing(() => mnemonicToEntropy(value, languages[language.value])),
|
|
message: 'Invalid mnemonic',
|
|
},
|
|
],
|
|
});
|
|
|
|
function refreshEntropy() {
|
|
entropy.value = generateEntropy();
|
|
}
|
|
|
|
const { copy: copyEntropy } = useCopy({ source: entropy, text: 'Entropy copied to the clipboard' });
|
|
const { copy: copyPassphrase } = useCopy({ source: passphrase, text: 'Passphrase copied to the clipboard' });
|
|
</script>
|