@multiplatform.one/web3 7.24.0 → 7.26.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 (363) hide show
  1. package/README.md +33 -0
  2. package/dist/cjs/bridge/AuthBridge.cjs +124 -0
  3. package/dist/cjs/bridge/AuthBridge.native.js +186 -0
  4. package/dist/cjs/bridge/AuthBridge.native.js.map +1 -0
  5. package/dist/cjs/bridge/BridgeClient.cjs +12 -9
  6. package/dist/cjs/bridge/BridgeClient.native.js +17 -12
  7. package/dist/cjs/bridge/BridgeClient.native.js.map +1 -1
  8. package/dist/cjs/bridge/BridgeHost.cjs +11 -3
  9. package/dist/cjs/bridge/BridgeHost.native.js +11 -3
  10. package/dist/cjs/bridge/BridgeHost.native.js.map +1 -1
  11. package/dist/cjs/bridge/GpgBridge.cjs +61 -0
  12. package/dist/cjs/bridge/GpgBridge.native.js +111 -0
  13. package/dist/cjs/bridge/GpgBridge.native.js.map +1 -0
  14. package/dist/cjs/bridge/SuiBridge.cjs +51 -0
  15. package/dist/cjs/bridge/SuiBridge.native.js +99 -0
  16. package/dist/cjs/bridge/SuiBridge.native.js.map +1 -0
  17. package/dist/cjs/bridge/authTypes.cjs +28 -0
  18. package/dist/cjs/bridge/authTypes.native.js +31 -0
  19. package/dist/cjs/bridge/authTypes.native.js.map +1 -0
  20. package/dist/cjs/bridge/core.cjs +65 -0
  21. package/dist/cjs/bridge/core.native.js +68 -0
  22. package/dist/cjs/bridge/core.native.js.map +1 -0
  23. package/dist/cjs/bridge/hosting.cjs +91 -0
  24. package/dist/cjs/bridge/hosting.native.js +117 -0
  25. package/dist/cjs/bridge/hosting.native.js.map +1 -0
  26. package/dist/cjs/bridge/index.cjs +3 -17
  27. package/dist/cjs/bridge/index.native.js +2 -16
  28. package/dist/cjs/bridge/index.native.js.map +1 -1
  29. package/dist/cjs/bridge/nativeHost.cjs +91 -0
  30. package/dist/cjs/bridge/nativeHost.native.js +118 -0
  31. package/dist/cjs/bridge/nativeHost.native.js.map +1 -0
  32. package/dist/cjs/bridge/protocol.cjs +30 -1
  33. package/dist/cjs/bridge/protocol.native.js +147 -1
  34. package/dist/cjs/bridge/protocol.native.js.map +1 -1
  35. package/dist/cjs/core/family.cjs +88 -0
  36. package/dist/cjs/core/family.native.js +115 -0
  37. package/dist/cjs/core/family.native.js.map +1 -0
  38. package/dist/cjs/core/index.cjs +41 -0
  39. package/dist/cjs/core/index.native.js +44 -0
  40. package/dist/cjs/core/index.native.js.map +1 -0
  41. package/dist/cjs/core/message.cjs +89 -0
  42. package/dist/cjs/core/message.native.js +104 -0
  43. package/dist/cjs/core/message.native.js.map +1 -0
  44. package/dist/cjs/core/names.cjs +51 -0
  45. package/dist/cjs/core/names.native.js +95 -0
  46. package/dist/cjs/core/names.native.js.map +1 -0
  47. package/dist/cjs/core/react.cjs +48 -0
  48. package/dist/cjs/core/react.native.js +52 -0
  49. package/dist/cjs/core/react.native.js.map +1 -0
  50. package/dist/cjs/core/store.cjs +450 -0
  51. package/dist/cjs/core/store.native.js +637 -0
  52. package/dist/cjs/core/store.native.js.map +1 -0
  53. package/dist/cjs/core/types.cjs +18 -0
  54. package/dist/cjs/core/types.native.js +21 -0
  55. package/dist/cjs/core/types.native.js.map +1 -0
  56. package/dist/cjs/index.cjs +3 -1
  57. package/dist/cjs/index.native.js +2 -0
  58. package/dist/cjs/index.native.js.map +1 -1
  59. package/dist/cjs/providers/WalletProvider.cjs +2 -0
  60. package/dist/cjs/providers/WalletProvider.native.js +123 -90
  61. package/dist/cjs/providers/WalletProvider.native.js.map +1 -1
  62. package/dist/cjs/providers/index.cjs +1 -0
  63. package/dist/cjs/providers/index.native.js +1 -0
  64. package/dist/cjs/providers/index.native.js.map +1 -1
  65. package/dist/cjs/providers/native/deepLink.cjs +40 -23
  66. package/dist/cjs/providers/native/deepLink.native.js +43 -25
  67. package/dist/cjs/providers/native/deepLink.native.js.map +1 -1
  68. package/dist/cjs/providers/native/inject.cjs +2 -4
  69. package/dist/cjs/providers/native/inject.native.js +2 -4
  70. package/dist/cjs/providers/native/inject.native.js.map +1 -1
  71. package/dist/cjs/providers/walletBridge.cjs +35 -0
  72. package/dist/cjs/providers/walletBridge.native.js +38 -0
  73. package/dist/cjs/providers/walletBridge.native.js.map +1 -0
  74. package/dist/cjs/providers/walletConfig.native.js.map +1 -1
  75. package/dist/esm/bridge/AuthBridge.mjs +99 -0
  76. package/dist/esm/bridge/AuthBridge.mjs.map +1 -0
  77. package/dist/esm/bridge/AuthBridge.native.js +158 -0
  78. package/dist/esm/bridge/AuthBridge.native.js.map +1 -0
  79. package/dist/esm/bridge/BridgeClient.mjs +13 -10
  80. package/dist/esm/bridge/BridgeClient.mjs.map +1 -1
  81. package/dist/esm/bridge/BridgeClient.native.js +18 -13
  82. package/dist/esm/bridge/BridgeClient.native.js.map +1 -1
  83. package/dist/esm/bridge/BridgeHost.mjs +12 -4
  84. package/dist/esm/bridge/BridgeHost.mjs.map +1 -1
  85. package/dist/esm/bridge/BridgeHost.native.js +12 -4
  86. package/dist/esm/bridge/BridgeHost.native.js.map +1 -1
  87. package/dist/esm/bridge/GpgBridge.mjs +36 -0
  88. package/dist/esm/bridge/GpgBridge.mjs.map +1 -0
  89. package/dist/esm/bridge/GpgBridge.native.js +83 -0
  90. package/dist/esm/bridge/GpgBridge.native.js.map +1 -0
  91. package/dist/esm/bridge/SuiBridge.mjs +26 -0
  92. package/dist/esm/bridge/SuiBridge.mjs.map +1 -0
  93. package/dist/esm/bridge/SuiBridge.native.js +71 -0
  94. package/dist/esm/bridge/SuiBridge.native.js.map +1 -0
  95. package/dist/esm/bridge/authTypes.mjs +3 -0
  96. package/dist/esm/bridge/authTypes.mjs.map +1 -0
  97. package/dist/esm/bridge/authTypes.native.js +3 -0
  98. package/dist/esm/bridge/authTypes.native.js.map +1 -0
  99. package/dist/esm/bridge/core.mjs +17 -0
  100. package/dist/esm/bridge/core.mjs.map +1 -0
  101. package/dist/esm/bridge/core.native.js +17 -0
  102. package/dist/esm/bridge/core.native.js.map +1 -0
  103. package/dist/esm/bridge/hosting.mjs +62 -0
  104. package/dist/esm/bridge/hosting.mjs.map +1 -0
  105. package/dist/esm/bridge/hosting.native.js +85 -0
  106. package/dist/esm/bridge/hosting.native.js.map +1 -0
  107. package/dist/esm/bridge/index.mjs +2 -9
  108. package/dist/esm/bridge/index.mjs.map +1 -1
  109. package/dist/esm/bridge/index.native.js +2 -9
  110. package/dist/esm/bridge/index.native.js.map +1 -1
  111. package/dist/esm/bridge/nativeHost.mjs +65 -0
  112. package/dist/esm/bridge/nativeHost.mjs.map +1 -0
  113. package/dist/esm/bridge/nativeHost.native.js +89 -0
  114. package/dist/esm/bridge/nativeHost.native.js.map +1 -0
  115. package/dist/esm/bridge/protocol.mjs +28 -2
  116. package/dist/esm/bridge/protocol.mjs.map +1 -1
  117. package/dist/esm/bridge/protocol.native.js +145 -2
  118. package/dist/esm/bridge/protocol.native.js.map +1 -1
  119. package/dist/esm/core/family.mjs +62 -0
  120. package/dist/esm/core/family.mjs.map +1 -0
  121. package/dist/esm/core/family.native.js +86 -0
  122. package/dist/esm/core/family.native.js.map +1 -0
  123. package/dist/esm/core/index.mjs +7 -0
  124. package/dist/esm/core/index.mjs.map +1 -0
  125. package/dist/esm/core/index.native.js +7 -0
  126. package/dist/esm/core/index.native.js.map +1 -0
  127. package/dist/esm/core/message.mjs +63 -0
  128. package/dist/esm/core/message.mjs.map +1 -0
  129. package/dist/esm/core/message.native.js +75 -0
  130. package/dist/esm/core/message.native.js.map +1 -0
  131. package/dist/esm/core/names.mjs +25 -0
  132. package/dist/esm/core/names.mjs.map +1 -0
  133. package/dist/esm/core/names.native.js +66 -0
  134. package/dist/esm/core/names.native.js.map +1 -0
  135. package/dist/esm/core/react.mjs +21 -0
  136. package/dist/esm/core/react.mjs.map +1 -0
  137. package/dist/esm/core/react.native.js +22 -0
  138. package/dist/esm/core/react.native.js.map +1 -0
  139. package/dist/esm/core/store.mjs +424 -0
  140. package/dist/esm/core/store.mjs.map +1 -0
  141. package/dist/esm/core/store.native.js +608 -0
  142. package/dist/esm/core/store.native.js.map +1 -0
  143. package/dist/esm/core/types.mjs +2 -0
  144. package/dist/esm/core/types.mjs.map +1 -0
  145. package/dist/esm/core/types.native.js +2 -0
  146. package/dist/esm/core/types.native.js.map +1 -0
  147. package/dist/esm/index.mjs +3 -2
  148. package/dist/esm/index.mjs.map +1 -1
  149. package/dist/esm/index.native.js +3 -2
  150. package/dist/esm/index.native.js.map +1 -1
  151. package/dist/esm/providers/WalletProvider.mjs +2 -1
  152. package/dist/esm/providers/WalletProvider.mjs.map +1 -1
  153. package/dist/esm/providers/WalletProvider.native.js +125 -93
  154. package/dist/esm/providers/WalletProvider.native.js.map +1 -1
  155. package/dist/esm/providers/index.mjs +2 -2
  156. package/dist/esm/providers/index.mjs.map +1 -1
  157. package/dist/esm/providers/index.native.js +2 -2
  158. package/dist/esm/providers/index.native.js.map +1 -1
  159. package/dist/esm/providers/native/deepLink.mjs +36 -24
  160. package/dist/esm/providers/native/deepLink.mjs.map +1 -1
  161. package/dist/esm/providers/native/deepLink.native.js +39 -26
  162. package/dist/esm/providers/native/deepLink.native.js.map +1 -1
  163. package/dist/esm/providers/native/inject.mjs +1 -3
  164. package/dist/esm/providers/native/inject.mjs.map +1 -1
  165. package/dist/esm/providers/native/inject.native.js +1 -3
  166. package/dist/esm/providers/native/inject.native.js.map +1 -1
  167. package/dist/esm/providers/walletBridge.mjs +9 -0
  168. package/dist/esm/providers/walletBridge.mjs.map +1 -0
  169. package/dist/esm/providers/walletBridge.native.js +9 -0
  170. package/dist/esm/providers/walletBridge.native.js.map +1 -0
  171. package/dist/esm/providers/walletConfig.mjs.map +1 -1
  172. package/dist/esm/providers/walletConfig.native.js.map +1 -1
  173. package/dist/jsx/bridge/AuthBridge.mjs +99 -0
  174. package/dist/jsx/bridge/AuthBridge.mjs.map +1 -0
  175. package/dist/jsx/bridge/AuthBridge.native.js +186 -0
  176. package/dist/jsx/bridge/AuthBridge.native.js.map +1 -0
  177. package/dist/jsx/bridge/BridgeClient.mjs +13 -10
  178. package/dist/jsx/bridge/BridgeClient.mjs.map +1 -1
  179. package/dist/jsx/bridge/BridgeClient.native.js +17 -12
  180. package/dist/jsx/bridge/BridgeClient.native.js.map +1 -1
  181. package/dist/jsx/bridge/BridgeHost.mjs +12 -4
  182. package/dist/jsx/bridge/BridgeHost.mjs.map +1 -1
  183. package/dist/jsx/bridge/BridgeHost.native.js +11 -3
  184. package/dist/jsx/bridge/BridgeHost.native.js.map +1 -1
  185. package/dist/jsx/bridge/GpgBridge.mjs +36 -0
  186. package/dist/jsx/bridge/GpgBridge.mjs.map +1 -0
  187. package/dist/jsx/bridge/GpgBridge.native.js +111 -0
  188. package/dist/jsx/bridge/GpgBridge.native.js.map +1 -0
  189. package/dist/jsx/bridge/SuiBridge.mjs +26 -0
  190. package/dist/jsx/bridge/SuiBridge.mjs.map +1 -0
  191. package/dist/jsx/bridge/SuiBridge.native.js +99 -0
  192. package/dist/jsx/bridge/SuiBridge.native.js.map +1 -0
  193. package/dist/jsx/bridge/authTypes.mjs +3 -0
  194. package/dist/jsx/bridge/authTypes.mjs.map +1 -0
  195. package/dist/jsx/bridge/authTypes.native.js +31 -0
  196. package/dist/jsx/bridge/authTypes.native.js.map +1 -0
  197. package/dist/jsx/bridge/core.mjs +17 -0
  198. package/dist/jsx/bridge/core.mjs.map +1 -0
  199. package/dist/jsx/bridge/core.native.js +68 -0
  200. package/dist/jsx/bridge/core.native.js.map +1 -0
  201. package/dist/jsx/bridge/hosting.mjs +62 -0
  202. package/dist/jsx/bridge/hosting.mjs.map +1 -0
  203. package/dist/jsx/bridge/hosting.native.js +117 -0
  204. package/dist/jsx/bridge/hosting.native.js.map +1 -0
  205. package/dist/jsx/bridge/index.mjs +2 -9
  206. package/dist/jsx/bridge/index.mjs.map +1 -1
  207. package/dist/jsx/bridge/index.native.js +2 -16
  208. package/dist/jsx/bridge/index.native.js.map +1 -1
  209. package/dist/jsx/bridge/nativeHost.mjs +65 -0
  210. package/dist/jsx/bridge/nativeHost.mjs.map +1 -0
  211. package/dist/jsx/bridge/nativeHost.native.js +118 -0
  212. package/dist/jsx/bridge/nativeHost.native.js.map +1 -0
  213. package/dist/jsx/bridge/protocol.mjs +28 -2
  214. package/dist/jsx/bridge/protocol.mjs.map +1 -1
  215. package/dist/jsx/bridge/protocol.native.js +147 -1
  216. package/dist/jsx/bridge/protocol.native.js.map +1 -1
  217. package/dist/jsx/core/family.mjs +62 -0
  218. package/dist/jsx/core/family.mjs.map +1 -0
  219. package/dist/jsx/core/family.native.js +115 -0
  220. package/dist/jsx/core/family.native.js.map +1 -0
  221. package/dist/jsx/core/index.mjs +7 -0
  222. package/dist/jsx/core/index.mjs.map +1 -0
  223. package/dist/jsx/core/index.native.js +44 -0
  224. package/dist/jsx/core/index.native.js.map +1 -0
  225. package/dist/jsx/core/message.mjs +63 -0
  226. package/dist/jsx/core/message.mjs.map +1 -0
  227. package/dist/jsx/core/message.native.js +104 -0
  228. package/dist/jsx/core/message.native.js.map +1 -0
  229. package/dist/jsx/core/names.mjs +25 -0
  230. package/dist/jsx/core/names.mjs.map +1 -0
  231. package/dist/jsx/core/names.native.js +95 -0
  232. package/dist/jsx/core/names.native.js.map +1 -0
  233. package/dist/jsx/core/react.mjs +21 -0
  234. package/dist/jsx/core/react.mjs.map +1 -0
  235. package/dist/jsx/core/react.native.js +52 -0
  236. package/dist/jsx/core/react.native.js.map +1 -0
  237. package/dist/jsx/core/store.mjs +424 -0
  238. package/dist/jsx/core/store.mjs.map +1 -0
  239. package/dist/jsx/core/store.native.js +637 -0
  240. package/dist/jsx/core/store.native.js.map +1 -0
  241. package/dist/jsx/core/types.mjs +2 -0
  242. package/dist/jsx/core/types.mjs.map +1 -0
  243. package/dist/jsx/core/types.native.js +21 -0
  244. package/dist/jsx/core/types.native.js.map +1 -0
  245. package/dist/jsx/index.js +3 -2
  246. package/dist/jsx/index.js.map +1 -1
  247. package/dist/jsx/index.mjs +3 -2
  248. package/dist/jsx/index.mjs.map +1 -1
  249. package/dist/jsx/index.native.js +2 -0
  250. package/dist/jsx/index.native.js.map +1 -1
  251. package/dist/jsx/providers/WalletProvider.mjs +2 -1
  252. package/dist/jsx/providers/WalletProvider.mjs.map +1 -1
  253. package/dist/jsx/providers/WalletProvider.native.js +123 -90
  254. package/dist/jsx/providers/WalletProvider.native.js.map +1 -1
  255. package/dist/jsx/providers/index.mjs +2 -2
  256. package/dist/jsx/providers/index.mjs.map +1 -1
  257. package/dist/jsx/providers/index.native.js +1 -0
  258. package/dist/jsx/providers/index.native.js.map +1 -1
  259. package/dist/jsx/providers/native/deepLink.mjs +36 -24
  260. package/dist/jsx/providers/native/deepLink.mjs.map +1 -1
  261. package/dist/jsx/providers/native/deepLink.native.js +43 -25
  262. package/dist/jsx/providers/native/deepLink.native.js.map +1 -1
  263. package/dist/jsx/providers/native/inject.mjs +1 -3
  264. package/dist/jsx/providers/native/inject.mjs.map +1 -1
  265. package/dist/jsx/providers/native/inject.native.js +2 -4
  266. package/dist/jsx/providers/native/inject.native.js.map +1 -1
  267. package/dist/jsx/providers/walletBridge.mjs +9 -0
  268. package/dist/jsx/providers/walletBridge.mjs.map +1 -0
  269. package/dist/jsx/providers/walletBridge.native.js +38 -0
  270. package/dist/jsx/providers/walletBridge.native.js.map +1 -0
  271. package/dist/jsx/providers/walletConfig.mjs.map +1 -1
  272. package/dist/jsx/providers/walletConfig.native.js.map +1 -1
  273. package/docs/bridge-protocol.md +485 -0
  274. package/package.json +14 -6
  275. package/src/bridge/AuthBridge.ts +146 -0
  276. package/src/bridge/BridgeClient.spec.ts +12 -0
  277. package/src/bridge/BridgeClient.ts +15 -10
  278. package/src/bridge/BridgeHost.spec.ts +20 -4
  279. package/src/bridge/BridgeHost.ts +16 -5
  280. package/src/bridge/GpgBridge.ts +49 -0
  281. package/src/bridge/SuiBridge.ts +34 -0
  282. package/src/bridge/authTypes.ts +76 -0
  283. package/src/bridge/core.ts +42 -0
  284. package/src/bridge/hosting.spec.ts +98 -0
  285. package/src/bridge/hosting.ts +99 -0
  286. package/src/bridge/index.ts +1 -8
  287. package/src/bridge/nativeHost.spec.ts +165 -0
  288. package/src/bridge/nativeHost.ts +120 -0
  289. package/src/bridge/protocol.spec.ts +24 -1
  290. package/src/bridge/protocol.ts +44 -1
  291. package/src/core/family.spec.ts +117 -0
  292. package/src/core/family.ts +103 -0
  293. package/src/core/imports.spec.ts +82 -0
  294. package/src/core/index.ts +47 -0
  295. package/src/core/message.spec.ts +178 -0
  296. package/src/core/message.ts +119 -0
  297. package/src/core/names.ts +29 -0
  298. package/src/core/react.spec.tsx +75 -0
  299. package/src/core/react.ts +34 -0
  300. package/src/core/store.spec.ts +890 -0
  301. package/src/core/store.ts +558 -0
  302. package/src/core/types.ts +96 -0
  303. package/src/index.ts +6 -0
  304. package/src/providers/WalletProvider.native.tsx +139 -85
  305. package/src/providers/WalletProvider.tsx +1 -1
  306. package/src/providers/index.ts +2 -0
  307. package/src/providers/native/deepLink.spec.ts +73 -1
  308. package/src/providers/native/deepLink.ts +76 -28
  309. package/src/providers/native/inject.ts +1 -9
  310. package/src/providers/walletBridge.ts +24 -0
  311. package/src/providers/walletConfig.ts +15 -1
  312. package/types/bridge/AuthBridge.d.ts +58 -0
  313. package/types/bridge/AuthBridge.d.ts.map +1 -0
  314. package/types/bridge/BridgeClient.d.ts +3 -1
  315. package/types/bridge/BridgeClient.d.ts.map +1 -1
  316. package/types/bridge/BridgeHost.d.ts +1 -1
  317. package/types/bridge/BridgeHost.d.ts.map +1 -1
  318. package/types/bridge/GpgBridge.d.ts +23 -0
  319. package/types/bridge/GpgBridge.d.ts.map +1 -0
  320. package/types/bridge/SuiBridge.d.ts +18 -0
  321. package/types/bridge/SuiBridge.d.ts.map +1 -0
  322. package/types/bridge/authTypes.d.ts +71 -0
  323. package/types/bridge/authTypes.d.ts.map +1 -0
  324. package/types/bridge/core.d.ts +16 -0
  325. package/types/bridge/core.d.ts.map +1 -0
  326. package/types/bridge/hosting.d.ts +34 -0
  327. package/types/bridge/hosting.d.ts.map +1 -0
  328. package/types/bridge/index.d.ts +1 -8
  329. package/types/bridge/index.d.ts.map +1 -1
  330. package/types/bridge/nativeHost.d.ts +55 -0
  331. package/types/bridge/nativeHost.d.ts.map +1 -0
  332. package/types/bridge/protocol.d.ts +34 -1
  333. package/types/bridge/protocol.d.ts.map +1 -1
  334. package/types/core/family.d.ts +44 -0
  335. package/types/core/family.d.ts.map +1 -0
  336. package/types/core/index.d.ts +7 -0
  337. package/types/core/index.d.ts.map +1 -0
  338. package/types/core/message.d.ts +44 -0
  339. package/types/core/message.d.ts.map +1 -0
  340. package/types/core/names.d.ts +7 -0
  341. package/types/core/names.d.ts.map +1 -0
  342. package/types/core/react.d.ts +14 -0
  343. package/types/core/react.d.ts.map +1 -0
  344. package/types/core/store.d.ts +64 -0
  345. package/types/core/store.d.ts.map +1 -0
  346. package/types/core/types.d.ts +88 -0
  347. package/types/core/types.d.ts.map +1 -0
  348. package/types/index.d.ts +2 -1
  349. package/types/index.d.ts.map +1 -1
  350. package/types/providers/WalletProvider.d.ts +1 -0
  351. package/types/providers/WalletProvider.d.ts.map +1 -1
  352. package/types/providers/WalletProvider.native.d.ts +2 -1
  353. package/types/providers/WalletProvider.native.d.ts.map +1 -1
  354. package/types/providers/index.d.ts +1 -1
  355. package/types/providers/index.d.ts.map +1 -1
  356. package/types/providers/native/deepLink.d.ts +29 -4
  357. package/types/providers/native/deepLink.d.ts.map +1 -1
  358. package/types/providers/native/inject.d.ts +1 -7
  359. package/types/providers/native/inject.d.ts.map +1 -1
  360. package/types/providers/walletBridge.d.ts +17 -0
  361. package/types/providers/walletBridge.d.ts.map +1 -0
  362. package/types/providers/walletConfig.d.ts +18 -1
  363. package/types/providers/walletConfig.d.ts.map +1 -1
