@bsv/wallet-toolbox 1.7.11 → 1.7.12

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/docs/client.md +213 -52
  3. package/docs/wallet.md +213 -52
  4. package/mobile/out/src/WalletPermissionsManager.d.ts +60 -0
  5. package/mobile/out/src/WalletPermissionsManager.d.ts.map +1 -1
  6. package/mobile/out/src/WalletPermissionsManager.js +200 -35
  7. package/mobile/out/src/WalletPermissionsManager.js.map +1 -1
  8. package/mobile/package-lock.json +2 -2
  9. package/mobile/package.json +1 -1
  10. package/out/src/WalletPermissionsManager.d.ts +60 -0
  11. package/out/src/WalletPermissionsManager.d.ts.map +1 -1
  12. package/out/src/WalletPermissionsManager.js +200 -35
  13. package/out/src/WalletPermissionsManager.js.map +1 -1
  14. package/out/src/__tests/WalletPermissionsManager.fixtures.d.ts.map +1 -1
  15. package/out/src/__tests/WalletPermissionsManager.fixtures.js.map +1 -1
  16. package/out/src/__tests/WalletPermissionsManager.pmodules.test.d.ts +2 -0
  17. package/out/src/__tests/WalletPermissionsManager.pmodules.test.d.ts.map +1 -0
  18. package/out/src/__tests/WalletPermissionsManager.pmodules.test.js +624 -0
  19. package/out/src/__tests/WalletPermissionsManager.pmodules.test.js.map +1 -0
  20. package/out/src/__tests/WalletPermissionsManager.proxying.test.js.map +1 -1
  21. package/out/src/storage/remoting/StorageServer.d.ts.map +1 -1
  22. package/out/src/storage/remoting/StorageServer.js.map +1 -1
  23. package/out/tsconfig.all.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/src/Wallet.ts +2 -2
  26. package/src/WalletLogger.ts +1 -1
  27. package/src/WalletPermissionsManager.ts +350 -42
  28. package/src/__tests/WalletPermissionsManager.fixtures.ts +1 -2
  29. package/src/__tests/WalletPermissionsManager.pmodules.test.ts +798 -0
  30. package/src/__tests/WalletPermissionsManager.proxying.test.ts +2 -2
  31. package/src/storage/remoting/StorageServer.ts +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.7.11",
3
+ "version": "1.7.12",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
package/src/Wallet.ts CHANGED
@@ -115,10 +115,10 @@ export interface WalletArgs {
115
115
  lookupResolver?: LookupResolver
116
116
  /**
117
117
  * Optional. Provide a function conforming to the `MakeWalletLogger` type to enable wallet request logging.
118
- *
118
+ *
119
119
  * For simple requests using `Console` may be adequate, initialize with
120
120
  * `() => Console`
121
- *
121
+ *
122
122
  * Aggregate tracing and control over capturing all logged output in one place:
123
123
  * `(log?: string | WalletLoggerInterface) => new WalletLogger(log)`
124
124
  */
@@ -210,4 +210,4 @@ export interface WalletLoggerArgs {
210
210
  * Optional array of accumulated logged data and errors.
211
211
  */
212
212
  logs?: WalletLoggerLog[]
213
- }
213
+ }
@@ -8,7 +8,19 @@ import {
8
8
  Base64String,
9
9
  PubKeyHex,
10
10
  Beef,
11
- Validation
11
+ Validation,
12
+ WalletEncryptArgs,
13
+ WalletDecryptArgs,
14
+ CreateHmacArgs,
15
+ VerifyHmacArgs,
16
+ CreateSignatureArgs,
17
+ VerifySignatureArgs,
18
+ InternalizeActionArgs,
19
+ ListOutputsArgs,
20
+ RelinquishOutputArgs,
21
+ GetPublicKeyArgs,
22
+ CreateActionArgs,
23
+ ListOutputsResult
12
24
  } from '@bsv/sdk'
13
25
 
14
26
  ////// TODO: ADD SUPPORT FOR ADMIN COUNTERPARTIES BASED ON WALLET STORAGE
@@ -42,6 +54,36 @@ function isObject(object: any): boolean {
42
54
  return object != null && typeof object === 'object'
43
55
  }
44
56
 
