A lightweight secp256k1 signing sidecar for TellorLayer validators.
Holds the bridge signing key in isolation from the validator process and serves synchronous signing requests over a mTLS-secured gRPC connection.
validator node (layer)
└── VoteExtHandler
└── VoteExtensionSigner (gRPC client)
│ mTLS
▼
bridge-signer
└── signer backend
├── file (soft-sign)
├── fortanixdsm
└── yubihsm (not ready yet)
- Go 1.24+
- protoc (for regenerating proto files only)
make proto-tools
# make sure $GOPATH/bin is in your PATH
export PATH="$PATH:$(go env GOPATH)/bin"make proto# Standard build (file + fortanixdsm backends)
make build
# binary at ./bin/bridge-signer# Generate a new secp256k1 key
./bin/bridge-signer --keygen --out /path/to/bridge.key
# Verify the key — prints compressed public key and Ethereum address
./bin/bridge-signer --pubkey --key /path/to/bridge.key# CA
mkdir tls
cd tls
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 365 -key tls/ca.key -out tls/ca.crt -subj "/CN=bridge-signer-ca"
# Server (sidecar)
openssl genrsa -out tls/server.key 4096
openssl req -new -key tls/server.key -out tls/server.csr -subj "/CN=bridge-signer"
openssl x509 -req -days 365 -in tls/server.csr -CA tls/ca.crt -CAkey tls/ca.key -CAcreateserial -out tls/server.crt
# Client (validator)
openssl genrsa -out tls/client.key 4096
openssl req -new -key tls/client.key -out tls/client.csr -subj "/CN=tellor-validator"
openssl x509 -req -days 365 -in tls/client.csr -CA tls/ca.crt -CAkey tls/ca.key -CAcreateserial -out tls/client.crtcp config.example.yaml config.yaml
# edit config.yaml with your paths
./bin/bridge-signer --config ./config.yamlSee config.example.yaml for all options with comments.
signer:
backend: file # file | fortanixdsm
key_path: /path/to/bridge.key # file backend
# dsm_api_endpoint: https://amer.smartkey.io
# dsm_api_key: your-api-key
# dsm_key_id: your-key-id (UUID format)
# dsm_key_name: my-bridge-key
server:
listen_addr: "0.0.0.0:9191"
health_addr: "0.0.0.0:9192"
request_timeout: 2s
tls:
ca_cert: /path/to/ca.crt
server_cert: /path/to/server.crt
server_key: /path/to/server.key
logging:
level: info # debug | info | warn | error
format: json # json | text| Backend | Key location |
|---|---|
file |
Hex file on disk |
fortanixdsm |
FortanixDSM |
On the validator node, enable the remote signer with these flags:
layerd start \
--remote-signer-enabled \
--remote-signer-addr localhost:9191 \
--remote-signer-ca-cert /path/to/ca.crt \
--remote-signer-client-cert /path/to/client.crt \
--remote-signer-client-key /path/to/client.key \
--remote-signer-server-name bridge-signerWithout --remote-signer-enabled, the validator uses the local keyring
for bridge signing.