@b3dotfun/sdk 0.1.70-alpha.2 → 0.1.70-alpha.21

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 (355) hide show
  1. package/README.md +3 -3
  2. package/constants/chains/b3Chain.js +3 -1
  3. package/dist/cjs/anyspend/constants/rpc.d.ts +3 -1
  4. package/dist/cjs/anyspend/constants/rpc.js +6 -2
  5. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +9 -1
  6. package/dist/cjs/anyspend/react/components/AnySpend.js +123 -46
  7. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +8 -10
  8. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +15 -3
  9. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +78 -25
  10. package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +32 -13
  11. package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +32 -10
  12. package/dist/cjs/anyspend/react/components/QRDeposit.d.ts +22 -3
  13. package/dist/cjs/anyspend/react/components/QRDeposit.js +25 -16
  14. package/dist/cjs/anyspend/react/components/checkout/CryptoPayPanel.js +18 -11
  15. package/dist/cjs/anyspend/react/components/common/PureTransferView.d.ts +30 -0
  16. package/dist/cjs/anyspend/react/components/common/PureTransferView.js +64 -0
  17. package/dist/cjs/anyspend/react/components/common/TokenBalance.js +4 -5
  18. package/dist/cjs/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +3 -3
  19. package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
  20. package/dist/cjs/anyspend/utils/address.d.ts +2 -1
  21. package/dist/cjs/anyspend/utils/address.js +12 -9
  22. package/dist/cjs/anyspend/utils/chain.d.ts +84 -1
  23. package/dist/cjs/anyspend/utils/chain.js +73 -3
  24. package/dist/cjs/anyspend/utils/token.d.ts +2 -0
  25. package/dist/cjs/anyspend/utils/token.js +15 -1
  26. package/dist/cjs/app.shared.d.ts +9 -1
  27. package/dist/cjs/app.shared.js +19 -0
  28. package/dist/cjs/global-account/app.native.d.ts +1 -1
  29. package/dist/cjs/global-account/better-auth-client.d.ts +3314 -36
  30. package/dist/cjs/global-account/better-auth-client.js +28 -3
  31. package/dist/cjs/global-account/bsmnt.d.ts +2 -2
  32. package/dist/cjs/global-account/bsmnt.native.d.ts +1 -1
  33. package/dist/cjs/global-account/client-manager.d.ts +7 -5
  34. package/dist/cjs/global-account/client-manager.js +51 -4
  35. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +6 -11
  36. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +11 -0
  37. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +12 -0
  38. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +12 -2
  39. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +25 -3
  40. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthProvider.js +45 -4
  41. package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  42. package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +11 -5
  43. package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.js +23 -15
  44. package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +2 -2
  45. package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +8 -6
  46. package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +1 -1
  47. package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +17 -8
  48. package/dist/cjs/global-account/react/components/Send/Send.js +15 -11
  49. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +3 -1
  50. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -5
  51. package/dist/cjs/global-account/react/components/SignInWithB3/components/AuthButton.js +2 -1
  52. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +1 -0
  53. package/dist/cjs/global-account/react/components/SignInWithB3/utils/signInUtils.d.ts +3 -2
  54. package/dist/cjs/global-account/react/components/SignInWithB3/utils/signInUtils.js +3 -3
  55. package/dist/cjs/global-account/react/components/index.d.ts +1 -1
  56. package/dist/cjs/global-account/react/components/index.js +3 -3
  57. package/dist/cjs/global-account/react/hooks/index.d.ts +2 -3
  58. package/dist/cjs/global-account/react/hooks/index.js +7 -10
  59. package/dist/cjs/global-account/react/hooks/useAuth.d.ts +5 -4
  60. package/dist/cjs/global-account/react/hooks/useAuth.js +1 -0
  61. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +3 -2
  62. package/dist/cjs/global-account/react/hooks/useAuthentication.js +2 -1
  63. package/dist/cjs/global-account/react/hooks/useBetterAuth.d.ts +1657 -22
  64. package/dist/cjs/global-account/react/hooks/useBetterAuth.js +7 -7
  65. package/dist/cjs/global-account/react/hooks/useClient.d.ts +3 -3
  66. package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  67. package/dist/cjs/global-account/react/hooks/useFirstEOA.js +1 -0
  68. package/dist/cjs/global-account/react/hooks/useNativeBalance.js +2 -2
  69. package/dist/cjs/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  70. package/dist/cjs/global-account/react/hooks/usePortfolioBalance.js +76 -0
  71. package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  72. package/dist/cjs/global-account/react/hooks/usePortfolioCollectibles.js +178 -0
  73. package/dist/cjs/global-account/react/hooks/useSiwe.d.ts +1 -1
  74. package/dist/cjs/global-account/react/hooks/useSiwe.native.d.ts +1 -1
  75. package/dist/cjs/global-account/react/hooks/useTWAuth.d.ts +1 -1
  76. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.d.ts +1 -0
  77. package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +37 -27
  78. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +14 -2
  79. package/dist/cjs/global-account/types/b3-api.types.d.ts +5 -0
  80. package/dist/cjs/global-account/types/feature-flags.d.ts +5 -5
  81. package/dist/cjs/notifications/services/api.js +1 -0
  82. package/dist/cjs/shared/constants/chains/b3Chain.d.ts +30 -54
  83. package/dist/cjs/shared/constants/chains/b3Chain.js +5 -41
  84. package/dist/cjs/shared/constants/chains/supported.d.ts +1 -49
  85. package/dist/cjs/shared/constants/chains/supported.js +8 -36
  86. package/dist/cjs/shared/constants/index.d.ts +4 -0
  87. package/dist/cjs/shared/utils/chain-transformers.d.ts +4 -4
  88. package/dist/cjs/shared/utils/chain-transformers.js +38 -37
  89. package/dist/cjs/shared/utils/thirdweb-insights.js +2 -2
  90. package/dist/cjs/shared/utils/upload.d.ts +9 -0
  91. package/dist/cjs/shared/utils/upload.js +34 -0
  92. package/dist/cjs/shared/utils/zerionPositions.d.ts +96 -0
  93. package/dist/cjs/shared/utils/zerionPositions.js +188 -0
  94. package/dist/esm/anyspend/constants/rpc.d.ts +3 -1
  95. package/dist/esm/anyspend/constants/rpc.js +5 -1
  96. package/dist/esm/anyspend/react/components/AnySpend.d.ts +9 -1
  97. package/dist/esm/anyspend/react/components/AnySpend.js +124 -47
  98. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +9 -11
  99. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +15 -3
  100. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +80 -27
  101. package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +33 -14
  102. package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +33 -11
  103. package/dist/esm/anyspend/react/components/QRDeposit.d.ts +22 -3
  104. package/dist/esm/anyspend/react/components/QRDeposit.js +27 -18
  105. package/dist/esm/anyspend/react/components/checkout/CryptoPayPanel.js +21 -14
  106. package/dist/esm/anyspend/react/components/common/PureTransferView.d.ts +30 -0
  107. package/dist/esm/anyspend/react/components/common/PureTransferView.js +61 -0
  108. package/dist/esm/anyspend/react/components/common/TokenBalance.js +6 -7
  109. package/dist/esm/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +3 -3
  110. package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
  111. package/dist/esm/anyspend/utils/address.d.ts +2 -1
  112. package/dist/esm/anyspend/utils/address.js +9 -6
  113. package/dist/esm/anyspend/utils/chain.d.ts +84 -1
  114. package/dist/esm/anyspend/utils/chain.js +73 -5
  115. package/dist/esm/anyspend/utils/token.d.ts +2 -0
  116. package/dist/esm/anyspend/utils/token.js +13 -0
  117. package/dist/esm/app.shared.d.ts +9 -1
  118. package/dist/esm/app.shared.js +17 -0
  119. package/dist/esm/global-account/app.native.d.ts +1 -1
  120. package/dist/esm/global-account/better-auth-client.d.ts +3314 -36
  121. package/dist/esm/global-account/better-auth-client.js +27 -4
  122. package/dist/esm/global-account/bsmnt.d.ts +2 -2
  123. package/dist/esm/global-account/bsmnt.native.d.ts +1 -1
  124. package/dist/esm/global-account/client-manager.d.ts +7 -5
  125. package/dist/esm/global-account/client-manager.js +51 -5
  126. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +6 -11
  127. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +11 -0
  128. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +11 -0
  129. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +12 -2
  130. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +26 -4
  131. package/dist/esm/global-account/react/components/B3Provider/BetterAuthProvider.js +46 -5
  132. package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  133. package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +11 -5
  134. package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.js +24 -16
  135. package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +3 -3
  136. package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +9 -7
  137. package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +1 -1
  138. package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +18 -9
  139. package/dist/esm/global-account/react/components/Send/Send.js +16 -12
  140. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +3 -1
  141. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +1 -5
  142. package/dist/esm/global-account/react/components/SignInWithB3/components/AuthButton.js +2 -1
  143. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +1 -0
  144. package/dist/esm/global-account/react/components/SignInWithB3/utils/signInUtils.d.ts +3 -2
  145. package/dist/esm/global-account/react/components/SignInWithB3/utils/signInUtils.js +3 -3
  146. package/dist/esm/global-account/react/components/index.d.ts +1 -1
  147. package/dist/esm/global-account/react/components/index.js +1 -1
  148. package/dist/esm/global-account/react/hooks/index.d.ts +2 -3
  149. package/dist/esm/global-account/react/hooks/index.js +2 -3
  150. package/dist/esm/global-account/react/hooks/useAuth.d.ts +5 -4
  151. package/dist/esm/global-account/react/hooks/useAuth.js +1 -0
  152. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +3 -2
  153. package/dist/esm/global-account/react/hooks/useAuthentication.js +2 -1
  154. package/dist/esm/global-account/react/hooks/useBetterAuth.d.ts +1657 -22
  155. package/dist/esm/global-account/react/hooks/useBetterAuth.js +8 -8
  156. package/dist/esm/global-account/react/hooks/useClient.d.ts +3 -3
  157. package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  158. package/dist/esm/global-account/react/hooks/useFirstEOA.js +1 -0
  159. package/dist/esm/global-account/react/hooks/useNativeBalance.js +1 -1
  160. package/dist/esm/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  161. package/dist/esm/global-account/react/hooks/usePortfolioBalance.js +72 -0
  162. package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  163. package/dist/esm/global-account/react/hooks/usePortfolioCollectibles.js +175 -0
  164. package/dist/esm/global-account/react/hooks/useSiwe.d.ts +1 -1
  165. package/dist/esm/global-account/react/hooks/useSiwe.native.d.ts +1 -1
  166. package/dist/esm/global-account/react/hooks/useTWAuth.d.ts +1 -1
  167. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.d.ts +1 -0
  168. package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +37 -27
  169. package/dist/esm/global-account/react/stores/useModalStore.d.ts +14 -2
  170. package/dist/esm/global-account/types/b3-api.types.d.ts +5 -0
  171. package/dist/esm/global-account/types/feature-flags.d.ts +5 -5
  172. package/dist/esm/notifications/services/api.js +1 -0
  173. package/dist/esm/shared/constants/chains/b3Chain.d.ts +30 -54
  174. package/dist/esm/shared/constants/chains/b3Chain.js +4 -38
  175. package/dist/esm/shared/constants/chains/supported.d.ts +1 -49
  176. package/dist/esm/shared/constants/chains/supported.js +7 -35
  177. package/dist/esm/shared/constants/index.d.ts +4 -0
  178. package/dist/esm/shared/utils/chain-transformers.d.ts +4 -4
  179. package/dist/esm/shared/utils/chain-transformers.js +38 -37
  180. package/dist/esm/shared/utils/thirdweb-insights.js +2 -2
  181. package/dist/esm/shared/utils/upload.d.ts +9 -0
  182. package/dist/esm/shared/utils/upload.js +31 -0
  183. package/dist/esm/shared/utils/zerionPositions.d.ts +96 -0
  184. package/dist/esm/shared/utils/zerionPositions.js +180 -0
  185. package/dist/styles/index.css +1 -1
  186. package/dist/types/anyspend/constants/rpc.d.ts +3 -1
  187. package/dist/types/anyspend/react/components/AnySpend.d.ts +9 -1
  188. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +15 -3
  189. package/dist/types/anyspend/react/components/QRDeposit.d.ts +22 -3
  190. package/dist/types/anyspend/react/components/common/PureTransferView.d.ts +30 -0
  191. package/dist/types/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +3 -3
  192. package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
  193. package/dist/types/anyspend/utils/address.d.ts +2 -1
  194. package/dist/types/anyspend/utils/chain.d.ts +84 -1
  195. package/dist/types/anyspend/utils/token.d.ts +2 -0
  196. package/dist/types/app.shared.d.ts +9 -1
  197. package/dist/types/global-account/app.native.d.ts +1 -1
  198. package/dist/types/global-account/better-auth-client.d.ts +3314 -36
  199. package/dist/types/global-account/bsmnt.d.ts +2 -2
  200. package/dist/types/global-account/bsmnt.native.d.ts +1 -1
  201. package/dist/types/global-account/client-manager.d.ts +7 -5
  202. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +11 -0
  203. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +12 -2
  204. package/dist/types/global-account/react/components/B3Provider/RelayKitProviderWrapper.d.ts +1 -2
  205. package/dist/types/global-account/react/components/SignInWithB3/utils/signInUtils.d.ts +3 -2
  206. package/dist/types/global-account/react/components/index.d.ts +1 -1
  207. package/dist/types/global-account/react/hooks/index.d.ts +2 -3
  208. package/dist/types/global-account/react/hooks/useAuth.d.ts +5 -4
  209. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +3 -2
  210. package/dist/types/global-account/react/hooks/useBetterAuth.d.ts +1657 -22
  211. package/dist/types/global-account/react/hooks/useClient.d.ts +3 -3
  212. package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +4 -7666
  213. package/dist/types/global-account/react/hooks/usePortfolioBalance.d.ts +15 -0
  214. package/dist/types/global-account/react/hooks/usePortfolioCollectibles.d.ts +12 -0
  215. package/dist/types/global-account/react/hooks/useSiwe.d.ts +1 -1
  216. package/dist/types/global-account/react/hooks/useSiwe.native.d.ts +1 -1
  217. package/dist/types/global-account/react/hooks/useTWAuth.d.ts +1 -1
  218. package/dist/types/global-account/react/hooks/useUnifiedChainSwitchAndExecute.d.ts +1 -0
  219. package/dist/types/global-account/react/stores/useModalStore.d.ts +14 -2
  220. package/dist/types/global-account/types/b3-api.types.d.ts +5 -0
  221. package/dist/types/global-account/types/feature-flags.d.ts +5 -5
  222. package/dist/types/shared/constants/chains/b3Chain.d.ts +30 -54
  223. package/dist/types/shared/constants/chains/supported.d.ts +1 -49
  224. package/dist/types/shared/constants/index.d.ts +4 -0
  225. package/dist/types/shared/utils/chain-transformers.d.ts +4 -4
  226. package/dist/types/shared/utils/upload.d.ts +9 -0
  227. package/dist/types/shared/utils/zerionPositions.d.ts +96 -0
  228. package/node_modules/@b3/chain-registry/chains.json +1225 -0
  229. package/node_modules/@b3/chain-registry/dist/chains.json +1225 -0
  230. package/node_modules/@b3/chain-registry/dist/index.cjs +1676 -0
  231. package/node_modules/@b3/chain-registry/dist/index.d.cts +195 -0
  232. package/node_modules/@b3/chain-registry/dist/index.d.ts +195 -0
  233. package/node_modules/@b3/chain-registry/dist/index.mjs +1604 -0
  234. package/node_modules/@b3/chain-registry/dist/src/index.d.ts +193 -0
  235. package/node_modules/@b3/chain-registry/dist/src/index.js +408 -0
  236. package/node_modules/@b3/chain-registry/package.json +66 -0
  237. package/node_modules/@b3/chain-registry/src/index.test.ts +432 -0
  238. package/node_modules/@b3/chain-registry/src/index.ts +672 -0
  239. package/package.json +81 -30
  240. package/src/anyspend/README.md +2 -2
  241. package/src/anyspend/constants/rpc.ts +5 -2
  242. package/src/anyspend/docs/components.md +6 -6
  243. package/src/anyspend/docs/contributing.md +1 -1
  244. package/src/anyspend/docs/hooks.md +3 -3
  245. package/src/anyspend/docs/installation.md +2 -2
  246. package/src/anyspend/react/components/AnySpend.tsx +163 -47
  247. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +10 -11
  248. package/src/anyspend/react/components/AnySpendDeposit.tsx +130 -31
  249. package/src/anyspend/react/components/AnySpendStakeB3.tsx +55 -14
  250. package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +55 -11
  251. package/src/anyspend/react/components/QRDeposit.tsx +101 -22
  252. package/src/anyspend/react/components/__tests__/QRDeposit.test.tsx +331 -0
  253. package/src/anyspend/react/components/checkout/CryptoPayPanel.tsx +38 -16
  254. package/src/anyspend/react/components/common/PureTransferView.tsx +212 -0
  255. package/src/anyspend/react/components/common/TokenBalance.tsx +10 -7
  256. package/src/anyspend/react/hooks/useAnyspendQuote.ts +13 -13
  257. package/src/anyspend/react/hooks/useCreateDepositFirstOrder.ts +4 -4
  258. package/src/anyspend/services/gas.test.ts +95 -18
  259. package/src/anyspend/types/api_req_res.ts +10 -5
  260. package/src/anyspend/utils/__tests__/address.test.ts +39 -0
  261. package/src/anyspend/utils/__tests__/deprecatedChains.test.ts +44 -0
  262. package/src/anyspend/utils/__tests__/toRegistryChainId.test.ts +17 -0
  263. package/src/anyspend/utils/address.ts +8 -6
  264. package/src/anyspend/utils/chain.ts +79 -3
  265. package/src/anyspend/utils/token.ts +14 -0
  266. package/src/app.shared.ts +21 -1
  267. package/src/global-account/app.native.ts +5 -1
  268. package/src/global-account/better-auth-client.ts +30 -4
  269. package/src/global-account/bsmnt.native.ts +5 -1
  270. package/src/global-account/bsmnt.ts +9 -2
  271. package/src/global-account/client-manager.ts +74 -9
  272. package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +6 -11
  273. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +12 -0
  274. package/src/global-account/react/components/B3Provider/B3Provider.tsx +40 -4
  275. package/src/global-account/react/components/B3Provider/BetterAuthProvider.tsx +51 -5
  276. package/src/global-account/react/components/B3Provider/RelayKitProviderWrapper.tsx +11 -11
  277. package/src/global-account/react/components/ManageAccount/ContentTokens.tsx +50 -21
  278. package/src/global-account/react/components/ManageAccount/NFTContent.tsx +5 -3
  279. package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +10 -6
  280. package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +1 -1
  281. package/src/global-account/react/components/ManageAccount/TokenContent.tsx +22 -9
  282. package/src/global-account/react/components/Send/Send.tsx +39 -15
  283. package/src/global-account/react/components/SignInWithB3/BetterAuthSignIn.tsx +12 -1
  284. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +1 -4
  285. package/src/global-account/react/components/SignInWithB3/components/AuthButton.tsx +9 -1
  286. package/src/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.tsx +1 -0
  287. package/src/global-account/react/components/SignInWithB3/utils/signInUtils.ts +4 -4
  288. package/src/global-account/react/components/index.ts +1 -1
  289. package/src/global-account/react/components/ui/button.tsx +1 -2
  290. package/src/global-account/react/hooks/__tests__/useUnifiedChainSwitchAndExecute.test.tsx +156 -0
  291. package/src/global-account/react/hooks/index.ts +2 -3
  292. package/src/global-account/react/hooks/useAuth.ts +5 -4
  293. package/src/global-account/react/hooks/useAuthentication.ts +5 -4
  294. package/src/global-account/react/hooks/useBetterAuth.ts +10 -10
  295. package/src/global-account/react/hooks/useClient.ts +11 -2
  296. package/src/global-account/react/hooks/useFirstEOA.tsx +9 -2
  297. package/src/global-account/react/hooks/useNativeBalance.tsx +1 -1
  298. package/src/global-account/react/hooks/usePortfolioBalance.ts +89 -0
  299. package/src/global-account/react/hooks/usePortfolioCollectibles.ts +212 -0
  300. package/src/global-account/react/hooks/useSiwe.native.tsx +1 -1
  301. package/src/global-account/react/hooks/useSiwe.tsx +1 -1
  302. package/src/global-account/react/hooks/useTWAuth.tsx +1 -1
  303. package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +47 -31
  304. package/src/global-account/react/stores/useModalStore.ts +14 -2
  305. package/src/global-account/types/b3-api.types.ts +5 -1
  306. package/src/notifications/services/api.ts +1 -0
  307. package/src/shared/constants/chains/b3Chain.ts +4 -43
  308. package/src/shared/constants/chains/supported.ts +9 -48
  309. package/src/shared/constants/index.ts +8 -0
  310. package/src/shared/react/hooks/__tests__/useCurrencyConversion.test.ts +54 -43
  311. package/src/shared/utils/__tests__/zerionPositions.test.ts +248 -0
  312. package/src/shared/utils/chain-transformers.ts +41 -39
  313. package/src/shared/utils/thirdweb-insights.ts +2 -2
  314. package/src/shared/utils/upload.ts +48 -0
  315. package/src/shared/utils/zerionPositions.ts +247 -0
  316. package/src/styles/index.css +27 -0
  317. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.d.ts +0 -10
  318. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +0 -46
  319. package/dist/cjs/global-account/react/hooks/useHandleConnectWithPrivy.d.ts +0 -11
  320. package/dist/cjs/global-account/react/hooks/useHandleConnectWithPrivy.js +0 -70
  321. package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +0 -59
  322. package/dist/cjs/global-account/react/hooks/useSimBalance.js +0 -98
  323. package/dist/cjs/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  324. package/dist/cjs/global-account/react/hooks/useSimCollectibles.js +0 -190
  325. package/dist/cjs/global-account/react/utils/simdune.d.ts +0 -7
  326. package/dist/cjs/global-account/react/utils/simdune.js +0 -21
  327. package/dist/cjs/global-account/types/chain-networks.d.ts +0 -44
  328. package/dist/cjs/global-account/types/chain-networks.js +0 -48
  329. package/dist/cjs/shared/generated/chain-networks.json +0 -684
  330. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.d.ts +0 -10
  331. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Privy.js +0 -43
  332. package/dist/esm/global-account/react/hooks/useHandleConnectWithPrivy.d.ts +0 -11
  333. package/dist/esm/global-account/react/hooks/useHandleConnectWithPrivy.js +0 -67
  334. package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +0 -59
  335. package/dist/esm/global-account/react/hooks/useSimBalance.js +0 -93
  336. package/dist/esm/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  337. package/dist/esm/global-account/react/hooks/useSimCollectibles.js +0 -187
  338. package/dist/esm/global-account/react/utils/simdune.d.ts +0 -7
  339. package/dist/esm/global-account/react/utils/simdune.js +0 -17
  340. package/dist/esm/global-account/types/chain-networks.d.ts +0 -44
  341. package/dist/esm/global-account/types/chain-networks.js +0 -45
  342. package/dist/esm/shared/generated/chain-networks.json +0 -684
  343. package/dist/types/global-account/react/components/SignInWithB3/SignInWithB3Privy.d.ts +0 -10
  344. package/dist/types/global-account/react/hooks/useHandleConnectWithPrivy.d.ts +0 -11
  345. package/dist/types/global-account/react/hooks/useSimBalance.d.ts +0 -59
  346. package/dist/types/global-account/react/hooks/useSimCollectibles.d.ts +0 -45
  347. package/dist/types/global-account/react/utils/simdune.d.ts +0 -7
  348. package/dist/types/global-account/types/chain-networks.d.ts +0 -44
  349. package/src/global-account/react/components/SignInWithB3/SignInWithB3Privy.tsx +0 -63
  350. package/src/global-account/react/hooks/useHandleConnectWithPrivy.tsx +0 -79
  351. package/src/global-account/react/hooks/useSimBalance.ts +0 -164
  352. package/src/global-account/react/hooks/useSimCollectibles.ts +0 -238
  353. package/src/global-account/react/utils/simdune.ts +0 -20
  354. package/src/global-account/types/chain-networks.ts +0 -54
  355. package/src/shared/generated/chain-networks.json +0 -684
