@ducat-unit/wallet-snap 0.1.2 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUDIT_SCOPE.md +5 -5
- package/DEMO_SCRIPT.md +3 -3
- package/LISTING.md +4 -4
- package/README.md +72 -150
- package/RELEASE_CHECKLIST.md +34 -30
- package/SECURITY.md +5 -6
- package/SNAPPER_REVIEW.md +3 -1
- package/SUPPORT.md +1 -1
- package/dist/bundle.js +1 -1
- package/package.json +4 -2
- package/snap.manifest.json +10 -7
package/AUDIT_SCOPE.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Ducat Snap Audit Scope
|
|
2
2
|
|
|
3
|
-
This file defines the minimum security review scope before
|
|
3
|
+
This file defines the minimum security review scope before MetaMask allowlisting for `@ducat-unit/wallet-snap@0.1.5`.
|
|
4
4
|
|
|
5
5
|
## In Scope
|
|
6
6
|
|
|
7
7
|
- `snap.manifest.json` permissions and allowed origins.
|
|
8
|
-
- BIP32 entropy use for `m/84'/
|
|
8
|
+
- BIP32 entropy use for `m/84'/0'`, `m/86'/0'`, `m/84'/1'`, and `m/86'/1'`.
|
|
9
9
|
- Local BIP32 child derivation in `src/bip32.ts`.
|
|
10
10
|
- Account derivation in `src/accounts.ts`.
|
|
11
11
|
- BIP322-style message signing in `src/message.ts`.
|
|
@@ -17,7 +17,7 @@ This file defines the minimum security review scope before publishing `@ducat-un
|
|
|
17
17
|
- User confirmation content in `src/confirmations.ts`.
|
|
18
18
|
- State storage in `src/state.ts`.
|
|
19
19
|
- Home page network fetches in `src/home.ts`.
|
|
20
|
-
- Build artifacts produced by `npm run verify`.
|
|
20
|
+
- Build artifacts produced by `npm run verify:release`.
|
|
21
21
|
|
|
22
22
|
## Required Findings To Rule Out
|
|
23
23
|
|
|
@@ -25,7 +25,7 @@ This file defines the minimum security review scope before publishing `@ducat-un
|
|
|
25
25
|
- Any signing path that signs an input not explicitly listed in `signInputs`.
|
|
26
26
|
- Any signing path that signs inputs for addresses not derived by the Snap.
|
|
27
27
|
- Any irreversible operation that can proceed without a MetaMask confirmation.
|
|
28
|
-
- Any mainnet key path, address, broadcast endpoint, or
|
|
28
|
+
- Any mainnet request that uses a testnet key path, testnet address, or testnet broadcast endpoint, and any testnet request that uses a mainnet key path, mainnet address, or mainnet broadcast endpoint.
|
|
29
29
|
- Any unauthorized origin able to invoke Snap RPC methods.
|
|
30
30
|
- Any malformed PSBT, wrong-network PSBT, unknown address, or unknown input index that is accepted.
|
|
31
31
|
- Any package dependency that violates MetaMask Snap SES constraints or creates avoidable key-management risk.
|
|
@@ -40,7 +40,7 @@ The final audit package should include:
|
|
|
40
40
|
- Fixed commit hash, if fixes are required.
|
|
41
41
|
- `npm pack --dry-run` output.
|
|
42
42
|
- `npm audit --omit=dev` output.
|
|
43
|
-
- `npm run verify` output.
|
|
43
|
+
- `npm run verify:release` output.
|
|
44
44
|
- Snapper/security scan output.
|
|
45
45
|
- Final `snap.manifest.json` shasum.
|
|
46
46
|
- Demo video URL following `DEMO_SCRIPT.md`.
|
package/DEMO_SCRIPT.md
CHANGED
|
@@ -6,8 +6,8 @@ Use this script for the MetaMask allowlist/directory submission video. Record ag
|
|
|
6
6
|
|
|
7
7
|
1. Build and serve the Snap with `npm run verify` and `npm run serve`.
|
|
8
8
|
2. Configure the Ducat frontend with `NEXT_PUBLIC_DUCAT_SNAP_ID` pointing at the local Snap during pre-submission testing, or `npm:@ducat-unit/wallet-snap` for the npm build.
|
|
9
|
-
3. Use
|
|
10
|
-
4. Fund the Snap-derived sats account with
|
|
9
|
+
3. Use the audited network being demonstrated. For mainnet demos, use small controlled amounts and the audited production validator/frontend configuration.
|
|
10
|
+
4. Fund the Snap-derived sats account with BTC for the selected network.
|
|
11
11
|
|
|
12
12
|
## Recording Steps
|
|
13
13
|
|
|
@@ -31,5 +31,5 @@ Use this script for the MetaMask allowlist/directory submission video. Record ag
|
|
|
31
31
|
- Every irreversible signing action shows a MetaMask confirmation.
|
|
32
32
|
- Confirmations include origin, network, signed input indexes, output summary, and fee when calculable.
|
|
33
33
|
- Private keys are never exported or shown.
|
|
34
|
-
- Mainnet
|
|
34
|
+
- Mainnet, signet, and mutinynet all use the expected network-specific addresses, validator endpoints, and broadcast endpoints.
|
|
35
35
|
- Xverse and UniSat remain available in the wallet list.
|
package/LISTING.md
CHANGED
|
@@ -6,16 +6,16 @@ Ducat Bitcoin accounts and Ducat-aware transaction signing in MetaMask.
|
|
|
6
6
|
|
|
7
7
|
## Long Description
|
|
8
8
|
|
|
9
|
-
Ducat is a MetaMask Snap for using Ducat with Bitcoin signet and mutinynet accounts derived inside MetaMask. The Snap derives deterministic
|
|
9
|
+
Ducat is a MetaMask Snap for using Ducat with Bitcoin mainnet, signet, and mutinynet accounts derived inside MetaMask. The Snap derives deterministic Bitcoin accounts from the user's MetaMask Secret Recovery Phrase, keeps private keys inside MetaMask, and signs only explicit PSBT inputs requested by the Ducat web app.
|
|
10
10
|
|
|
11
11
|
The Ducat web app remains the action surface for create, deposit, borrow, repay, withdraw, swap, liquidation, and repossess flows. The Snap provides account discovery, BIP322-style message signing, PSBT signing, batch PSBT signing, a simple transfer path, Ducat-aware MetaMask confirmations, pending/completed/failed action notifications, recent action history, and a Snap home page with copyable account addresses, BTC/UNIT balance, vault summary lookups, recent activity, and Ducat app routes.
|
|
12
12
|
|
|
13
|
-
Mainnet is
|
|
13
|
+
Mainnet is enabled in this audit candidate and must be covered by the third-party review before production distribution.
|
|
14
14
|
|
|
15
15
|
## Permissions Rationale
|
|
16
16
|
|
|
17
17
|
- `endowment:rpc`: Allows only approved Ducat frontend origins to invoke the Snap.
|
|
18
|
-
- `snap_getBip32Entropy`: Derives Bitcoin
|
|
18
|
+
- `snap_getBip32Entropy`: Derives Bitcoin account keys for `m/84'/0'`, `m/86'/0'`, `m/84'/1'`, and `m/86'/1'`.
|
|
19
19
|
- `snap_dialog`: Shows mandatory confirmations before message signing, PSBT signing, batch signing, or transfers.
|
|
20
20
|
- `snap_manageState`: Stores recent Ducat action metadata for Snap home.
|
|
21
21
|
- `snap_notify`: Shows informational MetaMask notifications for pending approvals, completed actions, and failed non-rejection actions.
|
|
@@ -28,7 +28,7 @@ Mainnet is intentionally not enabled in this release.
|
|
|
28
28
|
- Install approval screen for the Ducat Snap.
|
|
29
29
|
- Ducat app wallet modal showing MetaMask as a connector.
|
|
30
30
|
- Connected Ducat account addresses.
|
|
31
|
-
- PSBT confirmation for create or deposit showing an action title, origin,
|
|
31
|
+
- PSBT confirmation for create or deposit showing an action title, origin, network, compact summary rows, signed input details, output details, fees, warnings, and Ducat app metadata.
|
|
32
32
|
- Batch confirmation for liquidation or repossess showing all-or-nothing signing, per-transaction rows, total fee, and warnings.
|
|
33
33
|
- Message signing confirmation showing origin, network, signing account, BIP322 signature type, message fingerprint, message length, and copyable message body.
|
|
34
34
|
- Transfer confirmation showing amount, fee, the `You pay` amount, change, sender, recipient, selected UTXOs, and broadcast endpoint.
|
package/README.md
CHANGED
|
@@ -1,242 +1,164 @@
|
|
|
1
1
|
# Ducat MetaMask Snap
|
|
2
2
|
|
|
3
|
-
`@ducat-unit/wallet-snap` is the Ducat Bitcoin account and signing Snap for MetaMask.
|
|
3
|
+
`@ducat-unit/wallet-snap` is the Ducat Bitcoin account and signing Snap for MetaMask. It derives deterministic mainnet, signet, and mutinynet Bitcoin accounts from the user's MetaMask Secret Recovery Phrase, keeps private keys inside MetaMask, and exposes a narrow Ducat JSON-RPC API to approved Ducat frontend origins.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The Ducat web app remains the user action surface. Users create, deposit, borrow, repay, withdraw, swap, liquidate, and repossess in the web app; the Snap handles account discovery, MetaMask confirmations, message signing, PSBT signing, batch signing, transfer signing, recent action state, notifications, and Snap Home.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Release Candidate Status
|
|
8
8
|
|
|
9
|
+
- Package candidate: `@ducat-unit/wallet-snap@0.1.5`
|
|
10
|
+
- Snap ID: `npm:@ducat-unit/wallet-snap`
|
|
9
11
|
- Proposed Snap name: `Ducat`
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Derivation paths:
|
|
16
|
-
- sats: `m/84'/1'/0'/0/0`, P2WPKH `tb1q...`, compressed 33-byte public key
|
|
17
|
-
- runes: `m/86'/1'/0'/0/0`, P2TR `tb1p...`, x-only 32-byte internal public key
|
|
18
|
-
- vault: `m/86'/1'/0'/0/1`, P2TR `tb1p...`, x-only 32-byte internal public key
|
|
12
|
+
- Audit candidate tag: `audit-candidate-0.1.5-20260615-audit-confirmation-hardening`
|
|
13
|
+
- Audit candidate commit: tag target for `audit-candidate-0.1.5-20260615-audit-confirmation-hardening`
|
|
14
|
+
- GitHub verification: `Verify Ducat Snap`
|
|
15
|
+
- Manifest source shasum: `RE0s+LP6Soq0Xn0R8P+DA2ChhPOB2pasPp9BsJng5/Y=`
|
|
16
|
+
- Package candidate digest evidence: `RELEASE_EVIDENCE.md`
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
Launch scope:
|
|
21
19
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
20
|
+
- Networks: `mainnet`, `signet`, and `mutinynet`
|
|
21
|
+
- Mainnet: enabled in this audit candidate
|
|
22
|
+
- Derivation paths:
|
|
23
|
+
- sats mainnet: `m/84'/0'/0'/0/0`, P2WPKH `bc1q...`, compressed 33-byte public key
|
|
24
|
+
- runes mainnet: `m/86'/0'/0'/0/0`, P2TR `bc1p...`, x-only 32-byte internal public key
|
|
25
|
+
- vault mainnet: `m/86'/0'/0'/0/1`, P2TR `bc1p...`, x-only 32-byte internal public key
|
|
26
|
+
- sats testnet: `m/84'/1'/0'/0/0`, P2WPKH `tb1q...`, compressed 33-byte public key
|
|
27
|
+
- runes testnet: `m/86'/1'/0'/0/0`, P2TR `tb1p...`, x-only 32-byte internal public key
|
|
28
|
+
- vault testnet: `m/86'/1'/0'/0/1`, P2TR `tb1p...`, x-only 32-byte internal public key
|
|
26
29
|
|
|
27
30
|
## Install
|
|
28
31
|
|
|
29
32
|
```bash
|
|
30
|
-
cd /Users/lucasrodriguez/Desktop/Ducat/SNAP
|
|
31
33
|
npm ci
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Use the normal development gate while editing:
|
|
36
|
+
Recommended local edit gate:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
npm run type-check
|
|
40
|
-
npm test
|
|
40
|
+
npm test -- --runInBand
|
|
41
41
|
npm run build
|
|
42
42
|
npm run manifest
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Or run the combined gate:
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm run verify
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
After `npm run verify`, smoke-test the built Snap in MetaMask's simulation runtime:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
43
|
npm run harness:accounts
|
|
44
|
+
npm run harness:smoke-signing
|
|
55
45
|
```
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
The stricter release gate also runs the MetaMask simulation harness smoke test, production dependency audit, Snapper, and an npm package dry-run:
|
|
47
|
+
Full release gate:
|
|
60
48
|
|
|
61
49
|
```bash
|
|
62
50
|
npm run verify:release
|
|
63
51
|
```
|
|
64
52
|
|
|
53
|
+
`verify:release` runs type checking, Jest, build, manifest regeneration, MetaMask simulation harness checks, production dependency audit, Snapper, release metadata verification, release manifest verification, and `npm pack --dry-run`.
|
|
54
|
+
|
|
65
55
|
## Run Locally
|
|
66
56
|
|
|
67
|
-
Serve the Snap
|
|
57
|
+
Serve the local Snap:
|
|
68
58
|
|
|
69
59
|
```bash
|
|
70
|
-
cd /Users/lucasrodriguez/Desktop/Ducat/SNAP
|
|
71
60
|
npm run serve
|
|
72
61
|
```
|
|
73
62
|
|
|
74
|
-
The Snap is served
|
|
63
|
+
The local Snap is served at:
|
|
75
64
|
|
|
76
65
|
```text
|
|
77
66
|
http://localhost:8080
|
|
78
67
|
```
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
npm run build
|
|
84
|
-
npm run manifest
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Then restart `npm run serve` if the server is already running.
|
|
88
|
-
|
|
89
|
-
## Frontend Setup
|
|
90
|
-
|
|
91
|
-
In the Ducat frontend `.env.local`, point the MetaMask connector at the local Snap:
|
|
69
|
+
For local frontend testing:
|
|
92
70
|
|
|
93
71
|
```bash
|
|
94
72
|
NEXT_PUBLIC_DUCAT_SNAP_ID="local:http://localhost:8080"
|
|
95
73
|
NEXT_PUBLIC_DUCAT_SNAP_VERSION=""
|
|
96
74
|
```
|
|
97
75
|
|
|
98
|
-
For the published Snap
|
|
76
|
+
For the published Snap:
|
|
99
77
|
|
|
100
78
|
```bash
|
|
101
79
|
NEXT_PUBLIC_DUCAT_SNAP_ID="npm:@ducat-unit/wallet-snap"
|
|
102
|
-
NEXT_PUBLIC_DUCAT_SNAP_VERSION="^0.1.
|
|
80
|
+
NEXT_PUBLIC_DUCAT_SNAP_VERSION="^0.1.5"
|
|
103
81
|
```
|
|
104
82
|
|
|
105
|
-
|
|
83
|
+
Allowed HTTPS Ducat origins in the published mainnet manifest:
|
|
106
84
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
Allowed local origins are:
|
|
113
|
-
|
|
114
|
-
- `http://localhost:3000`
|
|
115
|
-
- `http://localhost:3001`
|
|
116
|
-
- `http://localhost:3002`
|
|
117
|
-
- `http://localhost:3003`
|
|
118
|
-
|
|
119
|
-
Allowed HTTPS QA origins are:
|
|
120
|
-
|
|
121
|
-
- `https://dev-git-feat-metamask-snap-connector-ducat.vercel.app`
|
|
122
|
-
|
|
123
|
-
These localhost origins are intentionally present for local development and Snap QA only. Do not remove them from the development manifest during local testing.
|
|
124
|
-
|
|
125
|
-
### Known Deferred Issue: Localhost Manifest Origins
|
|
126
|
-
|
|
127
|
-
`snap.manifest.json` currently includes localhost origins. That is intentional for local Snap development and QA, but the current development manifest is not directory-ready. Do not remove the localhost origins in this iteration; handle this as a dedicated release-manifest task before MetaMask submission.
|
|
128
|
-
|
|
129
|
-
Release update plan:
|
|
130
|
-
|
|
131
|
-
1. Keep the current development manifest available for local Snap testing.
|
|
132
|
-
2. Add a release manifest path or manifest-generation mode that removes every localhost origin.
|
|
133
|
-
3. Keep only approved HTTPS Ducat frontend origins in `endowment:rpc.allowedOrigins`.
|
|
134
|
-
4. Rebuild from the audited commit and regenerate the Snap manifest source shasum.
|
|
135
|
-
5. Update all release artifacts from that exact build: `RELEASE_EVIDENCE.md`, `AUDITOR_HANDOFF.md`, `submission/metamask-directory.json`, `submission/ALLOWLIST_SUBMISSION.md`, package shasum/integrity, screenshots, demo notes, and frontend production Snap env values.
|
|
136
|
-
6. Run `npm run build`, `npm run manifest`, `npm run verify:release-manifest`, `npm run verify:release`, and `npm run verify:submission-ready`.
|
|
137
|
-
7. Retag the final audit or submission candidate only after the release manifest, package evidence, and submission metadata are synced.
|
|
138
|
-
|
|
139
|
-
## MetaMask Local Update Flow
|
|
85
|
+
- `https://app.ducatprotocol.com`
|
|
86
|
+
- `https://dev.app.ducatprotocol.com`
|
|
87
|
+
- `https://staging.app.ducatprotocol.com`
|
|
140
88
|
|
|
141
|
-
|
|
142
|
-
2. Run the frontend with `NEXT_PUBLIC_DUCAT_SNAP_ID="local:http://localhost:8080"`.
|
|
143
|
-
3. Connect MetaMask from the Ducat wallet picker.
|
|
144
|
-
4. If the Snap was already installed and the local shasum changed, use the frontend `Update Snap` button in the wallet picker or connected wallet dropdown.
|
|
145
|
-
5. Approve the MetaMask update prompt.
|
|
146
|
-
6. Retry the Ducat action.
|
|
147
|
-
|
|
148
|
-
The connector intentionally does not call `wallet_requestSnaps` before every signature. Signing methods use `wallet_invokeSnap` against the installed Snap, so a stale local build must be updated explicitly.
|
|
89
|
+
The published manifest authorizes only stable, org-controlled HTTPS Ducat origins. Local development (`http://localhost`) and ephemeral, re-registerable preview deployments (`*.vercel.app`) are deliberately excluded so a local process or a taken-over preview subdomain can never drive mainnet signing; use a separate, unpublished dev manifest for local Snap QA. The release verifier rejects localhost, non-HTTPS, wildcard, duplicate, or unknown origins in the shipped manifest.
|
|
149
90
|
|
|
150
91
|
## JSON-RPC API
|
|
151
92
|
|
|
152
93
|
- `ducat_getAccounts({ network })`
|
|
153
|
-
- `ducat_clearRecentActions()`
|
|
154
94
|
- `ducat_getCapabilities()`
|
|
155
95
|
- `ducat_signMessage({ network, address, message })`
|
|
156
96
|
- `ducat_signPsbt({ network, psbt, signInputs, context })`
|
|
157
97
|
- `ducat_signBatch({ network, entries, context })`
|
|
158
98
|
- `ducat_sendTransfer({ network, address, amountSats, feeRate })`
|
|
159
99
|
- `ducat_getHomeState({ network })`
|
|
100
|
+
- `ducat_clearRecentActions()`
|
|
160
101
|
|
|
161
|
-
##
|
|
102
|
+
## User Confirmation Surface
|
|
162
103
|
|
|
163
|
-
MetaMask confirmations are
|
|
104
|
+
MetaMask confirmations are action-specific and structured:
|
|
164
105
|
|
|
165
|
-
- Message signing shows the Ducat action label, origin,
|
|
166
|
-
- PSBT signing shows the Ducat action label, origin,
|
|
106
|
+
- Message signing shows the Ducat action label, origin, network, account, BIP322 signature type, message length, message fingerprint, and copyable message body.
|
|
107
|
+
- PSBT signing shows the Ducat action label, origin, network, summary rows, signed input details, output details, fee, warnings, and Ducat app metadata.
|
|
167
108
|
- Batch signing shows transaction count, all-or-nothing semantics, total fee, per-transaction summaries, and warning count.
|
|
168
|
-
- Simple BTC transfer shows amount, estimated fee,
|
|
169
|
-
- Snap Home shows
|
|
170
|
-
- MetaMask notifications announce pending approvals, completed signing/broadcast actions, and non-rejection failures. Notifications are informational only and never gate signing behavior.
|
|
171
|
-
|
|
172
|
-
Errors returned to the frontend are friendly by default and include a stable `code` plus diagnostic `details` for developers. The frontend should display the `message` and keep details available for expanded debugging.
|
|
173
|
-
|
|
174
|
-
## Troubleshooting
|
|
109
|
+
- Simple BTC transfer shows amount, estimated fee, `You pay`, change, sender, recipient, selected UTXOs, and broadcast endpoint.
|
|
110
|
+
- Snap Home shows last connected network, copyable BTC/UNIT/vault addresses, public balance and vault lookups when available, recent action state, approved HTTPS Ducat app links, and local development routes.
|
|
175
111
|
|
|
176
|
-
|
|
177
|
-
| --- | --- | --- |
|
|
178
|
-
| `Fetching local snaps is disabled` | MetaMask local Snap development is disabled. | Enable local Snap fetching in MetaMask/Flask developer settings, then retry install/update. |
|
|
179
|
-
| MetaMask asks to reinstall before signing | The served local Snap shasum changed. | Run `npm run build && npm run manifest`, restart `npm run serve`, then use the frontend `Update Snap` button. |
|
|
180
|
-
| `This site is not authorized to use the Ducat Snap` | The frontend origin is not in `snap.manifest.json`. | Use one of the allowed local origins or add the origin intentionally and regenerate the manifest. |
|
|
181
|
-
| `This transaction is trying to spend an input from a different Ducat Snap account` | The PSBT input does not match the derived Snap account requested in `signInputs`. | Refresh the frontend wallet account state and rebuild the Ducat transaction. Use diagnostic details to compare expected and actual input addresses. |
|
|
182
|
-
| Balance or vault status is unavailable on Snap Home | Public indexer or Ducat validator lookup timed out or failed. | Retry later. Signing still uses PSBT data supplied by the Ducat app. |
|
|
112
|
+
Errors returned to the frontend include a stable `code`, user-facing `message`, and diagnostic `details` for expanded debugging.
|
|
183
113
|
|
|
184
114
|
## Security Model
|
|
185
115
|
|
|
186
|
-
- Private keys never leave the Snap.
|
|
187
|
-
- The Snap
|
|
188
|
-
- Mainnet requests
|
|
116
|
+
- Private keys, child private keys, WIFs, and raw entropy never leave the Snap.
|
|
117
|
+
- The Snap requests Bitcoin mainnet and testnet BIP32 entropy paths: `m/84'/0'`, `m/86'/0'`, `m/84'/1'`, and `m/86'/1'`.
|
|
118
|
+
- Mainnet requests use Bitcoin mainnet addresses, transaction parsing, and broadcast endpoints; signet and mutinynet requests use Bitcoin testnet parameters.
|
|
119
|
+
- Unauthorized origins cannot invoke the Snap RPC API.
|
|
189
120
|
- Only explicit `signInputs` indexes are signed.
|
|
190
121
|
- Signing is restricted to derived Ducat Snap accounts.
|
|
191
|
-
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
|
|
195
|
-
### Taproot Script-Path Policy
|
|
122
|
+
- Message, PSBT, batch, and transfer signing require MetaMask confirmation.
|
|
123
|
+
- Frontend context is treated as untrusted display metadata. Parsed PSBT data is the signing source of truth.
|
|
124
|
+
- Snap state stores recent Ducat action metadata only.
|
|
196
125
|
|
|
197
|
-
|
|
126
|
+
Taproot script-path inputs must include a Ducat cosign tapleaf and control-block data that recomputes to the prevout P2TR output key. The tapleaf must place the derived Ducat vault key in the client slot, and the client and guard pubkeys must be distinct. The Snap rejects uncommitted script-path inputs, client/guard key collapse, and generic leaves even when a leaf contains the derived vault key.
|
|
198
127
|
|
|
199
|
-
|
|
128
|
+
## Audit And Submission Packet
|
|
200
129
|
|
|
201
|
-
|
|
130
|
+
Primary audit documents:
|
|
202
131
|
|
|
203
|
-
|
|
132
|
+
- `AUDITOR_HANDOFF.md`
|
|
133
|
+
- `AUDIT_SCOPE.md`
|
|
134
|
+
- `RELEASE_EVIDENCE.md`
|
|
135
|
+
- `INTERNAL_SECURITY_REVIEW.md`
|
|
136
|
+
- `DEPENDENCY_AUDIT.md`
|
|
137
|
+
- `SNAPPER_REVIEW.md`
|
|
204
138
|
|
|
205
|
-
|
|
139
|
+
Submission documents:
|
|
206
140
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
141
|
+
- `submission/README.md`
|
|
142
|
+
- `submission/ALLOWLIST_SUBMISSION.md`
|
|
143
|
+
- `submission/EXTERNAL_GATES.md`
|
|
144
|
+
- `submission/metamask-directory.json`
|
|
145
|
+
- `submission/fixtures/README.md`
|
|
146
|
+
- `submission/e2e/README.md`
|
|
147
|
+
- `submission/screenshots/README.md`
|
|
212
148
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
1. Confirm `npm run verify:release` passes from a clean checkout.
|
|
216
|
-
2. Update `RELEASE_EVIDENCE.md` for the audited candidate.
|
|
217
|
-
3. Tag the audit candidate.
|
|
218
|
-
4. Complete the third-party audit required for `snap_getBip32Entropy`.
|
|
219
|
-
5. Merge any audit fixes and tag the fixed candidate.
|
|
220
|
-
6. Publish `@ducat-unit/wallet-snap@0.1.2` to npm.
|
|
221
|
-
7. Replace pending external fields in `submission/metamask-directory.json` and `submission/ALLOWLIST_SUBMISSION.md`.
|
|
222
|
-
8. Capture real PSBT fixtures into `submission/fixtures/`.
|
|
223
|
-
9. Capture final E2E evidence into `submission/e2e/evidence.json`.
|
|
224
|
-
10. Capture final screenshots into `submission/screenshots/`.
|
|
225
|
-
11. Record the demo video using `DEMO_SCRIPT.md`.
|
|
226
|
-
12. Run `npm run verify:submission-ready`.
|
|
227
|
-
13. Submit the MetaMask allowlist/directory request with audit report, npm URL, public repo URL, demo video, support details, and listing assets.
|
|
149
|
+
The source, package, metadata, and local verification evidence are ready for external audit handoff. MetaMask directory submission still requires the third-party audit report, final screenshots, demo video, real transaction fixtures, final E2E evidence, and project-owned support/escalation details listed in `submission/EXTERNAL_GATES.md`.
|
|
228
150
|
|
|
229
151
|
## Useful Commands
|
|
230
152
|
|
|
231
153
|
```bash
|
|
232
154
|
npm run type-check
|
|
233
|
-
npm test
|
|
155
|
+
npm test -- --runInBand
|
|
234
156
|
npm run build
|
|
235
157
|
npm run manifest
|
|
236
|
-
npm run
|
|
237
|
-
npm run verify
|
|
158
|
+
npm run verify:harness
|
|
238
159
|
npm run verify:release
|
|
239
160
|
npm run verify:metadata
|
|
161
|
+
npm run verify:release-manifest
|
|
240
162
|
npm run verify:submission-ready
|
|
241
163
|
npm run audit:prod
|
|
242
164
|
npm run pack:dry-run
|
package/RELEASE_CHECKLIST.md
CHANGED
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
# Ducat Snap Release Checklist
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Completed For `0.1.5`
|
|
4
4
|
|
|
5
|
-
- [x] Public repository contains the
|
|
6
|
-
- [x]
|
|
5
|
+
- [x] Public repository contains the audit-candidate source tag.
|
|
6
|
+
- [x] Audit candidate tag exists after the final handoff commit: `audit-candidate-0.1.5-20260615-audit-confirmation-hardening`.
|
|
7
|
+
- [ ] `.github/workflows/verify.yml` succeeds on the current audit candidate.
|
|
7
8
|
- [x] `npm run verify:release` succeeds locally.
|
|
8
|
-
- [ ] `submission/metamask-directory.json` pending external fields are replaced.
|
|
9
|
-
- [ ] `npm run verify:submission-ready` succeeds after external evidence is complete.
|
|
10
9
|
- [x] `npm run pack:dry-run` output reviewed.
|
|
11
10
|
- [x] `npm run audit:prod` output reviewed.
|
|
12
11
|
- [x] Dependency audit reviewed.
|
|
13
12
|
- [x] Snapper/security scan reviewed.
|
|
14
13
|
- [x] Console logs, unused permissions, accidental placeholders, and dead RPC methods removed or documented as external gates.
|
|
15
|
-
- [x]
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
14
|
+
- [x] Legacy Taproot script-path compatibility behavior removed and replaced with committed tapleaf verification.
|
|
15
|
+
- [x] Deterministic MetaMask simulation harness covers account derivation and owned P2WPKH PSBT signing.
|
|
16
|
+
- [x] Mainnet derivation, network parsing, endpoint selection, and release metadata added to the audit candidate.
|
|
17
|
+
- [x] `@ducat-unit/wallet-snap@0.1.5` release metadata prepared for audit handoff.
|
|
18
|
+
- [ ] Frontend PR #675 default Snap version range updated to `^0.1.5`.
|
|
19
|
+
|
|
20
|
+
## Required Before MetaMask Submission
|
|
21
|
+
|
|
18
22
|
- [ ] Third-party audit completed because the Snap uses `snap_getBip32Entropy`.
|
|
19
|
-
- [ ] Audit fixes merged and tagged.
|
|
23
|
+
- [ ] Audit fixes merged and tagged, if the audit requires fixes.
|
|
24
|
+
- [ ] `submission/metamask-directory.json` pending external fields are replaced.
|
|
25
|
+
- [ ] `submission/ALLOWLIST_SUBMISSION.md` pending external fields are replaced.
|
|
26
|
+
- [ ] Real create/deposit/borrow/repay/withdraw/swap/liquidation/repossess PSBT fixtures captured in `submission/fixtures/`.
|
|
27
|
+
- [ ] Final mainnet/signet/mutinynet E2E evidence captured in `submission/e2e/evidence.json`.
|
|
28
|
+
- [ ] Final screenshots captured in `submission/screenshots/`.
|
|
29
|
+
- [ ] Demo video recorded with `DEMO_SCRIPT.md`.
|
|
30
|
+
- [ ] Production support, escalation, and response-time details finalized.
|
|
31
|
+
- [ ] `npm run verify:submission-ready` succeeds after external evidence is complete.
|
|
20
32
|
|
|
21
33
|
## Listing Assets
|
|
22
34
|
|
|
23
|
-
- [x] Icon.
|
|
24
|
-
- [ ] `submission/screenshots/` contains final screenshots.
|
|
25
|
-
- [ ] Screenshots captured from the audited build using `LISTING.md`.
|
|
35
|
+
- [x] Icon: `images/icon.svg`.
|
|
26
36
|
- [x] Short description from `LISTING.md`.
|
|
27
37
|
- [x] Long description from `LISTING.md`.
|
|
28
|
-
- [x] Privacy policy.
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- [ ] Publish `@ducat-unit/wallet-snap` to npm.
|
|
35
|
-
- [ ] Submit MetaMask allowlist/directory request with:
|
|
36
|
-
- [ ] audited commit
|
|
37
|
-
- [ ] fixed commit
|
|
38
|
-
- [ ] audit report
|
|
39
|
-
- [ ] npm URL
|
|
40
|
-
- [ ] public repo URL
|
|
41
|
-
- [ ] demo video
|
|
42
|
-
- [ ] support details
|
|
43
|
-
- [ ] listing assets
|
|
38
|
+
- [x] Privacy policy source: `PRIVACY.md`.
|
|
39
|
+
- [x] Security disclosure source: `SECURITY.md`.
|
|
40
|
+
- [x] Support source: `SUPPORT.md`.
|
|
41
|
+
- [ ] Final PNG screenshots captured from the audited build.
|
|
42
|
+
- [ ] Demo video recorded from the audited build.
|
|
43
|
+
- [ ] Support and escalation contact copied into the submission form.
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## Submission
|
|
46
46
|
|
|
47
|
+
- [ ] Submit MetaMask allowlist/directory request with the audited commit, fixed commit if any, audit report, npm URL, public repository URL, demo video, support details, and listing assets.
|
|
47
48
|
- [ ] MetaMask allowlist approval received.
|
|
49
|
+
|
|
50
|
+
## Production Cutover
|
|
51
|
+
|
|
48
52
|
- [ ] Frontend production config uses `NEXT_PUBLIC_DUCAT_SNAP_ID=npm:@ducat-unit/wallet-snap`.
|
|
49
53
|
- [ ] Frontend production config uses the approved release range in `NEXT_PUBLIC_DUCAT_SNAP_VERSION`.
|
|
50
54
|
- [ ] Existing Xverse and UniSat regression flows pass.
|
|
51
|
-
- [ ]
|
|
55
|
+
- [ ] Mainnet/signet/mutinynet install, connect, create, deposit, borrow, repay, withdraw, swap, liquidation, and repossess E2E scenarios pass.
|
package/SECURITY.md
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Report security issues privately to the Ducat maintainers before public disclosure.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Release requirements:
|
|
6
6
|
|
|
7
7
|
- Third-party audit for key-management usage of `snap_getBip32Entropy`.
|
|
8
|
-
- MetaMask allowlist/directory review.
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
V1 signs only explicit PSBT input indexes that match the Snap-derived signet/mutinynet addresses.
|
|
8
|
+
- MetaMask allowlist/directory review before production distribution.
|
|
9
|
+
- Production dependency audit and Snapper/security scan for every release candidate.
|
|
10
|
+
- Mainnet key derivation, signing, and broadcast support must be covered by the third-party audit before production distribution.
|
|
13
11
|
|
|
12
|
+
`@ducat-unit/wallet-snap@0.1.5` supports mainnet, signet, and mutinynet. It signs only explicit PSBT input indexes that match Snap-derived addresses and requires MetaMask confirmation before message, PSBT, batch, or transfer signing.
|
package/SNAPPER_REVIEW.md
CHANGED
|
@@ -6,7 +6,9 @@ Last local command:
|
|
|
6
6
|
npx --yes @sayfer_io/snapper --path . --output snapper-report.json
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Local result:
|
|
9
|
+
Local result: 221 findings across the `ESLinting`, `ExcessiveComments`, and `HardcodedSecrets` categories.
|
|
10
|
+
|
|
11
|
+
The three `HardcodedSecrets` findings are the Ducat guardian x-only **public** key (`ef8e6d84…ca2e`) hardcoded per network in `src/networks.ts`. It is a public key that is intended to be embedded so the Snap can pin the vault cosigner identity; it is not a secret. The remaining findings are style/comment-density scanner policy, not signing, key-export, origin-authorization, confirmation-bypass, or network-scope findings.
|
|
10
12
|
|
|
11
13
|
## Addressed Findings
|
|
12
14
|
|
package/SUPPORT.md
CHANGED
|
@@ -6,4 +6,4 @@ https://github.com/DUCAT-UNIT/ducat-snap/issues
|
|
|
6
6
|
|
|
7
7
|
Security issues should not be filed as public issues. Follow `SECURITY.md` for private disclosure.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Before MetaMask directory submission, copy the final public support URL, private escalation contact, and response-time expectation into `submission/ALLOWLIST_SUBMISSION.md`.
|