@multiplatform.one/web3 7.17.0 → 7.19.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.
Files changed (421) hide show
  1. package/README.md +60 -0
  2. package/dist/cjs/clients/adapter.cjs +33 -0
  3. package/dist/cjs/clients/adapter.native.js +36 -0
  4. package/dist/cjs/clients/adapter.native.js.map +1 -0
  5. package/dist/cjs/clients/bitcoin.cjs +46 -0
  6. package/dist/cjs/clients/bitcoin.native.js +51 -0
  7. package/dist/cjs/clients/bitcoin.native.js.map +1 -0
  8. package/dist/cjs/clients/connector.cjs +45 -0
  9. package/dist/cjs/clients/connector.native.js +49 -0
  10. package/dist/cjs/clients/connector.native.js.map +1 -0
  11. package/dist/cjs/clients/evm.cjs +171 -0
  12. package/dist/cjs/clients/evm.native.js +198 -0
  13. package/dist/cjs/clients/evm.native.js.map +1 -0
  14. package/dist/cjs/clients/gpg.cjs +31 -0
  15. package/dist/cjs/clients/gpg.native.js +34 -0
  16. package/dist/cjs/clients/gpg.native.js.map +1 -0
  17. package/dist/cjs/clients/hooks.cjs +78 -0
  18. package/dist/cjs/clients/hooks.native.js +85 -0
  19. package/dist/cjs/clients/hooks.native.js.map +1 -0
  20. package/dist/cjs/clients/index.cjs +49 -0
  21. package/dist/cjs/clients/index.native.js +52 -0
  22. package/dist/cjs/clients/index.native.js.map +1 -0
  23. package/dist/cjs/clients/solana.cjs +322 -0
  24. package/dist/cjs/clients/solana.native.js +511 -0
  25. package/dist/cjs/clients/solana.native.js.map +1 -0
  26. package/dist/cjs/clients/solanaMessage.cjs +38 -0
  27. package/dist/cjs/clients/solanaMessage.native.js +44 -0
  28. package/dist/cjs/clients/solanaMessage.native.js.map +1 -0
  29. package/dist/cjs/clients/sui.cjs +46 -0
  30. package/dist/cjs/clients/sui.native.js +51 -0
  31. package/dist/cjs/clients/sui.native.js.map +1 -0
  32. package/dist/cjs/clients/types.cjs +37 -0
  33. package/dist/cjs/clients/types.native.js +160 -0
  34. package/dist/cjs/clients/types.native.js.map +1 -0
  35. package/dist/cjs/clients/useSolanaClient.cjs +50 -0
  36. package/dist/cjs/clients/useSolanaClient.native.js +57 -0
  37. package/dist/cjs/clients/useSolanaClient.native.js.map +1 -0
  38. package/dist/cjs/clients/walletStandard.cjs +63 -0
  39. package/dist/cjs/clients/walletStandard.native.js +71 -0
  40. package/dist/cjs/clients/walletStandard.native.js.map +1 -0
  41. package/dist/cjs/connectkit/components/Common/ConnectorList/index.cjs +33 -5
  42. package/dist/cjs/connectkit/components/Common/ConnectorList/index.native.js +38 -5
  43. package/dist/cjs/connectkit/components/Common/ConnectorList/index.native.js.map +1 -1
  44. package/dist/cjs/connectkit/components/ConnectButton/index.cjs +5 -0
  45. package/dist/cjs/connectkit/components/ConnectButton/index.native.js +5 -0
  46. package/dist/cjs/connectkit/components/ConnectButton/index.native.js.map +1 -1
  47. package/dist/cjs/connectkit/components/ConnectModal/ConnectWithInjector/index.cjs +9 -4
  48. package/dist/cjs/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js +12 -7
  49. package/dist/cjs/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js.map +1 -1
  50. package/dist/cjs/connectkit/connectors/walletAdapterConnector.cjs +2 -0
  51. package/dist/cjs/connectkit/connectors/walletAdapterConnector.native.js +2 -0
  52. package/dist/cjs/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
  53. package/dist/cjs/connectkit/index.cjs +5 -0
  54. package/dist/cjs/connectkit/index.native.js +5 -0
  55. package/dist/cjs/connectkit/index.native.js.map +1 -1
  56. package/dist/cjs/connectkit/openConnector/context.cjs +146 -0
  57. package/dist/cjs/connectkit/openConnector/context.native.js +188 -0
  58. package/dist/cjs/connectkit/openConnector/context.native.js.map +1 -0
  59. package/dist/cjs/connectkit/openConnector/device.cjs +42 -0
  60. package/dist/cjs/connectkit/openConnector/device.native.js +51 -0
  61. package/dist/cjs/connectkit/openConnector/device.native.js.map +1 -0
  62. package/dist/cjs/connectkit/openConnector/index.cjs +35 -0
  63. package/dist/cjs/connectkit/openConnector/index.native.js +38 -0
  64. package/dist/cjs/connectkit/openConnector/index.native.js.map +1 -0
  65. package/dist/cjs/connectkit/openConnector/launcher.cjs +133 -0
  66. package/dist/cjs/connectkit/openConnector/launcher.native.js +158 -0
  67. package/dist/cjs/connectkit/openConnector/launcher.native.js.map +1 -0
  68. package/dist/cjs/connectkit/screens.cjs +1 -10
  69. package/dist/cjs/connectkit/screens.native.js +1 -12
  70. package/dist/cjs/connectkit/screens.native.js.map +1 -1
  71. package/dist/cjs/connectkit/siwe/SIWEProvider.cjs +4 -5
  72. package/dist/cjs/connectkit/siwe/SIWEProvider.native.js +4 -5
  73. package/dist/cjs/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  74. package/dist/cjs/connectkit/siwe/connectIntent.cjs +9 -5
  75. package/dist/cjs/connectkit/siwe/connectIntent.native.js +10 -3
  76. package/dist/cjs/connectkit/siwe/connectIntent.native.js.map +1 -1
  77. package/dist/cjs/connectkit/useWeb3Modal.cjs +21 -0
  78. package/dist/cjs/connectkit/useWeb3Modal.native.js +22 -0
  79. package/dist/cjs/connectkit/useWeb3Modal.native.js.map +1 -1
  80. package/dist/cjs/connectkit/web3Bridge.cjs +4 -1
  81. package/dist/cjs/connectkit/web3Bridge.native.js +4 -1
  82. package/dist/cjs/connectkit/web3Bridge.native.js.map +1 -1
  83. package/dist/cjs/connectkit/web3Provider.native.js.map +1 -1
  84. package/dist/cjs/index.cjs +2 -1
  85. package/dist/cjs/index.native.js +1 -0
  86. package/dist/cjs/index.native.js.map +1 -1
  87. package/dist/cjs/solana.cjs +41 -0
  88. package/dist/cjs/solana.native.js +44 -0
  89. package/dist/cjs/solana.native.js.map +1 -0
  90. package/dist/esm/clients/adapter.mjs +8 -0
  91. package/dist/esm/clients/adapter.mjs.map +1 -0
  92. package/dist/esm/clients/adapter.native.js +8 -0
  93. package/dist/esm/clients/adapter.native.js.map +1 -0
  94. package/dist/esm/clients/bitcoin.mjs +21 -0
  95. package/dist/esm/clients/bitcoin.mjs.map +1 -0
  96. package/dist/esm/clients/bitcoin.native.js +23 -0
  97. package/dist/esm/clients/bitcoin.native.js.map +1 -0
  98. package/dist/esm/clients/connector.mjs +20 -0
  99. package/dist/esm/clients/connector.mjs.map +1 -0
  100. package/dist/esm/clients/connector.native.js +21 -0
  101. package/dist/esm/clients/connector.native.js.map +1 -0
  102. package/dist/esm/clients/evm.mjs +146 -0
  103. package/dist/esm/clients/evm.mjs.map +1 -0
  104. package/dist/esm/clients/evm.native.js +170 -0
  105. package/dist/esm/clients/evm.native.js.map +1 -0
  106. package/dist/esm/clients/gpg.mjs +3 -0
  107. package/dist/esm/clients/gpg.mjs.map +1 -0
  108. package/dist/esm/clients/gpg.native.js +3 -0
  109. package/dist/esm/clients/gpg.native.js.map +1 -0
  110. package/dist/esm/clients/hooks.mjs +51 -0
  111. package/dist/esm/clients/hooks.mjs.map +1 -0
  112. package/dist/esm/clients/hooks.native.js +55 -0
  113. package/dist/esm/clients/hooks.native.js.map +1 -0
  114. package/dist/esm/clients/index.mjs +11 -0
  115. package/dist/esm/clients/index.mjs.map +1 -0
  116. package/dist/esm/clients/index.native.js +11 -0
  117. package/dist/esm/clients/index.native.js.map +1 -0
  118. package/dist/esm/clients/solana.mjs +289 -0
  119. package/dist/esm/clients/solana.mjs.map +1 -0
  120. package/dist/esm/clients/solana.native.js +475 -0
  121. package/dist/esm/clients/solana.native.js.map +1 -0
  122. package/dist/esm/clients/solanaMessage.mjs +13 -0
  123. package/dist/esm/clients/solanaMessage.mjs.map +1 -0
  124. package/dist/esm/clients/solanaMessage.native.js +16 -0
  125. package/dist/esm/clients/solanaMessage.native.js.map +1 -0
  126. package/dist/esm/clients/sui.mjs +21 -0
  127. package/dist/esm/clients/sui.mjs.map +1 -0
  128. package/dist/esm/clients/sui.native.js +23 -0
  129. package/dist/esm/clients/sui.native.js.map +1 -0
  130. package/dist/esm/clients/types.mjs +12 -0
  131. package/dist/esm/clients/types.mjs.map +1 -0
  132. package/dist/esm/clients/types.native.js +132 -0
  133. package/dist/esm/clients/types.native.js.map +1 -0
  134. package/dist/esm/clients/useSolanaClient.mjs +25 -0
  135. package/dist/esm/clients/useSolanaClient.mjs.map +1 -0
  136. package/dist/esm/clients/useSolanaClient.native.js +29 -0
  137. package/dist/esm/clients/useSolanaClient.native.js.map +1 -0
  138. package/dist/esm/clients/walletStandard.mjs +33 -0
  139. package/dist/esm/clients/walletStandard.mjs.map +1 -0
  140. package/dist/esm/clients/walletStandard.native.js +38 -0
  141. package/dist/esm/clients/walletStandard.native.js.map +1 -0
  142. package/dist/esm/connectkit/components/Common/ConnectorList/index.mjs +34 -6
  143. package/dist/esm/connectkit/components/Common/ConnectorList/index.mjs.map +1 -1
  144. package/dist/esm/connectkit/components/Common/ConnectorList/index.native.js +39 -6
  145. package/dist/esm/connectkit/components/Common/ConnectorList/index.native.js.map +1 -1
  146. package/dist/esm/connectkit/components/ConnectButton/index.mjs +5 -0
  147. package/dist/esm/connectkit/components/ConnectButton/index.mjs.map +1 -1
  148. package/dist/esm/connectkit/components/ConnectButton/index.native.js +5 -0
  149. package/dist/esm/connectkit/components/ConnectButton/index.native.js.map +1 -1
  150. package/dist/esm/connectkit/components/ConnectModal/ConnectWithInjector/index.mjs +9 -4
  151. package/dist/esm/connectkit/components/ConnectModal/ConnectWithInjector/index.mjs.map +1 -1
  152. package/dist/esm/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js +12 -7
  153. package/dist/esm/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js.map +1 -1
  154. package/dist/esm/connectkit/connectors/walletAdapterConnector.mjs +2 -0
  155. package/dist/esm/connectkit/connectors/walletAdapterConnector.mjs.map +1 -1
  156. package/dist/esm/connectkit/connectors/walletAdapterConnector.native.js +2 -0
  157. package/dist/esm/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
  158. package/dist/esm/connectkit/index.mjs +3 -1
  159. package/dist/esm/connectkit/index.mjs.map +1 -1
  160. package/dist/esm/connectkit/index.native.js +3 -1
  161. package/dist/esm/connectkit/index.native.js.map +1 -1
  162. package/dist/esm/connectkit/openConnector/context.mjs +118 -0
  163. package/dist/esm/connectkit/openConnector/context.mjs.map +1 -0
  164. package/dist/esm/connectkit/openConnector/context.native.js +146 -0
  165. package/dist/esm/connectkit/openConnector/context.native.js.map +1 -0
  166. package/dist/esm/connectkit/openConnector/device.mjs +16 -0
  167. package/dist/esm/connectkit/openConnector/device.mjs.map +1 -0
  168. package/dist/esm/connectkit/openConnector/device.native.js +22 -0
  169. package/dist/esm/connectkit/openConnector/device.native.js.map +1 -0
  170. package/dist/esm/connectkit/openConnector/index.mjs +4 -0
  171. package/dist/esm/connectkit/openConnector/index.mjs.map +1 -0
  172. package/dist/esm/connectkit/openConnector/index.native.js +4 -0
  173. package/dist/esm/connectkit/openConnector/index.native.js.map +1 -0
  174. package/dist/esm/connectkit/openConnector/launcher.mjs +106 -0
  175. package/dist/esm/connectkit/openConnector/launcher.mjs.map +1 -0
  176. package/dist/esm/connectkit/openConnector/launcher.native.js +128 -0
  177. package/dist/esm/connectkit/openConnector/launcher.native.js.map +1 -0
  178. package/dist/esm/connectkit/screens.mjs +2 -11
  179. package/dist/esm/connectkit/screens.mjs.map +1 -1
  180. package/dist/esm/connectkit/screens.native.js +2 -13
  181. package/dist/esm/connectkit/screens.native.js.map +1 -1
  182. package/dist/esm/connectkit/siwe/SIWEProvider.mjs +4 -5
  183. package/dist/esm/connectkit/siwe/SIWEProvider.mjs.map +1 -1
  184. package/dist/esm/connectkit/siwe/SIWEProvider.native.js +4 -5
  185. package/dist/esm/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  186. package/dist/esm/connectkit/siwe/connectIntent.mjs +9 -6
  187. package/dist/esm/connectkit/siwe/connectIntent.mjs.map +1 -1
  188. package/dist/esm/connectkit/siwe/connectIntent.native.js +10 -4
  189. package/dist/esm/connectkit/siwe/connectIntent.native.js.map +1 -1
  190. package/dist/esm/connectkit/useWeb3Modal.mjs +22 -1
  191. package/dist/esm/connectkit/useWeb3Modal.mjs.map +1 -1
  192. package/dist/esm/connectkit/useWeb3Modal.native.js +23 -1
  193. package/dist/esm/connectkit/useWeb3Modal.native.js.map +1 -1
  194. package/dist/esm/connectkit/web3Bridge.mjs +4 -1
  195. package/dist/esm/connectkit/web3Bridge.mjs.map +1 -1
  196. package/dist/esm/connectkit/web3Bridge.native.js +4 -1
  197. package/dist/esm/connectkit/web3Bridge.native.js.map +1 -1
  198. package/dist/esm/connectkit/web3Provider.mjs.map +1 -1
  199. package/dist/esm/connectkit/web3Provider.native.js.map +1 -1
  200. package/dist/esm/index.mjs +1 -0
  201. package/dist/esm/index.mjs.map +1 -1
  202. package/dist/esm/index.native.js +1 -0
  203. package/dist/esm/index.native.js.map +1 -1
  204. package/dist/esm/solana.mjs +5 -0
  205. package/dist/esm/solana.mjs.map +1 -0
  206. package/dist/esm/solana.native.js +5 -0
  207. package/dist/esm/solana.native.js.map +1 -0
  208. package/dist/jsx/clients/adapter.mjs +8 -0
  209. package/dist/jsx/clients/adapter.mjs.map +1 -0
  210. package/dist/jsx/clients/adapter.native.js +36 -0
  211. package/dist/jsx/clients/adapter.native.js.map +1 -0
  212. package/dist/jsx/clients/bitcoin.mjs +21 -0
  213. package/dist/jsx/clients/bitcoin.mjs.map +1 -0
  214. package/dist/jsx/clients/bitcoin.native.js +51 -0
  215. package/dist/jsx/clients/bitcoin.native.js.map +1 -0
  216. package/dist/jsx/clients/connector.mjs +20 -0
  217. package/dist/jsx/clients/connector.mjs.map +1 -0
  218. package/dist/jsx/clients/connector.native.js +49 -0
  219. package/dist/jsx/clients/connector.native.js.map +1 -0
  220. package/dist/jsx/clients/evm.mjs +146 -0
  221. package/dist/jsx/clients/evm.mjs.map +1 -0
  222. package/dist/jsx/clients/evm.native.js +198 -0
  223. package/dist/jsx/clients/evm.native.js.map +1 -0
  224. package/dist/jsx/clients/gpg.mjs +3 -0
  225. package/dist/jsx/clients/gpg.mjs.map +1 -0
  226. package/dist/jsx/clients/gpg.native.js +34 -0
  227. package/dist/jsx/clients/gpg.native.js.map +1 -0
  228. package/dist/jsx/clients/hooks.mjs +51 -0
  229. package/dist/jsx/clients/hooks.mjs.map +1 -0
  230. package/dist/jsx/clients/hooks.native.js +85 -0
  231. package/dist/jsx/clients/hooks.native.js.map +1 -0
  232. package/dist/jsx/clients/index.mjs +11 -0
  233. package/dist/jsx/clients/index.mjs.map +1 -0
  234. package/dist/jsx/clients/index.native.js +52 -0
  235. package/dist/jsx/clients/index.native.js.map +1 -0
  236. package/dist/jsx/clients/solana.mjs +289 -0
  237. package/dist/jsx/clients/solana.mjs.map +1 -0
  238. package/dist/jsx/clients/solana.native.js +511 -0
  239. package/dist/jsx/clients/solana.native.js.map +1 -0
  240. package/dist/jsx/clients/solanaMessage.mjs +13 -0
  241. package/dist/jsx/clients/solanaMessage.mjs.map +1 -0
  242. package/dist/jsx/clients/solanaMessage.native.js +44 -0
  243. package/dist/jsx/clients/solanaMessage.native.js.map +1 -0
  244. package/dist/jsx/clients/sui.mjs +21 -0
  245. package/dist/jsx/clients/sui.mjs.map +1 -0
  246. package/dist/jsx/clients/sui.native.js +51 -0
  247. package/dist/jsx/clients/sui.native.js.map +1 -0
  248. package/dist/jsx/clients/types.mjs +12 -0
  249. package/dist/jsx/clients/types.mjs.map +1 -0
  250. package/dist/jsx/clients/types.native.js +160 -0
  251. package/dist/jsx/clients/types.native.js.map +1 -0
  252. package/dist/jsx/clients/useSolanaClient.mjs +25 -0
  253. package/dist/jsx/clients/useSolanaClient.mjs.map +1 -0
  254. package/dist/jsx/clients/useSolanaClient.native.js +57 -0
  255. package/dist/jsx/clients/useSolanaClient.native.js.map +1 -0
  256. package/dist/jsx/clients/walletStandard.mjs +33 -0
  257. package/dist/jsx/clients/walletStandard.mjs.map +1 -0
  258. package/dist/jsx/clients/walletStandard.native.js +71 -0
  259. package/dist/jsx/clients/walletStandard.native.js.map +1 -0
  260. package/dist/jsx/connectkit/components/Common/ConnectorList/index.mjs +34 -6
  261. package/dist/jsx/connectkit/components/Common/ConnectorList/index.mjs.map +1 -1
  262. package/dist/jsx/connectkit/components/Common/ConnectorList/index.native.js +38 -5
  263. package/dist/jsx/connectkit/components/Common/ConnectorList/index.native.js.map +1 -1
  264. package/dist/jsx/connectkit/components/ConnectButton/index.mjs +5 -0
  265. package/dist/jsx/connectkit/components/ConnectButton/index.mjs.map +1 -1
  266. package/dist/jsx/connectkit/components/ConnectButton/index.native.js +5 -0
  267. package/dist/jsx/connectkit/components/ConnectButton/index.native.js.map +1 -1
  268. package/dist/jsx/connectkit/components/ConnectModal/ConnectWithInjector/index.mjs +9 -4
  269. package/dist/jsx/connectkit/components/ConnectModal/ConnectWithInjector/index.mjs.map +1 -1
  270. package/dist/jsx/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js +12 -7
  271. package/dist/jsx/connectkit/components/ConnectModal/ConnectWithInjector/index.native.js.map +1 -1
  272. package/dist/jsx/connectkit/connectors/walletAdapterConnector.mjs +2 -0
  273. package/dist/jsx/connectkit/connectors/walletAdapterConnector.mjs.map +1 -1
  274. package/dist/jsx/connectkit/connectors/walletAdapterConnector.native.js +2 -0
  275. package/dist/jsx/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
  276. package/dist/jsx/connectkit/index.mjs +3 -1
  277. package/dist/jsx/connectkit/index.mjs.map +1 -1
  278. package/dist/jsx/connectkit/index.native.js +5 -0
  279. package/dist/jsx/connectkit/index.native.js.map +1 -1
  280. package/dist/jsx/connectkit/openConnector/context.mjs +118 -0
  281. package/dist/jsx/connectkit/openConnector/context.mjs.map +1 -0
  282. package/dist/jsx/connectkit/openConnector/context.native.js +188 -0
  283. package/dist/jsx/connectkit/openConnector/context.native.js.map +1 -0
  284. package/dist/jsx/connectkit/openConnector/device.mjs +16 -0
  285. package/dist/jsx/connectkit/openConnector/device.mjs.map +1 -0
  286. package/dist/jsx/connectkit/openConnector/device.native.js +51 -0
  287. package/dist/jsx/connectkit/openConnector/device.native.js.map +1 -0
  288. package/dist/jsx/connectkit/openConnector/index.mjs +4 -0
  289. package/dist/jsx/connectkit/openConnector/index.mjs.map +1 -0
  290. package/dist/jsx/connectkit/openConnector/index.native.js +38 -0
  291. package/dist/jsx/connectkit/openConnector/index.native.js.map +1 -0
  292. package/dist/jsx/connectkit/openConnector/launcher.mjs +106 -0
  293. package/dist/jsx/connectkit/openConnector/launcher.mjs.map +1 -0
  294. package/dist/jsx/connectkit/openConnector/launcher.native.js +158 -0
  295. package/dist/jsx/connectkit/openConnector/launcher.native.js.map +1 -0
  296. package/dist/jsx/connectkit/screens.mjs +2 -11
  297. package/dist/jsx/connectkit/screens.mjs.map +1 -1
  298. package/dist/jsx/connectkit/screens.native.js +1 -12
  299. package/dist/jsx/connectkit/screens.native.js.map +1 -1
  300. package/dist/jsx/connectkit/siwe/SIWEProvider.mjs +4 -5
  301. package/dist/jsx/connectkit/siwe/SIWEProvider.mjs.map +1 -1
  302. package/dist/jsx/connectkit/siwe/SIWEProvider.native.js +4 -5
  303. package/dist/jsx/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  304. package/dist/jsx/connectkit/siwe/connectIntent.mjs +9 -6
  305. package/dist/jsx/connectkit/siwe/connectIntent.mjs.map +1 -1
  306. package/dist/jsx/connectkit/siwe/connectIntent.native.js +10 -3
  307. package/dist/jsx/connectkit/siwe/connectIntent.native.js.map +1 -1
  308. package/dist/jsx/connectkit/useWeb3Modal.mjs +22 -1
  309. package/dist/jsx/connectkit/useWeb3Modal.mjs.map +1 -1
  310. package/dist/jsx/connectkit/useWeb3Modal.native.js +22 -0
  311. package/dist/jsx/connectkit/useWeb3Modal.native.js.map +1 -1
  312. package/dist/jsx/connectkit/web3Bridge.mjs +4 -1
  313. package/dist/jsx/connectkit/web3Bridge.mjs.map +1 -1
  314. package/dist/jsx/connectkit/web3Bridge.native.js +4 -1
  315. package/dist/jsx/connectkit/web3Bridge.native.js.map +1 -1
  316. package/dist/jsx/connectkit/web3Provider.mjs.map +1 -1
  317. package/dist/jsx/connectkit/web3Provider.native.js.map +1 -1
  318. package/dist/jsx/index.js +1 -0
  319. package/dist/jsx/index.js.map +1 -1
  320. package/dist/jsx/index.mjs +1 -0
  321. package/dist/jsx/index.mjs.map +1 -1
  322. package/dist/jsx/index.native.js +1 -0
  323. package/dist/jsx/index.native.js.map +1 -1
  324. package/dist/jsx/solana.mjs +5 -0
  325. package/dist/jsx/solana.mjs.map +1 -0
  326. package/dist/jsx/solana.native.js +44 -0
  327. package/dist/jsx/solana.native.js.map +1 -0
  328. package/package.json +14 -6
  329. package/src/clients/adapter.ts +13 -0
  330. package/src/clients/bitcoin.ts +42 -0
  331. package/src/clients/connector.spec.ts +78 -0
  332. package/src/clients/connector.ts +36 -0
  333. package/src/clients/evm.spec.ts +265 -0
  334. package/src/clients/evm.ts +223 -0
  335. package/src/clients/gpg.spec.ts +169 -0
  336. package/src/clients/gpg.ts +8 -0
  337. package/src/clients/hooks.spec.tsx +113 -0
  338. package/src/clients/hooks.ts +51 -0
  339. package/src/clients/index.ts +40 -0
  340. package/src/clients/solana.spec.ts +444 -0
  341. package/src/clients/solana.ts +465 -0
  342. package/src/clients/solanaMessage.ts +34 -0
  343. package/src/clients/sui.ts +42 -0
  344. package/src/clients/types.ts +40 -0
  345. package/src/clients/useSolanaClient.ts +31 -0
  346. package/src/clients/walletStandard.ts +87 -0
  347. package/src/connectkit/components/Common/ConnectorList/index.tsx +30 -2
  348. package/src/connectkit/components/ConnectButton/index.tsx +5 -0
  349. package/src/connectkit/components/ConnectModal/ConnectWithInjector/index.tsx +13 -8
  350. package/src/connectkit/connectors/walletAdapterConnector.ts +2 -0
  351. package/src/connectkit/index.ts +8 -0
  352. package/src/connectkit/openConnector/context.tsx +176 -0
  353. package/src/connectkit/openConnector/device.spec.ts +86 -0
  354. package/src/connectkit/openConnector/device.ts +37 -0
  355. package/src/connectkit/openConnector/index.ts +18 -0
  356. package/src/connectkit/openConnector/launcher.spec.ts +325 -0
  357. package/src/connectkit/openConnector/launcher.ts +203 -0
  358. package/src/connectkit/openConnector/modal.spec.tsx +330 -0
  359. package/src/connectkit/screens.tsx +2 -11
  360. package/src/connectkit/siwe/SIWEProvider.spec.tsx +112 -0
  361. package/src/connectkit/siwe/SIWEProvider.tsx +6 -10
  362. package/src/connectkit/siwe/connectIntent.spec.ts +90 -0
  363. package/src/connectkit/siwe/connectIntent.ts +19 -6
  364. package/src/connectkit/useWeb3Modal.ts +25 -1
  365. package/src/connectkit/web3Bridge.tsx +4 -1
  366. package/src/connectkit/web3Provider.tsx +4 -1
  367. package/src/index.ts +4 -0
  368. package/src/solana.ts +30 -0
  369. package/types/clients/adapter.d.ts +5 -0
  370. package/types/clients/adapter.d.ts.map +1 -0
  371. package/types/clients/bitcoin.d.ts +21 -0
  372. package/types/clients/bitcoin.d.ts.map +1 -0
  373. package/types/clients/connector.d.ts +14 -0
  374. package/types/clients/connector.d.ts.map +1 -0
  375. package/types/clients/evm.d.ts +68 -0
  376. package/types/clients/evm.d.ts.map +1 -0
  377. package/types/clients/gpg.d.ts +2 -0
  378. package/types/clients/gpg.d.ts.map +1 -0
  379. package/types/clients/hooks.d.ts +16 -0
  380. package/types/clients/hooks.d.ts.map +1 -0
  381. package/types/clients/index.d.ts +10 -0
  382. package/types/clients/index.d.ts.map +1 -0
  383. package/types/clients/solana.d.ts +111 -0
  384. package/types/clients/solana.d.ts.map +1 -0
  385. package/types/clients/solanaMessage.d.ts +18 -0
  386. package/types/clients/solanaMessage.d.ts.map +1 -0
  387. package/types/clients/sui.d.ts +21 -0
  388. package/types/clients/sui.d.ts.map +1 -0
  389. package/types/clients/types.d.ts +27 -0
  390. package/types/clients/types.d.ts.map +1 -0
  391. package/types/clients/useSolanaClient.d.ts +11 -0
  392. package/types/clients/useSolanaClient.d.ts.map +1 -0
  393. package/types/clients/walletStandard.d.ts +63 -0
  394. package/types/clients/walletStandard.d.ts.map +1 -0
  395. package/types/connectkit/components/Common/ConnectorList/index.d.ts.map +1 -1
  396. package/types/connectkit/components/ConnectButton/index.d.ts.map +1 -1
  397. package/types/connectkit/components/ConnectModal/ConnectWithInjector/index.d.ts.map +1 -1
  398. package/types/connectkit/connectors/walletAdapterConnector.d.ts.map +1 -1
  399. package/types/connectkit/index.d.ts +2 -0
  400. package/types/connectkit/index.d.ts.map +1 -1
  401. package/types/connectkit/openConnector/context.d.ts +48 -0
  402. package/types/connectkit/openConnector/context.d.ts.map +1 -0
  403. package/types/connectkit/openConnector/device.d.ts +18 -0
  404. package/types/connectkit/openConnector/device.d.ts.map +1 -0
  405. package/types/connectkit/openConnector/index.d.ts +3 -0
  406. package/types/connectkit/openConnector/index.d.ts.map +1 -0
  407. package/types/connectkit/openConnector/launcher.d.ts +64 -0
  408. package/types/connectkit/openConnector/launcher.d.ts.map +1 -0
  409. package/types/connectkit/screens.d.ts.map +1 -1
  410. package/types/connectkit/siwe/SIWEProvider.d.ts.map +1 -1
  411. package/types/connectkit/siwe/connectIntent.d.ts +8 -3
  412. package/types/connectkit/siwe/connectIntent.d.ts.map +1 -1
  413. package/types/connectkit/useWeb3Modal.d.ts +16 -0
  414. package/types/connectkit/useWeb3Modal.d.ts.map +1 -1
  415. package/types/connectkit/web3Bridge.d.ts.map +1 -1
  416. package/types/connectkit/web3Provider.d.ts +4 -1
  417. package/types/connectkit/web3Provider.d.ts.map +1 -1
  418. package/types/index.d.ts +1 -0
  419. package/types/index.d.ts.map +1 -1
  420. package/types/solana.d.ts +4 -0
  421. package/types/solana.d.ts.map +1 -0
