frostfs-s3-lifecycler/internal/credential/walletsource/wallet.go
Denis Kirillov d8b5cd5fc2 [#3] Add job fetcher
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2024-07-22 13:32:04 +03:00

77 lines
1.8 KiB
Go

package walletsource
import (
"context"
"errors"
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-s3-lifecycler/internal/lifecycle"
"github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet"
)
type Source struct {
keys []*keys.PrivateKey
}
type Wallet struct {
Path string
Address string
Passphrase string
}
var _ lifecycle.CredentialSource = (*Source)(nil)
func New(wallets []Wallet) (*Source, error) {
privateKeys := make([]*keys.PrivateKey, len(wallets))
var err error
for i, w := range wallets {
if privateKeys[i], err = readPrivateKey(w); err != nil {
return nil, fmt.Errorf("read private key from wallet '%s': %w", w.Path, err)
}
}
return &Source{keys: privateKeys}, nil
}
func (s *Source) Credentials(_ context.Context, pk *keys.PublicKey) (*keys.PrivateKey, error) {
for _, key := range s.keys {
if key.PublicKey().Equal(pk) {
return key, nil
}
}
return nil, errors.New("key not found")
}
func readPrivateKey(walletInfo Wallet) (*keys.PrivateKey, error) {
w, err := wallet.NewWalletFromFile(walletInfo.Path)
if err != nil {
return nil, fmt.Errorf("parse wallet: %w", err)
}
var addr util.Uint160
if walletInfo.Address == "" {
addr = w.GetChangeAddress()
} else {
addr, err = flags.ParseAddress(walletInfo.Address)
if err != nil {
return nil, fmt.Errorf("invalid address")
}
}
acc := w.GetAccount(addr)
if acc == nil {
return nil, fmt.Errorf("couldn't find wallet account for %s", address.Uint160ToString(addr))
}
if err = acc.Decrypt(walletInfo.Passphrase, w.Scrypt); err != nil {
return nil, fmt.Errorf("couldn't decrypt account: %w", err)
}
return acc.PrivateKey(), nil
}