From fc9f2c20bb41c8542edc3bbecaf261c44a52122d Mon Sep 17 00:00:00 2001 From: anhthii Date: Fri, 17 May 2024 22:19:31 +0700 Subject: [PATCH 1/4] Add eddsa signing session --- pkg/eventconsumer/events.go | 1 + ...ng_session.go => ecdsa_signing_session.go} | 9 +- pkg/mpc/eddsa_signing_session.go | 182 ++++++++++++++++++ pkg/mpc/key_type.go | 8 + 4 files changed, 198 insertions(+), 2 deletions(-) rename pkg/mpc/{signing_session.go => ecdsa_signing_session.go} (95%) create mode 100644 pkg/mpc/eddsa_signing_session.go create mode 100644 pkg/mpc/key_type.go diff --git a/pkg/eventconsumer/events.go b/pkg/eventconsumer/events.go index 369acce..2af4059 100644 --- a/pkg/eventconsumer/events.go +++ b/pkg/eventconsumer/events.go @@ -1,6 +1,7 @@ package eventconsumer type SignTxMessage struct { + KeyType string `json:"key_type"` WalletID string `json:"wallet_id"` NetworkInternalCode string `json:"network_internal_code"` TxID string `json:"tx_id"` diff --git a/pkg/mpc/signing_session.go b/pkg/mpc/ecdsa_signing_session.go similarity index 95% rename from pkg/mpc/signing_session.go rename to pkg/mpc/ecdsa_signing_session.go index b44f335..7faac99 100644 --- a/pkg/mpc/signing_session.go +++ b/pkg/mpc/ecdsa_signing_session.go @@ -22,6 +22,7 @@ const ( SignSuccessTopic = "mpc.mpc_sign_success.completed" ) +// Ecdsa signing session type SigningSession struct { Session endCh chan *common.SignatureData @@ -71,12 +72,15 @@ func NewSigningSession( keyinfoStore: keyinfoStore, topicComposer: &TopicComposer{ ComposeBroadcastTopic: func() string { - return fmt.Sprintf("sign:broadcast:%s", walletID) + return fmt.Sprintf("sign:ecdsa:broadcast:%s", walletID) }, ComposeDirectTopic: func(nodeID string) string { - return fmt.Sprintf("sign:direct:%s:%s", walletID, nodeID) + return fmt.Sprintf("sign:ecdsa:direct:%s:%s", walletID, nodeID) }, }, + composeKey: func(waleltID string) string { + return fmt.Sprintf("ecdsa:%s", waleltID) + }, successQueue: succesQueue, }, endCh: make(chan *common.SignatureData), @@ -176,6 +180,7 @@ func (s *SigningSession) Sign(done func()) { }) if err != nil { s.ErrCh <- errors.Wrap(err, "Failed to publish sign success message") + return } diff --git a/pkg/mpc/eddsa_signing_session.go b/pkg/mpc/eddsa_signing_session.go new file mode 100644 index 0000000..b6615f1 --- /dev/null +++ b/pkg/mpc/eddsa_signing_session.go @@ -0,0 +1,182 @@ +package mpc + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/bnb-chain/tss-lib/v2/common" + "github.com/bnb-chain/tss-lib/v2/eddsa/keygen" + "github.com/bnb-chain/tss-lib/v2/eddsa/signing" + "github.com/bnb-chain/tss-lib/v2/tss" + "github.com/cryptoniumX/mpcium/pkg/common/errors" + "github.com/cryptoniumX/mpcium/pkg/keyinfo" + "github.com/cryptoniumX/mpcium/pkg/kvstore" + "github.com/cryptoniumX/mpcium/pkg/logger" + "github.com/cryptoniumX/mpcium/pkg/messaging" + "github.com/decred/dcrd/dcrec/edwards/v2" + "github.com/samber/lo" +) + +type EDDSASigningSession struct { + Session + endCh chan *common.SignatureData + data *keygen.LocalPartySaveData + tx *big.Int + txID string + networkInternalCode string +} + +func NewEDDSASigningSession( + walletID string, + txID string, + networkInternalCode string, + pubSub messaging.PubSub, + direct messaging.DirectMessaging, + participantPeerIDs []string, + selfID *tss.PartyID, + partyIDs []*tss.PartyID, + threshold int, + kvstore kvstore.KVStore, + keyinfoStore keyinfo.Store, + succesQueue messaging.MessageQueue, +) *EDDSASigningSession { + return &EDDSASigningSession{ + Session: Session{ + walletID: walletID, + pubSub: pubSub, + direct: direct, + threshold: threshold, + participantPeerIDs: participantPeerIDs, + selfPartyID: selfID, + partyIDs: partyIDs, + outCh: make(chan tss.Message), + ErrCh: make(chan error), + // preParams: preParams, + kvstore: kvstore, + keyinfoStore: keyinfoStore, + topicComposer: &TopicComposer{ + ComposeBroadcastTopic: func() string { + return fmt.Sprintf("sign:eddsa:broadcast:%s", walletID) + }, + ComposeDirectTopic: func(nodeID string) string { + return fmt.Sprintf("sign:eddsa:direct:%s:%s", walletID, nodeID) + }, + }, + composeKey: func(waleltID string) string { + return fmt.Sprintf("eddsa:%s", waleltID) + }, + successQueue: succesQueue, + }, + endCh: make(chan *common.SignatureData), + txID: txID, + networkInternalCode: networkInternalCode, + } +} + +func (s *EDDSASigningSession) Init(tx *big.Int) error { + logger.Infof("Initializing signing session with partyID: %s, peerIDs %s", s.selfPartyID, s.partyIDs) + ctx := tss.NewPeerContext(s.partyIDs) + params := tss.NewParameters(tss.Edwards(), ctx, s.selfPartyID, len(s.partyIDs), s.threshold) + + keyData, err := s.kvstore.Get(s.composeKey(s.walletID)) + if err != nil { + return errors.Wrap(err, "Failed to get wallet data from KVStore") + } + + keyInfo, err := s.keyinfoStore.Get(s.composeKey(s.walletID)) + if err != nil { + return errors.Wrap(err, "Failed to get key info data") + } + + if len(s.participantPeerIDs) < keyInfo.Threshold+1 { + return fmt.Errorf("Not enough participants to sign, expected %d, got %d", keyInfo.Threshold+1, len(s.participantPeerIDs)) + } + + // check if t+1 participants are present + result := lo.Intersect(s.participantPeerIDs, keyInfo.ParticipantPeerIDs) + if len(result) < keyInfo.Threshold+1 { + return fmt.Errorf( + "Incompatible peerIDs to participate in signing. Current participants: %v, expected participants: %v", + s.participantPeerIDs, + keyInfo.ParticipantPeerIDs, + ) + } + + logger.Info("Have enough participants to sign", "participants", s.participantPeerIDs) + // Check if all the participants of the key are present + var data keygen.LocalPartySaveData + err = json.Unmarshal(keyData, &data) + if err != nil { + return errors.Wrap(err, "Failed to unmarshal wallet data") + } + + s.party = signing.NewLocalParty(tx, params, data, s.outCh, s.endCh) + s.data = &data + s.tx = tx + logger.Info("Initialized sigining session successfully!") + return nil +} + +func (s *EDDSASigningSession) Sign(done func()) { + logger.Info("Starting signing", "walletID", s.walletID) + go func() { + if err := s.party.Start(); err != nil { + s.ErrCh <- err + } + }() + + for { + + select { + case msg := <-s.outCh: + s.handleTssMessage(msg) + case sig := <-s.endCh: + publicKey := *s.data.EDDSAPub + pk := edwards.PublicKey{ + Curve: tss.Edwards(), + X: publicKey.X(), + Y: publicKey.Y(), + } + + ok := edwards.Verify(&pk, s.tx.Bytes(), new(big.Int).SetBytes(sig.R), new(big.Int).SetBytes(sig.S)) + if !ok { + s.ErrCh <- errors.New("Failed to verify signature") + return + } + + r := SigningSuccessEvent{ + NetworkInternalCode: s.networkInternalCode, + WalletID: s.walletID, + TxID: s.txID, + R: sig.R, + S: sig.S, + SignatureRecovery: sig.SignatureRecovery, + } + + bytes, err := json.Marshal(r) + if err != nil { + s.ErrCh <- errors.Wrap(err, "Failed to marshal raw signature") + return + } + + err = s.successQueue.Enqueue(SignSuccessTopic, bytes, &messaging.EnqueueOptions{ + IdempotententKey: s.txID, + }) + if err != nil { + s.ErrCh <- errors.Wrap(err, "Failed to publish sign success message") + return + } + + logger.Info("[SIGN] Sign successfully", "walletID", s.walletID) + err = s.Close() + if err != nil { + logger.Error("Failed to close session", err) + } + + done() + return + } + + } +} diff --git a/pkg/mpc/key_type.go b/pkg/mpc/key_type.go new file mode 100644 index 0000000..756efa8 --- /dev/null +++ b/pkg/mpc/key_type.go @@ -0,0 +1,8 @@ +package mpc + +type KeyType string + +const ( + KeyTypeSecp256k1 KeyType = "secp256k1" + KeyTypeEd25519 = "ed25519" +) From efc5125ed60ca774c382a5bcb01bb6de6fa548f0 Mon Sep 17 00:00:00 2001 From: anhthii Date: Fri, 17 May 2024 22:58:21 +0700 Subject: [PATCH 2/4] Support eddsa signing --- pkg/eventconsumer/consumer.go | 31 +++++++++++++++++++++++-------- pkg/eventconsumer/events.go | 17 ++++++++++++----- pkg/mpc/ecdsa_signing_session.go | 12 ++++++++++++ pkg/mpc/node.go | 26 ++++++++++++++++++++++++++ pkg/mpc/session.go | 4 ++++ 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/pkg/eventconsumer/consumer.go b/pkg/eventconsumer/consumer.go index 5f8c4da..07fee6d 100644 --- a/pkg/eventconsumer/consumer.go +++ b/pkg/eventconsumer/consumer.go @@ -167,13 +167,28 @@ func (ec *eventConsumer) consumeTxSigningEvent() error { logger.Info("Received signing event", "waleltID", msg.WalletID, "tx", msg.Tx) threshold := 1 - session, err := ec.node.CreateSigningSession( - msg.WalletID, - msg.TxID, - msg.NetworkInternalCode, - threshold, - ec.signingSuccessQueue, - ) + + var session mpc.ISigningSession + switch msg.KeyType { + case KeyTypeSecp256k1: + session, err = ec.node.CreateSigningSession( + msg.WalletID, + msg.TxID, + msg.NetworkInternalCode, + threshold, + ec.signingSuccessQueue, + ) + case KeyTypeEd25519: + session, err = ec.node.CreateEDDSASigningSession( + msg.WalletID, + msg.TxID, + msg.NetworkInternalCode, + threshold, + ec.signingSuccessQueue, + ) + + } + if err != nil { logger.Error("Failed to create signing session", err) return @@ -192,7 +207,7 @@ func (ec *eventConsumer) consumeTxSigningEvent() error { select { case <-ctx.Done(): return - case err := <-session.ErrCh: + case err := <-session.ErrChan(): logger.Error("Signing session error", err) } } diff --git a/pkg/eventconsumer/events.go b/pkg/eventconsumer/events.go index 2af4059..2c8897b 100644 --- a/pkg/eventconsumer/events.go +++ b/pkg/eventconsumer/events.go @@ -1,9 +1,16 @@ package eventconsumer +type KeyType string + +const ( + KeyTypeSecp256k1 KeyType = "secp256k1" + KeyTypeEd25519 = "ed25519" +) + type SignTxMessage struct { - KeyType string `json:"key_type"` - WalletID string `json:"wallet_id"` - NetworkInternalCode string `json:"network_internal_code"` - TxID string `json:"tx_id"` - Tx []byte `json:"tx"` + KeyType KeyType `json:"key_type"` + WalletID string `json:"wallet_id"` + NetworkInternalCode string `json:"network_internal_code"` + TxID string `json:"tx_id"` + Tx []byte `json:"tx"` } diff --git a/pkg/mpc/ecdsa_signing_session.go b/pkg/mpc/ecdsa_signing_session.go index 7faac99..831fccb 100644 --- a/pkg/mpc/ecdsa_signing_session.go +++ b/pkg/mpc/ecdsa_signing_session.go @@ -32,6 +32,18 @@ type SigningSession struct { networkInternalCode string } +type ISession interface { + ErrChan() <-chan error + ListenToIncomingMessageAsync() +} + +type ISigningSession interface { + ISession + + Init(tx *big.Int) error + Sign(done func()) +} + type SigningSuccessEvent struct { NetworkInternalCode string `json:"network_internal_code"` WalletID string `json:"wallet_id"` diff --git a/pkg/mpc/node.go b/pkg/mpc/node.go index 7a9d59c..468c0a2 100644 --- a/pkg/mpc/node.go +++ b/pkg/mpc/node.go @@ -163,6 +163,32 @@ func (p *Node) CreateSigningSession( return session, nil } +func (p *Node) CreateEDDSASigningSession( + walletID string, + txID string, + networkInternalCode string, + threshold int, + successQueue messaging.MessageQueue, +) (*EDDSASigningSession, error) { + readyPeerIDs := p.peerRegistry.GetReadyPeersIncludeSelf() + selfPartyID, allPartyIDs := p.generatePartyIDs(PurposeKeygen, readyPeerIDs) + session := NewEDDSASigningSession( + walletID, + txID, + networkInternalCode, + p.pubSub, + p.direct, + readyPeerIDs, + selfPartyID, + allPartyIDs, + threshold, + p.kvstore, + p.keyinfoStore, + successQueue, + ) + return session, nil +} + func (p *Node) generatePartyIDs(purpose string, readyPeerIDs []string) (self *tss.PartyID, all []*tss.PartyID) { var selfPartyID *tss.PartyID partyIDs := make([]*tss.PartyID, len(readyPeerIDs)) diff --git a/pkg/mpc/session.go b/pkg/mpc/session.go index b7e13ef..5400131 100644 --- a/pkg/mpc/session.go +++ b/pkg/mpc/session.go @@ -169,3 +169,7 @@ func (s *Session) Close() error { func (s *Session) GetPubKeyResult() []byte { return s.pubkeyBytes } + +func (s *Session) ErrChan() <-chan error { + return s.ErrCh +} From c915a5f7f925b85af67f0a5dd6c5ba29f3eee818 Mon Sep 17 00:00:00 2001 From: anhthii Date: Sat, 18 May 2024 15:00:29 +0700 Subject: [PATCH 3/4] Return only Signature in siging success event --- go.mod | 2 -- go.sum | 4 --- pkg/mpc/ecdsa_signing_session.go | 8 ++++-- pkg/mpc/eddsa_rounds.go | 43 ++++++++++++++++++++------------ pkg/mpc/eddsa_signing_session.go | 5 ++-- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 37cdf69..f9c6ba7 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/avast/retry-go v3.0.0+incompatible github.com/bnb-chain/tss-lib/v2 v2.0.2 github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/decred/base58 v1.0.5 github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3 github.com/dgraph-io/badger/v4 v4.2.0 github.com/google/uuid v1.4.0 @@ -27,7 +26,6 @@ require ( github.com/btcsuite/btcutil v1.0.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.0 // indirect diff --git a/go.sum b/go.sum index 80745d3..01a3ba9 100644 --- a/go.sum +++ b/go.sum @@ -63,11 +63,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/base58 v1.0.5 h1:hwcieUM3pfPnE/6p3J100zoRfGkQxBulZHo7GZfOqic= -github.com/decred/base58 v1.0.5/go.mod h1:s/8lukEHFA6bUQQb/v3rjUySJ2hu+RioCzLukAVkrfw= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3 h1:l/lhv2aJCUignzls81+wvga0TFlyoZx8QxRMQgXpZik= github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3/go.mod h1:AKpV6+wZ2MfPRJnTbQ6NPgWrKzbe9RCIlCF/FKzMtM8= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= diff --git a/pkg/mpc/ecdsa_signing_session.go b/pkg/mpc/ecdsa_signing_session.go index 831fccb..ef03039 100644 --- a/pkg/mpc/ecdsa_signing_session.go +++ b/pkg/mpc/ecdsa_signing_session.go @@ -51,6 +51,9 @@ type SigningSuccessEvent struct { R []byte `json:"r"` S []byte `json:"s"` SignatureRecovery []byte `json:"signature_recovery"` + + // TODO: define two separate events for eddsa and ecdsa + Signature []byte `json:"signature"` } func NewSigningSession( @@ -93,6 +96,7 @@ func NewSigningSession( composeKey: func(waleltID string) string { return fmt.Sprintf("ecdsa:%s", waleltID) }, + getRoundFunc: GetEcdsaMsgRound, successQueue: succesQueue, }, endCh: make(chan *common.SignatureData), @@ -106,12 +110,12 @@ func (s *SigningSession) Init(tx *big.Int) error { ctx := tss.NewPeerContext(s.partyIDs) params := tss.NewParameters(tss.S256(), ctx, s.selfPartyID, len(s.partyIDs), s.threshold) - keyData, err := s.kvstore.Get(s.walletID) + keyData, err := s.kvstore.Get(s.composeKey(s.walletID)) if err != nil { return errors.Wrap(err, "Failed to get wallet data from KVStore") } - keyInfo, err := s.keyinfoStore.Get(s.walletID) + keyInfo, err := s.keyinfoStore.Get(s.composeKey(s.walletID)) if err != nil { return errors.Wrap(err, "Failed to get key info data") } diff --git a/pkg/mpc/eddsa_rounds.go b/pkg/mpc/eddsa_rounds.go index 1200e74..94f2811 100644 --- a/pkg/mpc/eddsa_rounds.go +++ b/pkg/mpc/eddsa_rounds.go @@ -2,6 +2,7 @@ package mpc import ( "github.com/bnb-chain/tss-lib/v2/eddsa/keygen" + "github.com/bnb-chain/tss-lib/v2/eddsa/signing" "github.com/bnb-chain/tss-lib/v2/tss" "github.com/cryptoniumX/mpcium/pkg/common/errors" ) @@ -15,22 +16,14 @@ type RoundInfo struct { } const ( - EDDSA_KEYGEN1 = "KGRound1Message" - EDDSA_KEYGEN2aUnicast = "KGRound2Message1" - EDDSA_KEYGEN2b = "KGRound2Message2" - // KEYGEN3 = "KGRound3Message" - // KEYSIGN1aUnicast = "SignRound1Message1" - // KEYSIGN1b = "SignRound1Message2" - // KEYSIGN2Unicast = "SignRound2Message" - // KEYSIGN3 = "SignRound3Message" - // KEYSIGN4 = "SignRound4Message" - // KEYSIGN5 = "SignRound5Message" - // KEYSIGN6 = "SignRound6Message" - // KEYSIGN7 = "SignRound7Message" - // KEYSIGN8 = "SignRound8Message" - // KEYSIGN9 = "SignRound9Message" - EDDSA_TSSKEYGENROUNDS = 3 - // TSSKEYSIGNROUNDS = 10 + EDDSA_KEYGEN1 = "KGRound1Message" + EDDSA_KEYGEN2aUnicast = "KGRound2Message1" + EDDSA_KEYGEN2b = "KGRound2Message2" + EDDSA_KEYSIGN1 = "SignRound1Message" + EDDSA_KEYSIGN2 = "SignRound2Message" + EDDSA_KEYSIGN3 = "SignRound3Message" + EDDSA_TSSKEYGENROUNDS = 3 + EDDSA_TSSKEYSIGNROUNDS = 3 ) func GetEddsaMsgRound(msg []byte, partyID *tss.PartyID, isBroadcast bool) (RoundInfo, error) { @@ -57,6 +50,24 @@ func GetEddsaMsgRound(msg []byte, partyID *tss.PartyID, isBroadcast bool) (Round RoundMsg: EDDSA_KEYGEN2b, }, nil + case *signing.SignRound1Message: + return RoundInfo{ + Index: 0, + RoundMsg: EDDSA_KEYSIGN1, + }, nil + + case *signing.SignRound2Message: + return RoundInfo{ + Index: 0, + RoundMsg: EDDSA_KEYSIGN2, + }, nil + + case *signing.SignRound3Message: + return RoundInfo{ + Index: 0, + RoundMsg: EDDSA_KEYSIGN3, + }, nil + default: return RoundInfo{}, errors.New("unknown round") } diff --git a/pkg/mpc/eddsa_signing_session.go b/pkg/mpc/eddsa_signing_session.go index b6615f1..0dff3fd 100644 --- a/pkg/mpc/eddsa_signing_session.go +++ b/pkg/mpc/eddsa_signing_session.go @@ -66,6 +66,7 @@ func NewEDDSASigningSession( composeKey: func(waleltID string) string { return fmt.Sprintf("eddsa:%s", waleltID) }, + getRoundFunc: GetEddsaMsgRound, successQueue: succesQueue, }, endCh: make(chan *common.SignatureData), @@ -149,9 +150,7 @@ func (s *EDDSASigningSession) Sign(done func()) { NetworkInternalCode: s.networkInternalCode, WalletID: s.walletID, TxID: s.txID, - R: sig.R, - S: sig.S, - SignatureRecovery: sig.SignatureRecovery, + Signature: sig.Signature, } bytes, err := json.Marshal(r) From 9495ce20aea153ba00abde65a6628bf1f2602144 Mon Sep 17 00:00:00 2001 From: anhthii Date: Sun, 19 May 2024 11:17:38 +0700 Subject: [PATCH 4/4] Add script to add prefix ecdsa for existing keyinfos --- cmd/migration/update-keyinfo/main.go | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 cmd/migration/update-keyinfo/main.go diff --git a/cmd/migration/update-keyinfo/main.go b/cmd/migration/update-keyinfo/main.go new file mode 100644 index 0000000..d11250f --- /dev/null +++ b/cmd/migration/update-keyinfo/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + "log" + "strings" + + "github.com/cryptoniumX/mpcium/pkg/config" + "github.com/cryptoniumX/mpcium/pkg/logger" + "github.com/hashicorp/consul/api" +) + +// script to add key type prefix ecdsa for existing keys +func main() { + config.InitViperConfig() + logger.Init("production") + appConfig := config.LoadConfig() + logger.Info("App config", "config", appConfig) + + consulClient := NewConsulClient(appConfig.Consul.Address) + kv := consulClient.KV() + // Get a handle to the KV API + // List all keys with the specified prefix + prefix := "threshold_keyinfo" + keys, _, err := kv.Keys(prefix, "", nil) + if err != nil { + log.Fatal(err) + } + + // Print the keys + // fmt.Printf("Keys with prefix \"%s\":\n", prefix) + for _, key := range keys { + if !strings.Contains(key, "ecdsa") && !strings.Contains(key, "eddsa") { + pair, _, err := kv.Get(key, nil) + if err != nil { + log.Fatal(err) + } + + // Define variables to store the extracted values + var walletID string + + // Use fmt.Sscanf to extract the values + _, err = fmt.Sscanf(key, "threshold_keyinfo/%s", &walletID) + if err != nil { + fmt.Println("Error:", err) + return + } + + if walletID != "" { + kv.Put(&api.KVPair{Key: fmt.Sprintf("threshold_keyinfo/ecdsa:%s", walletID), Value: pair.Value}, nil) + kv.Delete(key, nil) + + } + + } + + fmt.Println(key) + } + +} + +func NewConsulClient(addr string) *api.Client { + // Create a new Consul client + consulConfig := api.DefaultConfig() + consulConfig.Address = addr + consulClient, err := api.NewClient(consulConfig) + if err != nil { + logger.Fatal("Failed to create consul client", err) + } + logger.Info("Connected to consul!") + return consulClient +}