rob thijssen 851500a5fb fix: manifest author and homepage are blackbeard's, not polkadot{.js}'s
The rebrand renamed the extension but left the manifest's author as
"polkadot.{js}" and its homepage as the upstream GitHub repo. Browsers show
both on the add-on's details page. Package.json authorship stays upstream's:
that is credit for the code, not the extension's identity.

Refs #2, #15

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
2026-09-16 20:50:20 +03:00
2025-01-03 02:15:31 +02:00
2024-07-31 04:07:05 +03:00
2022-01-13 10:07:35 +02:00
2019-05-20 12:40:44 +02:00
2024-03-24 17:47:57 +02:00
2021-06-08 18:05:50 +03:00
2026-03-12 19:27:39 +02:00
2026-07-31 12:43:58 -03:00
2026-07-31 15:14:13 +00:00
2026-03-12 19:27:39 +02:00
2019-05-20 12:40:44 +02:00
2026-09-16 19:34:06 +03:00
2026-03-12 19:27:39 +02:00
2021-07-09 15:28:47 +02:00
2022-01-11 09:02:35 +02:00
2023-03-07 12:30:15 +02:00

blackbeard

A post-quantum browser wallet for the Quantus Network, forked from the polkadot{.js} extension. It keeps upstream's shape — accounts in a popup, a signer injected into dapps — with the cryptography, encoding and account model Quantus actually needs:

  • ML-DSA only. Accounts are ML-DSA-65 and ML-DSA-87 (the two variants of the runtime's DilithiumSignatureScheme), derived as quantus-cli and the mobile wallet derive them.
  • The runtime is the codec. Calls and extrinsics are encoded and decoded from the chain's own metadata (@quantus/codec), fetched from a node and checked against its genesis — never from a hardcoded type registry, which drifts from a runtime that changes.
  • Wallets, not keypairs. A recovery phrase is one wallet, shown as every account it unlocks: ML-DSA-65, ML-DSA-87 and wormhole tabs, per account index. The phrase is stored encrypted with the wallet password so further accounts can be derived later.
  • Wormhole balances, read-only. Deposits come from a blackbeard observer and are checked against the chain's own transfer counts; spent status is decided locally from nullifiers precomputed while the password is to hand, checked against whole buckets of Wormhole::UsedNullifiers so no node learns which ones are yours. Sending from a wormhole address is not in the extension yet (quantus/extension#13).

Work is tracked at git.lair.cafe/quantus/extension/issues; #1 is the epic.

Installation

There is no store listing. Build from source (below), or use the zips a build writes to the repo root.

  • Firefox: about:debugging#/runtime/this-firefoxLoad Temporary Add-on…master-ff-build.zip. Temporary add-ons are unloaded on restart; a permanent install of an unsigned add-on needs Developer Edition or Nightly with xpinstall.signatures.required set to false.
  • Chrome / Chromium / Brave: unzip master-chrome-build.zip into a folder, then chrome://extensionsDeveloper modeLoad unpacked → that folder. Not packages/extension/build, which holds whichever browser was built last.

Privacy settings

Everything the extension asks the network is a setting, and each can be pointed at your own infrastructure or turned off:

  • Read balances from — the node used for balances and wormhole chain state.
  • Look up wormhole deposits with — the observer asked which deposits went to your wormhole addresses. It learns that those addresses belong to one person; nothing it is sent can name your exits.

Development

yarn install
yarn build          # both browsers; writes master-chrome-build.zip and master-ff-build.zip
yarn test           # background specs (the upstream React specs are not run: see quantus/extension#14)
yarn lint

The Quantus forks it builds against (@polkadot/util-crypto, @polkadot/keyring, @polkadot/ui-keyring, @polkadot/networks) and @quantus/crypto / @quantus/codec come from the Gitea package registry; see .yarnrc.yml. scripts/tier1 submits real extrinsics against a node, and scripts/tier2 is a dapp harness for exercising the injected signer in a browser.

The packages keep their upstream @polkadot/extension-* names:

Dapp developers

Use @polkadot/extension-dapp, or any library that enumerates window.injectedWeb3; this extension appears there as blackbeard. Signing requests are encoded and shown using the chain's own metadata, so a dapp does not need to supply any.

API interface

The extension injection interfaces are generic, i.e. it is designed to allow any extension developer to easily inject extensions (that conforms to a specific interface) and at the same time, it allows for any dapp developer to easily enable the interfaces from multiple extensions at the same time. It is not an all-or-nothing approach, but rather it is an ecosystem where the user can choose which extensions fit their style best.

From a dapp developer perspective, the only work needed is to include the @polkadot/extension-dapp package and call the appropriate enabling function to retrieve all the extensions and their associated interfaces.

From an extension developer perspective, the only work required is to enable the extension via the razor-thin @polkadot/extension-inject wrapper. Any dapp using the above interfaces will have access to the extension via this interface.

When there is more than one extension, each will populate an entry via the injection interface and each will be made available to the dapp. The Injected interface, as returned via enable, contains the following information for any compliant extension -

interface Injected {
  // the interface for Accounts, as detailed below
  readonly accounts: Accounts;
  // the standard Signer interface for the API, as detailed below
  readonly signer: Signer;
  // not injected as of yet, subscribable provider for polkadot-js API injection,
  // this can be passed to the API itself upon construction in the dapp
  // readonly provider?: Provider
}

interface Account = {
  // ss-58 encoded address
  readonly address: string;
  // the genesisHash for this account (empty if applicable to all)
  readonly genesisHash?: string;
  // (optional) name for display
  readonly name?: string;
};

// exposes accounts
interface Accounts {
  // retrieves the list of accounts for right now
  get: () => Promise<Account[]>;
  // (optional) subscribe to all accounts, updating as they change
  subscribe?: (cb: (accounts: Account[]) => any) => () => void
}

// a signer that communicates with the extension via sendMessage
interface Signer extends SignerInterface {
  // no specific signer extensions, exposes the `sign` interface for use by
  // the polkadot-js API, confirming the Signer interface for this API
}

Injection information

The information contained in this section may change and evolve. It is therefore recommended that all access is done via the @polkadot/extension-dapp (for dapps) and extension-inject (for extensions) packages, which removes the need to work with the lower-level targets.

The extension injects injectedWeb3 into the global window object, exposing the following: (This is meant to be generic across extensions, allowing any dapp to utilize multiple signers, and pull accounts from multiples, as they are available.)

window.injectedWeb3 = {
  // this is the name for this extension, there could be multiples injected,
  // each with their own keys, here `blackbeard` is for this extension
  'blackbeard': {
    // semver for the package
    version: '0.1.0',

    // this is called to enable the injection, and returns an injected
    // object containing the accounts, signer and provider interfaces
    // (or it will reject if not authorized)
    enable (originName: string): Promise<Injected>
  }
}

Recovery phrases and passwords

A wallet's password encrypts the stored recovery phrase and each account's key; the phrase itself is not protected by it, so anyone with the phrase controls every account the wallet shows. Import accepts a BIP39 phrase, or a 0x-prefixed 32-byte seed for the dev accounts. There are no derivation paths to type: account indices are added from the wallet's menu, and derive the same accounts quantus-cli and the mobile wallet derive for that index.

Description
No description provided
Readme Apache-2.0 62 MiB
Languages
TypeScript 93.4%
JavaScript 5.2%
HTML 0.7%
CSS 0.5%
Shell 0.2%