57
+ /**
58
+ * A permissions module handles request/response transformation for a specific P-protocol or P-basket scheme under BRC-98/99.
59
+ * Modules are registered in the config mapped by their scheme ID.
60
+ */
61
+ export interface PermissionsModule {
62
+ /**
63
+ * Transforms the request before it's passed to the underlying wallet.
64
+ * Can check and enforce permissions, throw errors, or modify any arguments as needed prior to invocation.
65
+ *
66
+ * @param req - The incoming request with method, args, and originator
67
+ * @returns Transformed arguments that will be passed to the underlying wallet
68
+ */
69
+ onRequest(req: { method: string; args: object; originator: string }): Promise<{ args: object }>
70
+
71
+ /**
72
+ * Transforms the response from the underlying wallet before returning to caller.
73
+ *
74
+ * @param res - The response from the underlying wallet
75
+ * @param context - Metadata about the original request (method, originator)
76
+ * @returns Transformed response to return to the caller
77
+ */
78
+ onResponse(
79
+ res: any,
80
+ context: {
81
+ method: string
82
+ originator: string
83
+ }
84
+ ): Promise<any>
85
+ }
86
+
45
87
  /**
46
88
  * Describes a group of permissions that can be requested together.
47
89
  * This structure is based on BRC-73.
@@ -234,6 +276,20 @@ export interface WalletPermissionsManagerCallbacks {
234
276
  * By default, all of these are `true` unless specified otherwise. This is the most secure configuration.
235
277
  */
