Skip to content

Commit 8c451d1

Browse files
refactor(wallet): ensure classic address derivation when master address is provided on FromSeed function
1 parent 1479a80 commit 8c451d1

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

xrpl/wallet/wallet.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import (
1818
"github.com/tyler-smith/go-bip39"
1919
)
2020

21+
var (
22+
ErrAddressTagNotZero = errors.New("address tag is not zero")
23+
)
24+
2125
// A utility for deriving a wallet composed of a keypair (publicKey/privateKey).
2226
// A wallet can be derived from either a seed, mnemonic, or entropy (array of random numbers).
2327
// It provides functionality to sign/verify transactions offline.
@@ -47,8 +51,12 @@ func FromSeed(seed string, masterAddress string) (Wallet, error) {
4751
}
4852

4953
var classicAddr types.Address
50-
if ok := addresscodec.IsValidClassicAddress(masterAddress); ok {
51-
classicAddr = types.Address(masterAddress)
54+
55+
if masterAddress != "" {
56+
classicAddr, err = ensureClassicAddress(masterAddress)
57+
if err != nil {
58+
return Wallet{}, err
59+
}
5260
} else {
5361
addr, err := keypairs.DeriveClassicAddress(pubKey)
5462
if err != nil {
@@ -212,6 +220,26 @@ func (w *Wallet) computeSignature(encodedTx string) (string, error) {
212220
return txHash, nil
213221
}
214222

223+
// Ensures that the address is a classic address.
224+
// If the address is an x-address with a tag of 0 (no tag), it will be converted to a classic address.
225+
// If the address is not a classic address, it will be returned as is.
226+
func ensureClassicAddress(account string) (types.Address, error) {
227+
if ok := addresscodec.IsValidXAddress(account); ok {
228+
classicAddr, tag, _, err := addresscodec.XAddressToClassicAddress(account)
229+
if err != nil {
230+
return "", err
231+
}
232+
233+
if tag != 0 {
234+
return "", ErrAddressTagNotZero
235+
}
236+
237+
return types.Address(classicAddr), nil
238+
}
239+
240+
return types.Address(account), nil
241+
}
242+
215243
// Verifies a signed transaction offline.
216244
// Returns a boolean indicating if the transaction is valid and an error if it is not.
217245
// If the transaction is signed with a public key, the public key must match the one in the transaction.

xrpl/wallet/wallet_test.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ func TestNewWalletFromSeed(t *testing.T) {
1212
PublicKey string
1313
PrivateKey string
1414
ClassicAddress types.Address
15+
MasterAddress types.Address
1516
}{
1617
{
1718
Seed: "sEd7io6yt5dFJrcePgRiFVHvmkJhJD1",
@@ -31,10 +32,16 @@ func TestNewWalletFromSeed(t *testing.T) {
3132
PrivateKey: "ED2C0EAB27E1411DBB8FACC88D531A69967DA0E45AC7821A4041A5AEE24BB8FF29",
3233
ClassicAddress: "rs7cvHcsEF54DEs2y24Tpph3Xf71xUUrFu",
3334
},
35+
{
36+
Seed: "sh8i92YRnEjJy3fpFkL8txQSCVo79",
37+
PublicKey: "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
38+
PrivateKey: "004265A28F3E18340A490421D47B2EB8DBC2C0BF2C24CEFEA971B61CED2CABD233",
39+
MasterAddress: "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
40+
},
3441
}
3542

3643
for _, tc := range testCases {
37-
wallet, err := FromSeed(tc.Seed, "")
44+
wallet, err := FromSeed(tc.Seed, tc.MasterAddress.String())
3845
if err != nil {
3946
t.Errorf("Error generating wallet from seed: %s", err)
4047
}
@@ -47,8 +54,14 @@ func TestNewWalletFromSeed(t *testing.T) {
4754
t.Errorf("Private key does not match expected value. Expected: %s, got: %s", tc.PrivateKey, wallet.PrivateKey)
4855
}
4956

50-
if wallet.ClassicAddress != tc.ClassicAddress {
51-
t.Errorf("Classic address does not match expected value. Expected: %s, got: %s", tc.ClassicAddress, wallet.ClassicAddress)
57+
if tc.MasterAddress != "" {
58+
if wallet.ClassicAddress != tc.MasterAddress {
59+
t.Errorf("Classic address does not match expected value. Expected: %s, got: %s", tc.MasterAddress, wallet.ClassicAddress)
60+
}
61+
} else {
62+
if wallet.ClassicAddress != tc.ClassicAddress {
63+
t.Errorf("Classic address does not match expected value. Expected: %s, got: %s", tc.ClassicAddress, wallet.ClassicAddress)
64+
}
5265
}
5366
}
5467
}

0 commit comments

Comments
 (0)