arch-kit is a CLI for generating Arch keys, deploying programs, publishing
canonical on-chain IDLs, and inspecting APL tokens.
Install the published crate with Cargo:
cargo install arch-kit --lockedInstall from this repository when developing arch-kit itself:
cargo install --path .Cargo installs the binary to $CARGO_HOME/bin (usually ~/.cargo/bin). If it
is not already available on your PATH, add this to your shell profile:
export PATH="$HOME/.cargo/bin:$PATH"After pulling changes, update the installed binary with:
cargo install --path . --forceStore the program and authority key contents as PROGRAM_KEY and
AUTHORITY_KEY repository secrets. Both accept the same hex or SDK-compatible
JSON formats as local key files. A program repository can then build and deploy
with the reusable workflow:
jobs:
deploy:
uses: Arch-Network/arch-kit/.github/workflows/deploy-program.yml@v0.1.0
with:
program-path: program
bitcoin-network: testnet
rpc-url: https://rpc.testnet.arch.network
fund-authority: true
secrets:
PROGRAM_KEY: ${{ secrets.PROGRAM_KEY }}
AUTHORITY_KEY: ${{ secrets.AUTHORITY_KEY }}When idl-path is omitted, the workflow builds the Satellite IDL from the
program. Programs with manually maintained IDLs can bypass that step:
with:
program-path: program
idl-path: idl/program.json
idl-size: 20000The workflow builds the SBF ELF, checks node health, and deploys or upgrades the program and canonical IDL. Faucet funding is disabled unless explicitly enabled. Reusing the same two key secrets updates the existing deployment; changing the program key creates a new deployment.
Programs using Satellite require Rust nightly during the IDL-building step.
Install it with rustup toolchain install nightly; Satellite's
IDL builder explicitly selects the nightly toolchain.
| Command | Usage | Description |
|---|---|---|
init |
arch-kit init <PATH> --program-key <PATH> |
Initialize a new Satellite Hello World program. |
build-idl |
arch-kit build-idl <PROGRAM_PATH> <OUTPUT> |
Build a Satellite program's IDL JSON. |
deploy |
arch-kit deploy [OPTIONS] |
Deploy or update a program and its IDL. |
| Command | Usage | Description |
|---|---|---|
keygen |
arch-kit keygen [OPTIONS] <PATH>... |
Generate one or more secp256k1 key files, with optional public key prefixes (vanity). |
pubkey |
arch-kit pubkey <PATH> |
Derive a Base58 Arch public key from a secret key file. |
| Command | Usage | Description |
|---|---|---|
ata |
arch-kit ata <OWNER> <MINT> |
Derive an associated token account address. |
token-balance |
arch-kit token-balance <OWNER> <MINT> |
Read an owner's ATA balance for a mint. |
token-account |
arch-kit token-account <ADDRESS> |
Inspect one APL token account. |
token-accounts |
arch-kit token-accounts <OWNER> |
List every APL token account owned by an address. |
mint-info |
arch-kit mint-info <MINT> |
Inspect an APL token mint. |
create-mint |
arch-kit create-mint --mint-signer <SOURCE> --signer <SOURCE> |
Create an APL token mint with optional initial supply. |
mint-tokens |
arch-kit mint-tokens <RECIPIENT> <MINT> <AMOUNT> --signer <SOURCE> |
Mint tokens to a user's ATA. |
token-transfer |
arch-kit token-transfer <RECIPIENT> <MINT> <AMOUNT> --signer <SOURCE> |
Transfer tokens to a user's ATA, creating it idempotently. |
token-transfer-to-account |
arch-kit token-transfer-to-account <DESTINATION> <MINT> <AMOUNT> --signer <SOURCE> |
Transfer tokens directly to an APL token account. |
| Command | Usage | Description |
|---|---|---|
faucet |
arch-kit faucet --key <PATH> |
Create or fund an account using a non-mainnet faucet. |
transfer-arch |
arch-kit transfer-arch <DESTINATION> <AMOUNT> --signer <SOURCE> |
Transfer native ARCH to an account. |
arch-balance |
arch-kit arch-balance <ACCOUNT> |
Read an account's native ARCH balance. |
| Command | Usage | Description |
|---|---|---|
health |
arch-kit health |
Check validator readiness and block progression. |
Run arch-kit <COMMAND> --help for the complete option list.
Networked commands share these top-level settings:
| Setting | CLI argument | Environment variable | Default |
|---|---|---|---|
| Arch RPC | --rpc-url <URL> |
ARCH_RPC_URL |
https://rpc.testnet.arch.network |
| Bitcoin network | --bitcoin-network <NETWORK> |
ARCH_BITCOIN_NETWORK |
testnet |
Explicit arguments override environment variables and defaults. Place them
before the command, for example arch-kit --bitcoin-network regtest deploy ....
Supported networks are mainnet, testnet, testnet4, signet, and
regtest.
Transaction commands accept local files and remote arch-cosigner roles through the same source format:
--signer file:./keys/authority.key
--signer cosigner:TREASURYA bare path is treated as a local file. cosigner:TREASURY reads
TREASURY_COSIGNER_URL, TREASURY_COSIGNER_TOKEN,
TREASURY_COSIGNER_ROLE, and TREASURY_COSIGNER_PUBKEY; the public key must
be 64-character hex. Existing --key and --mint-key spellings remain aliases.
Deployment and faucet funding remain file-only until their SDK helpers accept
external signers.
arch-kit init ./hello-world --program-key ./keys/program.keyThe destination must not exist. The command creates a Satellite program whose
declared ID is derived from the supplied program key. Its say_hello
instruction requires a user signer and logs Hello <USER_BASE58_PUBKEY>; the
signature constraint uses the custom error defined in src/error.rs. The
secret key is read only and is not copied into the project.
Build the generated program from its project directory, or pass its manifest path explicitly:
cargo build-sbf --manifest-path ./hello-world/Cargo.tomlGenerate the Satellite IDL JSON before publishing it with deploy --idl:
arch-kit build-idl ./hello-world ./target/idl/hello_world.jsonThe Satellite builder uses Rust nightly and derives the IDL from the program's declared instructions and accounts.
arch-kit healthThe command checks validator readiness, reports RPC latency, and samples the block height twice. It exits successfully only when the node is ready and the height increases during its two-second observation window.
Generate one or several independent keys:
arch-kit keygen ./keys/program.key ./keys/authority.keySearch for a Base58 Arch public-key prefix, optionally limiting CPU threads:
arch-kit keygen --prefix PAMM --threads 8 ./keys/vanity-program.keyParent directories must exist, and destination paths must not. Existing paths
are never replaced. Secrets are stored as SDK-compatible hex, never printed,
and created with 0600 permissions on Unix.
Vanity search uses all available CPU parallelism by default. Each additional Base58 character increases the rough expected work by about 58 times; the estimate is only a baseline because first characters are not uniformly distributed.
arch-kit pubkey ./keys/authority.keyThe command reads either supported secret-key file format and writes only the derived Base58 Arch public key to standard output.
Derive an ATA locally without contacting an RPC node:
arch-kit ata <OWNER> <MINT>Read its balance or inspect token state:
arch-kit token-balance <OWNER> <MINT>
arch-kit token-account <TOKEN_ACCOUNT>
arch-kit token-accounts <OWNER>
arch-kit mint-info <MINT>Public keys may be Base58 or 64-character hex. Amounts include both raw and
decimal-formatted values. RPC-backed token commands accept --json; raw token
amounts are encoded as strings in JSON to preserve full u64 precision. A
missing ATA has a zero balance and exists: false, while malformed or
incorrectly owned accounts are errors.
Create a mint using existing mint and authority key files:
arch-kit create-mint \
--mint-signer file:./keys/mint.key \
--signer file:./keys/authority.key \
--decimals 6 \
--initial-supply 1000000Decimals default to 9. The payer also becomes the mint authority. Mints are
non-freezable by default; pass --freeze-authority <PUBKEY> to set one. Initial
supply is minted to the authority's ATA in the same transaction. Add
--fixed-supply to permanently revoke mint authority after the initial mint.
Mint additional tokens to a user's ATA, creating it idempotently when needed:
arch-kit mint-tokens <RECIPIENT> <MINT> 100 --signer file:./keys/authority.keyAmounts are interpreted using the mint's decimals. Fixed-supply mints reject this operation because they no longer have a mint authority.
Transfer tokens from the signing key's ATA to another user's ATA. The recipient ATA is derived and idempotently created in the same transaction:
arch-kit token-transfer <RECIPIENT> <MINT> 1.25 --signer file:./keys/owner.keyTransfer directly to an existing token account, including a non-ATA account:
arch-kit token-transfer-to-account <TOKEN_ACCOUNT> <MINT> 1.25 \
--signer file:./keys/owner.keyAmounts are human-readable decimals interpreted using the mint's configured
decimals. Both commands derive the source ATA from the signing key by default;
pass --source <TOKEN_ACCOUNT> to use another token account owned by the same
signer.
Create or top up an account through the configured network's faucet:
arch-kit faucet --key ./keys/owner.keyThe command is unavailable on mainnet. It waits for funding to be processed and reports the resulting native ARCH balance.
Transfer native ARCH using a local secret key file:
arch-kit transfer-arch <DESTINATION> 0.1 --signer file:./keys/owner.keyARCH uses nine decimal places. The command validates the sender's system account and requires enough balance for both the amount and the network's 5,000-lamport base fee before submitting a native system transfer. For mainnet, place the shared network arguments before the command:
arch-kit --rpc-url https://rpc.mainnet.arch.network \
--bitcoin-network mainnet \
transfer-arch <DESTINATION> 0.1 --signer file:./keys/owner.keyRead an account's native balance:
arch-kit arch-balance <ACCOUNT>
arch-kit arch-balance <ACCOUNT> --jsonARCH uses nine decimal places. JSON output represents lamports as a string to
preserve full u64 precision.
arch-kit deploy \
--elf ./target/deploy/example.so \
--program-key ./keys/program.key \
--authority ./keys/authority.keyKey files may contain a secp256k1 secret-key string or an SDK-compatible JSON byte array.
Useful deployment options:
--generate-if-missingsecurely creates missing program or authority keys.--fund-authorityrequests faucet funding before deployment; it is rejected on mainnet.--idl <PATH>publishes or upgrades an IDL after deployment.--idl-size <BYTES>sets the initial IDL account size and requires--idl.
IDL accounts default to at least 10,000 bytes, including the 44-byte header. Reserve enough capacity for future upgrades because a populated IDL account cannot be grown. The target program must include compatible canonical Satellite IDL handlers. If IDL publication fails, the deployed program remains deployed and its program ID is included in the error.
Maintainers publish from GitHub Actions using the Publish Crate workflow.
Configure a protected crates-io environment containing the
CRATES_IO_TOKEN secret, update Cargo.toml, Cargo.lock, and the pinned
ARCH_KIT_VERSION in the reusable workflow, then run the workflow with that
version. After publication, create the matching immutable Git tag, such as
v0.1.0, for workflow consumers.