@@ -0,0 +1,87 @@
1
+ // Minimal Wallet Standard plumbing for Solana: the registry handshake and the
2
+ // feature shapes the client calls. Structural types instead of @wallet-standard/*
3
+ // so the page bundle carries no extra package; Phantom, Solflare and Backpack all
4
+ // register this way.
5
+
6
+ export interface StandardWalletAccount {
7
+ readonly address: string;
8
+ readonly publicKey: Uint8Array;
9
+ readonly chains: readonly string[];
10
+ readonly features: readonly string[];
11
+ }
12
+
13
+ export interface StandardWallet {
14
+ readonly name: string;
15
+ readonly icon?: string;
16
+ readonly chains: readonly string[];
17
+ readonly accounts: readonly StandardWalletAccount[];
18
+ readonly features: Readonly<Record<string, unknown>>;
19
+ }
20
+
21
+ export const SolanaSignMessage = "solana:signMessage";
22
+ export const SolanaSignTransaction = "solana:signTransaction";
23
+ export const SolanaSignAndSendTransaction = "solana:signAndSendTransaction";
24
+ export const StandardConnect = "standard:connect";
25
+
26
+ export interface SolanaSignMessageFeature {
27
+ signMessage(
28
+ ...inputs: { account: StandardWalletAccount; message: Uint8Array }[]
29
+ ): Promise<{ signedMessage: Uint8Array; signature: Uint8Array }[]>;
30
+ }
31
+
32
+ export interface SolanaSignTransactionFeature {
33
+ signTransaction(
34
+ ...inputs: { account: StandardWalletAccount; transaction: Uint8Array; chain?: string }[]
35
+ ): Promise<{ signedTransaction: Uint8Array }[]>;
36
+ }
37
+
38
+ export interface SolanaSignAndSendTransactionFeature {
39
+ signAndSendTransaction(
40
+ ...inputs: {
41
+ account: StandardWalletAccount;
42
+ transaction: Uint8Array;
43
+ chain: string;
44
+ options?: { commitment?: "processed" | "confirmed" | "finalized"; skipPreflight?: boolean };
45
+ }[]
46
+ ): Promise<{ signature: Uint8Array }[]>;
47
+ }
48
+
49
+ export interface StandardConnectFeature {
50
+ connect(input?: { silent?: boolean }): Promise<{ accounts: readonly StandardWalletAccount[] }>;
51
+ }
52
+
53
+ /**
54
+ * Every wallet registered with the Wallet Standard right now. Wallets answer
55
+ * `app-ready` synchronously, so this can be called again to pick up late ones.
56
+ */
57
+ export function getStandardWallets(): StandardWallet[] {
58
+ if (typeof window === "undefined") return [];
59
+ const wallets: StandardWallet[] = [];
60
+ const api = {
61
+ register: (...registered: StandardWallet[]) => {
62
+ wallets.push(...registered);
63
+ return () => {};
64
+ },
65
+ };
66
+ const onRegister = (event: Event) => {
67
+ try {
68
+ ((event as CustomEvent).detail as (a: typeof api) => void)(api);
69
+ } catch {
70
+ // a wallet that throws during registration is simply not offered
71
+ }
72
+ };
73
+ window.addEventListener("wallet-standard:register-wallet", onRegister);
74
+ try {
75
+ window.dispatchEvent(new CustomEvent("wallet-standard:app-ready", { detail: api }));
76
+ } finally {
77
+ window.removeEventListener("wallet-standard:register-wallet", onRegister);
78
+ }
79
+ return [...new Set(wallets)];
80
+ }
81
+
82
+ /** Wallets that can sign Solana transactions. */
83
+ export function getSolanaWallets(): StandardWallet[] {
84
+ return getStandardWallets().filter(
85
+ (wallet) => wallet.features[SolanaSignTransaction] && wallet.features[StandardConnect],
86
+ );
87
+ }
@@ -10,6 +10,11 @@ import {
10
10
  isMetaMaskConnector,
11
11
  isPortoConnector,
12
12
  isWalletConnectConnector,
13
+ resolveListEntries,
14
+ useModalState,
15
+ useScreenRegistry,
16
+ type ScreenDef,
17
+ type ScreenListEntry,
13
18
  } from "@multiplatform.one/connectkit";
