npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xyo-network/wallet-xl1-cli

v0.1.22

Published

Standalone XL1 Wallet CLI

Readme

logo

@xyo-network/wallet-xl1-cli

npm license

Standalone XL1 wallet CLI for seed phrases, accounts, balances, transfers, payload signing, and wallet-signed JWTs.

Description

@xyo-network/wallet-xl1-cli provides the xl1-wallet command. It is a focused XL1 wallet tool that can create or import wallets, derive accounts, manage network and contact metadata, sign transactions and payloads, send XL1, and mint or verify wallet-backed JWTs.

The Aries CLI uses this same package for aries wallet ..., so the standalone and nested command surfaces stay aligned.

Installation

Prerequisites

  • Node.js >=22.19.0
  • A package manager such as npm, pnpm, or yarn

Global Install

npm install -g @xyo-network/wallet-xl1-cli
xl1-wallet --help

Run From This Repository

pnpm xy compile @xyo-network/wallet-xl1-cli
pnpm xl1-wallet --help

Quick Start

Create a new wallet, derive an account, check its balance, then dry-run a transfer:

xl1-wallet create --label primary
xl1-wallet account derive 0 --label main
xl1-wallet balance 0
xl1-wallet send 0x0000000000000000000000000000000000000000 1 --xl1 --dry-run

Import an existing recovery phrase instead:

xl1-wallet import --label primary --phrase "test test test test test test test test test test test junk"
xl1-wallet use <wallet-id>

Use the same wallet CLI through Aries:

aries wallet balance 0
aries wallet send 0x0000000000000000000000000000000000000000 1.25 --milli --json

Requester-scoped Node signing

The supported @xyo-network/wallet-xl1-cli/signing entry exposes public wallet summaries and short-lived, account-bound signing sessions. Install the package locally with its @xyo-network/xl1-sdk peer. Consumers select the requester ID, exact wallet ID, derivation offset, expected account, chain ID, and independently verified genesis hash. The wallet itself confirms that selection and prompts on the trusted terminal for its password; this API does not accept a password, mnemonic, root wallet, or caller-provided signer.

import { listSigningWallets, openWalletSigningSession } from '@xyo-network/wallet-xl1-cli/signing'

const wallets = listSigningWallets()
const session = await openWalletSigningSession(selection)
try {
  const snapshot = await session.snapshot()
  const signed = await session.signTransaction({ requestId, transaction })
  // Persist signed bytes in the participant publication journal before broadcasting.
} finally {
  await session.close()
}

Here selection is the complete explicit binding and transaction is an SDK unsigned hydrated transaction. The session signs without publishing bodies or broadcasting. It supports secp256k1 wallets; post-quantum transaction signing is not qualified. Sessions expire within five minutes. Lock, close, password replacement, and wallet replacement revoke authority for new signing.

The wallet persists request intent and encrypted signed results in signing.json under its existing guarded store lease. Retrying the same request returns the same bytes. signingOutcome(requestId) recovers a retained result through a fresh authorized session with the same complete binding. An uncertain intent blocks new same-account signing; an error, timeout, or 4001 is never proof that no signature exists. Existing CLI tx sign and send use this same signing ledger, with publication remaining a separate command step. Legacy offline signing has an explicitly unasserted genesis scope; it cannot authorize public requester sessions. This does not reconstruct pre-upgrade or external-key signing history.

Run the isolated packed public import, type, real terminal prompt, and process recovery fixture from the repository root after both wallet package builds:

node packages/wallet-cli/scripts/verifySigningPacked.mjs /absolute/fresh/evidence-directory

The terminal fixture currently qualifies macOS. It creates only a temporary public deterministic wallet. Its strict consumer type check uses skipLibCheck; the full dependency declaration check is retained separately because upstream SDK declarations currently fail that broader check.

Wallet Storage

Wallet CLI data is stored under ~/.xl1/wallet/cli by default.

| Variable | Purpose | | --- | --- | | XL1_WALLET_HOME | Overrides the wallet storage directory. | | ARIES_WALLET_HOME | Legacy fallback storage override. Used only when XL1_WALLET_HOME is not set. | | ARIES_WALLET_PASSWORD | Supplies the wallet password. A nonempty value is validated before any cached session is used. For a new store, it sets the initial password. | | ARIES_WALLET_NON_INTERACTIVE=1 | Refuses terminal password and recovery-phrase prompts. Private-key access requires an unlocked session or ARIES_WALLET_PASSWORD; import requires --phrase-stdin or --phrase. |

Wallet seed phrases are encrypted at rest. Commands that need private key access prompt for the wallet password unless ARIES_WALLET_PASSWORD is set.

unlock stores a short-lived encrypted session so follow-up commands can run without repeatedly prompting:

xl1-wallet unlock --ttl 900
xl1-wallet lock

Networks

