github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/nuls/nulsparser_test.go (about)

     1  //go:build unittest
     2  
     3  package nuls
     4  
     5  import (
     6  	"encoding/hex"
     7  	"math/big"
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/ethereum/go-ethereum/common/hexutil"
    12  	"github.com/martinboehm/btcutil/hdkeychain"
    13  	"github.com/trezor/blockbook/bchain"
    14  	"github.com/trezor/blockbook/bchain/coins/btc"
    15  	"github.com/trezor/blockbook/common"
    16  )
    17  
    18  var (
    19  	testTx1, testTx2 bchain.Tx
    20  
    21  	testTxPacked1 = "0001e240daadfbe7931e000000007b22686578223a22222c2274786964223a223030323036626231323431303861356664393865383238623138316666303162393237633063366234373764343531326266656638346366353266306663326136613161222c2276657273696f6e223a312c226c6f636b74696d65223a302c2276696e223a5b7b22636f696e62617365223a22222c2274786964223a223030323035343537616230373033623164313034363264343334373034386330626233353634653430663537616531663632353136393539343364653161633831306130222c22766f7574223a302c22736372697074536967223a7b22686578223a22227d2c2273657175656e6365223a302c22616464726573736573223a5b224e736535334d77524c424a31575555365365644d485141466643507442377734225d7d5d2c22766f7574223a5b7b2256616c7565536174223a3339393939393030303030302c2276616c7565223a302c226e223a302c227363726970745075624b6579223a7b22686578223a224e7365347a705a4873557555376835796d7632387063476277486a75336a6f56222c22616464726573736573223a5b224e7365347a705a4873557555376835796d7632387063476277486a75336a6f56225d7d7d5d2c22626c6f636b74696d65223a313535323335373834343137357d"
    22  	testTxPacked2 = "0007c91adaadfbb89946000000007b22686578223a22222c2274786964223a223030323037386139386633383163373134613036386436303565346265316565323139353438353736313165303938616262636333663530633536383066386164326535222c2276657273696f6e223a312c226c6f636b74696d65223a302c2276696e223a5b7b22636f696e62617365223a22222c2274786964223a223030323037613430646334623661633430376434396133633333616137353462623466303565343565353763323438313162313437653762663363616630363361383233222c22766f7574223a312c22736372697074536967223a7b22686578223a22227d2c2273657175656e6365223a302c22616464726573736573223a5b224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169225d7d5d2c22766f7574223a5b7b2256616c7565536174223a3430303030303030303030302c2276616c7565223a302c226e223a302c227363726970745075624b6579223a7b22686578223a224e736534696b6a45383867324267734e7773737754646b53776953724b6a6a53222c22616464726573736573223a5b224e736534696b6a45383867324267734e7773737754646b53776953724b6a6a53225d7d7d2c7b2256616c7565536174223a373238363536353537303030302c2276616c7565223a302c226e223a312c227363726970745075624b6579223a7b22686578223a224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169222c22616464726573736573223a5b224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169225d7d7d5d2c22626c6f636b74696d65223a313535323335373435393535357d"
    23  )
    24  
    25  func init() {
    26  	testTx1 = bchain.Tx{
    27  		Hex:       "",
    28  		Blocktime: 1552357844175,
    29  		Txid:      "00206bb124108a5fd98e828b181ff01b927c0c6b477d4512bfef84cf52f0fc2a6a1a",
    30  		LockTime:  0,
    31  		Version:   1,
    32  		Vin: []bchain.Vin{
    33  			{
    34  				Txid:     "00205457ab0703b1d10462d4347048c0bb3564e40f57ae1f6251695943de1ac810a0",
    35  				Vout:     0,
    36  				Sequence: 0,
    37  				Addresses: []string{
    38  					"Nse53MwRLBJ1WUU6SedMHQAFfCPtB7w4",
    39  				},
    40  			},
    41  		},
    42  		Vout: []bchain.Vout{
    43  			{
    44  				ValueSat:  *big.NewInt(399999000000),
    45  				N:         0,
    46  				JsonValue: common.JSONNumber("0"),
    47  				ScriptPubKey: bchain.ScriptPubKey{
    48  					Hex: "Nse4zpZHsUuU7h5ymv28pcGbwHju3joV",
    49  					Addresses: []string{
    50  						"Nse4zpZHsUuU7h5ymv28pcGbwHju3joV",
    51  					},
    52  				},
    53  			},
    54  		},
    55  		//CoinSpecificData: []string{},
    56  	}
    57  
    58  	testTx2 = bchain.Tx{
    59  		Hex:       "",
    60  		Blocktime: 1552357459555,
    61  		Txid:      "002078a98f381c714a068d605e4be1ee21954857611e098abbcc3f50c5680f8ad2e5",
    62  		LockTime:  0,
    63  		Version:   1,
    64  		Vin: []bchain.Vin{
    65  			{
    66  				Txid:     "00207a40dc4b6ac407d49a3c33aa754bb4f05e45e57c24811b147e7bf3caf063a823",
    67  				Vout:     1,
    68  				Sequence: 0,
    69  				Addresses: []string{
    70  					"Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi",
    71  				},
    72  			},
    73  		},
    74  		Vout: []bchain.Vout{
    75  			{
    76  				ValueSat:  *big.NewInt(400000000000),
    77  				N:         0,
    78  				JsonValue: common.JSONNumber("0"),
    79  				ScriptPubKey: bchain.ScriptPubKey{
    80  					Hex: "Nse4ikjE88g2BgsNwsswTdkSwiSrKjjS",
    81  					Addresses: []string{
    82  						"Nse4ikjE88g2BgsNwsswTdkSwiSrKjjS",
    83  					},
    84  				},
    85  			},
    86  			{
    87  				ValueSat:  *big.NewInt(7286565570000),
    88  				N:         1,
    89  				JsonValue: common.JSONNumber("0"),
    90  				ScriptPubKey: bchain.ScriptPubKey{
    91  					Hex: "Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi",
    92  					Addresses: []string{
    93  						"Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi",
    94  					},
    95  				},
    96  			},
    97  		},
    98  		//CoinSpecificData: []string{},
    99  	}
   100  }
   101  
   102  func TestGetAddrDescFromAddress(t *testing.T) {
   103  	type args struct {
   104  		address string
   105  	}
   106  	tests := []struct {
   107  		name    string
   108  		args    args
   109  		want    string
   110  		wantErr bool
   111  	}{
   112  		{
   113  			name:    "P2PKH",
   114  			args:    args{address: "Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"},
   115  			want:    "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1",
   116  			wantErr: false,
   117  		},
   118  		{
   119  			name:    "P2PKH",
   120  			args:    args{address: "Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"},
   121  			want:    "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e",
   122  			wantErr: false,
   123  		},
   124  		{
   125  			name:    "P2PKH",
   126  			args:    args{address: "NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"},
   127  			want:    "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478",
   128  			wantErr: false,
   129  		},
   130  	}
   131  	parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{})
   132  
   133  	for _, tt := range tests {
   134  		t.Run(tt.name, func(t *testing.T) {
   135  			got, err := parser.GetAddrDescFromAddress(tt.args.address)
   136  			if (err != nil) != tt.wantErr {
   137  				t.Errorf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr)
   138  				return
   139  			}
   140  			h := hex.EncodeToString(got)
   141  			if !reflect.DeepEqual(h, tt.want) {
   142  				t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want)
   143  			}
   144  		})
   145  	}
   146  }
   147  
   148  func TestGetAddrDescFromVout(t *testing.T) {
   149  	type args struct {
   150  		vout bchain.Vout
   151  	}
   152  	tests := []struct {
   153  		name    string
   154  		args    args
   155  		want    string
   156  		wantErr bool
   157  	}{
   158  		{
   159  			name:    "P2PK",
   160  			args:    args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"}}},
   161  			want:    "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1",
   162  			wantErr: false,
   163  		},
   164  		{
   165  			name:    "P2PK",
   166  			args:    args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"}}},
   167  			want:    "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e",
   168  			wantErr: false,
   169  		},
   170  		{
   171  			name:    "P2PK",
   172  			args:    args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"}}},
   173  			want:    "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478",
   174  			wantErr: false,
   175  		},
   176  	}
   177  	parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{})
   178  
   179  	for _, tt := range tests {
   180  		t.Run(tt.name, func(t *testing.T) {
   181  			got, err := parser.GetAddrDescFromVout(&tt.args.vout)
   182  			if (err != nil) != tt.wantErr {
   183  				t.Errorf("GetAddrDescFromVout() error = %v, wantErr %v", err, tt.wantErr)
   184  				return
   185  			}
   186  			h := hex.EncodeToString(got)
   187  			if !reflect.DeepEqual(h, tt.want) {
   188  				t.Errorf("GetAddrDescFromVout() = %v, want %v", h, tt.want)
   189  			}
   190  		})
   191  	}
   192  }
   193  
   194  func TestGetAddressesFromAddrDesc(t *testing.T) {
   195  	type args struct {
   196  		script string
   197  	}
   198  	tests := []struct {
   199  		name    string
   200  		args    args
   201  		want    []string
   202  		want2   bool
   203  		wantErr bool
   204  	}{
   205  		{
   206  			name:    "P2PKH",
   207  			args:    args{script: "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1"},
   208  			want:    []string{"Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"},
   209  			want2:   true,
   210  			wantErr: false,
   211  		},
   212  		{
   213  			name:    "P2PKH",
   214  			args:    args{script: "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e"},
   215  			want:    []string{"Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"},
   216  			want2:   true,
   217  			wantErr: false,
   218  		},
   219  		{
   220  			name:    "P2PKH",
   221  			args:    args{script: "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478"},
   222  			want:    []string{"NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"},
   223  			want2:   true,
   224  			wantErr: false,
   225  		},
   226  	}
   227  
   228  	parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{})
   229  
   230  	for _, tt := range tests {
   231  		t.Run(tt.name, func(t *testing.T) {
   232  			b, _ := hex.DecodeString(tt.args.script)
   233  			got, got2, err := parser.GetAddressesFromAddrDesc(b)
   234  			if (err != nil) != tt.wantErr {
   235  				t.Errorf("GetAddressesFromAddrDesc() error = %v, wantErr %v", err, tt.wantErr)
   236  				return
   237  			}
   238  			if !reflect.DeepEqual(got, tt.want) {
   239  				t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.want)
   240  			}
   241  			if !reflect.DeepEqual(got2, tt.want2) {
   242  				t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.want2)
   243  			}
   244  		})
   245  	}
   246  }
   247  
   248  func TestPackTx(t *testing.T) {
   249  	type args struct {
   250  		tx        bchain.Tx
   251  		height    uint32
   252  		blockTime int64
   253  		parser    *NulsParser
   254  	}
   255  	tests := []struct {
   256  		name    string
   257  		args    args
   258  		want    string
   259  		wantErr bool
   260  	}{
   261  		{
   262  			name: "test-1",
   263  			args: args{
   264  				tx:        testTx1,
   265  				height:    123456,
   266  				blockTime: 1552357844175,
   267  				parser:    NewNulsParser(GetChainParams("main"), &btc.Configuration{}),
   268  			},
   269  			want:    testTxPacked1,
   270  			wantErr: false,
   271  		},
   272  		{
   273  			name: "test-2",
   274  			args: args{
   275  				tx:        testTx2,
   276  				height:    510234,
   277  				blockTime: 1552357459555,
   278  				parser:    NewNulsParser(GetChainParams("main"), &btc.Configuration{}),
   279  			},
   280  			want:    testTxPacked2,
   281  			wantErr: false,
   282  		},
   283  	}
   284  	for _, tt := range tests {
   285  		t.Run(tt.name, func(t *testing.T) {
   286  			got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime)
   287  			if (err != nil) != tt.wantErr {
   288  				t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr)
   289  				return
   290  			}
   291  			h := hex.EncodeToString(got)
   292  			if !reflect.DeepEqual(h, tt.want) {
   293  				t.Errorf("packTx() = %v, want %v", h, tt.want)
   294  			}
   295  		})
   296  	}
   297  }
   298  
   299  func TestUnpackTx(t *testing.T) {
   300  	type args struct {
   301  		packedTx string
   302  		parser   *NulsParser
   303  	}
   304  	tests := []struct {
   305  		name    string
   306  		args    args
   307  		want    *bchain.Tx
   308  		want1   uint32
   309  		wantErr bool
   310  	}{
   311  		{
   312  			name: "test-1",
   313  			args: args{
   314  				packedTx: testTxPacked1,
   315  				parser:   NewNulsParser(GetChainParams("main"), &btc.Configuration{}),
   316  			},
   317  			want:    &testTx1,
   318  			want1:   123456,
   319  			wantErr: false,
   320  		},
   321  		{
   322  			name: "test-2",
   323  			args: args{
   324  				packedTx: testTxPacked2,
   325  				parser:   NewNulsParser(GetChainParams("main"), &btc.Configuration{}),
   326  			},
   327  			want:    &testTx2,
   328  			want1:   510234,
   329  			wantErr: false,
   330  		},
   331  	}
   332  	for _, tt := range tests {
   333  		t.Run(tt.name, func(t *testing.T) {
   334  			b, _ := hex.DecodeString(tt.args.packedTx)
   335  			got, got1, err := tt.args.parser.UnpackTx(b)
   336  			if (err != nil) != tt.wantErr {
   337  				t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr)
   338  				return
   339  			}
   340  			if !reflect.DeepEqual(got, tt.want) {
   341  				t.Errorf("unpackTx() got = %+v, want %+v", got, tt.want)
   342  			}
   343  			if got1 != tt.want1 {
   344  				t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1)
   345  			}
   346  		})
   347  	}
   348  }
   349  
   350  func TestDeriveAddressDescriptorsFromTo(t *testing.T) {
   351  
   352  	parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{})
   353  
   354  	// test xpub xprv math ,and get private key
   355  	xprv := "xprv9yEvwSfPanK5gLYVnYvNyF2CEWJx1RsktQtKDeT6jnCnqASBiPCvFYHFSApXv39bZbF6hRaha1kWQBVhN1xjo7NHuhAn5uUfzy79TBuGiHh"
   356  	xpub := "xpub6CEHLxCHR9sNtpcxtaTPLNxvnY9SQtbcFdov22riJ7jmhxmLFvXAoLbjHSzwXwNNuxC1jUP6tsHzFV9rhW9YKELfmR9pJaKFaM8C3zMPgjw"
   357  	extKey, err := hdkeychain.NewKeyFromString(xprv, parser.Params.Base58CksumHasher)
   358  	if err != nil {
   359  		t.Errorf("DeriveAddressDescriptorsFromTo() error = %v", err)
   360  		return
   361  	}
   362  	changeExtKey, err := extKey.Derive(0)
   363  	if err != nil {
   364  		t.Errorf("DeriveAddressDescriptorsFromTo() error = %v", err)
   365  		return
   366  	}
   367  
   368  	key1, _ := changeExtKey.Derive(0)
   369  	priKey1, _ := key1.ECPrivKey()
   370  	wantPriKey1 := "0x995c98115809359eb57a5e179558faddd55ef88f88e5cf58617a5f9f3d6bb3a1"
   371  	if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey1), priKey1.Serialize()) {
   372  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPriKey1, hexutil.Encode(priKey1.Serialize()))
   373  		return
   374  	}
   375  	pubKey1, _ := key1.ECPubKey()
   376  	wantPubKey1 := "0x028855d37e8b1d2760289ea51996df05f3297d86fae4e113aea696a0f02a420ae2"
   377  	if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey1), pubKey1.SerializeCompressed()) {
   378  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPubKey1, hexutil.Encode(pubKey1.SerializeCompressed()))
   379  		return
   380  	}
   381  
   382  	key2, _ := changeExtKey.Derive(1)
   383  	priKey2, _ := key2.ECPrivKey()
   384  	wantPriKey2 := "0x0f65dee42d3c974c1a4bcc79f141be89715dc8d6406faa9ad4f1f55ca95fabc8"
   385  	if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey2), priKey2.Serialize()) {
   386  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPriKey2, hexutil.Encode(priKey2.Serialize()))
   387  		return
   388  	}
   389  	pubKey2, _ := key2.ECPubKey()
   390  	wantPubKey2 := "0x0216f460ea59194464a6c981560e3f52899203496ed8a20f8f9a57a9225d841293"
   391  	if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey2), pubKey2.SerializeCompressed()) {
   392  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPubKey2, hexutil.Encode(pubKey2.SerializeCompressed()))
   393  		return
   394  	}
   395  
   396  	key3, _ := changeExtKey.Derive(2)
   397  	priKey3, _ := key3.ECPrivKey()
   398  	wantPriKey3 := "0x6fd98d1d9c3f3ac1ff61bbf3f20e89f00ffa8d43a554f2a7d73fd464b6666f45"
   399  	if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey3), priKey3.Serialize()) {
   400  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPriKey3, hexutil.Encode(priKey3.Serialize()))
   401  		return
   402  	}
   403  	pubKey3, _ := key3.ECPubKey()
   404  	wantPubKey3 := "0x0327ef15c2eaf99365610d6ef89d9ad1e89d1ddf888fc0ec7eb8a94d97153ee482"
   405  	if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey3), pubKey3.SerializeCompressed()) {
   406  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPubKey3, hexutil.Encode(pubKey3.SerializeCompressed()))
   407  		return
   408  	}
   409  
   410  	key4, _ := changeExtKey.Derive(3)
   411  	priKey4, _ := key4.ECPrivKey()
   412  	wantPriKey4 := "0x21412d9e33aba493faf4bc7d408ed5290bea5b36a7beec554b858051f8d4bff3"
   413  	if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey4), priKey4.Serialize()) {
   414  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPriKey4, hexutil.Encode(priKey4.Serialize()))
   415  		return
   416  	}
   417  	pubKey4, _ := key4.ECPubKey()
   418  	wantPubKey4 := "0x02a73aebd08c6f70fa97f616b1c0b63756efe9eb070a14628de3d850b2b970a9a7"
   419  	if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey4), pubKey4.SerializeCompressed()) {
   420  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPubKey4, hexutil.Encode(pubKey4.SerializeCompressed()))
   421  		return
   422  	}
   423  
   424  	key5, _ := changeExtKey.Derive(4)
   425  	priKey5, _ := key5.ECPrivKey()
   426  	wantPriKey5 := "0xdc3d290e32a4e0f38bc26c25a78ceb1c8779110883d9cb0be54629043c1f8724"
   427  	if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey5), priKey5.Serialize()) {
   428  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPriKey5, hexutil.Encode(priKey5.Serialize()))
   429  		return
   430  	}
   431  	pubKey5, _ := key5.ECPubKey()
   432  	wantPubKey5 := "0x02f87eb70b985a857d7238bc9423dab7d5930f3fcfc2118ccac0634a9342b9d324"
   433  	if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey5), pubKey5.SerializeCompressed()) {
   434  		t.Errorf("DeriveAddressDescriptorsFromTo()  %v, want %v", wantPubKey5, hexutil.Encode(pubKey5.SerializeCompressed()))
   435  		return
   436  	}
   437  
   438  	type args struct {
   439  		xpub      string
   440  		change    uint32
   441  		fromIndex uint32
   442  		toIndex   uint32
   443  	}
   444  	tests := []struct {
   445  		name    string
   446  		args    args
   447  		want    []string
   448  		wantErr bool
   449  	}{
   450  		{
   451  			name: "test-xpub",
   452  			args: args{
   453  				xpub:      xpub,
   454  				change:    0,
   455  				fromIndex: 0,
   456  				toIndex:   5,
   457  			},
   458  			want: []string{
   459  				"NsdtwhD8hb8H72J7FyQpGta2sqLngrXZ",
   460  				"Nse51sBAzRTVtm48wYQLb4TH7MGAHAER",
   461  				"NsdvoFSwfh1oW238SFM6p5wL4J834Gv2",
   462  				"Nse4wVWsJ4v3jPcpE4vRkAiZLFyQSNKd",
   463  				"Nse5NzUcZybsvFQeNgqfuWmmmwCfhdxF",
   464  			},
   465  			wantErr: false,
   466  		},
   467  		{
   468  			name: "test-xprv",
   469  			args: args{
   470  				xpub:      xprv,
   471  				change:    0,
   472  				fromIndex: 0,
   473  				toIndex:   5,
   474  			},
   475  			want: []string{
   476  				"NsdtwhD8hb8H72J7FyQpGta2sqLngrXZ",
   477  				"Nse51sBAzRTVtm48wYQLb4TH7MGAHAER",
   478  				"NsdvoFSwfh1oW238SFM6p5wL4J834Gv2",
   479  				"Nse4wVWsJ4v3jPcpE4vRkAiZLFyQSNKd",
   480  				"Nse5NzUcZybsvFQeNgqfuWmmmwCfhdxF",
   481  			},
   482  			wantErr: false,
   483  		},
   484  	}
   485  
   486  	for _, tt := range tests {
   487  		t.Run(tt.name, func(t *testing.T) {
   488  			descriptor, err := parser.ParseXpub(tt.args.xpub)
   489  			if err != nil {
   490  				t.Errorf("ParseXpub() error = %v", err)
   491  				return
   492  			}
   493  			got, err := parser.DeriveAddressDescriptorsFromTo(descriptor, tt.args.change, tt.args.fromIndex, tt.args.toIndex)
   494  			if (err != nil) != tt.wantErr {
   495  				t.Errorf("DeriveAddressDescriptorsFromTo() error = %v, wantErr %v", err, tt.wantErr)
   496  				return
   497  			}
   498  			if len(got) != len(tt.want) {
   499  				t.Errorf("DeriveAddressDescriptorsFromTo() result count = %v, want %v", len(got), len(tt.want))
   500  				return
   501  			}
   502  
   503  			for i, add := range tt.want {
   504  				addStrs, ok, error := parser.GetAddressesFromAddrDesc(got[i])
   505  				if !ok || error != nil {
   506  					t.Errorf("DeriveAddressDescriptorsFromTo() fail %v - %v , %v", i, ok, error)
   507  					return
   508  				}
   509  				if len(addStrs) != 1 {
   510  					t.Errorf("DeriveAddressDescriptorsFromTo() len(adds) != 1, %v", addStrs)
   511  					return
   512  				}
   513  				if !reflect.DeepEqual(addStrs[0], add) {
   514  					t.Errorf("DeriveAddressDescriptorsFromTo() of index %v = %v, want %v", i, addStrs, add)
   515  					return
   516  				}
   517  			}
   518  		})
   519  	}
   520  
   521  }