14
19
 
15
20
  import {
@@ -51,6 +56,9 @@ const ConnectorList = () => {
51
56
  const { lastConnectorId } = useLastConnector();
52
57
  const aaveAccountConnector = useAaveAccountConnector();
53
58
  const [expanded, setExpanded] = useState<string | null>(null);
59
+ const { screens } = useScreenRegistry();
60
+ const modalState = useModalState();
61
+ const screenEntries = resolveListEntries(screens, modalState);
54
62
 
55
63
  const filteredWallets = wallets.filter((wallet) => wallet.id !== aaveAccountConnector?.id);
56
64
 
@@ -79,7 +87,7 @@ const ConnectorList = () => {
79
87
  }
80
88
  }
81
89
 
82
- if (groups.length === 0) {
90
+ if (groups.length === 0 && screenEntries.length === 0) {
83
91
  return (
84
92
  <ScrollArea mobileDirection={"horizontal"}>
85
93
  <Alert error>No connectors found in ConnectKit config.</Alert>
@@ -111,7 +119,7 @@ const ConnectorList = () => {
111
119
 
112
120
  return (
113
121
  <ScrollArea mobileDirection={"horizontal"}>
114
- <ConnectorsContainer $mobile={isMobile} $totalResults={groups.length}>
122
+ <ConnectorsContainer $mobile={isMobile} $totalResults={groups.length + screenEntries.length}>
115
123
  {groups.map((group) =>
116
124
  group.members.length === 1 ? (
117
125
  <ConnectorItem
@@ -128,6 +136,9 @@ const ConnectorList = () => {
128
136
  />
129
137
  ),
130
138
  )}
139
+ {screenEntries.map((def) => (
140
+ <ScreenEntryItem key={def.id} def={def} />
141
+ ))}
131
142
  </ConnectorsContainer>
132
143
  </ScrollArea>
133
144
  );
@@ -135,6 +146,23 @@ const ConnectorList = () => {
135
146
 
136
147
  export default ConnectorList;
137
148
 
149
+ // A registered screen offered in the list (GPG): tapping it routes to the screen.
150
+ const ScreenEntryItem = ({ def }: { def: ScreenDef & { listEntry: ScreenListEntry } }) => {
151
+ const context = useContext();
152
+ const { name, icon } = def.listEntry;
153
+ return (
154
+ <ConnectorButton
155
+ type="button"
156
+ data-screen-entry={def.id}
157
+ disabled={context.route !== routes.CONNECTORS}
158
+ onClick={() => context.setRoute(def.id)}
159
+ >
160
+ <ConnectorIcon data-shape="squircle">{icon}</ConnectorIcon>
161
+ <ConnectorLabel>{name}</ConnectorLabel>
162
+ </ConnectorButton>
163
+ );
164
+ };
165
+
138
166
  // A collapsed multi-chain wallet row — clicking expands the chain picker.
139
167
  const GroupItem = ({
140
168
  group,
@@ -25,6 +25,7 @@ import { useSIWE } from "../../siwe";
25
25
  import { Chain } from "viem";
26
26
  import { useChainIsSupported } from "../../hooks/useChainIsSupported";
27
27
  import { useEnsFallbackConfig } from "../../hooks/useEnsFallbackConfig";
28
+ import { useConnectorLauncher } from "../../openConnector";
28
29
 
29
30
  const contentVariants: Variants = {
30
31
  initial: {
@@ -123,6 +124,7 @@ const ConnectButtonRenderer: React.FC<ConnectButtonRendererProps> = ({ children
123
124
  const isMounted = useIsMounted();
124
125
  const context = useContext();
125
126
  const { open, setOpen } = useModal();
127
+ const launcher = useConnectorLauncher();
126
128
 
127
129
  const { address, isConnected, chain } = useAccount();
128
130
  const isChainSupported = useChainIsSupported(chain?.id);
@@ -139,6 +141,7 @@ const ConnectButtonRenderer: React.FC<ConnectButtonRendererProps> = ({ children
139
141
  }
140
142
 
141
143
  function show() {
144
+ if (!isConnected && launcher?.openPreferredConnector()) return;
142
145
  setOpen(true);
143
146
  context.setRoute(isConnected ? routes.PROFILE : routes.CONNECTORS);
144
147
  }
@@ -336,11 +339,13 @@ export function ConnectKitButton({
336
339
  const isMounted = useIsMounted();
337
340
 
338
341
  const context = useContext();
342
+ const launcher = useConnectorLauncher();
339
343
 
340
344
  const { isConnected, address, chain } = useAccount();
341
345
  const chainIsSupported = useChainIsSupported(chain?.id);
342
346
 
343
347
  function show() {
348
+ if (!isConnected && launcher?.openPreferredConnector()) return;
344
349
  context.setOpen(true);
345
350
  context.setRoute(isConnected ? routes.PROFILE : routes.CONNECTORS);
346
351
  }
@@ -38,6 +38,7 @@ import { useConnect } from "../../../hooks/useConnect";
38
38
  import { useWallet } from "../../../wallets/useWallets";
39
39
  import { setConnectIntent } from "../../../siwe/connectIntent";
40
40
  import { isEmbeddedDesktopWebview } from "../../../connectors/embeddedDesktop";
41
+ import { useConnectorLauncher } from "../../../openConnector";
41
42
  import CircleSpinner from "./CircleSpinner";
42
43
 
43
44
  export const states = {
@@ -166,6 +167,12 @@ const ConnectWithInjector: React.FC<{
166
167
  };
167
168
  }, [wallet?.connector]);
168
169
 
170
+ // openConnector fires connect() inside the app's own tap, before this screen
171
+ // mounts, so the connector may have announced its deeplink already.
172
+ const launcher = useConnectorLauncher();
173
+ const launchedHere = !!wallet && launcher?.pending?.connector.uid === wallet.connector.uid;
174
+ const deeplink = sdkDeeplink ?? (launchedHere ? launcher?.pendingDeeplink : null) ?? undefined;
175
+
169
176
  const expiryDefault = 9; // Starting at 10 causes layout shifting, better to start at 9
170
177
  const [expiryTimer, setExpiryTimer] = useState<number>(expiryDefault);
171
178
 
@@ -176,7 +183,7 @@ const ConnectWithInjector: React.FC<{
176
183
  const showEmbeddedDesktopMetaMaskQr =
177
184
  !isMobile &&
178
185
  isMetaMaskConnector(wallet?.connector.id) &&
179
- !!sdkDeeplink &&
186
+ !!deeplink &&
180
187
  isEmbeddedDesktopWebview();
181
188
 
182
189
  const extensionUrl = wallet?.downloadUrls?.[browser];
@@ -221,6 +228,8 @@ const ConnectWithInjector: React.FC<{
221
228
  // (ConnectorList shouldConnectImmediately); firing again here would queue a
222
229
  // second SDK request / deeplink into the MetaMask app.
223
230
  if (isMobile && isMetaMaskConnector(wallet?.connector.id)) return;
231
+ // Same when openConnector already fired it inside the app's tap.
232
+ if (launchedHere) return;
224
233
 
225
234
  // UX: Give user time to see the UI before opening the extension
226
235
  connectTimeout = setTimeout(runConnect, 600);
@@ -468,11 +477,7 @@ const ConnectWithInjector: React.FC<{
468
477
  )}
469
478
  </ModalContent>
470
479
  {showEmbeddedDesktopMetaMaskQr && (
471
- <CustomQRCode
472
- value={sdkDeeplink}
473
- image={walletInfo.icon}
474
- imagePosition="center"
475
- />
480
+ <CustomQRCode value={deeplink} image={walletInfo.icon} imagePosition="center" />
476
481
  )}
477
482
  {/* The SDK auto-opens its deeplink, but browsers drop external-
478
483
  protocol navigations whose user activation expired while the
@@ -485,8 +490,8 @@ const ConnectWithInjector: React.FC<{
485
490
  ASWebAuthenticationSession). So once the SDK emits
486
491
  display_uri we render it as a REAL anchor — same-tab,
487
492
  because auth sheets can't open new tabs. */}
488
- {isMobile && isMetaMaskConnector(wallet?.connector.id) && sdkDeeplink && (
489
- <Button href={sdkDeeplink} target="_self">
493
+ {isMobile && isMetaMaskConnector(wallet?.connector.id) && deeplink && (
494
+ <Button href={deeplink} target="_self">
490
495
  Open {walletInfo.name}
491
496
  </Button>
492
497
  )}
@@ -71,6 +71,8 @@ export function walletAdapterConnector(entry: WalletConnectorEntry) {
71
71
  icon: entry.icon,
72
72
  // custom tag read by getConnectorEcosystem()/WalletProps.ecosystem
73
73
  ecosystem: entry.ecosystem,
74
+ // read by clientForConnector() to build the per-chain client
75
+ adapter: entry.adapter,
74
76
 
75
77
  async getProvider() {
76
78
  return provider;
@@ -8,6 +8,14 @@ export { wallets } from "./wallets";
8
8
  // web3's wrapper (generic connectkit useModal + wallet/SIWE openers) keeps the
9
9
  // consumer-facing `useModal` API. The agnostic base lives in ./hooks/useModal.
10
10
  export { useWeb3Modal as useModal } from "./useWeb3Modal";
11
+ export {
12
+ DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS,
13
+ DEFAULT_OPEN_CONNECTOR_FALLBACK_MS,
14
+ type MobileConnectOptions,
15
+ type OpenConnectorOptions,
16
+ type Web3ConnectKitOptions,
17
+ } from "./openConnector";
18
+ export { CONNECT_INTENT_TTL_MS } from "./siwe/connectIntent";
11
19
  export { SIWEProvider, useSIWE, SIWE_NONCE_QUERY_KEY, SIWE_SESSION_QUERY_KEY } from "./siwe";
12
20
  export type { SIWESession, SIWEConfig } from "./siwe";
13
21
 
@@ -0,0 +1,176 @@
1
+ import React, {
2
+ createContext,
3
+ useCallback,
4
+ useContext as useReactContext,
5
+ useEffect,
6
+ useMemo,
7
+ useRef,
8
+ useSyncExternalStore,
9
+ } from "react";
10
+ import { useAccountEffect, type Connector } from "wagmi";
11
+ import {
12
+ routes,
13
+ useContext,
14
+ isMobile,
15
+ type ConnectKitOptions,
16
+ } from "@multiplatform.one/connectkit";
17
+
18
+ import { useConnect } from "../hooks/useConnect";
19
+ import { useConnectors } from "../hooks/useConnectors";
20
+ import { useWallets, type WalletProps } from "../wallets/useWallets";
21
+ import { clearConnectIntent, setConnectIntent } from "../siwe/connectIntent";
22
+ import { defaultOpenConnectorFallbackMs } from "./device";
23
+ import {
24
+ createConnectorLauncher,
25
+ type LauncherDeps,
26
+ type OpenConnectorOptions,
27
+ type PendingConnect,
28
+ } from "./launcher";
29
+
30
+ export type MobileConnectOptions = {
31
+ /**
32
+ * Connector id a phone connects straight to (e.g. `"metaMaskSDK"`): `openSIWE()`
33
+ * and the default ConnectKit button skip the wallet list for it. Desktop keeps
34
+ * the list. A phone here is what connectkit's `isMobile()` reads from the user
35
+ * agent, so iPadOS Safari and Android's "Desktop site", which both send a desktop
36
+ * one, keep the list too.
37
+ */
38
+ preferredConnector?: string;
39
+ /** Passed to `openConnector` for the preferred connector. */
40
+ fallbackMs?: number;
41
+ };
42
+
43
+ /** ConnectKit options as web3's ConnectKitProvider takes them. */
44
+ export type Web3ConnectKitOptions = ConnectKitOptions & {
45
+ mobile?: MobileConnectOptions;
46
+ };
47
+
48
+ export type ConnectorLauncherValue = {
49
+ openConnector: (id: string, options?: OpenConnectorOptions) => void;
50
+ /**
51
+ * On a phone with `mobile.preferredConnector` set, open that connector and
52
+ * return true. Otherwise do nothing and return false.
53
+ */
54
+ openPreferredConnector: () => boolean;
55
+ /** Wallet id `openConnector` is connecting, or null. */
56
+ pendingConnector: string | null;
57
+ /** The pending connect's wallet deeplink, once the connector announced it. */
58
+ pendingDeeplink: string | null;
59
+ /** The pending connect, for screens that must not start a second one. */
60
+ pending: PendingConnect | null;
61
+ };
62
+
63
+ const ConnectorLauncherContext = createContext<ConnectorLauncherValue | null>(null);
64
+
65
+ /** The launcher, or null outside web3's ConnectKitProvider. */
66
+ export function useConnectorLauncher(): ConnectorLauncherValue | null {
67
+ return useReactContext(ConnectorLauncherContext);
68
+ }
69
+
70
+ export function getMobileOptions(options?: ConnectKitOptions): MobileConnectOptions {
71
+ return (options as Web3ConnectKitOptions | undefined)?.mobile ?? {};
72
+ }
73
+
74
+ /**
75
+ * Find the list wallet for a connector id. The list hides the MetaMask SDK row
76
+ * behind an injected MetaMask (EIP-6963 `io.metamask`), so an id that is not in
77
+ * the list resolves through its connector's rdns.
78
+ */
79
+ export function resolveWallet(
80
+ wallets: readonly WalletProps[],
81
+ connectors: readonly Connector[],
82
+ id: string,
83
+ ): WalletProps | undefined {
84
+ const direct = wallets.find((wallet) => wallet.id === id);
85
+ if (direct) return direct;
86
+ const connector = connectors.find((c) => c.id === id);
87
+ if (!connector) return undefined;
88
+ const rdns = connector.rdns === undefined ? [] : [connector.rdns].flat();
89
+ return wallets.find((wallet) => rdns.includes(wallet.id));
90
+ }
91
+
92
+ export const ConnectorLauncherProvider: React.FC<{ children: React.ReactNode }> = ({
93
+ children,
94
+ }) => {
95
+ const context = useContext();
96
+ const wallets = useWallets();
97
+ const { connectAsync } = useConnect();
98
+ const connectors = useConnectors();
99
+
100
+ const depsRef = useRef<LauncherDeps>(null as unknown as LauncherDeps);
101
+ depsRef.current = {
102
+ connect: (connector) => connectAsync({ connector }),
103
+ showConnecting: (walletId) => {
104
+ context.setConnector({ id: walletId });
105
+ context.setRoute(routes.CONNECT);
106
+ context.setOpen(true);
107
+ },
108
+ showList: () => {
109
+ context.setRoute(routes.CONNECTORS);
110
+ context.setOpen(true);
111
+ },
112
+ onFailed: () => clearConnectIntent(),
113
+ };
114
+ const latest = useRef({ wallets, connectors, options: context.options });
115
+ latest.current = { wallets, connectors, options: context.options };
116
+
117
+ const launcher = useMemo(() => createConnectorLauncher(() => depsRef.current), []);
118
+ useEffect(() => () => launcher.cancel(), [launcher]);
119
+ const pending = useSyncExternalStore(launcher.subscribe, launcher.pending, launcher.pending);
120
+
121
+ // The session belongs to the connecting screen it opened. Once the user closes the
122
+ // modal or moves off that screen, a fallback must not pull the list back up.
123
+ const { open, route } = context;
124
+ const shownId = context.connector?.id;
125
+ useEffect(() => {
126
+ if (!pending) return;
127
+ if (!open || route !== routes.CONNECT || shownId !== pending.walletId) launcher.cancel();
128
+ }, [launcher, pending, open, route, shownId]);
129
+
130
+ // Any wallet connecting ends the session, including one the user connected some
131
+ // other way while this connect never answered.
132
+ useAccountEffect({ onConnect: () => launcher.cancel() });
133
+
134
+ const openConnector = useCallback(
135
+ (id: string, options: OpenConnectorOptions = {}) => {
136
+ const { wallets, connectors } = latest.current;
137
+ const wallet = resolveWallet(wallets, connectors, id);
138
+ if (!wallet) {
139
+ context.log(`openConnector: no connector ${id}, showing the wallet list.`);
140
+ depsRef.current.showList();
141
+ return;
142
+ }
143
+ // A phone bounces out to the wallet app and often reloads this page on the
144
+ // way back; the intent is what carries the flow on into signing.
145
+ setConnectIntent();
146
+ launcher.open(wallet.id, wallet.connector, {
147
+ fallbackMs: options.fallbackMs ?? defaultOpenConnectorFallbackMs(),
148
+ });
149
+ },
150
+ // context.log is stable enough for a debug line; the rest is read through refs.
151
+ // eslint-disable-next-line react-hooks/exhaustive-deps
152
+ [launcher],
153
+ );
154
+
155
+ const openPreferredConnector = useCallback(() => {
156
+ const mobile = getMobileOptions(latest.current.options);
157
+ if (!mobile.preferredConnector || !isMobile()) return false;
158
+ openConnector(mobile.preferredConnector, { fallbackMs: mobile.fallbackMs });
159
+ return true;
160
+ }, [openConnector]);
161
+
162
+ const value = useMemo<ConnectorLauncherValue>(
163
+ () => ({
164
+ openConnector,
165
+ openPreferredConnector,
166
+ pendingConnector: pending?.walletId ?? null,
167
+ pendingDeeplink: pending?.deeplink ?? null,
168
+ pending,
169
+ }),
170
+ [openConnector, openPreferredConnector, pending],
171
+ );
172
+
173
+ return (
174
+ <ConnectorLauncherContext.Provider value={value}>{children}</ConnectorLauncherContext.Provider>
175
+ );
176
+ };
@@ -0,0 +1,86 @@
1
+ // @vitest-environment happy-dom
2
+ import { afterEach, describe, expect, it } from "vitest";
3
+
4
+ import { defaultOpenConnectorFallbackMs, isTouchDevice } from "./device";
5
+ import {
6
+ DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS,
7
+ DEFAULT_OPEN_CONNECTOR_FALLBACK_MS,
8
+ } from "./launcher";
9
+
10
+ const IPADOS_SAFARI_UA =
11
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Safari/605.1.15";
12
+ const ANDROID_DESKTOP_SITE_UA =
13
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36";
14
+ const ANDROID_UA =
15
+ "Mozilla/5.0 (Linux; Android 16; Pixel 9) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Mobile Safari/537.36";
16
+ const WINDOWS_UA =
17
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36";
18
+
19
+ const coarse = () => ({ matches: true });
20
+ const fine = () => ({ matches: false });
21
+
22
+ function setNavigator(userAgent: string, maxTouchPoints: number) {
23
+ Object.defineProperty(window.navigator, "userAgent", { value: userAgent, configurable: true });
24
+ Object.defineProperty(window.navigator, "maxTouchPoints", {
25
+ value: maxTouchPoints,
26
+ configurable: true,
27
+ });
28
+ }
29
+
30
+ afterEach(() => {
31
+ setNavigator(WINDOWS_UA, 0);
32
+ });
33
+
34
+ describe("isTouchDevice", () => {
35
+ it("counts iPadOS Safari, which sends a Mac user agent", () => {
36
+ expect(isTouchDevice({ userAgent: IPADOS_SAFARI_UA, maxTouchPoints: 5 }, fine)).toBe(true);
37
+ });
38
+
39
+ it("does not count a Mac", () => {
40
+ expect(isTouchDevice({ userAgent: IPADOS_SAFARI_UA, maxTouchPoints: 0 }, coarse)).toBe(false);
41
+ });
42
+
43
+ it("counts Android's Desktop site: touch points and a coarse primary pointer", () => {
44
+ expect(isTouchDevice({ userAgent: ANDROID_DESKTOP_SITE_UA, maxTouchPoints: 5 }, coarse)).toBe(
45
+ true,
46
+ );
47
+ });
48
+
49
+ it("does not count a touch-screen laptop, whose primary pointer is fine", () => {
50
+ expect(isTouchDevice({ userAgent: WINDOWS_UA, maxTouchPoints: 10 }, fine)).toBe(false);
51
+ });
52
+
53
+ it("is false without a navigator (SSR) or a matchMedia", () => {
54
+ expect(isTouchDevice(null, coarse)).toBe(false);
55
+ expect(isTouchDevice({ userAgent: ANDROID_DESKTOP_SITE_UA, maxTouchPoints: 5 }, null)).toBe(
56
+ false,
57
+ );
58
+ });
59
+
60
+ it("is false when matchMedia throws", () => {
61
+ const throws = () => {
62
+ throw new Error("no media queries");
63
+ };
64
+ expect(isTouchDevice({ userAgent: ANDROID_DESKTOP_SITE_UA, maxTouchPoints: 5 }, throws)).toBe(
65
+ false,
66
+ );
67
+ });
68
+ });
69
+
70
+ describe("defaultOpenConnectorFallbackMs", () => {
71
+ it("is the phone default on a phone", () => {
72
+ setNavigator(ANDROID_UA, 5);
73
+ expect(defaultOpenConnectorFallbackMs()).toBe(DEFAULT_OPEN_CONNECTOR_FALLBACK_MS);
74
+ });
75
+
76
+ it("is the phone default on an iPad that asks for the desktop site", () => {
77
+ setNavigator(IPADOS_SAFARI_UA, 5);
78
+ expect(defaultOpenConnectorFallbackMs()).toBe(DEFAULT_OPEN_CONNECTOR_FALLBACK_MS);
79
+ });
80
+
81
+ it("is still a fallback on desktop, so an explicit call never spins forever", () => {
82
+ setNavigator(WINDOWS_UA, 0);
83
+ expect(defaultOpenConnectorFallbackMs()).toBe(DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS);
84
+ expect(DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS).toBeGreaterThan(0);
85
+ });
86
+ });
@@ -0,0 +1,37 @@
1
+ import { isMobile } from "@multiplatform.one/connectkit";
2
+
3
+ import {
4
+ DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS,
5
+ DEFAULT_OPEN_CONNECTOR_FALLBACK_MS,
6
+ } from "./launcher";
7
+
8
+ type DeviceNavigator = { userAgent?: string; maxTouchPoints?: number };
9
+ type MatchMedia = (query: string) => { matches: boolean };
10
+
11
+ /**
12
+ * A touch device whose browser sends a desktop user agent, which connectkit's
13
+ * `isMobile()` reads as desktop: iPadOS Safari sends a Mac one, and Android's
14
+ * "Desktop site" a Linux one. A Mac reports no touch points, and a laptop's touch
15
+ * screen is not its primary pointer, so neither counts.
16
+ */
17
+ export function isTouchDevice(
18
+ nav: DeviceNavigator | null = typeof navigator === "undefined" ? null : navigator,
19
+ matchMedia: MatchMedia | null = typeof window === "undefined" || !window.matchMedia
20
+ ? null
21
+ : (query) => window.matchMedia(query),
22
+ ): boolean {
23
+ if (!nav || (nav.maxTouchPoints ?? 0) < 2) return false;
24
+ if (/Macintosh/.test(nav.userAgent ?? "")) return true;
25
+ try {
26
+ return matchMedia?.("(pointer: coarse)").matches ?? false;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+
32
+ /** The `fallbackMs` an `openConnector` call without one gets on this device. */
33
+ export function defaultOpenConnectorFallbackMs(): number {
34
+ return isMobile() || isTouchDevice()
35
+ ? DEFAULT_OPEN_CONNECTOR_FALLBACK_MS
36
+ : DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS;
37
+ }
@@ -0,0 +1,18 @@
1
+ export {
2
+ createConnectorLauncher,
3
+ DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS,
4
+ DEFAULT_OPEN_CONNECTOR_FALLBACK_MS,
5
+ type ConnectorLauncher,
6
+ type LauncherDeps,
7
+ type OpenConnectorOptions,
8
+ type PendingConnect,
9
+ } from "./launcher";
10
+ export {
11
+ ConnectorLauncherProvider,
12
+ getMobileOptions,
13
+ resolveWallet,
14
+ useConnectorLauncher,
15
+ type ConnectorLauncherValue,
16
+ type MobileConnectOptions,
17
+ type Web3ConnectKitOptions,
18
+ } from "./context";