The CLI ships with XL1 mainnet and XL1 Sequence testnet network definitions.

| ID | Label | RPC URL | | --- | --- | --- | | xl1-mainnet | XL1 (Mainnet) | https://api.chain.xyo.network/rpc | | xl1-sequence | XL1 Sequence (Testnet) | https://beta.api.chain.xyo.network/rpc |

List and switch networks:

xl1-wallet network list
xl1-wallet network use xl1-sequence

Add a local or custom network:

xl1-wallet network add local http://127.0.0.1:8080/rpc --label "Local XL1" --chain-id 1234
xl1-wallet network use local

Adding a network preserves the current selection and rejects duplicate IDs. New IDs must be nonblank, contain no control characters, fit within 256 UTF-8 bytes, and not begin with -. Optional labels are preserved exactly and may contain up to 1024 UTF-8 bytes. Optional chain IDs use the XL1 protocol's nonempty lowercase hexadecimal form without a 0x prefix; there is no fixed length requirement. The chain ID is stored metadata: adding a network does not probe the endpoint or verify its chain.

For endpoints containing path or query credentials, pass the complete URL via private stdin instead of a positional argument. Stdin must contain only the URL as UTF-8, with no trailing newline, and is limited to 16 KiB. URLs must be complete HTTP or HTTPS URLs without controls or fragments. Local HTTP endpoints are supported. URL username/password information is rejected because the RPC fetch transport does not support it.

printf '%s' "$RPC_URL" | xl1-wallet network inspect-add custom \
  --rpc-url-stdin --label="Custom XL1" --chain-id=1234 --json
printf '%s' "$RPC_URL" | xl1-wallet network add custom \
  --rpc-url-stdin --label="Custom XL1" --chain-id=1234 \
  --expected-state="$REVIEWED_STATE_HASH" --json

inspect-add validates the proposed entry and returns its ID, label, optional chain ID, current active ID, canonical wallet root, and stateHash. Use that hash as REVIEWED_STATE_HASH for the corresponding add. Inspection does not create networks.json; the add writes defaults and the custom entry atomically under the wallet store lease. If any wallet file changes after review, the guarded add fails and must be reviewed again. --rpc-url-stdin and a positional URL are mutually exclusive.

Network list and add support --json. Network summaries and success messages omit the entire RPC URL, including its hostname. The URL is stored in the private wallet configuration for RPC use.

Remove a custom network:

xl1-wallet network remove local

Commands

Wallets

| Command | Description | | --- | --- | | xl1-wallet create | Create a new wallet. | | xl1-wallet import | Import a recovery phrase. | | xl1-wallet export | Print a wallet recovery phrase using a password or unlocked session. | | xl1-wallet list | List wallets in the current wallet home. | | xl1-wallet use <id> | Set the active wallet. | | xl1-wallet rename <id> <label> | Rename a wallet. | | xl1-wallet remove [id] | Authenticate and remove a wallet; --wallet-id targets an exact ID. | | xl1-wallet reset | Delete known wallet files after confirmation, preserving unrelated files. | | xl1-wallet unlock | Cache an encrypted wallet session for a limited time. | | xl1-wallet lock | Clear the cached wallet session. | | xl1-wallet password change | Change the shared password for every wallet in the store. | | xl1-wallet lifecycle preview --json | Inspect the canonical store path, state fingerprint, wallets, and known files. |

Examples:

xl1-wallet create
xl1-wallet create --label quant --algorithm ml-dsa-65
xl1-wallet import --label recovery --phrase "..."
xl1-wallet import --label quant-recovery --phrase "..." --algorithm ml-dsa-65
xl1-wallet list
xl1-wallet use <wallet-id>
xl1-wallet export --id <wallet-id>
xl1-wallet export --wallet-id <exact-wallet-id> --json

create and import default to --algorithm secp256k1. Use --algorithm ml-dsa-65 for QuantHDWallet wallets, which derive qm65... bech32m addresses. Wallet-signed JWT commands require secp256k1 because ML-DSA-65 does not yet have a standardized JOSE algorithm. Wallet labels must be unique, nonblank, and free of NUL characters. Other label text, including surrounding spaces, is preserved. If create is run without --label, the CLI uses the first available wallet# label, starting with wallet0. Commands accepting a wallet ID or label prefer an exact ID match before looking for a matching label.

For unattended imports, --phrase-stdin reads raw UTF-8 from standard input until EOF, up to 16 KiB, and trims surrounding whitespace. It is mutually exclusive with --phrase. The algorithm, label, and recovery phrase are validated before the command initializes a password or stores a wallet.

export --wallet-id accepts only an exact stored ID and cannot be combined with --id. The existing --id option also accepts labels; omitting both options reveals the active wallet.

