Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
client: create new accounts with different token account address
Browse files Browse the repository at this point in the history
GitOrigin-RevId: c5eda6da27b92b09d53e2cae0aa2e1608bc87561
  • Loading branch information
kikengineering committed Nov 26, 2020
1 parent 2015a97 commit 5054393
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 26 deletions.
14 changes: 9 additions & 5 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1108,17 +1108,19 @@ func TestClient_Kin4AccountManagement(t *testing.T) {
priv, err := NewPrivateKey()
require.NoError(t, err)

balance, err := env.client.GetBalance(context.Background(), priv.Public())
tokenAcc, _ := generateTokenAccount(ed25519.PrivateKey(priv))

balance, err := env.client.GetBalance(context.Background(), PublicKey(tokenAcc))
assert.Equal(t, ErrAccountDoesNotExist, err)
assert.Zero(t, balance)

err = env.client.CreateAccount(context.Background(), PrivateKey(priv))
err = env.client.CreateAccount(context.Background(), priv)
assert.NoError(t, err)

err = env.client.CreateAccount(context.Background(), PrivateKey(priv))
err = env.client.CreateAccount(context.Background(), priv)
assert.Equal(t, ErrAccountExists, err)

balance, err = env.client.GetBalance(context.Background(), priv.Public())
balance, err = env.client.GetBalance(context.Background(), PublicKey(tokenAcc))
assert.NoError(t, err)
assert.EqualValues(t, 10, balance)
}
Expand Down Expand Up @@ -1931,7 +1933,9 @@ func TestClient_CreateAccountMigration(t *testing.T) {

env.v4Server.Mux.Lock()
assert.Len(t, env.v4Server.Accounts, 1)
assert.NotNil(t, env.v4Server.Accounts[priv.Public().Base58()])

tokenAcc, _ := generateTokenAccount(ed25519.PrivateKey(priv))
assert.NotNil(t, env.v4Server.Accounts[PublicKey(tokenAcc).Base58()])
env.v4Server.Mux.Unlock()
}

Expand Down
13 changes: 7 additions & 6 deletions client/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ func (c *InternalClient) CreateSolanaAccount(ctx context.Context, key PrivateKey
return ErrNoSubsidizer
}

publicKey := ed25519.PublicKey(key.Public())
owner := ed25519.PublicKey(key.Public())
tokenAcc, tokenAccKey := generateTokenAccount(ed25519.PrivateKey(key))
tokenProgram := config.TokenProgram.Value

var subsidizerID ed25519.PublicKey
Expand All @@ -272,17 +273,17 @@ func (c *InternalClient) CreateSolanaAccount(ctx context.Context, key PrivateKey
}

tx := solana.NewTransaction(subsidizerID,
system.CreateAccount(subsidizerID, publicKey, tokenProgram, minBalance, token.AccountSize),
token.InitializeAccount(publicKey, config.Token.Value, publicKey),
token.SetAuthority(publicKey, publicKey, subsidizerID, token.AuthorityTypeCloseAccount),
system.CreateAccount(subsidizerID, tokenAcc, tokenProgram, minBalance, token.AccountSize),
token.InitializeAccount(tokenAcc, config.Token.Value, owner),
token.SetAuthority(tokenAcc, owner, subsidizerID, token.AuthorityTypeCloseAccount),
)
tx.SetBlockhash(recentBlockhash)

