33
44import type { DescriptorPair } from '@metamask/bitcoindevkit' ;
55import {
6+ Address ,
67 ChangeSet ,
78 xpriv_to_descriptor ,
89 xpub_to_descriptor ,
@@ -26,6 +27,9 @@ jest.mock('@metamask/bitcoindevkit', () => {
2627 ChangeSet : {
2728 from_json : jest . fn ( ) ,
2829 } ,
30+ Address : {
31+ from_string : jest . fn ( ) ,
32+ } ,
2933 slip10_to_extended : jest . fn ( ) . mockReturnValue ( 'mock-extended' ) ,
3034 xpub_to_descriptor : jest . fn ( ) ,
3135 xpriv_to_descriptor : jest . fn ( ) ,
@@ -57,11 +61,16 @@ describe('BdkAccountRepository', () => {
5761 derivationPath : mockDerivationPath ,
5862 } ) ;
5963 const mockChangeSet = mock < ChangeSet > ( ) ;
64+ const mockAddress = mock < Address > ( {
65+ toString : ( ) => 'bc1qaddress...' ,
66+ } ) ;
6067 const mockAccount = mock < BitcoinAccount > ( {
6168 id : 'some-id' ,
6269 derivationPath : mockDerivationPath ,
6370 network : 'bitcoin' ,
6471 addressType : 'p2wpkh' ,
72+ publicAddress : mockAddress ,
73+ publicDescriptor : 'mock-public-descriptor' ,
6574 } ) ;
6675
6776 const repo = new BdkAccountRepository ( mockSnapClient ) ;
@@ -74,6 +83,7 @@ describe('BdkAccountRepository', () => {
7483 mockSnapClient . getPublicEntropy . mockResolvedValue ( mockSlip10Node ) ;
7584 ( xpriv_to_descriptor as jest . Mock ) . mockReturnValue ( mockDescriptors ) ;
7685 ( xpub_to_descriptor as jest . Mock ) . mockReturnValue ( mockDescriptors ) ;
86+ jest . mocked ( Address . from_string ) . mockReturnValue ( mockAddress ) ;
7787 ( mockAccount . takeStaged as jest . Mock ) = jest
7888 . fn ( )
7989 . mockReturnValue ( mockChangeSet ) ;
@@ -234,6 +244,40 @@ describe('BdkAccountRepository', () => {
234244 expect ( mockSnapClient . setState ) . not . toHaveBeenCalled ( ) ;
235245 } ) ;
236246
247+ it ( 'uses cached account metadata without loading BDK wallets' , async ( ) => {
248+ const accountStateWithMetadata : AccountState = {
249+ ...accountState1 ,
250+ metadata : {
251+ address : 'bc1qcached...' ,
252+ addressType : 'p2wpkh' ,
253+ network : 'bitcoin' ,
254+ publicDescriptor : 'cached-public-descriptor' ,
255+ } ,
256+ } ;
257+ mockSnapClient . getState
258+ . mockResolvedValueOnce ( {
259+ "m/84'/0'/1'" : 'some-id-1' ,
260+ } )
261+ . mockResolvedValueOnce ( {
262+ 'some-id-1' : accountStateWithMetadata ,
263+ } ) ;
264+ ( BdkAccountAdapter . load as jest . Mock ) . mockClear ( ) ;
265+ ( ChangeSet . from_json as jest . Mock ) . mockClear ( ) ;
266+
267+ const result = await repo . getByDerivationPaths ( [ derivationPath1 ] ) ;
268+ const account = result [ 0 ] ;
269+
270+ expect ( account ?. id ) . toBe ( 'some-id-1' ) ;
271+ expect ( account ?. publicAddress . toString ( ) ) . toBe ( 'bc1qaddress...' ) ;
272+ expect ( account ?. publicDescriptor ) . toBe ( 'cached-public-descriptor' ) ;
273+ expect ( jest . mocked ( Address . from_string ) ) . toHaveBeenCalledWith (
274+ 'bc1qcached...' ,
275+ 'bitcoin' ,
276+ ) ;
277+ expect ( ChangeSet . from_json ) . not . toHaveBeenCalled ( ) ;
278+ expect ( BdkAccountAdapter . load ) . not . toHaveBeenCalled ( ) ;
279+ } ) ;
280+
237281 it ( 'repairs missing derivation path indexes from account state' , async ( ) => {
238282 mockSnapClient . getState
239283 . mockResolvedValueOnce ( {
@@ -342,6 +386,12 @@ describe('BdkAccountRepository', () => {
342386 wallet : mockWalletData ,
343387 inscriptions : [ ] ,
344388 derivationPath : mockDerivationPath ,
389+ metadata : {
390+ address : 'bc1qaddress...' ,
391+ addressType : 'p2wpkh' ,
392+ network : 'bitcoin' ,
393+ publicDescriptor : 'mock-public-descriptor' ,
394+ } ,
345395 } ,
346396 ) ;
347397 } ) ;
@@ -415,9 +465,17 @@ describe('BdkAccountRepository', () => {
415465 const account1 = mock < BitcoinAccount > ( ) ;
416466 account1 . id = 'some-id-1' ;
417467 account1 . derivationPath = [ 'm' , "84'" , "0'" , "1'" ] ;
468+ account1 . network = 'bitcoin' ;
469+ account1 . addressType = 'p2wpkh' ;
470+ account1 . publicAddress = mockAddress ;
471+ account1 . publicDescriptor = 'mock-public-descriptor-1' ;
418472 const account2 = mock < BitcoinAccount > ( ) ;
419473 account2 . id = 'some-id-2' ;
420474 account2 . derivationPath = [ 'm' , "84'" , "0'" , "2'" ] ;
475+ account2 . network = 'bitcoin' ;
476+ account2 . addressType = 'p2wpkh' ;
477+ account2 . publicAddress = mockAddress ;
478+ account2 . publicDescriptor = 'mock-public-descriptor-2' ;
421479 ( account1 . takeStaged as jest . Mock ) = jest
422480 . fn ( )
423481 . mockReturnValue ( mockChangeSet ) ;
@@ -443,11 +501,23 @@ describe('BdkAccountRepository', () => {
443501 wallet : mockWalletData ,
444502 inscriptions : [ ] ,
445503 derivationPath : [ 'm' , "84'" , "0'" , "1'" ] ,
504+ metadata : {
505+ address : 'bc1qaddress...' ,
506+ addressType : 'p2wpkh' ,
507+ network : 'bitcoin' ,
508+ publicDescriptor : 'mock-public-descriptor-1' ,
509+ } ,
446510 } ,
447511 'some-id-2' : {
448512 wallet : mockWalletData ,
449513 inscriptions : [ ] ,
450514 derivationPath : [ 'm' , "84'" , "0'" , "2'" ] ,
515+ metadata : {
516+ address : 'bc1qaddress...' ,
517+ addressType : 'p2wpkh' ,
518+ network : 'bitcoin' ,
519+ publicDescriptor : 'mock-public-descriptor-2' ,
520+ } ,
451521 } ,
452522 } ) ;
453523 expect ( mockSnapClient . setState ) . toHaveBeenNthCalledWith (
0 commit comments