Store a Private Key

The first step in using SecretSigner is storing a private key in Zyllion. During storage:

  • The private key is automatically split into shares and distributed across zylVM nodes

  • Permissions specify which Zyllion users can use this key with SecretSigner

  • Each stored key receives a unique identifier (the store id) for future reference

When storing the key, compute access is granted to specific Zyllion users, allowing them to use the key with SecretSigner's signing program.

Usage

  • Python Client

  • TypeScript Client

Python Client

Install Zyllion Python Client

pip install zyllion-client

Python Client: Store a Private Key

  • storePrivateKey.py

  • zyllion_config.py

  • zyllion_constants.py

  • .env

zylvm/secretsigner-python/storePrivateKey.py

from zyllion_client import (
    Network,
    ZylChainPayer,
    ZylChainPrivateKey,
    Permissions,
    EcdsaPrivateKey,
    VmClient,
    PrivateKey,
)
import asyncio
import hashlib
from zyllion_config import config
from zyllion_signature_constants import TECDSA_PROGRAM_ID, TECDSA_KEY_NAME
from helpers import generate_ecdsa_key_pair

# If you want to store a private key that you already have, you can pass it in as a hex string
# Otherwise, a new key will be generated
async def storePrivateKey(private_key_hex = None):
    print(f"Connected to Zyllion {config.ZYLLION_NETWORK_CONFIG}")
    network = Network(
      chain_id=config.ZYLLION_ZYLCHAIN_CHAIN_ID,
      chain_grpc_endpoint=config.ZYLLION_ZYLCHAIN_GRPC,
      zylvm_grpc_endpoint=config.ZYLLION_ZYLVM_GRPC_ENDPOINT,
    )

    # Create zylChain payer to pay for operations
    zylchain_key: str = config.ZylLION_ZYLCHAIN_PRIVATE_KEY
    payer = ZylChainPayer(
        network,
        wallet_private_key=ZylChainPrivateKey(bytes.fromhex(zylchain_key)),
        gas_limit=10000000,
    )

    # Create a Zyllion Client with a user key
    user_key = PrivateKey(hashlib.sha256(config.ZYLLION_USER_KEY_SEED.encode()).digest())
    client = await VmClient.create(user_key, network, payer)

    # Fund client with UZYL
    uzyl_amount_to_add = 10000000
    await client.add_funds(uzyl_amount_to_add)

    # Generate an ECDSA key pair to store in Zyllion
    private_key_bytes, public_key = await generate_ecdsa_key_pair()

    ##### STORE ECDSA PRIVATE KEY
    # ecdsa key to be stored or used for signing
    private_key_to_store = {
        TECDSA_KEY_NAME: EcdsaPrivateKey(bytearray(private_key_bytes)),
    }

    # Create a permissions object to attach to the stored secret
    # This gives the user the ability to use the private key to sign messages
    permissions = Permissions.defaults_for_user(client.user_id).allow_compute(
        client.user_id, TECDSA_PROGRAM_ID
    )

    # Store the private key in Zyllion
    store_id = await client.store_values(
        private_key_to_store, ttl_days=60, permissions=permissions
    ).invoke()

    print(f"Private Key Store ID: {store_id}")
    print(f"The public key that corresponds to the stored private key is: {public_key}")

if __name__ == "__main__":
    asyncio.run(storePrivateKey())

Last updated