@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
@@ -4,7 +4,7 @@ import { B3_AUTH_COOKIE_NAME } from "@b3dotfun/sdk/shared/constants";
4
4
  import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
5
5
  import Cookies from "js-cookie";
6
6
  import { useEffect, useRef } from "react";
7
- import { betterAuthClient } from "../../../better-auth-client";
7
+ import { getBetterAuthClient } from "../../../better-auth-client";
8
8
  import { useUserQuery } from "../../hooks/useUserQuery";
9
9
 
10
10
  const debug = debugB3React("BetterAuthProvider");
@@ -43,7 +43,7 @@ const BetterAuthProvider = ({ partnerId }: { partnerId: string }) => {
43
43
  (app as any).logout = async () => {
44
44
  debug("Patched logout: clearing Better Auth session");
45
45
  try {
46
- await betterAuthClient.signOut();
46
+ await getBetterAuthClient().signOut();
47
47
  } catch {
48
48
  debug("Better Auth signOut failed (non-critical)");
49
49
  }
@@ -79,9 +79,55 @@ const BetterAuthProvider = ({ partnerId }: { partnerId: string }) => {
79
79
  debug("No existing Feathers JWT");
80
80
  }
81
81
 
82
- // 2. Check for a Better Auth session (e.g. after OAuth redirect sets a cookie)
82
+ // 2. Check for _ba_token in URL (OAuth callback with third-party cookie bypass).
83
+ // When the API and frontend are on different domains, browsers with third-party
84
+ // cookie blocking (Firefox TCP, Safari ITP, Chrome Privacy Sandbox) prevent the
85
+ // better-auth.session_token cookie from being sent on cross-origin requests.
86
+ // The B3 API injects the session token into the redirect URL as _ba_token,
87
+ // allowing direct exchange without relying on cookies.
88
+ const params = new URLSearchParams(window.location.search);
89
+ const baToken = params.get("_ba_token");
90
+ if (baToken) {
91
+ debug("Found _ba_token in URL, exchanging for Feathers JWT");
92
+
93
+ // Clean the token from the URL immediately (security)
94
+ params.delete("_ba_token");
95
+ const cleanSearch = params.toString();
96
+ const cleanUrl = window.location.pathname + (cleanSearch ? `?${cleanSearch}` : "") + window.location.hash;
97
+ window.history.replaceState({}, "", cleanUrl);
98
+
99
+ try {
100
+ const response = await app.authenticate({
101
+ strategy: "better-auth",
102
+ accessToken: baToken,
103
+ partnerId,
104
+ } as any);
105
+
106
+ if (response.accessToken) {
107
+ Cookies.set(B3_AUTH_COOKIE_NAME, response.accessToken, {
108
+ secure: true,
109
+ sameSite: "Lax",
110
+ });
111
+ }
112
+
113
+ if (response.user) {
114
+ setUser(response.user);
115
+ setIsAuthenticated(true);
116
+ setIsConnected(true);
117
+ }
118
+
119
+ debug("_ba_token exchanged for Feathers JWT", { userId: response.user?.userId });
120
+ setIsAuthenticating(false);
121
+ return;
122
+ } catch (err) {
123
+ debug("_ba_token exchange failed", err);
124
+ }
125
+ }
126
+
127
+ // 3. Check for a Better Auth session via cookie (works when API and frontend
128
+ // share a domain or when cookies aren't partitioned)
83
129
  try {
84
- const session = await betterAuthClient.getSession();
130
+ const session = await getBetterAuthClient().getSession();
85
131
  if (session.data?.session?.token) {
86
132
  debug("Better Auth session found, exchanging for Feathers JWT", {
87
133
  betterAuthUserId: session.data.user?.id,
@@ -114,7 +160,7 @@ const BetterAuthProvider = ({ partnerId }: { partnerId: string }) => {
114
160
  debug("No Better Auth session to restore");
115
161
  }
116
162
 
117
- // 3. Nothing found — show login UI
163
+ // 4. Nothing found — show login UI
118
164
  setIsAuthenticating(false);
119
165
  };
120
166
 
@@ -2,13 +2,7 @@ import { RelayKitProvider } from "@relayprotocol/relay-kit-ui";
2
2
  import { fetchChainConfigs, MAINNET_RELAY_API, RelayChain } from "@relayprotocol/relay-sdk";
3
3
  import { useEffect, useState } from "react";
4
4
 
5
- export function RelayKitProviderWrapper({
6
- children,
7
- simDuneApiKey,
8
- }: {
9
- children: React.ReactNode;
10
- simDuneApiKey?: string;
11
- }) {
5
+ export function RelayKitProviderWrapper({ children }: { children: React.ReactNode }) {
12
6
  const [relayChains, setRelayChains] = useState<RelayChain[]>([]);
13
7
 
14
8
  useEffect(() => {
@@ -19,19 +13,25 @@ export function RelayKitProviderWrapper({
19
13
  fetchChains();
20
14
  }, []);
21
15
 
16
+ // Balances for Relay's token selector come from the b3-zerion-api Zerion proxy, not Relay's own Dune
17
+ // integration. Relay only fires the balance query when duneConfig.apiKey is set, so apiBaseUrl points
18
+ // it at our proxy; the proxy ignores the client-sent key and holds the real Zerion credential itself.
22
19
  return (
23
20
  <RelayKitProvider
24
21
  options={{
25
22
  baseApiUrl: MAINNET_RELAY_API,
26
23
  source: "anyspend",
27
- duneConfig: {
28
- apiKey: simDuneApiKey,
29
- apiBaseUrl: "https://api.sim.dune.com",
30
- },
31
24
  chains: relayChains,
32
25
  privateChainIds: undefined,
33
26
  appName: "AnySpend",
34
27
  useGasFeeEstimations: true,
28
+ duneConfig: {
29
+ // Non-secret placeholder. Relay only fires its balance query when apiKey is defined; the value is sent
30
+ // as X-Sim-Api-Key to our proxy, which ignores it. The real Zerion key stays server-side in b3-zerion-api.
31
+ apiKey: "proxied-via-portfolio-api",
32
+ // Relay appends /v1/evm/balances/{address}. Our b3-zerion-api worker serves that route, backed by Zerion.
33
+ apiBaseUrl: "https://portfolio-api.b3.fun",
34
+ },
35
35
  }}
36
36
  >
37
37
  <>{children}</>
@@ -5,7 +5,7 @@ import {
5
5
  toast,
6
6
  TransitionPanel,
7
7
  useAnalytics,
8
- useSimBalance,
8
+ usePortfolioBalance,
9
9
  useUnifiedChainSwitchAndExecute,
10
10
  } from "@b3dotfun/sdk/global-account/react";
11
11
  import { formatDisplayNumber, formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
@@ -16,7 +16,7 @@ import { NumericFormat } from "react-number-format";
16
16
 
17
17
  import { useActiveAccount } from "thirdweb/react";
18
18
  import { encodeFunctionData, erc20Abi, isAddress, parseUnits } from "viem";
19
- import { SimBalanceItem } from "../../hooks/useSimBalance";
19
+ import type { B3TokenBalance } from "@b3dotfun/sdk/shared/utils/zerionPositions";
20
20
 
21
21
  // Panel view enum for managing navigation between token list and send form
22
22
  enum TokenPanelView {
@@ -45,7 +45,7 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
45
45
  const [tokenPanelView, setTokenPanelView] = useState<TokenPanelView>(TokenPanelView.LIST);
46
46
 
47
47
  // === SEND FORM STATE ===
48
- const [selectedToken, setSelectedToken] = useState<SimBalanceItem | null>(null);
48
+ const [selectedToken, setSelectedToken] = useState<B3TokenBalance | null>(null);
49
49
  const [recipientAddress, setRecipientAddress] = useState("");
50
50
  const [sendAmount, setSendAmount] = useState("");
51
51
  const [isSending, setIsSending] = useState(false);
@@ -58,7 +58,12 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
58
58
 
59
59
  // === DATA FETCHING ===
60
60
  const account = useActiveAccount();
61
- const { data: simBalance, refetch: refetchSimBalance, isLoading: isLoadingBalance } = useSimBalance(account?.address);
61
+ const {
62
+ data: balances,
63
+ refetch: refetchBalances,
64
+ isLoading: isLoadingBalance,
65
+ isError: isBalanceError,
66
+ } = usePortfolioBalance(account?.address);
62
67
 
63
68
  // === BLOCKCHAIN INTERACTION ===
64
69
  const { switchChainAndExecute } = useUnifiedChainSwitchAndExecute();
@@ -96,14 +101,14 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
96
101
  // === HELPER FUNCTION ===
97
102
  // Get current version of selected token from fresh balance data
98
103
  // 🔧 FIX: Prevents auto-navigation back to token list when balance refreshes
99
- // The useSimBalance hook refreshes data, creating new token object references
104
+ // The balance hook refreshes data, creating new token object references
100
105
  // This helper ensures we always get the fresh token data instead of stale references
101
- const getCurrentSelectedToken = (): SimBalanceItem | null => {
102
- if (!selectedToken || !simBalance?.balances) {
106
+ const getCurrentSelectedToken = (): B3TokenBalance | null => {
107
+ if (!selectedToken || !balances) {
103
108
  return null;
104
109
  }
105
110
 
106
- const found = simBalance.balances.find(
111
+ const found = balances.find(
107
112
  token => token.chain_id === selectedToken.chain_id && token.address === selectedToken.address,
108
113
  );
109
114
 
@@ -184,11 +189,16 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
184
189
  args: [recipientAddress, amountInWei],
185
190
  });
186
191
 
187
- const tx = await switchChainAndExecute(displayToken.chain_id, {
188
- to: displayToken.address === "native" ? recipientAddress : displayToken.address,
189
- data: sendTokenData,
190
- value: displayToken.address === "native" ? amountInWei : BigInt(0),
191
- });
192
+ // A native send carries value and no calldata; an ERC-20 send carries calldata and no
193
+ // value. Branch on the explicit flag, never on the address: the native sentinel is a
194
+ // display detail, and taking the ERC-20 path for a native coin spends gas without moving
195
+ // anything.
196
+ const tx = await switchChainAndExecute(
197
+ displayToken.chain_id,
198
+ displayToken.is_native
199
+ ? { to: recipientAddress, value: amountInWei }
200
+ : { to: displayToken.address, data: sendTokenData, value: BigInt(0) },
201
+ );
192
202
 
193
203
  if (tx) {
194
204
  // Track successful send
@@ -215,7 +225,7 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
215
225
  // Wait 1 second to make sure the tx is indexed on sim api.
216
226
  setTimeout(async () => {
217
227
  // Force refetch to bypass cache and get fresh balance data
218
- await refetchSimBalance();
228
+ await refetchBalances();
219
229
  }, 1000);
220
230
  setIsSending(false);
221
231
  }
@@ -409,8 +419,28 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
409
419
  return <LoadingIndicator />;
410
420
  }
411
421
 
412
- // Show empty state when no account or no balance data
413
- if (!account?.address || !simBalance) {
422
+ // A wallet IS connected here only the read failed. Prompting the user to connect would send
423
+ // them to fix something that is not broken.
424
+ // `isBalanceError` as well as the absent list: after a first success a later refetch failure
425
+ // keeps `data` populated, so `!balances` alone would show stale numbers as if they were fresh.
426
+ if (account?.address && (isBalanceError || !balances)) {
427
+ return (
428
+ <div className="flex flex-col items-center justify-center py-12 text-center">
429
+ <div className="bg-b3-line/50 mb-4 rounded-full p-4">
430
+ <Loader2 className="text-b3-foreground-muted h-8 w-8" />
431
+ </div>
432
+ <h3 className="text-b3-grey font-neue-montreal-semibold mb-2">Couldn&apos;t load your tokens</h3>
433
+ <button
434
+ onClick={() => refetchBalances()}
435
+ className="text-b3-foreground-muted font-neue-montreal-medium text-sm underline"
436
+ >
437
+ Try again
438
+ </button>
439
+ </div>
440
+ );
441
+ }
442
+
443
+ if (!account?.address) {
414
444
  return (
415
445
  <div className="flex flex-col items-center justify-center py-12 text-center">
416
446
  <div className="bg-b3-line/50 mb-4 rounded-full p-4">
@@ -426,8 +456,7 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
426
456
 
427
457
  // === SMART FILTERING LOGIC ===
428
458
  // Filter tokens with value >= $1 to reduce noise from dust tokens
429
- const filteredTokens =
430
- simBalance?.balances.filter(token => token.value_usd !== undefined && token.value_usd >= 1) || [];
459
+ const filteredTokens = balances?.filter(token => token.value_usd !== undefined && token.value_usd >= 1) || [];
431
460
 
432
461
  // 🧠 INTELLIGENT DISPLAY LOGIC:
433
462
  // Show all tokens automatically when filtering would be unhelpful:
@@ -435,11 +464,11 @@ export function ContentTokens({ activeTab }: ContentTokensProps) {
435
464
  // 2. No tokens with value >= $1 (user has only dust), OR
436
465
  // 3. 5 or fewer tokens with value >= $1 (not enough to warrant filtering)
437
466
  const shouldShowAllTokens = showAllTokens || filteredTokens.length === 0 || filteredTokens.length <= 5;
438
- const tokensToShow = shouldShowAllTokens ? simBalance?.balances || [] : filteredTokens;
439
- const hasHiddenTokens = !shouldShowAllTokens && (simBalance?.balances.length || 0) > filteredTokens.length;
467
+ const tokensToShow = shouldShowAllTokens ? balances || [] : filteredTokens;
468
+ const hasHiddenTokens = !shouldShowAllTokens && (balances?.length || 0) > filteredTokens.length;
440
469
 
441
470
  // Handle token selection and navigate to send form
442
- const handleTokenClick = (token: SimBalanceItem) => {
471
+ const handleTokenClick = (token: B3TokenBalance) => {
443
472
  setSelectedToken(token);
444
473
  animationDirection.current = "forward"; // Set animation direction BEFORE state change
445
474
  setTokenPanelView(TokenPanelView.SEND);
@@ -1,6 +1,6 @@
1
1
  import { useActiveWallet } from "thirdweb/react";
2
2
  import { AccountAssets } from "..";
3
- import { useSimCollectibles } from "../../hooks";
3
+ import { usePortfolioCollectibles } from "../../hooks";
4
4
 
5
5
  const NFTContent = () => {
6
6
  // Get active wallet state
@@ -8,11 +8,13 @@ const NFTContent = () => {
8
8
  const activeAccount = activeWallet?.getAccount();
9
9
  const activeAddress = activeAccount?.address;
10
10
 
11
- const { data: nfts, isLoading } = useSimCollectibles(activeAddress, [1, 8453], { filterSpam: true });
11
+ const { data: nfts, isLoading, isError } = usePortfolioCollectibles(activeAddress, [1, 8453], { filterSpam: true });
12
12
 
13
13
  return (
14
14
  <div style={{ minHeight: "100px" }}>
15
- {nfts ? (
15
+ {isError ? (
16
+ <div className="py-12 text-center text-gray-500">Couldn&apos;t load your NFTs</div>
17
+ ) : nfts ? (
16
18
  <AccountAssets nfts={nfts} isLoading={isLoading} />
17
19
  ) : (
18
20
  <div className="py-12 text-center text-gray-500">No NFTs found</div>
@@ -3,7 +3,7 @@ import {
3
3
  useB3Config,
4
4
  useModalStore,
5
5
  useProfile,
6
- useSimBalance,
6
+ usePortfolioBalance,
7
7
  useUser,
8
8
  } from "@b3dotfun/sdk/global-account/react";
9
9
  import { validateImageUrl } from "@b3dotfun/sdk/global-account/react/utils/profileDisplay";
@@ -32,14 +32,16 @@ const ProfileSection = () => {
32
32
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
33
33
  const navigateBack = useModalStore(state => state.navigateBack);
34
34
 
35
- const { data: simBalance } = useSimBalance(smartWalletAddress);
35
+ const { data: balances, isError: isBalanceError } = usePortfolioBalance(smartWalletAddress);
36
36
  const [imgError, setImgError] = useState(false);
37
37
  const handleImgError = useCallback(() => setImgError(true), []);
38
38
 
39
+ // Null while the holdings are unknown. Summing an absent list to $0.00 would report an empty
40
+ // portfolio to someone whose balances merely failed to load.
39
41
  const totalBalanceUsd = useMemo(() => {
40
- if (!simBalance?.balances) return 0;
41
- return simBalance.balances.reduce((sum, token) => sum + (token.value_usd || 0), 0);
42
- }, [simBalance]);
42
+ if (isBalanceError || !balances) return null;
43
+ return balances.reduce((sum, token) => sum + (token.value_usd || 0), 0);
44
+ }, [balances, isBalanceError]);
43
45
 
44
46
  const handleEditAvatar = () => {
45
47
  setB3ModalOpen(true);
@@ -92,7 +94,9 @@ const ProfileSection = () => {
92
94
  {!isBetterAuth && (
93
95
  <h2 className="text-b3-grey font-neue-montreal-semibold flex h-[38px] items-center gap-1 text-xl">
94
96
  <div className="text-b3-foreground-muted"> $</div>
95
- <div className="text-[30px]">{formatDisplayNumber(totalBalanceUsd, { fractionDigits: 2 })}</div>
97
+ <div className="text-[30px]">
98
+ {totalBalanceUsd === null ? "—" : formatDisplayNumber(totalBalanceUsd, { fractionDigits: 2 })}
99
+ </div>
96
100
  </h2>
97
101
  )}
98
102
  <div className="b3-modal-username font-neue-montreal-semibold text-base leading-none text-[#0B57C2]">
@@ -84,7 +84,7 @@ const SettingsProfileCard = () => {
84
84
  // Better Auth: register username without wallet signing (DB-only, no ENS)
85
85
  // Skip ens_normalize — it rejects underscores/mixed-case that are valid non-ENS usernames
86
86
  const sanitizedUsername = editedUsername.trim().toLowerCase();
87
- // Type assertion needed: b3-mono now accepts message/hash as optional for Better Auth users
87
+ // Type assertion needed: API now accepts message/hash as optional for Better Auth users
88
88
  updatedUser = (await app
89
89
  .service("users")
90
90
  .registerUsername({ username: sanitizedUsername } as any, {} as any)) as unknown as Users;
@@ -1,10 +1,16 @@
1
- import { useSimBalance } from "@b3dotfun/sdk/global-account/react";
1
+ import { usePortfolioBalance } from "@b3dotfun/sdk/global-account/react";
2
2
  import { getChainLogo } from "@b3dotfun/sdk/shared/constants/chains/supported";
3
3
  import { useActiveWallet } from "thirdweb/react";
4
4
  import { TokenBalanceRow } from "./TokenBalanceRow";
5
5
 
6
- // Chain logo URLs mapping
7
- const CHAIN_LOGOS: Record<number, string> = [1, 8453, 8333].map(chainId => getChainLogo(chainId));
6
+ const ETHEREUM_CHAIN_ID = 1;
7
+
8
+ // Chain logo URLs, keyed by chain id. Built with Object.fromEntries rather than `.map()`: an array
9
+ // satisfies Record<number, string> for the type checker while indexing by 0,1,2 at runtime, so
10
+ // every lookup by a real chain id would miss.
11
+ const CHAIN_LOGOS: Record<number, string> = Object.fromEntries(
12
+ [ETHEREUM_CHAIN_ID, 8453, 8333].map(chainId => [chainId, getChainLogo(chainId)]),
13
+ );
8
14
 
9
15
  const TokenContent = () => {
10
16
  // Get active wallet state
@@ -12,19 +18,26 @@ const TokenContent = () => {
12
18
  const activeAccount = activeWallet?.getAccount();
13
19
  const activeAddress = activeAccount?.address;
14
20
 
15
- const { data: simBalance } = useSimBalance(activeAddress, [8453, 8333, 1]);
16
- console.log("simBalance :", simBalance);
21
+ // Base and Ethereum only. B3 (8333) is deliberately absent: the portfolio provider does not index
22
+ // it, so asking for it returns nothing and reads as a coverage gap rather than a choice. Restoring
23
+ // B3 needs a non-provider source, the way HyperEVM and Plume are served on-chain in b3os-web.
24
+ const { data: balances, isError: isBalanceError } = usePortfolioBalance(activeAddress, [8453, ETHEREUM_CHAIN_ID]);
17
25
 
18
26
  if (!activeAddress) {
19
27
  return <div className="col-span-3 py-12 text-center text-gray-500">No tokens found</div>;
20
28
  }
21
29
 
22
- if (!simBalance?.balances || simBalance.balances.length === 0) {
30
+ // "Couldn't load" and "holds nothing" are different answers and must not share a message.
31
+ if (isBalanceError) {
32
+ return <div className="col-span-3 py-12 text-center text-gray-500">Couldn&apos;t load your tokens</div>;
33
+ }
34
+
35
+ if (!balances || balances.length === 0) {
23
36
  return <div className="col-span-3 py-12 text-center text-gray-500">No tokens found</div>;
24
37
  }
25
38
 
26
39
  // Sort by USD value descending
27
- const sortedBalances = [...simBalance.balances].sort((a, b) => {
40
+ const sortedBalances = [...balances].sort((a, b) => {
28
41
  const valueA = a.value_usd || 0;
29
42
  const valueB = b.value_usd || 0;
30
43
  return valueB - valueA;
@@ -43,8 +56,8 @@ const TokenContent = () => {
43
56
  // Determine token logo
44
57
  // For native tokens, use ETH logo instead of chain logo
45
58
  let tokenLogo = token.token_metadata?.logo || "";
46
- if (token.address === "native" && token.symbol === "ETH") {
47
- tokenLogo = CHAIN_LOGOS[0];
59
+ if (token.is_native && token.symbol === "ETH") {
60
+ tokenLogo = CHAIN_LOGOS[ETHEREUM_CHAIN_ID];
48
61
  }
49
62
 
50
63
  return (
@@ -6,7 +6,7 @@ import {
6
6
  useAnalytics,
7
7
  useModalStore,
8
8
  useProfile,
9
- useSimBalance,
9
+ usePortfolioBalance,
10
10
  useUnifiedChainSwitchAndExecute,
11
11
  } from "@b3dotfun/sdk/global-account/react";
12
12
  import { validateImageUrl } from "@b3dotfun/sdk/global-account/react/utils/profileDisplay";
@@ -18,7 +18,7 @@ import { NumericFormat } from "react-number-format";
18
18
 
19
19
  import { encodeFunctionData, erc20Abi, isAddress, parseUnits } from "viem";
20
20
 
21
- import type { SimBalanceItem } from "../../hooks/useSimBalance";
21
+ import type { B3TokenBalance } from "@b3dotfun/sdk/shared/utils/zerionPositions";
22
22
  import { useRecentAddressesStore } from "../../stores/useRecentAddressesStore";
23
23
  import ModalHeader from "../ModalHeader/ModalHeader";
24
24
  import { Button } from "../ui/button";
@@ -66,7 +66,7 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
66
66
 
67
67
  // Wizard state
68
68
  const [step, setStep] = useState<SendStep>("recipient");
69
- const [selectedToken, setSelectedToken] = useState<SimBalanceItem | null>(null);
69
+ const [selectedToken, setSelectedToken] = useState<B3TokenBalance | null>(null);
70
70
  const [recipientAddress, setRecipientAddress] = useState(initialRecipient || "");
71
71
  const [sendAmount, setSendAmount] = useState("");
72
72
  const [isSending, setIsSending] = useState(false);
@@ -74,7 +74,12 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
74
74
  const [showValidatedResult, setShowValidatedResult] = useState(false);
75
75
 
76
76
  // Hooks
77
- const { data: simBalance, refetch: refetchSimBalance, isLoading: isLoadingBalance } = useSimBalance(address);
77
+ const {
78
+ data: balances,
79
+ refetch: refetchBalances,
80
+ isLoading: isLoadingBalance,
81
+ isError: isBalanceError,
82
+ } = usePortfolioBalance(address);
78
83
  const { switchChainAndExecute } = useUnifiedChainSwitchAndExecute();
79
84
  const { sendAnalyticsEvent } = useAnalytics();
80
85
 
@@ -138,11 +143,11 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
138
143
  };
139
144
 
140
145
  // Get current selected token from fresh balance
141
- const getCurrentSelectedToken = (): SimBalanceItem | null => {
142
- if (!selectedToken || !simBalance?.balances) {
146
+ const getCurrentSelectedToken = (): B3TokenBalance | null => {
147
+ if (!selectedToken || !balances) {
143
148
  return null;
144
149
  }
145
- const found = simBalance.balances.find(
150
+ const found = balances.find(
146
151
  token => token.chain_id === selectedToken.chain_id && token.address === selectedToken.address,
147
152
  );
148
153
  return found || null;
@@ -187,11 +192,15 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
187
192
  args: [recipientAddress, amountInWei],
188
193
  });
189
194
 
190
- const tx = await switchChainAndExecute(currentToken.chain_id, {
191
- to: currentToken.address === "native" ? recipientAddress : currentToken.address,
192
- data: sendTokenData,
193
- value: currentToken.address === "native" ? amountInWei : BigInt(0),
194
- });
195
+ // A native send carries value and no calldata; an ERC-20 send carries calldata and no value.
196
+ // Branch on the explicit flag, never on the address: the native sentinel is a display detail,
197
+ // and taking the ERC-20 path for a native coin spends gas without moving anything.
198
+ const tx = await switchChainAndExecute(
199
+ currentToken.chain_id,
200
+ currentToken.is_native
201
+ ? { to: recipientAddress, value: amountInWei }
202
+ : { to: currentToken.address, data: sendTokenData, value: BigInt(0) },
203
+ );
195
204
 
196
205
  if (tx) {
197
206
  sendAnalyticsEvent("send_token_button_click", {
@@ -208,7 +217,7 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
208
217
  }
209
218
 
210
219
  setTimeout(async () => {
211
- await refetchSimBalance();
220
+ await refetchBalances();
212
221
  }, 1000);
213
222
  }
214
223
  } catch (error: any) {
@@ -364,10 +373,10 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
364
373
  ))}
365
374
  </div>
366
375
  </div>
367
- ) : simBalance?.balances && simBalance.balances.length > 0 ? (
376
+ ) : balances && balances.length > 0 ? (
368
377
  <div className="space-y-4">
369
378
  <div className="space-y-1">
370
- {simBalance.balances.map(token => (
379
+ {balances.map(token => (
371
380
  <div
372
381
  key={token.chain_id + "_" + token.address}
373
382
  className="hover:bg-b3-line/60 dark:hover:bg-b3-primary-wash/40 group flex cursor-pointer items-center justify-between rounded-xl p-3 transition-all duration-200"
@@ -411,6 +420,21 @@ export function Send({ recipientAddress: initialRecipient, onSuccess }: SendModa
411
420
  ))}
412
421
  </div>
413
422
  </div>
423
+ ) : isBalanceError ? (
424
+ // Telling someone they hold nothing, when the read simply failed, invites them to go
425
+ // looking for missing funds.
426
+ <div className="flex flex-col items-center justify-center py-12 text-center">
427
+ <CircleHelp className="text-b3-foreground-muted mb-4 h-8 w-8" />
428
+ <p className="text-b3-foreground-muted font-neue-montreal-medium text-sm">
429
+ Couldn&apos;t load your tokens
430
+ </p>
431
+ <button
432
+ onClick={() => refetchBalances()}
433
+ className="text-b3-foreground-muted font-neue-montreal-medium mt-2 text-sm underline"
434
+ >
435
+ Try again
436
+ </button>
437
+ </div>
414
438
  ) : (
415
439
  <div className="flex flex-col items-center justify-center py-12 text-center">
416
440
  <CircleHelp className="text-b3-foreground-muted mb-4 h-8 w-8" />
@@ -1,4 +1,5 @@
1
1
  import { Button, Input, Loading, useAuthStore } from "@b3dotfun/sdk/global-account/react";
2
+ import { cn } from "@b3dotfun/sdk/shared/utils";
2
3
  import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
3
4
  import { useState } from "react";
4
5
  import {
@@ -20,6 +21,7 @@ const DEFAULT_SOCIAL_PROVIDERS: SocialProviderConfig[] = [
20
21
  { id: "discord", label: "Discord" },
21
22
  { id: "microsoft", label: "Microsoft" },
22
23
  { id: "slack", label: "Slack" },
24
+ { id: "twitter", label: "X" },
23
25
  ];
24
26
 
25
27
  export interface BetterAuthSignInProps {
@@ -415,7 +417,16 @@ export function BetterAuthSignIn({
415
417
  />
416
418
  </svg>
417
419
  ) : (
418
- icon && <img src={icon} alt="" className="h-5 w-5" />
420
+ icon && (
421
+ <img
422
+ src={icon}
423
+ alt=""
424
+ className={cn(
425
+ "h-5 w-5",
426
+ (provider.id === "github" || provider.id === "twitter") && "dark:invert",
427
+ )}
428
+ />
429
+ )
419
430
  )}
420
431
  <span>{isProviderLoading ? "Redirecting..." : label}</span>
421
432
  </button>
@@ -12,7 +12,6 @@ import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
12
12
  import { useCallback, useEffect, useRef, useState } from "react";
13
13
  import { useActiveAccount } from "thirdweb/react";
14
14
  import { Account } from "thirdweb/wallets";
15
- import { SignInWithB3Privy } from "./SignInWithB3Privy";
16
15
  import { LoginStep, LoginStepContainer } from "./steps/LoginStep";
17
16
  import { LoginStepCustom } from "./steps/LoginStepCustom";
18
17
 
@@ -310,9 +309,7 @@ export function SignInWithB3Flow({
310
309
  );
311
310
  } else {
312
311
  // Custom strategy
313
- if (strategies?.[0] === "privy") {
314
- content = <SignInWithB3Privy onSuccess={handleLoginSuccess} chain={chain} />;
315
- } else if (strategies) {
312
+ if (strategies) {
316
313
  // Strategies are explicitly provided
317
314
  content = (
318
315
  <LoginStepCustom
@@ -1,4 +1,5 @@
1
1
  import { Button } from "../../custom/Button";
2
+ import { cn } from "@b3dotfun/sdk/shared/utils";
2
3
  import { Github, Mail } from "lucide-react";
3
4
  import { strategyIcons, strategyLabels } from "../utils/signInUtils";
4
5
 
@@ -31,7 +32,14 @@ export function AuthButton({
31
32
  className="flex w-full items-center justify-center bg-gray-100 px-2 py-3 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700"
32
33
  >
33
34
  {strategyIcon ? (
34
- <img src={strategyIcon} alt={`${strategyLabel} icon`} className="h-9 w-9" />
35
+ <img
36
+ src={strategyIcon}
37
+ alt={`${strategyLabel} icon`}
38
+ className={cn(
39
+ "h-9 w-9",
40
+ (strategy === "github" || strategy === "twitter" || strategy === "x") && "dark:invert",
41
+ )}
42
+ />
35
43
  ) : FallbackIcon ? (
36
44
  <FallbackIcon className="h-9 w-9 text-gray-900 dark:text-gray-100" />
37
45
  ) : (
@@ -18,6 +18,7 @@ const SOCIAL_PROVIDERS: { id: BetterAuthSocialProvider; label: string }[] = [
18
18
  { id: "discord", label: "Discord" },
19
19
  { id: "microsoft", label: "Microsoft" },
20
20
  { id: "slack", label: "Slack" },
21
+ { id: "twitter", label: "X" },
21
22
  ];
22
23
 
23
24
  interface LoginStepBetterAuthProps {
@@ -3,12 +3,11 @@ import { createWallet, SingleStepAuthArgsType, Wallet } from "thirdweb/wallets";
3
3
 
4
4
  type WalletType = Wallet["id"];
5
5
  type StrategyType = SingleStepAuthArgsType["strategy"];
6
- type CustomStrategyType = "basement" | "privy";
6
+ const customStrategies = ["basement"] as const;
7
+ type CustomStrategyType = (typeof customStrategies)[number];
7
8
 
8
9
  type AllowedStrategies = StrategyType | WalletType | CustomStrategyType | "email";
9
10
  type NonWalletStrategyType = Exclude<AllowedStrategies, WalletType>;
10
- const customStrategies = ["basement", "privy"] as const;
11
- // type CustomStrategy = (typeof customStrategies)[number];
12
11
 
13
12
  export const allowedStrategies = [
14
13
  // Auth strategies
@@ -26,7 +25,6 @@ export const allowedStrategies = [
26
25
  "com.coinbase.wallet",
27
26
 
28
27
  // Custom strategies
29
- // TODO: Audit we don't use "privy" directly anymore
30
28
  ...customStrategies,
31
29
  ] as const;
32
30
 
@@ -67,6 +65,7 @@ export const strategyIcons: Record<string, string> = {
67
65
  google: "https://cdn.b3.fun/google.svg",
68
66
  github: "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg",
69
67
  x: "https://cdn.b3.fun/x.svg?1",
68
+ twitter: "https://cdn.b3.fun/x.svg?1",
70
69
  discord: "https://cdn.b3.fun/discord.svg",
71
70
  apple: "https://cdn.b3.fun/apple.svg",
72
71
  guest: "https://cdn.b3.fun/incognito.svg",
@@ -77,6 +76,7 @@ export const strategyIcons: Record<string, string> = {
77
76
  export const strategyLabels: Record<string, string> = {
78
77
  google: "Google",
79
78
  x: "X",
79
+ twitter: "X",
80
80
  discord: "Discord",
81
81
  apple: "Apple",
82
82
  guest: "Guest",