create --json and export --json emit only {id, label, algorithm, mnemonic} to stdout. This output contains the recovery phrase. import --json emits only {id, label, algorithm} and does not include the phrase. Text output remains the default.

Password change requires the current password even with an unlocked session. ARIES_WALLET_PASSWORD supplies only that current password. For automation, password change --new-password-stdin --json reads the new password as raw UTF-8 until EOF, preserving all whitespace, with a 4096-byte limit and no NUL characters. Its JSON result is {changed: true}. Interactive mode asks for and confirms the new password separately. Rotation clears the cached session.

remove --wallet-id=<exact-id> --json returns {id, label, removed: true}. The named selector cannot be combined with the positional ID/label. A supplied wrong password fails even if an unlocked session exists.

Password change, removal, and reset accept --expected-state=<stateHash> from lifecycle preview --json. The CLI checks this fingerprint under its filesystem lease before writing; a changed store requires a new review. Preview returns {root, stateHash, wallets, files} without credentials. If wallet metadata is corrupt, wallets is null with a metadataError, so reset can still be reviewed.

Updated CLI processes share a canonical-path filesystem lease. Overlapping operations report a busy store; a killed owner's lease expires after 30 seconds. Older CLI versions and other programs that ignore the lease are not coordinated. Password rotation, removal, and reset commit a durable roll-forward journal before replacing data files. The journal contains encrypted wallet records and password-verifier metadata, never plaintext passwords or recovery phrases. The next leased operation completes a valid pending transaction before reading the store. After an interrupted rotation, try the new password first. Individual files and journals are limited to 16 MiB. File data is synced; directory syncing is best effort on Windows where unsupported. A corrupt or unrecoverable journal blocks operations, including reset: preserve its files for repair.

Accounts

| Command | Description | | --- | --- | | xl1-wallet account derive <offset> | Derive and store an account at an offset. | | xl1-wallet account list [--wallet <id-or-label>] | List stored accounts for the active or specified wallet. | | xl1-wallet account show <offset> | Show a derived account address. | | xl1-wallet account label <offset> <label> | Label an account. | | xl1-wallet account remove <offset> | Remove a stored account record. |

Examples:

xl1-wallet account derive 0 --label main
xl1-wallet account show 0
xl1-wallet account list
xl1-wallet account derive 4 --wallet-id <wallet-id> --label savings

Account show, derive, label, and remove accept --wallet-id to target an exact stored wallet without changing the active wallet. Labels are not accepted by this option. Omitting it keeps the active-wallet default. Desktop account changes require an explicit wallet ID so a reviewed change stays attached to the intended wallet. Account removal only removes address-book metadata; the key remains derivable and funds are unaffected. Account labeling validates the derivation path before saving it.

Balances And Transfers

| Command | Description | | --- | --- | | xl1-wallet balance [offset] | Get the XL1 balance for an account offset. | | xl1-wallet send <recipient> <amount> | Send XL1 from an account in the active wallet to an address. |

Examples:

xl1-wallet balance 0
xl1-wallet send 0x1111111111111111111111111111111111111111 1 --xl1
xl1-wallet send 0x1111111111111111111111111111111111111111 250 --micro --offset 0
xl1-wallet send 0x1111111111111111111111111111111111111111 1.5 --milli --dry-run
xl1-wallet send 0x1111111111111111111111111111111111111111 1000000000000000000 --atto --json

send supports --dry-run, which signs and validates the transaction plan without submitting it to the network.

Use --json when scripting:

xl1-wallet send 0x1111111111111111111111111111111111111111 1 --xl1 --json

Amount Units

Amounts are converted to attoXL1 before signing.

| Flag | Unit | Atto multiplier | Fractional input | | --- | --- | ---: | --- | | --xl1 | XL1 | 1000000000000000000 | Yes | | --milli | milliXL1 | 1000000000000000 | Yes | | --micro | microXL1 | 1000000000000 | Yes | | --nano | nanoXL1 | 1000000000 | Yes | | --pico | picoXL1 | 1000000 | Yes | | --femto | femtoXL1 | 1000 | Yes | | --atto | attoXL1 | 1 | No |

If no unit flag is supplied, send defaults to --xl1.

Contacts

| Command | Description | | --- | --- | | xl1-wallet contact add <address> <label> | Save a contact. | | xl1-wallet contact list | List saved contacts. | | xl1-wallet contact rename <address> <label> | Rename a contact. | | xl1-wallet contact remove <address> | Remove a contact. |

Examples:

xl1-wallet contact add 0x1111111111111111111111111111111111111111 treasury
xl1-wallet contact list

Transaction Files And Payloads

Use sign to sign a payload JSON file directly:

xl1-wallet sign payload.json --output signed-payload.json

Use tx sign and tx broadcast for XL1 transaction files. This path supports on-chain payloads. Replace the chain value with the target XL1 chain id.

