@multiplatform.one/web3 7.23.1 → 7.24.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 (431) hide show
  1. package/README.md +150 -11
  2. package/dist/cjs/clients/evm.cjs +299 -11
  3. package/dist/cjs/clients/evm.native.js +500 -12
  4. package/dist/cjs/clients/evm.native.js.map +1 -1
  5. package/dist/cjs/clients/index.cjs +5 -0
  6. package/dist/cjs/clients/index.native.js +5 -0
  7. package/dist/cjs/clients/index.native.js.map +1 -1
  8. package/dist/cjs/clients/solana.cjs +39 -21
  9. package/dist/cjs/clients/solana.native.js +48 -23
  10. package/dist/cjs/clients/solana.native.js.map +1 -1
  11. package/dist/cjs/connectkit/GpgProvider.cjs +44 -0
  12. package/dist/cjs/connectkit/GpgProvider.native.js +51 -0
  13. package/dist/cjs/connectkit/GpgProvider.native.js.map +1 -0
  14. package/dist/cjs/connectkit/adapters/BitcoinAdapter.cjs +5 -14
  15. package/dist/cjs/connectkit/adapters/BitcoinAdapter.native.js +5 -15
  16. package/dist/cjs/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
  17. package/dist/cjs/connectkit/adapters/EthereumAdapter.cjs +6 -15
  18. package/dist/cjs/connectkit/adapters/EthereumAdapter.native.js +7 -16
  19. package/dist/cjs/connectkit/adapters/EthereumAdapter.native.js.map +1 -1
  20. package/dist/cjs/connectkit/adapters/SolanaAdapter.cjs +5 -14
  21. package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js +5 -15
  22. package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  23. package/dist/cjs/connectkit/adapters/SuiAdapter.cjs +5 -14
  24. package/dist/cjs/connectkit/adapters/SuiAdapter.native.js +5 -15
  25. package/dist/cjs/connectkit/adapters/SuiAdapter.native.js.map +1 -1
  26. package/dist/cjs/connectkit/connectors/createWalletMessage.cjs +2 -2
  27. package/dist/cjs/connectkit/connectors/createWalletMessage.native.js +2 -2
  28. package/dist/cjs/connectkit/connectors/createWalletMessage.native.js.map +1 -1
  29. package/dist/cjs/connectkit/index.cjs +4 -3
  30. package/dist/cjs/connectkit/index.native.js +4 -3
  31. package/dist/cjs/connectkit/index.native.js.map +1 -1
  32. package/dist/cjs/connectkit/siwe/SIWEContext.native.js.map +1 -1
  33. package/dist/cjs/connectkit/siwe/SIWEProvider.cjs +18 -3
  34. package/dist/cjs/connectkit/siwe/SIWEProvider.native.js +18 -3
  35. package/dist/cjs/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  36. package/dist/cjs/index.cjs +1 -0
  37. package/dist/cjs/index.native.js +1 -0
  38. package/dist/cjs/index.native.js.map +1 -1
  39. package/dist/cjs/keycloak/KeycloakWalletLogin.cjs +255 -0
  40. package/dist/cjs/keycloak/KeycloakWalletLogin.native.js +33 -0
  41. package/dist/cjs/keycloak/KeycloakWalletLogin.native.js.map +1 -0
  42. package/dist/cjs/keycloak/browserFlow.cjs +83 -0
  43. package/dist/cjs/keycloak/browserFlow.native.js +90 -0
  44. package/dist/cjs/keycloak/browserFlow.native.js.map +1 -0
  45. package/dist/cjs/keycloak/device.cjs +36 -0
  46. package/dist/cjs/keycloak/device.native.js +45 -0
  47. package/dist/cjs/keycloak/device.native.js.map +1 -0
  48. package/dist/cjs/keycloak/directGrant.cjs +189 -0
  49. package/dist/cjs/keycloak/directGrant.native.js +233 -0
  50. package/dist/cjs/keycloak/directGrant.native.js.map +1 -0
  51. package/dist/cjs/keycloak/iife.cjs +4 -0
  52. package/dist/cjs/keycloak/iife.native.js +7 -0
  53. package/dist/cjs/keycloak/iife.native.js.map +1 -0
  54. package/dist/cjs/keycloak/index.cjs +53 -0
  55. package/dist/cjs/keycloak/index.native.js +56 -0
  56. package/dist/cjs/keycloak/index.native.js.map +1 -0
  57. package/dist/cjs/keycloak/keycloakWallet.cjs +214 -0
  58. package/dist/cjs/keycloak/keycloakWallet.native.js +285 -0
  59. package/dist/cjs/keycloak/keycloakWallet.native.js.map +1 -0
  60. package/dist/cjs/keycloak/mount.cjs +53 -0
  61. package/dist/cjs/keycloak/mount.native.js +33 -0
  62. package/dist/cjs/keycloak/mount.native.js.map +1 -0
  63. package/dist/cjs/keycloak/registerWallet.cjs +74 -0
  64. package/dist/cjs/keycloak/registerWallet.native.js +81 -0
  65. package/dist/cjs/keycloak/registerWallet.native.js.map +1 -0
  66. package/dist/cjs/keycloak/types.cjs +46 -0
  67. package/dist/cjs/keycloak/types.native.js +179 -0
  68. package/dist/cjs/keycloak/types.native.js.map +1 -0
  69. package/dist/cjs/keycloak/useDirectLogin.cjs +57 -0
  70. package/dist/cjs/keycloak/useDirectLogin.native.js +77 -0
  71. package/dist/cjs/keycloak/useDirectLogin.native.js.map +1 -0
  72. package/dist/cjs/keycloak/useWalletLogin.cjs +97 -0
  73. package/dist/cjs/keycloak/useWalletLogin.native.js +33 -0
  74. package/dist/cjs/keycloak/useWalletLogin.native.js.map +1 -0
  75. package/dist/cjs/message/buildWalletMessage.cjs +113 -0
  76. package/dist/cjs/message/buildWalletMessage.native.js +121 -0
  77. package/dist/cjs/message/buildWalletMessage.native.js.map +1 -0
  78. package/dist/cjs/message/index.cjs +29 -0
  79. package/dist/cjs/message/index.native.js +32 -0
  80. package/dist/cjs/message/index.native.js.map +1 -0
  81. package/dist/cjs/providers/WalletProvider.cjs +8 -2
  82. package/dist/cjs/siws/message.cjs +5 -16
  83. package/dist/cjs/siws/message.native.js +6 -16
  84. package/dist/cjs/siws/message.native.js.map +1 -1
  85. package/dist/cjs/solana.native.js.map +1 -1
  86. package/dist/esm/clients/evm.mjs +295 -12
  87. package/dist/esm/clients/evm.mjs.map +1 -1
  88. package/dist/esm/clients/evm.native.js +496 -13
  89. package/dist/esm/clients/evm.native.js.map +1 -1
  90. package/dist/esm/clients/index.mjs +2 -2
  91. package/dist/esm/clients/index.mjs.map +1 -1
  92. package/dist/esm/clients/index.native.js +2 -2
  93. package/dist/esm/clients/index.native.js.map +1 -1
  94. package/dist/esm/clients/solana.mjs +39 -21
  95. package/dist/esm/clients/solana.mjs.map +1 -1
  96. package/dist/esm/clients/solana.native.js +48 -23
  97. package/dist/esm/clients/solana.native.js.map +1 -1
  98. package/dist/esm/connectkit/GpgProvider.mjs +19 -0
  99. package/dist/esm/connectkit/GpgProvider.mjs.map +1 -0
  100. package/dist/esm/connectkit/GpgProvider.native.js +23 -0
  101. package/dist/esm/connectkit/GpgProvider.native.js.map +1 -0
  102. package/dist/esm/connectkit/adapters/BitcoinAdapter.mjs +5 -14
  103. package/dist/esm/connectkit/adapters/BitcoinAdapter.mjs.map +1 -1
  104. package/dist/esm/connectkit/adapters/BitcoinAdapter.native.js +5 -15
  105. package/dist/esm/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
  106. package/dist/esm/connectkit/adapters/EthereumAdapter.mjs +6 -15
  107. package/dist/esm/connectkit/adapters/EthereumAdapter.mjs.map +1 -1
  108. package/dist/esm/connectkit/adapters/EthereumAdapter.native.js +7 -16
  109. package/dist/esm/connectkit/adapters/EthereumAdapter.native.js.map +1 -1
  110. package/dist/esm/connectkit/adapters/SolanaAdapter.mjs +5 -14
  111. package/dist/esm/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
  112. package/dist/esm/connectkit/adapters/SolanaAdapter.native.js +5 -15
  113. package/dist/esm/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  114. package/dist/esm/connectkit/adapters/SuiAdapter.mjs +5 -14
  115. package/dist/esm/connectkit/adapters/SuiAdapter.mjs.map +1 -1
  116. package/dist/esm/connectkit/adapters/SuiAdapter.native.js +5 -15
  117. package/dist/esm/connectkit/adapters/SuiAdapter.native.js.map +1 -1
  118. package/dist/esm/connectkit/connectors/createWalletMessage.mjs +1 -1
  119. package/dist/esm/connectkit/connectors/createWalletMessage.native.js +1 -1
  120. package/dist/esm/connectkit/index.mjs +3 -2
  121. package/dist/esm/connectkit/index.mjs.map +1 -1
  122. package/dist/esm/connectkit/index.native.js +3 -2
  123. package/dist/esm/connectkit/index.native.js.map +1 -1
  124. package/dist/esm/connectkit/siwe/SIWEContext.mjs.map +1 -1
  125. package/dist/esm/connectkit/siwe/SIWEContext.native.js.map +1 -1
  126. package/dist/esm/connectkit/siwe/SIWEProvider.mjs +19 -4
  127. package/dist/esm/connectkit/siwe/SIWEProvider.mjs.map +1 -1
  128. package/dist/esm/connectkit/siwe/SIWEProvider.native.js +19 -4
  129. package/dist/esm/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  130. package/dist/esm/index.mjs +1 -0
  131. package/dist/esm/index.mjs.map +1 -1
  132. package/dist/esm/index.native.js +1 -0
  133. package/dist/esm/index.native.js.map +1 -1
  134. package/dist/esm/keycloak/KeycloakWalletLogin.mjs +218 -0
  135. package/dist/esm/keycloak/KeycloakWalletLogin.mjs.map +1 -0
  136. package/dist/esm/keycloak/KeycloakWalletLogin.native.js +5 -0
  137. package/dist/esm/keycloak/KeycloakWalletLogin.native.js.map +1 -0
  138. package/dist/esm/keycloak/browserFlow.mjs +58 -0
  139. package/dist/esm/keycloak/browserFlow.mjs.map +1 -0
  140. package/dist/esm/keycloak/browserFlow.native.js +62 -0
  141. package/dist/esm/keycloak/browserFlow.native.js.map +1 -0
  142. package/dist/esm/keycloak/device.mjs +10 -0
  143. package/dist/esm/keycloak/device.mjs.map +1 -0
  144. package/dist/esm/keycloak/device.native.js +16 -0
  145. package/dist/esm/keycloak/device.native.js.map +1 -0
  146. package/dist/esm/keycloak/directGrant.mjs +164 -0
  147. package/dist/esm/keycloak/directGrant.mjs.map +1 -0
  148. package/dist/esm/keycloak/directGrant.native.js +205 -0
  149. package/dist/esm/keycloak/directGrant.native.js.map +1 -0
  150. package/dist/esm/keycloak/iife.mjs +5 -0
  151. package/dist/esm/keycloak/iife.mjs.map +1 -0
  152. package/dist/esm/keycloak/iife.native.js +5 -0
  153. package/dist/esm/keycloak/iife.native.js.map +1 -0
  154. package/dist/esm/keycloak/index.mjs +13 -0
  155. package/dist/esm/keycloak/index.mjs.map +1 -0
  156. package/dist/esm/keycloak/index.native.js +13 -0
  157. package/dist/esm/keycloak/index.native.js.map +1 -0
  158. package/dist/esm/keycloak/keycloakWallet.mjs +186 -0
  159. package/dist/esm/keycloak/keycloakWallet.mjs.map +1 -0
  160. package/dist/esm/keycloak/keycloakWallet.native.js +254 -0
  161. package/dist/esm/keycloak/keycloakWallet.native.js.map +1 -0
  162. package/dist/esm/keycloak/mount.mjs +28 -0
  163. package/dist/esm/keycloak/mount.mjs.map +1 -0
  164. package/dist/esm/keycloak/mount.native.js +5 -0
  165. package/dist/esm/keycloak/mount.native.js.map +1 -0
  166. package/dist/esm/keycloak/registerWallet.mjs +49 -0
  167. package/dist/esm/keycloak/registerWallet.mjs.map +1 -0
  168. package/dist/esm/keycloak/registerWallet.native.js +53 -0
  169. package/dist/esm/keycloak/registerWallet.native.js.map +1 -0
  170. package/dist/esm/keycloak/types.mjs +20 -0
  171. package/dist/esm/keycloak/types.mjs.map +1 -0
  172. package/dist/esm/keycloak/types.native.js +150 -0
  173. package/dist/esm/keycloak/types.native.js.map +1 -0
  174. package/dist/esm/keycloak/useDirectLogin.mjs +32 -0
  175. package/dist/esm/keycloak/useDirectLogin.mjs.map +1 -0
  176. package/dist/esm/keycloak/useDirectLogin.native.js +49 -0
  177. package/dist/esm/keycloak/useDirectLogin.native.js.map +1 -0
  178. package/dist/esm/keycloak/useWalletLogin.mjs +72 -0
  179. package/dist/esm/keycloak/useWalletLogin.mjs.map +1 -0
  180. package/dist/esm/keycloak/useWalletLogin.native.js +5 -0
  181. package/dist/esm/keycloak/useWalletLogin.native.js.map +1 -0
  182. package/dist/esm/message/buildWalletMessage.mjs +87 -0
  183. package/dist/esm/message/buildWalletMessage.mjs.map +1 -0
  184. package/dist/esm/message/buildWalletMessage.native.js +92 -0
  185. package/dist/esm/message/buildWalletMessage.native.js.map +1 -0
  186. package/dist/esm/message/index.mjs +3 -0
  187. package/dist/esm/message/index.mjs.map +1 -0
  188. package/dist/esm/message/index.native.js +3 -0
  189. package/dist/esm/message/index.native.js.map +1 -0
  190. package/dist/esm/providers/WalletProvider.mjs +9 -3
  191. package/dist/esm/providers/WalletProvider.mjs.map +1 -1
  192. package/dist/esm/siws/message.mjs +5 -16
  193. package/dist/esm/siws/message.mjs.map +1 -1
  194. package/dist/esm/siws/message.native.js +6 -16
  195. package/dist/esm/siws/message.native.js.map +1 -1
  196. package/dist/esm/solana.mjs.map +1 -1
  197. package/dist/esm/solana.native.js.map +1 -1
  198. package/dist/jsx/clients/evm.mjs +295 -12
  199. package/dist/jsx/clients/evm.mjs.map +1 -1
  200. package/dist/jsx/clients/evm.native.js +500 -12
  201. package/dist/jsx/clients/evm.native.js.map +1 -1
  202. package/dist/jsx/clients/index.mjs +2 -2
  203. package/dist/jsx/clients/index.mjs.map +1 -1
  204. package/dist/jsx/clients/index.native.js +5 -0
  205. package/dist/jsx/clients/index.native.js.map +1 -1
  206. package/dist/jsx/clients/solana.mjs +39 -21
  207. package/dist/jsx/clients/solana.mjs.map +1 -1
  208. package/dist/jsx/clients/solana.native.js +48 -23
  209. package/dist/jsx/clients/solana.native.js.map +1 -1
  210. package/dist/jsx/connectkit/GpgProvider.mjs +19 -0
  211. package/dist/jsx/connectkit/GpgProvider.mjs.map +1 -0
  212. package/dist/jsx/connectkit/GpgProvider.native.js +51 -0
  213. package/dist/jsx/connectkit/GpgProvider.native.js.map +1 -0
  214. package/dist/jsx/connectkit/adapters/BitcoinAdapter.mjs +5 -14
  215. package/dist/jsx/connectkit/adapters/BitcoinAdapter.mjs.map +1 -1
  216. package/dist/jsx/connectkit/adapters/BitcoinAdapter.native.js +5 -15
  217. package/dist/jsx/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
  218. package/dist/jsx/connectkit/adapters/EthereumAdapter.mjs +6 -15
  219. package/dist/jsx/connectkit/adapters/EthereumAdapter.mjs.map +1 -1
  220. package/dist/jsx/connectkit/adapters/EthereumAdapter.native.js +7 -16
  221. package/dist/jsx/connectkit/adapters/EthereumAdapter.native.js.map +1 -1
  222. package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs +5 -14
  223. package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
  224. package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js +5 -15
  225. package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
  226. package/dist/jsx/connectkit/adapters/SuiAdapter.mjs +5 -14
  227. package/dist/jsx/connectkit/adapters/SuiAdapter.mjs.map +1 -1
  228. package/dist/jsx/connectkit/adapters/SuiAdapter.native.js +5 -15
  229. package/dist/jsx/connectkit/adapters/SuiAdapter.native.js.map +1 -1
  230. package/dist/jsx/connectkit/connectors/createWalletMessage.mjs +1 -1
  231. package/dist/jsx/connectkit/connectors/createWalletMessage.native.js +2 -2
  232. package/dist/jsx/connectkit/index.mjs +3 -2
  233. package/dist/jsx/connectkit/index.mjs.map +1 -1
  234. package/dist/jsx/connectkit/index.native.js +4 -3
  235. package/dist/jsx/connectkit/index.native.js.map +1 -1
  236. package/dist/jsx/connectkit/siwe/SIWEContext.mjs.map +1 -1
  237. package/dist/jsx/connectkit/siwe/SIWEContext.native.js.map +1 -1
  238. package/dist/jsx/connectkit/siwe/SIWEProvider.mjs +19 -4
  239. package/dist/jsx/connectkit/siwe/SIWEProvider.mjs.map +1 -1
  240. package/dist/jsx/connectkit/siwe/SIWEProvider.native.js +18 -3
  241. package/dist/jsx/connectkit/siwe/SIWEProvider.native.js.map +1 -1
  242. package/dist/jsx/index.js +1 -0
  243. package/dist/jsx/index.js.map +1 -1
  244. package/dist/jsx/index.mjs +1 -0
  245. package/dist/jsx/index.mjs.map +1 -1
  246. package/dist/jsx/index.native.js +1 -0
  247. package/dist/jsx/index.native.js.map +1 -1
  248. package/dist/jsx/keycloak/KeycloakWalletLogin.mjs +218 -0
  249. package/dist/jsx/keycloak/KeycloakWalletLogin.mjs.map +1 -0
  250. package/dist/jsx/keycloak/KeycloakWalletLogin.native.js +33 -0
  251. package/dist/jsx/keycloak/KeycloakWalletLogin.native.js.map +1 -0
  252. package/dist/jsx/keycloak/browserFlow.mjs +58 -0
  253. package/dist/jsx/keycloak/browserFlow.mjs.map +1 -0
  254. package/dist/jsx/keycloak/browserFlow.native.js +90 -0
  255. package/dist/jsx/keycloak/browserFlow.native.js.map +1 -0
  256. package/dist/jsx/keycloak/device.mjs +10 -0
  257. package/dist/jsx/keycloak/device.mjs.map +1 -0
  258. package/dist/jsx/keycloak/device.native.js +45 -0
  259. package/dist/jsx/keycloak/device.native.js.map +1 -0
  260. package/dist/jsx/keycloak/directGrant.mjs +164 -0
  261. package/dist/jsx/keycloak/directGrant.mjs.map +1 -0
  262. package/dist/jsx/keycloak/directGrant.native.js +233 -0
  263. package/dist/jsx/keycloak/directGrant.native.js.map +1 -0
  264. package/dist/jsx/keycloak/iife.mjs +5 -0
  265. package/dist/jsx/keycloak/iife.mjs.map +1 -0
  266. package/dist/jsx/keycloak/iife.native.js +7 -0
  267. package/dist/jsx/keycloak/iife.native.js.map +1 -0
  268. package/dist/jsx/keycloak/index.mjs +13 -0
  269. package/dist/jsx/keycloak/index.mjs.map +1 -0
  270. package/dist/jsx/keycloak/index.native.js +56 -0
  271. package/dist/jsx/keycloak/index.native.js.map +1 -0
  272. package/dist/jsx/keycloak/keycloakWallet.mjs +186 -0
  273. package/dist/jsx/keycloak/keycloakWallet.mjs.map +1 -0
  274. package/dist/jsx/keycloak/keycloakWallet.native.js +285 -0
  275. package/dist/jsx/keycloak/keycloakWallet.native.js.map +1 -0
  276. package/dist/jsx/keycloak/mount.mjs +28 -0
  277. package/dist/jsx/keycloak/mount.mjs.map +1 -0
  278. package/dist/jsx/keycloak/mount.native.js +33 -0
  279. package/dist/jsx/keycloak/mount.native.js.map +1 -0
  280. package/dist/jsx/keycloak/registerWallet.mjs +49 -0
  281. package/dist/jsx/keycloak/registerWallet.mjs.map +1 -0
  282. package/dist/jsx/keycloak/registerWallet.native.js +81 -0
  283. package/dist/jsx/keycloak/registerWallet.native.js.map +1 -0
  284. package/dist/jsx/keycloak/types.mjs +20 -0
  285. package/dist/jsx/keycloak/types.mjs.map +1 -0
  286. package/dist/jsx/keycloak/types.native.js +179 -0
  287. package/dist/jsx/keycloak/types.native.js.map +1 -0
  288. package/dist/jsx/keycloak/useDirectLogin.mjs +32 -0
  289. package/dist/jsx/keycloak/useDirectLogin.mjs.map +1 -0
  290. package/dist/jsx/keycloak/useDirectLogin.native.js +77 -0
  291. package/dist/jsx/keycloak/useDirectLogin.native.js.map +1 -0
  292. package/dist/jsx/keycloak/useWalletLogin.mjs +72 -0
  293. package/dist/jsx/keycloak/useWalletLogin.mjs.map +1 -0
  294. package/dist/jsx/keycloak/useWalletLogin.native.js +33 -0
  295. package/dist/jsx/keycloak/useWalletLogin.native.js.map +1 -0
  296. package/dist/jsx/message/buildWalletMessage.mjs +87 -0
  297. package/dist/jsx/message/buildWalletMessage.mjs.map +1 -0
  298. package/dist/jsx/message/buildWalletMessage.native.js +121 -0
  299. package/dist/jsx/message/buildWalletMessage.native.js.map +1 -0
  300. package/dist/jsx/message/index.mjs +3 -0
  301. package/dist/jsx/message/index.mjs.map +1 -0
  302. package/dist/jsx/message/index.native.js +32 -0
  303. package/dist/jsx/message/index.native.js.map +1 -0
  304. package/dist/jsx/providers/WalletProvider.mjs +9 -3
  305. package/dist/jsx/providers/WalletProvider.mjs.map +1 -1
  306. package/dist/jsx/siws/message.mjs +5 -16
  307. package/dist/jsx/siws/message.mjs.map +1 -1
  308. package/dist/jsx/siws/message.native.js +6 -16
  309. package/dist/jsx/siws/message.native.js.map +1 -1
  310. package/dist/jsx/solana.mjs.map +1 -1
  311. package/dist/jsx/solana.native.js.map +1 -1
  312. package/dist/keycloak/login.iife.js +3604 -0
  313. package/package.json +27 -8
  314. package/src/clients/evm.spec.ts +644 -10
  315. package/src/clients/evm.ts +498 -10
  316. package/src/clients/index.ts +8 -0
  317. package/src/clients/solana.spec.ts +116 -0
  318. package/src/clients/solana.ts +51 -31
  319. package/src/connectkit/GpgProvider.tsx +16 -0
  320. package/src/connectkit/adapters/BitcoinAdapter.ts +5 -16
  321. package/src/connectkit/adapters/EthereumAdapter.ts +6 -17
  322. package/src/connectkit/adapters/SolanaAdapter.ts +5 -16
  323. package/src/connectkit/adapters/SuiAdapter.ts +5 -16
  324. package/src/connectkit/connectors/createWalletMessage.ts +1 -1
  325. package/src/connectkit/index.ts +2 -6
  326. package/src/connectkit/openConnector/modal.spec.tsx +1 -1
  327. package/src/connectkit/siwe/SIWEContext.tsx +6 -2
  328. package/src/connectkit/siwe/SIWEProvider.tsx +22 -5
  329. package/src/index.ts +3 -0
  330. package/src/keycloak/KeycloakWalletLogin.native.tsx +7 -0
  331. package/src/keycloak/KeycloakWalletLogin.spec.tsx +168 -0
  332. package/src/keycloak/KeycloakWalletLogin.tsx +251 -0
  333. package/src/keycloak/browserFlow.spec.ts +108 -0
  334. package/src/keycloak/browserFlow.ts +84 -0
  335. package/src/keycloak/device.ts +17 -0
  336. package/src/keycloak/directGrant.spec.ts +331 -0
  337. package/src/keycloak/directGrant.ts +214 -0
  338. package/src/keycloak/iife.ts +3 -0
  339. package/src/keycloak/index.ts +44 -0
  340. package/src/keycloak/keycloakWallet.spec.ts +216 -0
  341. package/src/keycloak/keycloakWallet.ts +275 -0
  342. package/src/keycloak/mount.native.ts +11 -0
  343. package/src/keycloak/mount.tsx +45 -0
  344. package/src/keycloak/nonceReset.spec.tsx +205 -0
  345. package/src/keycloak/registerWallet.spec.ts +88 -0
  346. package/src/keycloak/registerWallet.ts +59 -0
  347. package/src/keycloak/types.ts +66 -0
  348. package/src/keycloak/useDirectLogin.spec.tsx +112 -0
  349. package/src/keycloak/useDirectLogin.ts +74 -0
  350. package/src/keycloak/useWalletLogin.native.ts +7 -0
  351. package/src/keycloak/useWalletLogin.ts +99 -0
  352. package/src/message/buildWalletMessage.spec.ts +291 -0
  353. package/src/message/buildWalletMessage.ts +150 -0
  354. package/src/message/index.ts +8 -0
  355. package/src/providers/WalletProvider.tsx +15 -2
  356. package/src/siws/message.ts +3 -22
  357. package/src/solana.ts +1 -0
  358. package/types/clients/evm.d.ts +144 -2
  359. package/types/clients/evm.d.ts.map +1 -1
  360. package/types/clients/index.d.ts +1 -1
  361. package/types/clients/index.d.ts.map +1 -1
  362. package/types/clients/solana.d.ts +14 -5
  363. package/types/clients/solana.d.ts.map +1 -1
  364. package/types/connectkit/GpgProvider.d.ts +10 -0
  365. package/types/connectkit/GpgProvider.d.ts.map +1 -0
  366. package/types/connectkit/adapters/BitcoinAdapter.d.ts.map +1 -1
  367. package/types/connectkit/adapters/EthereumAdapter.d.ts.map +1 -1
  368. package/types/connectkit/adapters/SolanaAdapter.d.ts.map +1 -1
  369. package/types/connectkit/adapters/SuiAdapter.d.ts.map +1 -1
  370. package/types/connectkit/connectors/createWalletMessage.d.ts +1 -1
  371. package/types/connectkit/connectors/createWalletMessage.d.ts.map +1 -1
  372. package/types/connectkit/index.d.ts +3 -2
  373. package/types/connectkit/index.d.ts.map +1 -1
  374. package/types/connectkit/siwe/SIWEContext.d.ts +2 -1
  375. package/types/connectkit/siwe/SIWEContext.d.ts.map +1 -1
  376. package/types/connectkit/siwe/SIWEProvider.d.ts.map +1 -1
  377. package/types/index.d.ts +1 -0
  378. package/types/index.d.ts.map +1 -1
  379. package/types/keycloak/KeycloakWalletLogin.d.ts +45 -0
  380. package/types/keycloak/KeycloakWalletLogin.d.ts.map +1 -0
  381. package/types/keycloak/KeycloakWalletLogin.native.d.ts +4 -0
  382. package/types/keycloak/KeycloakWalletLogin.native.d.ts.map +1 -0
  383. package/types/keycloak/browserFlow.d.ts +27 -0
  384. package/types/keycloak/browserFlow.d.ts.map +1 -0
  385. package/types/keycloak/device.d.ts +14 -0
  386. package/types/keycloak/device.d.ts.map +1 -0
  387. package/types/keycloak/directGrant.d.ts +43 -0
  388. package/types/keycloak/directGrant.d.ts.map +1 -0
  389. package/types/keycloak/iife.d.ts +2 -0
  390. package/types/keycloak/iife.d.ts.map +1 -0
  391. package/types/keycloak/index.d.ts +12 -0
  392. package/types/keycloak/index.d.ts.map +1 -0
  393. package/types/keycloak/keycloakWallet.d.ts +120 -0
  394. package/types/keycloak/keycloakWallet.d.ts.map +1 -0
  395. package/types/keycloak/mount.d.ts +16 -0
  396. package/types/keycloak/mount.d.ts.map +1 -0
  397. package/types/keycloak/mount.native.d.ts +5 -0
  398. package/types/keycloak/mount.native.d.ts.map +1 -0
  399. package/types/keycloak/registerWallet.d.ts +22 -0
  400. package/types/keycloak/registerWallet.d.ts.map +1 -0
  401. package/types/keycloak/types.d.ts +50 -0
  402. package/types/keycloak/types.d.ts.map +1 -0
  403. package/types/keycloak/useDirectLogin.d.ts +29 -0
  404. package/types/keycloak/useDirectLogin.d.ts.map +1 -0
  405. package/types/keycloak/useWalletLogin.d.ts +26 -0
  406. package/types/keycloak/useWalletLogin.d.ts.map +1 -0
  407. package/types/keycloak/useWalletLogin.native.d.ts +4 -0
  408. package/types/keycloak/useWalletLogin.native.d.ts.map +1 -0
  409. package/types/message/buildWalletMessage.d.ts +46 -0
  410. package/types/message/buildWalletMessage.d.ts.map +1 -0
  411. package/types/message/index.d.ts +2 -0
  412. package/types/message/index.d.ts.map +1 -0
  413. package/types/providers/WalletProvider.d.ts +8 -1
  414. package/types/providers/WalletProvider.d.ts.map +1 -1
  415. package/types/siws/message.d.ts.map +1 -1
  416. package/types/solana.d.ts +1 -1
  417. package/types/solana.d.ts.map +1 -1
  418. package/dist/cjs/connectkit/adapters/messages.cjs +0 -73
  419. package/dist/cjs/connectkit/adapters/messages.native.js +0 -79
  420. package/dist/cjs/connectkit/adapters/messages.native.js.map +0 -1
  421. package/dist/esm/connectkit/adapters/messages.mjs +0 -48
  422. package/dist/esm/connectkit/adapters/messages.mjs.map +0 -1
  423. package/dist/esm/connectkit/adapters/messages.native.js +0 -51
  424. package/dist/esm/connectkit/adapters/messages.native.js.map +0 -1
  425. package/dist/jsx/connectkit/adapters/messages.mjs +0 -48
  426. package/dist/jsx/connectkit/adapters/messages.mjs.map +0 -1
  427. package/dist/jsx/connectkit/adapters/messages.native.js +0 -79
  428. package/dist/jsx/connectkit/adapters/messages.native.js.map +0 -1
  429. package/src/connectkit/adapters/messages.ts +0 -84
  430. package/types/connectkit/adapters/messages.d.ts +0 -16
  431. package/types/connectkit/adapters/messages.d.ts.map +0 -1
