@bsv/btms-permission-module 1.0.0

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/INTEGRATION.md ADDED
@@ -0,0 +1,399 @@
1
+ # BTMS Permission Module Integration Guide
2
+
3
+ Complete guide for integrating the BTMS Permission Module into your wallet application.
4
+
5
+ ## Related Docs
6
+
7
+ - Project index: [`../README.md`](../README.md)
8
+ - Main BTMS API package (`@bsv/btms`): [`../core/README.md`](../core/README.md)
9
+ - Core permission module overview: [`./README.md`](./README.md)
10
+ - React/MUI prompt package: [`../permission-module-ui/README.md`](../permission-module-ui/README.md)
11
+ - Frontend app and live deployment (`https://btms.metanet.app`): [`../frontend/README.md`](../frontend/README.md)
12
+
13
+ ## Table of Contents
14
+
15
+ - [Overview](#overview)
16
+ - [Architecture](#architecture)
17
+ - [Installation](#installation)
18
+ - [Integration Steps](#integration-steps)
19
+ - [API Reference](#api-reference)
20
+ - [Examples](#examples)
21
+ - [Troubleshooting](#troubleshooting)
22
+
23
+ ## Overview
24
+
25
+ The BTMS Permission Module provides wallet permission management for BTMS token operations. It consists of two main components:
26
+
27
+ 1. **Core Factory (`createBtmsModule`)** - Creates the permission module instance (framework-agnostic)
28
+ 2. **TokenAccessPrompt** - React UI component for displaying token spending authorization requests
29
+
30
+ ## Architecture
31
+
32
+ ### Flow Diagram
33
+
34
+ ```
35
+ User Action (Token Spend)
36
+
37
+ BTMS Core (createAction/createSignature)
38
+
39
+ BasicTokenModule (intercepts via P-basket delegation)
40
+
41
+ requestTokenAccess (your callback)
42
+
43
+ TokenAccessPrompt UI (shows dialog)
44
+
45
+ User Approves/Denies
46
+
47
+ BasicTokenModule (allows/blocks operation)
48
+
49
+ Transaction Completes/Fails
50
+ ```
51
+
52
+ ### Component Responsibilities
53
+
54
+ **Core factory (`createBtmsModule`):**
55
+ - Intercepts `createAction` calls to extract token spend information
56
+ - Intercepts `createSignature` calls to verify authorized transactions
57
+ - Manages session-based authorization for transaction flows
58
+ - Validates transaction integrity using BIP-143 preimage verification
59
+
60
+ **TokenAccessPrompt:**
61
+ - Displays token information (amount, name, asset ID)
62
+ - Shows recipient and change details
63
+ - Handles window focus management (optional)
64
+ - Provides approve/deny actions
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ npm install @bsv/btms-permission-module
70
+ ```
71
+
72
+ ### Peer Dependencies
73
+
74
+ Ensure you have the following installed:
75
+
76
+ ```json
77
+ {
78
+ "@bsv/sdk": ">=2.0.0",
79
+ "@bsv/wallet-toolbox-client": ">=1.5.0",
80
+ "react": ">=18.0.0",
81
+ "@mui/material": ">=5.0.0",
82
+ "@mui/icons-material": ">=5.0.0"
83
+ }
84
+ ```
85
+
86
+ ## Integration Steps
87
+
88
+ ### Step 1: Setup the Token Usage Prompt Hook
89
+
90
+ First, create the prompt function with optional focus handlers for desktop applications.
91
+
92
+ ```typescript
93
+ import { useTokenSpendPrompt, type FocusHandlers } from '@bsv/btms-permission-module-ui'
94
+ import { UserContext } from './UserContext' // Your app's context
95
+
96
+ // In your wallet context provider component:
97
+ const { isFocused, onFocusRequested, onFocusRelinquished } = useContext(UserContext)
98
+
99
+ // Setup the hook with focus handlers (optional - omit for web-only apps)
100
+ const { promptUser: requestTokenAccess, PromptComponent } = useTokenSpendPrompt({
101
+ isFocused,
102
+ onFocusRequested,
103
+ onFocusRelinquished
104
+ })
105
+
106
+ const requestTokenAccessWithTheme = useCallback((app: string, message: string) => {
107
+ return requestTokenAccess(app, message, tokenPromptPaletteMode)
108
+ }, [requestTokenAccess, tokenPromptPaletteMode])
109
+ ```
110
+
111
+ **For web-only applications** (no window focus management):
112
+
113
+ ```typescript
114
+ const { promptUser: requestTokenAccess, PromptComponent } = useTokenSpendPrompt()
115
+ ```
116
+
117
+ ### Step 2: Create the Module Instance
118
+
119
+ Create an instance of `BasicTokenModule` and pass your prompt function.
120
+
121
+ ```typescript
122
+ import { createBtmsModule } from '@bsv/btms-permission-module'
123
+
124
+ const basicTokenModule = createBtmsModule({
125
+ wallet,
126
+ promptHandler: requestTokenAccessWithTheme
127
+ })
128
+ ```
129
+
130
+ ### Step 3: Register with WalletPermissionsManager
131
+
132
+ Add the module to your wallet's permission configuration.
133
+
134
+ ```typescript
135
+ import { WalletPermissionsManager } from '@bsv/wallet-toolbox-client'
136
+
137
+ // Add permission modules to config
138
+ const configWithModules = {
139
+ ...permissionConfig,
140
+ permissionModules: {
141
+ btms: basicTokenModule
142
+ }
143
+ }
144
+
145
+ // Create permissions manager with the config
146
+ const permissionsManager = new WalletPermissionsManager(
147
+ wallet,
148
+ adminOriginator,
149
+ configWithModules
150
+ )
151
+ ```
152
+
153
+ ### Step 4: Render the Prompt Component
154
+
155
+ Include the prompt component in your app's render tree.
156
+
157
+ ```tsx
158
+ return (
159
+ <WalletContext.Provider value={contextValue}>
160
+ {children}
161
+
162
+ {/* Render token usage prompt */}
163
+ <PromptComponent />
164
+
165
+ {/* Other permission prompts */}
166
+ </WalletContext.Provider>
167
+ )
168
+ ```
169
+
170
+ ## API Reference
171
+
172
+ ### `useTokenSpendPrompt(focusHandlers?: FocusHandlers)`
173
+
174
+ React hook for managing token spend prompts.
175
+
176
+ **Parameters:**
177
+ - `focusHandlers` (optional): Object containing window focus management functions
178
+ - `isFocused: () => Promise<boolean>` - Check if window is focused
179
+ - `onFocusRequested: () => Promise<void>` - Request window focus
180
+ - `onFocusRelinquished: () => Promise<void>` - Release window focus
181
+
182
+ **Returns:**
183
+ - `promptUser: (app: string, message: string) => Promise<boolean>` - Function to show prompt
184
+ - `PromptComponent: React.ComponentType` - Component to render in your app
185
+
186
+ ### `BasicTokenModule`
187
+
188
+ Permission module for BTMS token operations.
189
+
190
+ **Constructor:**
191
+ ```typescript
192
+ new BasicTokenModule(
193
+ requestTokenAccess: (app: string, message: string) => Promise<boolean>,
194
+ btms: BTMS
195
+ )
196
+ ```
197
+
198
+ **Parameters:**
199
+ - `requestTokenAccess`: Async function that displays a prompt and returns user's decision
200
+
201
+ **Message Format:**
202
+
203
+ The `message` parameter is a JSON string with the following structure:
204
+
205
+ ```typescript
206
+ {
207
+ type: 'btms_spend',
208
+ sendAmount: number, // Amount being sent to recipient
209
+ tokenName: string, // Token name from metadata
210
+ assetId: string, // Asset ID (txid.outputIndex)
211
+ recipient?: string, // Recipient public key (if available)
212
+ iconURL?: string, // Token icon URL (if available)
213
+ changeAmount: number, // Change amount returned to sender
214
+ totalInputAmount: number // Total amount from inputs
215
+ }
216
+ ```
217
+
218
+ ### `FocusHandlers`
219
+
220
+ Interface for window focus management (desktop apps).
221
+
222
+ ```typescript
223
+ interface FocusHandlers {
224
+ isFocused: () => Promise<boolean>
225
+ onFocusRequested: () => Promise<void>
226
+ onFocusRelinquished: () => Promise<void>
227
+ }
228
+ ```
229
+
230
+ ## Examples
231
+
232
+ ### Complete Integration Example
233
+
234
+ ```typescript
235
+ import React, { useContext, useState } from 'react'
236
+ import { WalletPermissionsManager } from '@bsv/wallet-toolbox-client'
237
+ import { BasicTokenModule, useTokenSpendPrompt } from '@bsv/btms-permission-module'
238
+
239
+ export const WalletContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
240
+ const [wallet, setWallet] = useState(null)
241
+
242
+ // Get focus handlers from your app context (desktop apps only)
243
+ const { isFocused, onFocusRequested, onFocusRelinquished } = useContext(UserContext)
244
+
245
+ // Step 1: Setup token spend prompt with focus handlers
246
+ const { promptUser: requestTokenAccess, PromptComponent } = useTokenSpendPrompt({
247
+ isFocused,
248
+ onFocusRequested,
249
+ onFocusRelinquished
250
+ })
251
+
252
+ // Initialize wallet and permissions
253
+ const initializeWallet = async () => {
254
+ // ... wallet initialization code ...
255
+
256
+ // Step 2: Initialize BTMS + BasicTokenModule
257
+ const btms = new BTMS({ wallet, networkPreset: 'local' })
258
+ const basicTokenModule = new BasicTokenModule(
259
+ requestTokenAccess,
260
+ btms
261
+ )
262
+
263
+ // Step 3: Configure permissions with the module
264
+ const configWithModules = {
265
+ ...permissionConfig,
266
+ permissionModules: {
267
+ btms: basicTokenModule
268
+ }
269
+ }
270
+
271
+ // Create permissions manager
272
+ const permissionsManager = new WalletPermissionsManager(
273
+ wallet,
274
+ adminOriginator,
275
+ configWithModules
276
+ )
277
+
278
+ // Bind other permission callbacks...
279
+ permissionsManager.bindCallback('onSpendingAuthorizationRequested', spendingCallback)
280
+ // etc...
281
+
282
+ setWallet(wallet)
283
+ }
284
+
285
+ return (
286
+ <WalletContext.Provider value={{ wallet }}>
287
+ {children}
288
+
289
+ {/* Step 4: Render the prompt component */}
290
+ <PromptComponent />
291
+ </WalletContext.Provider>
292
+ )
293
+ }
294
+ ```
295
+
296
+ ### Web-Only Integration (No Focus Management)
297
+
298
+ ```typescript
299
+ // Simplified for web applications without window focus management
300
+ const { promptUser: requestTokenAccess, PromptComponent } = useTokenSpendPrompt()
301
+
302
+ const btms = new BTMS({ wallet, networkPreset: 'local' })
303
+ const basicTokenModule = new BasicTokenModule(requestTokenAccess, btms)
304
+
305
+ // Rest of integration is the same...
306
+ ```
307
+
308
+ ### Custom Prompt Implementation
309
+
310
+ If you want to use your own UI instead of the provided `TokenAccessPrompt`:
311
+
312
+ ```typescript
313
+ const customPromptFunction = async (app: string, message: string): Promise<boolean> => {
314
+ // Parse the message
315
+ const spendInfo = JSON.parse(message)
316
+
317
+ // Show your custom UI
318
+ const result = await showMyCustomDialog({
319
+ app,
320
+ tokenName: spendInfo.tokenName,
321
+ amount: spendInfo.sendAmount,
322
+ assetId: spendInfo.assetId
323
+ })
324
+
325
+ return result // true = approved, false = denied
326
+ }
327
+
328
+ const btms = new BTMS({ wallet, networkPreset: 'local' })
329
+ const basicTokenModule = new BasicTokenModule(customPromptFunction, btms)
330
+ ```
331
+
332
+ ## Troubleshooting
333
+
334
+ ### Issue: Prompt not appearing
335
+
336
+ **Possible causes:**
337
+ 1. `PromptComponent` not rendered in your app tree
338
+ 2. Focus handlers not working correctly (desktop apps)
339
+ 3. Module not registered with `WalletPermissionsManager`
340
+
341
+ **Solution:**
342
+ - Verify `<PromptComponent />` is included in your render tree
343
+ - Check browser console for errors
344
+ - Ensure `permissionModules` config includes your `basicTokenModule`
345
+
346
+ ### Issue: Two prompts appearing
347
+
348
+ **Cause:** Both generic wallet permission and BTMS-specific prompt showing.
349
+
350
+ **Solution:** This was a bug in earlier versions. Ensure you're using the latest version where session authorization prevents duplicate prompts.
351
+
352
+ ### Issue: Token information not displaying
353
+
354
+ **Possible causes:**
355
+ 1. Token metadata not properly encoded in locking script
356
+ 2. PushDrop field count mismatch
357
+
358
+ **Solution:**
359
+ - Verify tokens are created with proper metadata
360
+ - Check that `BTMSToken.createTransfer` is called with correct parameters
361
+ - Ensure `includeSignature` parameter matches your use case
362
+
363
+ ### Issue: Window focus not working (desktop apps)
364
+
365
+ **Cause:** Focus handlers not properly implemented or passed.
366
+
367
+ **Solution:**
368
+ - Verify your `UserContext` provides valid focus handler functions
369
+ - Check that Tauri commands (or equivalent) are properly configured
370
+ - Test focus handlers independently to ensure they work
371
+
372
+ ## Security Considerations
373
+
374
+ ### Transaction Verification
375
+
376
+ `BasicTokenModule` implements multiple security layers:
377
+
378
+ 1. **Session Authorization**: Temporary authorization for transaction flows
379
+ 2. **Preimage Verification**: Validates that signature requests match authorized transactions
380
+ 3. **Output Hash Validation**: Ensures transaction outputs haven't been modified
381
+
382
+ ### Best Practices
383
+
384
+ 1. **Always prompt users**: Never bypass the authorization flow
385
+ 2. **Validate token metadata**: Ensure token information is accurate before displaying
386
+ 3. **Handle errors gracefully**: Show user-friendly messages when operations fail
387
+ 4. **Secure focus management**: Prevent focus-stealing attacks in desktop apps
388
+
389
+ ## Additional Resources
390
+
391
+ - [BTMS Core Documentation](../core/README.md)
392
+ - [BRC-99: Permissioned Baskets](https://github.com/bitcoin-sv/BRCs)
393
+ - [Wallet Toolbox Client](https://github.com/bitcoin-sv/wallet-toolbox)
394
+
395
+ ## Support
396
+
397
+ For issues or questions:
398
+ - GitHub Issues: [btms repository](https://github.com/bitcoin-sv/btms)
399
+ - Documentation: [BTMS Core API Reference](../core/README.md#api-reference)
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # BTMS Permission Module
2
+
3
+ Wallet permission module for BTMS token spending authorization.
4
+
5
+ ## Overview
6
+
7
+ This is the **core permission module** for BTMS token operations - framework agnostic with no UI dependencies.
8
+
9
+ - **BasicTokenModule** - Permission module that intercepts token operations and prompts users
10
+ - **Framework Agnostic** - Works with any UI framework (React, Vue, Angular, vanilla JS)
11
+ - **Minimal Dependencies** - Only requires `@bsv/sdk` and `@bsv/wallet-toolbox-client`
12
+
13
+ For ready-to-use React/MUI UI components, see **@bsv/btms-permission-module-ui**
14
+
15
+ ## Target Audience
16
+
17
+ This module is for wallet developers integrating BTMS token support into **BRC-100 wallets** via **BRC-98/99 hooks**.
18
+
19
+ ## Related Docs
20
+
21
+ - Project index: [`../README.md`](../README.md)
22
+ - Main BTMS API package (`@bsv/btms`): [`../core/README.md`](../core/README.md)
23
+ - React/MUI prompt components: [`../permission-module-ui/README.md`](../permission-module-ui/README.md)
24
+ - Full wallet integration guide: [`./INTEGRATION.md`](./INTEGRATION.md)
25
+ - Frontend app and live deployment (`https://btms.metanet.app`): [`../frontend/README.md`](../frontend/README.md)
26
+
27
+ ## Features
28
+
29
+ - **Token Spend Authorization**: Prompts users before spending or burning BTMS tokens
30
+ - **Burn Authorization**: Prompts users before permanently destroying tokens
31
+ - **Session-based Authorization**: Caches authorization for transaction flows
32
+ - **Security Verification**: Validates signature requests match authorized transactions
33
+ - **Rich Token Display**: Shows amounts, names, metadata, and transaction details
34
+ - **Window Focus Management**: Brings app to foreground when prompting (desktop apps)
35
+ - **Customizable UI**: Use provided components or implement your own
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ npm install @bsv/btms-permission-module
41
+ ```
42
+
43
+ ### Peer Dependencies
44
+
45
+ ```bash
46
+ npm install @bsv/sdk @bsv/wallet-toolbox-client
47
+ ```
48
+
49
+ ## Quick Start
50
+
51
+ ### 1. Implement Your Prompt Function
52
+
53
+ ```typescript
54
+ import { BasicTokenModule } from '@bsv/btms-permission-module'
55
+
56
+ // Create a function that shows a prompt to the user
57
+ const requestTokenAccess = async (app: string, message: string): Promise<boolean> => {
58
+ // Parse the token spend information
59
+ const spendInfo = JSON.parse(message)
60
+
61
+ // Show your UI (React, Vue, Angular, vanilla JS, etc.)
62
+ const approved = await showMyCustomDialog({
63
+ app,
64
+ tokenName: spendInfo.tokenName,
65
+ amount: spendInfo.sendAmount,
66
+ assetId: spendInfo.assetId
67
+ })
68
+
69
+ return approved // true = user approved, false = user denied
70
+ }
71
+ ```
72
+
73
+ ### 2. Initialize the Module
74
+
75
+ ```typescript
76
+ const basicTokenModule = new BasicTokenModule(requestTokenAccess)
77
+ ```
78
+
79
+ ### 3. Register with Wallet
80
+
81
+ ```typescript
82
+ const permissionsManager = new WalletPermissionsManager(wallet, originator, {
83
+ ...config,
84
+ permissionModules: {
85
+ btms: basicTokenModule
86
+ }
87
+ })
88
+ ```
89
+
90
+ ## Using with React/MUI
91
+
92
+ For a complete React implementation with Material-UI, install the UI package:
93
+
94
+ ```bash
95
+ npm install @bsv/btms-permission-module-ui
96
+ ```
97
+
98
+ Then use the provided hook:
99
+
100
+ ```typescript
101
+ import { BasicTokenModule } from '@bsv/btms-permission-module'
102
+ import { useTokenSpendPrompt } from '@bsv/btms-permission-module-ui'
103
+
104
+ const { promptUser, PromptComponent } = useTokenSpendPrompt()
105
+ const basicTokenModule = new BasicTokenModule(promptUser)
106
+
107
+ // Render the component
108
+ return (
109
+ <>
110
+ {children}
111
+ <PromptComponent />
112
+ </>
113
+ )
114
+ ```
115
+
116
+ See the `@bsv/btms-permission-module-ui` package for full documentation.
117
+
118
+ ## Documentation
119
+
120
+ - **[Integration Guide](./INTEGRATION.md)** - Complete step-by-step integration instructions
121
+ - **[API Reference](./INTEGRATION.md#api-reference)** - Detailed API documentation
122
+ - **[Examples](./INTEGRATION.md#examples)** - Code examples and use cases
123
+ - **[Troubleshooting](./INTEGRATION.md#troubleshooting)** - Common issues and solutions
124
+
125
+ ## API Overview
126
+
127
+ ### `BasicTokenModule`
128
+
129
+ Permission module for BTMS token operations.
130
+
131
+ **Constructor:**
132
+ ```typescript
133
+ new BasicTokenModule(
134
+ requestTokenAccess: (app: string, message: string) => Promise<boolean>
135
+ )
136
+ ```
137
+
138
+ ### Message Format
139
+
140
+ The prompt message is a JSON string containing:
141
+
142
+ ```typescript
143
+ {
144
+ type: 'btms_spend' | 'btms_burn',
145
+ sendAmount: number, // Amount being sent (0 for burn)
146
+ burnAmount?: number, // Amount being burned (for burn operations)
147
+ tokenName: string, // Token name
148
+ assetId: string, // Asset ID (txid.vout)
149
+ recipient?: string, // Recipient public key (not present for burn)
150
+ iconURL?: string, // Token icon URL
151
+ changeAmount: number, // Change returned
152
+ totalInputAmount: number // Total from inputs
153
+ }
154
+ ```
155
+
156
+ ## Architecture
157
+
158
+ ```
159
+ User Action → BTMS Core → BasicTokenModule → promptUser → UI → User Decision → Allow/Deny
160
+ ```
161
+
162
+ See [INTEGRATION.md](./INTEGRATION.md#architecture) for detailed flow diagrams.
163
+
164
+ ## Security
165
+
166
+ The module implements multiple security layers:
167
+
168
+ - **Session Authorization**: Temporary auth for transaction flows
169
+ - **Preimage Verification**: Validates signature requests match authorized transactions
170
+ - **Output Hash Validation**: Ensures outputs haven't been modified
171
+
172
+ ## License
173
+
174
+ Open BSV