{
  "chain": "0x1234",
  "nbf": 0,
  "exp": 4102444800,
  "onChainPayloads": [
    {
      "schema": "network.xyo.example",
      "payload": {
        "message": "hello xl1"
      }
    }
  ]
}
xl1-wallet tx sign unsigned-transaction.json --output signed-transaction.json
xl1-wallet tx broadcast signed-transaction.json

JWTs

Create, verify, and decode wallet-signed JWTs:

xl1-wallet jwt create --audience https://example.com --claim role=operator
xl1-wallet jwt verify <token> --audience https://example.com
xl1-wallet jwt decode <token>

Create a JWT from a payload file:

xl1-wallet jwt create \
  --audience https://example.com \
  --schema network.xyo.example \
  --payload-file payload.json \
  --output token.jwt

Backup And Reset

Backup exports and imports wallet CLI metadata such as contacts and address books. It does not replace saving wallet recovery phrases.

xl1-wallet backup export wallet-metadata.json
xl1-wallet backup import wallet-metadata.json
xl1-wallet reset

Metadata backups retain the version 1 network.xyo.wallet.backup format. They contain address-book offsets and labels, and contact addresses, labels, and timestamps. They do not contain recovery phrases, passwords, session credentials, or network configuration. Imports merge metadata: incoming defined account labels and contact labels win, existing account labels survive when incoming labels are omitted, and existing contact creation timestamps are preserved. Contact update timestamps never move backward when importing an older backup.

Review an import or export before applying it:

xl1-wallet backup inspect wallet-metadata.json --direction=import --json
xl1-wallet backup inspect wallet-metadata.json --direction=export --json

The JSON result is {root, stateHash, path, fileStateHash, exists, addressBooks, accounts, contacts}. root and path are canonical absolute paths. Counts refer to incoming backup entries for import, or the stored metadata to export. The inspection exposes only paths, counts, existence, and hashes. To require exactly the reviewed wallet and file states, pass both hashes to the subsequent command:

xl1-wallet backup import wallet-metadata.json \
  --expected-state=<stateHash> --expected-file-state=<fileStateHash> --json
xl1-wallet backup export wallet-metadata.json --overwrite \
  --expected-state=<stateHash> --expected-file-state=<fileStateHash> --json

Import returns {imported: true, addressBooks, accounts, contacts}; export returns {exported: true, addressBooks, accounts, contacts}. Existing export destinations require --overwrite. New exports never overwrite a file created concurrently. Exports use private 0600 temporary files, fsync, and atomic publication. Imports commit address books and contacts together through the wallet recovery journal and never modify their source backup. Cooperating CLI processes coordinate by wallet root and export destination, including exports from different wallet roots.

Files must be regular files of at most 16 MiB, with one filesystem link. Symlinks, directories, special files, wallet storage files, and wallet transaction or lease paths are rejected. The parent directory must already exist. Version 1 schemas and fields are validated strictly; unknown entries, duplicate books/accounts or contacts, invalid legacy or quant addresses, and prototype keys are rejected. Labels preserve every string accepted by existing version 1 authoring commands, including empty, multiline, and long values, within the overall file size limit. Offsets use decimal HD path segments up to 2147483647, optional hardened apostrophes and m/, at most 32 segments and 512 characters. Timestamps use UTC ISO format with milliseconds, as produced by the CLI.

For noninteractive reset, pass both --confirm=RESET and --yes; --json returns {reset: true, removedFiles: number}. No password is required. Reset removes only password.json, phrases.json, active.json, address-books.json, contacts.json, networks.json, session.json, and .machine-id. It preserves the directory and unrelated files, and refuses to recurse into a directory occupying one of those filenames.

Output And Automation

Most commands print readable text by default. Commands intended for automation, such as send, also support JSON output:

xl1-wallet send 0x1111111111111111111111111111111111111111 1 --xl1 --json

For isolated test runs, set a temporary wallet home:

XL1_WALLET_HOME="$(mktemp -d)" ARIES_WALLET_PASSWORD="test-password" xl1-wallet create

Development

Compile the package:

pnpm xy compile @xyo-network/wallet-xl1-cli

Run the wallet CLI test suite:

pnpm exec vitest run packages/wallet-cli-lib/src/spec/*.spec.ts --project node

Smoke-test the built bin:

node packages/wallet-cli/dist/bin/wallet.mjs --help

License

LGPL-3.0-only

Machine-readable output

The read/listing commands accept --json to emit structured JSON instead of formatted text:

xl1-wallet list --json
xl1-wallet account list --json
xl1-wallet account show 0 --json
xl1-wallet balance --json
xl1-wallet network list --json
xl1-wallet contact list --json
xl1-wallet export --json

In --json mode the command prints only JSON to stdout (no decoration), so the output can be piped directly into jq or another parser.

Credits

Made with 🔥 and ❄️ by XYO Foundation