Files
sendico/api/gateway/chain/internal/keymanager/vault/manager.go
2026-02-28 10:10:26 +01:00

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)