From 8bfe3ae17dc555506477c03aea37bdef5375f92d Mon Sep 17 00:00:00 2001 From: overtorment Date: Sat, 15 Jun 2024 20:11:02 +0100 Subject: [PATCH] ADD: can add regular onchain address as contact --- class/contact-list.ts | 18 ++++++++++++++++++ screen/wallets/PaymentCodesList.tsx | 11 +++++++++-- tests/unit/contact-list.test.ts | 9 +++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/class/contact-list.ts b/class/contact-list.ts index e61fcaf72..f06acf386 100644 --- a/class/contact-list.ts +++ b/class/contact-list.ts @@ -3,6 +3,7 @@ import BIP47Factory from '@spsina/bip47'; import { SilentPayment } from 'silent-payments'; import ecc from '../blue_modules/noble_ecc'; +import * as bitcoin from 'bitcoinjs-lib'; export class ContactList { isBip47PaymentCodeValid(pc: string) { @@ -21,4 +22,21 @@ export class ContactList { isPaymentCodeValid(pc: string): boolean { return this.isBip47PaymentCodeValid(pc) || this.isBip352PaymentCodeValid(pc); } + + isAddressValid(address: string): boolean { + try { + bitcoin.address.toOutputScript(address); // throws, no? + + if (!address.toLowerCase().startsWith('bc1')) return true; + const decoded = bitcoin.address.fromBech32(address); + if (decoded.version === 0) return true; + if (decoded.version === 1 && decoded.data.length !== 32) return false; + if (decoded.version === 1 && !ecc.isPoint(Buffer.concat([Buffer.from([2]), decoded.data]))) return false; + if (decoded.version > 1) return false; + // ^^^ some day, when versions above 1 will be actually utilized, we would need to unhardcode this + return true; + } catch (e) { + return false; + } + } } diff --git a/screen/wallets/PaymentCodesList.tsx b/screen/wallets/PaymentCodesList.tsx index 7bf103cdc..979bd7e9f 100644 --- a/screen/wallets/PaymentCodesList.tsx +++ b/screen/wallets/PaymentCodesList.tsx @@ -147,8 +147,8 @@ export default function PaymentCodesList() { } case String(Actions.pay): { const cl = new ContactList(); - // ok its a SilentPayments code, ok to just send - if (cl.isBip352PaymentCodeValid(pc)) { + // ok its a SilentPayments code/regular address, no need to check for notif tx, ok to just send + if (cl.isBip352PaymentCodeValid(pc) || cl.isAddressValid(pc)) { _navigateToSend(pc); return; } @@ -261,6 +261,13 @@ export default function PaymentCodesList() { const cl = new ContactList(); + if (cl.isAddressValid(newPc)) { + // this is not a payment code but a regular onchain address. pretending its a payment code and adding it + foundWallet.addBIP47Receiver(newPc); + setReload(Math.random()); + return; + } + if (!cl.isPaymentCodeValid(newPc)) { presentAlert({ message: loc.bip47.invalid_pc }); return; diff --git a/tests/unit/contact-list.test.ts b/tests/unit/contact-list.test.ts index c5fcb72a7..f4c9bf335 100644 --- a/tests/unit/contact-list.test.ts +++ b/tests/unit/contact-list.test.ts @@ -3,6 +3,15 @@ import assert from 'assert'; import { ContactList } from '../../class/contact-list'; describe('ContactList', () => { + it('isAddressValid()', () => { + const cl = new ContactList(); + assert.ok(cl.isAddressValid('3BDsBDxDimYgNZzsqszNZobqQq3yeUoJf2')); + assert.ok(cl.isAddressValid('bc1quuafy8htjjj263cvpj7md84magzmc8svmh8lrm')); + assert.ok(cl.isAddressValid('BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7')); + + assert.ok(!cl.isAddressValid('sfhsdhsdf')); + }); + it('isPaymentCodeValid()', async () => { const cl = new ContactList();