@@ -0,0 +1,47 @@
1
+ // Core contracts of mpo web3 (MPO-385): the family registry, the connection
2
+ // driver interface, the connection store and the message registry. Nothing here
3
+ // imports a chain SDK; each family package brings its own driver and message.
4
+ export {
5
+ createFamilyRegistry,
6
+ defineWalletFamily,
7
+ type FamilyRegistry,
8
+ type WalletFamily,
9
+ type WalletFamilyDefinition,
10
+ } from "./family";
11
+ export {
12
+ createMessageRegistry,
13
+ formatWalletMessage,
14
+ type MessageFamily,
15
+ type WalletMessageRegistry,
16
+ type WalletMessageSpec,
17
+ } from "./message";
18
+ export {
19
+ createConnectionStore,
20
+ defaultConnectionStorageKey,
21
+ type ConnectionStore,
22
+ type ConnectionStoreOptions,
23
+ type FamilyConnector,
24
+ } from "./store";
25
+ export {
26
+ ConnectionProvider,
27
+ useConnection,
28
+ useConnectionStore,
29
+ type ConnectionProviderProps,
30
+ } from "./react";
31
+ export type {
32
+ ConnectionDriver,
33
+ ConnectionState,
34
+ ConnectionStatus,
35
+ ConnectionStorage,
36
+ DriverAccount,
37
+ DriverConnectOptions,
38
+ DriverState,
39
+ SavedConnection,
40
+ WalletConnector,
41
+ } from "./types";
42
+ export {
43
+ UnsupportedClientMethodError,
44
+ type ChainClient,
45
+ type ClientCapability,
46
+ type ClientFamily,
47
+ } from "../clients/types";
@@ -0,0 +1,178 @@
1
+ import { getAddress } from "viem";
2
+ import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import { buildWalletMessage, type SignerFamily } from "../message/buildWalletMessage";
4
+ import { createMessageRegistry, formatWalletMessage, type MessageFamily } from "./message";
5
+
6
+ // The five families as their packages will register them. Kept in step with
7
+ // buildWalletMessage, which every Keycloak golden test already pins.
8
+ const families: MessageFamily[] = [
9
+ {
10
+ id: "eth",
11
+ aliases: ["evm"],
12
+ message: {
13
+ header: "wants you to sign in with your Ethereum account:",
14
+ statement: "Sign in With Ethereum.",
15
+ chainId: "1",
16
+ numericChainId: true,
17
+ keepStatementLine: true,
18
+ normalizeAddress: (address) => getAddress(address),
19
+ },
20
+ },
21
+ {
22
+ id: "sol",
23
+ aliases: ["solana"],
24
+ message: {
25
+ header: "wants you to sign in with your Solana account:",
26
+ statement: "Sign in With Solana.",
27
+ chainId: "solana:mainnet",
28
+ },
29
+ },
30
+ {
31
+ id: "sui",
32
+ message: {
33
+ header: "wants you to sign in with your Sui account:",
34
+ statement: "Sign in With Sui.",
35
+ chainId: "sui:mainnet",
36
+ },
37
+ },
38
+ {
39
+ id: "btc",
40
+ aliases: ["bitcoin"],
41
+ message: {
42
+ header: "wants you to sign in with your Bitcoin account:",
43
+ statement: "Sign in With Bitcoin.",
44
+ chainId: "bitcoin",
45
+ },
46
+ },
47
+ {
48
+ id: "gpg",
49
+ message: {
50
+ header: "wants you to sign in with your GPG key.",
51
+ statement: null,
52
+ chainId: null,
53
+ address: false,
54
+ },
55
+ },
56
+ ];
57
+
58
+ const registry = createMessageRegistry(families);
59
+ const names: SignerFamily[] = ["eth", "evm", "sol", "solana", "sui", "btc", "bitcoin", "gpg"];
60
+ const base = {
61
+ domain: "app.multiplatform.one",
62
+ uri: "https://app.multiplatform.one/login",
63
+ nonce: "ohY7vD2Kq9",
64
+ issuedAt: "2026-09-26T20:48:18.648Z",
65
+ address: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
66
+ };
67
+
68
+ const outcome = (build: () => string) => {
69
+ try {
70
+ return { message: build() };
71
+ } catch {
72
+ return { threw: true };
73
+ }
74
+ };
75
+
76
+ afterEach(() => {
77
+ vi.unstubAllGlobals();
78
+ });
79
+
80
+ describe("the core message registry", () => {
81
+ it("builds the same bytes as buildWalletMessage for every family, alias and option", () => {
82
+ let compared = 0;
83
+ for (const family of names) {
84
+ for (const statement of [undefined, null, "", "Custom statement."]) {
85
+ for (const chainId of [undefined, 137, "solana:devnet", 900001]) {
86
+ for (const version of [undefined, "2"]) {
87
+ const opts = { ...base, statement, chainId, version };
88
+ expect(registry.build(family, opts), `${family} ${JSON.stringify(opts)}`).toBe(
89
+ buildWalletMessage(family, opts),
90
+ );
91
+ compared++;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ expect(compared).toBe(256);
97
+ });
98
+
99
+ it("refuses what buildWalletMessage refuses", () => {
100
+ for (const family of names) {
101
+ for (const opts of [
102
+ { ...base, address: undefined },
103
+ { ...base, domain: "evil.example\nURI: https://evil.example" },
104
+ { ...base, uri: "https://a\nb" },
105
+ { ...base, statement: "two\nlines" },
106
+ ]) {
107
+ expect(outcome(() => registry.build(family, opts))).toEqual(
108
+ outcome(() => buildWalletMessage(family, opts)),
109
+ );
110
+ }
111
+ }
112
+ });
113
+
114
+ it("takes domain and uri from the page like buildWalletMessage", () => {
115
+ for (const location of [
116
+ { host: "shop.example", origin: "https://shop.example" },
117
+ { host: "file.example", origin: "null" },
118
+ { host: "", origin: "" },
119
+ ]) {
120
+ vi.stubGlobal("location", location);
121
+ for (const family of names) {
122
+ const opts = { nonce: base.nonce, issuedAt: base.issuedAt, address: base.address };
123
+ expect(outcome(() => registry.build(family, opts))).toEqual(
124
+ outcome(() => buildWalletMessage(family, opts)),
125
+ );
126
+ }
127
+ }
128
+ });
129
+
130
+ it("resolves aliases and lists families in registration order", () => {
131
+ expect(registry.families).toEqual(["eth", "sol", "sui", "btc", "gpg"]);
132
+ expect(registry.resolve("evm")).toBe("eth");
133
+ expect(registry.resolve("cosmos")).toBeUndefined();
134
+ expect(registry.spec("bitcoin")?.chainId).toBe("bitcoin");
135
+ });
136
+
137
+ it("names the registered families when asked for another", () => {
138
+ expect(() => registry.build("cosmos", base)).toThrow(
139
+ "no wallet message for family cosmos; registered: eth, sol, sui, btc, gpg",
140
+ );
141
+ expect(() => createMessageRegistry([]).build("eth", base)).toThrow(/registered: none/);
142
+ });
143
+
144
+ it("a new family needs only a spec", () => {
145
+ const cosmos = createMessageRegistry([
146
+ {
147
+ id: "cosmos",
148
+ message: {
149
+ header: "wants you to sign in with your Cosmos account:",
150
+ statement: "Sign in With Cosmos.",
151
+ chainId: "cosmoshub-4",
152
+ },
153
+ },
154
+ ]);
155
+ expect(cosmos.build("cosmos", { ...base, address: "cosmos1abc" }).split("\n")).toEqual([
156
+ "app.multiplatform.one wants you to sign in with your Cosmos account:",
157
+ "cosmos1abc",
158
+ "",
159
+ "Sign in With Cosmos.",
160
+ "",
161
+ "URI: https://app.multiplatform.one/login",
162
+ "Version: 1",
163
+ "Chain ID: cosmoshub-4",
164
+ "Nonce: ohY7vD2Kq9",
165
+ "Issued At: 2026-09-26T20:48:18.648Z",
166
+ ]);
167
+ });
168
+
169
+ it("formatWalletMessage names the family in its errors", () => {
170
+ expect(() =>
171
+ formatWalletMessage(
172
+ { header: "wants you to sign in:", statement: null, chainId: null },
173
+ { ...base, address: undefined },
174
+ "sol",
175
+ ),
176
+ ).toThrow("wallet message: sol needs an address");
177
+ });
178
+ });
@@ -0,0 +1,119 @@
1
+ import type { WalletMessageOptions } from "../message/buildWalletMessage";
2
+ import { nameTable } from "./names";
3
+
4
+ /**
5
+ * How one family's sign-in message differs from the shared envelope. A family
6
+ * package defines its spec; the envelope (domain line, statement, URI, Version,
7
+ * Chain ID, Nonce, Issued At) is the same bytes the Keycloak verifiers parse.
8
+ */
9
+ export interface WalletMessageSpec {
10
+ /** First-line text after the domain, which the verifiers content-sniff. */
11
+ readonly header: string;
12
+ /** Default statement. Null means none. */
13
+ readonly statement: string | null;
14
+ /** The `Chain ID:` value when the caller gives none. Null omits the line. */
15
+ readonly chainId: string | null;
16
+ /** Whether the message names the signer's address. GPG's identity is its key. Default true. */
17
+ readonly address?: boolean;
18
+ /**
19
+ * Honour a numeric `chainId` option. Only EVM chain ids are numbers; elsewhere
20
+ * a number is a connector's synthetic id and is ignored.
21
+ */
22
+ readonly numericChainId?: boolean;
23
+ /** EIP-4361 keeps an empty line where an omitted statement would be. */
24
+ readonly keepStatementLine?: boolean;
25
+ /** Canonical address form, such as EIP-55 for EVM. */
26
+ readonly normalizeAddress?: (address: string) => string;
27
+ }
28
+
29
+ export interface MessageFamily {
30
+ readonly id: string;
31
+ readonly aliases?: readonly string[];
32
+ readonly message: WalletMessageSpec;
33
+ }
34
+
35
+ export interface WalletMessageRegistry {
36
+ /** Registered family ids, in registration order. */
37
+ readonly families: readonly string[];
38
+ /** The family id for an id or alias, or undefined. */
39
+ resolve(family: string): string | undefined;
40
+ spec(family: string): WalletMessageSpec | undefined;
41
+ /** Builds the sign-in message. Throws for a family nobody registered. */
42
+ build(family: string, opts: WalletMessageOptions): string;
43
+ }
44
+
45
+ function singleLine(field: string, value: string | null | undefined) {
46
+ if (value && /[\r\n]/.test(value)) {
47
+ throw new Error(`wallet message: ${field} must be a single line`);
48
+ }
49
+ }
50
+
51
+ function pageLocation(): { host: string; origin: string } {
52
+ const location = (globalThis as { location?: { host?: string; origin?: string } }).location;
53
+ return { host: location?.host ?? "", origin: location?.origin ?? "" };
54
+ }
55
+
56
+ /** Builds one sign-in message from a family spec. `family` only names the family in errors. */
57
+ export function formatWalletMessage(
58
+ spec: WalletMessageSpec,
59
+ opts: WalletMessageOptions,
60
+ family = "wallet",
61
+ ): string {
62
+ const page = pageLocation();
63
+ const domain = opts.domain ?? page.host;
64
+ if (!domain) {
65
+ throw new Error(
66
+ "wallet message: no domain. Pass opts.domain; a file:// or native page has no host.",
67
+ );
68
+ }
69
+ const pageOrigin = page.origin && page.origin !== "null" ? page.origin : "";
70
+ const uri = opts.uri ?? (pageOrigin || `https://${domain}`);
71
+ const statement = opts.statement === undefined ? spec.statement : opts.statement;
72
+ singleLine("domain", domain);
73
+ singleLine("uri", uri);
74
+ singleLine("statement", statement);
75
+ const lines = [`${domain} ${spec.header}`];
76
+ if (spec.address !== false) {
77
+ if (!opts.address) throw new Error(`wallet message: ${family} needs an address`);
78
+ lines.push(spec.normalizeAddress ? spec.normalizeAddress(opts.address) : opts.address);
79
+ }
80
+ lines.push("");
81
+ if (statement) lines.push(statement, "");
82
+ else if (spec.keepStatementLine) lines.push("");
83
+ lines.push(`URI: ${uri}`, `Version: ${opts.version ?? "1"}`);
84
+ if (spec.chainId !== null) {
85
+ const chainId = spec.numericChainId
86
+ ? (opts.chainId ?? spec.chainId)
87
+ : typeof opts.chainId === "string"
88
+ ? opts.chainId
89
+ : spec.chainId;
90
+ lines.push(`Chain ID: ${chainId}`);
91
+ }
92
+ lines.push(`Nonce: ${opts.nonce}`, `Issued At: ${opts.issuedAt ?? new Date().toISOString()}`);
93
+ return lines.join("\n");
94
+ }
95
+
96
+ /** The message half of the family registry: family id or alias to spec. */
97
+ export function createMessageRegistry(families: Iterable<MessageFamily>): WalletMessageRegistry {
98
+ const list = [...families];
99
+ const names = nameTable(list);
100
+ const specs = new Map(list.map((family) => [family.id, family.message]));
101
+ const spec = (family: string) => {
102
+ const id = names.get(family);
103
+ return id === undefined ? undefined : specs.get(id);
104
+ };
105
+ return {
106
+ families: list.map((family) => family.id),
107
+ resolve: (family) => names.get(family),
108
+ spec,
109
+ build(family, opts) {
110
+ const found = spec(family);
111
+ if (found === undefined) {
112
+ throw new Error(
113
+ `no wallet message for family ${family}; registered: ${list.map((entry) => entry.id).join(", ") || "none"}`,
114
+ );
115
+ }
116
+ return formatWalletMessage(found, opts, names.get(family));
117
+ },
118
+ };
119
+ }
@@ -0,0 +1,29 @@
1
+ const pattern = /^[a-z][a-z0-9-]*$/;
2
+
3
+ export function assertName(kind: string, name: unknown): asserts name is string {
4
+ if (typeof name !== "string" || !pattern.test(name)) {
5
+ throw new Error(`${kind} must be lowercase letters, digits and dashes: ${String(name)}`);
6
+ }
7
+ }
8
+
9
+ /** Maps every id and alias to its entry's id, refusing a name two entries claim. */
10
+ export function nameTable(
11
+ entries: Iterable<{ readonly id: string; readonly aliases?: readonly string[] }>,
12
+ ): Map<string, string> {
13
+ const table = new Map<string, string>();
14
+ const claim = (name: string, id: string) => {
15
+ const owner = table.get(name);
16
+ if (owner === undefined) table.set(name, id);
17
+ else if (owner !== id) {
18
+ throw new Error(`wallet family name "${name}" is claimed by ${owner} and ${id}`);
19
+ }
20
+ };
21
+ for (const entry of entries) {
22
+ if (table.get(entry.id) === entry.id) {
23
+ throw new Error(`wallet family ${entry.id} is registered twice`);
24
+ }
25
+ claim(entry.id, entry.id);
26
+ for (const alias of entry.aliases ?? []) claim(alias, entry.id);
27
+ }
28
+ return table;
29
+ }
@@ -0,0 +1,75 @@
1
+ // @vitest-environment happy-dom
2
+ import { act, renderHook } from "@testing-library/react";
3
+ import type { ReactNode } from "react";
4
+ import { describe, expect, it } from "vitest";
5
+ import { testDriver } from "../../tests/core/testDriver";
6
+ import { defineWalletFamily } from "./family";
7
+ import { ConnectionProvider, useConnection, useConnectionStore } from "./react";
8
+ import { createConnectionStore } from "./store";
9
+
10
+ function setup() {
11
+ const sol = testDriver("solana", [{ id: "phantom", name: "Phantom" }], {
12
+ phantom: { address: "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV", chainId: "solana:mainnet" },
13
+ });
14
+ const store = createConnectionStore({
15
+ storage: null,
16
+ families: [
17
+ defineWalletFamily({
18
+ id: "sol",
19
+ label: "Solana",
20
+ message: { header: "wants you to sign in:", statement: null, chainId: null },
21
+ driver: () => sol,
22
+ }),
23
+ ],
24
+ });
25
+ const wrapper = ({ children }: { children: ReactNode }) => (
26
+ <ConnectionProvider store={store}>{children}</ConnectionProvider>
27
+ );
28
+ return { store, sol, wrapper };
29
+ }
30
+
31
+ describe("useConnection", () => {
32
+ it("renders the store's state and follows connect, account changes and disconnect", async () => {
33
+ const { store, sol, wrapper } = setup();
34
+ const { result } = renderHook(() => useConnection(), { wrapper });
35
+ expect(result.current.status).toBe("disconnected");
36
+
37
+ await act(() => store.connect("sol", "phantom"));
38
+ expect(result.current).toMatchObject({
39
+ status: "connected",
40
+ family: "sol",
41
+ connector: { id: "phantom", name: "Phantom" },
42
+ address: "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
43
+ chainId: "solana:mainnet",
44
+ });
45
+ expect(result.current.client?.family).toBe("solana");
46
+
47
+ act(() =>
48
+ sol.emit({
49
+ status: "connected",
50
+ connectorId: "phantom",
51
+ account: {
52
+ address: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
53
+ chainId: "solana:devnet",
54
+ },
55
+ }),
56
+ );
57
+ expect(result.current).toMatchObject({
58
+ address: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
59
+ chainId: "solana:devnet",
60
+ });
61
+
62
+ await act(() => store.disconnect());
63
+ expect(result.current.status).toBe("disconnected");
64
+ });
65
+
66
+ it("useConnectionStore hands back the provided store", () => {
67
+ const { store, wrapper } = setup();
68
+ const { result } = renderHook(() => useConnectionStore(), { wrapper });
69
+ expect(result.current).toBe(store);
70
+ });
71
+
72
+ it("refuses to run outside a ConnectionProvider", () => {
73
+ expect(() => renderHook(() => useConnection())).toThrow(/needs a ConnectionProvider/);
74
+ });
75
+ });
@@ -0,0 +1,34 @@
1
+ import {
2
+ createContext,
3
+ createElement,
4
+ useContext,
5
+ useSyncExternalStore,
6
+ type ReactNode,
7
+ } from "react";
8
+ import type { ConnectionStore } from "./store";
9
+ import type { ConnectionState } from "./types";
10
+
11
+ const ConnectionStoreContext = createContext<ConnectionStore | null>(null);
12
+
13
+ export interface ConnectionProviderProps {
14
+ store: ConnectionStore;
15
+ children?: ReactNode;
16
+ }
17
+
18
+ /** Makes one connection store the app's. Web3Provider mounts this once it owns a store. */
19
+ export function ConnectionProvider({ store, children }: ConnectionProviderProps) {
20
+ return createElement(ConnectionStoreContext.Provider, { value: store }, children);
21
+ }
22
+
23
+ /** The store under the nearest ConnectionProvider, for connect, disconnect and reconnect. */
24
+ export function useConnectionStore(): ConnectionStore {
25
+ const store = useContext(ConnectionStoreContext);
26
+ if (!store) throw new Error("useConnectionStore needs a ConnectionProvider above it");
27
+ return store;
28
+ }
29
+
30
+ /** The active connection: status, family, connector, address, chainId and client. */
31
+ export function useConnection(): ConnectionState {
32
+ const store = useConnectionStore();
33
+ return useSyncExternalStore(store.subscribe, store.getState, store.getState);
34
+ }