@bsv/wallet-toolbox 1.6.18 → 1.6.20

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 (48) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/docs/client.md +93 -27
  3. package/docs/wallet.md +93 -27
  4. package/mobile/out/src/Wallet.d.ts +4 -0
  5. package/mobile/out/src/Wallet.d.ts.map +1 -1
  6. package/mobile/out/src/Wallet.js +62 -21
  7. package/mobile/out/src/Wallet.js.map +1 -1
  8. package/mobile/out/src/index.client.d.ts +1 -0
  9. package/mobile/out/src/index.client.d.ts.map +1 -1
  10. package/mobile/out/src/index.client.js +1 -0
  11. package/mobile/out/src/index.client.js.map +1 -1
  12. package/mobile/out/src/index.mobile.d.ts +1 -0
  13. package/mobile/out/src/index.mobile.d.ts.map +1 -1
  14. package/mobile/out/src/index.mobile.js +1 -0
  15. package/mobile/out/src/index.mobile.js.map +1 -1
  16. package/mobile/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.d.ts +29 -0
  17. package/mobile/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.d.ts.map +1 -0
  18. package/mobile/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js +70 -0
  19. package/mobile/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js.map +1 -0
  20. package/mobile/package-lock.json +2 -2
  21. package/mobile/package.json +1 -1
  22. package/out/src/Wallet.d.ts +4 -0
  23. package/out/src/Wallet.d.ts.map +1 -1
  24. package/out/src/Wallet.js +62 -21
  25. package/out/src/Wallet.js.map +1 -1
  26. package/out/src/index.all.d.ts +1 -0
  27. package/out/src/index.all.d.ts.map +1 -1
  28. package/out/src/index.all.js +1 -0
  29. package/out/src/index.all.js.map +1 -1
  30. package/out/src/index.client.d.ts +1 -0
  31. package/out/src/index.client.d.ts.map +1 -1
  32. package/out/src/index.client.js +1 -0
  33. package/out/src/index.client.js.map +1 -1
  34. package/out/src/index.mobile.d.ts +1 -0
  35. package/out/src/index.mobile.d.ts.map +1 -1
  36. package/out/src/index.mobile.js +1 -0
  37. package/out/src/index.mobile.js.map +1 -1
  38. package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.d.ts +29 -0
  39. package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.d.ts.map +1 -0
  40. package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js +70 -0
  41. package/out/src/wab-client/auth-method-interactors/DevConsoleInteractor.js.map +1 -0
  42. package/out/tsconfig.all.tsbuildinfo +1 -1
  43. package/package.json +1 -1
  44. package/src/Wallet.ts +87 -28
  45. package/src/index.all.ts +1 -0
  46. package/src/index.client.ts +1 -0
  47. package/src/index.mobile.ts +1 -0
  48. package/src/wab-client/auth-method-interactors/DevConsoleInteractor.ts +73 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.6.18",
3
+ "version": "1.6.20",
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
@@ -615,6 +615,15 @@ export class Wallet implements WalletInterface, ProtoWallet {
615
615
  return r
616
616
  }
617
617
 