var signers []ed25519.PrivateKey
if subsidizer != nil {
signers = []ed25519.PrivateKey{ed25519.PrivateKey(subsidizer), ed25519.PrivateKey(key)}
signers = []ed25519.PrivateKey{ed25519.PrivateKey(subsidizer), ed25519.PrivateKey(key), tokenAccKey}
} else {
signers = []ed25519.PrivateKey{ed25519.PrivateKey(key)}
signers = []ed25519.PrivateKey{ed25519.PrivateKey(key), tokenAccKey}
}
err = tx.Sign(signers...)
if err != nil {
Expand Down
36 changes: 21 additions & 15 deletions client/internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,16 @@ func TestInternal_SolanaAccountRoundTrip(t *testing.T) {

priv, err := NewPrivateKey()
require.NoError(t, err)
tokenAcc, _ := generateTokenAccount(ed25519.PrivateKey(priv))

accountInfo, err := env.internal.GetSolanaAccountInfo(context.Background(), priv.Public(), commonpbv4.Commitment_SINGLE)
accountInfo, err := env.internal.GetSolanaAccountInfo(context.Background(), PublicKey(tokenAcc), commonpbv4.Commitment_SINGLE)
assert.Nil(t, accountInfo)
assert.Equal(t, ErrAccountDoesNotExist, err)

assert.NoError(t, env.internal.CreateSolanaAccount(context.Background(), priv, commonpbv4.Commitment_SINGLE, nil))
assert.Equal(t, ErrAccountExists, env.internal.CreateSolanaAccount(context.Background(), priv, commonpbv4.Commitment_SINGLE, nil))

accountInfo, err = env.internal.GetSolanaAccountInfo(context.Background(), priv.Public(), commonpbv4.Commitment_SINGLE)
accountInfo, err = env.internal.GetSolanaAccountInfo(context.Background(), PublicKey(tokenAcc), commonpbv4.Commitment_SINGLE)
assert.NoError(t, err)
assert.NotNil(t, accountInfo)
assert.EqualValues(t, 10, accountInfo.Balance)
Expand All @@ -509,26 +510,27 @@ func TestInternal_SolanaAccountRoundTrip(t *testing.T) {

tx := solana.Transaction{}
require.NoError(t, tx.Unmarshal(createReq.Transaction.Value))
assert.Len(t, tx.Signatures, 2)
assert.Len(t, tx.Signatures, 3)
ed25519.Verify(ed25519.PublicKey(priv.Public()), tx.Message.Marshal(), tx.Signatures[1][:])
ed25519.Verify(tokenAcc, tx.Message.Marshal(), tx.Signatures[2][:])

sysCreate, err := system.DecompileCreateAccount(tx.Message, 0)
require.NoError(t, err)
assert.Equal(t, subsidizer, sysCreate.Funder)
assert.EqualValues(t, priv.Public(), sysCreate.Address)
assert.EqualValues(t, tokenAcc, sysCreate.Address)
assert.Equal(t, tokenProgram, sysCreate.Owner)
assert.Equal(t, testserver.MinBalanceForRentException, sysCreate.Lamports)
assert.Equal(t, token.AccountSize, int(sysCreate.Size))

tokenInit, err := token.DecompileInitializeAccount(tx.Message, 1)
require.NoError(t, err)
assert.EqualValues(t, priv.Public(), tokenInit.Account)
assert.EqualValues(t, tokenAcc, tokenInit.Account)
assert.Equal(t, tokenKey, tokenInit.Mint)
assert.EqualValues(t, priv.Public(), tokenInit.Owner)

setAuth, err := token.DecompileSetAuthority(tx.Message, 2)
require.NoError(t, err)
assert.EqualValues(t, priv.Public(), setAuth.Account)
assert.EqualValues(t, tokenAcc, setAuth.Account)
assert.EqualValues(t, priv.Public(), setAuth.CurrentAuthority)
assert.Equal(t, subsidizer, setAuth.NewAuthority)
assert.Equal(t, token.AuthorityTypeCloseAccount, setAuth.Type)
Expand All @@ -542,6 +544,7 @@ func TestInternal_CreateNoServiceSubsidizer(t *testing.T) {

priv, err := NewPrivateKey()
require.NoError(t, err)
tokenAcc, _ := generateTokenAccount(ed25519.PrivateKey(priv))

err = env.internal.CreateSolanaAccount(context.Background(), priv, commonpbv4.Commitment_SINGLE, nil)
require.Equal(t, ErrNoSubsidizer, err)
Expand All @@ -558,26 +561,28 @@ func TestInternal_CreateNoServiceSubsidizer(t *testing.T) {

tx := solana.Transaction{}
require.NoError(t, tx.Unmarshal(createReq.Transaction.Value))
assert.Len(t, tx.Signatures, 2)
assert.Len(t, tx.Signatures, 3)
ed25519.Verify(ed25519.PublicKey(subsidizer.Public()), tx.Message.Marshal(), tx.Signatures[0][:])
ed25519.Verify(ed25519.PublicKey(priv.Public()), tx.Message.Marshal(), tx.Signatures[1][:])
ed25519.Verify(tokenAcc, tx.Message.Marshal(), tx.Signatures[2][:])

sysCreate, err := system.DecompileCreateAccount(tx.Message, 0)
require.NoError(t, err)
assert.EqualValues(t, subsidizer.Public(), sysCreate.Funder)
assert.EqualValues(t, priv.Public(), sysCreate.Address)
assert.EqualValues(t, tokenAcc, sysCreate.Address)
assert.Equal(t, tokenProgram, sysCreate.Owner)
assert.Equal(t, testserver.MinBalanceForRentException, sysCreate.Lamports)
assert.Equal(t, token.AccountSize, int(sysCreate.Size))

tokenInit, err := token.DecompileInitializeAccount(tx.Message, 1)
require.NoError(t, err)
assert.EqualValues(t, priv.Public(), tokenInit.Account)
assert.EqualValues(t, tokenAcc, tokenInit.Account)
assert.Equal(t, tokenKey, tokenInit.Mint)
assert.EqualValues(t, priv.Public(), tokenInit.Owner)

setAuth, err := token.DecompileSetAuthority(tx.Message, 2)
require.NoError(t, err)
assert.EqualValues(t, priv.Public(), setAuth.Account)
assert.EqualValues(t, tokenAcc, setAuth.Account)
assert.EqualValues(t, priv.Public(), setAuth.CurrentAuthority)
assert.EqualValues(t, subsidizer.Public(), setAuth.NewAuthority)
assert.Equal(t, token.AuthorityTypeCloseAccount, setAuth.Type)
Expand Down Expand Up @@ -951,23 +956,24 @@ func TestInternal_RequestAirdrop(t *testing.T) {
env, cleanup := setup(t)
defer cleanup()

sender, err := NewPrivateKey()
priv, err := NewPrivateKey()
require.NoError(t, err)
tokenAcc, _ := generateTokenAccount(ed25519.PrivateKey(priv))

// Account doesn't exist
txID, err := env.internal.RequestAirdrop(context.Background(), sender.Public(), 10, commonpbv4.Commitment_SINGLE)
txID, err := env.internal.RequestAirdrop(context.Background(), PublicKey(tokenAcc), 10, commonpbv4.Commitment_SINGLE)
assert.Equal(t, ErrAccountDoesNotExist, err)
assert.Nil(t, txID)

setServiceConfigResp(t, env.v4Server, true)
require.NoError(t, env.internal.CreateSolanaAccount(context.Background(), sender, commonpbv4.Commitment_SINGLE, nil))
require.NoError(t, env.internal.CreateSolanaAccount(context.Background(), priv, commonpbv4.Commitment_SINGLE, nil))

// Too much money
txID, err = env.internal.RequestAirdrop(context.Background(), sender.Public(), testserver.MaxAirdrop+1, commonpbv4.Commitment_SINGLE)
txID, err = env.internal.RequestAirdrop(context.Background(), PublicKey(tokenAcc), testserver.MaxAirdrop+1, commonpbv4.Commitment_SINGLE)
assert.Equal(t, ErrInsufficientBalance, err)
assert.Nil(t, txID)

txID, err = env.internal.RequestAirdrop(context.Background(), sender.Public(), testserver.MaxAirdrop, commonpbv4.Commitment_SINGLE)
txID, err = env.internal.RequestAirdrop(context.Background(), PublicKey(tokenAcc), testserver.MaxAirdrop, commonpbv4.Commitment_SINGLE)
require.NoError(t, err)
assert.NotNil(t, txID)
}
Expand Down
12 changes: 12 additions & 0 deletions client/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package client

import (
"crypto/ed25519"
"crypto/sha256"
)

func generateTokenAccount(ownerKey ed25519.PrivateKey) (ed25519.PublicKey, ed25519.PrivateKey) {
tokenAccSeed := sha256.Sum256(ownerKey)
tokenAccKey := ed25519.NewKeyFromSeed(tokenAccSeed[:])
return tokenAccKey.Public().(ed25519.PublicKey), tokenAccKey
}

0 comments on commit 5054393

Please sign in to comment.