@@ -1,25 +1,27 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
1
  import { renderHook } from "@testing-library/react";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { useCurrencyConversion } from "../useCurrencyConversion";
4
4
 
5
5
  // Mock the external dependencies
6
6
  // Store mock rates for different quote currencies
7
7
  const mockRates: Record<string, number | undefined> = {};
8
8
 
9
- // Mock store state
10
9
  const mockStoreState: any = {
11
10
  selectedCurrency: "B3",
12
11
  baseCurrency: "B3",
12
+ customCurrencies: {},
13
+ getExchangeRate: vi.fn(() => undefined),
13
14
  setSelectedCurrency: vi.fn(),
14
15
  setBaseCurrency: vi.fn(),
15
16
  };
16
17
 
17
- vi.mock("@b3dotfun/sdk/global-account/react", () => ({
18
- useExchangeRate: vi.fn((params: any) => {
19
- const rate = mockRates[params?.quoteCurrency];
20
- return { rate };
21
- }),
22
- }));
18
+ vi.mock("@tanstack/react-query", async importOriginal => {
19
+ const actual = await importOriginal<typeof import("@tanstack/react-query")>();
20
+ return {
21
+ ...actual,
22
+ useQuery: vi.fn(() => ({ data: mockRates })),
23
+ };
24
+ });
23
25
 
