Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xdr: Easily created MuxedAccount objects from a G-address and a memo ID. #3677

Merged
merged 10 commits into from
Jun 25, 2021
7 changes: 2 additions & 5 deletions txnbuild/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4371,12 +4371,9 @@ func TestVerifyTxSignatureInvalid(t *testing.T) {

func TestClaimableBalanceIds(t *testing.T) {
aKeys := keypair.MustParseFull("SC4REDCJNPFAYW4SMH44KNGO5JRDQ72G4HE6GILRBSICI3M2IUOC7AAL")
// TODO: Replace with
// xdr.MuxedAccountFromAccountId(aKeys.Address(), uint64(1234)).Address()
// once https://github.com/stellar/go/pull/3677 gets in
aMuxed := "MDUJNO4HVE4YCQHV7LINPWVDQJFSAPHHUNSTT64YRBCCRZ5UYUXAWAAAAAAAAAAE2IUOE"
aMuxedAccount := NewSimpleAccount(aMuxed, int64(5894915628204034))
A := "MDUJNO4HVE4YCQHV7LINPWVDQJFSAPHHUNSTT64YRBCCRZ5UYUXAWAAAAAAAAAAE2IUOE"
B := "GCACCFMIWJAHUUASSE2WC7V6VVDLYRLSJYZ3DJEXCG523FSHTNII6KOG"
aMuxedAccount := NewSimpleAccount(A, int64(5894915628204034))

// Create the operation and submit it in a transaction.
claimableBalanceEntry := CreateClaimableBalance{
Expand Down
41 changes: 41 additions & 0 deletions xdr/muxed_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@ func MustMuxedAddressPtr(address string) *MuxedAccount {
return &muxed
}

func MuxedAccountFromAccountId(gAddress string, id uint64) (MuxedAccount, error) {
bytes, err := strkey.Decode(strkey.VersionByteAccountID, gAddress)
if err != nil {
return MuxedAccount{}, err
}

var publicKey Uint256
copy(publicKey[:], bytes)
Shaptic marked this conversation as resolved.
Show resolved Hide resolved

return NewMuxedAccount(
CryptoKeyTypeKeyTypeMuxedEd25519,
MuxedAccountMed25519{
Id: Uint64(id),
Ed25519: publicKey,
},
)
}

// SetEd25519Address modifies the receiver, setting it's value to the MuxedAccount form
// of the provided G-address. Unlike SetAddress(), it only supports G-addresses.
func (m *MuxedAccount) SetEd25519Address(address string) error {
Expand Down Expand Up @@ -133,7 +151,30 @@ func (m *MuxedAccount) GetAddress() (string, error) {
default:
return "", fmt.Errorf("Unknown muxed account type: %v", m.Type)
}
}

// GetId retrieves the underlying memo ID if this is a fully muxed account. It
// will return an error if the muxed account does not have a memo ID (i.e it's
// of the key type Ed25519).
func (m *MuxedAccount) GetId() (uint64, error) {
if m == nil {
return 0, nil
}

switch m.Type {
case CryptoKeyTypeKeyTypeEd25519:
return 0, errors.New("muxed account has no ID")

case CryptoKeyTypeKeyTypeMuxedEd25519:
ed, ok := m.GetMed25519()
if !ok {
return 0, errors.New("could not get Med25519")
}
return uint64(ed.Id), nil

default:
return 0, fmt.Errorf("Unknown muxed account type: %v", m.Type)
}
}

// ToAccountId transforms a MuxedAccount to an AccountId, dropping the
Expand Down
16 changes: 16 additions & 0 deletions xdr/muxed_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var _ = Describe("xdr.MuxedAccount#Get/SetAddress()", func() {
Expect(err).ShouldNot(HaveOccurred())
Expect(unmuxed.Type).To(Equal(CryptoKeyTypeKeyTypeEd25519))
Expect(*unmuxed.Ed25519).To(Equal(Uint256{63, 12, 52, 191, 147, 173, 13, 153, 113, 208, 76, 204, 144, 247, 5, 81, 28, 131, 138, 173, 151, 52, 164, 162, 251, 13, 122, 3, 252, 127, 232, 154}))
_, err = unmuxed.GetId()
Expect(err).Should(HaveOccurred())
muxedy := unmuxed.Address()
Expect(muxedy).To(Equal("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"))

Expand All @@ -29,17 +31,31 @@ var _ = Describe("xdr.MuxedAccount#Get/SetAddress()", func() {
Expect(muxed.Med25519.Id).To(Equal(Uint64(9223372036854775808)))
Expect(muxed.Med25519.Ed25519).To(Equal(*unmuxed.Ed25519))
muxedy = muxed.Address()
id, err := muxed.GetId()
Expect(id).To(Equal(uint64(9223372036854775808)))
Expect(muxedy).To(Equal("MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK"))

err = muxed.SetAddress("MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUQ")
Expect(err).ShouldNot(HaveOccurred())
Expect(muxed.Type).To(Equal(CryptoKeyTypeKeyTypeMuxedEd25519))
Expect(muxed.Med25519.Id).To(Equal(Uint64(0)))
Expect(muxed.Med25519.Ed25519).To(Equal(*unmuxed.Ed25519))
id, err = muxed.GetId()
Expect(id).To(Equal(uint64(0)))
muxedy = muxed.Address()
Expect(muxedy).To(Equal("MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUQ"))
})

It("returns a muxed account from an account ID and memo", func() {
accountId := "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"
expectedMuxedId := "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAABUTGI4"

muxedAccount, err := MuxedAccountFromAccountId(accountId, uint64(420))
Expect(err).ShouldNot(HaveOccurred())
Expect(muxedAccount.GetAddress()).To(Equal(expectedMuxedId))
Expect(muxedAccount.GetId()).To(Equal(uint64(420)))
})

It("returns an error when the strkey is invalid", func() {
var muxed MuxedAccount

Expand Down