Files
ark/pkg/client-sdk/wallet/singlekey/wallet.go
Pietralberto Mazza 7f937e8418 Vars and fields renaming (#387)
* Rename asp > server

* Rename pool > round

* Consolidate naming for pubkey/prvkey vars and types

* Fix

* Fix

* Fix wasm

* Rename congestionTree > vtxoTree

* Fix wasm

* Rename payment > request

* Rename congestionTree > vtxoTree after syncing with master

* Fix Send API in SDK

* Fix wasm

* Fix wasm

* Fixes

* Fixes after review

* Fix

* Fix naming

* Fix

* Fix e2e tests
2024-11-26 15:57:16 +01:00

132 lines
2.9 KiB
Go

package singlekeywallet
import (
"bytes"
"context"
"encoding/hex"
"fmt"
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
"github.com/ark-network/ark/pkg/client-sdk/types"
"github.com/ark-network/ark/pkg/client-sdk/wallet"
walletstore "github.com/ark-network/ark/pkg/client-sdk/wallet/singlekey/store"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
)
type singlekeyWallet struct {
configStore types.ConfigStore
walletStore walletstore.WalletStore
privateKey *secp256k1.PrivateKey
walletData *walletstore.WalletData
}
func (w *singlekeyWallet) GetType() string {
return wallet.SingleKeyWallet
}
func (w *singlekeyWallet) Create(
_ context.Context, password, seed string,
) (string, error) {
var privateKey *secp256k1.PrivateKey
if len(seed) <= 0 {
prvkey, err := utils.GenerateRandomPrivateKey()
if err != nil {
return "", err
}
privateKey = prvkey
} else {
prvkeyBytes, err := hex.DecodeString(seed)
if err != nil {
return "", err
}
privateKey = secp256k1.PrivKeyFromBytes(prvkeyBytes)
}
pwd := []byte(password)
passwordHash := utils.HashPassword(pwd)
pubkey := privateKey.PubKey()
buf := privateKey.Serialize()
encryptedPrivateKey, err := utils.EncryptAES256(buf, pwd)
if err != nil {
return "", err
}
walletData := walletstore.WalletData{
EncryptedPrvkey: encryptedPrivateKey,
PasswordHash: passwordHash,
PubKey: pubkey,
}
if err := w.walletStore.AddWallet(walletData); err != nil {
return "", err
}
w.walletData = &walletData
return hex.EncodeToString(privateKey.Serialize()), nil
}
func (w *singlekeyWallet) Lock(_ context.Context, password string) error {
if w.walletData == nil {
return fmt.Errorf("wallet not initialized")
}
if w.privateKey == nil {
return nil
}
pwd := []byte(password)
currentPassHash := utils.HashPassword(pwd)
if !bytes.Equal(w.walletData.PasswordHash, currentPassHash) {
return fmt.Errorf("invalid password")
}
w.privateKey = nil
return nil
}
func (w *singlekeyWallet) Unlock(
_ context.Context, password string,
) (bool, error) {
if w.walletData == nil {
return false, fmt.Errorf("wallet not initialized")
}
if w.privateKey != nil {
return true, nil
}
pwd := []byte(password)
currentPassHash := utils.HashPassword(pwd)
if !bytes.Equal(w.walletData.PasswordHash, currentPassHash) {
return false, fmt.Errorf("invalid password")
}
privateKeyBytes, err := utils.DecryptAES256(w.walletData.EncryptedPrvkey, pwd)
if err != nil {
return false, err
}
w.privateKey = secp256k1.PrivKeyFromBytes(privateKeyBytes)
return false, nil
}
func (w *singlekeyWallet) IsLocked() bool {
return w.privateKey == nil
}
func (w *singlekeyWallet) Dump(ctx context.Context) (string, error) {
if w.walletData == nil {
return "", fmt.Errorf("wallet not initialized")
}
if w.IsLocked() {
return "", fmt.Errorf("wallet is locked")
}
return hex.EncodeToString(w.privateKey.Serialize()), nil
}