docs: standardize extension names to BCR-agreed standard

Replace placeholder 'bip352' / 'bip47_rpa' with the finalized
extension names from the BCR post and BCH Stealth Protocol spec:

- bip352      → bch_stealth_bip352
- bip47_rpa   → rpa_bip47

Add spend_path / scan_path fields to each extension handshake
object, pointing to the hardened gate paths where the wallet
exports xpubs. Dapps derive the non-hardened /0 child locally.

Add rpa_spend / rpa_scan path names alongside stealth_spend /
stealth_scan in all examples. Update known extensions table with
full path information and BCR reference links.

Spec: https://bitcoincashresearch.org/t/ecdh-stealth-addresses-on-bitcoin-cash-implementation-code/1773/5

I have read the CLA Document and I hereby sign the CLA
This commit is contained in:
CyberAshven 2026-03-28 22:39:34 +03:00
parent 8b6a2e275f
commit d1369f5867

View file

@ -21,18 +21,30 @@ interface Hdwalletv1Session {
```
Each key in `extensions` is an extension name. Its **presence** indicates the wallet supports that
extension. The value carries extension-specific handshake data, or `{}` if no data is needed.
extension. The value carries extension-specific handshake data (derivation paths to the hardened
gate where the wallet exports xpubs), or `{}` if no data is needed.
Example:
```json
{
"paths": [
{ "name": "receive", "xpub": "xpub6..." },
{ "name": "change", "xpub": "xpub6..." },
{ "name": "defi", "xpub": "xpub6..." }
{ "name": "receive", "xpub": "xpub6..." },
{ "name": "change", "xpub": "xpub6..." },
{ "name": "defi", "xpub": "xpub6..." },
{ "name": "stealth_spend", "xpub": "xpub6..." },
{ "name": "stealth_scan", "xpub": "xpub6..." },
{ "name": "rpa_spend", "xpub": "xpub6..." },
{ "name": "rpa_scan", "xpub": "xpub6..." }
],
"extensions": {
"bip352": {},
"bch_stealth_bip352": {
"spend_path": "m/352'/145'/0'/0'",
"scan_path": "m/352'/145'/0'/1'"
},
"rpa_bip47": {
"spend_path": "m/47'/145'/0'/0'",
"scan_path": "m/47'/145'/0'/1'"
},
"decrypt": { "public_key": "02abc...", "scheme": "ecies" }
}
}
@ -46,13 +58,22 @@ Example:
```json
{
"paths": [
{ "name": "receive", "xpub": "xpub6..." },
{ "name": "change", "xpub": "xpub6..." },
{ "name": "stealth_scan", "xpub": "xpub6..." },
{ "name": "stealth_spend", "xpub": "xpub6..." }
{ "name": "receive", "xpub": "xpub6..." },
{ "name": "change", "xpub": "xpub6..." },
{ "name": "stealth_spend", "xpub": "xpub6..." },
{ "name": "stealth_scan", "xpub": "xpub6..." },
{ "name": "rpa_spend", "xpub": "xpub6..." },
{ "name": "rpa_scan", "xpub": "xpub6..." }
],
"extensions": {
"bip352": {}
"bch_stealth_bip352": {
"spend_path": "m/352'/145'/0'/0'",
"scan_path": "m/352'/145'/0'/1'"
},
"rpa_bip47": {
"spend_path": "m/47'/145'/0'/0'",
"scan_path": "m/47'/145'/0'/1'"
}
}
}
```
@ -123,13 +144,24 @@ const adapter: WalletAdapter = {
getAdditionalPaths() {
return [
{ name: "stealth_scan", xpub: deriveScanXpub() },
{ name: "stealth_spend", xpub: deriveSpendXpub() },
{ name: "stealth_spend", xpub: deriveXpub("m/352'/145'/0'/0'") },
{ name: "stealth_scan", xpub: deriveXpub("m/352'/145'/0'/1'") },
{ name: "rpa_spend", xpub: deriveXpub("m/47'/145'/0'/0'") },
{ name: "rpa_scan", xpub: deriveXpub("m/47'/145'/0'/1'") },
];
},
getExtensions() {
return { "bip352": {} };
return {
"bch_stealth_bip352": {
"spend_path": "m/352'/145'/0'/0'",
"scan_path": "m/352'/145'/0'/1'",
},
"rpa_bip47": {
"spend_path": "m/47'/145'/0'/0'",
"scan_path": "m/47'/145'/0'/1'",
},
};
},
};
```
@ -145,11 +177,18 @@ Dapps check for extension support after receiving `wallet_ready`:
manager.on("walletready", (msg) => {
const session = msg.session["hdwalletv1"] as Hdwalletv1Session;
if (session.extensions?.bip352) {
const scanPath = session.paths.find(p => p.name === "stealth_scan");
if (session.extensions?.bch_stealth_bip352) {
const scanPath = session.paths.find(p => p.name === "stealth_scan");
const spendPath = session.paths.find(p => p.name === "stealth_spend");
// enable stealth address features
} else {
// show: "Stealth payments require a wallet that supports BIP352"
// show: "Stealth payments require a wallet that supports BCH Stealth (BIP352)"
}
if (session.extensions?.rpa_bip47) {
const rpaSpend = session.paths.find(p => p.name === "rpa_spend");
const rpaScan = session.paths.find(p => p.name === "rpa_scan");
// enable RPA features
}
});
```
@ -159,12 +198,10 @@ wallet doesn't support, inform the user rather than failing silently.
## Known extensions
No extensions are standardized yet. The following are under discussion:
| Extension name | Purpose | Status |
|---------------|---------|--------|
| `bip352` | BIP352 silent/stealth payments. Adds `stealth_scan` and `stealth_spend` paths. | Proposed |
| `bip47_rpa` | BIP47 reusable payment addresses. Adds `rpa` path and payment code data. | Proposed |
| `decrypt` | Dapp-side encrypted storage. Wallet provides a public key; dapp encrypts data for storage and sends `decrypt_request` messages when the data is needed. | Proposed |
| Extension name | Path names | Hardened gate paths | Purpose | Status |
|---------------|-----------|---------------------|---------|--------|
| `bch_stealth_bip352` | `stealth_spend`, `stealth_scan` | `m/352'/145'/0'/0'`, `m/352'/145'/0'/1'` | BCH stealth addresses (BIP352 structure). Wallet exports xpubs at hardened gates; dapp derives `/0` child locally. | Standard — [BCR post](https://bitcoincashresearch.org/t/ecdh-stealth-addresses-on-bitcoin-cash-implementation-code/1773/5) |
| `rpa_bip47` | `rpa_spend`, `rpa_scan` | `m/47'/145'/0'/0'`, `m/47'/145'/0'/1'` | BIP47 reusable payment addresses. Wallet exports xpubs at hardened gates; dapp derives `/0` child locally. | Standard — [BCR post](https://bitcoincashresearch.org/t/ecdh-stealth-addresses-on-bitcoin-cash-implementation-code/1773/5) |
| `decrypt` | — | — | Dapp-side encrypted storage. Wallet provides a public key; dapp encrypts data for storage and sends `decrypt_request` messages when the data is needed. | Proposed |
See the discussions and specifications for each extension as they are formalized.