did-btcr2-js

btcr2 create

Creates a did:btcr2 identifier and, with it, the initial DID document. Creation is an offline step: the command opens no Bitcoin or CAS connection, and it broadcasts nothing. Two identifier types exist. A k identifier (deterministic, KEY) encodes a 33-byte compressed secp256k1 public key. The initial DID document derives from the identifier. An x identifier (EXTERNAL) encodes the 32-byte SHA-256 hash of a genesis document. You supply that document as sidecar data at resolution time.

For -t k, the command has three input modes, and only one applies per run: use the public key of a stored key (--key, else the default key), generate a new key in the keystore (if no default key exists), or supply the public key as hex (--bytes, no keystore). The default key is the same key that update and deactivate sign with, so the default key can update the new identifier. For -t x, the command has two input modes: the genesis document file (--document), which the api hashes, or the hash as hex (--bytes). btcr2 genesis build writes the document file.

Synopsis

btcr2 create [options]

btcr2 create                                  # -t k: use the default key, else generate a key
btcr2 create -k <ref>                         # -t k: use the public key of a stored key
btcr2 create -b <66-hex-chars>                # -t k: a 33-byte compressed public key
btcr2 create -t x --document <path>           # -t x: hash the genesis document file
btcr2 create -t x -b <64-hex-chars>           # -t x: the 32-byte genesis document hash

There are no subcommands.

Options

Flag Value Default Description
-k, --key <ref> a key reference: a key URN (urn:kms:secp256k1:<32-hex>), a unique keystore name tag, or a unique fingerprint prefix the identity.default of the active profile, else the active key For -t k: the stored key whose public key becomes the genesis bytes. The order of the match: an exact URN, then a unique name tag, then a unique fingerprint prefix. An exact name wins over a fingerprint prefix. The command reads public material only, so it never decrypts and never asks for the passphrase. A watch-only key (from key import --public) is valid. The command fails with No key matches reference "<ref>"., or with an ambiguity error if more than one key matches. An empty value fails with --key must not be empty. The flag is not valid with -t x, and it is exclusive with --bytes.
-t, --type <type> k | x k The identifier type. k = a deterministic KEY identifier from a compressed secp256k1 public key. x = an external identifier from a genesis document hash. Another value fails with Invalid type. Must be "k" or "x". and exit code 1.
-n, --network <network> bitcoin | testnet3 | testnet4 | signet | mutinynet | regtest from the config (see the precedence below), else regtest The Bitcoin network that the identifier encodes. Creation stays offline. The network only fixes the target of the identifier, and of the later resolution and update traffic. An unsupported value fails with Invalid network. Must be one of "bitcoin", "testnet3", "testnet4", "signet", "mutinynet", or "regtest".
-b, --bytes <bytes> a hex string (case-insensitive, the command trims whitespace) none The genesis bytes. For -t k: exactly 33 bytes (66 hex characters), a valid compressed secp256k1 public key. For -t x: exactly 32 bytes (64 hex characters), the SHA-256 hash of the genesis document. Non-hex input fails with Invalid bytes: not valid hex. .... A wrong length fails with Invalid bytes length for type="<t>": .... The method layer refuses a 33-byte value that is not a point on the curve (Expected "genesisBytes" to be a valid compressed secp256k1 public key).
--document <path> file path none For -t x only: the JSON genesis document to hash, for example the file that btcr2 genesis build wrote. The api checks the document (the placeholder id did:btcr2:_, the two contexts, a placeholder id in each method and service) and hashes it as written. An unreadable path or non-JSON content fails with Invalid genesis document path. .... A document with a wrong shape fails with the reason, for example The genesis document id must be "did:btcr2:_", .... The flag is exclusive with --bytes (Provide at most one of --bytes or --document.). With -t k, the flag fails with --document applies only to external identifiers (-t x)..
-h, --help none n/a Print the help of the command and exit.

The --help text describes the -n default as “config defaults.network, else regtest”. The source has one more step between the two: the network of the active profile (see the precedence below). The source behavior applies.

Input modes for -t k

Exactly one of the three modes runs. The present inputs select the mode. --key with --bytes fails with Provide at most one of --bytes or --key.

  1. Stored key (--key <ref>, else the default key). The key is, in this order: --key <ref>, the identity.default of the active profile, the active key of the keystore. update and deactivate use the same order for their signing key. The command resolves the reference against the keystore and uses the public key of that key as the genesis bytes. It never decrypts and never asks for the passphrase.
  2. Generate (no --bytes, and no key from the order above). The command makes a new secp256k1 key, imports it into the keystore, and sets it as the active key. The seal of the secret key needs the keystore passphrase (see the passphrase section below). On a keystore that does not exist yet, this step creates an encrypted keystore: an interactive prompt asks twice, and the two entries must match (Passphrases did not match. otherwise). The command reads an environment variable or a file source once, without a confirmation. On an existing encrypted keystore, the command verifies the passphrase against the verifier of the keystore. On a dev keystore (from btcr2 keystore init --dev), the command stores the secret key in plaintext and never asks for a passphrase. Mainnet guard (ADR 080): the command refuses -n bitcoin with a dev keystore up front (DEV_KEYSTORE_MAINNET_ERROR), so a plaintext keystore never holds a mainnet key.
  3. Raw bytes (--bytes <hex>). Fully offline, with no keystore. The command does not touch the keystore file, and no passphrase code runs.

