Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2f2ec12
wip: implement taurus lib
vietddude Oct 2, 2025
b94e763
wip: done taurus in mem and pubsub
vietddude Oct 3, 2025
3fff150
Implement Taurus CMP key generation and signing functionality in even…
vietddude Oct 6, 2025
69069cd
Refactor NATSTransport message handling to unify handle functions and…
vietddude Oct 6, 2025
71062e6
Add CMP reshare handling in event consumer
vietddude Oct 6, 2025
4b417fa
refactor: avoid conflict
vietddude Oct 6, 2025
0c0e0dd
fix: lint
vietddude Oct 6, 2025
58feb9f
fix: remove cmp test
vietddude Oct 6, 2025
df2bd34
update: add cmp test
vietddude Oct 7, 2025
56de445
refactor: remove unused Done channel from TaurusNetworkAdapter
vietddude Oct 7, 2025
1f1aa93
feat: add Frost, Taproot and change cmp to CGGMP21
vietddude Oct 15, 2025
17318b0
refactor: format taurus pkg
vietddude Oct 15, 2025
93fbe50
feat: implement presign CGGMP21 functionality in MPC client and event…
vietddude Oct 25, 2025
8e06092
feat: enhance PresignCache with TTL support and automatic cleanup
vietddude Oct 25, 2025
bb8cf07
refactor: update presign handling to use WalletID instead of TxID and…
vietddude Nov 3, 2025
07e8c7f
feat: update wallet creation and signing processes to support multipl…
vietddude Nov 6, 2025
01af87c
feat (WIP): implement presign pool worker and enhance presign handlin…
vietddude Nov 6, 2025
bfd2ebf
feat: cggmp21 presign pool with auto cleanup
vietddude Nov 7, 2025
ed52f34
fix: resolve gosec uint64→int conversion warning in deterministic pre…
vietddude Nov 7, 2025
bbfddde
fix: update presign selection to use int32 for hash index calculation
vietddude Nov 7, 2025
7851ea0
refactor: update identity file loading to read and parse peers.json d…
vietddude Nov 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ node2
config.yaml
.vscode
.vagrant
wallets.json
45 changes: 45 additions & 0 deletions INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ Update `config.yaml`:
event_initiator_pubkey: "09be5d070816aadaa1b6638cad33e819a8aed7101626f6bf1e0b427412c3408a"
```

> 💡 **Note**: If you plan to use the presign pool worker (see [Presign Pool Worker](#presign-pool-worker) section), you'll need the `event_initiator.key` file (or `event_initiator.key.age` if encrypted) to be available. The private key file is generated alongside the identity file.

---

## Configure Node Identities
Expand Down Expand Up @@ -274,6 +276,49 @@ mpcium start -n node2

---

## Presign Pool Worker

The presign pool worker automatically maintains a pool of presignatures for hot wallets, ensuring they're ready for immediate use.

### Setup

To enable the presign pool worker on a node:

1. **Copy the event initiator private key** to the node directory:

If you generated the initiator with encryption:
```bash
# Decrypt the key first
age --decrypt -o event_initiator.key event_initiator.key.age
```

Then copy it to the node directory:
```bash
cp event_initiator.key node0/
```

If you generated the initiator without encryption:
```bash
cp event_initiator.key node0/
```

2. **Start the node with the `--presign-pool-worker` flag**:

```bash
cd node0
mpcium start -n node0 --presign-pool-worker
```

> ⚠️ **Important**: Only one node in the cluster should run the presign pool worker. The node running this worker must have the `event_initiator.key` file in its working directory.

### How It Works

- The worker monitors hot wallet activity and automatically generates presignatures when needed
- It maintains a pool of presignatures between `MinPoolSize` (default: 5) and `MaxPoolSize` (default: 20)
- The worker subscribes to hot wallet events and proactively refills the presignature pool

---

## Production Deployment (High Security)

1. Use production-grade **NATS** and **Consul** clusters.
Expand Down
48 changes: 47 additions & 1 deletion cmd/mpcium/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"syscall"
"time"

"github.com/fystack/mpcium/pkg/client"
"github.com/fystack/mpcium/pkg/config"
"github.com/fystack/mpcium/pkg/constant"
"github.com/fystack/mpcium/pkg/event"
Expand All @@ -22,7 +23,10 @@ import (
"github.com/fystack/mpcium/pkg/logger"
"github.com/fystack/mpcium/pkg/messaging"
"github.com/fystack/mpcium/pkg/mpc"
"github.com/fystack/mpcium/pkg/presign"
"github.com/fystack/mpcium/pkg/presigninfo"
"github.com/fystack/mpcium/pkg/security"
"github.com/fystack/mpcium/pkg/types"
"github.com/hashicorp/consul/api"
"github.com/nats-io/nats.go"
"github.com/spf13/viper"
Expand Down Expand Up @@ -77,6 +81,11 @@ func main() {
Aliases: []string{"k"},
Usage: "Path to file containing password for decrypting .age encrypted node private key",
},
&cli.BoolFlag{
Name: "presign-pool-worker",
Usage: "Enable presign pool worker",
Value: false,
},
&cli.BoolFlag{
Name: "debug",
Usage: "Enable debug logging",
Expand Down Expand Up @@ -109,6 +118,7 @@ func runNode(ctx context.Context, c *cli.Command) error {
usePrompts := c.Bool("prompt-credentials")
passwordFile := c.String("password-file")
agePasswordFile := c.String("identity-password-file")
presignPoolWorker := c.Bool("presign-pool-worker")
debug := c.Bool("debug")

viper.SetDefault("backup_enabled", true)
Expand Down Expand Up @@ -177,6 +187,7 @@ func runNode(ctx context.Context, c *cli.Command) error {
"mpc.mpc_keygen_result.*",
event.SigningResultTopic,
"mpc.mpc_reshare_result.*",
event.PresignResultTopic,
}, natsConn)

genKeyResultQueue := mqManager.NewMessageQueue("mpc_keygen_result")
Expand All @@ -185,11 +196,14 @@ func runNode(ctx context.Context, c *cli.Command) error {
defer singingResultQueue.Close()
reshareResultQueue := mqManager.NewMessageQueue("mpc_reshare_result")
defer reshareResultQueue.Close()
presignResultQueue := mqManager.NewMessageQueue("mpc_presign_result")
defer presignResultQueue.Close()

logger.Info("Node is running", "ID", nodeID, "name", nodeName)

peerNodeIDs := GetPeerIDs(peers)
peerRegistry := mpc.NewRegistry(nodeID, peerNodeIDs, consulClient.KV(), directMessaging, pubsub, identityStore)
presignInfoStore := presigninfo.NewStore(consulClient.KV())

mpcNode := mpc.NewNode(
nodeID,
Expand All @@ -198,6 +212,7 @@ func runNode(ctx context.Context, c *cli.Command) error {
directMessaging,
badgerKV,
keyinfoStore,
presignInfoStore,
peerRegistry,
identityStore,
)
Expand All @@ -209,6 +224,7 @@ func runNode(ctx context.Context, c *cli.Command) error {
genKeyResultQueue,
singingResultQueue,
reshareResultQueue,
presignResultQueue,
identityStore,
)
eventConsumer.Run()
Expand Down Expand Up @@ -289,14 +305,44 @@ func runNode(ctx context.Context, c *cli.Command) error {
logger.Info("All consumers have finished")
close(errChan)
}()

// Start presign pool worker before entering the blocking error loop
if presignPoolWorker {
presignPoolCtx, presignPoolCancel := context.WithCancel(appContext)
defer presignPoolCancel()
localSigner, err := client.NewLocalSigner(types.EventInitiatorKeyTypeEd25519, client.LocalSignerOptions{
KeyPath: "./event_initiator.key",
})
if err != nil {
logger.Fatal("Failed to create local signer", err)
}
mpcClient := client.NewMPCClient(client.Options{
NatsConn: natsConn,
Signer: localSigner,
})
presignPool := presign.NewPresignPool(nil, mpcClient, presignInfoStore)

_, err = pubsub.Subscribe(eventconsumer.MPCHotWalletEvent, func(nm *nats.Msg) {
walletID := string(nm.Data)
if walletID != "" {
presignPool.TouchHot(walletID)
}
})
if err != nil {
logger.Warn("Failed to subscribe to hot wallet events", "err", err)
}

presignPool.Start(presignPoolCtx)
defer presignPool.Stop()
}

for err := range errChan {
if err != nil {
logger.Error("Consumer error received", err)
cancel()
return err
}
}

return nil
}

Expand Down
14 changes: 10 additions & 4 deletions e2e/go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
module github.com/fystack/mpcium/e2e

go 1.23.0
go 1.23.8

require (
github.com/dgraph-io/badger/v4 v4.7.0
github.com/fystack/mpcium v0.0.0-00010101000000-000000000000
github.com/google/uuid v1.6.0
github.com/hashicorp/consul/api v1.26.1
github.com/hashicorp/consul/api v1.32.1
github.com/nats-io/nats.go v1.31.0
github.com/stretchr/testify v1.10.0
gopkg.in/yaml.v2 v2.4.0
Expand Down Expand Up @@ -37,13 +37,15 @@ require (
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/btcsuite/btcutil v1.0.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cronokirby/saferith v0.33.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand All @@ -61,6 +63,7 @@ require (
github.com/ipfs/go-log v1.0.5 // indirect
github.com/ipfs/go-log/v2 v2.1.3 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand All @@ -83,6 +86,9 @@ require (
github.com/spf13/pflag v1.0.6 // indirect
github.com/spf13/viper v1.18.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/taurusgroup/multi-party-sig v0.7.0-alpha-2025-01-28 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
Expand All @@ -91,7 +97,7 @@ require (
go.uber.org/multierr v1.9.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.31.0 // indirect
Expand Down
34 changes: 27 additions & 7 deletions e2e/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cronokirby/saferith v0.33.0 h1:TgoQlfsD4LIwx71+ChfRcIpjkw+RPOapDEVxa+LhwLo=
github.com/cronokirby/saferith v0.33.0/go.mod h1:QKJhjoqUtBsXCAVEjw38mFqoi7DebT7kthcD7UzbnoA=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -96,8 +98,9 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
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=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y=
github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA=
Expand All @@ -118,6 +121,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
Expand Down Expand Up @@ -158,10 +163,10 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/consul/api v1.26.1 h1:5oSXOO5fboPZeW5SN+TdGFP/BILDgBm19OrPZ/pICIM=
github.com/hashicorp/consul/api v1.26.1/go.mod h1:B4sQTeaSO16NtynqrAdwOlahJ7IUDZM9cj2420xYL8A=
github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU=
github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo=
github.com/hashicorp/consul/api v1.32.1 h1:0+osr/3t/aZNAdJX558crU3PEjVrG4x6715aZHRgceE=
github.com/hashicorp/consul/api v1.32.1/go.mod h1:mXUWLnxftwTmDv4W3lzxYCPD199iNLLUyLfLGFJbtl4=
github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg=
github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -220,6 +225,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand Down Expand Up @@ -361,12 +369,22 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/taurusgroup/multi-party-sig v0.7.0-alpha-2025-01-28 h1:rbyJpV3kH/aMxG7gUQ5ynveAEXuPiIG136Ld3HGNV7I=
github.com/taurusgroup/multi-party-sig v0.7.0-alpha-2025-01-28/go.mod h1:roZI3gaKCo15PUSB4LdJpTLTjq8TFsJiOH5kpcN1HpQ=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
Expand Down Expand Up @@ -402,8 +420,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
Expand Down Expand Up @@ -440,6 +458,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
6 changes: 5 additions & 1 deletion examples/generate/kms/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,11 @@ func main() {
for _, walletID := range walletIDs {
wg.Add(1) // Add to WaitGroup BEFORE attempting to create wallet

if err := mpcClient.CreateWallet(walletID); err != nil {
if err := mpcClient.CreateWallet(&types.GenerateKeyMessage{
WalletID: walletID,
ECDSAProtocol: types.ProtocolCGGMP21,
EdDSAProtocol: types.ProtocolGG18,
}); err != nil {
logger.Error("CreateWallet failed", err)
walletStartTimes.Delete(walletID)
wg.Done() // Now this is safe since we added 1 above
Expand Down
18 changes: 17 additions & 1 deletion examples/generate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,19 @@ func main() {
walletIDsMu.Unlock()
}

// Track processed results to prevent duplicate processing
processedResults := sync.Map{}

// STEP 2: Register the result handler AFTER all walletIDs are stored
err = mpcClient.OnWalletCreationResult(func(event event.KeygenResultEvent) {
logger.Info("Received wallet creation result", "event", event)

// Check if we've already processed this result
if _, alreadyProcessed := processedResults.LoadOrStore(event.WalletID, true); alreadyProcessed {
logger.Warn("Duplicate wallet result received, ignoring", "walletID", event.WalletID)
return
}

now := time.Now()
startTimeAny, ok := walletStartTimes.Load(event.WalletID)
if ok {
Expand Down Expand Up @@ -124,9 +134,15 @@ func main() {
for _, walletID := range walletIDs {
wg.Add(1) // Add to WaitGroup BEFORE attempting to create wallet

if err := mpcClient.CreateWallet(walletID); err != nil {
if err := mpcClient.CreateWallet(&types.GenerateKeyMessage{
WalletID: walletID,
ECDSAProtocol: types.ProtocolCGGMP21,
EdDSAProtocol: types.ProtocolGG18,
}); err != nil {
logger.Error("CreateWallet failed", err)
walletStartTimes.Delete(walletID)
// Mark this wallet as processed to prevent callback from processing it
processedResults.Store(walletID, true)
wg.Done() // Now this is safe since we added 1 above
continue
}
Expand Down
Loading
Loading