code.vegaprotocol.io/vega@v0.79.0/core/examples/nullchain/wallet.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package nullchain
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  
    23  	vgrand "code.vegaprotocol.io/vega/libs/rand"
    24  	api "code.vegaprotocol.io/vega/protos/vega/api/v1"
    25  	walletpb "code.vegaprotocol.io/vega/protos/vega/wallet/v1"
    26  	storev1 "code.vegaprotocol.io/vega/wallet/wallet/store/v1"
    27  	"code.vegaprotocol.io/vega/wallet/wallets"
    28  )
    29  
    30  var ErrFailedSubmission = errors.New("failed to submit transaction")
    31  
    32  type Party struct {
    33  	wallet string
    34  	pubkey string
    35  }
    36  
    37  type Wallet struct {
    38  	handler    *wallets.Handler
    39  	store      *storev1.FileStore
    40  	passphrase string
    41  }
    42  
    43  func NewWallet(root, passphrase string) *Wallet {
    44  	store, err := storev1.InitialiseStore(root, false)
    45  	if err != nil {
    46  		panic(fmt.Errorf("could not initialise the wallet store: %w", err))
    47  	}
    48  
    49  	return &Wallet{
    50  		handler:    wallets.NewHandler(store),
    51  		store:      store,
    52  		passphrase: passphrase,
    53  	}
    54  }
    55  
    56  func (w *Wallet) MakeParties(n uint64) ([]*Party, error) {
    57  	parties := make([]*Party, 0, n)
    58  
    59  	var err error
    60  	defer func() {
    61  		if err != nil {
    62  			w.DeleteParties(parties)
    63  		}
    64  	}()
    65  	// make n wallet's each with a single key
    66  	passphrase := "pin"
    67  
    68  	for i := uint64(0); i < n; i++ {
    69  		walletName := vgrand.RandomStr(10)
    70  		if _, err = w.handler.CreateWallet(walletName, passphrase); err != nil {
    71  			return nil, err
    72  		}
    73  		if err := w.handler.LoginWallet(walletName, passphrase); err != nil {
    74  			return nil, err
    75  		}
    76  
    77  		kp, err := w.handler.GenerateKeyPair(walletName, passphrase, nil)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  
    82  		parties = append(parties, &Party{
    83  			wallet: walletName,
    84  			pubkey: kp.PublicKey(),
    85  		})
    86  	}
    87  
    88  	return parties, nil
    89  }
    90  
    91  func (w *Wallet) DeleteParties(party []*Party) {
    92  	ctx := context.Background()
    93  	for _, party := range party {
    94  		_ = w.store.DeleteWallet(ctx, party.wallet)
    95  	}
    96  }
    97  
    98  func (w *Wallet) Login(wallet string) {
    99  	_ = w.handler.LoginWallet(wallet, w.passphrase)
   100  }
   101  
   102  func (w *Wallet) SubmitTransaction(conn *Connection, party *Party, txn *walletpb.SubmitTransactionRequest) error {
   103  	blockHeight, _ := conn.LastBlockHeight()
   104  
   105  	w.Login(party.wallet)
   106  
   107  	// Add public key to the transaction
   108  	txn.PubKey = party.pubkey
   109  
   110  	chainID, err := conn.NetworkChainID()
   111  	if err != nil {
   112  		return err
   113  	}
   114  
   115  	signedTx, err := w.handler.SignTx(party.wallet, txn, blockHeight, chainID)
   116  	if err != nil {
   117  		return err
   118  	}
   119  
   120  	submitReq := &api.SubmitTransactionRequest{
   121  		Tx:   signedTx,
   122  		Type: api.SubmitTransactionRequest_TYPE_SYNC,
   123  	}
   124  	submitResponse, err := conn.core.SubmitTransaction(context.Background(), submitReq)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	if !submitResponse.Success {
   129  		return ErrFailedSubmission
   130  	}
   131  
   132  	return nil
   133  }
   134  
   135  func (w *Wallet) Close() {
   136  	w.store.Close()
   137  }