@bounded-sh/client 0.0.112-ux-audit.2 → 0.0.113

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 (53) hide show
  1. package/dist/auth/bounded-widget-modal.d.ts +24 -2
  2. package/dist/auth/providers/injected-wallet-provider.d.ts +7 -0
  3. package/dist/auth/providers/injected-wallet-types.d.ts +2 -0
  4. package/dist/auth/providers/solana-mobile-registration.d.ts +18 -0
  5. package/dist/{email-auth-provider-BfCH7K6N.mjs → email-auth-provider-Bk5GSpYT.mjs} +2 -2
  6. package/dist/{email-auth-provider-C7RXLVd9.mjs.map → email-auth-provider-Bk5GSpYT.mjs.map} +1 -1
  7. package/dist/{email-auth-provider-DTrCfOJd.js → email-auth-provider-Cr66GaKw.js} +2 -2
  8. package/dist/{email-auth-provider-DTrCfOJd.js.map → email-auth-provider-Cr66GaKw.js.map} +1 -1
  9. package/dist/{email-auth-provider-53sA5_i2.js → email-auth-provider-DeORQbTK.js} +2 -2
  10. package/dist/{email-auth-provider-53sA5_i2.js.map → email-auth-provider-DeORQbTK.js.map} +1 -1
  11. package/dist/{email-auth-provider-C7RXLVd9.mjs → email-auth-provider-nDZjRDpj.mjs} +2 -2
  12. package/dist/{email-auth-provider-BfCH7K6N.mjs.map → email-auth-provider-nDZjRDpj.mjs.map} +1 -1
  13. package/dist/{guest-auth-provider-00KkSNpE.js → guest-auth-provider-5bX-xt6K.js} +2 -2
  14. package/dist/{guest-auth-provider-00KkSNpE.js.map → guest-auth-provider-5bX-xt6K.js.map} +1 -1
  15. package/dist/{guest-auth-provider-Tndt6tzJ.js → guest-auth-provider-CUNkZVFK.js} +2 -2
  16. package/dist/{guest-auth-provider-Tndt6tzJ.js.map → guest-auth-provider-CUNkZVFK.js.map} +1 -1
  17. package/dist/{guest-auth-provider-DjOFjtnk.mjs → guest-auth-provider-DDudqqxY.mjs} +2 -2
  18. package/dist/{guest-auth-provider-DjOFjtnk.mjs.map → guest-auth-provider-DDudqqxY.mjs.map} +1 -1
  19. package/dist/{guest-auth-provider-2J4fnTX5.mjs → guest-auth-provider-ejUTbjCC.mjs} +2 -2
  20. package/dist/{guest-auth-provider-2J4fnTX5.mjs.map → guest-auth-provider-ejUTbjCC.mjs.map} +1 -1
  21. package/dist/{index-D3kdhCpH.mjs → index-BAiLpNEQ.mjs} +190 -53
  22. package/dist/index-BAiLpNEQ.mjs.map +1 -0
  23. package/dist/{index-DJeEMevo.js → index-BZ0X1Z9X.js} +190 -53
  24. package/dist/index-BZ0X1Z9X.js.map +1 -0
  25. package/dist/index.js +1 -1
  26. package/dist/index.mjs +1 -1
  27. package/dist/{index.native-ingNhWPw.js → index.native-DJSOqyKQ.js} +101 -14
  28. package/dist/index.native-DJSOqyKQ.js.map +1 -0
  29. package/dist/{index.native-CAH_ks0s.mjs → index.native-DcW2klyn.mjs} +100 -15
  30. package/dist/index.native-DcW2klyn.mjs.map +1 -0
  31. package/dist/index.native.js +1 -1
  32. package/dist/index.native.mjs +1 -1
  33. package/dist/{injected-evm-wallet-provider-Cao1U0NZ.js → injected-evm-wallet-provider-BDYWjIOQ.js} +2 -2
  34. package/dist/{injected-evm-wallet-provider-Cao1U0NZ.js.map → injected-evm-wallet-provider-BDYWjIOQ.js.map} +1 -1
  35. package/dist/{injected-evm-wallet-provider-DXjwPjLW.mjs → injected-evm-wallet-provider-BQ_kG1vI.mjs} +2 -2
  36. package/dist/{injected-evm-wallet-provider-DXjwPjLW.mjs.map → injected-evm-wallet-provider-BQ_kG1vI.mjs.map} +1 -1
  37. package/dist/{injected-evm-wallet-provider-BtyG1HOX.mjs → injected-evm-wallet-provider-C4aKa2v1.mjs} +2 -2
  38. package/dist/{injected-evm-wallet-provider-BtyG1HOX.mjs.map → injected-evm-wallet-provider-C4aKa2v1.mjs.map} +1 -1
  39. package/dist/{injected-evm-wallet-provider-IlkuKffc.js → injected-evm-wallet-provider-D06arDQD.js} +2 -2
  40. package/dist/{injected-evm-wallet-provider-IlkuKffc.js.map → injected-evm-wallet-provider-D06arDQD.js.map} +1 -1
  41. package/dist/{injected-wallet-provider-BEYwsn6M.js → injected-wallet-provider-B9jvzDM5.js} +51 -22
  42. package/dist/{injected-wallet-provider-BEYwsn6M.js.map → injected-wallet-provider-B9jvzDM5.js.map} +1 -1
  43. package/dist/{injected-wallet-provider-0SSONh1d.mjs → injected-wallet-provider-Dj-F69gb.mjs} +51 -22
  44. package/dist/{injected-wallet-provider-0SSONh1d.mjs.map → injected-wallet-provider-Dj-F69gb.mjs.map} +1 -1
  45. package/dist/{injected-wallet-provider-DSlHfgMU.js → injected-wallet-provider-Dqmk-m4V.js} +67 -26
  46. package/dist/{injected-wallet-provider-DSlHfgMU.js.map → injected-wallet-provider-Dqmk-m4V.js.map} +1 -1
  47. package/dist/{injected-wallet-provider-CfYNIIHd.mjs → injected-wallet-provider-DxPcYxP-.mjs} +67 -26
  48. package/dist/{injected-wallet-provider-CfYNIIHd.mjs.map → injected-wallet-provider-DxPcYxP-.mjs.map} +1 -1
  49. package/package.json +2 -2
  50. package/dist/index-D3kdhCpH.mjs.map +0 -1
  51. package/dist/index-DJeEMevo.js.map +0 -1
  52. package/dist/index.native-CAH_ks0s.mjs.map +0 -1
  53. package/dist/index.native-ingNhWPw.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@bounded-sh/core');