@@ -274,6 +274,122 @@ describe("confirmTransaction against the blockhash lifetime", () => {
274
274
  });
275
275
  });
276
276
 
277
+ describe("confirmTransaction when a poll fails", () => {
278
+ const outage = () => new Error("fetch failed: 503 Service Unavailable");
279
+
280
+ // Each RPC method answers from its script in order; a function entry throws.
281
+ function flaky(script: {
282
+ statuses: (({ confirmationStatus: string } | null) | (() => never))[];
283
+ heights?: (bigint | (() => never))[];
284
+ }) {
285
+ const statuses = [...script.statuses];
286
+ const heights = [...(script.heights ?? [])];
287
+ const answer = <T>(queue: (T | (() => never))[]) => {
288
+ const next = queue.length > 1 ? queue.shift() : queue[0];
289
+ return typeof next === "function" ? (next as () => never)() : next;
290
+ };
291
+ return {
292
+ getSignatureStatuses: vi.fn(() => ({
293
+ send: async () => ({ value: [answer(statuses) ?? null] }),
294
+ })),
295
+ getBlockHeight: vi.fn(() => ({ send: async () => answer(heights) })),
296
+ } as unknown as Rpc<SolanaRpcApi> & {
297
+ getSignatureStatuses: ReturnType<typeof vi.fn>;
298
+ getBlockHeight: ReturnType<typeof vi.fn>;
299
+ };
300
+ }
301
+
302
+ const confirm = (rpc: Rpc<SolanaRpcApi>, lastValidBlockHeight?: bigint) =>
303
+ solanaClient({ signer: mockSigner(), rpc })
304
+ .confirmTransaction({ signature: "sig" as never, lastValidBlockHeight }, { pollMs: 0 })
305
+ .catch((e: unknown) => e);
306
+
307
+ it("wraps a getSignatureStatuses failure, saying the transaction may still land", async () => {
308
+ const cause = outage();
309
+ const error = await confirm(
310
+ flaky({
311
+ statuses: [
312
+ () => {
313
+ throw cause;
314
+ },
315
+ ],
316
+ }),
317
+ );
318
+ expect(error).toBeInstanceOf(SolanaConfirmationError);
319
+ expect(error).toMatchObject({ reason: "rpc", mayStillLand: true, lastStatus: null, cause });
320
+ expect((error as Error).message).toMatch(
321
+ /getSignatureStatuses failed \(fetch failed: 503 Service Unavailable\).*may still land, so do not resend/,
322
+ );
323
+ });
324
+
325
+ it("wraps a getBlockHeight failure and carries the last status the poll saw", async () => {
326
+ const cause = outage();
327
+ const rpc = flaky({
328
+ statuses: [{ confirmationStatus: "processed" }],
329
+ heights: [
330
+ 5n,
331
+ () => {
332
+ throw cause;
333
+ },
334
+ ],
335
+ });
336
+ const error = await confirm(rpc, 10n);
337
+ expect(error).toBeInstanceOf(SolanaConfirmationError);
338
+ expect(error).toMatchObject({
339
+ reason: "rpc",
340
+ mayStillLand: true,
341
+ lastStatus: "processed",
342
+ cause,
343
+ });
344
+ expect((error as Error).message).toMatch(/getBlockHeight failed/);
345
+ expect(rpc.getBlockHeight).toHaveBeenCalledTimes(2);
346
+ });
347
+
348
+ it("wraps a method that throws before it sends", async () => {
349
+ const cause = new TypeError("rpc transport closed");
350
+ const rpc = {
351
+ getSignatureStatuses: () => {
352
+ throw cause;
353
+ },
354
+ } as unknown as Rpc<SolanaRpcApi>;
355
+ const error = await confirm(rpc);
356
+ expect(error).toMatchObject({ reason: "rpc", mayStillLand: true, cause });
357
+ });
358
+
359
+ it("reports a failed final check past the blockhash as rpc, never as expired", async () => {
360
+ const rpc = flaky({
361
+ statuses: [
362
+ null,
363
+ () => {
364
+ throw outage();
365
+ },
366
+ ],
367
+ heights: [11n],
368
+ });
369
+ const error = await confirm(rpc, 10n);
370
+ expect(error).toMatchObject({ reason: "rpc", mayStillLand: true });
371
+ expect(error).not.toMatchObject({ reason: "expired" });
372
+ });
373
+
374
+ it("confirms the same submission once the RPC recovers, without sending it again", async () => {
375
+ const rpc = flaky({
376
+ statuses: [
377
+ () => {
378
+ throw outage();
379
+ },
380
+ { confirmationStatus: "confirmed" },
381
+ ],
382
+ });
383
+ const client = solanaClient({ signer: mockSigner(), rpc });
384
+ const submission = { signature: "sig" as never, lastValidBlockHeight: 10n };
385
+ await expect(client.confirmTransaction(submission, { pollMs: 0 })).rejects.toMatchObject({
386
+ reason: "rpc",
387
+ mayStillLand: true,
388
+ });
389
+ await expect(client.confirmTransaction(submission, { pollMs: 0 })).resolves.toBeUndefined();
390
+ });
391
+ });
392
+
277
393
  describe("transferSol", () => {
278
394
  const blockhash = b58(new Uint8Array(32).fill(4));
279
395
 
@@ -91,29 +91,38 @@ export interface SolanaSubmission {
91
91
  lastValidBlockHeight?: bigint;
92
92
  }
93
93
 
94
- export type SolanaConfirmationFailure = "failed" | "expired" | "timeout";
94
+ export type SolanaConfirmationFailure = "failed" | "expired" | "timeout" | "rpc";
95
+
96
+ export type SolanaCommitmentStatus = "processed" | "confirmed" | "finalized";
95
97
 
96
98
  /**
97
99
  * confirmTransaction's failure. `mayStillLand` is the part a caller acts on:
98
- * resending while it is true can pay twice.
100
+ * resending while it is true can pay twice. `rpc` means a status or block
101
+ * height poll failed, which says nothing about the transaction, so confirm the
102
+ * same submission again rather than sending a new one.
99
103
  */
100
104
  export class SolanaConfirmationError extends Error {
101
105
  readonly mayStillLand: boolean;
106
+ /** The last confirmationStatus the poll saw, or null when it never saw the signature. */
107
+ readonly lastStatus: SolanaCommitmentStatus | null;
102
108
  constructor(
103
109
  readonly signature: Signature,
104
110
  readonly reason: SolanaConfirmationFailure,
105
111
  detail: string,
112
+ options: { lastStatus?: SolanaCommitmentStatus | null; cause?: unknown } = {},
106
113
  ) {
107
- const mayStillLand = reason === "timeout";
114
+ const mayStillLand = reason === "timeout" || reason === "rpc";
108
115
  super(
109
116
  `solana transaction ${signature} ${detail}; ${
110
117
  mayStillLand
111
118
  ? "it may still land, so do not resend it until its blockhash expires"
112
119
  : "it will not land, so it is safe to retry"
113
120
  }`,
121
+ { cause: options.cause },
114
122
  );
115
123
  this.name = "SolanaConfirmationError";
116
124
  this.mayStillLand = mayStillLand;
125
+ this.lastStatus = options.lastStatus ?? null;
117
126
  }
118
127
  }
119
128
 
@@ -141,8 +150,9 @@ export interface SolanaClient extends ChainClient<"solana"> {
141
150
  /**
142
151
  * Resolves once the transaction reaches `commitment`. Rejects with
143
152
  * SolanaConfirmationError: `failed` (it landed and errored), `expired` (block
144
- * height passed lastValidBlockHeight without it, safe to retry) or `timeout`
145
- * (no lastValidBlockHeight to judge by, so it may still land).
153
+ * height passed lastValidBlockHeight without it, safe to retry), `timeout`
154
+ * (no lastValidBlockHeight to judge by, so it may still land) or `rpc` (a
155
+ * poll failed, so it may still land; confirm it again).
146
156
  */
147
157
  confirmTransaction(
148
158
  submission: SolanaSubmission | Signature,
@@ -206,7 +216,7 @@ const lastValidBlockHeightOf = (transaction: Transaction | Uint8Array): bigint |
206
216
 
207
217
  type SignatureStatus = {
208
218
  err: unknown;
209
- confirmationStatus: "processed" | "confirmed" | "finalized" | null;
219
+ confirmationStatus: SolanaCommitmentStatus | null;
210
220
  } | null;
211
221
 
212
222
  const reached = (status: SignatureStatus, commitment: "confirmed" | "finalized") =>
@@ -251,21 +261,6 @@ export function solanaClient(config: SolanaClientConfig): SolanaClient {
251
261
  return { signature: await broadcast(await signer.signTransaction(wire)), lastValidBlockHeight };
252
262
  };
253
263
 
254
- const statusOf = async (signature: Signature): Promise<SignatureStatus> => {
255
- const { value } = await rpc
256
- .getSignatureStatuses([signature], { searchTransactionHistory: true })
257
- .send();
258
- const status = value[0] as SignatureStatus;
259
- if (status?.err) {
260
- throw new SolanaConfirmationError(
261
- signature,
262
- "failed",
263
- `failed on chain: ${JSON.stringify(status.err, (_, v) => (typeof v === "bigint" ? `${v}` : v))}`,
264
- );
265
- }
266
- return status;
267
- };
268
-
269
264
  return {
270
265
  family: "solana",
271
266
  address: owner,
@@ -290,28 +285,53 @@ export function solanaClient(config: SolanaClientConfig): SolanaClient {
290
285
  pollMs = 500,
291
286
  } = options;
292
287
  const deadline = Date.now() + timeoutMs;
288
+ let lastStatus: SolanaCommitmentStatus | null = null;
289
+ const fail = (reason: SolanaConfirmationFailure, detail: string, cause?: unknown) =>
290
+ new SolanaConfirmationError(signature, reason, detail, { lastStatus, cause });
291
+ const poll = async <T>(method: string, call: () => Promise<T>): Promise<T> => {
292
+ try {
293
+ return await call();
294
+ } catch (error) {
295
+ throw fail(
296
+ "rpc",
297
+ `was not confirmed: ${method} failed (${error instanceof Error ? error.message : String(error)})`,
298
+ error,
299
+ );
300
+ }
301
+ };
302
+ const statusOf = async (): Promise<SignatureStatus> => {
303
+ const { value } = await poll("getSignatureStatuses", () =>
304
+ rpc.getSignatureStatuses([signature], { searchTransactionHistory: true }).send(),
305
+ );
306
+ const status = value[0] as SignatureStatus;
307
+ if (status?.confirmationStatus) lastStatus = status.confirmationStatus;
308
+ if (status?.err) {
309
+ throw fail(
310
+ "failed",
311
+ `failed on chain: ${JSON.stringify(status.err, (_, v) => (typeof v === "bigint" ? `${v}` : v))}`,
312
+ );
313
+ }
314
+ return status;
315
+ };
293
316
  for (;;) {
294
- if (reached(await statusOf(signature), commitment)) return;
317
+ if (reached(await statusOf(), commitment)) return;
295
318
  if (lastValidBlockHeight !== undefined) {
296
- const height = await rpc.getBlockHeight({ commitment }).send();
319
+ const height = await poll("getBlockHeight", () =>
320
+ rpc.getBlockHeight({ commitment }).send(),
321
+ );
297
322
  if (height > lastValidBlockHeight) {
298
323
  // It can no longer be included, but it may have been in the last valid block.
299
- const status = await statusOf(signature);
324
+ const status = await statusOf();
300
325
  if (reached(status, commitment)) return;
301
326
  if (!status) {
302
- throw new SolanaConfirmationError(
303
- signature,
327
+ throw fail(
304
328
  "expired",
305
329
  `expired: block height ${height} passed ${lastValidBlockHeight}`,
306
330
  );
307
331
  }
308
332
  }
309
333
  } else if (Date.now() > deadline) {
310
- throw new SolanaConfirmationError(
311
- signature,
312
- "timeout",
313
- `not ${commitment} after ${timeoutMs}ms`,
314
- );
334
+ throw fail("timeout", `not ${commitment} after ${timeoutMs}ms`);
315
335
  }
316
336
  await sleep(pollMs);
317
337
  }
@@ -0,0 +1,16 @@
1
+ import { GpgProvider as BaseGpgProvider, type GpgConfig } from "@multiplatform.one/gpg";
2
+ import type { ComponentProps } from "react";
3
+ import { buildWalletMessage } from "../message";
4
+
5
+ type GpgProviderProps = Omit<ComponentProps<typeof BaseGpgProvider>, "buildMessage"> &
6
+ Partial<Pick<GpgConfig, "buildMessage">>;
7
+
8
+ const buildGpgMessage = ({ nonce }: { nonce: string }) => buildWalletMessage("gpg", { nonce });
9
+
10
+ /**
11
+ * `@multiplatform.one/gpg`'s GpgProvider, signing mpo web3's GPG message
12
+ * (`buildWalletMessage("gpg")` on the page's host) unless given a builder.
13
+ */
14
+ export function GpgProvider({ buildMessage = buildGpgMessage, ...props }: GpgProviderProps) {
15
+ return <BaseGpgProvider {...props} buildMessage={buildMessage} />;
16
+ }
@@ -14,6 +14,7 @@
14
14
  // pick the "payment" (native-segwit) account; if a wallet's active address is
15
15
  // taproot (`bc1p…`) the server rejects it.
16
16
 
17
+ import { buildWalletMessage } from "../../message";
17
18
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
18
19
 
19
20
  interface UnisatProvider {
@@ -89,22 +90,10 @@ export class BitcoinAdapter implements WalletAdapter {
89
90
  /** Build the canonical SIWB message the Java BitcoinMessage parser accepts. */
90
91
  async buildMessage(opts: SignInMessageOptions): Promise<string> {
91
92
  if (!this.address) throw new Error("connect a Bitcoin wallet first");
92
- const domain = opts.domain ?? window.location.host;
93
- const uri = opts.uri ?? window.location.origin;
94
- const issuedAt = opts.issuedAt ?? new Date().toISOString();
95
- const statement = opts.statement ?? "Sign in With Bitcoin.";
96
- return (
97
- `${domain} wants you to sign in with your Bitcoin account:\n` +
98
- `${this.address}\n` +
99
- `\n` +
100
- `${statement}\n` +
101
- `\n` +
102
- `URI: ${uri}\n` +
103
- `Version: 1\n` +
104
- `Chain ID: bitcoin\n` +
105
- `Nonce: ${opts.nonce}\n` +
106
- `Issued At: ${issuedAt}`
107
- );
93
+ return buildWalletMessage("btc", {
94
+ ...opts,
95
+ address: this.address,
96
+ });
108
97
  }
109
98
 
110
99
  /** BIP-322 simple signature (base64) — submitted as keycloak's username. */
@@ -10,6 +10,7 @@
10
10
  // checksummed address, so we checksum via viem's getAddress (already bundled).
11
11
 
12
12
  import { getAddress } from "viem";
13
+ import { buildWalletMessage } from "../../message";
13
14
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
14
15
 
15
16
  interface Eip1193Provider {
@@ -58,23 +59,11 @@ export class EthereumAdapter implements WalletAdapter {
58
59
  /** Build the canonical EIP-4361 message the Java SiweUtil/moonstoneid verifies. */
59
60
  async buildMessage(opts: SignInMessageOptions): Promise<string> {
60
61
  if (!this.address) throw new Error("connect an EVM wallet first");
61
- const domain = opts.domain ?? window.location.host;
62
- const uri = opts.uri ?? window.location.origin;
63
- const issuedAt = opts.issuedAt ?? new Date().toISOString();
64
- const statement = opts.statement ?? "Sign in With Ethereum.";
65
- const chainId = this.networkId ?? 1;
66
- return (
67
- `${domain} wants you to sign in with your Ethereum account:\n` +
68
- `${this.address}\n` +
69
- `\n` +
70
- `${statement}\n` +
71
- `\n` +
72
- `URI: ${uri}\n` +
73
- `Version: 1\n` +
74
- `Chain ID: ${chainId}\n` +
75
- `Nonce: ${opts.nonce}\n` +
76
- `Issued At: ${issuedAt}`
77
- );
62
+ return buildWalletMessage("eth", {
63
+ ...opts,
64
+ address: this.address,
65
+ chainId: this.networkId ?? 1,
66
+ });
78
67
  }
79
68
 
80
69
  /** personal_sign — returns the 0x hex signature, submitted as keycloak's username. */
@@ -11,6 +11,7 @@
11
11
  // (A future system-browser / Mobile-Wallet-Adapter path — the Solana analogue
12
12
  // of a relay — would be a separate adapter, same as the Ethereum gap.)
13
13
 
14
+ import { buildWalletMessage } from "../../message";
14
15
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
15
16
 
16
17
  const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -84,22 +85,10 @@ export class SolanaAdapter implements WalletAdapter {
84
85
  /** Build the canonical SIWS message the Java SiwsMessage parser accepts. */
85
86
  async buildMessage(opts: SignInMessageOptions): Promise<string> {
86
87
  if (!this.address) throw new Error("connect a Solana wallet first");
87
- const domain = opts.domain ?? window.location.host;
88
- const uri = opts.uri ?? window.location.origin;
89
- const issuedAt = opts.issuedAt ?? new Date().toISOString();
90
- const statement = opts.statement ?? "Sign in With Solana.";
91
- return (
92
- `${domain} wants you to sign in with your Solana account:\n` +
93
- `${this.address}\n` +
94
- `\n` +
95
- `${statement}\n` +
96
- `\n` +
97
- `URI: ${uri}\n` +
98
- `Version: 1\n` +
99
- `Chain ID: solana:mainnet\n` +
100
- `Nonce: ${opts.nonce}\n` +
101
- `Issued At: ${issuedAt}`
102
- );
88
+ return buildWalletMessage("sol", {
89
+ ...opts,
90
+ address: this.address,
91
+ });
103
92
  }
104
93
 
105
94
  /** Sign the UTF-8 message bytes; returns the base58 ed25519 signature. */
@@ -11,6 +11,7 @@
11
11
  // from `sui:signPersonalMessage`), password = base64(message); the message's
12
12
  // address line is the 0x Sui address (blake2b256(flag||pubkey)).
13
13
 
14
+ import { buildWalletMessage } from "../../message";
14
15
  import type { SignInMessageOptions, WalletAdapter, WalletAddress } from "./types";
15
16
 
16
17
  interface StandardWallet {
@@ -99,22 +100,10 @@ export class SuiAdapter implements WalletAdapter {
99
100
  /** Build the canonical SIWU message the Java SuiMessage parser accepts. */
100
101
  async buildMessage(opts: SignInMessageOptions): Promise<string> {
101
102
  if (!this.address) throw new Error("connect a Sui wallet first");
102
- const domain = opts.domain ?? window.location.host;
103
- const uri = opts.uri ?? window.location.origin;
104
- const issuedAt = opts.issuedAt ?? new Date().toISOString();
105
- const statement = opts.statement ?? "Sign in With Sui.";
106
- return (
107
- `${domain} wants you to sign in with your Sui account:\n` +
108
- `${this.address}\n` +
109
- `\n` +
110
- `${statement}\n` +
111
- `\n` +
112
- `URI: ${uri}\n` +
113
- `Version: 1\n` +
114
- `Chain ID: sui:mainnet\n` +
115
- `Nonce: ${opts.nonce}\n` +
116
- `Issued At: ${issuedAt}`
117
- );
103
+ return buildWalletMessage("sui", {
104
+ ...opts,
105
+ address: this.address,
106
+ });
118
107
  }
119
108
 
120
109
  /** Sui's serialized signature (flag||sig||pubkey, base64) — submitted as keycloak's username. */
@@ -1,4 +1,4 @@
1
- import { buildWalletMessage, type SignerFamily } from "../adapters/messages";
1
+ import { buildWalletMessage, type SignerFamily } from "../../message";
2
2
  import { ecosystemBySyntheticChainId } from "./syntheticChains";
3
3
 
4
4
  /** Derive the signer family from the (possibly synthetic) chainId of the active connector. */
@@ -26,12 +26,12 @@ export type { SIWESession, SIWEConfig } from "./siwe";
26
26
  // Sign-In With GPG (SIWG) — a separate, connection-free signer that opens the SAME
27
27
  // modal to a GPG screen. Pulls in NO wagmi/viem; destined for a standalone gpg package.
28
28
  export {
29
- GpgProvider,
30
29
  useGpg,
31
30
  GpgStatusState,
32
31
  GPG_NONCE_QUERY_KEY,
33
32
  SignInWithGpgButton,
34
33
  } from "@multiplatform.one/gpg";
34
+ export { GpgProvider } from "./GpgProvider";
35
35
  export type { GpgConfig } from "@multiplatform.one/gpg";
36
36
 
37
37
  export { ConnectKitProvider } from "./web3Provider";
@@ -88,11 +88,7 @@ export {
88
88
  // The unified sign-in message layer: ONE source of truth for the SIWx message per
89
89
  // signer family, and a chain-agnostic createMessage to plug into SIWEConfig so all
90
90
  // chains sign in through ConnectKit's single signIn().
91
- export {
92
- buildWalletMessage,
93
- type SignerFamily,
94
- type WalletMessageOptions,
95
- } from "./adapters/messages";
91
+ export { buildWalletMessage, type SignerFamily, type WalletMessageOptions } from "../message";
96
92
  export {
97
93
  createWalletMessage,
98
94
  familyFromChainId,
@@ -8,11 +8,11 @@ import { connect } from "wagmi/actions";
8
8
  import { mock } from "wagmi/connectors";
9
9
  import { mainnet } from "wagmi/chains";
10
10
  import { routes, useContext } from "@multiplatform.one/connectkit";
11
- import { GpgProvider } from "@multiplatform.one/gpg";
12
11
 
13
12
  import {
14
13
  ConnectKitProvider,
15
14
  DEFAULT_DESKTOP_OPEN_CONNECTOR_FALLBACK_MS,
15
+ GpgProvider,
16
16
  useModal,
17
17
  type Web3ConnectKitOptions,
18
18
  } from "..";
@@ -46,10 +46,14 @@ export type SIWEConfig = {
46
46
  password: string;
47
47
  message: string;
48
48
  }) => Promise<boolean | void> | boolean | void;
49
+ // Called with a listener on mount; the provider refetches its nonce whenever
50
+ // the listener fires (e.g. keycloakWallet's resetNonce after a direct grant
51
+ // or registration consumed the nonce). Returns the unsubscribe.
52
+ subscribeNonceReset?: (listener: () => void) => () => void;
49
53
  };
50
54
 
51
- export type SIWEContextValue = Required<Omit<SIWEConfig, "onSign">> &
52
- Pick<SIWEConfig, "onSign"> & {
55
+ export type SIWEContextValue = Required<Omit<SIWEConfig, "onSign" | "subscribeNonceReset">> &
56
+ Pick<SIWEConfig, "onSign" | "subscribeNonceReset"> & {
53
57
  nonce: ReturnType<typeof useQuery<string | null>>;
54
58
  session: ReturnType<typeof useQuery<SIWESession | null>>;
55
59
  status: StatusState;
@@ -1,7 +1,7 @@
1
1
  import { ReactNode, useContext, useEffect, useState } from "react";
2
2
  import { useAccount, useAccountEffect, useSignMessage } from "wagmi";
3
3
  import { getAddress } from "viem";
4
- import { useQuery } from "@tanstack/react-query";
4
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
5
5
 
6
6
  import { Context as ConnectKitContext } from "@multiplatform.one/connectkit";
7
7
  import { SIWEContext, SIWEConfig, StatusState, SIWESession } from "./SIWEContext";
@@ -46,6 +46,7 @@ export const SIWEProvider = ({
46
46
  throw new Error("ConnectKitProvider must be mounted inside SIWEProvider.");
47
47
  }
48
48
 
49
+ const queryClient = useQueryClient();
49
50
  const nonce = useQuery({
50
51
  queryKey: [SIWE_NONCE_QUERY_KEY],
51
52
  queryFn: () => siweConfig.getNonce(),
@@ -60,6 +61,15 @@ export const SIWEProvider = ({
60
61
  staleTime: Infinity,
61
62
  });
62
63
 
64
+ const { subscribeNonceReset } = siweConfig;
65
+ const refetchNonce = nonce.refetch;
66
+ useEffect(() => {
67
+ if (!subscribeNonceReset) return;
68
+ return subscribeNonceReset(() => {
69
+ void refetchNonce();
70
+ });
71
+ }, [subscribeNonceReset, refetchNonce]);
72
+
63
73
  const session = useQuery({
64
74
  queryKey: [SIWE_SESSION_QUERY_KEY],
65
75
  queryFn: () => siweConfig.getSession(),
@@ -118,16 +128,23 @@ export const SIWEProvider = ({
118
128
  if (!address) throw new Error("No address found");
119
129
  if (!chainId) throw new Error("No chainId found");
120
130
 
121
- if (!nonce.data) {
131
+ setStatus(StatusState.LOADING);
132
+
133
+ // Read the query live, not this render's `nonce`: right after a reset
134
+ // its data is the nonce the server just dropped, so wait for the refetch.
135
+ const nonceState = queryClient.getQueryState<string>([SIWE_NONCE_QUERY_KEY]);
136
+ const nonceValue =
137
+ nonceState?.fetchStatus === "fetching"
138
+ ? (await nonce.refetch({ cancelRefetch: false })).data
139
+ : nonceState?.data;
140
+ if (!nonceValue) {
122
141
  throw new Error("Could not fetch nonce");
123
142
  }
124
143
 
125
- setStatus(StatusState.LOADING);
126
-
127
144
  const message = await siweConfig.createMessage({
128
145
  address,
129
146
  chainId,
130
- nonce: nonce?.data,
147
+ nonce: nonceValue,
131
148
  });
132
149
 
133
150
  // Ask user to sign message with their wallet. wallet (non-EVM) connectors can't
package/src/index.ts CHANGED
@@ -64,6 +64,9 @@ export { mainnet, polygon, optimism, arbitrum, base, sepolia } from "wagmi/chain
64
64
  // Bridge (Hermes-safe; shared by web + the native WebView host)
65
65
  export * from "./bridge";
66
66
 
67
+ // The one wallet sign-in message builder (Hermes-safe)
68
+ export * from "./message";
69
+
67
70
  // Per-chain clients (EVM on viem, GPG signer, Solana/Sui/Bitcoin message signing;
68
71
  // the Solana kit client is the web-only ./solana subpath)
69
72
  export * from "./clients";
@@ -0,0 +1,7 @@
1
+ import type { KeycloakWalletLoginProps } from "./KeycloakWalletLogin";
2
+
3
+ export type { KeycloakWalletLoginProps };
4
+
5
+ export function KeycloakWalletLogin(_props: KeycloakWalletLoginProps): null {
6
+ throw new Error("KeycloakWalletLogin is web only; a native app signs in with useDirectLogin");
7
+ }