@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.
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ interface TokenUsagePromptProps {
3
+ app: string;
4
+ message: string;
5
+ onAllow: () => void;
6
+ onDeny: () => void;
7
+ }
8
+ /**
9
+ * Modal dialog for prompting user to approve BTMS token spending.
10
+ * Displays comprehensive token information in an elegant, user-friendly format.
11
+ */
12
+ declare const TokenUsagePromptDialog: React.FC<TokenUsagePromptProps>;
13
+ /**
14
+ * Focus handlers for window management (optional)
15
+ */
16
+ export interface FocusHandlers {
17
+ isFocused: () => Promise<boolean>;
18
+ onFocusRequested: () => Promise<void>;
19
+ onFocusRelinquished: () => Promise<void>;
20
+ }
21
+ /**
22
+ * Hook for managing BTMS token usage prompts.
23
+ * Returns a function that can be called to prompt the user and a component to render.
24
+ *
25
+ * @param focusHandlers - Optional focus management handlers for desktop apps
26
+ */
27
+ export declare const useTokenUsagePrompt: (focusHandlers?: FocusHandlers) => {
28
+ promptUser: (app: string, message: string) => Promise<boolean>;
29
+ PromptComponent: () => import("react/jsx-runtime").JSX.Element | null;
30
+ };
31
+ export default TokenUsagePromptDialog;
32
+ //# sourceMappingURL=TokenUsagePrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenUsagePrompt.d.ts","sourceRoot":"","sources":["../src/TokenUsagePrompt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAA;AAmBrE,UAAU,qBAAqB;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB;AAkED;;;GAGG;AACH,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4O3D,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACjC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACzC;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,gBAAgB,aAAa;sBASpB,MAAM,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;;CAsDtF,CAAA;AAED,eAAe,sBAAsB,CAAA"}
@@ -0,0 +1,181 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback, useMemo, useRef } from 'react';
3
+ import { Dialog, DialogContent, DialogActions, Button, Typography, Box, Stack, Divider, Avatar, Chip } from '@mui/material';
4
+ import TokenIcon from '@mui/icons-material/Token';
5
+ import AppsIcon from '@mui/icons-material/Apps';
6
+ import SendIcon from '@mui/icons-material/Send';
7
+ import PersonIcon from '@mui/icons-material/Person';
8
+ import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
9
+ /**
10
+ * Parses the BTMS token message to extract structured information.
11
+ * Now supports JSON-encoded spend info from BasicTokenModule.
12
+ */
13
+ const parseTokenMessage = (message) => {
14
+ try {
15
+ const parsed = JSON.parse(message);
16
+ if (parsed.type === 'btms_spend') {
17
+ return parsed;
18
+ }
19
+ }
20
+ catch {
21
+ // Not JSON, fall back to legacy parsing
22
+ }
23
+ // Legacy format: "Spend {amount} {tokenName} token(s)\n\nAsset ID: {assetId}\nApp: {app}"
24
+ const lines = message.split('\n');
25
+ const firstLine = lines[0] || '';
26
+ const spendMatch = firstLine.match(/Spend (\d+) (.+?) token/);
27
+ const amount = spendMatch?.[1] ? parseInt(spendMatch[1], 10) : 0;
28
+ const tokenName = spendMatch?.[2] || 'Unknown Token';
29
+ const assetIdMatch = message.match(/Asset ID: (.+?)(?:\n|$)/);
30
+ const assetId = assetIdMatch?.[1] || '';
31
+ return {
32
+ type: 'btms_spend',
33
+ sendAmount: amount,
34
+ tokenName,
35
+ assetId,
36
+ changeAmount: 0,
37
+ totalInputAmount: amount
38
+ };
39
+ };
40
+ /**
41
+ * Formats a number with locale-aware separators
42
+ */
43
+ const formatAmount = (amount) => {
44
+ return amount.toLocaleString();
45
+ };
46
+ /**
47
+ * Truncates a hex string (like identity key or asset ID) for display
48
+ */
49
+ const truncateHex = (hex, startChars = 8, endChars = 6) => {
50
+ if (hex.length <= startChars + endChars + 3)
51
+ return hex;
52
+ return `${hex.slice(0, startChars)}...${hex.slice(-endChars)}`;
53
+ };
54
+ /**
55
+ * Modal dialog for prompting user to approve BTMS token spending.
56
+ * Displays comprehensive token information in an elegant, user-friendly format.
57
+ */
58
+ const TokenUsagePromptDialog = ({ app, message, onAllow, onDeny }) => {
59
+ const spendInfo = useMemo(() => parseTokenMessage(message), [message]);
60
+ if (!spendInfo) {
61
+ return null;
62
+ }
63
+ const hasRecipient = spendInfo.recipient && spendInfo.recipient.length > 0;
64
+ const hasChange = spendInfo.changeAmount > 0;
65
+ const hasAssetId = spendInfo.assetId && spendInfo.assetId.length > 0;
66
+ return (_jsxs(Dialog, { open: true, onClose: onDeny, maxWidth: "sm", fullWidth: true, PaperProps: {
67
+ sx: {
68
+ borderRadius: 3,
69
+ overflow: 'hidden'
70
+ }
71
+ }, children: [_jsx(Box, { sx: {
72
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
73
+ p: 3,
74
+ color: 'white'
75
+ }, children: _jsxs(Box, { display: "flex", alignItems: "center", gap: 1.5, children: [_jsx(Avatar, { sx: { bgcolor: 'rgba(255,255,255,0.2)', width: 48, height: 48 }, children: _jsx(TokenIcon, { sx: { fontSize: 28 } }) }), _jsxs(Box, { children: [_jsx(Typography, { variant: "h6", fontWeight: "bold", children: "Token Transfer Request" }), _jsx(Typography, { variant: "body2", sx: { opacity: 0.9 }, children: "Review and approve this transaction" })] })] }) }), _jsx(DialogContent, { sx: { p: 3 }, children: _jsxs(Stack, { spacing: 3, children: [_jsxs(Box, { sx: {
76
+ display: 'flex',
77
+ alignItems: 'center',
78
+ gap: 1.5,
79
+ p: 2,
80
+ backgroundColor: 'grey.50',
81
+ borderRadius: 2
82
+ }, children: [_jsx(AppsIcon, { color: "action" }), _jsxs(Box, { children: [_jsx(Typography, { variant: "caption", color: "text.secondary", display: "block", children: "Requesting App" }), _jsx(Typography, { variant: "body1", fontWeight: "medium", children: app })] })] }), _jsxs(Box, { sx: {
83
+ textAlign: 'center',
84
+ p: 4,
85
+ background: 'linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%)',
86
+ borderRadius: 3,
87
+ border: '2px solid',
88
+ borderColor: 'primary.light'
89
+ }, children: [spendInfo.iconURL && (_jsx(Avatar, { src: spendInfo.iconURL, sx: { width: 64, height: 64, mx: 'auto', mb: 2 }, children: _jsx(TokenIcon, { sx: { fontSize: 32 } }) })), _jsx(Typography, { variant: "h3", fontWeight: "bold", color: "primary.main", gutterBottom: true, children: formatAmount(spendInfo.sendAmount) }), _jsx(Typography, { variant: "h5", color: "text.primary", fontWeight: "medium", children: spendInfo.tokenName }), hasAssetId && (_jsx(Chip, { label: truncateHex(spendInfo.assetId, 12, 8), size: "small", variant: "outlined", sx: { mt: 1.5, fontFamily: 'monospace', fontSize: '0.75rem' } }))] }), _jsxs(Box, { sx: {
90
+ backgroundColor: 'grey.50',
91
+ borderRadius: 2,
92
+ overflow: 'hidden'
93
+ }, children: [hasRecipient && (_jsxs(Box, { sx: {
94
+ display: 'flex',
95
+ alignItems: 'center',
96
+ gap: 2,
97
+ p: 2,
98
+ borderBottom: '1px solid',
99
+ borderColor: 'divider'
100
+ }, children: [_jsx(Avatar, { sx: { bgcolor: 'success.light', width: 36, height: 36 }, children: _jsx(PersonIcon, { sx: { fontSize: 20, color: 'success.dark' } }) }), _jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [_jsx(Typography, { variant: "caption", color: "text.secondary", display: "block", children: "Recipient" }), _jsxs(Typography, { variant: "body2", fontFamily: "monospace", sx: {
101
+ overflow: 'hidden',
102
+ textOverflow: 'ellipsis',
103
+ whiteSpace: 'nowrap'
104
+ }, children: [spendInfo.recipient, "..."] })] }), _jsx(SendIcon, { color: "action", sx: { fontSize: 20 } })] })), hasChange && (_jsxs(Box, { sx: {
105
+ display: 'flex',
106
+ alignItems: 'center',
107
+ gap: 2,
108
+ p: 2
109
+ }, children: [_jsx(Avatar, { sx: { bgcolor: 'info.light', width: 36, height: 36 }, children: _jsx(SwapHorizIcon, { sx: { fontSize: 20, color: 'info.dark' } }) }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Typography, { variant: "caption", color: "text.secondary", display: "block", children: "Change (returned to you)" }), _jsxs(Typography, { variant: "body2", fontWeight: "medium", children: [formatAmount(spendInfo.changeAmount), " ", spendInfo.tokenName] })] })] })), spendInfo.totalInputAmount > spendInfo.sendAmount && (_jsx(Box, { sx: {
110
+ p: 2,
111
+ backgroundColor: 'grey.100',
112
+ borderTop: '1px solid',
113
+ borderColor: 'divider'
114
+ }, children: _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [_jsx(Typography, { variant: "body2", color: "text.secondary", children: "Total from wallet" }), _jsxs(Typography, { variant: "body2", fontWeight: "medium", children: [formatAmount(spendInfo.totalInputAmount), " tokens"] })] }) }))] }), _jsx(Box, { sx: {
115
+ p: 2,
116
+ backgroundColor: 'warning.lighter',
117
+ borderRadius: 2,
118
+ border: '1px solid',
119
+ borderColor: 'warning.light'
120
+ }, children: _jsxs(Typography, { variant: "body2", color: "warning.dark", children: [_jsx("strong", { children: "Review carefully:" }), " This action will transfer tokens from your wallet. Only approve if you trust this application."] }) })] }) }), _jsx(Divider, {}), _jsxs(DialogActions, { sx: { p: 2.5, gap: 1.5 }, children: [_jsx(Button, { onClick: onDeny, color: "inherit", variant: "outlined", size: "large", fullWidth: true, sx: { borderRadius: 2, py: 1.5 }, children: "Deny" }), _jsx(Button, { onClick: onAllow, color: "primary", variant: "contained", size: "large", autoFocus: true, fullWidth: true, sx: {
121
+ borderRadius: 2,
122
+ py: 1.5,
123
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
124
+ '&:hover': {
125
+ background: 'linear-gradient(135deg, #5a6fd6 0%, #6a4190 100%)'
126
+ }
127
+ }, children: "Approve Transfer" })] })] }));
128
+ };
129
+ /**
130
+ * Hook for managing BTMS token usage prompts.
131
+ * Returns a function that can be called to prompt the user and a component to render.
132
+ *
133
+ * @param focusHandlers - Optional focus management handlers for desktop apps
134
+ */
135
+ export const useTokenUsagePrompt = (focusHandlers) => {
136
+ const wasOriginallyFocusedRef = useRef(false);
137
+ const [promptState, setPromptState] = useState(null);
138
+ const promptUser = useCallback(async (app, message) => {
139
+ // Request focus before showing the prompt (if handlers provided)
140
+ if (focusHandlers) {
141
+ const currentlyFocused = await focusHandlers.isFocused();
142
+ wasOriginallyFocusedRef.current = currentlyFocused;
143
+ if (!currentlyFocused) {
144
+ await focusHandlers.onFocusRequested();
145
+ }
146
+ }
147
+ return new Promise((resolve) => {
148
+ setPromptState({ app, message, resolver: resolve });
149
+ });
150
+ }, [focusHandlers]);
151
+ const handleAllow = useCallback(() => {
152
+ if (promptState) {
153
+ promptState.resolver(true);
154
+ setPromptState(null);
155
+ // Relinquish focus if we weren't originally focused
156
+ if (focusHandlers && !wasOriginallyFocusedRef.current) {
157
+ focusHandlers.onFocusRelinquished();
158
+ }
159
+ }
160
+ }, [promptState, focusHandlers]);
161
+ const handleDeny = useCallback(() => {
162
+ if (promptState) {
163
+ promptState.resolver(false);
164
+ setPromptState(null);
165
+ // Relinquish focus if we weren't originally focused
166
+ if (focusHandlers && !wasOriginallyFocusedRef.current) {
167
+ focusHandlers.onFocusRelinquished();
168
+ }
169
+ }
170
+ }, [promptState, focusHandlers]);
171
+ const PromptComponent = useCallback(() => {
172
+ if (!promptState)
173
+ return null;
174
+ return (_jsx(TokenUsagePromptDialog, { app: promptState.app, message: promptState.message, onAllow: handleAllow, onDeny: handleDeny }));
175
+ }, [promptState, handleAllow, handleDeny]);
176
+ return {
177
+ promptUser,
178
+ PromptComponent
179
+ };
180
+ };
181
+ export default TokenUsagePromptDialog;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * BTMS Permission Module (Core)
3
+ *
4
+ * Provides wallet permission module for BTMS token spending authorization.
5
+ * This is the core module without UI dependencies - framework agnostic.
6
+ *
7
+ * For React/MUI UI components, see @bsv/btms-permission-module-ui
8
+ */
9
+ import type { WalletInterface } from '@bsv/sdk';
10
+ import { BasicTokenModule } from './BasicTokenModule.js';
11
+ export type PermissionPromptHandler = (app: string, message: string) => Promise<boolean>;
12
+ export type PermissionModuleFactoryArgs = {
13
+ wallet: WalletInterface;
14
+ promptHandler?: PermissionPromptHandler;
15
+ };
16
+ export declare const createBtmsModule: ({ wallet, promptHandler }: PermissionModuleFactoryArgs) => BasicTokenModule;
17
+ export { BasicTokenModule };
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,MAAM,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAExF,MAAM,MAAM,2BAA2B,GAAG;IACxC,MAAM,EAAE,eAAe,CAAA;IACvB,aAAa,CAAC,EAAE,uBAAuB,CAAA;CACxC,CAAA;AAID,eAAO,MAAM,gBAAgB,GAAI,2BAA2B,2BAA2B,qBAGtF,CAAA;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * BTMS Permission Module (Core)
3
+ *
4
+ * Provides wallet permission module for BTMS token spending authorization.
5
+ * This is the core module without UI dependencies - framework agnostic.
6
+ *
7
+ * For React/MUI UI components, see @bsv/btms-permission-module-ui
8
+ */
9
+ import { BTMS } from '@bsv/btms';
10
+ import { BasicTokenModule } from './BasicTokenModule.js';
11
+ const denyPrompt = async () => false;
12
+ export const createBtmsModule = ({ wallet, promptHandler }) => {
13
+ const btms = new BTMS({ wallet, networkPreset: 'local' });
14
+ return new BasicTokenModule(promptHandler ?? denyPrompt, btms);
15
+ };
16
+ export { BasicTokenModule };
@@ -0,0 +1,67 @@
1
+ /** Permissioned basket prefix - aligns with btms-core */
2
+ export declare const P_BASKET_PREFIX = "p btms";
3
+ /** Literal used in field[0] to indicate token issuance - aligns with btms-core */
4
+ export declare const ISSUE_MARKER = "ISSUE";
5
+ /** Index positions for BTMS PushDrop token fields */
6
+ export declare const BTMS_FIELD: {
7
+ readonly ASSET_ID: 0;
8
+ readonly AMOUNT: 1;
9
+ readonly METADATA: 2;
10
+ };
11
+ /**
12
+ * Parsed information about a BTMS token from its locking script
13
+ */
14
+ export interface ParsedTokenInfo {
15
+ assetId: string;
16
+ amount: number;
17
+ metadata?: {
18
+ name?: string;
19
+ description?: string;
20
+ iconURL?: string;
21
+ [key: string]: unknown;
22
+ };
23
+ }
24
+ /**
25
+ * Comprehensive token spend information extracted from createAction args
26
+ */
27
+ export interface TokenSpendInfo {
28
+ /** Total amount being sent to recipient (not including change) */
29
+ sendAmount: number;
30
+ /** Total amount being spent from inputs */
31
+ totalInputAmount: number;
32
+ /** Change amount (totalInputAmount - sendAmount) */
33
+ changeAmount: number;
34
+ /** Total amount sent in token outputs (derived from outputs) */
35
+ outputSendAmount: number;
36
+ /** Total amount returned as change in token outputs (derived from outputs) */
37
+ outputChangeAmount: number;
38
+ /** Whether any token outputs were parsed */
39
+ hasTokenOutputs: boolean;
40
+ /** Source of totalInputAmount */
41
+ inputAmountSource: 'beef' | 'descriptions' | 'derived' | 'none';
42
+ /** Token name from metadata */
43
+ tokenName: string;
44
+ /** Asset ID */
45
+ assetId: string;
46
+ /** Recipient identity key (truncated) */
47
+ recipient?: string;
48
+ /** Token icon URL if available */
49
+ iconURL?: string;
50
+ /** Full action description */
51
+ actionDescription: string;
52
+ }
53
+ /**
54
+ * Authorized transaction data captured from createAction response.
55
+ * Used to verify createSignature calls are signing what was actually authorized.
56
+ */
57
+ export interface AuthorizedTransaction {
58
+ /** The reference from the signable transaction */
59
+ reference: string;
60
+ /** Hash of all outputs (BIP-143 hashOutputs) */
61
+ hashOutputs: string;
62
+ /** Set of authorized outpoints (txid.vout format) */
63
+ authorizedOutpoints: Set<string>;
64
+ /** Timestamp when this authorization was created */
65
+ timestamp: number;
66
+ }
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAUA,yDAAyD;AACzD,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,kFAAkF;AAClF,eAAO,MAAM,YAAY,UAAU,CAAA;AAEnC,qDAAqD;AACrD,eAAO,MAAM,UAAU;;;;CAIb,CAAA;AAEV;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACvB,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAA;IAClB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAA;IACxB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,gBAAgB,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4CAA4C;IAC5C,eAAe,EAAE,OAAO,CAAA;IACxB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,MAAM,CAAA;IAC/D,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe;IACf,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8BAA8B;IAC9B,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAA;IACjB,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAA;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,19 @@
1
+ // ---------------------------------------------------------------------------
2
+ // BTMS Permission Module Constants and Types
3
+ // ---------------------------------------------------------------------------
4
+ // BRC-99: Baskets prefixed with "p " are permissioned and require wallet
5
+ // permission module support. The scheme ID is "btms".
6
+ //
7
+ // Token basket format: "p btms <assetId>"
8
+ // Example: "p btms abc123def456.0"
9
+ // ---------------------------------------------------------------------------
10
+ /** Permissioned basket prefix - aligns with btms-core */
11
+ export const P_BASKET_PREFIX = 'p btms';
12
+ /** Literal used in field[0] to indicate token issuance - aligns with btms-core */
13
+ export const ISSUE_MARKER = 'ISSUE';
14
+ /** Index positions for BTMS PushDrop token fields */
15
+ export const BTMS_FIELD = {
16
+ ASSET_ID: 0,
17
+ AMOUNT: 1,
18
+ METADATA: 2
19
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@bsv/btms-permission-module",
3
+ "version": "1.0.0",
4
+ "description": "BTMS Permission Module for wallet integration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc -b",
16
+ "clean": "rm -rf dist"
17
+ },
18
+ "keywords": [
19
+ "btms",
20
+ "tokens",
21
+ "permissions",
22
+ "wallet"
23
+ ],
24
+ "author": "BSV Blockchain Association",
25
+ "license": "Open BSV",
26
+ "peerDependencies": {
27
+ "@bsv/btms": ">=1.0.0",
28
+ "@bsv/sdk": ">=2.0.3",
29
+ "@bsv/wallet-toolbox-client": ">=2.0.16"
30
+ },
31
+ "devDependencies": {
32
+ "@bsv/btms": "^1.0.0",
33
+ "@bsv/sdk": "^2.0.3",
34
+ "@bsv/wallet-toolbox-client": "^2.0.16",
35
+ "typescript": "^5.2.2"
36
+ }
37
+ }