4
- var index_native = require('./index.native-ingNhWPw.js');
4
+ var index_native = require('./index.native-DJSOqyKQ.js');
5
5
  require('react');
6
6
 
7
7
  const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
@@ -2470,7 +2470,9 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
2470
2470
  // mobile adapter fills DEFAULT_FEATURES in exactly that case. So an empty list
2471
2471
  // means none, and reading it as "everything" picks an account that cannot sign
2472
2472
  // and fails at the wallet instead of here.
2473
- const accountSupports = (account, feature) => account.features.includes(feature);
2473
+ // The mobile adapter hands a wallet app's own feature names through
2474
+ // untranslated, so each name is read as its Wallet Standard equivalent.
2475
+ const accountSupports = (account, feature) => account.features.some((f) => index_native.walletStandardFeatureName(f) === feature);
2474
2476
  const pickSolanaAccount = (accounts) => {
2475
2477
  // With a network configured, an account that does not support it is not a
2476
2478
  // usable account: `WalletAccount.chains` is what that account can sign for,
@@ -2545,13 +2547,23 @@ function standardWalletToInjectedProvider(wallet, configuredNetwork) {
2545
2547
  } }, (hasFeature(wallet, SolanaSignIn)
2546
2548
  ? {
2547
2549
  async signIn(input) {
2548
- const acc = requireAccount();
2549
- if (!accountSupports(acc, SolanaSignIn))
2550
- throw new Error("Wallet account does not support solana:signIn");
2550
+ var _a;
2551
2551
  const sign = feature(wallet, SolanaSignIn);
2552
2552
  if (!sign)
2553
2553
  throw new Error("Wallet does not support solana:signIn");
2554
+ const open = currentAccount();
2555
+ if (open && !accountSupports(open, SolanaSignIn))
2556
+ throw new Error("Wallet account does not support solana:signIn");
2557
+ if (index_native.solanaMobileWalletAnswersSignInFromCache(wallet.name)) {
2558
+ // Drop the cached authorization so this sign-in is performed by the
2559
+ // wallet app, with its payload, rather than answered from a record
2560
+ // that holds no sign-in result or an earlier sign-in's spent nonce.
2561
+ // Local to the page: the adapter's disconnect opens nothing.
2562
+ await ((_a = feature(wallet, StandardDisconnect)) === null || _a === void 0 ? void 0 : _a.disconnect());
2563
+ }
2554
2564
  const [out] = await sign.signIn(input);
2565
+ if (!out)
2566
+ throw new Error("Wallet returned no sign-in result");
2555
2567
  return { account: { address: out.account.address }, signedMessage: out.signedMessage, signature: out.signature };
2556
2568
  },
2557
2569
  }
@@ -2834,37 +2846,66 @@ class InjectedWalletProvider {
2834
2846
  throw new Error('Wallet did not return a public key on connect');
2835
2847
  return pk.toString();
2836
2848
  }
2849
+ /**
2850
+ * The account the wallet already holds open for this page, named WITHOUT a
2851
+ * prompt: a live connection, else a silent connect (an injected wallet that
2852
+ * still trusts the page; the mobile wallet's cached authorization, read from
2853
+ * storage). Null when the wallet would have to ask the user.
2854
+ */
2855
+ async trustedAddress(provider) {
2856
+ try {
2857
+ return await this.connectAddress(provider, true);
2858
+ }
2859
+ catch (_a) {
2860
+ return null;
2861
+ }
2862
+ }
2837
2863
  async login() {
2864
+ var _a;
2838
2865
  index_native.setAuthLoading(true);
2839
2866
  try {
2840
2867
  const provider = this.resolveProvider();
2841
- const address = await this.connectAddress(provider);
2842
- // Reuse a still-valid session for THIS wallet.
2843
- const existing = await core.getActiveSessionManager().getSession();
2844
- if (existing && existing.address === address) {
2845
- const user = { address, id: address, provider: this };
2846
- this.authenticatedAddress = address;
2868
+ // SEC-01: a wallet without Sign In With Solana is refused before it is
2869
+ // asked anything, never downgraded to plain message signing.
2870
+ if (typeof provider.signIn !== 'function')
2871
+ throw new Error(WALLET_SIGN_IN_UNSUPPORTED_ERR);
2872
+ // Reuse a still-valid session for THIS wallet, when the wallet names its
2873
+ // account without prompting. Nothing here opens the wallet: the sign-in
2874
+ // below is the one interactive step of a login.
2875
+ const trusted = await this.trustedAddress(provider);
2876
+ const existing = trusted ? await core.getActiveSessionManager().getSession() : null;
2877
+ if (trusted && existing && existing.address === trusted) {
2878
+ const user = { address: trusted, id: trusted, provider: this };
2879
+ this.authenticatedAddress = trusted;
2847
2880
  index_native.setCurrentUser(user);
2848
2881
  this.markAuthMethod();
2849
2882
  return user;
2850
2883
  }
2851
- // Sign In With Solana (SEC-01): the wallet renders the standard sign-in
2852
- // text and, with the domain left unset here, stamps THIS page's host; the
2853
- // issuer refuses any other domain for the request's Origin, so a phishing
2854
- // page cannot obtain a login for another site. Bounded chooses only the nonce,
2855
- // the validity window and the app id (Request ID); a wallet without the
2856
- // feature is refused, never downgraded to plain message signing. The
2857
- // nonce is fetched HERE, after connect, on purpose: a network round trip
2858
- // before the wallet handoff decays the transient activation the mobile
2859
- // wallet's intent navigation needs.
2860
- if (typeof provider.signIn !== 'function')
2861
- throw new Error(WALLET_SIGN_IN_UNSUPPORTED_ERR);
2884
+ // Sign In With Solana (SEC-01) is connect and sign in ONE wallet step:
2885
+ // the wallet authorizes an account, renders the standard sign-in text
2886
+ // for it and, with the domain left unset here, stamps THIS page's host;
2887
+ // the issuer refuses any other domain for the request's Origin, so a
2888
+ // phishing page cannot obtain a login for another site. Bounded chooses
2889
+ // only the nonce, the validity window and the app id (Request ID).
2890
+ // No separate connect comes first: the mobile adapter would answer the
2891
+ // sign-in from the authorization that connect cached, with no sign-in
2892
+ // result in it, and a second wallet prompt is friction for every other
2893
+ // wallet. The nonce is fetched BEFORE the gesture below, so nothing
2894
+ // async sits between the tap and the wallet handoff - a network round
2895
+ // trip there decays the transient activation the mobile wallet's intent
2896
+ // navigation needs.
2862
2897
  const nonce = await core.genAuthNonce();
2863
2898
  const request = await core.genSolanaSignInRequest(nonce);
2864
- await this.freshActivation(provider, 'login', address);
2899
+ await this.freshActivation(provider, 'login', trusted);
2865
2900
  const signedIn = normalizeSignInOutput(await provider.signIn(request));
2866
- if (signedIn.account.address !== address) {
2867
- throw new Error(`The wallet signed in as ${signedIn.account.address}, not the connected account ${address}. Sign in again.`);
2901
+ const address = signedIn.account.address;
2902
+ // The account the wallet now reports as open must be the one that signed
2903
+ // in: a proof for another account would bind this session to an identity
2904
+ // the wallet is not acting as (DS2-0369). A wallet that reports no account
2905
+ // leaves the sign-in output as the only word on which one it is.
2906
+ const active = (_a = provider.publicKey) === null || _a === void 0 ? void 0 : _a.toString();
2907
+ if (active && active !== address) {
2908
+ throw new Error(`The wallet signed in as ${address}, not the connected account ${active}. Sign in again.`);
2868
2909
  }
2869
2910
  // The issuer verifies the signature over the EXACT bytes the wallet signed
2870
2911
  // and parses them, so the text travels as the wallet rendered it.
@@ -3184,4 +3225,4 @@ class InjectedWalletProvider {
3184
3225
  exports.InjectedWalletProvider = InjectedWalletProvider;
3185
3226
  exports.WALLET_SIGN_IN_UNSUPPORTED_ERR = WALLET_SIGN_IN_UNSUPPORTED_ERR;
3186
3227
  exports.defaultInjectedProvider = defaultInjectedProvider;
3187
- //# sourceMappingURL=injected-wallet-provider-DSlHfgMU.js.map
3228
+ //# sourceMappingURL=injected-wallet-provider-Dqmk-m4V.js.map