mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 15:20:55 +01:00
Merge branch 'master' into rtl
This commit is contained in:
commit
a876bb16dc
46 changed files with 1125 additions and 553 deletions
|
@ -7,7 +7,7 @@ minimum_perc = 30
|
|||
source_file = loc/en.json
|
||||
source_lang = en
|
||||
type = KEYVALUEJSON
|
||||
lang_map = af_ZA: zar_afr, bg_BG: bg_bg, ca: ca, cs_CZ: cs_cz, cy: cy, da_DK: da_dk, de_DE: de_de, el: el, es_ES: es, fa_IR: fa, fi_FI: fi_fi, fr_FR: fr_fr, hr_HR: hr_hr, hu_HU: hu_hu, id_ID: id_id, ja_JP: jp_jp, nb_NO: nb_no, nl_NL: nl_nl, pt_BR: pt_br, pt_PT: pt_pt, sk_SK: sk_sk, sv_SE: sv_se, th_TH: th_th, tr_TR: tr_tr, uk_UA: ua, vi_VN: vi_vn, xh: zar_xho, zh_CN: zh_cn, zh_TW: zh_tw
|
||||
lang_map = af_ZA: zar_afr, bg_BG: bg_bg, ca: ca, cs_CZ: cs_cz, cy: cy, da_DK: da_dk, de_DE: de_de, el: el, es_ES: es, fa_IR: fa, fi_FI: fi_fi, fr_FR: fr_fr, hr_HR: hr_hr, hu_HU: hu_hu, id_ID: id_id, ja_JP: jp_jp, nb_NO: nb_no, nl_NL: nl_nl, pt_BR: pt_br, pt_PT: pt_pt, ro: ro, sk_SK: sk_sk, sv_SE: sv_se, th_TH: th_th, tr_TR: tr_tr, uk_UA: ua, vi_VN: vi_vn, xh: zar_xho, zh_CN: zh_cn, zh_TW: zh_tw
|
||||
|
||||
[bluewallet-fastlane.ios-fastlane-metadata-en-us-description-txt--master]
|
||||
file_filter = ios/fastlane/metadata/<lang>/description.txt
|
||||
|
|
2
App.js
2
App.js
|
@ -12,6 +12,7 @@ import {
|
|||
UIManager,
|
||||
useColorScheme,
|
||||
View,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import { NavigationContainer, CommonActions } from '@react-navigation/native';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
|
@ -336,6 +337,7 @@ const App = () => {
|
|||
return (
|
||||
<SafeAreaProvider>
|
||||
<View style={styles.root}>
|
||||
<StatusBar barStyle={colorScheme === 'dark' ? 'light-content' : 'dark-content'} backgroundColor="transparent" translucent />
|
||||
<NavigationContainer ref={navigationRef} theme={colorScheme === 'dark' ? BlueDarkTheme : BlueDefaultTheme}>
|
||||
<InitRoot />
|
||||
<Notifications onProcessNotifications={processPushNotifications} />
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
InteractionManager,
|
||||
} from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
@ -223,8 +224,8 @@ export class BlueWalletNavigationHeader extends Component {
|
|||
onWalletUnitChange: PropTypes.func,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(props, state) {
|
||||
return { wallet: props.wallet, onWalletUnitChange: props.onWalletUnitChange, allowOnchainAddress: state.allowOnchainAddress };
|
||||
static getDerivedStateFromProps(props) {
|
||||
return { wallet: props.wallet, onWalletUnitChange: props.onWalletUnitChange };
|
||||
}
|
||||
|
||||
static contextType = BlueStorageContext;
|
||||
|
@ -235,7 +236,7 @@ export class BlueWalletNavigationHeader extends Component {
|
|||
this.state = {
|
||||
wallet: props.wallet,
|
||||
walletPreviousPreferredUnit: props.wallet.getPreferredBalanceUnit(),
|
||||
showManageFundsButton: false,
|
||||
allowOnchainAddress: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -243,13 +244,28 @@ export class BlueWalletNavigationHeader extends Component {
|
|||
Clipboard.setString(formatBalance(this.state.wallet.getBalance(), this.state.wallet.getPreferredBalanceUnit()).toString());
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
componentDidUpdate(prevState) {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
if (prevState.wallet.getID() !== this.state.wallet.getID() && this.state.wallet.type === LightningCustodianWallet.type) {
|
||||
this.verifyIfWalletAllowsOnchainAddress();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
verifyIfWalletAllowsOnchainAddress = () => {
|
||||
if (this.state.wallet.type === LightningCustodianWallet.type) {
|
||||
this.state.wallet
|
||||
.allowOnchainAddress()
|
||||
.then(value => this.setState({ allowOnchainAddress: value }))
|
||||
.catch(e => console.log('This Lndhub wallet does not have an onchain address API.'));
|
||||
.catch(e => {
|
||||
console.log('This Lndhub wallet does not have an onchain address API.');
|
||||
this.setState({ allowOnchainAddress: false });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.verifyIfWalletAllowsOnchainAddress();
|
||||
}
|
||||
|
||||
handleBalanceVisibility = async _item => {
|
||||
|
@ -589,6 +605,7 @@ export const BlueTextCentered = props => {
|
|||
|
||||
export const BlueListItem = React.memo(props => {
|
||||
const { colors } = useTheme();
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
containerStyle={props.containerStyle ?? { backgroundColor: 'transparent' }}
|
||||
|
@ -599,6 +616,7 @@ export const BlueListItem = React.memo(props => {
|
|||
onPress={props.onPress}
|
||||
onLongPress={props.onLongPress}
|
||||
disabled={props.disabled}
|
||||
accessible={props.switch === undefined}
|
||||
>
|
||||
{props.leftAvatar && <Avatar>{props.leftAvatar}</Avatar>}
|
||||
{props.leftIcon && <Avatar icon={props.leftIcon} />}
|
||||
|
@ -610,12 +628,14 @@ export const BlueListItem = React.memo(props => {
|
|||
fontWeight: '500',
|
||||
}}
|
||||
numberOfLines={0}
|
||||
accessible={props.switch === undefined}
|
||||
>
|
||||
{props.title}
|
||||
</ListItem.Title>
|
||||
{props.subtitle && (
|
||||
<ListItem.Subtitle
|
||||
numberOfLines={props.subtitleNumberOfLines ?? 1}
|
||||
accessible={props.switch === undefined}
|
||||
style={{ flexWrap: 'wrap', color: colors.alternativeTextColor, fontWeight: '400', fontSize: 14 }}
|
||||
>
|
||||
{props.subtitle}
|
||||
|
@ -635,7 +655,7 @@ export const BlueListItem = React.memo(props => {
|
|||
<>
|
||||
{props.chevron && <ListItem.Chevron />}
|
||||
{props.rightIcon && <Avatar icon={props.rightIcon} />}
|
||||
{props.switch && <Switch {...props.switch} />}
|
||||
{props.switch && <Switch {...props.switch} accessibilityLabel={props.title} accessible accessibilityRole="switch" />}
|
||||
{props.checkmark && <ListItem.CheckBox iconType="octaicon" checkedColor="#0070FF" checkedIcon="check" checked />}
|
||||
</>
|
||||
)}
|
||||
|
@ -1508,7 +1528,7 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
|
|||
actions.push(
|
||||
{
|
||||
id: 'copyTX_ID',
|
||||
text: loc.transactions.transaction_id,
|
||||
text: loc.transactions.txid,
|
||||
onPress: handleOnCopyTransactionID,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -116,7 +116,7 @@ const WalletsRoot = () => {
|
|||
|
||||
return (
|
||||
<WalletsStack.Navigator {...(Platform.OS === 'android' ? { screenOptions: defaultScreenOptions } : null)}>
|
||||
<WalletsStack.Screen name="WalletsList" component={WalletsList} />
|
||||
<WalletsStack.Screen name="WalletsList" component={WalletsList} options={WalletsList.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="WalletTransactions" component={WalletTransactions} options={WalletTransactions.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="WalletDetails" component={WalletDetails} options={WalletDetails.navigationOptions(theme)} />
|
||||
<WalletsStack.Screen name="TransactionDetails" component={TransactionDetails} options={TransactionDetails.navigationOptions(theme)} />
|
||||
|
|
|
@ -14,17 +14,17 @@ import { HDAezeedWallet } from "./wallets/hd-aezeed-wallet";
|
|||
import { useTheme } from '@react-navigation/native';
|
||||
|
||||
export default class WalletGradient {
|
||||
static hdSegwitP2SHWallet = ['#65ceef', '#68bbe1'];
|
||||
static hdSegwitBech32Wallet = ['#68bbe1', '#3b73d4'];
|
||||
static segwitBech32Wallet = ['#f8bbe1', '#945a90'];
|
||||
static watchOnlyWallet = ['#7d7d7d', '#4a4a4a'];
|
||||
static legacyWallet = ['#40fad1', '#15be98'];
|
||||
static hdLegacyP2PKHWallet = ['#e36dfa', '#bd10e0'];
|
||||
static hdSegwitP2SHWallet = ['#007AFF', '#0040FF'];
|
||||
static hdSegwitBech32Wallet = ['#6CD9FC', '#44BEE5'];
|
||||
static segwitBech32Wallet = ['#6CD9FC', '#44BEE5'];
|
||||
static watchOnlyWallet = ['#474646', '#282828'];
|
||||
static legacyWallet = ['#37E8C0', '#15BE98'];
|
||||
static hdLegacyP2PKHWallet = ['#FD7478', '#E73B40'];
|
||||
static hdLegacyBreadWallet = ['#fe6381', '#f99c42'];
|
||||
static multisigHdWallet = ['#1ce6eb', '#296fc5', '#3500A2'];
|
||||
static defaultGradients = ['#c65afb', '#9053fe'];
|
||||
static lightningCustodianWallet = ['#f1be07', '#f79056'];
|
||||
static aezeedWallet = ['#550271', '#530140'];
|
||||
static defaultGradients = ['#B770F6', '#9013FE'];
|
||||
static lightningCustodianWallet = ['#F1AA07', '#FD7E37'];
|
||||
static aezeedWallet = ['#8584FF', '#5351FB'];
|
||||
|
||||
static createWallet = () => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import bip39 from 'bip39';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import b58 from 'bs58check';
|
||||
|
||||
import { randomBytes } from '../rng';
|
||||
import { AbstractHDWallet } from './abstract-hd-wallet';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
|
@ -818,6 +819,22 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds WIF corresponding to address and returns it
|
||||
*
|
||||
* @param address {string} Address that belongs to this wallet
|
||||
* @returns {string|false} WIF or false
|
||||
*/
|
||||
_getWIFbyAddress(address) {
|
||||
for (let c = 0; c < this.next_free_address_index + this.gap_limit; c++) {
|
||||
if (this._getExternalAddressByIndex(c) === address) return this._getWIFByIndex(false, c);
|
||||
}
|
||||
for (let c = 0; c < this.next_free_change_address_index + this.gap_limit; c++) {
|
||||
if (this._getInternalAddressByIndex(c) === address) return this._getWIFByIndex(true, c);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
weOwnAddress(address) {
|
||||
for (let c = 0; c < this.next_free_address_index + this.gap_limit; c++) {
|
||||
if (this._getExternalAddressByIndex(c) === address) return true;
|
||||
|
|
|
@ -19,6 +19,7 @@ export class AbstractWallet {
|
|||
constructor() {
|
||||
this.type = this.constructor.type;
|
||||
this.typeReadable = this.constructor.typeReadable;
|
||||
this.segwitType = this.constructor.segwitType;
|
||||
this.label = '';
|
||||
this.secret = ''; // private key or recovery phrase
|
||||
this.balance = 0;
|
||||
|
@ -123,6 +124,10 @@ export class AbstractWallet {
|
|||
return false;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
weOwnAddress(address) {
|
||||
throw Error('not implemented');
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ const { CipherSeed } = require('aezeed');
|
|||
export class HDAezeedWallet extends AbstractHDElectrumWallet {
|
||||
static type = 'HDAezeedWallet';
|
||||
static typeReadable = 'HD Aezeed';
|
||||
static segwitType = 'p2wpkh';
|
||||
|
||||
setSecret(newSecret) {
|
||||
this.secret = newSecret.trim();
|
||||
|
@ -160,4 +161,8 @@ export class HDAezeedWallet extends AbstractHDElectrumWallet {
|
|||
allowPayJoin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ export class HDLegacyP2PKHWallet extends AbstractHDElectrumWallet {
|
|||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getXpub() {
|
||||
if (this._xpub) {
|
||||
return this._xpub; // cache hit
|
||||
|
|
|
@ -8,6 +8,7 @@ import { AbstractHDElectrumWallet } from './abstract-hd-electrum-wallet';
|
|||
export class HDSegwitBech32Wallet extends AbstractHDElectrumWallet {
|
||||
static type = 'HDsegwitBech32';
|
||||
static typeReadable = 'HD SegWit (BIP84 Bech32 Native)';
|
||||
static segwitType = 'p2wpkh';
|
||||
|
||||
allowSend() {
|
||||
return true;
|
||||
|
@ -36,4 +37,8 @@ export class HDSegwitBech32Wallet extends AbstractHDElectrumWallet {
|
|||
allowCosignPsbt() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ const HDNode = require('bip32');
|
|||
export class HDSegwitP2SHWallet extends AbstractHDElectrumWallet {
|
||||
static type = 'HDsegwitP2SH';
|
||||
static typeReadable = 'HD SegWit (BIP49 P2SH)';
|
||||
static segwitType = 'p2sh(p2wpkh)';
|
||||
|
||||
allowSend() {
|
||||
return true;
|
||||
|
@ -25,6 +26,10 @@ export class HDSegwitP2SHWallet extends AbstractHDElectrumWallet {
|
|||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get internal/external WIF by wallet index
|
||||
* @param {Boolean} internal
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
import bitcoinMessage from 'bitcoinjs-message';
|
||||
import { randomBytes } from '../rng';
|
||||
import { AbstractWallet } from './abstract-wallet';
|
||||
import { HDSegwitBech32Wallet } from '..';
|
||||
import BigNumber from 'bignumber.js';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const BlueElectrum = require('../../blue_modules/BlueElectrum');
|
||||
const coinSelectAccumulative = require('coinselect/accumulative');
|
||||
|
@ -479,6 +480,10 @@ export class LegacyWallet extends AbstractWallet {
|
|||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if address is a Change address. Needed for Coin control.
|
||||
* Useless for Legacy wallets, so it is always false
|
||||
|
@ -489,4 +494,44 @@ export class LegacyWallet extends AbstractWallet {
|
|||
addressIsChange(address) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds WIF corresponding to address and returns it
|
||||
*
|
||||
* @param address {string} Address that belongs to this wallet
|
||||
* @returns {string|false} WIF or false
|
||||
*/
|
||||
_getWIFbyAddress(address) {
|
||||
return this.getAddress() === address ? this.secret : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signes text message using address private key and returs signature
|
||||
*
|
||||
* @param message {string}
|
||||
* @param address {string}
|
||||
* @returns {string} base64 encoded signature
|
||||
*/
|
||||
signMessage(message, address) {
|
||||
const wif = this._getWIFbyAddress(address);
|
||||
if (wif === null) throw new Error('Invalid address');
|
||||
const keyPair = bitcoin.ECPair.fromWIF(wif);
|
||||
const privateKey = keyPair.privateKey;
|
||||
const options = this.segwitType ? { segwitType: this.segwitType } : undefined;
|
||||
const signature = bitcoinMessage.sign(message, privateKey, keyPair.compressed, options);
|
||||
return signature.toString('base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies text message signature by address
|
||||
*
|
||||
* @param message {string}
|
||||
* @param address {string}
|
||||
* @param signature {string}
|
||||
* @returns {boolean} base64 encoded signature
|
||||
*/
|
||||
verifyMessage(message, address, signature) {
|
||||
// null, true so it can verify Electrum signatores without errors
|
||||
return bitcoinMessage.verify(message, address, signature, null, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ const bitcoin = require('bitcoinjs-lib');
|
|||
export class SegwitBech32Wallet extends LegacyWallet {
|
||||
static type = 'segwitBech32';
|
||||
static typeReadable = 'P2 WPKH';
|
||||
static segwitType = 'p2wpkh';
|
||||
|
||||
getAddress() {
|
||||
if (this._address) return this._address;
|
||||
|
@ -132,4 +133,8 @@ export class SegwitBech32Wallet extends LegacyWallet {
|
|||
allowSendMax() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ function pubkeyToP2shSegwitAddress(pubkey, network) {
|
|||
export class SegwitP2SHWallet extends LegacyWallet {
|
||||
static type = 'segwitP2SH';
|
||||
static typeReadable = 'SegWit (P2SH)';
|
||||
static segwitType = 'p2sh(p2wpkh)';
|
||||
|
||||
static witnessToAddress(witness) {
|
||||
try {
|
||||
|
@ -141,4 +142,8 @@ export class SegwitP2SHWallet extends LegacyWallet {
|
|||
allowSendMax() {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSignVerifyMessage() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,9 @@ const BottomModal = ({ onBackButtonPress, onBackdropPress, onClose, windowHeight
|
|||
onBackButtonPress={handleBackButtonPress}
|
||||
onBackdropPress={handleBackdropPress}
|
||||
{...props}
|
||||
accessibilityViewIsModal
|
||||
useNativeDriver
|
||||
useNativeDriverForBackdrop
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ const iStyles = StyleSheet.create({
|
|||
},
|
||||
grad: {
|
||||
padding: 15,
|
||||
borderRadius: 10,
|
||||
borderRadius: 12,
|
||||
minHeight: 164,
|
||||
elevation: 5,
|
||||
},
|
||||
|
@ -217,9 +217,9 @@ const WalletCarouselItem = ({ item, index, onPress, handleLongPress, isSelectedW
|
|||
return (
|
||||
<Animated.View
|
||||
style={[iStyles.root, { opacity, transform: [{ scale: scaleValue }] }]}
|
||||
shadowOpacity={40 / 100}
|
||||
shadowOffset={{ width: 0, height: 0 }}
|
||||
shadowRadius={5}
|
||||
shadowOpacity={25 / 100}
|
||||
shadowOffset={{ width: 0, height: 3 }}
|
||||
shadowRadius={8}
|
||||
>
|
||||
<TouchableWithoutFeedback
|
||||
testID={item.getLabel()}
|
||||
|
@ -278,7 +278,7 @@ const cStyles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
content: {
|
||||
left: 20,
|
||||
left: 16,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 9 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 9.3 KiB |
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="16097.2" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
|
||||
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="17701" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
|
||||
<device id="watch44"/>
|
||||
<dependencies>
|
||||
<deployment identifier="watchOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="16012"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="17500"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--BlueWallet-->
|
||||
|
@ -203,9 +203,9 @@
|
|||
<!--ViewQRCodefaceController-->
|
||||
<scene sceneID="jZ8-sK-IyQ">
|
||||
<objects>
|
||||
<controller identifier="ViewQRCodefaceController" fullBounds="YES" fullScreen="YES" id="ON9-Qg-65y" customClass="ViewQRCodefaceController" customModule="BlueWalletWatch_Extension">
|
||||
<controller identifier="ViewQRCodefaceController" fullBounds="YES" id="ON9-Qg-65y" customClass="ViewQRCodefaceController" customModule="BlueWalletWatch_Extension">
|
||||
<items>
|
||||
<imageView height="0.90000000000000002" alignment="left" image="textfor" id="cp4-B3-gV6"/>
|
||||
<imageView width="1" height="1" heightAdjustment="-5" alignment="left" image="textfor" animationDuration="1" id="cp4-B3-gV6"/>
|
||||
<label width="1" height="1" alignment="center" verticalAlignment="center" hidden="YES" text="Label" numberOfLines="0" minimumScaleFactor="0.5" id="JMO-XZ-1si"/>
|
||||
<table alignment="left" id="2TT-ef-7YA"/>
|
||||
</items>
|
||||
|
|
38
loc/ca.json
38
loc/ca.json
|
@ -16,7 +16,9 @@
|
|||
"seed": "Llavor",
|
||||
"wallet_key": "Clau del moneder",
|
||||
"invalid_animated_qr_code_fragment": "Fragment QRCode animat no vàlid. Siusplau torna-ho a provar.",
|
||||
"file_saved": "El fitxer ({filePath}) s'ha desat a la carpeta de descàrregues."
|
||||
"file_saved": "El fitxer ({filePath}) s'ha desat a la carpeta de descàrregues.",
|
||||
"discard_changes": "Descartar els canvis?",
|
||||
"discard_changes_detail": "Teniu canvis sense desar. Esteu segur que voleu descartar-los i sortir de la pantalla?"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "El codi del teu val és",
|
||||
|
@ -71,7 +73,9 @@
|
|||
"item_nooffers": "Sense ofertes. Proveu de canviar \" A prop meu\" per ofertes globals",
|
||||
"item_rating": "{rating} operacions",
|
||||
"item_rating_no": "Sense qualificació",
|
||||
"local_trader_new": "Nou",
|
||||
"login": "Iniciar sessió",
|
||||
"logout": "Sortir",
|
||||
"mycont": "Els meus contractes",
|
||||
"offer_accept": "Accepta l'oferta",
|
||||
"offer_account_finish": "Sembla que no heu acabat de configurar el compte a HodlHodl. Voleu acabar de configurar-lo ara?",
|
||||
|
@ -95,6 +99,7 @@
|
|||
"potentialFee": "Comissió potencial: {fee}",
|
||||
"refill": "Recarregar",
|
||||
"refill_card": "Recarrega amb tarjeta bancaria",
|
||||
"refill_external": "Recarregar amb un moneder extern",
|
||||
"refill_lnd_balance": "Recarregar el balanç del moneder Lightning",
|
||||
"sameWalletAsInvoiceError": "No pots pagar una factura amb el mateix moneder que l'ha creat.",
|
||||
"title": "gestionar fons"
|
||||
|
@ -102,6 +107,7 @@
|
|||
"lndViewInvoice": {
|
||||
"additional_info": "Informació addicional",
|
||||
"for": "Per:",
|
||||
"lightning_invoice": "Factura Lightning",
|
||||
"has_been_paid": "Aquesta factura ha estat pagada",
|
||||
"open_direct_channel": "Obrir un canal directe amb aquest node:",
|
||||
"please_pay": "Si us plau, pagui",
|
||||
|
@ -121,11 +127,14 @@
|
|||
"title": "Negació plausible"
|
||||
},
|
||||
"pleasebackup": {
|
||||
"ask": "Heu desat la frase de recuperació del vostre moneder? Aquesta frase de recuperació és necessària per accedir als vostres fons en cas que perdeu aquest dispositiu. Sense la frase de recuperació, els vostres fons es perdran permanentment.",
|
||||
"ask_no": "No, no en tinc",
|
||||
"ask_yes": "Si, en tinc",
|
||||
"ok": "OK, ja he assegurat una còpia en paper!",
|
||||
"ok_lnd": "D'acord, l'he guardat",
|
||||
"text": "Si us plau, apunteu en un paper el mnemotècnic. Aquesta 'frase' et permetrà regenerar el teu moneder en altres dispositius.",
|
||||
"text": "Si us plau, preneu-vos un moment per escriure aquesta frase mnemotècnica en un tros de paper. És la vostra còpia de seguretat que podeu utilitzar per restaurar el moneder en un altre dispositiu.",
|
||||
"text_lnd": "Si us plau, deseu aquesta còpia de seguretat del moneder. Permet restaurar el moneder en cas de pèrdua.",
|
||||
"text_lnd2": "Aquest moneder està allotjat a BlueWallet.",
|
||||
"title": "El teu moneder ha estat creat..."
|
||||
},
|
||||
"receive": {
|
||||
|
@ -161,14 +170,18 @@
|
|||
"details_adv_fee_bump": "Permeteu ampliar la comissió",
|
||||
"details_adv_full": "Utilitzeu tot el saldo",
|
||||
"details_adv_full_remove": "Els altres destinataris s'eliminaran d'aquesta transacció.",
|
||||
"details_adv_full_sure": "Esteu segur que voleu utilitzar el saldo complet del moneder per a aquesta transacció?",
|
||||
"details_adv_import": "Importar transacció",
|
||||
"details_amount_field_is_not_valid": "Quantitat invalida",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "La quantitat especificada és massa petita. Introduïu una quantitat superior a 500 sats.",
|
||||
"details_create": "Crear",
|
||||
"details_fee_field_is_not_valid": "Comissió invalida",
|
||||
"details_next": "Següent",
|
||||
"details_note_placeholder": "comentari (útil per tu)",
|
||||
"details_scan": "Escanejar",
|
||||
"details_total_exceeds_balance": "La quantitat excedeix el balanç disponible.",
|
||||
"details_unrecognized_file_format": "Format de fitxer no reconegut",
|
||||
"details_wallet_before_tx": "Abans de crear una transacció, primer heu d’afegir un moneder Bitcoin.",
|
||||
"details_wallet_selection": "Seleccionar moneder",
|
||||
"dynamic_init": "Inicialitzant",
|
||||
"dynamic_next": "Següent",
|
||||
|
@ -181,6 +194,7 @@
|
|||
"fee_custom": "Personalitzada",
|
||||
"fee_fast": "Ràpid",
|
||||
"fee_medium": "Mitjà",
|
||||
"fee_replace_min": "La taxa total (satoshi per byte) que voleu pagar ha de ser més gran que {min} sat/ byte.",
|
||||
"fee_satbyte": "en sat/byte",
|
||||
"fee_slow": "Lent",
|
||||
"header": "enviar",
|
||||
|
@ -190,9 +204,13 @@
|
|||
"input_total": "Total:",
|
||||
"permission_camera_message": "Necessitem el vostre permís per usar la vostra càmera.",
|
||||
"permission_camera_title": "Permís per usar la càmera",
|
||||
"psbt_sign": "Signar una transacció",
|
||||
"open_settings": "Obre configuració",
|
||||
"permission_storage_later": "Pregunta'm després",
|
||||
"permission_storage_message": "BlueWallet necessita el vostre permís per accedir al vostre emmagatzematge per desar aquest fitxer.",
|
||||
"permission_storage_denied_message": "BlueWallet no pot desar aquest fitxer. Obriu la configuració del dispositiu i activeu el permís d'emmagatzematge.",
|
||||
"permission_storage_title": "Permís d'accés a emmagatzematge",
|
||||
"psbt_clipboard": "Copiar al portapapers",
|
||||
"psbt_tx_export": "Exportar a arxiu",
|
||||
"success_done": "Fet",
|
||||
"problem_with_psbt": "Problema amb PSBT"
|
||||
|
@ -200,22 +218,32 @@
|
|||
"settings": {
|
||||
"about": "Sobre nosaltres",
|
||||
"about_backup": "Feu sempre còpies de seguretat de les vostres claus!",
|
||||
"about_license": "Llicència MIT",
|
||||
"about_review": "Deixa'ns una ressenya",
|
||||
"about_selftest": "Executa l'autotest",
|
||||
"about_sm_github": "GitHub",
|
||||
"about_sm_discord": "Servidor Discord",
|
||||
"about_sm_telegram": "Canal de Telegram",
|
||||
"about_sm_twitter": "Segueix-nos a Twitter",
|
||||
"advanced_options": "Configuracions avançades",
|
||||
"biometrics": "Biometria",
|
||||
"biom_conf_identity": "Si us plau, confirmeu la vostra identitat.",
|
||||
"currency": "Moneda",
|
||||
"currency_source": "Els preus s’obtenen de",
|
||||
"default_info": "Informació predeterminada",
|
||||
"default_wallets": "Veure tots els moneders",
|
||||
"electrum_connected": "Conectat",
|
||||
"electrum_connected_not": "No conectat",
|
||||
"electrum_port": "TCP port, generalment {example}",
|
||||
"electrum_port_ssl": "SSL port, generalment {example}",
|
||||
"electrum_settings": "Configuració d'Electrum",
|
||||
"electrum_settings_explain": "Deixa-ho buit per usar el valor per defecte",
|
||||
"electrum_status": "estat",
|
||||
"electrum_clear_alert_title": "Netejar l'historial?",
|
||||
"electrum_clear_alert_cancel": "Cancel·lar",
|
||||
"electrum_clear_alert_ok": "D'acord",
|
||||
"electrum_select": "selecciona",
|
||||
"electrum_reset": "Restableix la configuració predeterminada",
|
||||
"electrum_clear": "Neteja",
|
||||
"encrypt_del_uninstall": "Esborrar si BlueWallet es desinstala",
|
||||
"encrypt_title": "Seguretat",
|
||||
"general": "General",
|
||||
|
@ -235,6 +263,7 @@
|
|||
"passwords_do_not_match": "La contrasenya no coincideix",
|
||||
"plausible_deniability": "Negació plausible...",
|
||||
"privacy": "Privacitat",
|
||||
"privacy_read_clipboard": "Llegir el portapapers",
|
||||
"retype_password": "Introdueix de nou la contrasenya contrasenya",
|
||||
"save": "guardar",
|
||||
"saved": "Desat"
|
||||
|
@ -245,6 +274,7 @@
|
|||
"transactions": {
|
||||
"cancel_title": "Cancel·lar aquesta transacció (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} confirmacions",
|
||||
"note": "Nota",
|
||||
"cpfp_create": "Crear",
|
||||
"details_balance_hide": "Amaga el saldo",
|
||||
"details_balance_show": "Mostra el saldo",
|
||||
|
@ -293,7 +323,6 @@
|
|||
"export_title": "Exportació de moneder",
|
||||
"import_do_import": "Importar",
|
||||
"import_error": "No s'ha pogut importar. ¿És vàlid?",
|
||||
"import_explanation": "Escrigui aquí el mnemotècnic, clau privada, WIF, o quelcom que tingui. BlueWallet fara tot el posible per encertar el formato correcte e importar el moneder.",
|
||||
"import_file": "Importar arxiu",
|
||||
"import_imported": "Importat",
|
||||
"import_scan_qr": "o escanejar codi QR?",
|
||||
|
@ -303,7 +332,6 @@
|
|||
"list_create_a_wallet": "Afegeix un moneder",
|
||||
"list_empty_txs1": "Les seves transaccions apareixeran aquí,",
|
||||
"list_empty_txs1_lightning": "Els moneders Lightning poden ser usats per les seves transaccions diàries. Les comissions són baixes i els pagaments ràpids.",
|
||||
"list_empty_txs2": "encara no té cap transacció.",
|
||||
"list_latest_transaction": "última transacció",
|
||||
"list_long_choose": "Tria la foto",
|
||||
"list_long_scan": "Escaneja el codi QR",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"never": "nie",
|
||||
"of": "{number} von {total}",
|
||||
"ok": "OK",
|
||||
"storage_is_encrypted": "Dein Speicher ist verschlüsselt. Zum Entschlüsseln wird ein Passwort benötigt.",
|
||||
"storage_is_encrypted": "Zum Entschlüsseln des Speichers das Passwort eingeben.",
|
||||
"allow": "Zulassen",
|
||||
"dont_allow": "Ablehnen",
|
||||
"yes": "Ja",
|
||||
|
@ -101,9 +101,9 @@
|
|||
"placeholder": "Rechnung",
|
||||
"potentialFee": "Geschätzte Gebühr: {fee}",
|
||||
"refill": "Aufladen",
|
||||
"refill_card": "Aufladen mit Zahlkarte",
|
||||
"refill_card": "Mit Zahlkarte aufladen",
|
||||
"refill_create": "Bitte eine Bitcoin Wallet erstellen um fortzufahren",
|
||||
"refill_external": "Aufladen von einer anderen Wallet",
|
||||
"refill_external": "Mit externem Wallet aufladen",
|
||||
"refill_lnd_balance": "Lade deine Lightning Wallet auf",
|
||||
"sameWalletAsInvoiceError": "Du kannst nicht die Rechnung mit der Wallet begleichen, die du für die Erstellung dieser Rechnung verwendet hast.",
|
||||
"title": "Beträge verwalten"
|
||||
|
@ -274,7 +274,7 @@
|
|||
"electrum_clear_alert_cancel": "Abbrechen",
|
||||
"electrum_clear_alert_ok": "Ok",
|
||||
"electrum_select": "Auswählen",
|
||||
"electrum_reset": "Auf Standard zurücksetzen",
|
||||
"electrum_reset": "Zurücksetzten",
|
||||
"electrum_unable_to_connect": "Verbindung zu {Server} kann nicht hergestellt werden.",
|
||||
"electrum_history": "Serverhistorie",
|
||||
"electrum_reset_to_default": "Sollen die Electrum-Einstellungen wirklich auf die Standardwerte zurückgesetzt werden?",
|
||||
|
@ -291,7 +291,7 @@
|
|||
"general_adv_mode": "Erweiterter Modus",
|
||||
"general_adv_mode_e": "Erlaubt, wenn aktiviert, verschiedene Wallet-Typen anzulegen, dabei eine benutzerdefinierte Entropie zu verwenden und die LNDHub-Instanz der Lightning Wallet frei zu definieren.",
|
||||
"general_continuity": "Kontinuität",
|
||||
"general_continuity_e": "Zeigt, wenn aktiviert, ausgewählte Wallets und deren Transaktionen auf Deinen anderen Apple iCloud Geräten an. ",
|
||||
"general_continuity_e": "Wenn aktiviert werden ausgewählte Wallets und deren Transaktionen auf deinen anderen Apple iCloud Geräten angezeigt.",
|
||||
"groundcontrol_explanation": "GroundControl ist ein kostenloser Open-Source Push-Benachrichtigungsdienst für Bitcoin-Wallets. Trage hier die URL eines selbst aufgesetzten GroundControl-Servers ein, um von BlueWallet unabhängig zu bleiben. Leer lassen, um die Standardeinstellung zu verwenden.",
|
||||
"header": "Einstellungen",
|
||||
"language": "Sprache",
|
||||
|
@ -299,7 +299,7 @@
|
|||
"lightning_error_lndhub_uri": "Keine gültige LndHub URI",
|
||||
"lightning_saved": "Deine Änderungen wurden gespeichert.",
|
||||
"lightning_settings": "Lightning-Einstellungen",
|
||||
"lightning_settings_explain": "Um Dich mit deinem eigenen LND-Knoten zu verbinden bitte LNDHub installieren und die entsprechende URL hier in den Einstellungen eintragen. Feld leer lassen, um BlueWallet's LNDHub (lndhub.io) zu verwenden. Nach dem Speichern werden sich neu erstellte Wallets mit dem angegebenen LNDHub verbinden.",
|
||||
"lightning_settings_explain": "Zur Verbindung mit einem eigenen LND-Knoten ein LNDHub installieren und dessen URL hier eingeben. Das Feld leer lassen, um den LNDHub (lndhub.io) von BlueWallet zur verwenden. Nach dem Speichern werden sich neu erstellte Wallets mit dem angegebenen LNDHub verbinden.",
|
||||
"network": "Netzwerk",
|
||||
"network_broadcast": "Transaktion publizieren",
|
||||
"network_electrum": "Electrum Server",
|
||||
|
@ -316,9 +316,10 @@
|
|||
"privacy_system_settings": "Systemeinstellungen",
|
||||
"privacy_quickactions": "Walletverknüpfungen",
|
||||
"privacy_quickactions_explanation": "Halte auf dem Startbildschirm das BlueWallet App-Symbol gedrückt, um rasch deinen Saldo zu sehen.",
|
||||
"privacy_clipboard_explanation": "Stellt vorhandene Verknüpfungen der Zwischenablage für Rechnungen und Adressen bereit.",
|
||||
"privacy_clipboard_explanation": "Nutzt Rechnungen und Adressen in der Zwischenablage zum Senden.",
|
||||
"push_notifications": "Push-Meldungen",
|
||||
"retype_password": "Passwort wiederholen",
|
||||
"selfTest": "Selbsttest",
|
||||
"save": "Speichern",
|
||||
"saved": "Gespeichert",
|
||||
"success_transaction_broadcasted" : "Erfolg! Diene Transaktion wurde übertragen.",
|
||||
|
@ -336,7 +337,6 @@
|
|||
"cancel_no": "Diese Transaktion ist nicht ersetzbar.",
|
||||
"cancel_title": "Diese Transaktion abbrechen (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} Bestätigungen",
|
||||
"transaction_id": "Transaktions-ID",
|
||||
"note": "Bezeichnung",
|
||||
"expand_note": "Bezeichnung erweitern",
|
||||
"block_explorer_link": "Block Explorer Link",
|
||||
|
|
|
@ -319,6 +319,7 @@
|
|||
"privacy_clipboard_explanation": "Provide shortcuts if an address or invoice is found in your clipboard.",
|
||||
"push_notifications": "Push Notifications",
|
||||
"retype_password": "Re-type password",
|
||||
"selfTest": "Self-Test",
|
||||
"save": "Save",
|
||||
"saved": "Saved",
|
||||
"success_transaction_broadcasted" : "Success! You transaction has been broadcasted!",
|
||||
|
@ -336,7 +337,6 @@
|
|||
"cancel_no": "This transaction is not replaceable.",
|
||||
"cancel_title": "Cancel this transaction (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} confirmations",
|
||||
"transaction_id": "Transaction ID",
|
||||
"note": "Note",
|
||||
"expand_note": "Expand Note",
|
||||
"block_explorer_link": "Block Explorer Link",
|
||||
|
|
45
loc/es.json
45
loc/es.json
|
@ -9,14 +9,16 @@
|
|||
"ok": "OK",
|
||||
"storage_is_encrypted": "Tu almacenamiento está cifrado. Se requiere la contraseña para descifrarlo.",
|
||||
"allow": "Permitir",
|
||||
"dont_allow": "No permitir",
|
||||
"dont_allow": "No Permitir",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
"save": "Guardar",
|
||||
"seed": "Semilla",
|
||||
"wallet_key": "Llave de la cartera",
|
||||
"invalid_animated_qr_code_fragment" : "Fragmento de código QR inválido. Por favor inténtalo de nuevo.",
|
||||
"file_saved": "El archivo ({filePath}) se ha guardado en su carpeta de Descargas."
|
||||
"invalid_animated_qr_code_fragment": "Fragmento de código QR inválido. Por favor inténtalo de nuevo.",
|
||||
"file_saved": "El archivo ({filePath}) se ha guardado en su carpeta de Descargas.",
|
||||
"discard_changes": "¿Descartar cambios? ",
|
||||
"discard_changes_detail": "Tienes cambios sin guardar. ¿Estás seguro que quieres descartarlos y salir?"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "El código de tu cupón es",
|
||||
|
@ -87,7 +89,7 @@
|
|||
"offer_promt_fiat": "¿Cuántos {currency} quieres comprar?",
|
||||
"offer_promt_fiat_e": "Por ejemplo, 100",
|
||||
"offer_window": "ventana",
|
||||
"p2p": "Una casa de cambio p2p"
|
||||
"p2p": "Compra Bitcoin en un Exchange Peer-to-Peer "
|
||||
},
|
||||
"lnd": {
|
||||
"errorInvoiceExpired": "Factura expirada",
|
||||
|
@ -135,7 +137,7 @@
|
|||
"ask_yes": "Sí, lo he hecho",
|
||||
"ok": "OK, ya lo he anotado.",
|
||||
"ok_lnd": "OK, lo he guardado.",
|
||||
"text": "Tómate un momento para apuntar esta frase mnemotécnica en un papel. Es lo que te permitirá restaurar la cartera en otro dispositivo.",
|
||||
"text": "Por favor, tome un momento para anotar esta frase mnemotécnica en un papel. Este es su backup que puede utilizar para restaurar la billetera en otro dispositivo. ",
|
||||
"text_lnd": "Por favor guarda la copia de seguridad de esta cartera. Te permitirá restaurarla en caso de pérdida.",
|
||||
"text_lnd2": "Esta cartera está alojada en BlueWallet.",
|
||||
"title": "Tu cartera ha sido creada"
|
||||
|
@ -176,8 +178,8 @@
|
|||
"details_adv_full_sure": "¿Estás seguro de querer utilizar todo el saldo de tu cartera en esta transacción?",
|
||||
"details_adv_import": "Importar transacción",
|
||||
"details_amount_field_is_not_valid": "La cantidad no es válida",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "La cantidad especificada es muy pequeña. Por favor, introduzca una cantidad mayor a 500 sats. ",
|
||||
"details_create": "Crear factura",
|
||||
"details_error_decode": "Error: No se ha podido decodificar la dirección de Bitcoin",
|
||||
"details_fee_field_is_not_valid": "La comisión introducida no es válida",
|
||||
"details_next": "Siguiente",
|
||||
"details_no_maximum": "La cartera seleccionada no permite el cálculo automático del saldo máximo. ¿Estás seguro de querer seleccionar esta cartera?",
|
||||
|
@ -209,6 +211,7 @@
|
|||
"input_total": "Total:",
|
||||
"permission_camera_message": "Necesitamos permiso para usar tu cámara.",
|
||||
"permission_camera_title": "Permiso para usar la cámara",
|
||||
"psbt_sign": "Firmar una transacción",
|
||||
"open_settings": "Abrir configuración",
|
||||
"permission_storage_later": "Pregúntame luego",
|
||||
"permission_storage_message": "BlueWallet necesita permiso de acceso a tu almacenamiento para guardar este archivo.",
|
||||
|
@ -235,6 +238,7 @@
|
|||
"about_release_notes": "Notas de la versión",
|
||||
"about_review": "Escribe una reseña",
|
||||
"about_selftest": "Iniciar test local",
|
||||
"about_selftest_ok": "Todas las pruebas internas han concluido satisfactoriamente. La billetera funciona bien. ",
|
||||
"about_sm_github": "GitHub",
|
||||
"about_sm_discord": "Servidor de Discord",
|
||||
"about_sm_telegram": "Canal de Telegram",
|
||||
|
@ -260,7 +264,7 @@
|
|||
"electrum_saved": "Los cambios se han guardado. Puede que se requiera reiniciar la aplicación para que tomen efecto.",
|
||||
"set_electrum_server_as_default": "¿Establecer {server} como servidor Electrum por defecto?",
|
||||
"set_lndhub_as_default": "¿Establecer {url} como servidor LNDHub por defecto?",
|
||||
"electrum_settings": "Configuración de Electrum",
|
||||
"electrum_settings_server": "Ajustes del Servidor Electrum",
|
||||
"electrum_settings_explain": "Déjalo en blanco para usar el predeterminado",
|
||||
"electrum_status": "Estado",
|
||||
"electrum_clear_alert_title": "¿Limpiar historial?",
|
||||
|
@ -269,7 +273,9 @@
|
|||
"electrum_clear_alert_ok": "Ok",
|
||||
"electrum_select": "Seleccionar",
|
||||
"electrum_reset": "Restablecer valores predeterminados",
|
||||
"electrum_unable_to_connect": "Imposible conectar a {server}. ",
|
||||
"electrum_history": "Historial del servidor",
|
||||
"electrum_reset_to_default": "¿Estás seguro de querer reiniciar sus ajustes de Electrum por defecto? ",
|
||||
"electrum_clear": "Limpiar",
|
||||
"encrypt_decrypt": "Desencriptar almacenamiento",
|
||||
"encrypt_decrypt_q": "¿Seguro que quieres desencriptar tu almacenamiento? Al hacerlo, se podrá acceder a tus carteras sin contraseña.",
|
||||
|
@ -297,7 +303,7 @@
|
|||
"network_electrum": "Servidor Electrum",
|
||||
"not_a_valid_uri": "URI no válida",
|
||||
"notifications": "Notificaciones",
|
||||
"open_link_in_explorer" : "Abrir enlace en el navegador",
|
||||
"open_link_in_explorer": "Abrir enlace en el navegador",
|
||||
"password": "Contraseña",
|
||||
"password_explain": "Crea la contraseña que usarás para descifrar el almacenamiento",
|
||||
"passwords_do_not_match": "Contraseñas deben ser iguales",
|
||||
|
@ -313,7 +319,7 @@
|
|||
"retype_password": "Introduce la contraseña otra vez",
|
||||
"save": "Guardar",
|
||||
"saved": "Guardado",
|
||||
"success_transaction_broadcasted" : "¡Listo! ¡Tu transacción ha sido emitida!",
|
||||
"success_transaction_broadcasted": "¡Listo! ¡Tu transacción ha sido emitida!",
|
||||
"total_balance": "Balance total",
|
||||
"total_balance_explanation": "Muestra el balance total de todas tus carteras en los widgets de tu pantalla principal.",
|
||||
"widgets": "Widgets"
|
||||
|
@ -324,10 +330,14 @@
|
|||
"ask_me_later": "Pregúntame después"
|
||||
},
|
||||
"transactions": {
|
||||
"cancel_explain": "Reemplazaremos esta transacción con la que te pague y tenga tasas más altas, lo que cancelará la transacción. Esto se denomina RBF—Replace By Fee.",
|
||||
"cancel_explain": "Reemplazaremos esta transacción con la que que te pague y tenga mayor fee. Esto cancela efectivamente la transacción. Esto es llamado RBF—Reemplazar por Fee. ",
|
||||
"cancel_no": "Esta transacción no se puede reemplazar.",
|
||||
"cancel_title": "Cancelar esta transacción (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} confirmaciones",
|
||||
"transaction_id": "ID de transacción",
|
||||
"note": "Nota",
|
||||
"expand_note": "Expandir Nota",
|
||||
"block_explorer_link": "Enlace al explorador de bloques",
|
||||
"cpfp_create": "Crear",
|
||||
"cpfp_exp": "Crearemos una nueva transacción que gastará tu transacción aún no confirmada. La comisión total será mayor que la comisión original, lo cual debería hacer que sea minada en menos tiempo. Esto se denomina CPFP—Child Pays For Parent.",
|
||||
"cpfp_no_bump": "Esta transacción no se puede acelerar",
|
||||
|
@ -340,12 +350,12 @@
|
|||
"details_inputs": "Inputs",
|
||||
"details_outputs": "Outputs",
|
||||
"details_received": "Recibido",
|
||||
"transaction_note_saved":"La nota de la transacción ha sido guardada.",
|
||||
"transaction_note_saved": "La nota de la transacción ha sido guardada.",
|
||||
"details_show_in_block_explorer": "Mostrar en explorador de bloques",
|
||||
"details_title": "Transaccion",
|
||||
"details_to": "Destino",
|
||||
"details_transaction_details": "Detalles de la transacción",
|
||||
"enable_hw": "Esta cartera no está siendo usada junto a una cartera de hardware. ¿Quieres activar el uso con carteras de hardware?",
|
||||
"enable_offline_signing": "Esta billetera no se está usando en conjunción con una firma offline. ¿Quieres activarlo ahora? ",
|
||||
"list_conf": "Conf: {number}",
|
||||
"pending": "En espera",
|
||||
"list_title": "Transacciones",
|
||||
|
@ -354,7 +364,8 @@
|
|||
"status_bump": "Aumentar comisón",
|
||||
"status_cancel": "Cancelar transacción",
|
||||
"transactions_count": "Número de transacciones",
|
||||
"txid": "Txid"
|
||||
"txid": "ID de transacción ",
|
||||
"updating": "Actualizando... "
|
||||
},
|
||||
"wallets": {
|
||||
"add_bitcoin": "Bitcoin",
|
||||
|
@ -405,7 +416,7 @@
|
|||
"export_title": "Exportación de cartera",
|
||||
"import_do_import": "Importar",
|
||||
"import_error": "Error al importar. Por favor, asegúrate de que los datos introducidos son correctos.",
|
||||
"import_explanation": "Pon aquí una semilla mnemotécnica, una clave privada, un WIF o cualquier cosa que tengas. BlueWallet identificará el formato e importará la cartera.",
|
||||
"import_explanation": "Por favor, introduzca sus palabras semilla, llave pública, WIF, o cualquier otra cosa que tenga. BlueWallet hará lo posible para descifrar el formato correcto e importar su billetera. ",
|
||||
"import_file": "Importar archivo",
|
||||
"import_imported": "Importado",
|
||||
"import_placeholder_fail": "Importar cartera",
|
||||
|
@ -418,7 +429,7 @@
|
|||
"list_create_a_wallet_text": "Es gratis y puedes crear\ntodas las que quieras",
|
||||
"list_empty_txs1": "Tus transacciones aparecerán aquí",
|
||||
"list_empty_txs1_lightning": "Usa carteras Lightning para tus transacciones diarias. Tienen comisiones muy bajas y una velocidad de vértigo.",
|
||||
"list_empty_txs2": "Empieza con tu cartera",
|
||||
"list_empty_txs2": "Comienza con tu billetera. ",
|
||||
"list_empty_txs2_lightning": "\nPara comenzar a usarlo, toca en \"administrar fondos\" y añade algo de saldo.",
|
||||
"list_header": "Una cartera representa un par de llaves, una privada y una que puedes compartir para recibir fondos.",
|
||||
"list_import_error": "Error al intentar importar esta cartera.",
|
||||
|
@ -436,6 +447,7 @@
|
|||
"looks_like_bip38": "Parece que esto es una llave privada protegida con contraseña (BIP38)",
|
||||
"reorder_title": "Reorganizar carteras",
|
||||
"please_continue_scanning": "Por favor, continúa escaneando",
|
||||
"scan_error": "Error al escanear",
|
||||
"select_no_bitcoin": "No hay carteras de Bitcoin disponibles.",
|
||||
"select_no_bitcoin_exp": "Una cartera de Bitcoin es necesaria para recargar una cartera Lightning. Por favor, cree o importe una.",
|
||||
"select_wallet": "Selecciona una cartera",
|
||||
|
@ -448,6 +460,7 @@
|
|||
},
|
||||
"multisig": {
|
||||
"multisig_vault": "Vault",
|
||||
"default_label": "Bóveda multifirma",
|
||||
"multisig_vault_explain": "La mejor seguridad para grandes cantidades",
|
||||
"provide_signature": "Proporcionar firma",
|
||||
"vault_key": "Clave del Vault {number}",
|
||||
|
@ -459,7 +472,7 @@
|
|||
"share": "Compartir",
|
||||
"view": "Ver",
|
||||
"manage_keys": "Administrar claves",
|
||||
"how_many_signatures_can_bluewallet_make": "cuántas firmas puede hacer BlueWallet",
|
||||
"how_many_signatures_can_bluewallet_make": "Cuántas firmas puede hacer BlueWallet",
|
||||
"signatures_required_to_spend": "{number} firmas requeridas",
|
||||
"signatures_we_can_make": "puede hacer {number}",
|
||||
"scan_or_import_file": "Escanear o importar archivo",
|
||||
|
|
|
@ -180,7 +180,7 @@
|
|||
"details_amount_field_is_not_valid": "Määrä ei kelpaa",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "Määritetty määrä on liian pieni. Anna summa, joka on yli 500 sats. ",
|
||||
"details_create": "Luo Lasku",
|
||||
"details_error_decode": "Virhe: Bitcoin-osoitetta ei voida dekoodata",
|
||||
"details_error_decode": "Bitcoin-osoitetta ei voida dekoodata ",
|
||||
"details_fee_field_is_not_valid": "Siirtokulukenttä ei ole pätevä",
|
||||
"details_next": "Seuraava",
|
||||
"details_no_maximum": "Valittu lompakko ei tue automaattista enimmäis-saldolaskelmaa. Haluatko varmasti valita tämän lompakon?",
|
||||
|
@ -189,6 +189,7 @@
|
|||
"details_note_placeholder": "muistiinpano itselle",
|
||||
"details_scan": "Skannaa",
|
||||
"details_total_exceeds_balance": "Lähetettävä summa ylittää katteen",
|
||||
"details_unrecognized_file_format": "Tunnistamaton tiedostomuoto ",
|
||||
"details_wallet_before_tx": "Ennen siirtotapahtuman luomista, sinun on ensin lisättävä Bitcoin-lompakko.",
|
||||
"details_wallet_selection": "Lompakon Valinta",
|
||||
"dynamic_init": "Alustaa",
|
||||
|
@ -318,6 +319,7 @@
|
|||
"privacy_clipboard_explanation": "Toimita pikakuvakkeet, jos leikepöydältä löytyy osoite tai lasku.",
|
||||
"push_notifications": "Push-ilmoitukset",
|
||||
"retype_password": "Salasana uudelleen",
|
||||
"selfTest": "Itsetestaus ",
|
||||
"save": "Tallenna",
|
||||
"saved": "Tallennettu",
|
||||
"success_transaction_broadcasted" : "Onnistui! Siirtotapahtumasi on lähetetty!",
|
||||
|
@ -335,7 +337,6 @@
|
|||
"cancel_no": "Tämä siirtotapahtuma ei ole vaihdettavissa",
|
||||
"cancel_title": "Peruuta tämä siirtotapahtuma (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} vahvistukset",
|
||||
"transaction_id": "Siirtotapahtuman tunnus",
|
||||
"note": "Huomautus",
|
||||
"expand_note": "Laajenna huomautus",
|
||||
"block_explorer_link": "Lohkoselain-linkki",
|
||||
|
|
38
loc/he.json
38
loc/he.json
|
@ -17,7 +17,8 @@
|
|||
"wallet_key": "מפתח ארנק",
|
||||
"invalid_animated_qr_code_fragment": "קטע קוד QR מונפש לא תקין, אנא נסו שוב",
|
||||
"file_saved": "הקובץ ({filePath}) נשמר לתיקיית ההורדות שלך.",
|
||||
"discard_changes": "ביטול שינויים?"
|
||||
"discard_changes": "ביטול שינויים?",
|
||||
"discard_changes_detail": "יש לכם שינויים לא שמורים. האם להיפטר משינויים אלה ולעזוב את המסך?"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "קוד השובר שלך הוא",
|
||||
|
@ -104,7 +105,7 @@
|
|||
"refill_create": "כדי להמשיך, אנא צרו ארנק ביטקוין כדי לטעון באמצעותו.",
|
||||
"refill_external": "טעינה בעזרת ארנק חיצוני",
|
||||
"refill_lnd_balance": "מלאו את יתרת ארנק הברק",
|
||||
"sameWalletAsInvoiceError": "לא ניתן לשלם חשבונית עם אותו הארנק שיצר אותה.",
|
||||
"sameWalletAsInvoiceError": "לא ניתן לשלם חשבונית עם אותו הארנק בו היא נוצרה.",
|
||||
"title": "ניהול כספים"
|
||||
},
|
||||
"lndViewInvoice": {
|
||||
|
@ -121,17 +122,17 @@
|
|||
"plausibledeniability": {
|
||||
"create_fake_storage": "צרו אחסון מוצפן",
|
||||
"create_password": "צרו סיסמה",
|
||||
"create_password_explanation": "הסיסמה לאחסון המזויף צריכה להיות שונה מהסיסמה לאחסון הראשי",
|
||||
"create_password_explanation": "הסיסמה לאחסון המדומה צריכה להיות שונה מהסיסמה לאחסון הראשי",
|
||||
"help": "בנסיבות מסוימות, יתכן ותאולצו לחשוף את סיסמת הארנק. כדי לשמור על המטבעות בטוחים, BlueWallet מאפשר ליצור אחסון מוצפן נוסף, עם סיסמה שונה. תחת לחץ, תוכלו לחשוף את סיסמה זו לצד שלישי. אם הסיסמה תוכנס ל- BlueWallet, אחסון 'מזויף' חדש יפתח. מצב זה יראה לגיטימי לצד השלישי, בזמן שהאחסון הראשי ישמר בסודיות עם כשהמטבעות מוגנים.",
|
||||
"help2": "האחסון החדש יתפקד באופן מלא, ותוכלו לאחסן בו סכומים מינימליים כך שיראה יותר מהימן.",
|
||||
"password_should_not_match": "הסיסמה כבר בשימוש. אנא נסו סיסמה אחרת.",
|
||||
"passwords_do_not_match": "סיסמאות אינן תואמות, אנא נסו שוב",
|
||||
"retype_password": "הכניסו שוב סיסמה",
|
||||
"success": "הצלחה",
|
||||
"title": "הכחשה סבירה"
|
||||
"title": "יכולת הכחשה סבירה"
|
||||
},
|
||||
"pleasebackup": {
|
||||
"ask": "האם שמרת את מילות הגיבוי שלך? מילות גיבוי אלה דרושות כדי לגשת לכספים שלך במקרה ומכשיר זה נאבד. ללא גיבוי זה, הכספים יאבדו לצמיתות.",
|
||||
"ask": "האם שמרת את מילות הגיבוי שלך? מילות גיבוי אלה דרושות כדי לגשת לכספים שלך במקרה של אובדן מכשיר זה. ללא גיבוי זה, הכספים יאבדו לצמיתות.",
|
||||
"ask_no": "לא, לא גיביתי",
|
||||
"ask_yes": "כן, גיביתי",
|
||||
"ok": "אוקיי, רשמתי את זה!",
|
||||
|
@ -179,7 +180,7 @@
|
|||
"details_amount_field_is_not_valid": "שדה סכום אינו תקין",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "הסכום המוגדר קטן מידי. אנא הכניסו סכום גדול מ- 500 סאטס.",
|
||||
"details_create": "יצירת קבלה",
|
||||
"details_error_decode": "שגיאה: לא ניתן לפענח כתובת ביטקוין",
|
||||
"details_error_decode": "לא ניתן לפענח כתובת ביטקוין",
|
||||
"details_fee_field_is_not_valid": "שדה עמלה אינו תקין",
|
||||
"details_next": "הבא",
|
||||
"details_no_maximum": "הארנק הנבחר אינו תומך בחישוב יתרה מקסימלית אוטומטי. האם לבחור בארנק זה בכל זאת?",
|
||||
|
@ -188,6 +189,7 @@
|
|||
"details_note_placeholder": "הערה לעצמך",
|
||||
"details_scan": "סריקה",
|
||||
"details_total_exceeds_balance": "הסכום לשליחה חורג מהיתרה הזמינה.",
|
||||
"details_unrecognized_file_format": "פורמט קובץ לא מזוהה",
|
||||
"details_wallet_before_tx": "לפני יצירת העברה, עליך להוסיף ארנק ביטקוין.",
|
||||
"details_wallet_selection": "בחירת ארנקים",
|
||||
"dynamic_init": "איתחול",
|
||||
|
@ -209,8 +211,9 @@
|
|||
"input_done": "בוצע",
|
||||
"input_paste": "הדבק",
|
||||
"input_total": "סך הכל:",
|
||||
"permission_camera_message": "אנחנו צריכים את הרשאתך לשימוש במצלמה שלך",
|
||||
"permission_camera_message": "אנחנו צריכים את הרשאתך לשימוש במצלמה שלך.",
|
||||
"permission_camera_title": "הרשאה לשימוש במצלמה",
|
||||
"psbt_sign": "חתימה על העברה",
|
||||
"open_settings": "פתח הגדרות",
|
||||
"permission_storage_later": "שאל אותי מאוחר יותר",
|
||||
"permission_storage_message": "ארנק BlueWallet צריך את הרשאתך לגשת לאחסון שלך כדי לשמור את קובץ זה.",
|
||||
|
@ -237,6 +240,7 @@
|
|||
"about_release_notes": "הערות שחרור",
|
||||
"about_review": "השאירו לנו ביקורת",
|
||||
"about_selftest": "הרץ בדיקה עצמית",
|
||||
"about_selftest_ok": "כל הבדיקות הפנימיות עברו בהצלחה. הארנק פועל כיאות.",
|
||||
"about_sm_github": "GitHub",
|
||||
"about_sm_discord": "שרת דיסקורד",
|
||||
"about_sm_telegram": "צ'אט טלגרם",
|
||||
|
@ -259,7 +263,7 @@
|
|||
"electrum_saved": "השינויים נשמרו בהצלחה. ייתכן ותדרש הפעלה מחדש כדי שהשינויים ייכנסו לתוקף.",
|
||||
"set_electrum_server_as_default": "הגדרת {server} כשרת אלקטרום ברירת מחדל?",
|
||||
"set_lndhub_as_default": "הגדרת {url} כשרת LNDHub ברירת מחדל?",
|
||||
"electrum_settings": "הגדרות אלקטרום",
|
||||
"electrum_settings_server": "הגדרות שרת אלקטרום",
|
||||
"electrum_settings_explain": "השאירו ריק כדי להשתמש בברירת מחדל",
|
||||
"electrum_status": "מצב",
|
||||
"electrum_clear_alert_title": "ניקוי היסטוריה?",
|
||||
|
@ -268,7 +272,9 @@
|
|||
"electrum_clear_alert_ok": "אישור",
|
||||
"electrum_select": "בחירה",
|
||||
"electrum_reset": "איפוס ברירת מחדל",
|
||||
"electrum_unable_to_connect": "לא מסוגל להתחבר לשרת {server}.",
|
||||
"electrum_history": "היסטוריית שרת",
|
||||
"electrum_reset_to_default": "האם אתם בטוחים שברצונכם לשחזר את הגדרות האקלטרום שלכם לברירת מחדל?",
|
||||
"electrum_clear": "ניקוי",
|
||||
"encrypt_decrypt": "פתיחת אחסון מוצפן",
|
||||
"encrypt_decrypt_q": "האם לפענח אחסון מוצפן? זה יאפשר לגשת לארנקים שלך ללא סיסמה.",
|
||||
|
@ -300,7 +306,7 @@
|
|||
"password": "סיסמה",
|
||||
"password_explain": "צורו סיסמה שבה תשתמשו לפתיחת האחסון המוצפן",
|
||||
"passwords_do_not_match": "סיסמאות לא תואמות",
|
||||
"plausible_deniability": "הכחשה סבירה",
|
||||
"plausible_deniability": "יכולת הכחשה סבירה",
|
||||
"privacy": "פרטיות",
|
||||
"privacy_read_clipboard": "קריאה מקליפבורד",
|
||||
"privacy_read_clipboard_alert": "ארנק BlueWallet יציג קיצורי דרך לטיפול בחשבונית או כתובת אשר נמצאות בקליפבורד שלך.",
|
||||
|
@ -323,10 +329,14 @@
|
|||
"ask_me_later": "שאל אותי מאוחר יותר"
|
||||
},
|
||||
"transactions": {
|
||||
"cancel_explain": "אנו נחליף את ההעברה הזאת באחת עם עמלה גבוהה יותר. פעולה זאת למעשה מבטלת את העברה. פעולה זאת נקראת RBF - Replace By Fee.",
|
||||
"cancel_explain": "אנחנו נחליף את העברה זאת עם העברה לעצמך עם עמלות גבוהות יותר. זה למעשה מבטל את ההעברה. זה נקרא RBF—Replace by Fee.",
|
||||
"cancel_no": "העברה זאת אינה ניתנת להחלפה",
|
||||
"cancel_title": "בטל העברה זאת (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} אישורים",
|
||||
"transaction_id": "מזהה העברה",
|
||||
"note": "הערה",
|
||||
"expand_note": "הרחבת הערה",
|
||||
"block_explorer_link": "קישור סייר בלוקים",
|
||||
"cpfp_create": "צור",
|
||||
"cpfp_exp": "אנו ניצור העברה נוספת שתשתמש בעודף שנשאר מההעברה הקודמת שבוצעה. סך כל העמלה יהיה גבוה יותר מעמלת ההעברה המקורית, כך שמהירות קבלת האישור אמורה לעלות. פעולה זאת נקראת CPFP - Child Pays For Parent.",
|
||||
"cpfp_no_bump": "עמלת העברה זו אינה ניתנת להעלאה",
|
||||
|
@ -344,7 +354,6 @@
|
|||
"details_title": "העברה",
|
||||
"details_to": "פלט",
|
||||
"details_transaction_details": "פרטי העברה",
|
||||
"enable_hw": "ארנק זה אינו בשימוש בצירוף ארנק חומרה. האם ברצונך לאפשר שימוש בארנק חומרה?",
|
||||
"list_conf": "אישורים: {number}",
|
||||
"pending": "ממתין",
|
||||
"list_title": "תנועות",
|
||||
|
@ -416,9 +425,9 @@
|
|||
"list_create_a_button": "הוסיפו עכשיו",
|
||||
"list_create_a_wallet": "הוסיפו ארנק",
|
||||
"list_create_a_wallet_text": "זה חינם ותוכלו ליצור\nכמה שתרצו",
|
||||
"list_empty_txs1": "התנועות שלך יופיעו פה",
|
||||
"list_empty_txs1": "התנועות שלכם יופיעו פה",
|
||||
"list_empty_txs1_lightning": "ארנק הברק משמש לתשלומים יומיומיים. העברות זולות בצורה לא הגיונית המתבצעות במהירות הבזק.",
|
||||
"list_empty_txs2": "עם תחילת השימוש בארנק",
|
||||
"list_empty_txs2": "התחילו שימוש בארנקכם.",
|
||||
"list_empty_txs2_lightning": "\nלהתחלת שימוש לחצו על \"ניהול כספים\" ומלאו את היתרה",
|
||||
"list_header": "ארנק מייצר צמד מפתחות, מפתח פרטי וכתובת שאותה ניתן לשתף כדי לקבל מטבעות.",
|
||||
"list_import_error": "התרחשה שגיאה בניסיון לייבא ארנק זה.",
|
||||
|
@ -457,6 +466,7 @@
|
|||
"confirm": "אישור",
|
||||
"header": "שליחה",
|
||||
"share": "שיתוף",
|
||||
"view": "הצגה",
|
||||
"manage_keys": "ניהול מפתחות",
|
||||
"how_many_signatures_can_bluewallet_make": "כמה חתימות ארנק BlueWallet יכול ליצור",
|
||||
"signatures_required_to_spend": "חתימות דרושות {number}",
|
||||
|
@ -483,7 +493,7 @@
|
|||
"of": "מתוך",
|
||||
"wallet_type": "סוג ארנק",
|
||||
"view_key": "הצגה",
|
||||
"invalid_mnemonics": "צירוף מנמוני זה לא נראה תקין",
|
||||
"invalid_mnemonics": "צירוף מנמוני זה לא נראה תקין.",
|
||||
"invalid_cosigner": "נתוני חותם שותף לא תקינים",
|
||||
"not_a_multisignature_xpub": "זה אינו מפתח תצוגה מארנק רב-חתימות!",
|
||||
"invalid_cosigner_format": "חותם שותף שגוי: זה אינו חותם שותף לפורמט {format}",
|
||||
|
|
182
loc/hu_hu.json
182
loc/hu_hu.json
|
@ -1,22 +1,22 @@
|
|||
{
|
||||
"_": {
|
||||
"allow": "Engedélyezés",
|
||||
"bad_password": "Hibás jelszó, próbáld újra",
|
||||
"cancel": "Mégse",
|
||||
"continue": "Folytatás",
|
||||
"dont_allow": "Nem engedélyezem",
|
||||
"enter_password": "Írd be a jelszót",
|
||||
"file_saved": "({filePath}) fájl elmentve a Download (letöltések) könyvtárba.",
|
||||
"invalid_animated_qr_code_fragment": "Érvénytelen animált QR kód részlet, próbáld újra!",
|
||||
"never": "soha",
|
||||
"no": "Nem",
|
||||
"of": "{number} / {total}",
|
||||
"ok": "OK",
|
||||
"storage_is_encrypted": "A Tárhely titkosítva. Jelszó szükséges a dekódoláshoz",
|
||||
"allow": "Engedélyezés",
|
||||
"dont_allow": "Nem engedélyezem",
|
||||
"yes": "Igen",
|
||||
"no": "Nem",
|
||||
"save": "Mentés",
|
||||
"seed": "jelszó sorozat",
|
||||
"storage_is_encrypted": "A Tárhely titkosítva. Jelszó szükséges a dekódoláshoz",
|
||||
"wallet_key": "Tárca kulcs",
|
||||
"yes": "Igen"
|
||||
"invalid_animated_qr_code_fragment": "Érvénytelen animált QR kód részlet, próbáld újra!",
|
||||
"file_saved": "({filePath}) fájl elmentve a Download (letöltések) könyvtárba."
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "A kuponkódod ",
|
||||
|
@ -27,12 +27,6 @@
|
|||
"success": "Sikeres",
|
||||
"title": "Azte.co kupon jóváírása"
|
||||
},
|
||||
"cc": {
|
||||
"change": "váltás",
|
||||
"coins_selected": "Kriptopénz kiválasztva ({number})",
|
||||
"empty": "Ez a tárca jelenleg üres.",
|
||||
"use_coin": "Cryptovaluta használata "
|
||||
},
|
||||
"entropy": {
|
||||
"save": "Mentés",
|
||||
"title": "Entrópia",
|
||||
|
@ -79,7 +73,9 @@
|
|||
"item_nooffers": "Nincs ajánlat. Változtasd az ajánlatokat \"Ajánlatok világszerte\"-re.",
|
||||
"item_rating": "{rating} ügyletek",
|
||||
"item_rating_no": "Nincs értékelés",
|
||||
"local_trader_new": "Új",
|
||||
"login": "Belépés",
|
||||
"logout": "Kilépés",
|
||||
"mycont": "Ügyleteim",
|
||||
"offer_accept": "Ajánlat elfogadása",
|
||||
"offer_account_finish": "Nem fejezted be a HodlHodl fiókod megnyitását, szeretnéd most befejezni?",
|
||||
|
@ -119,50 +115,6 @@
|
|||
"sats": "satoshi",
|
||||
"wasnt_paid_and_expired": "Ezt a számlát nem fizették ki és lejárt"
|
||||
},
|
||||
"multisig": {
|
||||
"co_sign_transaction": "Egy tranzakció aláírása",
|
||||
"confirm": "Megerősítés",
|
||||
"cosign_this_transaction": "Aláírod ezt a tranzakciót?",
|
||||
"create": "Létrehoz",
|
||||
"create_new_key": "Készíts újat",
|
||||
"export_coordination_setup": "koordinációs beállítások exportálása",
|
||||
"fee": "Tranzakciós díj: {number}",
|
||||
"fee_btc": "{number} BTC",
|
||||
"header": "Küldés",
|
||||
"how_many_signatures_can_bluewallet_make": "BlueWallet aláírás kapacitása",
|
||||
"i_have_mnemonics": "Megvan a jelszó sorozatom ehhez a kulcshoz...",
|
||||
"i_wrote_it_down": "Rendben, leírtam!",
|
||||
"input_fp": "Ujjlenyomat megadása",
|
||||
"invalid_cosigner": "Helytelen társ aláíró adat",
|
||||
"legacy_title": "Hagyomány",
|
||||
"lets_start": "Kezdjük",
|
||||
"multisig_vault": "Trezor",
|
||||
"multisig_vault_explain": "Legnagyobb biztonság nagy összegekhez",
|
||||
"native_segwit_title": "Bevált gyakorlat",
|
||||
"needs": "szükséges",
|
||||
"of": "/",
|
||||
"provide_key": "Kulcs megadása",
|
||||
"provide_signature": "Aláírás végrehajtása ",
|
||||
"scan_or_import_file": "Szkennelés vagy fájl importálása",
|
||||
"scan_or_open_file": "Szkennelés vagy fájl megnyitása",
|
||||
"share": "Megosztás",
|
||||
"type_your_mnemonics": "Jelszó sorozat megadása egy létező trezor-kulcs megadásához",
|
||||
"vault_advanced_customize": "Trezor beállítások",
|
||||
"vault_key": "Trezor kulcs {number}",
|
||||
"view_edit_cosigners": "Társ aláírok megtekintése/szerkesztése ",
|
||||
"view_edit_cosigners_title": "Társ aláírók szerkesztése",
|
||||
"view_key": "megnéz",
|
||||
"wallet_type": "Tárca típusa",
|
||||
"what_is_vault": "A Trezor egy",
|
||||
"what_is_vault_description_number_of_vault_keys": "{m} trezor kulcsok",
|
||||
"what_is_vault_wallet": "tárca",
|
||||
"wrapped_segwit_title": "Legjobb kompatibilitás "
|
||||
},
|
||||
"notifications": {
|
||||
"ask_me_later": "Később",
|
||||
"no_and_dont_ask": "Nem és ne kérdezd újra",
|
||||
"would_you_like_to_receive_notifications": "Szeretnél értesítést a bejövő utalásokról? "
|
||||
},
|
||||
"plausibledeniability": {
|
||||
"create_fake_storage": "Hamis tárhely létrehozása",
|
||||
"create_password": "Jelszó létrehozása",
|
||||
|
@ -181,7 +133,6 @@
|
|||
"ask_yes": "Igen, van",
|
||||
"ok": "Rendben, leírtam!",
|
||||
"ok_lnd": "OK, elmentettem.",
|
||||
"text": "Kérlek írd le az alábbi emlékeztető szavakat egy papírlapra, és tedd el egy biztonságos helyre. Ez egy biztonsági mentés, amellyel helyreállíthatod a tárcádat egy másik eszközön.",
|
||||
"text_lnd": "Készíts biztonsági másolatot erről az LNDHub hitelesítésről. Ezzel a biztonsági másolattal visszaállíthatod a tárcát más eszközön.",
|
||||
"title": "A tárcád elkészült..."
|
||||
},
|
||||
|
@ -221,8 +172,8 @@
|
|||
"details_adv_full_sure": "Biztosan használni akarod a tárca teljes egyenlegét ehhez a tranzakcióhoz?",
|
||||
"details_adv_import": "Tranzakció importálása",
|
||||
"details_amount_field_is_not_valid": "Érvénytelen összeg",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "A megadott összeg túl kevés. Kérlek adj meg egy 500sat-nál nagyobb összeget.",
|
||||
"details_create": "Készíts számlát",
|
||||
"details_error_decode": "HIba: Nem lehet dekódolni a Bitcoin tárca címet",
|
||||
"details_fee_field_is_not_valid": "Èrvénytelen tranzakciós díj",
|
||||
"details_next": "Következő",
|
||||
"details_no_maximum": "A kiválasztott tárca nem támogatja az automatikus teljes egyenleg számítást. Biztosan ezt a tárcát választod?",
|
||||
|
@ -252,24 +203,24 @@
|
|||
"input_done": "Kész",
|
||||
"input_paste": "beillesztés",
|
||||
"input_total": "Összesen:",
|
||||
"no_tx_signing_in_progress": "Tranzakció aláírás nincs folyamatban",
|
||||
"open_settings": "Beállítások megnyitása",
|
||||
"permission_camera_message": "Kamera használat engedélyezése",
|
||||
"permission_camera_title": "Kamera használatának engedélyezése",
|
||||
"permission_storage_denied_message": "A BlueWallet nem mentette el ezt a fájlt. Engedélyezd a háttértár hozzáférést az eszköz beállításában. ",
|
||||
"open_settings": "Beállítások megnyitása",
|
||||
"permission_storage_later": "Később",
|
||||
"permission_storage_message": "A fájl elmentéséhez engedélyezned kell a BlueWallet hozzáférését a háttértárhoz.",
|
||||
"permission_storage_denied_message": "A BlueWallet nem mentette el ezt a fájlt. Engedélyezd a háttértár hozzáférést az eszköz beállításában. ",
|
||||
"permission_storage_title": "Háttértár hozzáférés engedélyezés",
|
||||
"problem_with_psbt": "Hiba a PSBT aláírásban.",
|
||||
"psbt_clipboard": "Másolás vágólapra",
|
||||
"psbt_this_is_psbt": "Ez egy részlegesen aláírt Bitcoin tranzakció (PSBT). Befejezheted a hardver tárcád aláírásával. ",
|
||||
"psbt_tx_export": "Exportálás fájlba",
|
||||
"no_tx_signing_in_progress": "Tranzakció aláírás nincs folyamatban",
|
||||
"psbt_tx_open": "Aláírt tranzakció megnyitása",
|
||||
"psbt_tx_scan": "Aláírt tranzakció szkennelése",
|
||||
"qr_error_no_qrcode": "A kiválasztott kép nem tartalmaz QR kódot.",
|
||||
"qr_error_no_wallet": "A kiválasztott fájl nem tartalmaz importálható tárcát.",
|
||||
"success_done": "Kész!",
|
||||
"txSaved": "A tranzakciós fájl ({filePath}) elmentve a Letöltések (Downloads) mappába."
|
||||
"txSaved": "A tranzakciós fájl ({filePath}) elmentve a Letöltések (Downloads) mappába.",
|
||||
"problem_with_psbt": "Hiba a PSBT aláírásban."
|
||||
},
|
||||
"settings": {
|
||||
"about": "Egyéb",
|
||||
|
@ -283,6 +234,7 @@
|
|||
"about_sm_telegram": "Telegram csevegés",
|
||||
"about_sm_twitter": "Kövess minket Twitteren",
|
||||
"advanced_options": "Haladó Beállítások",
|
||||
"biometrics": "Biometrikus azonosító",
|
||||
"currency": "Valuta",
|
||||
"currency_source": "Árak forrása",
|
||||
"default_desc": "Ha le van tiltva, a BlueWallet azonnal megnyitja a kiválasztott tárcát indításkor. ",
|
||||
|
@ -296,9 +248,16 @@
|
|||
"electrum_port": "TCP port, általában {example}",
|
||||
"electrum_port_ssl": "SSL port, általában {example}",
|
||||
"electrum_saved": "A változtatás sikeresen elmentve. Az új beállítások aktiválásához űjraindításra lehet szükség.",
|
||||
"electrum_settings": "Electrum beállítások",
|
||||
"electrum_settings_server": "Electrum Szerver beállítások",
|
||||
"electrum_settings_explain": "Hagyd üresen az alapértelmezett beállításhoz",
|
||||
"electrum_status": "Állapot",
|
||||
"electrum_clear_alert_cancel": "Mégse",
|
||||
"electrum_clear_alert_ok": "OK",
|
||||
"electrum_select": "Kiválasztás",
|
||||
"electrum_reset": "alapértelmezett beállítások visszaállítása",
|
||||
"electrum_unable_to_connect": "Nincs kapcsolat {server} -hez.",
|
||||
"electrum_history": "Szerver előzmények",
|
||||
"electrum_clear": "Törlés",
|
||||
"encrypt_decrypt": "Háttértár titkosításának feloldása",
|
||||
"encrypt_decrypt_q": "Biztosan feloldod a háttértár titkosítását? Ez lehetővé teszi a tárca jelszó nélküli használatát. ",
|
||||
"encrypt_del_uninstall": "Töröld ha a BlueWallet el lett távolítva",
|
||||
|
@ -325,24 +284,33 @@
|
|||
"network_electrum": "Electrum szerver",
|
||||
"not_a_valid_uri": "Hibás azonosító (URI)",
|
||||
"notifications": "Megjegyzések",
|
||||
"open_link_in_explorer": "Link megnyitása explorerben",
|
||||
"password": "Jelszó",
|
||||
"password_explain": "Add meg a jelszót, amivel majd dekódolhatod a tárhelyet",
|
||||
"passwords_do_not_match": "A megadott jelszavak különböznek!",
|
||||
"plausible_deniability": "Elfogadható tagadhatóság...",
|
||||
"privacy": "Személyes adatok",
|
||||
"privacy_quickactions": "tárca gyorsbillentyűk",
|
||||
"privacy_quickactions_explanation": "Érintsd meg és tartsd nyomva a BlueWallet alkalmazás ikont a képernyőn a tárca egyenleg gyors megtekintéséhez.",
|
||||
"privacy_read_clipboard": "Vágólap olvasása",
|
||||
"privacy_system_settings": "Rendszer beállítások",
|
||||
"privacy_quickactions": "tárca gyorsbillentyűk",
|
||||
"privacy_quickactions_explanation": "Érintsd meg és tartsd nyomva a BlueWallet alkalmazás ikont a képernyőn a tárca egyenleg gyors megtekintéséhez.",
|
||||
"push_notifications": "Push üzenet",
|
||||
"retype_password": "Jelszó megerősítése",
|
||||
"save": "Ment",
|
||||
"saved": "Elmentve"
|
||||
"saved": "Elmentve",
|
||||
"total_balance": "Teljes egyenleg"
|
||||
},
|
||||
"notifications": {
|
||||
"would_you_like_to_receive_notifications": "Szeretnél értesítést a bejövő utalásokról? ",
|
||||
"no_and_dont_ask": "Nem és ne kérdezd újra",
|
||||
"ask_me_later": "Később"
|
||||
},
|
||||
"transactions": {
|
||||
"cancel_explain": "Kiváltjuk ezt a tranzakciót egy magasabb tranzakciós díjjal járó, teljesülő tranzakcióval. Egyúttal töröljük az eredeti tranzakciót. Ezt a megoldást Tranzakciós Díj Pótlásnak hívjuk, angolul RBF - Replace by Fee.",
|
||||
"cancel_no": "Ez a tranzakció nem helyettesíthető",
|
||||
"cancel_title": "Tranzakció törlése (RBF)",
|
||||
"transaction_id": "Tranzakció azonosító",
|
||||
"note": "Megjegyzés",
|
||||
"expand_note": "További részletek",
|
||||
"cpfp_create": "Létrehoz",
|
||||
"cpfp_exp": "Új tranzakciót adunk a függő tranzakcióhoz. A teljes tranzakciós díj magasabb lesz, így hamarabb teljesül. Ezt hívják angolul \"CPFP - Child Pays For Parent / Gyerek fizet a szülőnek\".",
|
||||
"cpfp_no_bump": "Tranzakció nem kiváltható",
|
||||
|
@ -360,13 +328,15 @@
|
|||
"details_to": "Kimenő utalás",
|
||||
"details_transaction_details": "Tranzakció részletei",
|
||||
"list_conf": "megerősítés: {number}",
|
||||
"list_title": "tranzakciók",
|
||||
"pending": "függőben",
|
||||
"list_title": "tranzakciók",
|
||||
"rbf_explain": "Kiváltjuk ezt a tranzakciót egy magasabb tranzakciós díjjal járó tranzakcióval, így hamarabb teljesül. Ezt a megoldást Tranzakciós Díj Pótlásnak hívjuk, angolul RBF - Replace by Fee.",
|
||||
"rbf_title": "Kiváltási díj (RBF)",
|
||||
"status_bump": "Kiváltási díj",
|
||||
"status_cancel": "Tranzakció törlése",
|
||||
"transactions_count": "Tranzakciók száma"
|
||||
"transactions_count": "Tranzakciók száma",
|
||||
"txid": "Tranzakció azonosító",
|
||||
"updating": "Frissítés..."
|
||||
},
|
||||
"wallets": {
|
||||
"add_bitcoin": "Bitcoin",
|
||||
|
@ -412,9 +382,10 @@
|
|||
"export_title": "tárca exportálása",
|
||||
"import_do_import": "Importálás",
|
||||
"import_error": "Importálás sikertelen. Ellenőrizd, hogy helyes adatokat adtál-e meg.",
|
||||
"import_explanation": "Írd be a kulcsszavaidat, a titkos kulcsodat, WIF-et, vagy bármi mást. A BlueWallet megpróbálja kitalálni a helyes formátumot, és importálja a tárcádat",
|
||||
"import_file": "fájl importálása",
|
||||
"import_imported": "Importálva",
|
||||
"import_placeholder_fail": "Tárca importálás",
|
||||
"import_placeholder_inprogress": "Tárca importálása...",
|
||||
"import_scan_qr": "vagy QR-kód szkennelése?",
|
||||
"import_success": "Sikeres importálás!",
|
||||
"import_title": "importálás",
|
||||
|
@ -423,7 +394,6 @@
|
|||
"list_create_a_wallet_text": "Ingyenes, és annyit hozhatsz létre amennyit szeretnél",
|
||||
"list_empty_txs1": "A tranzakcióid itt fognak megjelenni",
|
||||
"list_empty_txs1_lightning": "A Lightning tárcát a mindennapi tranzakcióidhoz használhatod. A tranzakciók azonnal végrehajtódnak, minimális átutalási díjjal.",
|
||||
"list_empty_txs2": "Indítás a tárcáddal",
|
||||
"list_empty_txs2_lightning": "\nA kezdéshez kattints a \"Kezelés\"-re, és töltsd fel az egyenleged.",
|
||||
"list_header": "A tárca reprezentálja a kulcs párokat, egy privátot és egyet, amit megoszthatsz, hogy Bitcoint fogadhass. ",
|
||||
"list_import_error": "Hiba történt a tárca importálásakor.",
|
||||
|
@ -432,6 +402,7 @@
|
|||
"list_long_choose": "Válassz fényképet",
|
||||
"list_long_clipboard": "Másolás vágólapról",
|
||||
"list_long_scan": "QR kód szkennelése",
|
||||
"list_marketplace": "Piactér",
|
||||
"list_tap_here_to_buy": "Bitcoin vásárláshoz kattints ide",
|
||||
"list_title": "tárcák",
|
||||
"list_tryagain": "Próbáld újra",
|
||||
|
@ -443,5 +414,70 @@
|
|||
"take_photo": "Fénykép készítése",
|
||||
"xpub_copiedToClipboard": "Vágólapra másolva",
|
||||
"xpub_title": "a tárca XPUB kulcsa"
|
||||
},
|
||||
"multisig": {
|
||||
"multisig_vault": "Trezor",
|
||||
"multisig_vault_explain": "Legnagyobb biztonság nagy összegekhez",
|
||||
"provide_signature": "Aláírás végrehajtása ",
|
||||
"vault_key": "Trezor kulcs {number}",
|
||||
"fee": "Tranzakciós díj: {number}",
|
||||
"fee_btc": "{number} BTC",
|
||||
"confirm": "Megerősítés",
|
||||
"header": "Küldés",
|
||||
"share": "Megosztás",
|
||||
"view": "Megnéz",
|
||||
"manage_keys": "Kulcsok kezelése",
|
||||
"signatures_required_to_spend": "Aláírás szükséges {number}",
|
||||
"scan_or_import_file": "Szkennelés vagy fájl importálása",
|
||||
"export_coordination_setup": "koordinációs beállítások exportálása",
|
||||
"cosign_this_transaction": "Aláírod ezt a tranzakciót?",
|
||||
"lets_start": "Kezdjük",
|
||||
"create": "Létrehoz",
|
||||
"provide_key": "Kulcs megadása",
|
||||
"native_segwit_title": "Bevált gyakorlat",
|
||||
"wrapped_segwit_title": "Legjobb kompatibilitás ",
|
||||
"legacy_title": "Hagyomány",
|
||||
"co_sign_transaction": "Egy tranzakció aláírása",
|
||||
"what_is_vault": "A Trezor egy",
|
||||
"what_is_vault_wallet": "tárca",
|
||||
"vault_advanced_customize": "Trezor beállítások",
|
||||
"needs": "szükséges",
|
||||
"what_is_vault_description_number_of_vault_keys": "{m} trezor kulcsok",
|
||||
"of": "/",
|
||||
"wallet_type": "Tárca típusa",
|
||||
"view_key": "megnéz",
|
||||
"invalid_cosigner": "Helytelen társ aláíró adat",
|
||||
"create_new_key": "Készíts újat",
|
||||
"scan_or_open_file": "Szkennelés vagy fájl megnyitása",
|
||||
"i_have_mnemonics": "Megvan a jelszó sorozatom ehhez a kulcshoz...",
|
||||
"i_wrote_it_down": "Rendben, leírtam!",
|
||||
"type_your_mnemonics": "Jelszó sorozat megadása egy létező trezor-kulcs megadásához",
|
||||
"view_edit_cosigners": "Társ aláírok megtekintése/szerkesztése ",
|
||||
"input_fp": "Ujjlenyomat megadása",
|
||||
"ms_help": "Segítség",
|
||||
"ms_help_title1": "Több eszköz használata javasolt.",
|
||||
"ms_help_title2": "Kulcsok szerkesztése",
|
||||
"ms_help_title5": "Haladó mód"
|
||||
},
|
||||
"is_it_my_address": {
|
||||
"title": "Ez a saját címem?",
|
||||
"owns": "{label} tulajdonolja {address}",
|
||||
"enter_address": "Cím megadása",
|
||||
"check_address": "Cím ellenőrzése"
|
||||
},
|
||||
"cc": {
|
||||
"change": "váltás",
|
||||
"coins_selected": "Kriptopénz kiválasztva ({number})",
|
||||
"empty": "Ez a tárca jelenleg üres.",
|
||||
"freeze": "zárolás",
|
||||
"freezeLabel": "zárolás",
|
||||
"freezeLabel_un": "Zárolás feloldása",
|
||||
"use_coin": "Cryptovaluta használata ",
|
||||
"use_coins": "Kriptopénz használata"
|
||||
},
|
||||
"units": {
|
||||
"BTC": "BTC",
|
||||
"MAX": "Maximum",
|
||||
"sat_byte": "sat/byte"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,9 @@ const setDateTimeLocale = async () => {
|
|||
case 'pl':
|
||||
require('dayjs/locale/pl');
|
||||
break;
|
||||
case 'ro':
|
||||
require('dayjs/locale/ro');
|
||||
break;
|
||||
case 'ru':
|
||||
require('dayjs/locale/ru');
|
||||
break;
|
||||
|
@ -190,6 +193,7 @@ const strings = new Localization({
|
|||
pt_br: require('./pt_br.json'),
|
||||
pt_pt: require('./pt_pt.json'),
|
||||
pl: require('./pl.json'),
|
||||
ro: require('./ro.json'),
|
||||
ru: require('./ru.json'),
|
||||
sk_sk: require('./sk_sk.json'),
|
||||
sl_si: require('./sl_SI.json'),
|
||||
|
|
|
@ -26,6 +26,7 @@ export const AvailableLanguages = Object.freeze([
|
|||
{ label: 'Polskie (PL)', value: 'pl' },
|
||||
{ label: 'Português (BR)', value: 'pt_br' },
|
||||
{ label: 'Português (PT)', value: 'pt_pt' },
|
||||
{ label: 'Română (RO)', value: 'ro' },
|
||||
{ label: 'Русский (RU)', value: 'ru' },
|
||||
{ label: 'Slovenský (SK)', value: 'sk_sk' },
|
||||
{ label: 'Slovenščina (SL)', value: 'sl_si' },
|
||||
|
|
168
loc/ro.json
Normal file
168
loc/ro.json
Normal file
|
@ -0,0 +1,168 @@
|
|||
{
|
||||
"_": {
|
||||
"bad_password": "Parolă incorectă. Încearcă din nou. ",
|
||||
"cancel": "Anulează",
|
||||
"continue": "Continuă",
|
||||
"enter_password": "Introdu parola",
|
||||
"never": "Niciodată",
|
||||
"of": "{number} din {total}",
|
||||
"ok": "OK",
|
||||
"storage_is_encrypted": "Spațiul tău de stocare este criptat. E necesară parola pentru decriptare.",
|
||||
"allow": "Permite",
|
||||
"dont_allow": "Nu permite",
|
||||
"yes": "Da",
|
||||
"no": "Nu",
|
||||
"save": "Salvează",
|
||||
"wallet_key": "Cheia portofelului",
|
||||
"invalid_animated_qr_code_fragment": "Fragment animat de QRCode invalid. Încearcă din nou.",
|
||||
"file_saved": "Fișierul ({filePath}) a fost salvat în folderul Downloads.",
|
||||
"discard_changes": "Renunți la modificări?",
|
||||
"discard_changes_detail": "Ai modificări nesalvate. Ești sigur că vrei să renunți la ele și să părăsești ecranul?"
|
||||
},
|
||||
"azteco": {
|
||||
"codeIs": "Voucher codul tău este",
|
||||
"errorBeforeRefeem": "Înainte de revendicare, trebuie mai întîi să adaugi un portofel Bitcoin.",
|
||||
"errorSomething": "Ceva nu a mers. Este acest voucher încă valid?",
|
||||
"redeem": "Revendică în portofel",
|
||||
"redeemButton": "Revendică",
|
||||
"success": "Succes",
|
||||
"title": "Revendică voucher Azte.co"
|
||||
},
|
||||
"entropy": {
|
||||
"save": "Salvează",
|
||||
"title": "Entropie",
|
||||
"undo": "Anulează"
|
||||
},
|
||||
"errors": {
|
||||
"broadcast": "Difuzare eșuată.",
|
||||
"error": "Eroare",
|
||||
"network": "Eroare de rețea"
|
||||
},
|
||||
"hodl": {
|
||||
"are_you_sure_you_want_to_logout": "Ești sigur că vrei să te deloghezi din Hodl Hodl?",
|
||||
"cont_address_escrow": "Escrow",
|
||||
"cont_address_to": "Către",
|
||||
"cont_buying": "Cumpărare",
|
||||
"cont_cancel": "Anulează contract",
|
||||
"cont_cancel_q": "Ești sigur că vrei să anulezi acest contract?",
|
||||
"cont_cancel_y": "Da, anulează contract",
|
||||
"cont_chat": "Deschide chat cu contrapartida",
|
||||
"cont_how": "Cum să plătești",
|
||||
"cont_no": "Nu ai niciun contract în desfășurare.",
|
||||
"cont_paid": "Marchează contractul ca plătit",
|
||||
"cont_paid_e": "Fă asta doar dacă ai trimis fonduri vînzătorului prin metoda de plată agreată.",
|
||||
"cont_paid_q": "Ești sigur că vrei să marchezi acest contract ca plătit?",
|
||||
"cont_selling": "Vînzare",
|
||||
"cont_st_completed": "Totul este gata!",
|
||||
"cont_st_in_progress_buyer": "Monedele sunt în escrow. Plătește vînzătorul.",
|
||||
"cont_st_paid_enought": "Bitcoinii sunt în escrow. Plătește vînzătorul prin metoda de plată agreată.",
|
||||
"cont_st_paid_waiting": "Se așteaptă ca vînzătorul să elibereze monedele din escrow",
|
||||
"cont_st_waiting": "Se așteaptă ca vînzătorul să depună bitcoinii în escrow",
|
||||
"cont_title": "Contractele mele",
|
||||
"filter_any": "Oricare",
|
||||
"filter_buying": "Cumpărare",
|
||||
"filter_country_global": "Oferte globale",
|
||||
"filter_currency": "Monedă",
|
||||
"filter_detail": "Detaliu",
|
||||
"filter_filters": "Filtre",
|
||||
"filter_iambuying": "Cumpăr bitcoin",
|
||||
"filter_iamselling": "Vînd bitcoin",
|
||||
"filter_method": "Metodă de plată",
|
||||
"filter_search": "Caută",
|
||||
"filter_selling": "Vînzare",
|
||||
"item_minmax": "Min/Max",
|
||||
"item_nooffers": "Nicio ofertă. Încearcă să schimbi \"În apropiere\" în \"Oferte Globale\"",
|
||||
"item_rating": "{rating} schimburi",
|
||||
"item_rating_no": "Niciun schimb",
|
||||
"local_trader": "Comerciant Local",
|
||||
"local_trader_new": "Nou",
|
||||
"login": "Logare",
|
||||
"logout": "Delogare",
|
||||
"mycont": "Contractele mele",
|
||||
"offer_accept": "Acceptă oferta",
|
||||
"offer_account_finish": "Se pare că nu ai terminat de configurat cont pe Hodl Hodl. Ai vrea să termini configuratul acum?",
|
||||
"offer_choosemethod": "Alege Metoda de Plată",
|
||||
"offer_confirmations": "confirmări",
|
||||
"offer_minmax": "Min/Max",
|
||||
"offer_minutes": "Min",
|
||||
"offer_promt_fiat": "Cît {currency} vrei să cumperi?",
|
||||
"offer_promt_fiat_e": "De exemplu, 100",
|
||||
"offer_window": "Fereastră",
|
||||
"p2p": "Cumpără bitcoin pe un exchange peer-to-peer"
|
||||
},
|
||||
"lnd": {
|
||||
"errorInvoiceExpired": "Factură expirată",
|
||||
"exchange": "Schimbă",
|
||||
"expired": "Expirat",
|
||||
"expiredLow": "Expirat",
|
||||
"expiresIn": "Expiră: {time}",
|
||||
"payButton": "Plătește",
|
||||
"placeholder": "Factură",
|
||||
"potentialFee": "Comision Potențial: {fee}",
|
||||
"refill": "Reumple",
|
||||
"refill_card": "Reumple cu Card Bancar",
|
||||
"refill_create": "Pentru a continua, crează un portofel Bitcoin cu care să reumpli.",
|
||||
"refill_external": "Reumple cu Portofel Extern",
|
||||
"refill_lnd_balance": "Reumple balanța portofelului Lightning",
|
||||
"sameWalletAsInvoiceError": "Nu poți plăti o factură cu același portofel folosit să o creeze.",
|
||||
"title": "Administrează fondurile"
|
||||
},
|
||||
"lndViewInvoice": {
|
||||
"additional_info": "Informații suplimentare",
|
||||
"for": "Pentru:",
|
||||
"lightning_invoice": "Factură Lightning",
|
||||
"has_been_paid": "Această factură Lightning a fost plătită.",
|
||||
"open_direct_channel": "Deschide canal direct cu acest nod:",
|
||||
"please_pay": "Plătește",
|
||||
"preimage": "Pre-imagine",
|
||||
"sats": "sats.",
|
||||
"wasnt_paid_and_expired": "Această factură nu a fost plătită și a expirat."
|
||||
},
|
||||
"plausibledeniability": {
|
||||
"create_fake_storage": "Crează Spațiu de Stocare Criptat",
|
||||
"create_password": "Crează o parolă",
|
||||
"create_password_explanation": "Parola pentru stocarea falsă nu trebuie să fie acceași cu parola pentru stocarea principală.",
|
||||
"help": "În anumite circumstanțe, ai putea fi forțat să spui parola. Pentru a-ți păstra monedele în siguranță, BlueWallet poate crea un alt spațiu de stocare cu o parolă diferită. Sub presiune, poți oferi această parolă unei entități terțe. Dacă e introdusă în BlueWallet, va debloca un nou spațiu de stocare \"fals\". Acest lucru va părea în regulă unei entități terțe, dar îți va păstra în siguranță spațiul de stocare secret cu monedele tale.",
|
||||
"help2": "Noul spațiu de stocare va fi complet funcțional, și poți păstra o cantitate minimă pentru a părea mai credibil. ",
|
||||
"password_should_not_match": "Parola este deja în folosință. Încearcă o parolă diferită.",
|
||||
"passwords_do_not_match": "Parolele nu sunt identice. Încearcă din nou.",
|
||||
"retype_password": "Re-introdu parola",
|
||||
"success": "Succes",
|
||||
"title": "Negare plauzibilă"
|
||||
},
|
||||
"pleasebackup": {
|
||||
"ask": "Ai salvat cuvintele de rezervă ale portofelului tău? Aceste cuvinte de rezervă sunt necesare pentru a-ți accesa fondurile în cazul în care îți pierzi dispozitivul. Fără cuvintele de rezervă, fondurile tale vor fi permanent pierdute.",
|
||||
"ask_no": "Nu, nu am făcut asta",
|
||||
"ask_yes": "Da, am făcut asta",
|
||||
"ok": "Ok, am notat acestea.",
|
||||
"ok_lnd": "Ok, am salvat,",
|
||||
"text": "Notează această frază mnemonică pe o hîrtie. Este copia de rezervă pe care o poți folosi să restabilești portofelul pe alt dispozitiv. ",
|
||||
"text_lnd": "Salvează această copie de rezervă a portofelului. Îți permite să restabilești portofelul în cazul unei pierderi.",
|
||||
"text_lnd2": "Acest portofel este găzduit de BlueWallet.",
|
||||
"title": "Portofelul tău a fost creat."
|
||||
},
|
||||
"receive": {
|
||||
"details_create": "Crează",
|
||||
"details_label": "Descriere",
|
||||
"details_share": "Distribuie",
|
||||
"header": "Primește"
|
||||
},
|
||||
"send": {
|
||||
"broadcastButton": "Difuzează",
|
||||
"broadcastError": "Eroare",
|
||||
"broadcastNone": "Introdu hex-ul tranzacției",
|
||||
"broadcastPending": "În așteptare",
|
||||
"broadcastSuccess": "Succes",
|
||||
"confirm_header": "Confirmă",
|
||||
"confirm_sendNow": "Trimite acum",
|
||||
"create_amount": "Cantitate",
|
||||
"create_broadcast": "Difuzează",
|
||||
"create_copy": "Copiază și difuzează mai tîrziu",
|
||||
"create_details": "Detalii",
|
||||
"create_fee": "Comision",
|
||||
"create_memo": "Memo",
|
||||
"create_satoshi_per_byte": "Satoshi per byte",
|
||||
"create_this_is_hex": "Acesta este hex-ul tranzacției tale - semnat și gata să fie difuzat către rețea.",
|
||||
"create_to": "Către"
|
||||
}
|
||||
}
|
20
loc/ru.json
20
loc/ru.json
|
@ -15,7 +15,7 @@
|
|||
"save": "Сохранить",
|
||||
"seed": "Сид-фраза",
|
||||
"wallet_key": "Ключ кошелька",
|
||||
"invalid_animated_qr_code_fragment" : "Ошибочный фрагмент QRCode, попробуйте снова",
|
||||
"invalid_animated_qr_code_fragment": "Ошибочный фрагмент QRCode, попробуйте снова",
|
||||
"file_saved": "Файл ({filePath}) сохранён в папке Загрузки.",
|
||||
"discard_changes": "Отменить изменения?",
|
||||
"discard_changes_detail": "У вас есть несохраненные изменения. Вы уверены, что хотите отменить их?"
|
||||
|
@ -137,7 +137,6 @@
|
|||
"ask_yes": "Да, я сохранил",
|
||||
"ok": "Я всё записал!",
|
||||
"ok_lnd": "Я всё сохранил.",
|
||||
"text": "Пожалуйста, запишите эту мнемоническую фразу на листе бумаги. Это ваша резервная копия, которую вы можете использовать для восстановления кошелька на другом устройстве.",
|
||||
"text_lnd": "Сохраните резервную копию кошелька. Это поможет восстановить его в случае потери.",
|
||||
"text_lnd2": "Кошелёк хранится на серверах BlueWallet.",
|
||||
"title": "Кошелёк создан"
|
||||
|
@ -180,7 +179,6 @@
|
|||
"details_amount_field_is_not_valid": "Введенная сумма неверна",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "Сумма слишком мала. Пожалуйста, введите сумму больше 500 сатоши.",
|
||||
"details_create": "Создать",
|
||||
"details_error_decode": "Ошибка: Нельзя декодировать Bitcoin адрес",
|
||||
"details_fee_field_is_not_valid": "Введенная комиссия неверна",
|
||||
"details_next": "Дальше",
|
||||
"details_no_maximum": "Этот кошелёк не поддерживает отправку всех средств. Ты уверен что хочешь выбрать его?",
|
||||
|
@ -239,6 +237,7 @@
|
|||
"about_release_notes": "История изменений",
|
||||
"about_review": "Оставьте отзыв о нас",
|
||||
"about_selftest": "Запустить самодиагностику",
|
||||
"about_selftest_ok": "Все внутренние тестирование прошло успешно.\nКошелек работает отлично. ",
|
||||
"about_sm_github": "GitHub",
|
||||
"about_sm_discord": "Сервер Discord",
|
||||
"about_sm_telegram": "Telegram канал",
|
||||
|
@ -264,7 +263,7 @@
|
|||
"electrum_saved": "Ваши изменения были успешно сохранены. Для вступления изменений в силу может потребоваться перезагрузка.",
|
||||
"set_electrum_server_as_default": "Задать {server} как сервер electrum по умолчанию?",
|
||||
"set_lndhub_as_default": "Задать {url} как сервер LNDHub по умолчанию?",
|
||||
"electrum_settings": "Настройки Electrum",
|
||||
"electrum_settings_server": "Настройки Electrum",
|
||||
"electrum_settings_explain": "Очистите чтобы использовать по умолчанию",
|
||||
"electrum_status": "Статус",
|
||||
"electrum_clear_alert_title": "Очистить историю?",
|
||||
|
@ -273,6 +272,7 @@
|
|||
"electrum_clear_alert_ok": "Ок",
|
||||
"electrum_select": "Выбрать",
|
||||
"electrum_reset": "По умолчанию",
|
||||
"electrum_unable_to_connect": "Невозможно подключиться {сервер}.",
|
||||
"electrum_history": "История",
|
||||
"electrum_clear": "Очистить",
|
||||
"encrypt_decrypt": "Расшифровать хранилище",
|
||||
|
@ -301,7 +301,7 @@
|
|||
"network_electrum": "Electrum сервер",
|
||||
"not_a_valid_uri": "Неверный URI",
|
||||
"notifications": "Уведомления",
|
||||
"open_link_in_explorer" : "Посмотреть в эксплорере",
|
||||
"open_link_in_explorer": "Посмотреть в эксплорере",
|
||||
"password": "Пароль",
|
||||
"password_explain": "Придумай пароль для расшифровки хранилища",
|
||||
"passwords_do_not_match": "Пароли не совпадают",
|
||||
|
@ -317,7 +317,7 @@
|
|||
"retype_password": "Набери пароль повторно",
|
||||
"save": "Сохранить",
|
||||
"saved": "Сохранено",
|
||||
"success_transaction_broadcasted" : "Транзакция успешно транслирована в сеть!",
|
||||
"success_transaction_broadcasted": "Транзакция успешно транслирована в сеть!",
|
||||
"total_balance": "Баланс",
|
||||
"total_balance_explanation": "Показывать в виджетах общий баланс кошельков",
|
||||
"widgets": "Виджеты"
|
||||
|
@ -328,7 +328,6 @@
|
|||
"ask_me_later": "Спроси меня позже"
|
||||
},
|
||||
"transactions": {
|
||||
"cancel_explain": "Мы заменим эту транзакцию другой, которая платит вам и имеет более высокую комиссию. Это отменит предыдущую транзакцию. Это называется RBF - Replace By Fee.",
|
||||
"cancel_no": "Эту транзакцию не отменить",
|
||||
"cancel_title": "Отменить транзакцию (RBF)",
|
||||
"confirmations_lowercase": "{confirmations} подтверждений",
|
||||
|
@ -344,7 +343,7 @@
|
|||
"details_inputs": "Входы",
|
||||
"details_outputs": "Выходы",
|
||||
"details_received": "Получена",
|
||||
"transaction_note_saved":"Заметка о транзакции успешно сохранена.",
|
||||
"transaction_note_saved": "Заметка о транзакции успешно сохранена.",
|
||||
"details_show_in_block_explorer": "Показать транзакцию в блокчейне",
|
||||
"details_title": "Детали транзакци",
|
||||
"details_to": "Кому",
|
||||
|
@ -358,7 +357,6 @@
|
|||
"status_bump": "Повысить комиссию",
|
||||
"status_cancel": "Отменить транзакцию",
|
||||
"transactions_count": "кол-во транзакций",
|
||||
"txid": "Txid",
|
||||
"updating": "Обновление..."
|
||||
},
|
||||
"wallets": {
|
||||
|
@ -410,7 +408,6 @@
|
|||
"export_title": "Экспорт Кошелька",
|
||||
"import_do_import": "Импортировать",
|
||||
"import_error": "Не удалось импортировать",
|
||||
"import_explanation": "Напиши тут свою мнемоническую фразу, приватный ключ, WIF - что угодно! BlueWallet постарается угадать верный формат",
|
||||
"import_file": "Импортировать файл",
|
||||
"import_imported": "Импорт завершен",
|
||||
"import_placeholder_fail": "Импортированный кошелёк",
|
||||
|
@ -423,7 +420,6 @@
|
|||
"list_create_a_wallet_text": "Это бесплатно и ты можешь создать\nнеограниченное количество",
|
||||
"list_empty_txs1": "Список транзакций пока пуст",
|
||||
"list_empty_txs1_lightning": "Lightning кошелек отлично подходит для ежедневных транзакций. Комиссия несправедливо мала, а скорость невероятно высока.",
|
||||
"list_empty_txs2": "Пока транзакций нет ",
|
||||
"list_empty_txs2_lightning": "\nДля начала использования нажми \"Мои средства\" и пополни баланс.",
|
||||
"list_header": "Кошелек - пара ключей, один приватный, другой - публичный используется, чтобы получить Bitcoin.",
|
||||
"list_import_error": "При импорте этого кошелька возникла ошибка.",
|
||||
|
@ -450,7 +446,6 @@
|
|||
"pull_to_refresh": "потяните, чтобы обновить",
|
||||
"warning_do_not_disclose": "Внимание! Не разглашать",
|
||||
"add_ln_wallet_first": "Сначала добавьте Лайтнинг кошелёк.",
|
||||
"identity_pubkey": "Identity Pubkey",
|
||||
"xpub_title": "XPUB кошелька"
|
||||
},
|
||||
"multisig": {
|
||||
|
@ -467,7 +462,6 @@
|
|||
"share": "Отправить",
|
||||
"view": "Посмотреть",
|
||||
"manage_keys": "Управление ключами",
|
||||
"how_many_signatures_can_bluewallet_make": "количество подписей, которое может сделать BlueWallet",
|
||||
"signatures_required_to_spend": "Необходимо {number} подписей ",
|
||||
"signatures_we_can_make": "можно сделать {number}",
|
||||
"scan_or_import_file": "Сканировать или импортировать файл",
|
||||
|
|
123
loc/zh_cn.json
123
loc/zh_cn.json
|
@ -15,7 +15,7 @@
|
|||
"save": "保存",
|
||||
"seed": "种子",
|
||||
"wallet_key": "钱包密钥",
|
||||
"invalid_animated_qr_code_fragment" : "无效的动态二维码,请重试",
|
||||
"invalid_animated_qr_code_fragment": "无效的动态二维码,请重试。",
|
||||
"file_saved": "文件({filePath})已保存在您的“下载”文件夹中。",
|
||||
"discard_changes": "放弃更变?",
|
||||
"discard_changes_detail": "您尚有未保存的更变。 您确定要丢弃它们并离开屏幕吗?"
|
||||
|
@ -32,7 +32,7 @@
|
|||
"entropy": {
|
||||
"save": "保存",
|
||||
"title": "随机熵值",
|
||||
"undo": "回退"
|
||||
"undo": "还原"
|
||||
},
|
||||
"errors": {
|
||||
"broadcast": "广播失败",
|
||||
|
@ -42,7 +42,7 @@
|
|||
"hodl": {
|
||||
"are_you_sure_you_want_to_logout": "您确定要登出Hodl Hodl吗?",
|
||||
"cont_address_escrow": "第三方托管",
|
||||
"cont_address_to": "发给",
|
||||
"cont_address_to": "至",
|
||||
"cont_buying": "买",
|
||||
"cont_cancel": "取消合约",
|
||||
"cont_cancel_q": "您确定要取消此合约吗?",
|
||||
|
@ -51,12 +51,12 @@
|
|||
"cont_how": "如何支付",
|
||||
"cont_no": "您没有任何合约在进行中。",
|
||||
"cont_paid": "将合约标记为已付款",
|
||||
"cont_paid_e": "只有当您向卖方透过已商定的付款方式汇款时,才这样做",
|
||||
"cont_paid_e": "如果您向卖方透过已商定的支付方式匯款的话,才这样做",
|
||||
"cont_paid_q": "您确定要将此合约标记为已付款吗?",
|
||||
"cont_selling": "卖",
|
||||
"cont_st_completed": "全部完成",
|
||||
"cont_st_in_progress_buyer": "您的币处于托管状态。 请向卖家付款。",
|
||||
"cont_st_paid_enought": "比特币处于托管状态。 请向卖家付款\n透过商定的付款方式。",
|
||||
"cont_st_completed": "全部完成!",
|
||||
"cont_st_in_progress_buyer": "您的币处于托管状态,请向卖家付款。",
|
||||
"cont_st_paid_enought": "您的比特币处于托管状态。 请向卖家付款\n透过商定的支付方式。",
|
||||
"cont_st_paid_waiting": "等待卖方从托管状态释放币",
|
||||
"cont_st_waiting": "等待卖方将比特币存入托管",
|
||||
"cont_title": "我的联系人",
|
||||
|
@ -68,11 +68,11 @@
|
|||
"filter_filters": "过滤器",
|
||||
"filter_iambuying": "我要买比特币",
|
||||
"filter_iamselling": "我要卖比特币",
|
||||
"filter_method": "支付方式",
|
||||
"filter_method": "支付方法",
|
||||
"filter_search": "搜索",
|
||||
"filter_selling": "卖",
|
||||
"item_minmax": "最小/最大",
|
||||
"item_nooffers": "没有报价。 尝试将「在我附近」更改为「全球报价」。",
|
||||
"item_nooffers": "没有报价。 尝试将”在我附近“更改为”全球报价“。",
|
||||
"item_rating": "{rating} 交易",
|
||||
"item_rating_no": "无评分",
|
||||
"local_trader": "当地交易员",
|
||||
|
@ -82,7 +82,7 @@
|
|||
"mycont": "我的合约",
|
||||
"offer_accept": "接受报价",
|
||||
"offer_account_finish": "您似乎尚未完成设置Hodl Hodl帐户。 您想现在完成设置吗?",
|
||||
"offer_choosemethod": "选择付款方式",
|
||||
"offer_choosemethod": "选择付款方法",
|
||||
"offer_confirmations": "确认",
|
||||
"offer_minmax": "最小 / 最大",
|
||||
"offer_minutes": "最小",
|
||||
|
@ -92,13 +92,13 @@
|
|||
"p2p": "在点对点交易所购买比特币"
|
||||
},
|
||||
"lnd": {
|
||||
"errorInvoiceExpired": "凭证已过期",
|
||||
"errorInvoiceExpired": "账单已过期",
|
||||
"exchange": "交易所",
|
||||
"expired": "已过期",
|
||||
"expiredLow": "已过期",
|
||||
"expiresIn": "过期:{time}",
|
||||
"payButton": "支付",
|
||||
"placeholder": "凭证",
|
||||
"placeholder": "账单",
|
||||
"potentialFee": "潜在费用:{fee}",
|
||||
"refill": "充值",
|
||||
"refill_card": "用银行卡充值",
|
||||
|
@ -113,31 +113,31 @@
|
|||
"for": "为了:",
|
||||
"lightning_invoice": "闪电账单",
|
||||
"has_been_paid": "该账单已支付。",
|
||||
"open_direct_channel": "使用此节点打开直接通道:",
|
||||
"open_direct_channel": "使用此节点来开啟直接频道:",
|
||||
"please_pay": "请支付",
|
||||
"preimage": "原像",
|
||||
"sats": "聰",
|
||||
"wasnt_paid_and_expired": "该账单尚未付款,已过期。"
|
||||
"sats": "聪",
|
||||
"wasnt_paid_and_expired": "此账单尚未支付,已过期。"
|
||||
},
|
||||
"plausibledeniability": {
|
||||
"create_fake_storage": "创建加密存储",
|
||||
"create_password": "创建密码",
|
||||
"create_password_explanation": "虚假存储空间密码不能和主存储空间密码相同",
|
||||
"help": "在某些情况下,你不得不暴露密码。为了让你的比特币更加安全,BlueWallet可以创建另一个用不同密码的加密空间,在压力之下,你可能暴露这个钱包密码。如果进入 BlueWallet,我们会解锁一个新的虚假储存空间。对第三方来说看上去是合理的,但会偷偷的帮你保证主钱包的安全,币也就安全了。",
|
||||
"help": "在某些情况下,你不得不暴露密码。为了让你的比特币更加安全,BlueWallet可以创建另一个用不同密码的加密空间,在压力之下,你可能暴露这个密码。如果进入 BlueWallet,我们会解锁一个新的虚假存储空间。对第三方来说看上去是合理的,但会偷偷的帮你保证主钱包的安全,币也就安全了。",
|
||||
"help2": "新的储存空间具备完整的功能,你可以存入少量的金额在里面。",
|
||||
"password_should_not_match": "此密码已被使用。请用另一个密码。",
|
||||
"passwords_do_not_match": "密码不匹配。 请再试一遍。",
|
||||
"password_should_not_match": "此密码已被使用,请用另一个密码。",
|
||||
"passwords_do_not_match": "密码不匹配,请再试一遍。",
|
||||
"retype_password": "重输密码",
|
||||
"success": "成功",
|
||||
"title": "合理推诿"
|
||||
},
|
||||
"pleasebackup": {
|
||||
"ask": "您是否保存了钱包的备份短语? 如果您丢失了此设备,则需要此备用短语来访问您的资金。 没有此备份短语,您的资金将永久丢失。",
|
||||
"ask": "您是否保存了钱包的备份短语? 如果您丢失了此设备,则需要此备份短语来访问您的资金。没有此备份短语,您的资金将永久丢失。",
|
||||
"ask_no": "不,我还没有",
|
||||
"ask_yes": "是的,已完成",
|
||||
"ask_yes": "是的,我完成了",
|
||||
"ok": "好的!我已抄下来!",
|
||||
"ok_lnd": "OK!我已保存好,",
|
||||
"text": "请将您的助记(备份)短语抄写于一张纸上。这些备份可以用来在别的设备或者软件上恢复这个钱包。",
|
||||
"text": "请花少许时间将您的助记(备份)短语抄写于一张纸上。这些备份可以用来在别的设备或者软件上恢复这个钱包。",
|
||||
"text_lnd": "请保存此钱包备份。这个备份可以在装置遗失时用来恢复此钱包。",
|
||||
"text_lnd2": "此钱包由BlueWallet托管。",
|
||||
"title": "你的钱包已创建。"
|
||||
|
@ -163,7 +163,7 @@
|
|||
"create_details": "详情",
|
||||
"create_fee": "手续费",
|
||||
"create_memo": "消息",
|
||||
"create_satoshi_per_byte": "葱每byte",
|
||||
"create_satoshi_per_byte": "聪 每byte",
|
||||
"create_this_is_hex": "这个是您的交易的十六进制码,已签署并准备好广播到网络。",
|
||||
"create_to": "到",
|
||||
"create_tx_size": "交易大小",
|
||||
|
@ -178,7 +178,7 @@
|
|||
"details_adv_full_sure": "您确定要使用钱包的全部余额进行此交易吗?",
|
||||
"details_adv_import": "汇入交易",
|
||||
"details_amount_field_is_not_valid": "金额无效",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "指定的金额太小。 请输入大于500聪 的金额。",
|
||||
"details_amount_field_is_less_than_minimum_amount_sat": "指定的金额太小,请输入大于500聪 的金额。",
|
||||
"details_create": "创建",
|
||||
"details_error_decode": "错误:无法解密比特币地址",
|
||||
"details_fee_field_is_not_valid": "费用无效",
|
||||
|
@ -188,7 +188,8 @@
|
|||
"details_no_signed_tx": "所选文件不包含可以导入的交易。",
|
||||
"details_note_placeholder": "给自己的备注",
|
||||
"details_scan": "扫描",
|
||||
"details_total_exceeds_balance": "余额不足",
|
||||
"details_total_exceeds_balance": "发送金额超过可用馀额",
|
||||
"details_unrecognized_file_format": "不能辨认的档案格式",
|
||||
"details_wallet_before_tx": "在创建一笔交易之前,您必须首先添加一个比特币钱包。",
|
||||
"details_wallet_selection": "选择钱包",
|
||||
"dynamic_init": "初始化中",
|
||||
|
@ -199,7 +200,7 @@
|
|||
"fee_10m": "10分钟",
|
||||
"fee_1d": "1日",
|
||||
"fee_3h": "3小时",
|
||||
"fee_custom": "自我风格",
|
||||
"fee_custom": "自选",
|
||||
"fee_fast": "快速",
|
||||
"fee_medium": "中等",
|
||||
"fee_replace_min": "您要支付的总费用(聪 每字节)应高于{min}聪 每字节。",
|
||||
|
@ -209,17 +210,17 @@
|
|||
"input_clear": "清除",
|
||||
"input_done": "完成",
|
||||
"input_paste": "粘贴",
|
||||
"input_total": "全部:",
|
||||
"input_total": "总计:",
|
||||
"permission_camera_message": "我们需要您的授权许可才能使用您的相机。",
|
||||
"permission_camera_title": "授权允许使用相机",
|
||||
"psbt_sign": "签署交易",
|
||||
"psbt_sign": "签署一笔交易",
|
||||
"open_settings": "打开设置",
|
||||
"permission_storage_later": "等会再问我",
|
||||
"permission_storage_later": "等会问我",
|
||||
"permission_storage_message": "BlueWallet需要您的授权许可才能访问您的存储空间以保存此文件。",
|
||||
"permission_storage_denied_message": "BlueWallet无法保存此文件。请打开设备设置并启用存储权限。",
|
||||
"permission_storage_denied_message": "BlueWallet无法保存此文件,请打开您的设备设置并启用存储权限。",
|
||||
"permission_storage_title": "存储访问权限",
|
||||
"psbt_clipboard": "复制到剪贴板",
|
||||
"psbt_this_is_psbt": "这是已部分签署的比特币交易(PSBT)。 请用您的硬体钱包完成签署。",
|
||||
"psbt_this_is_psbt": "这是已部分签署的比特币交易(PSBT),请用您的硬体钱包完成签署。",
|
||||
"psbt_tx_export": "导出到文件",
|
||||
"no_tx_signing_in_progress": "没有交易签署正在进行中。",
|
||||
"psbt_tx_open": "打开已签署的交易",
|
||||
|
@ -234,12 +235,12 @@
|
|||
"about": "关于",
|
||||
"about_awesome": "从很棒的创立",
|
||||
"about_backup": "始终备份您的密钥!",
|
||||
"about_free": "BlueWallet是一个免费的开源项目。 由比特币用户制作。",
|
||||
"about_license": "麻省理工学院执照",
|
||||
"about_release_notes": "发行说明",
|
||||
"about_free": "BlueWallet是一个免费的开源项目,由比特币用户制作。",
|
||||
"about_license": "麻省理工学院许可证",
|
||||
"about_release_notes": "发布说明",
|
||||
"about_review": "给我们评论",
|
||||
"about_selftest": "运行自检",
|
||||
"about_selftest_ok": "所有内部测试均已成功通过。 钱包很好用。",
|
||||
"about_selftest_ok": "所有内部测试均已成功通过,钱包运作良好。",
|
||||
"about_sm_github": "Github",
|
||||
"about_sm_discord": "Discord 服务器",
|
||||
"about_sm_telegram": "电报频道",
|
||||
|
@ -249,7 +250,7 @@
|
|||
"biom_10times": "您已尝试输入密码10次。 您想重置存储空间吗? 这将删除所有钱包并解密您的存储。",
|
||||
"biom_conf_identity": "请确认您的身份。",
|
||||
"biom_no_passcode": "您的设备没有密码。 为了继续进行,请在“设置”应用中配置密码。",
|
||||
"biom_remove_decrypt": "您的所有钱包将被删除,您的存储空间将被解密。 您确定要继续吗?",
|
||||
"biom_remove_decrypt": "您的所有钱包将被删除,您的存储空间将被解密。您确定要继续吗?",
|
||||
"currency": "货币",
|
||||
"currency_source": "由此获取价格:",
|
||||
"default_desc": "停用后,BlueWallet将在启动时立即打开选定的钱包。",
|
||||
|
@ -276,7 +277,7 @@
|
|||
"electrum_reset": "重置为默认",
|
||||
"electrum_unable_to_connect": "无法连接至 {server}。",
|
||||
"electrum_history": "服务器历史记录",
|
||||
"electrum_reset_to_default": "您确定要重设您的Electrum设定为预设吗?",
|
||||
"electrum_reset_to_default": "您确定要重置您的Electrum设置为默认值吗?",
|
||||
"electrum_clear": "清除",
|
||||
"encrypt_decrypt": "解密存储",
|
||||
"encrypt_decrypt_q": "您确定要解密存储吗? 这样一来,无需密码即可访问您的钱包。",
|
||||
|
@ -290,7 +291,7 @@
|
|||
"general_adv_mode": "进阶模式",
|
||||
"general_adv_mode_e": "启用后,您将看到进阶选项,例如不同的钱包类型、指定连接LNDHub进程的能力以及在创建钱包期间的自定义熵。",
|
||||
"general_continuity": "连续性",
|
||||
"general_continuity_e": "启用后,您将能够查看选定的钱包、交易及使用其他Apple iCloud连接的设备。",
|
||||
"general_continuity_e": "启用后,您将能够查看选定的钱包、交易及使用您其他Apple iCloud连接的设备。",
|
||||
"groundcontrol_explanation": "GroundControl是一款免费的开源推送通知服务器,用于比特币钱包。 您可以安装自己的GroundControl服务器并将其URL放在此处,而不依赖BlueWallet的基础结构。 保留空白以使用GroundControl的默认服务器。",
|
||||
"header": "设置",
|
||||
"language": "语言",
|
||||
|
@ -304,7 +305,7 @@
|
|||
"network_electrum": "Electrum服务器",
|
||||
"not_a_valid_uri": "无效的URI",
|
||||
"notifications": "通知事项",
|
||||
"open_link_in_explorer" : "在资源管理器中打开链接",
|
||||
"open_link_in_explorer": "在资源管理器中打开链接",
|
||||
"password": "密码",
|
||||
"password_explain": "创建密码,您将用此密码来解密储存空间",
|
||||
"passwords_do_not_match": "两个密码不同",
|
||||
|
@ -314,21 +315,21 @@
|
|||
"privacy_read_clipboard_alert": "BlueWallet 将显示用于处理剪贴板中账单或地址的捷径。",
|
||||
"privacy_system_settings": "系统设置",
|
||||
"privacy_quickactions": "钱包捷径",
|
||||
"privacy_quickactions_explanation": "触摸并按住主屏幕上的BlueWallet应用图标,以快速查看您的钱包余额。",
|
||||
"privacy_quickactions_explanation": "触碰并按住主屏幕上的BlueWallet应用图标,以快速查看您的钱包余额。",
|
||||
"privacy_clipboard_explanation": "如果在剪贴板中找到地址或发票,请提供捷径。",
|
||||
"push_notifications": "推送通知",
|
||||
"retype_password": "再次输入密码",
|
||||
"save": "保存",
|
||||
"saved": "已保存",
|
||||
"success_transaction_broadcasted" : "成功! 您的交易已广播!",
|
||||
"success_transaction_broadcasted": "成功! 您的交易已广播!",
|
||||
"total_balance": "总余额",
|
||||
"total_balance_explanation": "在主屏幕小部件上显示您所有钱包的总余额。",
|
||||
"widgets": "小部件"
|
||||
"total_balance_explanation": "在主屏幕小工具上显示您所有钱包的总余额。",
|
||||
"widgets": "小工具"
|
||||
},
|
||||
"notifications": {
|
||||
"would_you_like_to_receive_notifications": "您想在收到款项时得到通知吗?",
|
||||
"no_and_dont_ask": "不,不要再问我",
|
||||
"ask_me_later": "等会再问我"
|
||||
"ask_me_later": "待会问我"
|
||||
},
|
||||
"transactions": {
|
||||
"cancel_explain": "我们将以较高费用的交易取代此交易,这有效地取消此交易。 这称为RBF-按费用替换(Replace by Fee)。",
|
||||
|
@ -356,7 +357,7 @@
|
|||
"details_title": "转账",
|
||||
"details_to": "输出",
|
||||
"details_transaction_details": "交易详情",
|
||||
"enable_offline_signing": "此钱包未与线下签名结合使用。 您想立即启用它吗?",
|
||||
"enable_offline_signing": "此钱包未与线下签名结合使用。您想立即启用它吗?",
|
||||
"list_conf": "Conf: {number}",
|
||||
"pending": "待办",
|
||||
"list_title": "交易",
|
||||
|
@ -377,7 +378,7 @@
|
|||
"add_entropy_remain": "产生熵的{gen}个字节。 剩余的{rem}字节将从系统随机数生成器中获得。",
|
||||
"add_import_wallet": "导入钱包",
|
||||
"add_lightning": "闪电",
|
||||
"add_lightning_explain": "用于即时交易的消费",
|
||||
"add_lightning_explain": "用于即时交易的花费",
|
||||
"add_lndhub": "连接到您的LNDHub",
|
||||
"add_lndhub_error": "提供的节点地址不是有效的LNDHub节点。",
|
||||
"add_lndhub_placeholder": "您的节点地址",
|
||||
|
@ -385,19 +386,19 @@
|
|||
"add_title": "添加钱包",
|
||||
"add_wallet_name": "名称",
|
||||
"add_wallet_type": "类型",
|
||||
"clipboard_bitcoin": "您的剪贴板上有一个比特币地址。 您想使用它进行交易吗?",
|
||||
"clipboard_bitcoin": "您的剪贴板上有一个比特币地址。您想使用它进行交易吗?",
|
||||
"clipboard_lightning": "您的剪贴板上有一张闪电賬單。 您想使用它进行交易吗?",
|
||||
"details_address": "地址",
|
||||
"details_advanced": "先进的",
|
||||
"details_advanced": "进阶的",
|
||||
"details_are_you_sure": "你确认么?",
|
||||
"details_connected_to": "连接到",
|
||||
"details_del_wb": "钱包余额",
|
||||
"details_del_wb_err": "提供的余额与此钱包的余额不匹配。 请再试一遍。",
|
||||
"details_del_wb_q": "这个钱包有余额。 在继续操作之前,请注意,没有此钱包的种子(备份)短语,您将无法取回资金。 为了避免意外移除该钱包,请输入您的钱包余额{balance} 聰。",
|
||||
"details_del_wb_err": "提供的余额与此钱包的余额不匹配,请再试一遍。",
|
||||
"details_del_wb_q": "这个钱包有余额。 在继续操作之前,请注意,没有此钱包的种子(备份)短语,您将无法取回资金。 为了避免意外移除该钱包,请输入您的钱包余额{balance} 聪。",
|
||||
"details_delete": "删除",
|
||||
"details_delete_wallet": "删除钱包",
|
||||
"details_derivation_path": "推导路径",
|
||||
"details_display": "在电子钱包清单中显示",
|
||||
"details_display": "在钱包清单中显示",
|
||||
"details_export_backup": "导出/备份",
|
||||
"details_marketplace": "市场",
|
||||
"details_master_fingerprint": "主指纹",
|
||||
|
@ -410,7 +411,7 @@
|
|||
"details_show_xpub": "展示钱包公钥",
|
||||
"details_title": "钱包",
|
||||
"details_type": "类型",
|
||||
"details_use_with_hardware_wallet": "与硬件钱包一起使用",
|
||||
"details_use_with_hardware_wallet": "与硬体钱包一起使用",
|
||||
"details_wallet_updated": "钱包已更新",
|
||||
"details_yes_delete": "是的,删除",
|
||||
"enter_bip38_password": "输入密码进行解密",
|
||||
|
@ -421,15 +422,15 @@
|
|||
"import_file": "导入文件",
|
||||
"import_imported": "已经导入",
|
||||
"import_placeholder_fail": "钱包导入",
|
||||
"import_placeholder_inprogress": "导入电子钱包...",
|
||||
"import_placeholder_inprogress": "导入钱包...",
|
||||
"import_scan_qr": "扫描或导入一个档案",
|
||||
"import_success": "你的钱包已成功导入。",
|
||||
"import_title": "导入",
|
||||
"list_create_a_button": "现在添加",
|
||||
"list_create_a_wallet": "添加钱包",
|
||||
"list_create_a_wallet_text": "它是免费的,您可以创建\n喜欢多少就多少。",
|
||||
"list_create_a_wallet_text": "这是免费的,您可以创建\n喜欢多少就多少。",
|
||||
"list_empty_txs1": "你的交易将在这里展示",
|
||||
"list_empty_txs1_lightning": "应使用闪电钱包进行日常交易。 费用超便宜而且速度飞快。",
|
||||
"list_empty_txs1_lightning": "应使用闪电钱包进行日常交易。费用超便宜而且速度飞快。",
|
||||
"list_empty_txs2": "从你的钱包开始。",
|
||||
"list_empty_txs2_lightning": "\n要开始使用它,请点击“管理资金”并充值。",
|
||||
"list_header": "钱包代表一对密钥:一个是私钥,另一个是您可以共享以接收币(公钥)。",
|
||||
|
@ -453,7 +454,7 @@
|
|||
"select_no_bitcoin_exp": "需要一个比特币钱包来为闪电钱包充值。 请创建或导入一个。",
|
||||
"select_wallet": "选择钱包",
|
||||
"take_photo": "拍照",
|
||||
"xpub_copiedToClipboard": "复制到粘贴板.",
|
||||
"xpub_copiedToClipboard": "复制到粘贴板。",
|
||||
"pull_to_refresh": "拉动来刷新",
|
||||
"warning_do_not_disclose": "警告! 不要透露。",
|
||||
"add_ln_wallet_first": "您必须先添加一个闪电钱包。",
|
||||
|
@ -474,7 +475,7 @@
|
|||
"share": "分享",
|
||||
"view": "查看",
|
||||
"manage_keys": "管理密钥",
|
||||
"how_many_signatures_can_bluewallet_make": "多少私钥BluewWallet能够生成?",
|
||||
"how_many_signatures_can_bluewallet_make": "BlueWallet能够生成多少私钥?",
|
||||
"signatures_required_to_spend": "需要签名 {number}",
|
||||
"signatures_we_can_make": "可以使{number}",
|
||||
"scan_or_import_file": "扫描或导入文件",
|
||||
|
@ -483,10 +484,10 @@
|
|||
"lets_start": "开始吧",
|
||||
"create": "创建",
|
||||
"provide_key": "提供密钥",
|
||||
"native_segwit_title": "最佳实践",
|
||||
"native_segwit_title": "最佳做法",
|
||||
"wrapped_segwit_title": "最佳兼容性",
|
||||
"legacy_title": "旧制式",
|
||||
"co_sign_transaction": "签署交易",
|
||||
"co_sign_transaction": "签署一笔交易",
|
||||
"what_is_vault": "保管库是",
|
||||
"what_is_vault_numberOfWallets": "{m}-of-{n} 多重签名",
|
||||
"what_is_vault_wallet": "钱包。",
|
||||
|
@ -511,7 +512,7 @@
|
|||
"i_wrote_it_down": "好,我把它写下来了。",
|
||||
"type_your_mnemonics": "插入种子以导入现有的保管库密钥。",
|
||||
"this_is_cosigners_xpub": "这是共同签名者的公钥,可以导入另一个钱包。 分享是安全的。",
|
||||
"wallet_key_created": "您的保管库密钥已创建。 花点时间安全地备份您的助记符种子。",
|
||||
"wallet_key_created": "您的保管库密钥已创建。花点时间安全地备份您的助记符种子。",
|
||||
"are_you_sure_seed_will_be_lost": "你确定吗? 如果没有备份,助记符种子将丢失。",
|
||||
"forget_this_seed": "忘记此种子,而是使用公钥。",
|
||||
"invalid_fingerprint": "该种子的指纹与该共同签名者的指纹不匹配。",
|
||||
|
@ -558,7 +559,7 @@
|
|||
"units": {
|
||||
"BTC": "比特幣",
|
||||
"MAX": "最大",
|
||||
"sat_byte": "聰/字节 ",
|
||||
"sats": "聰"
|
||||
"sat_byte": "聪/字节",
|
||||
"sats": "聪"
|
||||
}
|
||||
}
|
||||
|
|
48
package-lock.json
generated
48
package-lock.json
generated
|
@ -5330,9 +5330,9 @@
|
|||
}
|
||||
},
|
||||
"@react-native-async-storage/async-storage": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.13.4.tgz",
|
||||
"integrity": "sha512-P7cbA77XNhUFEBKAIaex17mKI/Db1RQHZVwplagskqzEnpqB+Yi+/l8QeOMr5OJdfmPkBA+V7DOmuWeB8Po6cQ==",
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.14.1.tgz",
|
||||
"integrity": "sha512-UkLUox2q5DKNYB6IMUzsuwrTJeXGLySvtQlnrqd3fd+96JErCT4X3xD+W1cvQjes0nm0LbaELbwObKc+Tea7wA==",
|
||||
"requires": {
|
||||
"deep-assign": "^3.0.0"
|
||||
}
|
||||
|
@ -5763,9 +5763,9 @@
|
|||
}
|
||||
},
|
||||
"@react-navigation/drawer": {
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-5.12.3.tgz",
|
||||
"integrity": "sha512-I0aR/ULjFZcGick0u724YWxR0shTNhqctXdQnP7YFbOWML645EBS1LCtKgStfd9qd3sojHRSHIc7fReYa8bHfA==",
|
||||
"version": "5.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@react-navigation/drawer/-/drawer-5.12.4.tgz",
|
||||
"integrity": "sha512-0O6OCTgCVnThx0XFsHd/48i6FeV7vxNvJYxeucantcdCwQMWJb46cVMsYGFYt49VwE8VX4Yg/KMZXMPfPxn7Pg==",
|
||||
"requires": {
|
||||
"color": "^3.1.3",
|
||||
"react-native-iphone-x-helper": "^1.3.0"
|
||||
|
@ -5781,9 +5781,9 @@
|
|||
}
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
|
||||
"integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz",
|
||||
"integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==",
|
||||
"requires": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
|
@ -7469,6 +7469,19 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"bitcoinjs-message": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bitcoinjs-message/-/bitcoinjs-message-2.2.0.tgz",
|
||||
"integrity": "sha512-103Wy3xg8Y9o+pdhGP4M3/mtQQuUWs6sPuOp1mYphSUoSMHjHTlkj32K4zxU8qMH0Ckv23emfkGlFWtoWZ7YFA==",
|
||||
"requires": {
|
||||
"bech32": "^1.1.3",
|
||||
"bs58check": "^2.1.2",
|
||||
"buffer-equals": "^1.0.3",
|
||||
"create-hash": "^1.1.2",
|
||||
"secp256k1": "^3.0.1",
|
||||
"varuint-bitcoin": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"bl": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz",
|
||||
|
@ -7737,6 +7750,11 @@
|
|||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
||||
},
|
||||
"buffer-equals": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz",
|
||||
"integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U="
|
||||
},
|
||||
"buffer-fill": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
|
||||
|
@ -8732,9 +8750,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"detox": {
|
||||
"version": "18.6.0",
|
||||
"resolved": "https://registry.npmjs.org/detox/-/detox-18.6.0.tgz",
|
||||
"integrity": "sha512-jIoDH+G/wBsS0vWtIoCLIs7JIkJdGhMhv44iVZKnIwApesHtCghHUUpViDMlOLLaPmRdFxS7vRGz79WHLD/hwg==",
|
||||
"version": "18.6.2",
|
||||
"resolved": "https://registry.npmjs.org/detox/-/detox-18.6.2.tgz",
|
||||
"integrity": "sha512-p+qh6XBKapp1aPAUA/oa1wqjIi+bBthCE/WylfCnHOhmB3ZjaeloskS+8qpxCLtu6efcO6CoxLiD2aStjhn9/w==",
|
||||
"requires": {
|
||||
"bunyan": "^1.8.12",
|
||||
"bunyan-debug-stream": "^1.1.0",
|
||||
|
@ -8900,9 +8918,9 @@
|
|||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.6",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz",
|
||||
"integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA=="
|
||||
"version": "20.2.7",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
|
||||
"integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -71,13 +71,13 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-env": "7.12.1",
|
||||
"@react-native-async-storage/async-storage": "1.13.4",
|
||||
"@react-native-async-storage/async-storage": "1.14.1",
|
||||
"@react-native-clipboard/clipboard": "1.7.0",
|
||||
"@react-native-community/blur": "3.6.0",
|
||||
"@react-native-community/masked-view": "0.1.10",
|
||||
"@react-native-community/push-notification-ios": "1.8.0",
|
||||
"@react-native-community/slider": "3.0.3",
|
||||
"@react-navigation/drawer": "5.12.3",
|
||||
"@react-navigation/drawer": "5.12.4",
|
||||
"@react-navigation/native": "5.9.2",
|
||||
"@react-navigation/stack": "5.14.2",
|
||||
"@remobile/react-native-qrcode-local-image": "git+https://github.com/BlueWallet/react-native-qrcode-local-image.git",
|
||||
|
@ -94,13 +94,14 @@
|
|||
"bip32": "2.0.6",
|
||||
"bip39": "2.6.0",
|
||||
"bitcoinjs-lib": "5.2.0",
|
||||
"bitcoinjs-message": "2.2.0",
|
||||
"bolt11": "1.2.7",
|
||||
"buffer": "6.0.3",
|
||||
"buffer-reverse": "1.0.1",
|
||||
"coinselect": "3.1.12",
|
||||
"crypto-js": "3.1.9-1",
|
||||
"dayjs": "1.10.4",
|
||||
"detox": "18.6.0",
|
||||
"detox": "18.6.2",
|
||||
"ecurve": "1.0.6",
|
||||
"electrum-client": "git+https://github.com/BlueWallet/rn-electrum-client.git#f9a827e724a5a2e578fdfdb483f83793af55b030",
|
||||
"electrum-mnemonic": "2.0.0",
|
||||
|
|
|
@ -274,5 +274,5 @@ Selftest.propTypes = {
|
|||
};
|
||||
|
||||
Selftest.navigationOptions = navigationStyle({
|
||||
title: 'Self test',
|
||||
title: loc.settings.selfTest,
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ActivityIndicator, Alert, KeyboardAvoidingView, Linking, StyleSheet, Platform, TextInput, View } from 'react-native';
|
||||
import { ActivityIndicator, Alert, KeyboardAvoidingView, Linking, StyleSheet, Platform, TextInput, View, Keyboard } from 'react-native';
|
||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||
import { useRoute, useTheme, useNavigation } from '@react-navigation/native';
|
||||
import * as bitcoin from 'bitcoinjs-lib';
|
||||
|
@ -21,6 +21,7 @@ import {
|
|||
} from '../../BlueComponents';
|
||||
import BlueElectrum from '../../blue_modules/BlueElectrum';
|
||||
import Notifications from '../../blue_modules/notifications';
|
||||
|
||||
const scanqr = require('../../helpers/scan-qr');
|
||||
|
||||
const BROADCAST_RESULT = Object.freeze({
|
||||
|
@ -55,6 +56,7 @@ const Broadcast = () => {
|
|||
const handleUpdateTxHex = nextValue => setTxHex(nextValue.trim());
|
||||
|
||||
const handleBroadcast = async () => {
|
||||
Keyboard.dismiss();
|
||||
setBroadcastResult(BROADCAST_RESULT.pending);
|
||||
try {
|
||||
await BlueElectrum.ping();
|
||||
|
@ -73,7 +75,7 @@ const Broadcast = () => {
|
|||
setBroadcastResult(BROADCAST_RESULT.error);
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.alert(error.message);
|
||||
Alert.alert(loc.errors.error, error.message);
|
||||
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
|
||||
setBroadcastResult(BROADCAST_RESULT.error);
|
||||
}
|
||||
|
@ -140,6 +142,7 @@ const Broadcast = () => {
|
|||
placeholderTextColor="#81868e"
|
||||
value={txHex}
|
||||
onChangeText={handleUpdateTxHex}
|
||||
onSubmitEditing={Keyboard.dismiss}
|
||||
testID="TxHex"
|
||||
/>
|
||||
</View>
|
||||
|
@ -151,7 +154,7 @@ const Broadcast = () => {
|
|||
<BlueButton
|
||||
title={loc.send.broadcastButton}
|
||||
onPress={handleBroadcast}
|
||||
disabled={broadcastResult === BROADCAST_RESULT.pending}
|
||||
disabled={broadcastResult === BROADCAST_RESULT.pending || txHex?.length === 0 || txHex === undefined}
|
||||
testID="BroadcastButton"
|
||||
/>
|
||||
<BlueSpacing20 />
|
||||
|
@ -175,7 +178,6 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
blueArea: {
|
||||
flex: 1,
|
||||
paddingTop: 19,
|
||||
},
|
||||
broadcastResultWrapper: {
|
||||
flex: 1,
|
||||
|
|
|
@ -57,6 +57,7 @@ const SendDetails = () => {
|
|||
const navigation = useNavigation();
|
||||
const { name, params: routeParams } = useRoute();
|
||||
const scrollView = useRef();
|
||||
const scrollIndex = useRef(0);
|
||||
const { colors } = useTheme();
|
||||
|
||||
// state
|
||||
|
@ -68,7 +69,6 @@ const SendDetails = () => {
|
|||
const [isFeeSelectionModalVisible, setIsFeeSelectionModalVisible] = useState(false);
|
||||
const [optionsVisible, setOptionsVisible] = useState(false);
|
||||
const [isTransactionReplaceable, setIsTransactionReplaceable] = useState(false);
|
||||
const [recipientsScrollIndex, setRecipientsScrollIndex] = useState(0);
|
||||
const [addresses, setAddresses] = useState([]);
|
||||
const [units, setUnits] = useState([]);
|
||||
const [memo, setMemo] = useState('');
|
||||
|
@ -137,7 +137,7 @@ const SendDetails = () => {
|
|||
if (routeParams.uri) {
|
||||
try {
|
||||
const { address, amount, memo, payjoinUrl } = DeeplinkSchemaMatch.decodeBitcoinUri(routeParams.uri);
|
||||
addresses.push({ address, amount, amountSats: currency.btcToSatoshi(amount) });
|
||||
addresses.push({ address, amount, amountSats: currency.btcToSatoshi(amount), key: String(Math.random()) });
|
||||
initialMemo = memo;
|
||||
setAddresses(addresses);
|
||||
setMemo(initialMemo);
|
||||
|
@ -148,13 +148,13 @@ const SendDetails = () => {
|
|||
Alert.alert(loc.errors.error, loc.send.details_error_decode);
|
||||
}
|
||||
} else if (routeParams.address) {
|
||||
addresses.push({ address: routeParams.address });
|
||||
addresses.push({ address: routeParams.address, key: String(Math.random()) });
|
||||
if (routeParams.memo) initialMemo = routeParams.memo;
|
||||
setAddresses(addresses);
|
||||
setMemo(initialMemo);
|
||||
setAmountUnit(BitcoinUnit.BTC);
|
||||
} else {
|
||||
setAddresses([{ address: '' }]);
|
||||
setAddresses([{ address: '', key: String(Math.random()) }]);
|
||||
}
|
||||
|
||||
// we are ready!
|
||||
|
@ -343,8 +343,8 @@ const SendDetails = () => {
|
|||
const unitsCopy = [...units];
|
||||
const dataWithoutSchema = data.replace('bitcoin:', '').replace('BITCOIN:', '');
|
||||
if (wallet.isAddressValid(dataWithoutSchema)) {
|
||||
recipients[recipientsScrollIndex].address = dataWithoutSchema;
|
||||
unitsCopy[recipientsScrollIndex] = amountUnit;
|
||||
recipients[scrollIndex.current].address = dataWithoutSchema;
|
||||
unitsCopy[scrollIndex.current] = amountUnit;
|
||||
setAddresses(recipients);
|
||||
setUnits(unitsCopy);
|
||||
setIsLoading(false);
|
||||
|
@ -368,10 +368,10 @@ const SendDetails = () => {
|
|||
|
||||
console.log('options', options);
|
||||
if (btcAddressRx.test(address) || address.startsWith('bc1') || address.startsWith('BC1')) {
|
||||
unitsCopy[recipientsScrollIndex] = BitcoinUnit.BTC; // also resetting current unit to BTC
|
||||
recipients[recipientsScrollIndex].address = address;
|
||||
recipients[recipientsScrollIndex].amount = options.amount;
|
||||
recipients[recipientsScrollIndex].amountSats = new BigNumber(options.amount).multipliedBy(100000000).toNumber();
|
||||
unitsCopy[scrollIndex.current] = BitcoinUnit.BTC; // also resetting current unit to BTC
|
||||
recipients[scrollIndex.current].address = address;
|
||||
recipients[scrollIndex.current].amount = options.amount;
|
||||
recipients[scrollIndex.current].amountSats = new BigNumber(options.amount).multipliedBy(100000000).toNumber();
|
||||
setAddresses(recipients);
|
||||
setMemo(options.label || options.message);
|
||||
setUnits(unitsCopy);
|
||||
|
@ -755,24 +755,27 @@ const SendDetails = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const handleAddRecipient = () => {
|
||||
addresses.push({ address: '' });
|
||||
const handleAddRecipient = async () => {
|
||||
addresses.push({ address: '', key: String(Math.random()) }); // key is for the FlatList
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut, () => scrollView.current.scrollToEnd());
|
||||
setAddresses(addresses);
|
||||
setAddresses([...addresses]);
|
||||
setOptionsVisible(false);
|
||||
scrollView.current.scrollToEnd();
|
||||
if (addresses.length > 1) scrollView.current.flashScrollIndicators();
|
||||
setRecipientsScrollIndex(addresses.length - 1);
|
||||
if (addresses.length === 0) return;
|
||||
await sleep(200); // wait for animation
|
||||
scrollView.current.flashScrollIndicators();
|
||||
};
|
||||
|
||||
const handleRemoveRecipient = () => {
|
||||
addresses.splice(recipientsScrollIndex, 1);
|
||||
const handleRemoveRecipient = async () => {
|
||||
const last = scrollIndex.current === addresses.length - 1;
|
||||
addresses.splice(scrollIndex.current, 1);
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setAddresses(addresses);
|
||||
setAddresses([...addresses]);
|
||||
setOptionsVisible(false);
|
||||
if (addresses.length > 1) scrollView.current.flashScrollIndicators();
|
||||
// after deletion it automatically scrolls to the last one
|
||||
setRecipientsScrollIndex(addresses.length - 1);
|
||||
if (addresses.length === 0) return;
|
||||
await sleep(200); // wait for animation
|
||||
scrollView.current.flashScrollIndicators();
|
||||
if (last && Platform.OS === 'android') scrollView.current.scrollToEnd(); // fix white screen on android
|
||||
};
|
||||
|
||||
const handleCoinControl = () => {
|
||||
|
@ -832,14 +835,22 @@ const SendDetails = () => {
|
|||
setIsTransactionReplaceable(value);
|
||||
};
|
||||
|
||||
const scrollViewCurrentIndex = () => {
|
||||
Keyboard.dismiss();
|
||||
const offset = scrollView.current.contentOffset;
|
||||
if (offset) {
|
||||
const page = Math.round(offset.x / Dimensions.get('window').width);
|
||||
return page;
|
||||
}
|
||||
return 0;
|
||||
// because of https://github.com/facebook/react-native/issues/21718 we use
|
||||
// onScroll for android and onMomentumScrollEnd for iOS
|
||||
const handleRecipientsScrollEnds = e => {
|
||||
if (Platform.OS === 'android') return; // for android we use handleRecipientsScroll
|
||||
const contentOffset = e.nativeEvent.contentOffset;
|
||||
const viewSize = e.nativeEvent.layoutMeasurement;
|
||||
const index = Math.floor(contentOffset.x / viewSize.width);
|
||||
scrollIndex.current = index;
|
||||
};
|
||||
|
||||
const handleRecipientsScroll = e => {
|
||||
if (Platform.OS === 'ios') return; // for iOS we use handleRecipientsScrollEnds
|
||||
const contentOffset = e.nativeEvent.contentOffset;
|
||||
const viewSize = e.nativeEvent.layoutMeasurement;
|
||||
const index = Math.floor(contentOffset.x / viewSize.width);
|
||||
scrollIndex.current = index;
|
||||
};
|
||||
|
||||
const onUseAllPressed = () => {
|
||||
|
@ -852,7 +863,7 @@ const SendDetails = () => {
|
|||
text: loc._.ok,
|
||||
onPress: async () => {
|
||||
Keyboard.dismiss();
|
||||
const recipient = addresses[scrollViewCurrentIndex()];
|
||||
const recipient = addresses[scrollIndex.current];
|
||||
recipient.amount = BitcoinUnit.MAX;
|
||||
recipient.amountSats = BitcoinUnit.MAX;
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
|
@ -1114,7 +1125,7 @@ const SendDetails = () => {
|
|||
{isLoading ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<BlueButton onPress={() => createTransaction()} title={loc.send.details_next} testID="CreateTransactionButton" />
|
||||
<BlueButton onPress={createTransaction} title={loc.send.details_next} testID="CreateTransactionButton" />
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
|
@ -1260,13 +1271,15 @@ const SendDetails = () => {
|
|||
scrollEnabled={addresses.length > 1}
|
||||
data={addresses}
|
||||
renderItem={renderBitcoinTransactionInfoFields}
|
||||
keyExtractor={(_item, index) => `${index}`}
|
||||
ref={scrollView}
|
||||
horizontal
|
||||
pagingEnabled
|
||||
removeClippedSubviews={false}
|
||||
onMomentumScrollBegin={Keyboard.dismiss}
|
||||
scrollIndicatorInsets={{ top: 0, left: 8, bottom: 0, right: 8 }}
|
||||
onMomentumScrollEnd={handleRecipientsScrollEnds}
|
||||
onScroll={handleRecipientsScroll}
|
||||
scrollEventThrottle={200}
|
||||
scrollIndicatorInsets={styles.scrollViewIndicator}
|
||||
contentContainerStyle={styles.scrollViewContent}
|
||||
/>
|
||||
<View style={[styles.memo, stylesHook.memo]}>
|
||||
|
@ -1338,6 +1351,12 @@ const styles = StyleSheet.create({
|
|||
scrollViewContent: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
scrollViewIndicator: {
|
||||
top: 0,
|
||||
left: 8,
|
||||
bottom: 0,
|
||||
right: 8,
|
||||
},
|
||||
modalContent: {
|
||||
padding: 22,
|
||||
borderTopLeftRadius: 16,
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
useWindowDimensions,
|
||||
SafeAreaView,
|
||||
findNodeHandle,
|
||||
useColorScheme,
|
||||
} from 'react-native';
|
||||
import { BlueHeaderDefaultMain, BlueTransactionListItem } from '../../BlueComponents';
|
||||
import WalletsCarousel from '../../components/WalletsCarousel';
|
||||
|
@ -28,6 +29,7 @@ import { useFocusEffect, useNavigation, useRoute, useTheme } from '@react-naviga
|
|||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import { isCatalyst, isMacCatalina, isTablet } from '../../blue_modules/environment';
|
||||
import BlueClipboard from '../../blue_modules/clipboard';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
|
||||
const A = require('../../blue_modules/analytics');
|
||||
const fs = require('../../blue_modules/fs');
|
||||
|
@ -35,6 +37,7 @@ const WalletsListSections = { CAROUSEL: 'CAROUSEL', LOCALTRADER: 'LOCALTRADER',
|
|||
|
||||
const WalletsList = () => {
|
||||
const walletsCarousel = useRef();
|
||||
const colorScheme = useColorScheme();
|
||||
const { wallets, pendingWallets, getTransactions, getBalance, refreshAllWalletTransactions, setSelectedWallet } = useContext(
|
||||
BlueStorageContext,
|
||||
);
|
||||
|
@ -78,7 +81,6 @@ const WalletsList = () => {
|
|||
useCallback(() => {
|
||||
verifyBalance();
|
||||
setSelectedWallet('');
|
||||
StatusBar.setBarStyle('default');
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []),
|
||||
);
|
||||
|
@ -442,7 +444,7 @@ const WalletsList = () => {
|
|||
|
||||
return (
|
||||
<View style={styles.root} onLayout={onLayout}>
|
||||
<StatusBar barStyle="default" />
|
||||
<StatusBar barStyle={colorScheme === 'dark' ? 'light-content' : 'dark-content'} backgroundColor="transparent" translucent />
|
||||
<View style={[styles.walletsListWrapper, stylesHook.walletsListWrapper]}>
|
||||
<SectionList
|
||||
onRefresh={onRefresh}
|
||||
|
@ -466,6 +468,7 @@ const WalletsList = () => {
|
|||
};
|
||||
|
||||
export default WalletsList;
|
||||
WalletsList.navigationOptions = navigationStyle({}, opts => ({ ...opts, title: '' }));
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
root: {
|
||||
|
|
|
@ -596,6 +596,16 @@ describe('BlueWallet UI Tests', () => {
|
|||
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
||||
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).typeText('0.0002\n');
|
||||
|
||||
await element(by.id('advancedOptionsMenuButton')).tap();
|
||||
await element(by.id('AddRecipient')).tap();
|
||||
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
|
||||
|
||||
// remove last output, check if second output is shown
|
||||
await element(by.id('advancedOptionsMenuButton')).tap();
|
||||
await element(by.id('RemoveRecipient')).tap();
|
||||
await yo('Transaction1');
|
||||
|
||||
// adding it again
|
||||
await element(by.id('advancedOptionsMenuButton')).tap();
|
||||
await element(by.id('AddRecipient')).tap();
|
||||
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
|
||||
|
@ -619,7 +629,7 @@ describe('BlueWallet UI Tests', () => {
|
|||
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
||||
assert.strictEqual(transaction.outs[0].value, 50000);
|
||||
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[1].script), 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
||||
assert.strictEqual(transaction.outs[1].value, 20000);
|
||||
assert.strictEqual(transaction.outs[1].value, 30000);
|
||||
|
||||
// now, testing sendMAX feature:
|
||||
|
||||
|
|
|
@ -84,4 +84,24 @@ describe('HDAezeedWallet', () => {
|
|||
aezeed._getNodePubkeyByIndex(1, 1).toString('hex'),
|
||||
);
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const aezeed = new HDAezeedWallet();
|
||||
aezeed.setSecret(
|
||||
'abstract rhythm weird food attract treat mosquito sight royal actor surround ride strike remove guilt catch filter summer mushroom protect poverty cruel chaos pattern',
|
||||
);
|
||||
assert.ok(await aezeed.validateMnemonicAsync());
|
||||
assert.ok(!(await aezeed.mnemonicInvalidPassword()));
|
||||
let signature;
|
||||
|
||||
// external address
|
||||
signature = aezeed.signMessage('vires is numeris', aezeed._getExternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'J9zF7mdGGdc/9HMlvor6Zl7ap1qseQpiBDJ4oaSpkzbQGGhdfkM6LHo6m9BV8o/BlqiQI1vuODaNlBFyeyIWgfE=');
|
||||
assert.strictEqual(aezeed.verifyMessage('vires is numeris', aezeed._getExternalAddressByIndex(0), signature), true);
|
||||
|
||||
// internal address
|
||||
signature = aezeed.signMessage('vires is numeris', aezeed._getInternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'KIda06aSswmo9NiAYNUBRADA9q1v39raSmHHVg56+thtah5xL7hVw/x+cZgydFNyel2bXfyGluJRaP1uRQfJtzo=');
|
||||
assert.strictEqual(aezeed.verifyMessage('vires is numeris', aezeed._getInternalAddressByIndex(0), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,132 +2,151 @@ import { HDLegacyP2PKHWallet } from '../../class';
|
|||
const assert = require('assert');
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
|
||||
it('Legacy HD (BIP44) works', async () => {
|
||||
if (!process.env.HD_MNEMONIC) {
|
||||
console.error('process.env.HD_MNEMONIC not set, skipped');
|
||||
return;
|
||||
}
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd.setSecret(process.env.HD_MNEMONIC);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
describe('Legacy HD (BIP44)', () => {
|
||||
it('works', async () => {
|
||||
if (!process.env.HD_MNEMONIC) {
|
||||
console.error('process.env.HD_MNEMONIC not set, skipped');
|
||||
return;
|
||||
}
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd.setSecret(process.env.HD_MNEMONIC);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
|
||||
assert.strictEqual(
|
||||
hd.getXpub(),
|
||||
'xpub6ByZUAv558PPheJgcPYHpxPLwz8M7TtueYMAik84NADeQcvbzS8W3WxxJ3C9NzfYkMoChiMAumWbeEvMWhTVpH75NqGv5c9wF3wKDbfQShb',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd.getXpub(),
|
||||
'xpub6ByZUAv558PPheJgcPYHpxPLwz8M7TtueYMAik84NADeQcvbzS8W3WxxJ3C9NzfYkMoChiMAumWbeEvMWhTVpH75NqGv5c9wF3wKDbfQShb',
|
||||
);
|
||||
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(0), '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(0), '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj');
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(0), '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(0), '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj');
|
||||
|
||||
assert.strictEqual(hd._getInternalWIFByIndex(0), 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb');
|
||||
assert.strictEqual(hd._getExternalWIFByIndex(0), 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH');
|
||||
assert.strictEqual(hd._getInternalWIFByIndex(0), 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb');
|
||||
assert.strictEqual(hd._getExternalWIFByIndex(0), 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH');
|
||||
|
||||
assert.ok(hd.getAllExternalAddresses().includes('186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj')); // not internal
|
||||
assert.ok(hd.getAllExternalAddresses().includes('186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj')); // not internal
|
||||
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
|
||||
'0316e84a2556f30a199541633f5dda6787710ccab26771b7084f4c9e1104f47667',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getInternalAddressByIndex(0)).toString('hex'),
|
||||
'02ad7b2216f3a2b38d56db8a7ee5c540fd12c4bbb7013106eff78cc2ace65aa002',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
|
||||
'0316e84a2556f30a199541633f5dda6787710ccab26771b7084f4c9e1104f47667',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getInternalAddressByIndex(0)).toString('hex'),
|
||||
'02ad7b2216f3a2b38d56db8a7ee5c540fd12c4bbb7013106eff78cc2ace65aa002',
|
||||
);
|
||||
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getExternalAddressByIndex(0)), "m/84'/0'/0'/0/0"); // wrong, FIXME
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getInternalAddressByIndex(0)), "m/84'/0'/0'/1/0"); // wrong, FIXME
|
||||
});
|
||||
|
||||
it('Legacy HD (BIP44) can create TX', async () => {
|
||||
if (!process.env.HD_MNEMONIC) {
|
||||
console.error('process.env.HD_MNEMONIC not set, skipped');
|
||||
return;
|
||||
}
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd.setSecret(process.env.HD_MNEMONIC);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
|
||||
const utxo = [
|
||||
{
|
||||
height: 554830,
|
||||
value: 10000,
|
||||
address: '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 0,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 10000,
|
||||
wif: 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 20000,
|
||||
address: '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 1,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 20000,
|
||||
wif: 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 30000,
|
||||
address: '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 2,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 30000,
|
||||
wif: 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 40000,
|
||||
address: '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 3,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 40000,
|
||||
wif: 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
];
|
||||
|
||||
let txNew = hd.createTransaction(
|
||||
utxo,
|
||||
[{ address: '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', value: 80000 }],
|
||||
1,
|
||||
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
|
||||
);
|
||||
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
|
||||
assert.strictEqual(tx.ins.length, 4);
|
||||
assert.strictEqual(tx.outs.length, 2);
|
||||
assert.strictEqual(tx.outs[0].value, 80000); // payee
|
||||
assert.strictEqual(tx.outs[1].value, 19330); // change
|
||||
let toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
|
||||
const changeAddress = bitcoin.address.fromOutputScript(tx.outs[1].script);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(hd.next_free_change_address_index), changeAddress);
|
||||
|
||||
// testing sendMax
|
||||
txNew = hd.createTransaction(
|
||||
utxo,
|
||||
[{ address: '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK' }],
|
||||
1,
|
||||
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
|
||||
);
|
||||
tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
|
||||
assert.strictEqual(tx.ins.length, 4);
|
||||
assert.strictEqual(tx.outs.length, 1);
|
||||
toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getExternalAddressByIndex(0)), "m/84'/0'/0'/0/0"); // wrong, FIXME
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getInternalAddressByIndex(0)), "m/84'/0'/0'/1/0"); // wrong, FIXME
|
||||
});
|
||||
|
||||
it('can create TX', async () => {
|
||||
if (!process.env.HD_MNEMONIC) {
|
||||
console.error('process.env.HD_MNEMONIC not set, skipped');
|
||||
return;
|
||||
}
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd.setSecret(process.env.HD_MNEMONIC);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
|
||||
const utxo = [
|
||||
{
|
||||
height: 554830,
|
||||
value: 10000,
|
||||
address: '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 0,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 10000,
|
||||
wif: 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 20000,
|
||||
address: '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 1,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 20000,
|
||||
wif: 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 30000,
|
||||
address: '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 2,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 30000,
|
||||
wif: 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
{
|
||||
height: 554830,
|
||||
value: 40000,
|
||||
address: '1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj',
|
||||
txId: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
vout: 3,
|
||||
txid: '4f65c8cb159585c00d4deba9c5b36a2bcdfb1399a561114dcf6f2d0c1174bc5f',
|
||||
amount: 40000,
|
||||
wif: 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb',
|
||||
confirmations: 1,
|
||||
txhex:
|
||||
'01000000000101e8d98effbb4fba4f0a89bcf217eb5a7e2f8efcae44f32ecacbc5d8cc3ce683c301000000171600148ba6d02e74c0a6e000e8b174eb2ed44e5ea211a6ffffffff0510270000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac204e0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac30750000000000001976a9144dc6cbf64df9ab106cee812c7501960b93e9217788ac409c0000000000001976a914bc2db6b74c8db9b188711dcedd511e6a305603f588ac204716000000000017a914e286d58e53f9247a4710e51232cce0686f16873c8702483045022100af3800cd8171f154785cf13f46c092f61c1668f97db432bb4e7ed7bc812a8c6d022051bddca1eaf1ad8b5f3bd0ccde7447e56fd3c8709e5906f02ec6326e9a5b2ff30121039a421d5eb7c9de6590ae2a471cb556b60de8c6b056beb907dbdc1f5e6092f58800000000',
|
||||
},
|
||||
];
|
||||
|
||||
let txNew = hd.createTransaction(
|
||||
utxo,
|
||||
[{ address: '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', value: 80000 }],
|
||||
1,
|
||||
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
|
||||
);
|
||||
let tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
|
||||
assert.strictEqual(tx.ins.length, 4);
|
||||
assert.strictEqual(tx.outs.length, 2);
|
||||
assert.strictEqual(tx.outs[0].value, 80000); // payee
|
||||
assert.strictEqual(tx.outs[1].value, 19330); // change
|
||||
let toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
|
||||
const changeAddress = bitcoin.address.fromOutputScript(tx.outs[1].script);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(hd.next_free_change_address_index), changeAddress);
|
||||
|
||||
// testing sendMax
|
||||
txNew = hd.createTransaction(
|
||||
utxo,
|
||||
[{ address: '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK' }],
|
||||
1,
|
||||
hd._getInternalAddressByIndex(hd.next_free_change_address_index),
|
||||
);
|
||||
tx = bitcoin.Transaction.fromHex(txNew.tx.toHex());
|
||||
assert.strictEqual(tx.ins.length, 4);
|
||||
assert.strictEqual(tx.outs.length, 1);
|
||||
toAddress = bitcoin.address.fromOutputScript(tx.outs[0].script);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
let signature;
|
||||
|
||||
// external address
|
||||
signature = hd.signMessage('vires is numeris', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'H5J8DbqvuBy8lqRW7+LTVrrtrsaqLSwRDyj+5XtCrZpdCgPlxKM4EKRD6qvdKeyEh1fiSfIVB/edPAum3gKcJZo=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getExternalAddressByIndex(0), signature), true);
|
||||
|
||||
// internal address
|
||||
signature = hd.signMessage('vires is numeris', hd._getInternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'H98hmvtyPFUbR6E5Tcsqmc+eSjlYhP2vy41Y6IyHS9DVKEI5n8VEMpIEDtvlMARVce96nOqbRHXo9nD05WXH/Eo=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getInternalAddressByIndex(0), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -104,4 +104,61 @@ describe('Bech32 Segwit HD (BIP84)', () => {
|
|||
// for UTXO with no metadata .getUTXOMetadata() should return an empty object
|
||||
assert.ok(Object.keys(hd.getUTXOMetadata('22222', 0)).length === 0);
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
const hd = new HDSegwitBech32Wallet();
|
||||
hd.setSecret(mnemonic);
|
||||
let signature;
|
||||
|
||||
// external address
|
||||
signature = hd.signMessage('vires is numeris', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'KGW4FfrptS9zV3UptUWxbEf65GhC2mCUz86G0GpN/H4MUC29Y5TsRhWGIqG2lettEpZXZETuc2yL+O7/UvDhxhM=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getExternalAddressByIndex(0), signature), true);
|
||||
|
||||
// internal address
|
||||
signature = hd.signMessage('vires is numeris', hd._getInternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'KJ5B9JkZ042FhtGeObU/MxLCzQWHbrpXNQxhfJj9wMboa/icLIIaAlsKaSkS27fZLvX3WH0qyj3aAaXscnWsfSw=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getInternalAddressByIndex(0), signature), true);
|
||||
|
||||
// multiline message
|
||||
signature = hd.signMessage('vires\nis\nnumeris', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'KFI22tlJVGq2HGQM5rcBtYu+Jq8oc7QyjSBP1ZQup3a/GEw1Khu2qFbL/iLzqw95wN22a/Tll1oMLdWxg9cWMYM=');
|
||||
assert.strictEqual(hd.verifyMessage('vires\nis\nnumeris', hd._getExternalAddressByIndex(0), signature), true);
|
||||
|
||||
// can't sign if address doesn't belong to wallet
|
||||
assert.throws(() => hd.signMessage('vires is numeris', '186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por'));
|
||||
|
||||
// can't verify wrong signature
|
||||
assert.throws(() => hd.verifyMessage('vires is numeris', hd._getInternalAddressByIndex(0), 'wrong signature'));
|
||||
|
||||
// can verify electrum message signature
|
||||
// bech32 segwit (p2wpkh)
|
||||
assert.strictEqual(
|
||||
hd.verifyMessage(
|
||||
'vires is numeris',
|
||||
'bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el',
|
||||
'Hya6IaZGbKF83eOmC5i1CX5V42Wqkf+eSMi8S+hvJuJrDmp5F56ivrHgAzcxNIShIpY2lJv76M2LB6zLV70KxWQ=',
|
||||
),
|
||||
true,
|
||||
);
|
||||
// p2sh-segwit (p2wpkh-p2sh)
|
||||
assert.strictEqual(
|
||||
hd.verifyMessage(
|
||||
'vires is numeris',
|
||||
'37VucYSaXLCAsxYyAPfbSi9eh4iEcbShgf',
|
||||
'IBm8XAd/NdWjjUBXr3pkXdVk1XQBHKPkBy4DCmSG0Ox4IKOLb1O+V7cTXPQ2vm3rcYquF+6iKSPJDiE1TPrAswY=',
|
||||
),
|
||||
true,
|
||||
);
|
||||
// legacy
|
||||
assert.strictEqual(
|
||||
hd.verifyMessage(
|
||||
'vires is numeris',
|
||||
'1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA',
|
||||
'IDNPawFev2E+W1xhHYi6NKuj7BY2Xe9qvXfddoWL4XZcPridoizzm8pda6jGEIwHlVYe4zrGhYqUR+j2hOsQxD8=',
|
||||
),
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,166 +1,185 @@
|
|||
import { SegwitP2SHWallet, SegwitBech32Wallet, HDSegwitP2SHWallet, HDLegacyP2PKHWallet, LegacyWallet } from '../../class';
|
||||
const assert = require('assert');
|
||||
|
||||
it('can create a Segwit HD (BIP49)', async function () {
|
||||
const mnemonic =
|
||||
'honey risk juice trip orient galaxy win situate shoot anchor bounce remind horse traffic exotic since escape mimic ramp skin judge owner topple erode';
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
|
||||
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
|
||||
assert.strictEqual(true, hd.validateMnemonic());
|
||||
describe('P2SH Segwit HD (BIP49)', () => {
|
||||
it('can create a wallet', async () => {
|
||||
const mnemonic =
|
||||
'honey risk juice trip orient galaxy win situate shoot anchor bounce remind horse traffic exotic since escape mimic ramp skin judge owner topple erode';
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
|
||||
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
|
||||
assert.strictEqual(true, hd.validateMnemonic());
|
||||
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
|
||||
'0348192db90b753484601aaf1e6220644ffe37d83a9a5feff32b4da43739f736be',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getInternalAddressByIndex(0)).toString('hex'),
|
||||
'03c107e6976d59e17490513fbed3fb321736b7231d24f3d09306c72714acf1859d',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
|
||||
'0348192db90b753484601aaf1e6220644ffe37d83a9a5feff32b4da43739f736be',
|
||||
);
|
||||
assert.strictEqual(
|
||||
hd._getPubkeyByAddress(hd._getInternalAddressByIndex(0)).toString('hex'),
|
||||
'03c107e6976d59e17490513fbed3fb321736b7231d24f3d09306c72714acf1859d',
|
||||
);
|
||||
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getExternalAddressByIndex(0)), "m/84'/0'/0'/0/0"); // wrong, FIXME
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getInternalAddressByIndex(0)), "m/84'/0'/0'/1/0"); // wrong, FIXME
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getExternalAddressByIndex(0)), "m/84'/0'/0'/0/0"); // wrong, FIXME
|
||||
assert.strictEqual(hd._getDerivationPathByAddress(hd._getInternalAddressByIndex(0)), "m/84'/0'/0'/1/0"); // wrong, FIXME
|
||||
|
||||
assert.strictEqual('L4MqtwJm6hkbACLG4ho5DF8GhcXdLEbbvpJnbzA9abfD6RDpbr2m', hd._getExternalWIFByIndex(0));
|
||||
assert.strictEqual(
|
||||
'ypub6WhHmKBmHNjcrUVNCa3sXduH9yxutMipDcwiKW31vWjcMbfhQHjXdyx4rqXbEtVgzdbhFJ5mZJWmfWwnP4Vjzx97admTUYKQt6b9D7jjSCp',
|
||||
hd.getXpub(),
|
||||
);
|
||||
});
|
||||
assert.strictEqual('L4MqtwJm6hkbACLG4ho5DF8GhcXdLEbbvpJnbzA9abfD6RDpbr2m', hd._getExternalWIFByIndex(0));
|
||||
assert.strictEqual(
|
||||
'ypub6WhHmKBmHNjcrUVNCa3sXduH9yxutMipDcwiKW31vWjcMbfhQHjXdyx4rqXbEtVgzdbhFJ5mZJWmfWwnP4Vjzx97admTUYKQt6b9D7jjSCp',
|
||||
hd.getXpub(),
|
||||
);
|
||||
});
|
||||
|
||||
it('can convert witness to address', () => {
|
||||
let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.strictEqual(address, '34ZVGb3gT8xMLT6fpqC6dNVqJtJmvdjbD7');
|
||||
address = SegwitP2SHWallet.witnessToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitP2SHWallet.witnessToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
it('can convert witness to address', () => {
|
||||
let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.strictEqual(address, '34ZVGb3gT8xMLT6fpqC6dNVqJtJmvdjbD7');
|
||||
address = SegwitP2SHWallet.witnessToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitP2SHWallet.witnessToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress('a914e286d58e53f9247a4710e51232cce0686f16873c87');
|
||||
assert.strictEqual(address, '3NLnALo49CFEF4tCRhCvz45ySSfz3UktZC');
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress('a914e286d58e53f9247a4710e51232cce0686f16873c87');
|
||||
assert.strictEqual(address, '3NLnALo49CFEF4tCRhCvz45ySSfz3UktZC');
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitP2SHWallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
|
||||
address = SegwitBech32Wallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.strictEqual(address, 'bc1quhnve8q4tk3unhmjts7ymxv8cd6w9xv8wy29uv');
|
||||
address = SegwitBech32Wallet.witnessToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.witnessToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8');
|
||||
assert.strictEqual(address, 'bc1quhnve8q4tk3unhmjts7ymxv8cd6w9xv8wy29uv');
|
||||
address = SegwitBech32Wallet.witnessToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.witnessToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress('00144d757460da5fcaf84cc22f3847faaa1078e84f6a');
|
||||
assert.strictEqual(address, 'bc1qf46hgcx6tl90snxz9uuy0742zpuwsnm27ysdh7');
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress('00144d757460da5fcaf84cc22f3847faaa1078e84f6a');
|
||||
assert.strictEqual(address, 'bc1qf46hgcx6tl90snxz9uuy0742zpuwsnm27ysdh7');
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = SegwitBech32Wallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
|
||||
address = LegacyWallet.scriptPubKeyToAddress('76a914d0b77eb1502c81c4093da9aa6eccfdf560cdd6b288ac');
|
||||
assert.strictEqual(address, '1L2bNMGRQQLT2AVUek4K9L7sn3SSMioMgE');
|
||||
address = LegacyWallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = LegacyWallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
});
|
||||
address = LegacyWallet.scriptPubKeyToAddress('76a914d0b77eb1502c81c4093da9aa6eccfdf560cdd6b288ac');
|
||||
assert.strictEqual(address, '1L2bNMGRQQLT2AVUek4K9L7sn3SSMioMgE');
|
||||
address = LegacyWallet.scriptPubKeyToAddress();
|
||||
assert.strictEqual(address, false);
|
||||
address = LegacyWallet.scriptPubKeyToAddress('trololo');
|
||||
assert.strictEqual(address, false);
|
||||
});
|
||||
|
||||
it('Segwit HD (BIP49) can generate addressess only via ypub', function () {
|
||||
const ypub = 'ypub6WhHmKBmHNjcrUVNCa3sXduH9yxutMipDcwiKW31vWjcMbfhQHjXdyx4rqXbEtVgzdbhFJ5mZJWmfWwnP4Vjzx97admTUYKQt6b9D7jjSCp';
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
hd._xpub = ypub;
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
|
||||
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
|
||||
});
|
||||
it('Segwit HD (BIP49) can generate addressess only via ypub', function () {
|
||||
const ypub = 'ypub6WhHmKBmHNjcrUVNCa3sXduH9yxutMipDcwiKW31vWjcMbfhQHjXdyx4rqXbEtVgzdbhFJ5mZJWmfWwnP4Vjzx97admTUYKQt6b9D7jjSCp';
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
hd._xpub = ypub;
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
|
||||
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
|
||||
});
|
||||
|
||||
it('can generate Segwit HD (BIP49)', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const hashmap = {};
|
||||
for (let c = 0; c < 1000; c++) {
|
||||
await hd.generate();
|
||||
const secret = hd.getSecret();
|
||||
if (hashmap[secret]) {
|
||||
throw new Error('Duplicate secret generated!');
|
||||
it('can generate Segwit HD (BIP49)', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const hashmap = {};
|
||||
for (let c = 0; c < 1000; c++) {
|
||||
await hd.generate();
|
||||
const secret = hd.getSecret();
|
||||
if (hashmap[secret]) {
|
||||
throw new Error('Duplicate secret generated!');
|
||||
}
|
||||
hashmap[secret] = 1;
|
||||
assert.ok(secret.split(' ').length === 12 || secret.split(' ').length === 24);
|
||||
}
|
||||
hashmap[secret] = 1;
|
||||
|
||||
const hd2 = new HDSegwitP2SHWallet();
|
||||
hd2.setSecret(hd.getSecret());
|
||||
assert.ok(hd2.validateMnemonic());
|
||||
});
|
||||
|
||||
it('can work with malformed mnemonic', () => {
|
||||
let mnemonic =
|
||||
'honey risk juice trip orient galaxy win situate shoot anchor bounce remind horse traffic exotic since escape mimic ramp skin judge owner topple erode';
|
||||
let hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
const seed1 = hd.getMnemonicToSeedHex();
|
||||
assert.ok(hd.validateMnemonic());
|
||||
|
||||
mnemonic = 'hell';
|
||||
hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
assert.ok(!hd.validateMnemonic());
|
||||
|
||||
// now, malformed mnemonic
|
||||
|
||||
mnemonic =
|
||||
' honey risk juice trip orient galaxy win !situate ;; shoot ;;; anchor Bounce remind\nhorse \n traffic exotic since escape mimic ramp skin judge owner topple erode ';
|
||||
hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
const seed2 = hd.getMnemonicToSeedHex();
|
||||
assert.strictEqual(seed1, seed2);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
});
|
||||
|
||||
it('can generate addressess based on xpub', async function () {
|
||||
const xpub = 'xpub6CQdfC3v9gU86eaSn7AhUFcBVxiGhdtYxdC5Cw2vLmFkfth2KXCMmYcPpvZviA89X6DXDs4PJDk5QVL2G2xaVjv7SM4roWHr1gR4xB3Z7Ps';
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd._xpub = xpub;
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(0), '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(0), '1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX');
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(1), '1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(1), '13CW9WWBsWpDUvLtbFqYziWBWTYUoQb4nU');
|
||||
assert.ok(hd.getAllExternalAddresses().includes('12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX')); // not internal
|
||||
});
|
||||
|
||||
it('can consume user generated entropy', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const zeroes = [...Array(32)].map(() => 0);
|
||||
await hd.generateFromEntropy(Buffer.from(zeroes));
|
||||
assert.strictEqual(
|
||||
hd.getSecret(),
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art',
|
||||
);
|
||||
});
|
||||
|
||||
it('can fullfill user generated entropy if less than 32 bytes provided', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const zeroes = [...Array(16)].map(() => 0);
|
||||
await hd.generateFromEntropy(Buffer.from(zeroes));
|
||||
const secret = hd.getSecret();
|
||||
assert.strictEqual(secret.startsWith('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon'), true);
|
||||
|
||||
let secretWithoutChecksum = secret.split(' ');
|
||||
secretWithoutChecksum.pop();
|
||||
secretWithoutChecksum = secretWithoutChecksum.join(' ');
|
||||
assert.strictEqual(
|
||||
secretWithoutChecksum.endsWith('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon'),
|
||||
false,
|
||||
);
|
||||
|
||||
assert.ok(secret.split(' ').length === 12 || secret.split(' ').length === 24);
|
||||
}
|
||||
});
|
||||
|
||||
const hd2 = new HDSegwitP2SHWallet();
|
||||
hd2.setSecret(hd.getSecret());
|
||||
assert.ok(hd2.validateMnemonic());
|
||||
});
|
||||
|
||||
it('can work with malformed mnemonic', () => {
|
||||
let mnemonic =
|
||||
'honey risk juice trip orient galaxy win situate shoot anchor bounce remind horse traffic exotic since escape mimic ramp skin judge owner topple erode';
|
||||
let hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
const seed1 = hd.getMnemonicToSeedHex();
|
||||
assert.ok(hd.validateMnemonic());
|
||||
|
||||
mnemonic = 'hell';
|
||||
hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
assert.ok(!hd.validateMnemonic());
|
||||
|
||||
// now, malformed mnemonic
|
||||
|
||||
mnemonic =
|
||||
' honey risk juice trip orient galaxy win !situate ;; shoot ;;; anchor Bounce remind\nhorse \n traffic exotic since escape mimic ramp skin judge owner topple erode ';
|
||||
hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
const seed2 = hd.getMnemonicToSeedHex();
|
||||
assert.strictEqual(seed1, seed2);
|
||||
assert.ok(hd.validateMnemonic());
|
||||
});
|
||||
|
||||
it('Legacy HD (BIP44) can generate addressess based on xpub', async function () {
|
||||
const xpub = 'xpub6CQdfC3v9gU86eaSn7AhUFcBVxiGhdtYxdC5Cw2vLmFkfth2KXCMmYcPpvZviA89X6DXDs4PJDk5QVL2G2xaVjv7SM4roWHr1gR4xB3Z7Ps';
|
||||
const hd = new HDLegacyP2PKHWallet();
|
||||
hd._xpub = xpub;
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(0), '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(0), '1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX');
|
||||
assert.strictEqual(hd._getExternalAddressByIndex(1), '1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5');
|
||||
assert.strictEqual(hd._getInternalAddressByIndex(1), '13CW9WWBsWpDUvLtbFqYziWBWTYUoQb4nU');
|
||||
assert.ok(hd.getAllExternalAddresses().includes('12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'));
|
||||
assert.ok(hd.getAllExternalAddresses().includes('1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5'));
|
||||
assert.ok(!hd.getAllExternalAddresses().includes('1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX')); // not internal
|
||||
});
|
||||
|
||||
it('can consume user generated entropy', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const zeroes = [...Array(32)].map(() => 0);
|
||||
await hd.generateFromEntropy(Buffer.from(zeroes));
|
||||
assert.strictEqual(
|
||||
hd.getSecret(),
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art',
|
||||
);
|
||||
});
|
||||
|
||||
it('can fullfill user generated entropy if less than 32 bytes provided', async () => {
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
const zeroes = [...Array(16)].map(() => 0);
|
||||
await hd.generateFromEntropy(Buffer.from(zeroes));
|
||||
const secret = hd.getSecret();
|
||||
assert.strictEqual(secret.startsWith('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon'), true);
|
||||
|
||||
let secretWithoutChecksum = secret.split(' ');
|
||||
secretWithoutChecksum.pop();
|
||||
secretWithoutChecksum = secretWithoutChecksum.join(' ');
|
||||
assert.strictEqual(
|
||||
secretWithoutChecksum.endsWith('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon'),
|
||||
false,
|
||||
);
|
||||
|
||||
assert.ok(secret.split(' ').length === 12 || secret.split(' ').length === 24);
|
||||
it('can sign and verify messages', async () => {
|
||||
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
||||
const hd = new HDSegwitP2SHWallet();
|
||||
hd.setSecret(mnemonic);
|
||||
let signature;
|
||||
|
||||
// external address
|
||||
signature = hd.signMessage('vires is numeris', hd._getExternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'JMgoRSlLLLw6mw/Gbbg8Uj3fACkIJ85CZ52T5ZQfBnpUBkz0myRju6Rmgvmq7ugytc4WyYbzdGEc3wufNbjP09g=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getExternalAddressByIndex(0), signature), true);
|
||||
|
||||
// internal address
|
||||
signature = hd.signMessage('vires is numeris', hd._getInternalAddressByIndex(0));
|
||||
assert.strictEqual(signature, 'I5WkniWTnJhTW74t3kTAkHq3HdiupTNgOZLpMp0hvUfAJw2HMuyRiNLl2pbNWobNCCrmvffSWM7IgkOBz/J9fYA=');
|
||||
assert.strictEqual(hd.verifyMessage('vires is numeris', hd._getInternalAddressByIndex(0), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -40,7 +40,7 @@ describe('Legacy wallet', () => {
|
|||
assert.strictEqual('1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB', bitcoin.address.fromOutputScript(tx.outs[0].script)); // to address
|
||||
});
|
||||
|
||||
it("throws error if you can 't create wallet from this entropy", async () => {
|
||||
it("throws error if you can't create wallet from this entropy", async () => {
|
||||
const l = new LegacyWallet();
|
||||
const zeroes = [...Array(32)].map(() => 0);
|
||||
await assert.rejects(async () => await l.generateFromEntropy(Buffer.from(zeroes)), {
|
||||
|
@ -68,4 +68,13 @@ describe('Legacy wallet', () => {
|
|||
assert.strictEqual(keyPair.privateKey.toString('hex').endsWith('00000000'), false);
|
||||
assert.strictEqual(keyPair.privateKey.toString('hex').endsWith('ffffffff'), false);
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const l = new LegacyWallet();
|
||||
l.setSecret('L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1'); // from bitcoinjs-message examples
|
||||
|
||||
const signature = l.signMessage('This is an example of a signed message.', l.getAddress());
|
||||
assert.strictEqual(signature, 'H9L5yLFjti0QTHhPyFrZCT1V/MMnBtXKmoiKDZ78NDBjERki6ZTQZdSMCtkgoNmp17By9ItJr8o7ChX0XxY91nk=');
|
||||
assert.strictEqual(l.verifyMessage('This is an example of a signed message.', l.getAddress(), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -36,4 +36,13 @@ describe('Segwit P2SH wallet', () => {
|
|||
assert.strictEqual(tx.outs.length, 1);
|
||||
assert.strictEqual('1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB', bitcoin.address.fromOutputScript(tx.outs[0].script)); // to address
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const l = new SegwitBech32Wallet();
|
||||
l.setSecret('L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1'); // from bitcoinjs-message examples
|
||||
|
||||
const signature = l.signMessage('This is an example of a signed message.', l.getAddress());
|
||||
assert.strictEqual(signature, 'J9L5yLFjti0QTHhPyFrZCT1V/MMnBtXKmoiKDZ78NDBjERki6ZTQZdSMCtkgoNmp17By9ItJr8o7ChX0XxY91nk=');
|
||||
assert.strictEqual(l.verifyMessage('This is an example of a signed message.', l.getAddress(), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,4 +37,13 @@ describe('Segwit P2SH wallet', () => {
|
|||
assert.strictEqual(tx.outs.length, 1);
|
||||
assert.strictEqual('1GX36PGBUrF8XahZEGQqHqnJGW2vCZteoB', bitcoin.address.fromOutputScript(tx.outs[0].script)); // to address
|
||||
});
|
||||
|
||||
it('can sign and verify messages', async () => {
|
||||
const l = new SegwitP2SHWallet();
|
||||
l.setSecret('L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1'); // from bitcoinjs-message examples
|
||||
|
||||
const signature = l.signMessage('This is an example of a signed message.', l.getAddress());
|
||||
assert.strictEqual(signature, 'I9L5yLFjti0QTHhPyFrZCT1V/MMnBtXKmoiKDZ78NDBjERki6ZTQZdSMCtkgoNmp17By9ItJr8o7ChX0XxY91nk=');
|
||||
assert.strictEqual(l.verifyMessage('This is an example of a signed message.', l.getAddress(), signature), true);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue