2023-02-09 22:13:47 -05:00
// import assert from 'assert';
2023-03-15 20:42:25 +00:00
import { ECPairFactory } from 'ecpair' ;
2023-02-09 22:13:47 -05:00
2023-03-15 20:42:25 +00:00
import { HDLegacyP2PKHWallet , HDSegwitBech32Wallet } from '../../class' ;
2023-02-09 22:13:47 -05:00
import * as BlueElectrum from '../../blue_modules/BlueElectrum' ;
2023-03-15 20:42:25 +00:00
import BIP47Factory from '@spsina/bip47' ;
import assert from 'assert' ;
const bitcoin = require ( 'bitcoinjs-lib' ) ;
const ecc = require ( 'tiny-secp256k1' ) ;
const ECPair = ECPairFactory ( ecc ) ;
2023-02-09 22:13:47 -05:00
2023-12-24 22:27:50 +00:00
jest . setTimeout ( 90 * 1000 ) ;
2023-02-09 22:13:47 -05:00
afterAll ( async ( ) = > {
// after all tests we close socket so the test suite can actually terminate
BlueElectrum . forceDisconnect ( ) ;
} ) ;
beforeAll ( async ( ) = > {
// awaiting for Electrum to be connected. For RN Electrum would naturally connect
// while app starts up, but for tests we need to wait for it
await BlueElectrum . connectMain ( ) ;
} ) ;
describe ( 'Bech32 Segwit HD (BIP84) with BIP47' , ( ) = > {
it ( 'should work' , async ( ) = > {
2023-03-15 20:42:25 +00:00
const hd = new HDLegacyP2PKHWallet ( ) ;
// @see https://gist.github.com/SamouraiDev/6aad669604c5930864bd
hd . setSecret ( 'reward upper indicate eight swift arch injury crystal super wrestle already dentist' ) ;
2023-02-09 22:13:47 -05:00
expect ( hd . getBIP47PaymentCode ( ) ) . toEqual (
'PM8TJS2JxQ5ztXUpBBRnpTbcUXbUHy2T1abfrb3KkAAtMEGNbey4oumH7Hc578WgQJhPjBxteQ5GHHToTYHE3A1w6p7tU6KSoFmWBVbFGjKPisZDbP97' ,
) ;
2023-03-15 20:42:25 +00:00
expect ( hd . allowBIP47 ( ) ) . toEqual ( true ) ;
2023-02-09 22:13:47 -05:00
await hd . fetchBIP47SenderPaymentCodes ( ) ;
2023-03-15 20:42:25 +00:00
expect ( hd . getBIP47SenderPaymentCodes ( ) . length ) . toBeGreaterThanOrEqual ( 3 ) ;
expect ( hd . getBIP47SenderPaymentCodes ( ) ) . toContain (
2023-02-09 22:13:47 -05:00
'PM8TJTLJbPRGxSbc8EJi42Wrr6QbNSaSSVJ5Y3E4pbCYiTHUskHg13935Ubb7q8tx9GVbh2UuRnBc3WSyJHhUrw8KhprKnn9eDznYGieTzFcwQRya4GA' ,
) ;
2023-03-15 20:42:25 +00:00
expect ( hd . getBIP47SenderPaymentCodes ( ) ) . toContain (
2023-02-09 22:13:47 -05:00
'PM8TJgndZSWCBPG5zCsqdXmCKLi7sP13jXuRp6b5X7G9geA3vRXQKAoXDf4Eym2RJB3vvcBdpDQT4vbo5QX7UfeV2ddjM8s79ERUTFS2ScKggSrciUsU' ,
) ;
2023-03-15 20:42:25 +00:00
expect ( hd . getBIP47SenderPaymentCodes ( ) ) . toContain (
2023-02-09 22:13:47 -05:00
'PM8TJNiWKcyiA2MsWCfuAr9jvhA5qMEdEkjNypEnUbxMRa1D5ttQWdggQ7ib9VNFbRBSuw7i6RkqPSkCMR1XGPSikJHaCSfqWtsb1fn4WNAXjp5JVL5z' ,
) ;
2023-03-15 20:42:25 +00:00
await hd . fetchBalance ( ) ;
2023-02-09 22:13:47 -05:00
await hd . fetchTransactions ( ) ;
expect ( hd . getTransactions ( ) . length ) . toBeGreaterThanOrEqual ( 4 ) ;
} ) ;
2023-03-15 20:42:25 +00:00
it ( 'should work (samurai)' , async ( ) = > {
if ( ! process . env . BIP47_HD_MNEMONIC ) {
console . error ( 'process.env.BIP47_HD_MNEMONIC not set, skipped' ) ;
return ;
}
const w = new HDSegwitBech32Wallet ( ) ;
w . setSecret ( process . env . BIP47_HD_MNEMONIC . split ( ':' ) [ 0 ] ) ;
w . setPassphrase ( '1' ) ;
expect ( w . getBIP47PaymentCode ( ) ) . toEqual (
'PM8TJXuZNUtSibuXKFM6bhCxpNaSye6r4px2GXRV5v86uRdH9Raa8ZtXEkG7S4zLREf4ierjMsxLXSFTbRVUnRmvjw9qnc7zZbyXyBstSmjcb7uVcDYF' ,
) ;
expect ( w . _getExternalAddressByIndex ( 0 ) ) . toEqual ( 'bc1q07l355j4yd5kyut36vjxn2u60d3dknnpt39t6y' ) ;
const bip47 = BIP47Factory ( ecc ) . fromBip39Seed ( w . getSecret ( ) , undefined , w . getPassphrase ( ) ) ;
const ourNotificationAddress = bip47 . getNotificationAddress ( ) ;
const publicBip47 = BIP47Factory ( ecc ) . fromPaymentCode ( w . getBIP47PaymentCode ( ) ) ;
expect ( ourNotificationAddress ) . toEqual ( publicBip47 . getNotificationAddress ( ) ) ;
expect ( ourNotificationAddress ) . toEqual ( '1EiP2kSqxNqRhn8MPMkrtSEqaWiCWLYyTS' ) ; // our notif address
await w . fetchBIP47SenderPaymentCodes ( ) ;
assert . ok (
w
. getBIP47SenderPaymentCodes ( )
. includes ( 'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo' ) ,
) ; // sparrow payment code
assert . ok ( w . weOwnAddress ( 'bc1q57nwf9vfq2qsl80q37wq5h0tjytsk95vgjq4fe' ) ) ; // this is an address that was derived (and paid) from counterparty payment code
const keyPair2 = ECPair . fromWIF ( w . _getWIFbyAddress ( 'bc1q57nwf9vfq2qsl80q37wq5h0tjytsk95vgjq4fe' ) || '' ) ;
const address = bitcoin . payments . p2wpkh ( {
pubkey : keyPair2.publicKey ,
} ) . address ;
assert . strictEqual ( address , 'bc1q57nwf9vfq2qsl80q37wq5h0tjytsk95vgjq4fe' ) ;
await w . fetchTransactions ( ) ;
assert . ok ( w . getTransactions ( ) . length >= 3 ) ;
assert . strictEqual (
w . getTransactions ( ) . find ( tx = > tx . txid === '64058a49bb75481fc0bebbb0d84a4aceebe319f9d32929e73cefb21d83342e9f' ) ? . value ,
100000 ,
) ; // initial deposit from sparrow after sparrow made a notification tx
assert . strictEqual (
w . getTransactions ( ) . find ( tx = > tx . txid === '06b4c14587182fd0474f265a77b156519b4778769a99c21623863a8194d0fa4f' ) ? . value ,
- 22692 ,
) ; // notification tx to sparrow so we can pay sparrow
assert . strictEqual (
w . getTransactions ( ) . find ( tx = > tx . txid === '73a2ac70858c5b306b101a861d582f40c456a692096a4e4805aa739258c4400d' ) ? . value ,
- 77308 ,
) ; // paying to sparrow
// now, constructing OP_RETURN data to notify sparrow about us
const aliceBip47 = bip47 ;
const keyPair = ECPair . fromWIF ( w . _getWIFbyAddress ( 'bc1q57nwf9vfq2qsl80q37wq5h0tjytsk95vgjq4fe' ) || '' ) ;
const bobBip47 = BIP47Factory ( ecc ) . fromPaymentCode (
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo' ,
) ;
const blindedPaymentCode = aliceBip47 . getBlindedPaymentCode (
bobBip47 ,
keyPair . privateKey as Buffer ,
// txid is reversed, as well as output number ()
Buffer . from ( '64058a49bb75481fc0bebbb0d84a4aceebe319f9d32929e73cefb21d83342e9f' , 'hex' ) . reverse ( ) . toString ( 'hex' ) + '01000000' ,
) ;
assert . strictEqual (
blindedPaymentCode ,
'0100039da7642943ec5d16c9bce09b71f240fe246d891fa3b52a7d236fece98318e1ae972f3747672f7e79a23fc88c4dc91a8d014233e14a9e4417e132405b6a6c166d00000000000000000000000000' ,
) ;
// checking that this is exactly a data payload we have in an actual notification transaction we have sent:
assert . strictEqual (
w . getTransactions ( ) . find ( tx = > tx . txid === '06b4c14587182fd0474f265a77b156519b4778769a99c21623863a8194d0fa4f' ) ? . outputs ? . [ 0 ]
? . scriptPubKey . hex ,
'6a4c50' + blindedPaymentCode ,
) ;
} ) ;
2023-02-09 22:13:47 -05:00
} ) ;