236
278
  export interface PermissionsManagerConfig {
279
+ /**
280
+ * A map of P-basket/protocol permission scheme modules.
281
+ *
282
+ * Keys are scheme IDs (e.g., "btms"), values are PermissionsModule instances.
283
+ *
284
+ * Each module handles basket/protocol names of the form: `p <schemeID> <rest...>`
285
+ *
286
+ * The WalletPermissionManager detects P-prefix baskets/protocols and delegates
287
+ * request/response transformation to the corresponding module.
288
+ *
289
+ * If no module exists for a given schemeID, the wallet will reject access.
290
+ */
291
+ permissionModules?: Record<string, PermissionsModule>
292
+
237
293
  /**
238
294
  * For `createSignature` and `verifySignature`,
239
295
  * require a "protocol usage" permission check?
@@ -466,6 +522,73 @@ export class WalletPermissionsManager implements WalletInterface {
466
522
  }
467
523
  }
468
524
 
525
+ /* ---------------------------------------------------------------------
526
+ * HELPER METHODS FOR P-MODULE DELEGATION
527
+ * --------------------------------------------------------------------- */
528
+
529
+ /**
530
+ * Delegates a wallet method call to a P-module if the basket or protocol name uses a P-scheme.
531
+ * Handles the full request/response transformation flow.
532
+ *
533
+ * @param basketOrProtocolName - The basket or protocol name to check for p-module delegation
534
+ * @param method - The wallet method name being called
535
+ * @param args - The original args passed to the method
536
+ * @param originator - The originator of the request
537
+ * @param underlyingCall - Callback that executes the underlying wallet method with transformed args
538
+ * @returns The transformed response, or null if not a P-basket/protocol (caller should continue normal flow)
539
+ */
540
+ private async delegateToPModuleIfNeeded<T>(
541
+ basketOrProtocolName: string,
542
+ method: string,
543
+ args: object,
544
+ originator: string,
545
+ underlyingCall: (transformedArgs: object, originator: string) => Promise<T>
546
+ ): Promise<T | null> {
547
+ // Check if this is a P-protocol/basket
548
+ if (!basketOrProtocolName.startsWith('p ')) {
549
+ return null // If not, caller should continue normal flow
550
+ }
551
+
552
+ const schemeID = basketOrProtocolName.split(' ')[1]
553
+ const module = this.config.permissionModules?.[schemeID]
554
+
555
+ if (!module) {
556
+ throw new Error(`Unsupported P-module scheme: p ${schemeID}`)
557
+ }
558
+
559
+ // Transform request with module
560
+ const transformedReq = await module.onRequest({
561
+ method,
562
+ args,
563
+ originator
564
+ })
565
+
566
+ // Call underlying method with transformed request
567
+ const results = await underlyingCall(transformedReq.args, originator)
568
+
569
+ // Transform response with module
570
+ return await module.onResponse(results, {
571
+ method,
572
+ originator
573
+ })
574
+ }
575
+
576
+ /**
577
+ * Decrypts custom instructions in listOutputs results if encryption is configured.
578
+ */
579
+ private async decryptListOutputsMetadata(results: ListOutputsResult): Promise<ListOutputsResult> {
580
+ if (results.outputs) {
581
+ for (let i = 0; i < results.outputs.length; i++) {
582
+ if (results.outputs[i].customInstructions) {
583
+ results.outputs[i].customInstructions = await this.maybeDecryptMetadata(
584
+ results.outputs[i].customInstructions!
585
+ )
586
+ }
587
+ }
588
+ }
589
+ return results
590
+ }
591
+
469
592
  /* ---------------------------------------------------------------------
470
593
  * 1) PUBLIC API FOR REGISTERING CALLBACKS (UI PROMPTS, LOGGING, ETC.)
471
594
  * --------------------------------------------------------------------- */
@@ -913,6 +1036,7 @@ export class WalletPermissionsManager implements WalletInterface {
913
1036
  if (this.isRecentlyGranted(cacheKey)) {
914
1037
  return true
915
1038
  }
1039
+
916
1040
  const token = await this.findBasketToken(originator, basket, true, lookupValues)
917
1041
  if (token) {
918
1042
  if (!this.isTokenExpired(token.expiry)) {
@@ -991,6 +1115,7 @@ export class WalletPermissionsManager implements WalletInterface {
991
1115
  if (this.isRecentlyGranted(cacheKey)) {
992
1116
  return true
993
1117
  }
1118
+
994
1119
  const token = await this.findCertificateToken(
995
1120
  originator,
996
1121
  privileged,
@@ -2474,19 +2599,40 @@ export class WalletPermissionsManager implements WalletInterface {
2474
2599
  args: Parameters<WalletInterface['createAction']>[0],
2475
2600
  originator?: string
2476
2601
  ): ReturnType<WalletInterface['createAction']> {
2477
- // 1) Ensure basket and label permissions
2602
+ // 1) Identify unique P-modules involved (one per schemeID)
2603
+ const pModulesByScheme = new Map<string, PermissionsModule>()
2604
+ const nonPBaskets: string[] = []
2605
+
2478
2606
  if (args.outputs) {
2479
2607
  for (const out of args.outputs) {
2480
2608
  if (out.basket) {
2481
- await this.ensureBasketAccess({
2482
- originator: originator!,
2483
- basket: out.basket,
2484
- reason: args.description,
2485
- usageType: 'insertion'
2486
- })
2609
+ if (out.basket.startsWith('p ')) {
2610
+ const schemeID = out.basket.split(' ')[1]
2611
+ if (!pModulesByScheme.has(schemeID)) {
2612
+ const module = this.config.permissionModules?.[schemeID]
2613
+ if (!module) {
2614
+ throw new Error(`Unsupported P-basket scheme: p ${schemeID}`)
2615
+ }
2616
+ pModulesByScheme.set(schemeID, module)
2617
+ }
2618
+ } else {
2619
+ // Track non-P baskets for normal permission checks
2620
+ nonPBaskets.push(out.basket)
2621
+ }
2487
2622
  }
2488
2623
  }
2489
2624
  }
2625
+
2626
+ // 2) Check permissions for non-P baskets
2627
+ for (const basket of nonPBaskets) {
2628
+ await this.ensureBasketAccess({
2629
+ originator: originator!,
2630
+ basket,
2631
+ reason: args.description,
2632
+ usageType: 'insertion'
2633
+ })
2634
+ }
2635
+
2490
2636
  if (args.labels) {
2491
2637
  for (const lbl of args.labels) {
2492
2638
  await this.ensureLabelAccess({
@@ -2499,7 +2645,7 @@ export class WalletPermissionsManager implements WalletInterface {
2499
2645
  }
2500
2646
 
2501
2647
  /**
2502
- * 2) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.
2648
+ * 4) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.
2503
2649
  * This ensures the underlying wallet returns a signableTransaction, letting us parse the transaction
2504
2650
  * to determine net spending and request authorization if needed.
2505
2651
  */
@@ -2510,7 +2656,7 @@ export class WalletPermissionsManager implements WalletInterface {
2510
2656
  throw new Error('Only the admin originator can set signAndProcess=true explicitly.')
2511
2657
  }
2512
2658
 
2513
- // 3) Encrypt transaction metadata, saving originals for use in permissions and line items.
2659
+ // 5) Encrypt transaction metadata, saving originals for use in permissions and line items.
2514
2660
  const originalDescription = args.description
2515
2661
  const originalInputDescriptions = {}
2516
2662
  const originalOutputDescriptions = {}
@@ -2532,23 +2678,48 @@ export class WalletPermissionsManager implements WalletInterface {
2532
2678
  }
2533
2679
 
2534
2680
  /**
2535
- * 4) Call the underlying wallets createAction. We add two “admin” labels:
2536
- * - "admin originator <domain>"
2537
- * - "admin month YYYY-MM"
2538
- * These labels help track the originator’s monthly spending.
2681
+ * 6) Call the underlying wallet's createAction.
2682
+ * - If P-modules are involved, chain request transformations through them first
2683
+ * - Add two "admin" labels for tracking: "admin originator <domain>" and "admin month YYYY-MM"
2684
+ * - If P-modules are involved, chain response transformations back through them
2539
2685
  */
2540
- const createResult = await this.underlying.createAction(
2541
- {
2542
- ...args,
2543
- options: modifiedOptions,
2544
- labels: [
2545
- ...(args.labels || []),
2546
- `admin originator ${originator}`,
2547
- `admin month ${this.getCurrentMonthYearUTC()}`
2548
- ]
2549
- },
2550
- originator
2551
- )
2686
+ const finalArgs = {
2687
+ ...args,
2688
+ options: modifiedOptions,
2689
+ labels: [...(args.labels || []), `admin originator ${originator}`, `admin month ${this.getCurrentMonthYearUTC()}`]
2690
+ }
2691
+
2692
+ let createResult: Awaited<ReturnType<WalletInterface['createAction']>>
2693
+
2694
+ if (pModulesByScheme.size > 0) {
2695
+ // P-modules are involved - chain transformations
2696
+ const pModules = Array.from(pModulesByScheme.values())
2697
+
2698
+ // Chain onRequest calls through all modules
2699
+ let transformedArgs: object = finalArgs
2700
+ for (const module of pModules) {
2701
+ const transformed = await module.onRequest({
2702
+ method: 'createAction',
2703
+ args: transformedArgs,
2704
+ originator: originator!
2705
+ })
2706
+ transformedArgs = transformed.args
2707
+ }
2708
+
2709
+ // Call underlying wallet with transformed args
2710
+ createResult = await this.underlying.createAction(transformedArgs as CreateActionArgs, originator!)
2711
+
2712
+ // Chain onResponse calls in reverse order
2713
+ for (let i = pModules.length - 1; i >= 0; i--) {
2714
+ createResult = await pModules[i].onResponse(createResult, {
2715
+ method: 'createAction',
2716
+ originator: originator!
2717
+ })
2718
+ }
2719
+ } else {
2720
+ // No P-modules - call underlying wallet directly
2721
+ createResult = await this.underlying.createAction(finalArgs, originator!)
2722
+ }
2552
2723
 
2553
2724
  // If there's no signableTransaction, the underlying wallet must have fully finalized it. Return as is.
2554
2725
  if (!createResult.signableTransaction) {
@@ -2556,7 +2727,7 @@ export class WalletPermissionsManager implements WalletInterface {
2556
2727
  }
2557
2728
 
2558
2729
  /**
2559
- * 5) We have a signable transaction. Parse it to determine how much the originator is actually spending.
2730
+ * 7) We have a signable transaction. Parse it to determine how much the originator is actually spending.
2560
2731
  * We only consider inputs the originator explicitly listed in args.inputs.
2561
2732
  * netSpent = (sum of originator-requested outputs) - (sum of matching originator inputs).
2562
2733
  * If netSpent > 0, we need spending authorization.
@@ -2626,7 +2797,7 @@ export class WalletPermissionsManager implements WalletInterface {
2626
2797
  */
2627
2798
  netSpent = totalOutputSatoshis + tx.getFee() - totalInputSatoshis
2628
2799
 
2629
- // 6) If netSpent > 0, require spending authorization. Abort if denied.
2800
+ // 8) If netSpent > 0, require spending authorization. Abort if denied.
2630
2801
  if (netSpent > 0) {
2631
2802
  try {
2632
2803
  await this.ensureSpendingAuthorization({
@@ -2642,7 +2813,7 @@ export class WalletPermissionsManager implements WalletInterface {
2642
2813
  }
2643
2814
 
2644
2815
  /**
2645
- * 7) Decide whether to finalize the transaction automatically or return the signableTransaction:
2816
+ * 9) Decide whether to finalize the transaction automatically or return the signableTransaction:
2646
2817
  * - If the user originally wanted signAndProcess (the default when undefined), we forcibly set it to false earlier, so check if we should now finalize it.
2647
2818
  * - If the transaction still needs more signatures, we must return the signableTransaction.
2648
2819
  */
@@ -2730,6 +2901,24 @@ export class WalletPermissionsManager implements WalletInterface {
2730
2901
  for (const outIndex in requestArgs.outputs) {
2731
2902
  const out = requestArgs.outputs[outIndex]
2732
2903
  if (out.protocol === 'basket insertion') {
2904
+ // Delegate to permission module if needed
2905
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
2906
+ out.insertionRemittance!.basket,
2907
+ 'internalizeAction',
2908
+ requestArgs,
2909
+ originator!,
2910
+ async transformedArgs => {
2911
+ if (out.insertionRemittance!.customInstructions) {
2912
+ ;(transformedArgs as InternalizeActionArgs).outputs[outIndex].insertionRemittance!.customInstructions =
2913
+ await this.maybeEncryptMetadata(out.insertionRemittance!.customInstructions)
2914
+ }
2915
+ return await this.underlying.internalizeAction(transformedArgs as InternalizeActionArgs, originator!)
2916
+ }
2917
+ )
2918
+ if (pModuleResult !== null) {
2919
+ return pModuleResult
2920
+ }
2921
+
2733
2922
  await this.ensureBasketAccess({
2734
2923
  originator: originator!,
2735
2924
  basket: out.insertionRemittance!.basket,
@@ -2750,6 +2939,23 @@ export class WalletPermissionsManager implements WalletInterface {
2750
2939
  ...args: Parameters<WalletInterface['listOutputs']>
2751
2940
  ): ReturnType<WalletInterface['listOutputs']> {
2752
2941
  const [requestArgs, originator] = args
2942
+
2943
+ // Delegate to permission module if needed
2944
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
2945
+ requestArgs.basket,
2946
+ 'listOutputs',
2947
+ requestArgs,
2948
+ originator!,
2949
+ async transformedArgs => {
2950
+ const result = await this.underlying.listOutputs(transformedArgs as ListOutputsArgs, originator!)
2951
+ // Apply metadata decryption to permission module response
2952
+ return await this.decryptListOutputsMetadata(result)
2953
+ }
2954
+ )
2955
+ if (pModuleResult !== null) {
2956
+ return pModuleResult
2957
+ }
2958
+
2753
2959
  // Ensure the originator has permission for the basket.
2754
2960
  await this.ensureBasketAccess({
2755
2961
  originator: originator!,
@@ -2758,23 +2964,30 @@ export class WalletPermissionsManager implements WalletInterface {
2758
2964
  usageType: 'listing'
2759
2965
  })
2760
2966
  const results = await this.underlying.listOutputs(...args)
2761
- // Transparently decrypt transaction metadata, if configured to do so.
2762
- if (results.outputs) {
2763
- for (let i = 0; i < results.outputs.length; i++) {
2764
- if (results.outputs[i].customInstructions) {
2765
- results.outputs[i].customInstructions = await this.maybeDecryptMetadata(
2766
- results.outputs[i].customInstructions!
2767
- )
2768
- }
2769
- }
2770
- }
2771
- return results
2967
+
2968
+ // Apply metadata decryption to regular response
2969
+ return await this.decryptListOutputsMetadata(results)
2772
2970
  }
2773
2971
 
2774
2972
  public async relinquishOutput(
2775
2973
  ...args: Parameters<WalletInterface['relinquishOutput']>
2776
2974
  ): ReturnType<WalletInterface['relinquishOutput']> {
2777
2975
  const [requestArgs, originator] = args
2976
+
2977
+ // Delegate to permission module if needed
2978
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
2979
+ requestArgs.basket,
2980
+ 'relinquishOutput',
2981
+ requestArgs,
2982
+ originator!,
2983
+ async transformedArgs => {
2984
+ return await this.underlying.relinquishOutput(transformedArgs as RelinquishOutputArgs, originator!)
2985
+ }
2986
+ )
2987
+ if (pModuleResult !== null) {
2988
+ return pModuleResult
2989
+ }
2990
+
2778
2991
  await this.ensureBasketAccess({
2779
2992
  originator: originator!,
2780
2993
  basket: requestArgs.basket,
@@ -2788,7 +3001,23 @@ export class WalletPermissionsManager implements WalletInterface {
2788
3001
  ...args: Parameters<WalletInterface['getPublicKey']>
2789
3002
  ): ReturnType<WalletInterface['getPublicKey']> {
2790
3003
  const [requestArgs, originator] = args
3004
+
2791
3005
  if (requestArgs.protocolID) {
3006
+ // Delegate to permission module if needed
3007
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3008
+ requestArgs.protocolID[1],
3009
+ 'getPublicKey',
3010
+ requestArgs,
3011
+ originator!,
3012
+ async transformedArgs => {
3013
+ return await this.underlying.getPublicKey(transformedArgs as GetPublicKeyArgs, originator!)
3014
+ }
3015
+ )
3016
+ if (pModuleResult !== null) {
3017
+ return pModuleResult
3018
+ }
3019
+
3020
+ // Not a P-protocol, continue with normal permission flow
2792
3021
  await this.ensureProtocolPermission({
2793
3022
  originator: originator!,
2794
3023
  privileged: requestArgs.privileged!,
@@ -2798,6 +3027,7 @@ export class WalletPermissionsManager implements WalletInterface {
2798
3027
  usageType: 'publicKey'
2799
3028
  })
2800
3029
  }
3030
+
2801
3031
  if (requestArgs.identityKey) {
2802
3032
  // We also require a minimal protocol permission to retrieve the user's identity key
2803
3033
  await this.ensureProtocolPermission({
@@ -2809,6 +3039,7 @@ export class WalletPermissionsManager implements WalletInterface {
2809
3039
  usageType: 'identityKey'
2810
3040
  })
2811
3041
  }
3042
+
2812
3043
  return this.underlying.getPublicKey(...args)
2813
3044
  }
2814
3045
 
@@ -2847,6 +3078,19 @@ export class WalletPermissionsManager implements WalletInterface {
2847
3078
 
2848
3079
  public async encrypt(...args: Parameters<WalletInterface['encrypt']>): ReturnType<WalletInterface['encrypt']> {
2849
3080
  const [requestArgs, originator] = args
3081
+ // Delegate to permission module if needed
3082
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3083
+ requestArgs.protocolID[1],
3084
+ 'encrypt',
3085
+ requestArgs,
3086
+ originator!,
3087
+ async transformedArgs => {
3088
+ return await this.underlying.encrypt(transformedArgs as WalletEncryptArgs, originator!)
3089
+ }
3090
+ )
3091
+ if (pModuleResult !== null) {
3092
+ return pModuleResult
3093
+ }
2850
3094
  await this.ensureProtocolPermission({
2851
3095
  originator: originator!,
2852
3096
  protocolID: requestArgs.protocolID,
@@ -2860,6 +3104,19 @@ export class WalletPermissionsManager implements WalletInterface {
2860
3104
 
2861
3105
  public async decrypt(...args: Parameters<WalletInterface['decrypt']>): ReturnType<WalletInterface['decrypt']> {
2862
3106
  const [requestArgs, originator] = args
3107
+ // Delegate to permission module if needed
3108
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3109
+ requestArgs.protocolID[1],
3110
+ 'decrypt',
3111
+ requestArgs,
3112
+ originator!,
3113
+ async transformedArgs => {
3114
+ return await this.underlying.decrypt(transformedArgs as WalletDecryptArgs, originator!)
3115
+ }
3116
+ )
3117
+ if (pModuleResult !== null) {
3118
+ return pModuleResult
3119
+ }
2863
3120
  await this.ensureProtocolPermission({
2864
3121
  originator: originator!,
2865
3122
  privileged: requestArgs.privileged!,
@@ -2875,6 +3132,19 @@ export class WalletPermissionsManager implements WalletInterface {
2875
3132
  ...args: Parameters<WalletInterface['createHmac']>
2876
3133
  ): ReturnType<WalletInterface['createHmac']> {
2877
3134
  const [requestArgs, originator] = args
3135
+ // Delegate to permission module if needed
3136
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3137
+ requestArgs.protocolID[1],
3138
+ 'createHmac',
3139
+ requestArgs,
3140
+ originator!,
3141
+ async transformedArgs => {
3142
+ return await this.underlying.createHmac(transformedArgs as CreateHmacArgs, originator!)
3143
+ }
3144
+ )
3145
+ if (pModuleResult !== null) {
3146
+ return pModuleResult
3147
+ }
2878
3148
  await this.ensureProtocolPermission({
2879
3149
  originator: originator!,
2880
3150
  privileged: requestArgs.privileged!,
@@ -2890,6 +3160,19 @@ export class WalletPermissionsManager implements WalletInterface {
2890
3160
  ...args: Parameters<WalletInterface['verifyHmac']>
2891
3161
  ): ReturnType<WalletInterface['verifyHmac']> {
2892
3162
  const [requestArgs, originator] = args
3163
+ // Delegate to permission module if needed
3164
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3165
+ requestArgs.protocolID[1],
3166
+ 'verifyHmac',
3167
+ requestArgs,
3168
+ originator!,
3169
+ async transformedArgs => {
3170
+ return await this.underlying.verifyHmac(transformedArgs as VerifyHmacArgs, originator!)
3171
+ }
3172
+ )
3173
+ if (pModuleResult !== null) {
3174
+ return pModuleResult
3175
+ }
2893
3176
  await this.ensureProtocolPermission({
2894
3177
  originator: originator!,
2895
3178
  privileged: requestArgs.privileged!,
@@ -2905,6 +3188,19 @@ export class WalletPermissionsManager implements WalletInterface {
2905
3188
  ...args: Parameters<WalletInterface['createSignature']>
2906
3189
  ): ReturnType<WalletInterface['createSignature']> {
2907
3190
  const [requestArgs, originator] = args
3191
+ // Delegate to permission module if needed
3192
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3193
+ requestArgs.protocolID[1],
3194
+ 'createSignature',
3195
+ requestArgs,
3196
+ originator!,
3197
+ async transformedArgs => {
3198
+ return await this.underlying.createSignature(transformedArgs as CreateSignatureArgs, originator!)
3199
+ }
3200
+ )
3201
+ if (pModuleResult !== null) {
3202
+ return pModuleResult
3203
+ }
2908
3204
  await this.ensureProtocolPermission({
2909
3205
  originator: originator!,
2910
3206
  privileged: requestArgs.privileged!,
@@ -2920,6 +3216,19 @@ export class WalletPermissionsManager implements WalletInterface {
2920
3216
  ...args: Parameters<WalletInterface['verifySignature']>
2921
3217
  ): ReturnType<WalletInterface['verifySignature']> {
2922
3218
  const [requestArgs, originator] = args
3219
+ // Delegate to permission module if needed
3220
+ const pModuleResult = await this.delegateToPModuleIfNeeded(
3221
+ requestArgs.protocolID[1],
3222
+ 'verifySignature',
3223
+ requestArgs,
3224
+ originator!,
3225
+ async transformedArgs => {
3226
+ return await this.underlying.verifySignature(transformedArgs as VerifySignatureArgs, originator!)
3227
+ }
3228
+ )
3229
+ if (pModuleResult !== null) {
3230
+ return pModuleResult
3231
+ }
2923
3232
  await this.ensureProtocolPermission({
2924
3233
  originator: originator!,
2925
3234
  privileged: requestArgs.privileged!,
@@ -3196,7 +3505,7 @@ export class WalletPermissionsManager implements WalletInterface {
3196
3505
  */
3197
3506
  private isAdminProtocol(proto: WalletProtocol): boolean {
3198
3507
  const protocolName = proto[1]
3199
- if (protocolName.startsWith('admin') || protocolName.startsWith('p ')) {
3508
+ if (protocolName.startsWith('admin')) {
3200
3509
  return true
3201
3510
  }
3202
3511
  return false
@@ -3226,7 +3535,6 @@ export class WalletPermissionsManager implements WalletInterface {
3226
3535
  private isAdminBasket(basket: string): boolean {
3227
3536
  if (basket === 'default') return true
3228
3537
  if (basket.startsWith('admin')) return true
3229
- if (basket.startsWith('p ')) return true
3230
3538
  return false
3231
3539
  }
3232
3540
 
@@ -1,5 +1,4 @@
1
-
2
- const { Validation } = jest.requireActual('@bsv/sdk');
1
+ const { Validation } = jest.requireActual('@bsv/sdk')
3
2
 
4
3
  /**
5
4
  * A permissions manager testing mock/stub file for: