85 lines
2.8 KiB
Go
85 lines
2.8 KiB
Go
package vault
|
|
|
|
import (
|
|
"context"
|
|
"math/big"
|
|
"strings"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/tech/sendico/pkg/vault/managedkey"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/tech/sendico/gateway/chain/internal/keymanager"
|
|
"github.com/tech/sendico/pkg/merrors"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
pmodel "github.com/tech/sendico/pkg/model"
|
|
)
|
|
|
|
// Config describes how to connect to Vault for managed wallet keys.
|
|
type Config = managedkey.Config
|
|
|
|
// Manager implements the keymanager.Manager contract backed by HashiCorp Vault.
|
|
type Manager struct {
|
|
logger mlogger.Logger
|
|
keys managedkey.Service
|
|
}
|
|
|
|
// New constructs a Vault-backed key manager.
|
|
func New(logger mlogger.Logger, cfg Config) (*Manager, error) {
|
|
if logger == nil {
|
|
return nil, merrors.InvalidArgument("vault key manager: logger is required")
|
|
}
|
|
keys, err := managedkey.New(managedkey.Options{
|
|
Logger: logger,
|
|
Config: managedkey.Config(cfg),
|
|
Component: "vault key manager",
|
|
DefaultKeyPrefix: "gateway/chain/wallets",
|
|
})
|
|
if err != nil {
|
|
logger.Error("Failed to initialise vault key manager", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
return &Manager{
|
|
logger: logger.Named("vault"),
|
|
keys: keys,
|
|
}, nil
|
|
}
|
|
|
|
// CreateManagedWalletKey creates a new managed wallet key and stores it in Vault.
|
|
func (m *Manager) CreateManagedWalletKey(ctx context.Context, walletRef string, network pmodel.ChainNetwork) (*keymanager.ManagedWalletKey, error) {
|
|
if network == pmodel.ChainNetworkUnspecified {
|
|
m.logger.Warn("Network missing for managed key creation", zap.String("wallet_ref", walletRef))
|
|
return nil, merrors.InvalidArgument("vault key manager: network is required")
|
|
}
|
|
networkValue := strings.TrimSpace(string(network))
|
|
if networkValue == "" {
|
|
m.logger.Warn("Network missing for managed key creation", zap.String("wallet_ref", walletRef))
|
|
return nil, merrors.InvalidArgument("vault key manager: network is required")
|
|
}
|
|
|
|
created, err := m.keys.CreateManagedWalletKey(ctx, walletRef, networkValue)
|
|
if err != nil {
|
|
m.logger.Warn("Failed to create managed wallet key", zap.String("wallet_ref", walletRef), zap.String("network", networkValue), zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
return &keymanager.ManagedWalletKey{
|
|
KeyID: created.KeyID,
|
|
Address: created.Address,
|
|
PublicKey: created.PublicKey,
|
|
}, nil
|
|
}
|
|
|
|
// SignTransaction loads the key material from Vault and signs the transaction.
|
|
func (m *Manager) SignTransaction(ctx context.Context, keyID string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
|
|
signed, err := m.keys.SignEVMTransaction(ctx, keyID, tx, chainID)
|
|
if err != nil {
|
|
m.logger.Warn("Failed to sign transaction", zap.String("key_id", keyID), zap.Error(err))
|
|
return nil, err
|
|
}
|
|
return signed, nil
|
|
}
|
|
|
|
var _ keymanager.Manager = (*Manager)(nil)
|