A wormhole address's System.Account balance is a receipt total. An exit
credits the exit account and records a nullifier, and nothing debits the
address. So what a wallet account can still spend is worked out deposit by
deposit, in pri(wallets.wormholeBalance):
- Transfer counts come from the chain's Wormhole.TransferCount, read from the
balance node.
- Deposits come from a blackbeard observer
(/v1/chains/{chain}/wormhole/deposits, blackbeard/observer#22), matched by
genesis, never by name. Anything the chain counts that the observer didn't
return is reported as missing, never folded into a smaller balance.
- Spent status comes from Wormhole.UsedNullifiers, read in whole buckets by
the first byte of blake2_128(nullifier), at least 16 buckets with random
decoys, in a shuffled order. A lookup by key would hand the node the
nullifier, and exits publish theirs.
- A deposit whose nullifier was never computed is reported as unchecked.
Nullifiers are precomputed while the password is available and stored per
wallet account: 128 transfer counts for each of the 40 addresses when a phrase
wallet or account is made. pri(wallets.wormholeUnlock) extends only the
addresses whose deposits outgrew what is stored, to their count plus 128.
Forgetting a wallet removes its nullifiers for every account index along with
the secret and the pairs. They're kept under their own prefix, and the
manifests ask for unlimitedStorage, since a busy mining address alone runs to
megabytes.
@quantus/crypto 0.3.0 provides wormholeNullifiers, pinned there to the chain's
circuit crate.
Specs: a wallet stores a full window whose bytes match a direct derivation; a
raw seed stores none; unlock extends only the addresses past their window and
keeps what was there; forget removes every account's nullifiers.
Live against mainnet and the deployed observer:
- a spent nullifier taken from a public ProofVerified event is found in its
bucket (240 entries, 158 ms);
- for a mining address the chain counts 41,849 transfers, the observer
returned 24,702, and 17,147 are reported missing. That is blackbeard/
observer#23's gap, now being rescanned, surfacing as intended.
Part of quantus/extension#14.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
48 lines
1.4 KiB
JSON
48 lines
1.4 KiB
JSON
{
|
|
"author": "Jaco Greeff <jacogr@gmail.com>",
|
|
"bugs": "https://github.com/polkadot-js/extension/issues",
|
|
"description": "Functions, classes and other utilities used in @polkadot/extension",
|
|
"engines": {
|
|
"node": ">=18"
|
|
},
|
|
"homepage": "https://github.com/polkadot-js/extension/tree/master/packages/extension-base#readme",
|
|
"license": "Apache-2.0",
|
|
"name": "@polkadot/extension-base",
|
|
"repository": {
|
|
"directory": "packages/extension-base",
|
|
"type": "git",
|
|
"url": "https://github.com/polkadot-js/extension.git"
|
|
},
|
|
"sideEffects": [
|
|
"./packageDetect.js",
|
|
"./packageDetect.cjs"
|
|
],
|
|
"type": "module",
|
|
"version": "0.64.0",
|
|
"main": "index.js",
|
|
"dependencies": {
|
|
"@polkadot/api": "^16.5.6",
|
|
"@polkadot/extension-chains": "0.64.0",
|
|
"@polkadot/extension-dapp": "0.64.0",
|
|
"@polkadot/extension-inject": "0.64.0",
|
|
"@polkadot/keyring": "^14.0.3",
|
|
"@polkadot/networks": "^14.0.3",
|
|
"@polkadot/phishing": "^0.25.25",
|
|
"@polkadot/rpc-provider": "^16.5.6",
|
|
"@polkadot/types": "^16.5.6",
|
|
"@polkadot/ui-keyring": "^3.16.7",
|
|
"@polkadot/ui-settings": "^3.16.7",
|
|
"@polkadot/util": "^14.0.3",
|
|
"@polkadot/util-crypto": "^14.0.3",
|
|
"@quantus/codec": "^0.5.0",
|
|
"@quantus/crypto": "^0.3.0",
|
|
"eventemitter3": "^5.0.1",
|
|
"rxjs": "^7.8.1",
|
|
"tslib": "^2.8.1"
|
|
},
|
|
"devDependencies": {
|
|
"@polkadot/dev-test": "^0.83.3",
|
|
"@polkadot/extension-mocks": "0.64.0"
|
|
}
|
|
}
|