@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
@@ -0,0 +1,672 @@
1
+ import chainsData from "../chains.json" with { type: "json" };
2
+
3
+ export interface ManualToken {
4
+ address: `0x${string}`;
5
+ symbol: string;
6
+ decimals: number;
7
+ name: string;
8
+ logoUrl?: string;
9
+ }
10
+
11
+ /**
12
+ * Known integration tags that can appear in `ChainDefinition.integrations`.
13
+ * Adding a new integration → extend this union. Consumers calling
14
+ * `chainsByIntegration("foo")` get autocomplete + typo safety.
15
+ */
16
+ export type KnownIntegration =
17
+ | "aerodrome"
18
+ | "anyspend"
19
+ | "cow-swap"
20
+ | "evm-log"
21
+ | "morpho"
22
+ | "railgun"
23
+ | "x402"
24
+ | "zerodev";
25
+
26
+ /** A chain's canonical/hub stablecoin(s). Bounded (1–3 per chain), not a general token registry —
27
+ * the first entry is the chain's primary quote stablecoin. */
28
+ export interface StablecoinRef {
29
+ symbol: string;
30
+ address: string;
31
+ }
32
+
33
+ export interface ChainDefinition {
34
+ chainId: number;
35
+ key: string;
36
+ name: string;
37
+ network: string;
38
+ /**
39
+ * DexScreener API chain id. Set explicitly for every registry chain known to
40
+ * be supported, even when equal to `network`; absence leaves provider routing
41
+ * opaque instead of guessing a slug.
42
+ */
43
+ dexscreenerNetwork?: string;
44
+ type: "evm" | "solana";
45
+ isTestnet: boolean;
46
+ integrations: KnownIntegration[];
47
+ /** Canonical stablecoins on this chain; `stablecoins[0]` is the hub. Optional — filled per chain
48
+ * as needed (Robinhood/4663 → USDG for B3-5081). TS-only; Go does not consume it. */
49
+ stablecoins?: StablecoinRef[];
50
+ nativeCurrency: {
51
+ name: string;
52
+ symbol: string;
53
+ decimals: number;
54
+ };
55
+ explorer: string;
56
+ rpcEnvKey: string | null;
57
+ fallbackRpc: string | null;
58
+ quicknodeSlug: string | null;
59
+ quicknodeRpcPath?: string;
60
+ coingecko: {
61
+ platform: string;
62
+ nativeCoinId: string;
63
+ } | null;
64
+ /**
65
+ * GeckoTerminal network slug (differs from `coingecko.platform`: GT uses
66
+ * "eth", CoinGecko uses "ethereum"). Used for on-chain pool lookups and
67
+ * OHLCV charts. Null when GeckoTerminal does not index this chain.
68
+ */
69
+ geckoTerminalNetwork?: string | null;
70
+ trustwalletSlug: string | null;
71
+ logoUrl: string | null;
72
+ tags: string[];
73
+ manualTokens?: ManualToken[];
74
+ /**
75
+ * Wrapped-native token address (ERC-20 or SPL).
76
+ * Used for market lookups on the native coin and for DEX routing that needs
77
+ * a wrapped form of the gas token.
78
+ */
79
+ wrappedNative?: string;
80
+ wrappedNativeCurrency?: {
81
+ name: string;
82
+ symbol: string;
83
+ decimals: number;
84
+ };
85
+ }
86
+
87
+ export type TokenIdentityKind = "native" | "wrapped-native" | "contract";
88
+ export type TokenIdentityMatch = "canonical" | "exact" | "ranked";
89
+ export type PairTokenSide = "base" | "quote";
90
+ export const TOKEN_RESOLVER_SCHEMA_VERSION = 1 as const;
91
+
92
+ export interface TokenResolverContractEnvelope {
93
+ schemaVersion: typeof TOKEN_RESOLVER_SCHEMA_VERSION;
94
+ }
95
+
96
+ export interface ResolvedTokenIdentity {
97
+ kind: TokenIdentityKind;
98
+ matchedBy: TokenIdentityMatch;
99
+ chainId: string;
100
+ address: string | null;
101
+ marketAddress: string;
102
+ name: string;
103
+ symbol: string;
104
+ nativeSymbol: string | null;
105
+ }
106
+
107
+ export interface TokenIdentityCandidate {
108
+ chainId: string;
109
+ /** DexScreener provider chain id used for follow-up market/detail requests. */
110
+ providerChainId?: string;
111
+ tokenAddress: string;
112
+ name: string;
113
+ symbol: string;
114
+ pairSide: PairTokenSide;
115
+ identity: ResolvedTokenIdentity;
116
+ }
117
+
118
+ export interface NativeAssetDefinition {
119
+ chainId: number;
120
+ chain: string;
121
+ dexscreenerChain: string;
122
+ name: string;
123
+ symbol: string;
124
+ decimals: number;
125
+ wrapped: {
126
+ address: string;
127
+ name: string;
128
+ symbol: string;
129
+ decimals: number;
130
+ };
131
+ }
132
+
133
+ export const chains: ChainDefinition[] = chainsData as unknown as ChainDefinition[];
134
+
135
+ function chainIdentifierKey(value: string): string {
136
+ return value
137
+ .trim()
138
+ .toLowerCase()
139
+ .replace(/[\s_]+/g, "-")
140
+ .replace(/-(?:chain|network|mainnet)$/, "");
141
+ }
142
+
143
+ const PROVIDER_CHAIN_ID_PATTERN = /^[a-z0-9][a-z0-9_-]{0,63}$/;
144
+
145
+ export interface DexScreenerChainIdentity {
146
+ /** Canonical B3 chain id for known chains; opaque provider id otherwise. */
147
+ identityChainId: string;
148
+ /** Exact DexScreener path/query chain id. */
149
+ providerChainId: string;
150
+ chainType: ChainDefinition["type"] | null;
151
+ registryChainId: number | null;
152
+ }
153
+
154
+ let chainByIdentifier: ReadonlyMap<string, ChainDefinition> = new Map();
155
+
156
+ export function resolveChainIdentifier(value: string): ChainDefinition | null {
157
+ return chainByIdentifier.get(chainIdentifierKey(value)) ?? null;
158
+ }
159
+
160
+ export function chainTypeForIdentifier(value: string): ChainDefinition["type"] | null {
161
+ return resolveChainIdentifier(value)?.type ?? null;
162
+ }
163
+ /**
164
+ * Translate any registry alias to its DexScreener id while preserving valid
165
+ * provider-native ids for chains the local registry does not know.
166
+ */
167
+ export function resolveDexScreenerChainIdentifier(value: string): DexScreenerChainIdentity | null {
168
+ const chain = resolveChainIdentifier(value);
169
+ if (chain?.dexscreenerNetwork) {
170
+ return {
171
+ identityChainId: chain.network,
172
+ providerChainId: chain.dexscreenerNetwork.toLowerCase(),
173
+ chainType: chain.type,
174
+ registryChainId: chain.chainId,
175
+ };
176
+ }
177
+
178
+ // A registry chain that has not declared its DexScreener id is UNKNOWN, not opaque.
179
+ // Echoing the input back hands the caller a numeric chain id or a registry alias as if
180
+ // it were a provider slug, and DexScreener answers those with 200 + [].
181
+ if (chain) {
182
+ return null;
183
+ }
184
+
185
+ const providerChainId = value.trim().toLowerCase();
186
+ if (!PROVIDER_CHAIN_ID_PATTERN.test(providerChainId)) {
187
+ return null;
188
+ }
189
+ return {
190
+ identityChainId: providerChainId,
191
+ providerChainId,
192
+ chainType: null,
193
+ registryChainId: null,
194
+ };
195
+ }
196
+
197
+ export function validateChainDefinitions(
198
+ definitions: readonly ChainDefinition[],
199
+ ): ReadonlyMap<string, ChainDefinition> {
200
+ const identifiers = new Map<string, ChainDefinition>();
201
+ const chainIds = new Map<number, ChainDefinition>();
202
+
203
+ for (const chain of definitions) {
204
+ if (
205
+ !Number.isSafeInteger(chain.chainId) ||
206
+ chain.chainId <= 0 ||
207
+ !chain.key?.trim() ||
208
+ !chain.name?.trim() ||
209
+ !chain.network?.trim() ||
210
+ (chain.type !== "evm" && chain.type !== "solana")
211
+ ) {
212
+ throw new Error(`Invalid chain definition: ${JSON.stringify(chain)}`);
213
+ }
214
+
215
+ const existingChainId = chainIds.get(chain.chainId);
216
+ if (existingChainId && existingChainId.network !== chain.network) {
217
+ throw new Error(
218
+ `Chain id ${chain.chainId} is claimed by both "${existingChainId.network}" and "${chain.network}"`,
219
+ );
220
+ }
221
+ chainIds.set(chain.chainId, chain);
222
+
223
+ if (chain.dexscreenerNetwork && !PROVIDER_CHAIN_ID_PATTERN.test(chain.dexscreenerNetwork)) {
224
+ throw new Error(`Invalid DexScreener network for "${chain.network}": ${chain.dexscreenerNetwork}`);
225
+ }
226
+ if (chain.wrappedNative && tokenAddressFamily(chain.wrappedNative) !== chain.type) {
227
+ throw new Error(`Invalid wrapped-native address for "${chain.network}": ${chain.wrappedNative}`);
228
+ }
229
+ if (chain.wrappedNativeCurrency) {
230
+ if (
231
+ !chain.wrappedNative ||
232
+ !chain.dexscreenerNetwork?.trim() ||
233
+ !chain.wrappedNativeCurrency.name?.trim() ||
234
+ !chain.wrappedNativeCurrency.symbol?.trim() ||
235
+ !Number.isSafeInteger(chain.wrappedNativeCurrency.decimals) ||
236
+ chain.wrappedNativeCurrency.decimals < 0
237
+ ) {
238
+ throw new Error(`Incomplete wrapped-native metadata for "${chain.network}"`);
239
+ }
240
+ }
241
+
242
+ for (const identifier of [
243
+ chain.network,
244
+ chain.key,
245
+ chain.name,
246
+ String(chain.chainId),
247
+ ...(chain.dexscreenerNetwork ? [chain.dexscreenerNetwork] : []),
248
+ ]) {
249
+ const key = chainIdentifierKey(identifier);
250
+ const existing = identifiers.get(key);
251
+ if (existing && existing.chainId !== chain.chainId) {
252
+ throw new Error(`Chain identifier "${key}" is claimed by both "${existing.network}" and "${chain.network}"`);
253
+ }
254
+ identifiers.set(key, chain);
255
+ }
256
+ }
257
+
258
+ const productionSolana = definitions.filter(chain => chain.type === "solana" && !chain.isTestnet);
259
+ if (productionSolana.length !== 1) {
260
+ throw new Error(`Expected one production Solana definition, found ${productionSolana.length}`);
261
+ }
262
+ const solana = productionSolana[0];
263
+ if (
264
+ solana.chainId !== 7565164 ||
265
+ solana.network !== "solana" ||
266
+ solana.name !== "Solana" ||
267
+ solana.nativeCurrency.name !== "SOL" ||
268
+ solana.nativeCurrency.symbol !== "SOL" ||
269
+ solana.nativeCurrency.decimals !== 9 ||
270
+ solana.dexscreenerNetwork !== "solana" ||
271
+ solana.wrappedNative !== "So11111111111111111111111111111111111111112" ||
272
+ solana.wrappedNativeCurrency?.name !== "Wrapped SOL" ||
273
+ solana.wrappedNativeCurrency.symbol !== "wSOL" ||
274
+ solana.wrappedNativeCurrency.decimals !== 9
275
+ ) {
276
+ throw new Error("Canonical Solana SOL/wSOL metadata is invalid");
277
+ }
278
+
279
+ return identifiers;
280
+ }
281
+
282
+ const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
283
+ const SOLANA_ADDRESS_PATTERN = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
284
+
285
+ function decodedBase58Length(value: string): number {
286
+ let leadingZeroBytes = 0;
287
+ while (value.charAt(leadingZeroBytes) === "1") {
288
+ leadingZeroBytes++;
289
+ }
290
+
291
+ let decoded = 0n;
292
+ for (let index = leadingZeroBytes; index < value.length; index++) {
293
+ decoded = decoded * 58n + BigInt(BASE58_ALPHABET.indexOf(value.charAt(index)));
294
+ }
295
+
296
+ let significantBytes = 0;
297
+ while (decoded > 0n) {
298
+ decoded >>= 8n;
299
+ significantBytes++;
300
+ }
301
+ return leadingZeroBytes + significantBytes;
302
+ }
303
+
304
+ export function isSolanaAddress(value: string): boolean {
305
+ return SOLANA_ADDRESS_PATTERN.test(value) && decodedBase58Length(value) === 32;
306
+ }
307
+
308
+ export function isEvmTokenAddress(value: string): boolean {
309
+ return /^0x[0-9a-fA-F]{40}$/.test(value);
310
+ }
311
+
312
+ export function tokenAddressFamily(value: string): ChainDefinition["type"] | null {
313
+ if (isEvmTokenAddress(value)) return "evm";
314
+ if (isSolanaAddress(value)) return "solana";
315
+ return null;
316
+ }
317
+ const OPAQUE_PROVIDER_TOKEN_PATTERN = /^[^\s\u0000-\u001F\u007F]{16,256}$/;
318
+ const SHORT_NAMESPACED_TOKEN_PATTERN = /^[^\s\u0000-\u001F\u007F]{1,256}::[^\s\u0000-\u001F\u007F]+$/;
319
+
320
+ /** Address/coin identifier accepted from a bounded DexScreener provider row. */
321
+ export function isProviderTokenAddress(value: string): boolean {
322
+ if (value.length === 0 || value.length > 256) {
323
+ return false;
324
+ }
325
+ return (
326
+ tokenAddressFamily(value) !== null ||
327
+ OPAQUE_PROVIDER_TOKEN_PATTERN.test(value) ||
328
+ SHORT_NAMESPACED_TOKEN_PATTERN.test(value)
329
+ );
330
+ }
331
+
332
+ chainByIdentifier = validateChainDefinitions(chains);
333
+
334
+ export const nativeAssets: readonly NativeAssetDefinition[] = chains.flatMap(chain => {
335
+ if (chain.isTestnet || !chain.dexscreenerNetwork || !chain.wrappedNative || !chain.wrappedNativeCurrency) {
336
+ return [];
337
+ }
338
+
339
+ return [
340
+ {
341
+ chainId: chain.chainId,
342
+ chain: chain.network,
343
+ dexscreenerChain: chain.dexscreenerNetwork,
344
+ name: chain.name,
345
+ symbol: chain.nativeCurrency.symbol,
346
+ decimals: chain.nativeCurrency.decimals,
347
+ wrapped: {
348
+ address: chain.wrappedNative,
349
+ name: chain.wrappedNativeCurrency.name,
350
+ symbol: chain.wrappedNativeCurrency.symbol,
351
+ decimals: chain.wrappedNativeCurrency.decimals,
352
+ },
353
+ },
354
+ ];
355
+ });
356
+
357
+ /** Solana asset identities whose ticker/name may short-circuit text search.
358
+ * Deliberately narrower than `nativeAssets`: B3-5071 must not change EVM
359
+ * ticker routing while establishing canonical SOL/wSOL resolution. */
360
+ export const CANONICAL_NAME_ASSETS: readonly NativeAssetDefinition[] = nativeAssets.filter(
361
+ asset => asset.chain === "solana",
362
+ );
363
+
364
+ export function matchCanonicalNativeAssetText(
365
+ asset: NativeAssetDefinition,
366
+ value: string,
367
+ ): "native" | "wrapped-native" | null {
368
+ const normalized = value.trim().replace(/^\$/, "").toLowerCase();
369
+ if (normalized === asset.symbol.toLowerCase() || normalized === asset.name.toLowerCase()) {
370
+ return "native";
371
+ }
372
+ if (normalized === asset.wrapped.symbol.toLowerCase() || normalized === asset.wrapped.name.toLowerCase()) {
373
+ return "wrapped-native";
374
+ }
375
+ return null;
376
+ }
377
+
378
+ const solanaNativeAsset = nativeAssets.find(asset => asset.chain === "solana");
379
+ if (!solanaNativeAsset) {
380
+ throw new Error("SOLANA native asset definition missing");
381
+ }
382
+ export const SOLANA_NATIVE_ASSET: NativeAssetDefinition = solanaNativeAsset;
383
+
384
+ export function createNativeTokenIdentity(asset: NativeAssetDefinition): ResolvedTokenIdentity {
385
+ return {
386
+ kind: "native",
387
+ matchedBy: "canonical",
388
+ chainId: asset.chain,
389
+ address: null,
390
+ marketAddress: asset.wrapped.address,
391
+ name: asset.name,
392
+ symbol: asset.symbol,
393
+ nativeSymbol: asset.symbol,
394
+ };
395
+ }
396
+
397
+ export function createWrappedNativeTokenIdentity(
398
+ asset: NativeAssetDefinition,
399
+ matchedBy: "canonical" | "exact",
400
+ ): ResolvedTokenIdentity {
401
+ return {
402
+ kind: "wrapped-native",
403
+ matchedBy,
404
+ chainId: asset.chain,
405
+ address: asset.wrapped.address,
406
+ marketAddress: asset.wrapped.address,
407
+ name: asset.wrapped.name,
408
+ symbol: asset.wrapped.symbol,
409
+ nativeSymbol: asset.symbol,
410
+ };
411
+ }
412
+
413
+ export function looksLikeTokenAddress(value: string): boolean {
414
+ return tokenAddressFamily(value) !== null;
415
+ }
416
+
417
+ /**
418
+ * User input likely to be a provider token address. Canonical EVM/Solana
419
+ * formats and explicit namespaced coin types qualify; arbitrary long labels do not.
420
+ */
421
+ export function looksLikeProviderTokenAddress(value: string): boolean {
422
+ if (looksLikeTokenAddress(value)) {
423
+ return true;
424
+ }
425
+ return SHORT_NAMESPACED_TOKEN_PATTERN.test(value);
426
+ }
427
+
428
+ export function isTokenAddressForChain(chainId: string, value: string): boolean {
429
+ const chainType = chainTypeForIdentifier(chainId);
430
+ return chainType !== null && tokenAddressFamily(value) === chainType;
431
+ }
432
+
433
+ export function tokenAddressKey(chainId: string, value: string): string {
434
+ const chainType = chainTypeForIdentifier(chainId);
435
+ return chainType === "evm" || (chainType === null && isEvmTokenAddress(value)) ? value.toLowerCase() : value;
436
+ }
437
+
438
+ export function isResolvedTokenIdentity(value: unknown): value is ResolvedTokenIdentity {
439
+ if (typeof value !== "object" || value === null) {
440
+ return false;
441
+ }
442
+
443
+ const identity = value as Record<string, unknown>;
444
+ if (
445
+ !["native", "wrapped-native", "contract"].includes(identity.kind as string) ||
446
+ !["canonical", "exact", "ranked"].includes(identity.matchedBy as string) ||
447
+ typeof identity.chainId !== "string" ||
448
+ resolveDexScreenerChainIdentifier(identity.chainId) === null ||
449
+ typeof identity.marketAddress !== "string" ||
450
+ !isProviderTokenAddress(identity.marketAddress) ||
451
+ typeof identity.name !== "string" ||
452
+ identity.name.trim().length === 0 ||
453
+ typeof identity.symbol !== "string" ||
454
+ identity.symbol.trim().length === 0
455
+ ) {
456
+ return false;
457
+ }
458
+
459
+ const chainType = chainTypeForIdentifier(identity.chainId);
460
+ if (chainType && tokenAddressFamily(identity.marketAddress) !== chainType) {
461
+ return false;
462
+ }
463
+
464
+ if (identity.kind === "native") {
465
+ return (
466
+ identity.matchedBy === "canonical" &&
467
+ identity.address === null &&
468
+ typeof identity.nativeSymbol === "string" &&
469
+ identity.nativeSymbol.trim().length > 0
470
+ );
471
+ }
472
+
473
+ if (identity.kind === "wrapped-native") {
474
+ return (
475
+ (identity.matchedBy === "canonical" || identity.matchedBy === "exact") &&
476
+ typeof identity.address === "string" &&
477
+ isProviderTokenAddress(identity.address) &&
478
+ (!chainType || tokenAddressFamily(identity.address) === chainType) &&
479
+ tokenAddressKey(identity.chainId, identity.address) ===
480
+ tokenAddressKey(identity.chainId, identity.marketAddress) &&
481
+ typeof identity.nativeSymbol === "string" &&
482
+ identity.nativeSymbol.trim().length > 0
483
+ );
484
+ }
485
+
486
+ return (
487
+ (identity.matchedBy === "exact" || identity.matchedBy === "ranked") &&
488
+ typeof identity.address === "string" &&
489
+ isProviderTokenAddress(identity.address) &&
490
+ (!chainType || tokenAddressFamily(identity.address) === chainType) &&
491
+ tokenAddressKey(identity.chainId, identity.address) === tokenAddressKey(identity.chainId, identity.marketAddress) &&
492
+ identity.nativeSymbol === null
493
+ );
494
+ }
495
+
496
+ export function isRegistryResolvedTokenIdentity(value: unknown): value is ResolvedTokenIdentity {
497
+ if (!isResolvedTokenIdentity(value)) {
498
+ return false;
499
+ }
500
+
501
+ if (value.kind === "native") {
502
+ return nativeAssets.some(
503
+ asset =>
504
+ value.chainId === asset.chain &&
505
+ tokenAddressKey(asset.chain, value.marketAddress) === tokenAddressKey(asset.chain, asset.wrapped.address) &&
506
+ value.name === asset.name &&
507
+ value.symbol === asset.symbol &&
508
+ value.nativeSymbol === asset.symbol,
509
+ );
510
+ }
511
+
512
+ if (value.kind === "wrapped-native") {
513
+ const address = value.address;
514
+ if (typeof address !== "string") {
515
+ return false;
516
+ }
517
+ return nativeAssets.some(
518
+ asset =>
519
+ value.chainId === asset.chain &&
520
+ tokenAddressKey(asset.chain, address) === tokenAddressKey(asset.chain, asset.wrapped.address) &&
521
+ tokenAddressKey(asset.chain, value.marketAddress) === tokenAddressKey(asset.chain, asset.wrapped.address) &&
522
+ value.name === asset.wrapped.name &&
523
+ value.symbol === asset.wrapped.symbol &&
524
+ value.nativeSymbol === asset.symbol,
525
+ );
526
+ }
527
+
528
+ const chainType = chainTypeForIdentifier(value.chainId);
529
+ return (
530
+ (!chainType || tokenAddressFamily(value.marketAddress) === chainType) &&
531
+ !nativeAssets.some(
532
+ asset =>
533
+ value.chainId === asset.chain &&
534
+ tokenAddressKey(asset.chain, value.marketAddress) === tokenAddressKey(asset.chain, asset.wrapped.address),
535
+ )
536
+ );
537
+ }
538
+
539
+ export function isTokenIdentityCandidate(value: unknown): value is TokenIdentityCandidate {
540
+ if (typeof value !== "object" || value === null) {
541
+ return false;
542
+ }
543
+
544
+ const candidate = value as Record<string, unknown>;
545
+ const identity = candidate.identity;
546
+ if (!isResolvedTokenIdentity(identity)) {
547
+ return false;
548
+ }
549
+
550
+ const chainType = chainTypeForIdentifier(identity.chainId);
551
+ return (
552
+ (!("providerChainId" in candidate) ||
553
+ (typeof candidate.providerChainId === "string" && candidate.providerChainId.trim().length > 0)) &&
554
+ (candidate.pairSide === "base" || candidate.pairSide === "quote") &&
555
+ candidate.chainId === identity.chainId &&
556
+ typeof candidate.tokenAddress === "string" &&
557
+ isProviderTokenAddress(candidate.tokenAddress) &&
558
+ (!chainType || tokenAddressFamily(candidate.tokenAddress) === chainType) &&
559
+ tokenAddressKey(identity.chainId, candidate.tokenAddress) ===
560
+ tokenAddressKey(identity.chainId, identity.marketAddress) &&
561
+ candidate.name === identity.name &&
562
+ candidate.symbol === identity.symbol
563
+ );
564
+ }
565
+
566
+ export function isRegistryTokenIdentityCandidate(value: unknown): value is TokenIdentityCandidate {
567
+ return isTokenIdentityCandidate(value) && isRegistryResolvedTokenIdentity(value.identity);
568
+ }
569
+
570
+ export const evmChains = chains.filter(c => c.type === "evm");
571
+
572
+ export const chainById = new Map(chains.map(c => [c.chainId, c]));
573
+
574
+ export const CHAIN_IDS: Record<string, number> = Object.fromEntries(chains.map(c => [c.key, c.chainId]));
575
+
576
+ export const CHAIN_NAMES: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.name]));
577
+
578
+ export const CHAIN_ID_TO_NETWORK: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.network]));
579
+
580
+ export const FALLBACK_RPC_URLS: Record<number, string> = Object.fromEntries(
581
+ chains.filter(c => c.fallbackRpc).map(c => [c.chainId, c.fallbackRpc!]),
582
+ );
583
+
584
+ export const BLOCK_EXPLORERS: Record<number, string> = Object.fromEntries(chains.map(c => [c.chainId, c.explorer]));
585
+
586
+ export const COINGECKO_MAPPINGS: Record<number, { platform: string; nativeCoinId: string }> = Object.fromEntries(
587
+ chains.filter(c => c.coingecko).map(c => [c.chainId, c.coingecko!]),
588
+ );
589
+
590
+ export const TRUSTWALLET_SLUGS: Record<number, string> = Object.fromEntries(
591
+ chains.filter(c => c.trustwalletSlug).map(c => [c.chainId, c.trustwalletSlug!]),
592
+ );
593
+
594
+ export const CHAIN_TAG_MAP: Record<string, number> = Object.fromEntries(
595
+ chains.flatMap(c => c.tags.map(tag => [tag, c.chainId])),
596
+ );
597
+
598
+ export const LOGO_URLS: Record<number, string> = Object.fromEntries(
599
+ chains.filter(c => c.logoUrl).map(c => [c.chainId, c.logoUrl!]),
600
+ );
601
+
602
+ export function buildQuicknodeUrl(subdomain: string, key: string, chain: ChainDefinition): string | null {
603
+ if (chain.quicknodeSlug === null) return null;
604
+ const network = chain.quicknodeSlug === "" ? "" : `.${chain.quicknodeSlug}`;
605
+ const path = chain.quicknodeRpcPath ?? "";
606
+ return `https://${subdomain}${network}.quiknode.pro/${key}${path}`;
607
+ }
608
+
609
+ export function buildQuicknodeRpcMap(subdomain: string, key: string): Record<number, string> {
610
+ return Object.fromEntries(
611
+ chains.filter(c => c.quicknodeSlug !== null).map(c => [c.chainId, buildQuicknodeUrl(subdomain, key, c)!]),
612
+ );
613
+ }
614
+
615
+ export function chainsByIntegration(integration: KnownIntegration): ChainDefinition[] {
616
+ return chains.filter(c => c.integrations.includes(integration));
617
+ }
618
+
619
+ export function chainIdsByIntegration(integration: KnownIntegration): number[] {
620
+ return chainsByIntegration(integration).map(c => c.chainId);
621
+ }
622
+
623
+ export function chainNamesByIntegration(integration: KnownIntegration): Record<number, string> {
624
+ return Object.fromEntries(chainsByIntegration(integration).map(c => [c.chainId, c.name]));
625
+ }
626
+
627
+ export const ZERODEV_SUPPORTED_CHAINS: ChainDefinition[] = chainsByIntegration("zerodev");
628
+
629
+ /**
630
+ * Chains tagged with the "anyspend" integration AND of EVM type — the set
631
+ * consumed by SDK `supportedChains` / `supportedChainsTW` for AnySpend's
632
+ * wallet-switch gate (`useUnifiedChainSwitchAndExecute`). Solana (also tagged
633
+ * anyspend) is excluded here because it's handled by Phantom-based flows that
634
+ * key off `RELAY_SOLANA_MAINNET_CHAIN_ID`, not viem.
635
+ */
636
+ export const ANYSPEND_EVM_CHAINS: ChainDefinition[] = chainsByIntegration("anyspend").filter(c => c.type === "evm");
637
+
638
+ // Validate at module init: every anyspend EVM chain must have a fallbackRpc.
639
+ // The SDK transformers (toViemChain / toThirdwebChain) assume this invariant
640
+ // holds — catching a missing RPC here is far better than throwing on first
641
+ // pay-button click in production.
642
+ {
643
+ const missingRpc = ANYSPEND_EVM_CHAINS.filter(c => !c.fallbackRpc);
644
+ if (missingRpc.length > 0) {
645
+ throw new Error(
646
+ `chain-registry: anyspend EVM chains missing fallbackRpc: ${missingRpc.map(c => `${c.chainId} (${c.key})`).join(", ")}`,
647
+ );
648
+ }
649
+ }
650
+
651
+ /**
652
+ * Chain IDs that declare `manualTokens` — their holdings must be enumerated
653
+ * from that list rather than discovered, so balance/metadata for them comes
654
+ * from RPC + CoinGecko instead of a portfolio indexer.
655
+ */
656
+ export const MANUAL_CHAIN_IDS: ReadonlySet<number> = new Set(
657
+ chains.filter(c => c.manualTokens && c.manualTokens.length > 0).map(c => c.chainId),
658
+ );
659
+
660
+ export function hasManualTokens(chainId: number): boolean {
661
+ return MANUAL_CHAIN_IDS.has(chainId);
662
+ }
663
+
664
+ export function getManualTokens(chainId: number): ManualToken[] {
665
+ return chainById.get(chainId)?.manualTokens ?? [];
666
+ }
667
+
668
+ export function findManualToken(chainId: number, address: string): ManualToken | null {
669
+ const lower = address.toLowerCase();
670
+ const tokens = getManualTokens(chainId);
671
+ return tokens.find(t => t.address.toLowerCase() === lower) ?? null;
672
+ }