618
+ /** 2-minute cache of trust settings for identity resolution paths */
619
+ private _trustSettingsCache?: {
620
+ expiresAt: number
621
+ trustSettings: Awaited<ReturnType<WalletSettingsManager['get']>>['trustSettings']
622
+ }
623
+
624
+ /** 2-minute cache of queryOverlay() results keyed by normalized query */
625
+ private _overlayCache: Map<string, { expiresAt: number; value: unknown }> = new Map()
626
+
618
627
  async discoverByIdentityKey(
619
628
  args: DiscoverByIdentityKeyArgs,
620
629
  originator?: OriginatorDomainNameStringUnder250Bytes
@@ -622,21 +631,42 @@ export class Wallet implements WalletInterface, ProtoWallet {
622
631
  validateOriginator(originator)
623
632
  this.validateAuthAndArgs(args, validateDiscoverByIdentityKeyArgs)
624
633
 
625
- const trustSettings = (await this.settingsManager.get()).trustSettings
626
- const results = await queryOverlay(
627
- {
628
- identityKey: args.identityKey,
629
- certifiers: trustSettings.trustedCertifiers.map(certifier => certifier.identityKey)
630
- },
631
- this.lookupResolver
632
- )
633
- if (!results) {
634
- return {
635
- totalCertificates: 0,
636
- certificates: []
637
- }
634
+ const TTL_MS = 2 * 60 * 1000
635
+ const now = Date.now()
636
+
637
+ // --- trustSettings cache (2 minutes) ---
638
+ let trustSettings =
639
+ this._trustSettingsCache && this._trustSettingsCache.expiresAt > now
640
+ ? this._trustSettingsCache.trustSettings
641
+ : undefined
642
+
643
+ if (!trustSettings) {
644
+ const settings = await this.settingsManager.get()
645
+ trustSettings = settings.trustSettings
646
+ this._trustSettingsCache = { trustSettings, expiresAt: now + TTL_MS }
638
647
  }
639
- return transformVerifiableCertificatesWithTrust(trustSettings, results)
648
+
649
+ const certifiers = trustSettings.trustedCertifiers.map(c => c.identityKey).sort()
650
+
651
+ // --- queryOverlay cache (2 minutes) ---
652
+ const cacheKey = JSON.stringify({
653
+ fn: 'discoverByIdentityKey',
654
+ identityKey: args.identityKey,
655
+ certifiers
656
+ })
657
+
658
+ let cached = this._overlayCache.get(cacheKey)
659
+ if (!cached || cached.expiresAt <= now) {
660
+ const value = await queryOverlay({ identityKey: args.identityKey, certifiers }, this.lookupResolver)
661
+ cached = { value, expiresAt: now + TTL_MS }
662
+ this._overlayCache.set(cacheKey, cached)
663
+ }
664
+
665
+ if (!cached.value) {
666
+ return { totalCertificates: 0, certificates: [] }
667
+ }
668
+
669
+ return transformVerifiableCertificatesWithTrust(trustSettings, cached.value as any)
640
670
  }
641
671
 
642
672
  async discoverByAttributes(
@@ -646,21 +676,50 @@ export class Wallet implements WalletInterface, ProtoWallet {
646
676
  validateOriginator(originator)
647
677
  this.validateAuthAndArgs(args, validateDiscoverByAttributesArgs)
648
678
 
649
- const trustSettings = (await this.settingsManager.get()).trustSettings
650
- const results = await queryOverlay(
651
- {
652
- attributes: args.attributes,
653
- certifiers: trustSettings.trustedCertifiers.map(certifier => certifier.identityKey)
654
- },
655
- this.lookupResolver
656
- )
657
- if (!results) {
658
- return {
659
- totalCertificates: 0,
660
- certificates: []
661
- }
679
+ const TTL_MS = 2 * 60 * 1000
680
+ const now = Date.now()
681
+
682
+ // --- trustSettings cache (2 minutes) ---
683
+ let trustSettings =
684
+ this._trustSettingsCache && this._trustSettingsCache.expiresAt > now
685
+ ? this._trustSettingsCache.trustSettings
686
+ : undefined
687
+
688
+ if (!trustSettings) {
689
+ const settings = await this.settingsManager.get()
690
+ trustSettings = settings.trustSettings
691
+ this._trustSettingsCache = { trustSettings, expiresAt: now + TTL_MS }
692
+ }
693
+
694
+ const certifiers = trustSettings.trustedCertifiers.map(c => c.identityKey).sort()
695
+
696
+ // Normalize attributes for a stable cache key.
697
+ // If attributes is an object, sort its top-level keys; if it's an array, sort a shallow copy.
698
+ let attributesKey: unknown = args.attributes
699
+ if (args.attributes && typeof args.attributes === 'object') {
700
+ const keys = Object.keys(args.attributes as Record<string, unknown>).sort()
701
+ attributesKey = JSON.stringify(args.attributes, keys)
662
702
  }
663
- return transformVerifiableCertificatesWithTrust(trustSettings, results)
703
+
704
+ // --- queryOverlay cache (2 minutes) ---
705
+ const cacheKey = JSON.stringify({
706
+ fn: 'discoverByAttributes',
707
+ attributes: attributesKey,
708
+ certifiers
709
+ })
710
+
711
+ let cached = this._overlayCache.get(cacheKey)
712
+ if (!cached || cached.expiresAt <= now) {
713
+ const value = await queryOverlay({ attributes: args.attributes, certifiers }, this.lookupResolver)
714
+ cached = { value, expiresAt: now + TTL_MS }
715
+ this._overlayCache.set(cacheKey, cached)
716
+ }
717
+
718
+ if (!cached.value) {
719
+ return { totalCertificates: 0, certificates: [] }
720
+ }
721
+
722
+ return transformVerifiableCertificatesWithTrust(trustSettings, cached.value as any)
664
723
  }
665
724
 
666
725
  verifyReturnedTxidOnly(beef: Beef, knownTxids?: string[]): Beef {
package/src/index.all.ts CHANGED
@@ -19,6 +19,7 @@ export * from './SimpleWalletManager'
19
19
  export * from './wab-client/auth-method-interactors/AuthMethodInteractor'
20
20
  export * from './wab-client/auth-method-interactors/PersonaIDInteractor'
21
21
  export * from './wab-client/auth-method-interactors/TwilioPhoneInteractor'
22
+ export * from './wab-client/auth-method-interactors/DevConsoleInteractor'
22
23
  export * from './wab-client/WABClient'
23
24
  export * from './Wallet'
24
25
  export * from './WalletAuthenticationManager'
@@ -17,6 +17,7 @@ export * from './SimpleWalletManager'
17
17
  export * from './wab-client/auth-method-interactors/AuthMethodInteractor'
18
18
  export * from './wab-client/auth-method-interactors/PersonaIDInteractor'
19
19
  export * from './wab-client/auth-method-interactors/TwilioPhoneInteractor'
20
+ export * from './wab-client/auth-method-interactors/DevConsoleInteractor'
20
21
  export * from './wab-client/WABClient'
21
22
  export * from './Wallet'
22
23
  export * from './WalletAuthenticationManager'
@@ -13,6 +13,7 @@ export * from './SimpleWalletManager'
13
13
  export * from './wab-client/auth-method-interactors/AuthMethodInteractor'
14
14
  export * from './wab-client/auth-method-interactors/PersonaIDInteractor'
15
15
  export * from './wab-client/auth-method-interactors/TwilioPhoneInteractor'
16
+ export * from './wab-client/auth-method-interactors/DevConsoleInteractor'
16
17
  export * from './wab-client/WABClient'
17
18
  export * from './Wallet'
18
19
  export * from './WalletAuthenticationManager'
@@ -0,0 +1,73 @@
1
+ import { AuthMethodInteractor, AuthPayload, StartAuthResponse, CompleteAuthResponse } from './AuthMethodInteractor'
2
+
3
+ /**
4
+ * DevConsoleInteractor
5
+ *
6
+ * A client-side class that knows how to call the WAB server for DevConsole-based authentication.
7
+ * This is a development-only auth method that generates OTP codes and logs them to the console.
8
+ */
9
+ export class DevConsoleInteractor extends AuthMethodInteractor {
10
+ public methodType = 'DevConsole'
11
+
12
+ /**
13
+ * Start the DevConsole authentication on the server.
14
+ * - The server will generate an OTP code and log it to the console for development use.
15
+ * @param serverUrl - The base URL of the WAB server (e.g. http://localhost:3000)
16
+ * @param presentationKey - The 256-bit key the client is attempting to authenticate with
17
+ * @param payload - { phoneNumber: string } (identifier for the authentication)
18
+ * @returns - { success, message, data }
19
+ */
20
+ public async startAuth(serverUrl: string, presentationKey: string, payload: AuthPayload): Promise<StartAuthResponse> {
21
+ const res = await fetch(`${serverUrl}/auth/start`, {
22
+ method: 'POST',
23
+ headers: { 'Content-Type': 'application/json' },
24
+ body: JSON.stringify({
25
+ methodType: this.methodType,
26
+ presentationKey,
27
+ payload
28
+ })
29
+ })
30
+
31
+ if (!res.ok) {
32
+ return {
33
+ success: false,
34
+ message: `HTTP error ${res.status}`
35
+ }
36
+ }
37
+
38
+ return res.json()
39
+ }
40
+
41
+ /**
42
+ * Complete the DevConsole authentication on the server.
43
+ * - The server will verify the OTP code that was generated and logged to the console.
44
+ * @param serverUrl - The base URL of the WAB server
45
+ * @param presentationKey - The 256-bit key
46
+ * @param payload - { phoneNumber: string, otp: string } (the identifier and OTP code from console)
47
+ * @returns - { success, message, presentationKey }
48
+ */
49
+ public async completeAuth(
50
+ serverUrl: string,
51
+ presentationKey: string,
52
+ payload: AuthPayload
53
+ ): Promise<CompleteAuthResponse> {
54
+ const res = await fetch(`${serverUrl}/auth/complete`, {
55
+ method: 'POST',
56
+ headers: { 'Content-Type': 'application/json' },
57
+ body: JSON.stringify({
58
+ methodType: this.methodType,
59
+ presentationKey,
60
+ payload
61
+ })
62
+ })
63
+
64
+ if (!res.ok) {
65
+ return {
66
+ success: false,
67
+ message: `HTTP error ${res.status}`
68
+ }
69
+ }
70
+
71
+ return res.json()
72
+ }
73
+ }