24
26
  vi.mock("@b3dotfun/sdk/shared/utils/number", () => ({
25
27
  formatDisplayNumber: vi.fn((value: any) => {
@@ -29,14 +31,8 @@ vi.mock("@b3dotfun/sdk/shared/utils/number", () => ({
29
31
  }),
30
32
  }));
31
33
 
32
- vi.mock("../../stores/currencyStore", () => ({
33
- useCurrencyStore: vi.fn((selector: any) => {
34
- if (selector) {
35
- return selector(mockStoreState);
36
- }
37
- return mockStoreState;
38
- }),
39
- CURRENCY_SYMBOLS: {
34
+ vi.mock("../../stores/currencyStore", () => {
35
+ const symbols: Record<string, string> = {
40
36
  B3: "B3",
41
37
  USD: "$",
42
38
  EUR: "€",
@@ -47,8 +43,23 @@ vi.mock("../../stores/currencyStore", () => ({
47
43
  ETH: "ETH",
48
44
  SOL: "SOL",
49
45
  KRW: "₩",
50
- },
51
- }));
46
+ };
47
+
48
+ return {
49
+ useCurrencyStore: vi.fn((selector: any) => {
50
+ if (selector) {
51
+ return selector(mockStoreState);
52
+ }
53
+ return mockStoreState;
54
+ }),
55
+ getCurrencySymbol: vi.fn((currency: string) => symbols[currency] ?? currency),
56
+ getCurrencyMetadata: vi.fn(() => undefined),
57
+ };
58
+ });
59
+
60
+ function renderCurrencyConversion() {
61
+ return renderHook(() => useCurrencyConversion());
62
+ }
52
63
 
53
64
  describe("useCurrencyConversion", () => {
54
65
  beforeEach(() => {
@@ -66,7 +77,7 @@ describe("useCurrencyConversion", () => {
66
77
  mockStoreState.selectedCurrency = "B3";
67
78
  mockStoreState.baseCurrency = "B3";
68
79
 
69
- const { result } = renderHook(() => useCurrencyConversion());
80
+ const { result } = renderCurrencyConversion();
70
81
  const formatted = result.current.formatCurrencyValue(100, "B3");
71
82
 
72
83
  expect(formatted).toContain("B3");
@@ -78,7 +89,7 @@ describe("useCurrencyConversion", () => {
78
89
  mockStoreState.selectedCurrency = "USD";
79
90
  mockStoreState.baseCurrency = "B3";
80
91
 
81
- const { result } = renderHook(() => useCurrencyConversion());
92
+ const { result } = renderCurrencyConversion();
82
93
  const formatted = result.current.formatCurrencyValue(100, "B3");
83
94
 
84
95
  expect(formatted).toContain("B3");
@@ -90,7 +101,7 @@ describe("useCurrencyConversion", () => {
90
101
  mockStoreState.selectedCurrency = "USD";
91
102
  mockStoreState.baseCurrency = "B3";
92
103
 
93
- const { result } = renderHook(() => useCurrencyConversion());
104
+ const { result } = renderCurrencyConversion();
94
105
  const formatted = result.current.formatCurrencyValue(100, "B3");
95
106
 
96
107
  expect(formatted).toMatch(/^\$/);
@@ -103,7 +114,7 @@ describe("useCurrencyConversion", () => {
103
114
  mockStoreState.selectedCurrency = "EUR";
104
115
  mockStoreState.baseCurrency = "B3";
105
116
 
106
- const { result } = renderHook(() => useCurrencyConversion());
117
+ const { result } = renderCurrencyConversion();
107
118
  const formatted = result.current.formatCurrencyValue(100, "B3");
108
119
 
109
120
  expect(formatted).toMatch(/^€/);
@@ -115,7 +126,7 @@ describe("useCurrencyConversion", () => {
115
126
  mockStoreState.selectedCurrency = "JPY";
116
127
  mockStoreState.baseCurrency = "B3";
117
128
 
118
- const { result } = renderHook(() => useCurrencyConversion());
129
+ const { result } = renderCurrencyConversion();
119
130
  const formatted = result.current.formatCurrencyValue(100, "B3");
120
131
 
121
132
  expect(formatted).toContain("¥");
@@ -128,7 +139,7 @@ describe("useCurrencyConversion", () => {
128
139
  mockStoreState.selectedCurrency = "KRW";
129
140
  mockStoreState.baseCurrency = "B3";
130
141
 
131
- const { result } = renderHook(() => useCurrencyConversion());
142
+ const { result } = renderCurrencyConversion();
132
143
  const formatted = result.current.formatCurrencyValue(100, "B3");
133
144
 
134
145
  expect(formatted).toContain("₩");
@@ -141,7 +152,7 @@ describe("useCurrencyConversion", () => {
141
152
  mockStoreState.selectedCurrency = "ETH";
142
153
  mockStoreState.baseCurrency = "B3";
143
154
 
144
- const { result } = renderHook(() => useCurrencyConversion());
155
+ const { result } = renderCurrencyConversion();
145
156
  const formatted = result.current.formatCurrencyValue(100, "B3");
146
157
 
147
158
  expect(formatted).toContain("ETH");
@@ -154,7 +165,7 @@ describe("useCurrencyConversion", () => {
154
165
  mockStoreState.selectedCurrency = "SOL";
155
166
  mockStoreState.baseCurrency = "B3";
156
167
 
157
- const { result } = renderHook(() => useCurrencyConversion());
168
+ const { result } = renderCurrencyConversion();
158
169
  const formatted = result.current.formatCurrencyValue(100, "B3");
159
170
 
160
171
  expect(formatted).toContain("SOL");
@@ -166,7 +177,7 @@ describe("useCurrencyConversion", () => {
166
177
  mockStoreState.selectedCurrency = "USD";
167
178
  mockStoreState.baseCurrency = "B3";
168
179
 
169
- const { result } = renderHook(() => useCurrencyConversion());
180
+ const { result } = renderCurrencyConversion();
170
181
  const formatted = result.current.formatCurrencyValue(10, "B3");
171
182
 
172
183
  // 10 * 1.5 = 15
@@ -180,7 +191,7 @@ describe("useCurrencyConversion", () => {
180
191
  mockStoreState.selectedCurrency = "USD";
181
192
  mockStoreState.baseCurrency = "B3";
182
193
 
183
- const { result } = renderHook(() => useCurrencyConversion());
194
+ const { result } = renderCurrencyConversion();
184
195
  const inputValue = 100;
185
196
  const formatted = result.current.formatCurrencyValue(inputValue, "B3");
186
197
 
@@ -193,7 +204,7 @@ describe("useCurrencyConversion", () => {
193
204
  mockStoreState.selectedCurrency = "USD";
194
205
  mockStoreState.baseCurrency = "B3";
195
206
 
196
- const { result } = renderHook(() => useCurrencyConversion());
207
+ const { result } = renderCurrencyConversion();
197
208
 
198
209
  expect(result.current.selectedCurrency).toBe("USD");
199
210
  });
@@ -202,7 +213,7 @@ describe("useCurrencyConversion", () => {
202
213
  mockStoreState.selectedCurrency = "USD";
203
214
  mockStoreState.baseCurrency = "B3";
204
215
 
205
- const { result } = renderHook(() => useCurrencyConversion());
216
+ const { result } = renderCurrencyConversion();
206
217
 
207
218
  expect(result.current.baseCurrency).toBe("B3");
208
219
  });
@@ -213,7 +224,7 @@ describe("useCurrencyConversion", () => {
213
224
  mockStoreState.selectedCurrency = "USD";
214
225
  mockStoreState.baseCurrency = "B3";
215
226
 
216
- const { result } = renderHook(() => useCurrencyConversion());
227
+ const { result } = renderCurrencyConversion();
217
228
 
218
229
  expect(result.current.exchangeRate).toBe(testRate);
219
230
  });
@@ -222,7 +233,7 @@ describe("useCurrencyConversion", () => {
222
233
  mockStoreState.selectedCurrency = "EUR";
223
234
  mockStoreState.baseCurrency = "B3";
224
235
 
225
- const { result } = renderHook(() => useCurrencyConversion());
236
+ const { result } = renderCurrencyConversion();
226
237
 
227
238
  expect(result.current.selectedCurrencySymbol).toBe("€");
228
239
  expect(result.current.baseCurrencySymbol).toBe("B3");
@@ -235,24 +246,24 @@ describe("useCurrencyConversion", () => {
235
246
  mockStoreState.selectedCurrency = "B3";
236
247
  mockStoreState.baseCurrency = "B3";
237
248
 
238
- const { result } = renderHook(() => useCurrencyConversion());
249
+ const { result } = renderCurrencyConversion();
239
250
  const tooltip = result.current.formatTooltipValue(100, "B3");
240
251
 
241
252
  expect(tooltip).toContain("USD");
242
253
  expect(tooltip).toContain("150");
243
254
  });
244
255
 
245
- it("should show base currency when displaying other currency", () => {
256
+ it("shows the USD equivalent regardless of selected display currency", () => {
246
257
  mockRates.EUR = 0.9;
247
258
  mockRates.USD = 1.2;
248
259
  mockStoreState.selectedCurrency = "EUR";
249
260
  mockStoreState.baseCurrency = "B3";
250
261
 
251
- const { result } = renderHook(() => useCurrencyConversion());
262
+ const { result } = renderCurrencyConversion();
252
263
  const tooltip = result.current.formatTooltipValue(100, "B3");
253
264
 
254
- expect(tooltip).toContain("B3");
255
- expect(tooltip).toContain("100");
265
+ expect(tooltip).toContain("USD");
266
+ expect(tooltip).toContain("120");
256
267
  });
257
268
 
258
269
  it("should handle custom currency for base currency", () => {
@@ -261,7 +272,7 @@ describe("useCurrencyConversion", () => {
261
272
  mockStoreState.selectedCurrency = "EUR";
262
273
  mockStoreState.baseCurrency = "B3";
263
274
 
264
- const { result } = renderHook(() => useCurrencyConversion());
275
+ const { result } = renderCurrencyConversion();
265
276
  const tooltip = result.current.formatTooltipValue(100, "B3");
266
277
 
267
278
  expect(tooltip).toContain("USD");
@@ -273,7 +284,7 @@ describe("useCurrencyConversion", () => {
273
284
  mockStoreState.selectedCurrency = "USD";
274
285
  mockStoreState.baseCurrency = "B3";
275
286
 
276
- const { result } = renderHook(() => useCurrencyConversion());
287
+ const { result } = renderCurrencyConversion();
277
288
  const tooltip = result.current.formatTooltipValue(50, "ETH");
278
289
 
279
290
  expect(tooltip).toContain("ETH");
@@ -285,7 +296,7 @@ describe("useCurrencyConversion", () => {
285
296
  mockStoreState.selectedCurrency = "B3";
286
297
  mockStoreState.baseCurrency = "B3";
287
298
 
288
- const { result } = renderHook(() => useCurrencyConversion());
299
+ const { result } = renderCurrencyConversion();
289
300
  const tooltip = result.current.formatTooltipValue(-100, "B3");
290
301
 
291
302
  expect(tooltip).toContain("USD");
@@ -293,15 +304,15 @@ describe("useCurrencyConversion", () => {
293
304
  expect(tooltip).not.toContain("-");
294
305
  });
295
306
 
296
- it("should handle exchange rate unavailable", () => {
307
+ it("falls back to the source currency when its USD rate is unavailable", () => {
297
308
  mockRates.USD = undefined;
298
309
  mockStoreState.selectedCurrency = "B3";
299
310
  mockStoreState.baseCurrency = "B3";
300
311
 
301
- const { result } = renderHook(() => useCurrencyConversion());
312
+ const { result } = renderCurrencyConversion();
302
313
  const tooltip = result.current.formatTooltipValue(100, "B3");
303
314
 
304
- expect(tooltip).toContain("USD");
315
+ expect(tooltip).toContain("B3");
305
316
  expect(tooltip).toContain("100");
306
317
  });
307
318
  });
@@ -0,0 +1,248 @@
1
+ import { isSolanaAddress as registryIsSolanaAddress, SOLANA_NATIVE_ASSET } from "@b3/chain-registry/runtime";
2
+ import { describe, expect, expectTypeOf, it } from "vitest";
3
+ import { isSolanaAddress as sdkIsSolanaAddress } from "../../../anyspend/utils/address";
4
+ import {
5
+ adaptZerionPositions,
6
+ chainIdToZerionSlug,
7
+ EVM_NATIVE_TOKEN_ADDRESS,
8
+ SOLANA_CHAIN_ID,
9
+ SOLANA_NATIVE_TOKEN_ADDRESS,
10
+ SOLANA_ZERION_SLUG,
11
+ zerionSlugToChainId,
12
+ type ZerionPositionLike,
13
+ } from "../zerionPositions";
14
+
15
+ // Slugs and ids below are shaped after live Zerion responses.
16
+ const SLUG_TO_CHAIN_ID: Record<string, number> = {
17
+ ethereum: 1,
18
+ base: 8453,
19
+ polygon: 137,
20
+ celo: 42220,
21
+ hyperevm: 999,
22
+ };
23
+ const slugToChainId = (slug: string) => SLUG_TO_CHAIN_ID[slug];
24
+
25
+ function position(overrides: {
26
+ id: string;
27
+ slug: string;
28
+ symbol: string;
29
+ implAddress?: string | null;
30
+ implDecimals?: number;
31
+ quantityDecimals?: number;
32
+ int?: string;
33
+ }): ZerionPositionLike {
34
+ const { id, slug, symbol, implAddress = null, implDecimals = 18, quantityDecimals = 18, int = "1000" } = overrides;
35
+ return {
36
+ id,
37
+ attributes: {
38
+ quantity: { int, decimals: quantityDecimals },
39
+ fungible_info: {
40
+ symbol,
41
+ implementations: [{ chain_id: slug, address: implAddress, decimals: implDecimals }],
42
+ },
43
+ },
44
+ relationships: { chain: { data: { id: slug } } },
45
+ };
46
+ }
47
+
48
+ describe("adaptZerionPositions native detection", () => {
49
+ it("treats a null implementation address as the chain's native coin", () => {
50
+ const [row] = adaptZerionPositions(
51
+ [position({ id: "base-base-asset-asset", slug: "base", symbol: "ETH" })],
52
+ slugToChainId,
53
+ );
54
+
55
+ expect(row.is_native).toBe(true);
56
+ expect(row.address).toBe(EVM_NATIVE_TOKEN_ADDRESS);
57
+ });
58
+
59
+ it("treats Polygon's native coin as native despite its system-contract address", () => {
60
+ const [row] = adaptZerionPositions(
61
+ [
62
+ position({
63
+ id: "base-polygon-asset-asset",
64
+ slug: "polygon",
65
+ symbol: "POL",
66
+ implAddress: "0x0000000000000000000000000000000000001010",
67
+ }),
68
+ ],
69
+ slugToChainId,
70
+ );
71
+
72
+ expect(row.is_native).toBe(true);
73
+ expect(row.address).toBe(EVM_NATIVE_TOKEN_ADDRESS);
74
+ });
75
+
76
+ it("treats Celo's native coin as native despite its ERC-20 address", () => {
77
+ const [row] = adaptZerionPositions(
78
+ [
79
+ position({
80
+ id: "base-celo-asset-asset",
81
+ slug: "celo",
82
+ symbol: "celo",
83
+ implAddress: "0x471ece3750da237f93b8e339c536989b8978a438",
84
+ }),
85
+ ],
86
+ slugToChainId,
87
+ );
88
+
89
+ expect(row.is_native).toBe(true);
90
+ });
91
+
92
+ it("keeps a same-symbol non-native fungible distinct from the native coin", () => {
93
+ const rows = adaptZerionPositions(
94
+ [
95
+ position({
96
+ id: "base-polygon-asset-asset",
97
+ slug: "polygon",
98
+ symbol: "POL",
99
+ implAddress: "0x0000000000000000000000000000000000001010",
100
+ }),
101
+ position({
102
+ id: "0x89299a4c719ebe9fe6018aed81eb1d48b4f78d56-polygon-asset-asset",
103
+ slug: "polygon",
104
+ symbol: "POL",
105
+ implAddress: "0x89299a4c719ebe9fe6018aed81eb1d48b4f78d56",
106
+ }),
107
+ ],
108
+ slugToChainId,
109
+ );
110
+
111
+ expect(rows.map(r => r.is_native)).toEqual([true, false]);
112
+ expect(rows[1].address).toBe("0x89299a4c719ebe9fe6018aed81eb1d48b4f78d56");
113
+ });
114
+ });
115
+
116
+ describe("adaptZerionPositions row filtering", () => {
117
+ it("drops a row whose chain is unmapped", () => {
118
+ const rows = adaptZerionPositions(
119
+ [position({ id: "base-unknownchain-asset-asset", slug: "unknownchain", symbol: "???" })],
120
+ slugToChainId,
121
+ );
122
+
123
+ expect(rows).toEqual([]);
124
+ });
125
+
126
+ it("drops a row whose fungible has no implementation on its chain, rather than calling it native", () => {
127
+ const rows = adaptZerionPositions(
128
+ [
129
+ {
130
+ id: "0xabc-ethereum-asset-asset",
131
+ attributes: {
132
+ quantity: { int: "1000", decimals: 18 },
133
+ fungible_info: {
134
+ symbol: "ORPHAN",
135
+ // implementations exist, but none for the position's own chain
136
+ implementations: [{ chain_id: "polygon", address: "0xabc", decimals: 18 }],
137
+ },
138
+ },
139
+ relationships: { chain: { data: { id: "ethereum" } } },
140
+ },
141
+ ],
142
+ slugToChainId,
143
+ );
144
+
145
+ expect(rows).toEqual([]);
146
+ });
147
+
148
+ it("drops a row that carries no quantity rather than reporting a zero balance", () => {
149
+ const rows = adaptZerionPositions(
150
+ [
151
+ {
152
+ id: "base-base-asset-asset",
153
+ attributes: {
154
+ quantity: { decimals: 18 },
155
+ fungible_info: { symbol: "ETH", implementations: [{ chain_id: "base", address: null, decimals: 18 }] },
156
+ },
157
+ relationships: { chain: { data: { id: "base" } } },
158
+ },
159
+ ],
160
+ slugToChainId,
161
+ );
162
+
163
+ expect(rows).toEqual([]);
164
+ });
165
+
166
+ it("drops a row that carries no decimals rather than guessing a scale", () => {
167
+ const rows = adaptZerionPositions(
168
+ [
169
+ {
170
+ id: "0xabc-ethereum-asset-asset",
171
+ attributes: {
172
+ quantity: { int: "1000" },
173
+ fungible_info: { symbol: "MYSTERY", implementations: [{ chain_id: "ethereum", address: "0xabc" }] },
174
+ },
175
+ relationships: { chain: { data: { id: "ethereum" } } },
176
+ },
177
+ ],
178
+ slugToChainId,
179
+ );
180
+
181
+ expect(rows).toEqual([]);
182
+ });
183
+
184
+ it("drops trash and non-displayable rows", () => {
185
+ const base = position({ id: "0xspam-ethereum-asset-asset", slug: "ethereum", symbol: "SPAM" });
186
+ const spam: ZerionPositionLike = { ...base, attributes: { ...base.attributes, flags: { is_trash: true } } };
187
+ const hidden: ZerionPositionLike = {
188
+ ...base,
189
+ attributes: { ...base.attributes, flags: { displayable: false } },
190
+ };
191
+
192
+ expect(adaptZerionPositions([spam, hidden], slugToChainId)).toEqual([]);
193
+ });
194
+
195
+ it("drops any quantity that is not a base-10 integer, since all of them format to NaN", () => {
196
+ const rows = adaptZerionPositions(
197
+ [
198
+ position({ id: "0xa-ethereum-asset-asset", slug: "ethereum", symbol: "A", int: "" }),
199
+ position({ id: "0xb-ethereum-asset-asset", slug: "ethereum", symbol: "B", int: null as unknown as string }),
200
+ position({ id: "0xc-ethereum-asset-asset", slug: "ethereum", symbol: "C", int: "not-a-number" }),
201
+ position({ id: "0xd-ethereum-asset-asset", slug: "ethereum", symbol: "D", int: "0x1f" }),
202
+ position({ id: "0xe-ethereum-asset-asset", slug: "ethereum", symbol: "E", int: "1.5" }),
203
+ ],
204
+ slugToChainId,
205
+ );
206
+
207
+ expect(rows).toEqual([]);
208
+ });
209
+
210
+ it("keeps a genuine zero balance", () => {
211
+ const [row] = adaptZerionPositions(
212
+ [position({ id: "base-ethereum-asset-asset", slug: "ethereum", symbol: "ETH", int: "0" })],
213
+ slugToChainId,
214
+ );
215
+
216
+ expect(row.amount).toBe("0");
217
+ });
218
+ });
219
+
220
+ describe("zerionSlugToChainId", () => {
221
+ it("reports an inherited object key as an unknown chain", () => {
222
+ // Slugs come off the wire; an object lookup would answer `constructor` with a function.
223
+ expect(zerionSlugToChainId("constructor")).toBeUndefined();
224
+ expect(zerionSlugToChainId("toString")).toBeUndefined();
225
+ });
226
+
227
+ it("still resolves a real slug", () => {
228
+ expect(zerionSlugToChainId("ethereum")).toBe(1);
229
+ expect(chainIdToZerionSlug(8453)).toBe("base");
230
+ });
231
+ });
232
+
233
+ describe("canonical Solana registry compatibility", () => {
234
+ it("preserves published SDK values and literal types", () => {
235
+ expect(SOLANA_NATIVE_TOKEN_ADDRESS).toBe(SOLANA_NATIVE_ASSET.wrapped.address);
236
+ expect(SOLANA_ZERION_SLUG).toBe(SOLANA_NATIVE_ASSET.chain);
237
+ expect(SOLANA_CHAIN_ID).toBe(SOLANA_NATIVE_ASSET.chainId);
238
+ expectTypeOf(SOLANA_NATIVE_TOKEN_ADDRESS).toEqualTypeOf<"So11111111111111111111111111111111111111112">();
239
+ expectTypeOf(SOLANA_ZERION_SLUG).toEqualTypeOf<"solana">();
240
+ expectTypeOf(SOLANA_CHAIN_ID).toEqualTypeOf<7565164>();
241
+ });
242
+
243
+ it("re-exports the registry Solana address guard unchanged", () => {
244
+ expect(sdkIsSolanaAddress).toBe(registryIsSolanaAddress);
245
+ expect(sdkIsSolanaAddress(SOLANA_NATIVE_TOKEN_ADDRESS)).toBe(true);
246
+ expect(sdkIsSolanaAddress("So1111111111111111111111111111111111111111O")).toBe(false);
247
+ });
248
+ });
@@ -1,51 +1,53 @@
1
- import type { ChainNetworks } from "@b3dotfun/sdk/global-account/types/chain-networks";
1
+ import type { ChainDefinition } from "@b3/chain-registry";
2
2
  import type { Chain as ThirdwebChain } from "thirdweb";
3
3
  import { defineChain as defineThirdwebChain } from "thirdweb";
4
- import { Chain } from "viem";
4
+ import type { Chain } from "viem";
5
5
 
6
- export function toViemChain(network: ChainNetworks): Chain {
6
+ // fallbackRpc is validated non-null at chain-registry module init for every
7
+ // anyspend EVM chain (see ANYSPEND_EVM_CHAINS in @b3/chain-registry). Callers
8
+ // outside the anyspend EVM set must ensure their own data shape.
9
+
10
+ // Derive icon format from URL extension. Thirdweb chain config carries an
11
+ // explicit `format` field; the old chain-networks.json had per-chain values
12
+ // (svg/png/etc.) but @b3/chain-registry only stores `logoUrl`. URL extension
13
+ // is reliable across our current chain set — 9/11 anyspend chains use .png
14
+ // (trustwallet/relay/coinmarketcap), 2 use .svg (Base, Plume from cdn.b3.fun).
15
+ function inferIconFormat(url: string): string {
16
+ const match = url.toLowerCase().match(/\.([a-z0-9]+)(?:\?|#|$)/);
17
+ const ext = match?.[1];
18
+ if (ext === "png" || ext === "jpg" || ext === "jpeg" || ext === "gif" || ext === "webp") return ext;
19
+ return "svg";
20
+ }
21
+
22
+ export function toViemChain(chain: ChainDefinition): Chain {
23
+ if (!chain.fallbackRpc) {
24
+ throw new Error(`toViemChain: chain ${chain.chainId} (${chain.key}) has no fallbackRpc`);
25
+ }
7
26
  return {
8
- id: network.id,
9
- name: network.name,
10
- nativeCurrency: network.nativeCurrency,
11
- rpcUrls: {
12
- default: {
13
- http: [network.rpcUrls.default.http],
14
- webSocket: network.rpcUrls.default.ws ? [network.rpcUrls.default.ws] : undefined,
15
- },
16
- },
27
+ id: chain.chainId,
28
+ name: chain.name,
29
+ nativeCurrency: chain.nativeCurrency,
30
+ rpcUrls: { default: { http: [chain.fallbackRpc] } },
17
31
  blockExplorers: {
18
- default: {
19
- name: network.blockExplorers.explorerTitle,
20
- url: network.blockExplorers.default,
21
- },
32
+ default: { name: `${chain.name} Explorer`, url: chain.explorer },
22
33
  },
23
- contracts: network.contracts,
24
- testnet: network.testnet,
25
- sourceId: network.sourceId,
26
- formatters: network.formatters,
27
- fees: network.fees,
34
+ testnet: chain.isTestnet,
28
35
  };
29
36
  }
30
37
 
31
- export function toThirdwebChain(network: ChainNetworks): ThirdwebChain {
38
+ export function toThirdwebChain(chain: ChainDefinition): ThirdwebChain {
39
+ if (!chain.fallbackRpc) {
40
+ throw new Error(`toThirdwebChain: chain ${chain.chainId} (${chain.key}) has no fallbackRpc`);
41
+ }
32
42
  return defineThirdwebChain({
33
- id: network.id,
34
- name: network.name,
35
- nativeCurrency: network.nativeCurrency,
36
- rpc: network.rpcUrls.default.http,
37
- icon: {
38
- url: network.icon.url,
39
- width: network.icon.width,
40
- height: network.icon.height,
41
- format: network.icon.format,
42
- },
43
- blockExplorers: [
44
- {
45
- name: network.blockExplorers.explorerTitle,
46
- url: network.blockExplorers.default,
47
- },
48
- ],
49
- testnet: network.testnet ? true : undefined,
43
+ id: chain.chainId,
44
+ name: chain.name,
45
+ nativeCurrency: chain.nativeCurrency,
46
+ rpc: chain.fallbackRpc,
47
+ icon: chain.logoUrl
48
+ ? { url: chain.logoUrl, width: 32, height: 32, format: inferIconFormat(chain.logoUrl) }
49
+ : undefined,
50
+ blockExplorers: [{ name: `${chain.name} Explorer`, url: chain.explorer }],
51
+ testnet: chain.isTestnet ? true : undefined,
50
52
  });
51
53
  }
@@ -291,7 +291,7 @@ export async function getNativeTokenBalance(address: string, chainId: number): P
291
291
 
292
292
  try {
293
293
  // Find chain info from supported chains
294
- const chainInfo = supportedChainNetworks.find(chain => chain.id === chainId);
294
+ const chainInfo = supportedChainNetworks.find(chain => chain.chainId === chainId);
295
295
 
296
296
  // Create a chain object from the chainId
297
297
  const chain = defineChain({
@@ -323,7 +323,7 @@ export async function getNativeTokenBalance(address: string, chainId: number): P
323
323
  balance: balance.value.toString(),
324
324
  metadata: {
325
325
  logoURI:
326
- chainInfo?.icon?.url ||
326
+ chainInfo?.logoUrl ||
327
327
  "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/info/logo.png",
328
328
  },
329
329
  // Add native token info in extra_metadata
@@ -0,0 +1,48 @@
1
+ const DEFAULT_UPLOADS_URL = "https://uploads.b3.fun";
2
+
3
+ const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
4
+ const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
5
+
6
+ interface UploadResponse {
7
+ success: boolean;
8
+ data?: { url: string; filename: string; size: number; contentType: string };
9
+ error?: string;
10
+ }
11
+
12
+ interface UploadOptions {
13
+ baseUrl?: string;
14
+ }
15
+
16
+ /**
17
+ * Upload a file to the B3 uploads service (Cloudflare R2).
18
+ * Returns the public URL of the uploaded asset.
19
+ */
20
+ export async function uploadFile(file: File, options?: UploadOptions): Promise<string> {
21
+ if (!ALLOWED_TYPES.includes(file.type)) {
22
+ throw new Error(`Invalid file type. Allowed: ${ALLOWED_TYPES.join(", ")}`);
23
+ }
24
+ if (file.size > MAX_FILE_SIZE) {
25
+ throw new Error(`File too large. Maximum size: ${MAX_FILE_SIZE / 1024 / 1024}MB`);
26
+ }
27
+
28
+ const uploadsUrl = options?.baseUrl || DEFAULT_UPLOADS_URL;
29
+ const formData = new FormData();
30
+ formData.append("file", file);
31
+
32
+ const res = await fetch(`${uploadsUrl}/upload/image`, {
33
+ method: "POST",
34
+ body: formData,
35
+ });
36
+
37
+ if (!res.ok) {
38
+ const body: UploadResponse = await res.json().catch(() => ({ success: false, error: "Upload failed" }));
39
+ throw new Error(body.error || `Upload failed (${res.status})`);
40
+ }
41
+
42
+ const body: UploadResponse = await res.json().catch(() => ({ success: false, error: "Invalid response" }));
43
+ if (!body.success || !body.data) {
44
+ throw new Error(body.error || "Upload failed");
45
+ }
46
+
47
+ return body.data.url;
48
+ }