diff --git a/LightningCustodianWallet.test.js b/LightningCustodianWallet.test.js index 82f6ab47..0903baee 100644 --- a/LightningCustodianWallet.test.js +++ b/LightningCustodianWallet.test.js @@ -247,4 +247,69 @@ describe('LightningCustodianWallet', () => { assert.equal(lOld.balance - oldBalance, 1); assert.equal(lNew.balance, 0); }); + + it('can pay free amount (tip) invoice', async function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 100 * 1000; + if (!process.env.BLITZHUB) { + console.error('process.env.BLITZHUB not set, skipped'); + return; + } + + // fetchig invoice from tippin.me : + + const api = new Frisbee({ + baseURI: 'https://tippin.me', + }); + const res = await api.post('/lndreq/newinvoice.php', { + headers: { + Origin: 'https://tippin.me', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8', + 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + Accept: 'application/json, text/javascript, */*; q=0.01', + }, + body: 'userid=1188&username=overtorment&istaco=0&customAmnt=0&customMemo=', + }); + + let json; + let invoice; + if (res && res.body && (json = JSON.parse(res.body)) && json.message) { + invoice = json.message; + } else { + throw new Error('tippin.me problem: ' + JSON.stringify(res)); + } + + // --> use to pay specific invoice + // invoice = + // 'lnbc1pwrp35spp5z62nvj8yw6luq7ns4a8utpwn2qkkdwdt0ludwm54wjeazk2xv5wsdpu235hqurfdcsx7an9wf6x7undv4h8ggpgw35hqurfdchx6eff9p6nzvfc8q5scqzysxqyz5vqj8xq6wz6dezmunw6qxleuw67ensjnt3fldltrmmkvzurge0dczpn94fkwwh7hkh5wqrhsvfegtvhswn252hn6uw5kx99dyumz4v5n9sp337py2'; + + let l2 = new LightningCustodianWallet(); + l2.setSecret(process.env.BLITZHUB); + await l2.authorize(); + await l2.fetchTransactions(); + await l2.fetchBalance(); + let oldBalance = +l2.balance; + let txLen = l2.transactions_raw.length; + + let decoded = await l2.decodeInvoice(invoice); + assert.ok(decoded.payment_hash); + assert.ok(decoded.description); + assert.equal(+decoded.num_satoshis, 0); + + await l2.checkRouteInvoice(invoice); + + let start = +new Date(); + await l2.payInvoice(invoice, 3); + let end = +new Date(); + if ((end - start) / 1000 > 9) { + console.warn('payInvoice took', (end - start) / 1000, 'sec'); + } + + await l2.fetchTransactions(); + assert.equal(l2.transactions_raw.length, txLen + 1); + // transactions became more after paying an invoice + + await l2.fetchBalance(); + assert.equal(oldBalance - l2.balance, 3); + }); }); diff --git a/class/lightning-custodian-wallet.js b/class/lightning-custodian-wallet.js index 723deb05..9c0cacf7 100644 --- a/class/lightning-custodian-wallet.js +++ b/class/lightning-custodian-wallet.js @@ -102,9 +102,9 @@ export class LightningCustodianWallet extends LegacyWallet { this.secret = 'lndhub://' + json.login + ':' + json.password; } - async payInvoice(invoice) { + async payInvoice(invoice, freeAmount = 0) { let response = await this._api.post('/payinvoice', { - body: { invoice: invoice }, + body: { invoice: invoice, amount: freeAmount }, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json', diff --git a/loc/index.js b/loc/index.js index fa0f72e1..0dfe633c 100644 --- a/loc/index.js +++ b/loc/index.js @@ -30,7 +30,8 @@ let strings; locale === 'pt-pt' || locale === 'de-de' || locale === 'cs-cz' || - locale === 'th-th' + locale === 'th-th' || + locale === 'nl-nl' ) { locale = locale.replace('-', '_'); strings.setLanguage(locale); @@ -51,6 +52,7 @@ strings = new Localization({ de_de: require('./de_DE.js'), cs_cz: require('./cs_CZ.js'), th_th: require('./th_TH.js'), + nl_nl: require('./nl_NL.js'), }); strings.saveLanguage = lang => AsyncStorage.setItem(AppStorage.LANG, lang); diff --git a/loc/nl_NL.js b/loc/nl_NL.js new file mode 100644 index 00000000..132ee06f --- /dev/null +++ b/loc/nl_NL.js @@ -0,0 +1,215 @@ +module.exports = { + _: { + storage_is_encrypted: 'Uw opslag is versleuteld. Wachtwoord is vereist om het te ontcijferen', + enter_password: 'Voer wachtwoord in', + bad_password: 'Verkeerd wachtwoord, probeer opnieuw', + months_ago: 'maanden geleden', + days_ago: 'dagen geleden', + hours_ago: 'uur geleden', + minutes_ago: 'minuten geleden', + never: 'nooit', + }, + wallets: { + select_wallet: 'Selecteer portemonnee', + options: 'opties', + list: { + app_name: 'Blue Wallet', + title: 'portemonnees', + header: 'Een portemonnee vertegenwoordigt een geheime (privésleutel) en een adres' + 'dat u kunt delen om munten te ontvangen.', + add: 'Portemonnee toevoegen', + create_a_wallet: 'Portemonnee aanmaken', + create_a_wallet1: "Het is gratis en u kunt er", + create_a_wallet2: 'zoveel maken als u wilt', + latest_transaction: 'laatste transactie', + empty_txs1: 'Uw transacties verschijnen hier,', + empty_txs2: 'geen transacties op dit moment', + tap_here_to_buy: 'Klik hier om Bitcoin te kopen', + }, + reorder: { + title: 'Portemonnees opnieuw ordenen', + }, + add: { + title: 'portemonnee toevoegen', + description: + 'U kunt een back-up papieren portemonnee scannen (in WIF - Wallet Import Format) of een nieuwe portemonnee maken. Segwit-wallets worden standaard ondersteund.', + scan: 'Scannen', + create: 'Aanmaken', + label_new_segwit: 'Nieuwe SegWit', + label_new_lightning: 'Nieuwe Lightning', + wallet_name: 'portemonnee naam', + wallet_type: 'type', + or: 'of', + import_wallet: 'Portemonnee importeren', + imported: 'Geïmporteerd', + coming_soon: 'Komt binnenkort', + lightning: 'Lightning', + bitcoin: 'Bitcoin', + }, + details: { + title: 'Portemonnee', + address: 'Adres', + type: 'Type', + label: 'Label', + destination: 'bestemming', + description: 'beschrijving', + are_you_sure: 'Weet u het zeker?', + yes_delete: 'Ja, verwijderen', + no_cancel: 'Nee, annuleren', + delete: 'Verwijderen', + save: 'Opslaan', + delete_this_wallet: 'Verwijder deze portemonnee', + export_backup: 'Exporteren / back-up maken', + buy_bitcoin: 'Koop Bitcoin', + show_xpub: 'Toon portemonnee XPUB', + }, + export: { + title: 'portemonnee exporteren', + }, + xpub: { + title: 'portemonnee XPUB', + copiedToClipboard: 'Gekopieerd naar het klembord.', + }, + import: { + title: 'importeren', + explanation: + "Schrijf hier uw ezelsbruggetje, privésleutel, WIF, of een ander formaat. BlueWallet zal zijn best doen om het juiste formaat te raden en uw portemonnee te importeren", + imported: 'Geïmporteerd', + error: 'Importeren mislukt. Zorg ervoor dat de verstrekte gegevens geldig zijn.', + success: 'Succes', + do_import: 'Importeren', + scan_qr: 'of QR-code scannen?', + }, + scanQrWif: { + go_back: 'Ga terug', + cancel: 'Annuleren', + decoding: 'Decoderen', + input_password: 'Voer wachtwoord in', + password_explain: 'Dit is een BIP38-gecodeerde privésleutel', + bad_password: 'Verkeerd wachtwoord', + wallet_already_exists: 'Zo\'n portemonnee bestaat al', + bad_wif: 'Verkeerde WIF', + imported_wif: 'WIF geïmporteerd ', + with_address: ' met adres ', + imported_segwit: 'SegWit geïmporteerd', + imported_legacy: 'Legacy geïmporteerd', + imported_watchonly: 'Watch-only geïmporteerd', + }, + }, + transactions: { + list: { + tabBarLabel: 'Transacties', + title: 'transacties', + description: 'Een lijst met ingaande of uitgaande transacties van uw portemonnee', + conf: 'conf', + }, + details: { + title: 'Transacties', + from: 'Invoer', + to: 'Uitgang', + copy: 'Kopiëren', + transaction_details: 'Transactie details', + show_in_block_explorer: 'Weergeven in blokverkenner', + }, + }, + send: { + header: 'Vertuur', + details: { + title: 'transacties aanmaken', + amount_field_is_not_valid: 'Bedrag veld is niet geldig', + fee_field_is_not_valid: 'Tarief is niet geldig', + address_field_is_not_valid: 'Adresveld is niet geldig', + total_exceeds_balance: 'Het verzendingsbedrag overschrijdt het beschikbare saldo.', + create_tx_error: 'Er is een fout opgetreden bij het maken van de transactie. Zorg ervoor dat het adres geldig is.', + address: 'adres', + amount_placeholder: 'te verzenden bedrag (in BTC)', + fee_placeholder: 'plus transactie vergoeding (in BTC)', + note_placeholder: 'notitie voor mezelf', + cancel: 'Annuleren', + scan: 'Scannen', + send: 'Verzenden', + create: 'Aanmaken', + remaining_balance: 'Resterende saldo', + }, + confirm: { + header: 'Bevestig', + sendNow: 'Nu verzenden', + }, + success: { + done: 'Klaar', + }, + create: { + details: 'Details', + title: 'transactie aanmaken', + error: 'Fout bij het maken van transactie. Ongeldig adres of bedrag?', + go_back: 'Ga terug', + this_is_hex: 'Dit is de transactie-hex, ondertekend en klaar om op het netwerk te worden uitgezonden.', + to: 'Naar', + amount: 'Bedrag', + fee: 'Vergoeding', + tx_size: 'TX grootte', + satoshi_per_byte: 'Satoshi per byte', + memo: 'Memo', + broadcast: 'Uitzenden', + not_enough_fee: 'Niet genoeg vergoeding. Verhoog de vergoeding', + }, + }, + receive: { + header: 'Ontvang', + details: { + title: 'Deel dit adres met betaler', + share: 'delen', + copiedToClipboard: 'Gekopieerd naar het klembord.', + label: 'Omschrijving', + setAmount: 'Ontvang met bedrag', + }, + }, + buyBitcoin: { + header: 'Koop Bitcoin', + tap_your_address: 'Tik op uw adres om het naar het klembord te kopiëren:', + copied: 'Gekopieerd naar het klembord!', + }, + settings: { + header: 'instellingen', + plausible_deniability: 'Plausibele ontkenning...', + storage_not_encrypted: 'Opslag: niet versleuteld', + storage_encrypted: 'Opslag: versleuteld', + password: 'Wachtwoord', + password_explain: 'Maak een wachtwoord aan dat u wilt gebruiken om de opslag te versleutelen', + retype_password: 'Geef nogmaals het wachtwoord', + passwords_do_not_match: 'Wachtwoorden komen niet overeen', + encrypt_storage: 'Versleutel opslag', + about: 'Over', + language: 'Taal', + currency: 'Valuta', + }, + plausibledeniability: { + title: 'Plausibele ontkenning', + help: + 'Onder bepaalde omstandigheden kunt u worden gedwongen om uw' + + ' wachtwoord te onthullen. Om uw munten veilig te houden, kan ' + + 'BlueWallet nog een versleutelde opslag aanmaken, met een ander ' + + 'wachtwoord. Onder druk kunt u dit wachtwoord bekendmaken aan ' + + 'de derde partij. Indien ingevoerd in BlueWallet, zal het nieuwe ' + + "nep'-opslagruimte worden ontgrendeld. Dit lijkt legitiem voor de " + + 'derde partij, maar zal uw hoofdopslag met munten niet bekend maken ' + + 'aan de derde partij', + help2: 'De nieuwe opslag zal volledig functioneel zijn en u kunt er ' + 'een minimum aantal munten opslaan zodat het geloofwaardig lijkt.', + create_fake_storage: 'Nep versleutelde opslag aanmaken', + go_back: 'Ga terug', + create_password: 'Wachtwoord aanmaken', + create_password_explanation: 'Wachtwoord voor nep-opslag hoort niet overeen te komen met wachtwoord voor uw hoofdopslag', + password_should_not_match: 'Wachtwoord voor nep-opslag hoort niet overeen te komen met wachtwoord voor uw hoofdopslag', + retype_password: 'Herhaal wachtwoord', + passwords_do_not_match: 'Wachtwoorden komen niet overeen, probeer het opnieuw', + success: 'Succes', + }, + lnd: { + title: 'fondsen beheren', + choose_source_wallet: 'Kies een bron portemonnee', + refill_lnd_balance: 'Vul Lightning-portemonneesaldo bij', + refill: 'Bijvullen', + withdraw: 'Opvragen', + expired: 'Verlopen', + sameWalletAsInvoiceError: 'U kunt geen factuur betalen met dezelfde portemonnee die is gebruikt om de factuur te maken.', + }, +}; diff --git a/loc/pt_BR.js b/loc/pt_BR.js index ca2e5525..f043cdba 100644 --- a/loc/pt_BR.js +++ b/loc/pt_BR.js @@ -1,125 +1,125 @@ module.exports = { _: { - storage_is_encrypted: 'O armazenamento está encriptado. Uma password é necessaria para desencriptar', - enter_password: 'Inserir password', - bad_password: 'pasword errada, tentar novamente', + storage_is_encrypted: 'Os arquivos estão criptografados, é necessária uma senha', + enter_password: 'Inserir senha', + bad_password: 'Senha errada, tente outra vez', months_ago: 'meses atrás', days_ago: 'dias atrás', hours_ago: 'horas atrás', - minutes_ago: 'minutos', - never: 'nunca...', + minutes_ago: 'minutos atrás', + never: 'nunca', }, wallets: { - options: 'options', - select_wallet: 'Select Wallet', + options: 'opções', + select_wallet: 'Escolher carteira', list: { - tabBarLabel: 'Wallets', + tabBarLabel: 'Carteiras', app_name: 'Blue Wallet', - title: 'Wallets', - header: 'Uma wallet representa um par entre um segredo (chave privada) e um endereço' + 'que pode partilhar para receber Bitcoin.', + title: 'carteiras', + header: 'Uma carteira representa um par composto de uma chave privada e um endereço que você pode .', add: 'adicionar wallet', - create_a_wallet: 'Criar uma wallet', - create_a_wallet1: 'Gratuito e pode criar', - create_a_wallet2: ' quantas quiser', + create_a_wallet: 'Criar uma carteira', + create_a_wallet1: 'é grátis e você pode criar', + create_a_wallet2: 'quantas você quiser', latest_transaction: 'última transação', - empty_txs1: 'Suas transações aparecerão aqui', - empty_txs2: 'nenhuma de momento', - tap_here_to_buy: 'Tap here to buy Bitcoin', + empty_txs1: 'Suas transações aparecerão aqui,', + empty_txs2: 'nenhuma no momento', + tap_here_to_buy: 'Toque aqui para comprar Bitcoin', }, reorder: { - title: 'Reorder Wallets', + title: 'Reordenar carteiras', }, add: { - title: 'Adicionar Wallet', + title: 'criando carteira', description: - 'Pode fazer um scaneamento de um backup de uma wallet em papel (em WIF - Wallet Import Format), ou criar uma nova wallet. Segwit suportado por defeito.', - scan: 'Scanear', + 'Você pode ler o backup de uma carteira (em WIF - Wallet Import Format) ou criar uma nova. O padrão é criar uma carteira SegWit.', + scan: 'Ler backup', create: 'Criar', - label_new_segwit: 'Novo SegWit', - label_new_lightning: 'Novo Lightning', - wallet_name: 'Nome', - wallet_type: 'Tipo', + label_new_segwit: 'Nova carteira SegWit', + label_new_lightning: 'Nova carteira Lightning', + wallet_name: 'nome', + wallet_type: 'tipo', or: 'ou', - import_wallet: 'Importar wallet', + import_wallet: 'Importar carteira', imported: 'Importado', - coming_soon: 'Brevemente', + coming_soon: 'Em breve', lightning: 'Lightning', bitcoin: 'Bitcoin', }, details: { - title: 'wallet', + title: 'Carteira', address: 'Endereço', type: 'Tipo', - destination: 'destination', - description: 'description', + destination: 'destino', + description: 'descrição', label: 'Nome', - are_you_sure: 'Tem a certeza?', - yes_delete: 'Sim, eliminar', + are_you_sure: 'Tem certeza?', + yes_delete: 'Sim, apagar', no_cancel: 'Não, cancelar', - delete_this_wallet: 'Apagar esta wallet', + delete_this_wallet: 'Apagar esta carteira', export_backup: 'Exportar / backup', - buy_bitcoin: 'Buy Bitcoin', - show_xpub: 'Show wallet XPUB', - delete: 'Delete', - save: 'Save', + buy_bitcoin: 'Comprar Bitcoin', + show_xpub: 'Ver XPUB', + delete: 'Apagar', + save: 'Salvar', }, export: { - title: 'Exportar Wallet', + title: 'Exportar carteira', }, xpub: { - title: 'wallet XPUB', - copiedToClipboard: 'copiado para clip board', + title: 'XPUB', + copiedToClipboard: 'Copiado para a área de transferência', }, import: { title: 'importar', explanation: - 'Escreva aqui sua frase mnemônica, chave privada, WIF, etc. Vamos fazer nosso melhor para importat a sua wallet em qualquer formato', + 'Escreva aqui sua frase mnemônica, chave privada, WIF, ou o que você tiver. Faremos nosso melhor para adivinhar o formato e importat sua carteira', imported: 'Importada', - error: 'Falhou. é um formato válido?', + error: 'Erro. Por favor, confira se o formato que você passou é válido.', success: 'Sucesso', do_import: 'Importar', - scan_qr: 'ou scan um QR code?', + scan_qr: 'ou ler um código QR?', }, scanQrWif: { go_back: 'Voltar', cancel: 'Cancelar', - decoding: 'Descodificar', - input_password: 'Inserir password', - password_explain: 'Isto é um BIP38 chave privada encriptada', - bad_password: 'Password errada', - wallet_already_exists: 'Esta wallet já existe', + decoding: 'Decodificar', + input_password: 'Inserir senha', + password_explain: 'Isto é um chave privada criptografada BIP38', + bad_password: 'Senha errada', + wallet_already_exists: 'Esta carteira já existe', bad_wif: 'WIF errado', - imported_wif: 'WIF transferido ', + imported_wif: 'WIF importado ', with_address: ' com endereço ', - imported_segwit: 'SegWit transferido', - imported_legacy: 'Legacy transferido', - imported_watchonly: 'Watch-only importada', + imported_segwit: 'Carteira SegWit importada', + imported_legacy: 'Carteira antiga importada', + imported_watchonly: 'Carteira somente-leitura importada', }, }, transactions: { list: { tabBarLabel: 'Transações', title: 'Transações', - description: 'Uma lista de transações feitas ou recebidas nas suas wallets', + description: 'Uma lista de transações feitas ou recebidas nas suas carteiras', conf: 'conf', }, details: { - title: 'transação', + title: 'Transação', from: 'De', to: 'Para', copy: 'Copiar', - transaction_details: 'Transaction details', - show_in_block_explorer: 'Show in block explorer', + transaction_details: 'Detalhes', + show_in_block_explorer: 'Mostrar num navegador', }, }, send: { header: 'Enviar', confirm: { - header: 'Confirm', - sendNow: 'Send now', + header: 'Confirmar', + sendNow: 'Enviar agora', }, success: { - done: 'Done', + done: 'Enviado', }, details: { title: 'Criar Transacção', @@ -134,53 +134,53 @@ module.exports = { cancel: 'Cancelar', scan: 'Scanear', create: 'Criar', - address: 'Address', - total_exceeds_balance: 'The total amount exceeds balance', + address: 'Endereço', + total_exceeds_balance: 'Valor total excede o saldo disponível', send: 'Send', remaining_balance: 'Saldo restante', }, create: { title: 'Criar Transacção', - details: 'Details', - error: 'Erro ao criar transação. Endereço inválido ou quantia?', + details: 'Detalhes', + error: 'Erro ao criar transação. Endereço ou valor inválidos?', go_back: 'Voltar', - this_is_hex: 'Este é o hex da transação, assinado e pronto para ser difundido para a network. Continuar?', + this_is_hex: 'Este é o hex da transação, assinado e pronto para ser divulgado para o mundo. Continuar?', to: 'Para', - amount: 'Quantia', + amount: 'Valor', fee: 'Taxa', - tx_size: 'Tamanho TX', - satoshi_per_byte: 'satoshiPerByte', - memo: 'Nota pessoal', - broadcast: 'Difundir', - not_enough_fee: 'Taxa demasiado baixa. Aumente a taxa', + tx_size: 'Tamanho', + satoshi_per_byte: 'satoshis por byte', + memo: 'Nota', + broadcast: 'Divulgar', + not_enough_fee: 'Taxa muito baixa. Aumente a taxa', }, }, receive: { - header: 'receber', + header: 'Receber', details: { - title: 'Partilhar este endereço com o pagador', - share: 'partilhar', - copiedToClipboard: 'copiado para clip board', - label: 'Description', - setAmount: 'Receive with amount', + title: 'Envie este endereço para o pagador', + share: 'Compartilhar', + copiedToClipboard: 'Copiado para a área de trabalho', + label: 'Descrição', + setAmount: 'Valor a receber', }, }, buyBitcoin: { - header: 'Buy Bitcoin', - tap_your_address: 'Tap your address to copy it to clipboard:', - copied: 'Copied to Clipboard!', + header: 'Comprar Bitcoin', + tap_your_address: 'Toque seu endereço para copiá-lo para a área de transferência:', + copied: 'Copiado!', }, settings: { - tabBarLabel: 'Definições', + tabBarLabel: 'preferências', header: 'definições', plausible_deniability: 'Negação plausível...', - storage_not_encrypted: 'Armazenamento: não encriptado', - storage_encrypted: 'Armazenamento: encriptado', - password: 'Password', - password_explain: 'Definir a password para desencriptar o armazenamento', - retype_password: 'Inserir password novamente', - passwords_do_not_match: 'Passwords não coincidem', - encrypt_storage: 'Encriptar', + storage_not_encrypted: 'Arquivos: não criptografados', + storage_encrypted: 'Arquivos: criptografados', + password: 'Senha', + password_explain: 'Definir a senha para descriptografar os arquivos', + retype_password: 'Inserir senha novamente', + passwords_do_not_match: 'Senhas não coincidem', + encrypt_storage: 'Criptografar', about: 'Sobre', language: 'Idioma', currency: 'Moeda', @@ -188,30 +188,30 @@ module.exports = { plausibledeniability: { title: 'Negação plausível', help: - 'Em algumas circunstâncias, pode ser forçado a relevar uma ' + - 'password. Para manter as suas moedas seguras, A BlueWallet pode criar outro ' + - 'armazenamento encriptado, com uma password diferente. Sobre pressão, ' + - 'pode revelar esta password a um terceiro. Se inserida na ' + - 'BlueWallet, esta vai abrir um armazenamento "falso". Que vai parecer ' + - 'legítimo a um terceiro, mas que secretamente vai manter o seu armazenamento principal ' + - 'com as moedas em segurança.', - help2: 'Este novo armazenamento é completamente funcional, e pode guardar ' + 'um valor minímo para parecer mais real.', - create_fake_storage: 'Criar armazenamento encriptado FALSO', + 'Em algumas circunstâncias, você pode ser forçado a revelar uma ' + + 'senha. Para manter seus bitcoins seguros, A BlueWallet pode criar ' + + 'uma senha alternativa. Sob pressão, você pode revelar essa senha ao ' + + 'invés da senha principal. Quando inserida na BlueWallet, esta abrirá ' + + 'uma interface falsa, que parecerá legítima a um terceiro, enquanto ' + + 'suas carteiras originais continuarão à salvo em segredo.', + help2: 'Essa nova interface é completamente funcional e você pode inclusive ' + + 'manter nele um valor minímo para que pareça mais real.', + create_fake_storage: 'Criar armazenamento criptografada falsa', go_back: 'Voltar', - create_password: 'Criar password', - create_password_explanation: 'Password para armazenamento FALSO não deve coincidir com o principal', - password_should_not_match: 'Password para armazenamento FALSO não deve coincidir com o principal', - retype_password: 'Inserir password novamente', - passwords_do_not_match: 'Passwords não coincidem, tente novamente', + create_password: 'Criar senha', + create_password_explanation: 'A senha para a interface falsa não deve coincidir com a principal', + password_should_not_match: 'A senha para a interface falsa não deve coincidir com a principal', + retype_password: 'Inserir senha novamente', + passwords_do_not_match: 'Senhas não coincidem, tente novamente', success: 'Sucesso', }, lnd: { - title: 'gerenciar fundos', - choose_source_wallet: 'Escolha a sua wallet', - refill_lnd_balance: 'Carregar o saldo da Lightning wallet', - refill: 'Carregar', - withdraw: 'Transferir', - expired: 'Expired', - sameWalletAsInvoiceError: 'You can not pay an invoice with the same wallet used to create it.', + title: 'manejar fundos', + choose_source_wallet: 'Escolha a carteira de origem', + refill_lnd_balance: 'Recarregar a carteira Lightning', + refill: 'Recarregar', + withdraw: 'Sacar', + expired: 'Vencido', + sameWalletAsInvoiceError: 'Você não pode pagar uma fatura com a mesma carteira que a criou.', }, }; diff --git a/prompt.js b/prompt.js index a09338f7..366962bb 100644 --- a/prompt.js +++ b/prompt.js @@ -1,6 +1,6 @@ import prompt from 'react-native-prompt-android'; -module.exports = (title, text, isCancelable = true) => { +module.exports = (title, text, isCancelable = true, type = 'secure-text') => { return new Promise((resolve, reject) => { const buttons = isCancelable ? [ @@ -30,7 +30,7 @@ module.exports = (title, text, isCancelable = true) => { ]; prompt(title, text, buttons, { - type: 'secure-text', + type: type, cancelable: isCancelable, }); }); diff --git a/screen/lnd/manageFunds.js b/screen/lnd/manageFunds.js index ea8272a2..c85c6f96 100644 --- a/screen/lnd/manageFunds.js +++ b/screen/lnd/manageFunds.js @@ -1,6 +1,6 @@ /* global alert */ import React, { Component } from 'react'; -import { TouchableOpacity, View } from 'react-native'; +import { TouchableOpacity, Linking, View } from 'react-native'; import { BlueSpacingVariable, BlueNavigationStyle, SafeBlueArea, BlueCard } from '../../BlueComponents'; import { ListItem } from 'react-native-elements'; import PropTypes from 'prop-types'; @@ -68,7 +68,7 @@ export default class ManageFunds extends Component { titleStyle={{ color: BlueApp.settings.foregroundColor }} component={TouchableOpacity} onPress={a => { - alert('Coming soon'); + Linking.openURL('https://zigzag.io'); }} title={loc.lnd.withdraw} /> diff --git a/screen/lnd/scanLndInvoice.js b/screen/lnd/scanLndInvoice.js index ba29afb8..8bbd89d8 100644 --- a/screen/lnd/scanLndInvoice.js +++ b/screen/lnd/scanLndInvoice.js @@ -10,6 +10,7 @@ let BlueApp = require('../../BlueApp'); let currency = require('../../currency'); let EV = require('../../events'); let loc = require('../../loc'); +let prompt = require('../../prompt'); const { width } = Dimensions.get('window'); export default class ScanLndInvoice extends React.Component { @@ -92,6 +93,14 @@ export default class ScanLndInvoice extends React.Component { let decoded; try { decoded = await w.decodeInvoice(data); + let freeAmount = 0; + while (+decoded.num_satoshis === 0) { + freeAmount = await prompt('This is free amount invoice', 'How many satoshis do you want to tip?', false, 'numeric'); + freeAmount = parseInt(freeAmount); + if (!isNaN(freeAmount) && freeAmount > 0) { + decoded.num_satoshis = freeAmount; + } + } let expiresIn = (decoded.timestamp * 1 + decoded.expiry * 1) * 1000; // ms if (+new Date() > expiresIn) { @@ -105,6 +114,7 @@ export default class ScanLndInvoice extends React.Component { invoice: data, decoded, expiresIn, + freeAmount, destination: data, }); } catch (Err) { @@ -143,7 +153,7 @@ export default class ScanLndInvoice extends React.Component { let start = +new Date(); let end; try { - await fromWallet.payInvoice(this.state.invoice); + await fromWallet.payInvoice(this.state.invoice, this.state.freeAmount); end = +new Date(); } catch (Err) { console.log(Err.message); @@ -170,7 +180,24 @@ export default class ScanLndInvoice extends React.Component { render() { return ( - + { + if (this.state.freeAmount) { + // must ask user again about the amount + let freeAmount = await prompt('This is free amount invoice', 'How many satoshis do you want to tip?', false, 'numeric'); + freeAmount = parseInt(freeAmount); + if (!isNaN(freeAmount) && freeAmount > 0) { + let decoded = this.state.decoded; + decoded.num_satoshis = freeAmount; + this.setState({ decoded, freeAmount }); + Keyboard.dismiss(); + } + } else { + Keyboard.dismiss(); + } + }} + accessible={false} + > {this.state.hasOwnProperty('decoded') && diff --git a/screen/settings/language.js b/screen/settings/language.js index 7861300a..106e96a2 100644 --- a/screen/settings/language.js +++ b/screen/settings/language.js @@ -26,6 +26,7 @@ export default class Language extends Component { { label: 'Deutsch (DE)', value: 'de_de' }, { label: 'Česky (CZ)', value: 'cs_cz' }, { label: 'Thai (TH)', value: 'th_th' }, + { label: 'Dutch (NL)', value: 'nl_nl' }, ], }; } diff --git a/screen/wallets/buyBitcoin.js b/screen/wallets/buyBitcoin.js index 9842af2b..5fea9229 100644 --- a/screen/wallets/buyBitcoin.js +++ b/screen/wallets/buyBitcoin.js @@ -90,9 +90,7 @@ export default class BuyBitcoin extends Component { color: BlueApp.settings.buttonTextColor, }} onPress={() => { - Linking.openURL( - 'https://payments.changelly.com/?crypto=USD&fiat=USD&ref_id=rtagfcvnwiwvhm99&address=' + this.state.address, - ); + Linking.openURL('https://old.changelly.com/?ref_id=rtagfcvnwiwvhm99'); }} title="Buy from Changelly" />