Input modes for -t x

Exactly one of the two modes runs. No input fails with External identifiers (-t x) require --document <path>, the genesis document, or --bytes <hex>, its 32-byte hash. .... Both inputs fail with Provide at most one of --bytes or --document. -t x with --key fails with --key applies only to deterministic identifiers (-t k).

  1. Document (--document <path>). The api hashes the file as written (JCS canonical form, SHA-256) and encodes the identifier. The result carries the hash as genesisBytes. Keep the file: the identifier resolves only with it. On a network with a faucet, a text-mode funding hint names the first beacon of the document.
  2. Raw bytes (--bytes <hex>). The 32-byte genesis document hash, computed elsewhere. The command prints no funding hint, because it does not know the beacons.

Output

Stderr hints and warnings

Errors

Each error exits with code 1 and prints the message only, unless --verbose is set. In addition to the per-flag checks above: PASSPHRASE_REQUIRED_ERROR if the generate mode needs a passphrase, no source (environment variable, file, session) has one, and stdin is not a terminal. The message is No passphrase available. Set BTCR2_KEYSTORE_PASSPHRASE, pass --passphrase-file, or run in a terminal. The command also refuses an empty or whitespace-only passphrase. A malformed config.json, or one with a schemaVersion newer than the CLI supports, fails the command if the command must read the config. The command reads the config for the default network (no -n) and for the keystore path (the generate mode and the stored-key mode). A raw-bytes run with an explicit -n does not read the config.

Environment and configuration

The command reads these environment variables:

Variable Role
BTCR2_HOME The home directory that holds config.json, keystore.json, and session.json. --home wins. The platform default: ~/.btcr2 on Linux and macOS. On Windows: %LOCALAPPDATA%\btcr2, else %APPDATA%\btcr2, else the user profile.
BTCR2_OUTPUT The output format (json or text) if -o/--output is absent.
BTCR2_KEYSTORE_PASSPHRASE The keystore passphrase for unattended use. Generate mode only. This is the passphrase source with the highest precedence. The CLI trims at most one trailing newline.

Only a command that opens a connection reads the endpoint variables (BTCR2_BTC_REST, BTCR2_BTC_RPC_*, BTCR2_CAS_*, BTCR2_BTC_TIMEOUT, BTCR2_CAS_TIMEOUT, BTCR2_FEE_RATE, BTCR2_BTC_SIGNAL_DISCOVERY). create builds its api without a network, so they have no effect here. The same applies to the global endpoint flags.

The config file keys (<home>/config.json, or the file that -c/--config names) that create reads:

Key Role
defaults.network The default for -n if the flag is absent.
defaults.profile The active profile if --profile is absent.
defaults.output The default output format below BTCR2_OUTPUT.
profiles.<name>.network The network that the profile declares. It feeds the default network fallback and the mismatch warning.
profiles.<name>.identity.keystore The keystore path for the generate mode and the stored-key mode, below the --keystore flag.
profiles.<name>.identity.default The default key reference, below the --key flag and above the active key of the keystore.

Precedence (the highest wins, and a blank value at one layer defers to the next layer):

Session (ADR 081): a session that btcr2 keystore unlock cached in <home>/session.json supplies the passphrase of the generate mode instead of a prompt, until it expires or btcr2 keystore lock revokes it. The session is bound to the verifier of the keystore, so a changed passphrase invalidates it. The command never reads the session for the first passphrase of a new keystore. You always type a first passphrase twice. The mainnet gate of the session (unlock --allow-mainnet) keys on the network that the keystore factory receives. create calls the factory without a network, like the key commands. A live session therefore supplies the passphrase of create on each network, also with -n bitcoin. The dev keystore mainnet refusal above is independent of the session and always applies.

Global flags

See the docs README for the shared global flags. create uses: --keystore, --passphrase-file, --home, -c/--config, --profile, -o/--output, --quiet (suppresses the funding hint and the mismatch warning), and --verbose (full error objects). The command accepts the --btc-* and --cas-* endpoint flags, but they have no effect. create never opens a connection.

Examples

# Create a mutinynet identifier from the default key. If the keystore has no
# default key, the command generates one (and asks for the keystore passphrase,
# twice on a new keystore)
btcr2 create -n mutinynet

# The same with JSON output: adds keyId and publicKey, no stderr hints
btcr2 create -n mutinynet -o json

# Use a stored key by name, by fingerprint prefix, or by full URN (no prompt)
btcr2 create -n mutinynet --key alice
btcr2 create -n mutinynet --key 3fa2
btcr2 create -n mutinynet --key urn:kms:secp256k1:3fa2e1c09b7d54a6880f13cd21e60b47

# Offline, no keystore: your own 33-byte compressed public key
btcr2 create -n mutinynet -b 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798

# An external identifier from a genesis document file (see: btcr2 genesis build)
btcr2 create -t x -n mutinynet --document ./genesis.json

# An external identifier from the SHA-256 hash of a genesis document
btcr2 create -t x -n mutinynet \
  -b 8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4

# Unattended run (CI): the passphrase from a file if the command generates a key, no hints
btcr2 create -n mutinynet --passphrase-file /run/secrets/btcr2-pass --quiet

See also