thirdweb 5.95.0-nightly-64bd603301b3067b6a69a29f66a28dee7ffa38f5-20250416000349 → 5.95.0-nightly-4cf15a2475fce1c5b55d19f7cf51ab080e80e33f-20250418000341

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 (230) hide show
  1. package/dist/cjs/chains/utils.js +2 -4
  2. package/dist/cjs/chains/utils.js.map +1 -1
  3. package/dist/cjs/event/actions/get-events.js +4 -10
  4. package/dist/cjs/event/actions/get-events.js.map +1 -1
  5. package/dist/cjs/extensions/erc1155/read/getNFT.js +40 -0
  6. package/dist/cjs/extensions/erc1155/read/getNFT.js.map +1 -1
  7. package/dist/cjs/extensions/erc1155/read/getNFTs.js +26 -0
  8. package/dist/cjs/extensions/erc1155/read/getNFTs.js.map +1 -1
  9. package/dist/cjs/extensions/erc1155/read/getOwnedNFTs.js +46 -0
  10. package/dist/cjs/extensions/erc1155/read/getOwnedNFTs.js.map +1 -1
  11. package/dist/cjs/extensions/erc20/read/getBalance.js +2 -0
  12. package/dist/cjs/extensions/erc20/read/getBalance.js.map +1 -1
  13. package/dist/cjs/extensions/erc721/read/getNFT.js +42 -0
  14. package/dist/cjs/extensions/erc721/read/getNFT.js.map +1 -1
  15. package/dist/cjs/extensions/erc721/read/getNFTs.js +44 -17
  16. package/dist/cjs/extensions/erc721/read/getNFTs.js.map +1 -1
  17. package/dist/cjs/extensions/erc721/read/getOwnedNFTs.js +46 -0
  18. package/dist/cjs/extensions/erc721/read/getOwnedNFTs.js.map +1 -1
  19. package/dist/cjs/extensions/marketplace/direct-listings/utils.js +7 -4
  20. package/dist/cjs/extensions/marketplace/direct-listings/utils.js.map +1 -1
  21. package/dist/cjs/extensions/marketplace/english-auctions/utils.js +9 -4
  22. package/dist/cjs/extensions/marketplace/english-auctions/utils.js.map +1 -1
  23. package/dist/cjs/extensions/marketplace/offers/utils.js +7 -4
  24. package/dist/cjs/extensions/marketplace/offers/utils.js.map +1 -1
  25. package/dist/cjs/insight/common.js +18 -0
  26. package/dist/cjs/insight/common.js.map +1 -0
  27. package/dist/cjs/insight/get-events.js +12 -9
  28. package/dist/cjs/insight/get-events.js.map +1 -1
  29. package/dist/cjs/insight/get-nfts.js +213 -16
  30. package/dist/cjs/insight/get-nfts.js.map +1 -1
  31. package/dist/cjs/insight/get-tokens.js +34 -14
  32. package/dist/cjs/insight/get-tokens.js.map +1 -1
  33. package/dist/cjs/insight/get-transactions.js +17 -12
  34. package/dist/cjs/insight/get-transactions.js.map +1 -1
  35. package/dist/cjs/insight/index.js +3 -1
  36. package/dist/cjs/insight/index.js.map +1 -1
  37. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js +6 -43
  38. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
  39. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js +3 -9
  40. package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
  41. package/dist/cjs/react/web/ui/components/TokenIcon.js +3 -1
  42. package/dist/cjs/react/web/ui/components/TokenIcon.js.map +1 -1
  43. package/dist/cjs/react/web/ui/prebuilt/NFT/utils.js +7 -2
  44. package/dist/cjs/react/web/ui/prebuilt/NFT/utils.js.map +1 -1
  45. package/dist/cjs/rpc/fetch-rpc.js +2 -22
  46. package/dist/cjs/rpc/fetch-rpc.js.map +1 -1
  47. package/dist/cjs/rpc/rpc.js +1 -1
  48. package/dist/cjs/rpc/rpc.js.map +1 -1
  49. package/dist/cjs/social/profiles.js +3 -8
  50. package/dist/cjs/social/profiles.js.map +1 -1
  51. package/dist/cjs/storage/download.js +2 -2
  52. package/dist/cjs/storage/download.js.map +1 -1
  53. package/dist/cjs/storage/unpin.js +2 -2
  54. package/dist/cjs/storage/unpin.js.map +1 -1
  55. package/dist/cjs/storage/upload/web-node.js +0 -1
  56. package/dist/cjs/storage/upload/web-node.js.map +1 -1
  57. package/dist/cjs/utils/nft/parseNft.js +4 -0
  58. package/dist/cjs/utils/nft/parseNft.js.map +1 -1
  59. package/dist/cjs/utils/signatures/resolve-signature.js +0 -2
  60. package/dist/cjs/utils/signatures/resolve-signature.js.map +1 -1
  61. package/dist/cjs/version.js +1 -1
  62. package/dist/cjs/wallets/in-app/core/users/getUser.js +2 -1
  63. package/dist/cjs/wallets/in-app/core/users/getUser.js.map +1 -1
  64. package/dist/cjs/wallets/smart/lib/calls.js +2 -2
  65. package/dist/cjs/wallets/smart/lib/calls.js.map +1 -1
  66. package/dist/cjs/wallets/utils/getWalletBalance.js +3 -0
  67. package/dist/cjs/wallets/utils/getWalletBalance.js.map +1 -1
  68. package/dist/esm/chains/utils.js +2 -4
  69. package/dist/esm/chains/utils.js.map +1 -1
  70. package/dist/esm/event/actions/get-events.js +1 -7
  71. package/dist/esm/event/actions/get-events.js.map +1 -1
  72. package/dist/esm/extensions/erc1155/read/getNFT.js +40 -0
  73. package/dist/esm/extensions/erc1155/read/getNFT.js.map +1 -1
  74. package/dist/esm/extensions/erc1155/read/getNFTs.js +26 -0
  75. package/dist/esm/extensions/erc1155/read/getNFTs.js.map +1 -1
  76. package/dist/esm/extensions/erc1155/read/getOwnedNFTs.js +46 -0
  77. package/dist/esm/extensions/erc1155/read/getOwnedNFTs.js.map +1 -1
  78. package/dist/esm/extensions/erc20/read/getBalance.js +2 -0
  79. package/dist/esm/extensions/erc20/read/getBalance.js.map +1 -1
  80. package/dist/esm/extensions/erc721/read/getNFT.js +42 -0
  81. package/dist/esm/extensions/erc721/read/getNFT.js.map +1 -1
  82. package/dist/esm/extensions/erc721/read/getNFTs.js +44 -17
  83. package/dist/esm/extensions/erc721/read/getNFTs.js.map +1 -1
  84. package/dist/esm/extensions/erc721/read/getOwnedNFTs.js +46 -0
  85. package/dist/esm/extensions/erc721/read/getOwnedNFTs.js.map +1 -1
  86. package/dist/esm/extensions/marketplace/direct-listings/utils.js +7 -4
  87. package/dist/esm/extensions/marketplace/direct-listings/utils.js.map +1 -1
  88. package/dist/esm/extensions/marketplace/english-auctions/utils.js +9 -4
  89. package/dist/esm/extensions/marketplace/english-auctions/utils.js.map +1 -1
  90. package/dist/esm/extensions/marketplace/offers/utils.js +7 -4
  91. package/dist/esm/extensions/marketplace/offers/utils.js.map +1 -1
  92. package/dist/esm/insight/common.js +15 -0
  93. package/dist/esm/insight/common.js.map +1 -0
  94. package/dist/esm/insight/get-events.js +8 -5
  95. package/dist/esm/insight/get-events.js.map +1 -1
  96. package/dist/esm/insight/get-nfts.js +208 -13
  97. package/dist/esm/insight/get-nfts.js.map +1 -1
  98. package/dist/esm/insight/get-tokens.js +30 -10
  99. package/dist/esm/insight/get-tokens.js.map +1 -1
  100. package/dist/esm/insight/get-transactions.js +13 -8
  101. package/dist/esm/insight/get-transactions.js.map +1 -1
  102. package/dist/esm/insight/index.js +1 -1
  103. package/dist/esm/insight/index.js.map +1 -1
  104. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js +6 -43
  105. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
  106. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js +3 -9
  107. package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
  108. package/dist/esm/react/web/ui/components/TokenIcon.js +3 -1
  109. package/dist/esm/react/web/ui/components/TokenIcon.js.map +1 -1
  110. package/dist/esm/react/web/ui/prebuilt/NFT/utils.js +7 -2
  111. package/dist/esm/react/web/ui/prebuilt/NFT/utils.js.map +1 -1
  112. package/dist/esm/rpc/fetch-rpc.js +2 -22
  113. package/dist/esm/rpc/fetch-rpc.js.map +1 -1
  114. package/dist/esm/rpc/rpc.js +1 -1
  115. package/dist/esm/rpc/rpc.js.map +1 -1
  116. package/dist/esm/social/profiles.js +3 -8
  117. package/dist/esm/social/profiles.js.map +1 -1
  118. package/dist/esm/storage/download.js +2 -2
  119. package/dist/esm/storage/download.js.map +1 -1
  120. package/dist/esm/storage/unpin.js +2 -2
  121. package/dist/esm/storage/unpin.js.map +1 -1
  122. package/dist/esm/storage/upload/web-node.js +0 -1
  123. package/dist/esm/storage/upload/web-node.js.map +1 -1
  124. package/dist/esm/utils/nft/parseNft.js +4 -0
  125. package/dist/esm/utils/nft/parseNft.js.map +1 -1
  126. package/dist/esm/utils/signatures/resolve-signature.js +0 -2
  127. package/dist/esm/utils/signatures/resolve-signature.js.map +1 -1
  128. package/dist/esm/version.js +1 -1
  129. package/dist/esm/wallets/in-app/core/users/getUser.js +2 -1
  130. package/dist/esm/wallets/in-app/core/users/getUser.js.map +1 -1
  131. package/dist/esm/wallets/smart/lib/calls.js +2 -2
  132. package/dist/esm/wallets/smart/lib/calls.js.map +1 -1
  133. package/dist/esm/wallets/utils/getWalletBalance.js +3 -0
  134. package/dist/esm/wallets/utils/getWalletBalance.js.map +1 -1
  135. package/dist/types/chains/utils.d.ts.map +1 -1
  136. package/dist/types/event/actions/get-events.d.ts.map +1 -1
  137. package/dist/types/extensions/erc1155/read/getNFT.d.ts +5 -0
  138. package/dist/types/extensions/erc1155/read/getNFT.d.ts.map +1 -1
  139. package/dist/types/extensions/erc1155/read/getNFTs.d.ts +5 -0
  140. package/dist/types/extensions/erc1155/read/getNFTs.d.ts.map +1 -1
  141. package/dist/types/extensions/erc1155/read/getOwnedNFTs.d.ts +7 -1
  142. package/dist/types/extensions/erc1155/read/getOwnedNFTs.d.ts.map +1 -1
  143. package/dist/types/extensions/erc20/read/getBalance.d.ts +2 -0
  144. package/dist/types/extensions/erc20/read/getBalance.d.ts.map +1 -1
  145. package/dist/types/extensions/erc721/read/getNFT.d.ts +5 -0
  146. package/dist/types/extensions/erc721/read/getNFT.d.ts.map +1 -1
  147. package/dist/types/extensions/erc721/read/getNFTs.d.ts +5 -0
  148. package/dist/types/extensions/erc721/read/getNFTs.d.ts.map +1 -1
  149. package/dist/types/extensions/erc721/read/getOwnedNFTs.d.ts +3 -1
  150. package/dist/types/extensions/erc721/read/getOwnedNFTs.d.ts.map +1 -1
  151. package/dist/types/extensions/marketplace/direct-listings/utils.d.ts.map +1 -1
  152. package/dist/types/extensions/marketplace/english-auctions/utils.d.ts.map +1 -1
  153. package/dist/types/extensions/marketplace/offers/utils.d.ts.map +1 -1
  154. package/dist/types/insight/common.d.ts +3 -0
  155. package/dist/types/insight/common.d.ts.map +1 -0
  156. package/dist/types/insight/get-events.d.ts +2 -2
  157. package/dist/types/insight/get-events.d.ts.map +1 -1
  158. package/dist/types/insight/get-nfts.d.ts +52 -4
  159. package/dist/types/insight/get-nfts.d.ts.map +1 -1
  160. package/dist/types/insight/get-tokens.d.ts +3 -3
  161. package/dist/types/insight/get-tokens.d.ts.map +1 -1
  162. package/dist/types/insight/get-transactions.d.ts +1 -1
  163. package/dist/types/insight/get-transactions.d.ts.map +1 -1
  164. package/dist/types/insight/index.d.ts +2 -2
  165. package/dist/types/insight/index.d.ts.map +1 -1
  166. package/dist/types/react/core/utils/wallet.d.ts +1 -1
  167. package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/useBuyTxStates.d.ts +1 -1
  168. package/dist/types/react/web/ui/ConnectWallet/screens/ViewNFTs.d.ts.map +1 -1
  169. package/dist/types/react/web/ui/ConnectWallet/screens/ViewTokens.d.ts.map +1 -1
  170. package/dist/types/react/web/ui/components/TokenIcon.d.ts.map +1 -1
  171. package/dist/types/react/web/ui/prebuilt/NFT/utils.d.ts.map +1 -1
  172. package/dist/types/rpc/fetch-rpc.d.ts.map +1 -1
  173. package/dist/types/rpc/rpc.d.ts.map +1 -1
  174. package/dist/types/social/profiles.d.ts.map +1 -1
  175. package/dist/types/storage/download.d.ts.map +1 -1
  176. package/dist/types/storage/unpin.d.ts.map +1 -1
  177. package/dist/types/storage/upload/web-node.d.ts.map +1 -1
  178. package/dist/types/utils/nft/parseNft.d.ts +8 -0
  179. package/dist/types/utils/nft/parseNft.d.ts.map +1 -1
  180. package/dist/types/utils/signatures/resolve-signature.d.ts.map +1 -1
  181. package/dist/types/version.d.ts +1 -1
  182. package/dist/types/wallets/in-app/core/users/getUser.d.ts.map +1 -1
  183. package/dist/types/wallets/utils/getWalletBalance.d.ts +2 -7
  184. package/dist/types/wallets/utils/getWalletBalance.d.ts.map +1 -1
  185. package/package.json +4 -4
  186. package/src/chains/utils.ts +6 -4
  187. package/src/event/actions/get-events.ts +1 -13
  188. package/src/extensions/erc1155/read/getNFT.test.ts +13 -0
  189. package/src/extensions/erc1155/read/getNFT.ts +53 -1
  190. package/src/extensions/erc1155/read/getNFTs.ts +38 -0
  191. package/src/extensions/erc1155/read/getOwnedNFTs.ts +65 -2
  192. package/src/extensions/erc20/drop20.test.ts +48 -132
  193. package/src/extensions/erc20/read/getBalance.test.ts +5 -9
  194. package/src/extensions/erc20/read/getBalance.ts +4 -0
  195. package/src/extensions/erc721/read/getNFT.test.ts +106 -0
  196. package/src/extensions/erc721/read/getNFT.ts +55 -1
  197. package/src/extensions/erc721/read/getNFTs.test.ts +212 -6
  198. package/src/extensions/erc721/read/getNFTs.ts +59 -20
  199. package/src/extensions/erc721/read/getOwnedNFTs.test.ts +27 -2
  200. package/src/extensions/erc721/read/getOwnedNFTs.ts +61 -1
  201. package/src/extensions/erc721/token721.test.ts +2 -0
  202. package/src/extensions/marketplace/direct-listings/direct-listings.test.ts +2 -18
  203. package/src/extensions/marketplace/direct-listings/utils.ts +7 -4
  204. package/src/extensions/marketplace/english-auctions/utils.ts +9 -4
  205. package/src/extensions/marketplace/offers/utils.ts +7 -4
  206. package/src/insight/common.ts +24 -0
  207. package/src/insight/get-events.ts +23 -9
  208. package/src/insight/get-nfts.ts +315 -20
  209. package/src/insight/get-tokens.ts +51 -23
  210. package/src/insight/get-transactions.ts +26 -16
  211. package/src/insight/index.ts +6 -2
  212. package/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx +43 -68
  213. package/src/react/web/ui/ConnectWallet/screens/ViewTokens.tsx +4 -14
  214. package/src/react/web/ui/components/TokenIcon.tsx +12 -3
  215. package/src/react/web/ui/prebuilt/NFT/utils.test.ts +2 -64
  216. package/src/react/web/ui/prebuilt/NFT/utils.ts +7 -2
  217. package/src/rpc/fetch-rpc.ts +2 -20
  218. package/src/rpc/rpc.ts +5 -1
  219. package/src/social/profiles.ts +5 -9
  220. package/src/storage/download.ts +4 -2
  221. package/src/storage/unpin.ts +4 -2
  222. package/src/storage/upload/web-node.ts +0 -1
  223. package/src/utils/nft/parseNft.test.ts +8 -0
  224. package/src/utils/nft/parseNft.ts +12 -0
  225. package/src/utils/signatures/resolve-signature.ts +0 -2
  226. package/src/version.ts +1 -1
  227. package/src/wallets/in-app/core/users/getUser.test.ts +4 -1
  228. package/src/wallets/in-app/core/users/getUser.ts +4 -1
  229. package/src/wallets/smart/lib/calls.ts +2 -2
  230. package/src/wallets/utils/getWalletBalance.ts +5 -7
@@ -130,53 +130,12 @@ export function ViewNFTsContent(props: {
130
130
  });
131
131
 
132
132
  return result
133
- .filter((nft) => !!nft.name && !!nft.image_url)
133
+ .filter((nft) => !!nft.metadata.name && !!nft.metadata.image)
134
134
  .map((nft) => {
135
- let parsedNft: NFT;
136
- const metadata = {
137
- name: nft.name,
138
- description: nft.description,
139
- image: nft.image_url,
140
- animation_url: nft.video_url,
141
- external_url: nft.external_url,
142
- background_color: nft.background_color,
143
- uri: nft.metadata_url ?? "",
144
- image_url: nft.image_url,
145
- attributes: Array.isArray(nft.extra_metadata?.attributes)
146
- ? nft.extra_metadata?.attributes?.reduce(
147
- (acc, attr) => {
148
- acc[attr.trait_type] = attr.value;
149
- return acc;
150
- },
151
- {} as Record<string, unknown>,
152
- )
153
- : {},
154
- };
155
-
156
- if (nft.contract?.type === "erc1155") {
157
- parsedNft = {
158
- id: BigInt(nft.token_id),
159
- type: "ERC1155",
160
- owner: activeAccount.address,
161
- tokenURI: nft.metadata_url ?? "",
162
- supply: BigInt(nft.balance), // TODO: this is wrong
163
- metadata,
164
- };
165
- } else {
166
- parsedNft = {
167
- id: BigInt(nft.token_id),
168
- type: "ERC721",
169
- owner: activeAccount.address,
170
- tokenURI: nft.metadata_url ?? "",
171
- metadata,
172
- };
173
- }
174
-
175
135
  return {
176
- chain: getCachedChain(nft.chain_id),
177
- address: nft.token_address as Address,
178
- quantityOwned: BigInt(nft.balance),
179
- ...parsedNft,
136
+ chain: getCachedChain(nft.chainId),
137
+ address: nft.tokenAddress as Address,
138
+ ...nft,
180
139
  };
181
140
  });
182
141
  },
@@ -197,29 +156,45 @@ export function ViewNFTsContent(props: {
197
156
 
198
157
  return (
199
158
  <>
200
- <Container
201
- style={{
202
- display: "grid",
203
- gridTemplateColumns: "1fr 1fr",
204
- gap: "12px",
205
- }}
206
- >
207
- {nftQuery.error ? (
208
- <Text>Error loading NFTs</Text>
209
- ) : nftQuery.isLoading || !filteredNFTs ? (
210
- <Skeleton height="150px" width="150px" />
211
- ) : (
212
- filteredNFTs.map((nft) => (
213
- <NftCard
214
- key={`${nft.chain.id}:${nft.address}:${nft.id}`}
215
- {...nft}
216
- client={props.client}
217
- chain={nft.chain}
218
- theme={props.theme}
219
- />
220
- ))
221
- )}
222
- </Container>
159
+ {nftQuery.error ? (
160
+ <Container center="both" py="lg">
161
+ <Text size="sm" color="secondaryText" center>
162
+ Error loading NFTs
163
+ </Text>
164
+ </Container>
165
+ ) : nftQuery.data?.length === 0 && !nftQuery.isLoading ? (
166
+ <Container center="both" py="lg">
167
+ <Text size="sm" color="secondaryText" center>
168
+ No NFTs found on this chain
169
+ </Text>
170
+ </Container>
171
+ ) : (
172
+ <Container
173
+ style={{
174
+ display: "grid",
175
+ gridTemplateColumns: "1fr 1fr",
176
+ gap: "12px",
177
+ }}
178
+ >
179
+ {nftQuery.isLoading || !filteredNFTs ? (
180
+ <>
181
+ <Skeleton height="150px" width="150px" />
182
+ <Skeleton height="150px" width="150px" />
183
+ <Skeleton height="150px" width="150px" />
184
+ </>
185
+ ) : (
186
+ filteredNFTs.map((nft) => (
187
+ <NftCard
188
+ key={`${nft.chain.id}:${nft.address}:${nft.id}`}
189
+ {...nft}
190
+ client={props.client}
191
+ chain={nft.chain}
192
+ theme={props.theme}
193
+ />
194
+ ))
195
+ )}
196
+ </Container>
197
+ )}
223
198
  <Spacer y="lg" />
224
199
  </>
225
200
  );
@@ -2,7 +2,6 @@ import { useQuery } from "@tanstack/react-query";
2
2
  import type { Chain } from "../../../../../chains/types.js";
3
3
  import type { ThirdwebClient } from "../../../../../client/client.js";
4
4
  import { getOwnedTokens } from "../../../../../insight/get-tokens.js";
5
- import { toTokens } from "../../../../../utils/units.js";
6
5
  import { fontSize } from "../../../../core/design-system/index.js";
7
6
  import { useWalletBalance } from "../../../../core/hooks/others/useWalletBalance.js";
8
7
  import { useActiveAccount } from "../../../../core/hooks/wallets/useActiveAccount.js";
@@ -94,8 +93,7 @@ export function ViewTokensContent(props: {
94
93
  return result.filter(
95
94
  (token) =>
96
95
  !defaultTokens[activeChain.id]?.some(
97
- (t) =>
98
- t.address.toLowerCase() === token.token_address.toLowerCase(),
96
+ (t) => t.address.toLowerCase() === token.tokenAddress.toLowerCase(),
99
97
  ),
100
98
  );
101
99
  },
@@ -139,22 +137,14 @@ export function ViewTokensContent(props: {
139
137
  return (
140
138
  <TokenInfo
141
139
  token={{
142
- address: token.token_address,
140
+ address: token.tokenAddress,
143
141
  name: token.name ?? "",
144
142
  symbol: token.symbol ?? "",
145
143
  }}
146
- key={token.token_address}
144
+ key={token.tokenAddress}
147
145
  chain={activeChain}
148
146
  client={props.client}
149
- balanceData={{
150
- symbol: token.symbol ?? "",
151
- name: token.name ?? "",
152
- decimals: token.decimals ?? 18,
153
- displayValue: toTokens(
154
- BigInt(token.balance),
155
- token.decimals ?? 18,
156
- ),
157
- }}
147
+ balanceData={token}
158
148
  />
159
149
  );
160
150
  })}
@@ -6,12 +6,13 @@ import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
6
6
  import { iconSize } from "../../../core/design-system/index.js";
7
7
  import { useChainIconUrl } from "../../../core/hooks/others/useChainQuery.js";
8
8
  import { genericTokenIcon } from "../../../core/utils/walletIcon.js";
9
+ import { CoinsIcon } from "../ConnectWallet/icons/CoinsIcon.js";
9
10
  import {
10
11
  type NativeToken,
11
12
  isNativeToken,
12
13
  } from "../ConnectWallet/screens/nativeToken.js";
13
14
  import { Img } from "./Img.js";
14
-
15
+ import { Container } from "./basic.js";
15
16
  /**
16
17
  * @internal
17
18
  */
@@ -38,13 +39,21 @@ export function TokenIcon(props: {
38
39
  return props.token.icon;
39
40
  }, [props.token, chainIconQuery.url]);
40
41
 
41
- return (
42
+ return tokenImage ? (
42
43
  <Img
43
- src={tokenImage || ""}
44
+ src={tokenImage}
44
45
  width={iconSize[props.size]}
45
46
  height={iconSize[props.size]}
46
47
  fallbackImage={genericTokenIcon}
47
48
  client={props.client}
48
49
  />
50
+ ) : (
51
+ <Container
52
+ center="both"
53
+ style={{ width: iconSize[props.size], height: iconSize[props.size] }}
54
+ color="secondaryText"
55
+ >
56
+ <CoinsIcon size={iconSize[props.size]} />
57
+ </Container>
49
58
  );
50
59
  }
@@ -12,40 +12,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getNFTInfo", () => {
12
12
  contract: DOODLES_CONTRACT,
13
13
  tokenId: 0n,
14
14
  });
15
- expect(nft).toStrictEqual({
16
- id: 0n,
17
- metadata: {
18
- attributes: [
19
- {
20
- trait_type: "face",
21
- value: "mustache",
22
- },
23
- {
24
- trait_type: "hair",
25
- value: "purple long",
26
- },
27
- {
28
- trait_type: "body",
29
- value: "blue and yellow jacket",
30
- },
31
- {
32
- trait_type: "background",
33
- value: "green",
34
- },
35
- {
36
- trait_type: "head",
37
- value: "tan",
38
- },
39
- ],
40
- description:
41
- "A community-driven collectibles project featuring art by Burnt Toast. Doodles come in a joyful range of colors, traits and sizes with a collection size of 10,000. Each Doodle allows its owner to vote for experiences and activations paid for by the Doodles Community Treasury. Burnt Toast is the working alias for Scott Martin, a Canadian–based illustrator, designer, animator and muralist.",
42
- image: "ipfs://QmUEfFfwAh4wyB5UfHCVPUxis4j4Q4kJXtm5x5p3g1fVUn",
43
- name: "Doodle #0",
44
- },
45
- owner: null,
46
- tokenURI: "ipfs://QmPMc4tcBsMqLRuCQtPmPe84bpSjrC3Ky7t3JWuHXYB4aS/0",
47
- type: "ERC721",
48
- });
15
+ expect(nft.metadata.name).toBe("Doodle #0");
49
16
  });
50
17
 
51
18
  it("should work with ERC1155", async () => {
@@ -53,36 +20,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getNFTInfo", () => {
53
20
  contract: DROP1155_CONTRACT,
54
21
  tokenId: 0n,
55
22
  });
56
- expect(nft).toStrictEqual({
57
- id: 0n,
58
- metadata: {
59
- animation_url:
60
- "ipfs://QmeGCqV1mSHTZrvuFzW1XZdCRRGXB6AmSotTqHoxA2xfDo/1.mp4",
61
- attributes: [
62
- {
63
- trait_type: "Revenue Share",
64
- value: "40%",
65
- },
66
- {
67
- trait_type: "Max Supply",
68
- value: "50",
69
- },
70
- {
71
- trait_type: "Max Per Wallet",
72
- value: "1",
73
- },
74
- ],
75
- background_color: "",
76
- description: "",
77
- external_url: "https://auraexchange.org",
78
- image: "ipfs://QmeGCqV1mSHTZrvuFzW1XZdCRRGXB6AmSotTqHoxA2xfDo/0.png",
79
- name: "Aura OG",
80
- },
81
- owner: null,
82
- supply: 33n,
83
- tokenURI: "ipfs://QmNgevzVNwJWJdErFY2B7KsuKdJz3gVuBraNKaSxPktLh5/0",
84
- type: "ERC1155",
85
- });
23
+ expect(nft.metadata.name).toBe("Aura OG");
86
24
  });
87
25
 
88
26
  it("should throw error if failed to load nft info", async () => {
@@ -11,8 +11,13 @@ export async function getNFTInfo(options: NFTProviderProps): Promise<NFT> {
11
11
  return withCache(
12
12
  async () => {
13
13
  const nft = await Promise.allSettled([
14
- getNFT721(options),
15
- getNFT1155(options),
14
+ getNFT721({
15
+ ...options,
16
+ useIndexer: false, // TODO (insight): switch this call to only call insight once
17
+ }),
18
+ getNFT1155({
19
+ ...options,
20
+ }),
16
21
  ]).then(([possibleNFT721, possibleNFT1155]) => {
17
22
  // getNFT extension always return an NFT object
18
23
  // so we need to check if the tokenURI exists
@@ -78,16 +78,7 @@ export async function fetchRpc(
78
78
  );
79
79
  }
80
80
 
81
- if (response.headers.get("Content-Type")?.startsWith("application/json")) {
82
- return await response.json();
83
- }
84
- const text = await response.text();
85
- try {
86
- return JSON.parse(text);
87
- } catch (err) {
88
- console.error("Error parsing response", err, text);
89
- throw err;
90
- }
81
+ return await response.json();
91
82
  }
92
83
 
93
84
  type FetchSingleRpcOptions = {
@@ -121,14 +112,5 @@ export async function fetchSingleRpc(
121
112
  `RPC request failed with status ${response.status} - ${response.statusText}: ${error || "unknown error"}`,
122
113
  );
123
114
  }
124
- if (response.headers.get("Content-Type")?.startsWith("application/json")) {
125
- return await response.json();
126
- }
127
- const text = await response.text();
128
- try {
129
- return JSON.parse(text);
130
- } catch (err) {
131
- console.error("Error parsing response", err, text);
132
- throw err;
133
- }
115
+ return await response.json();
134
116
  }
package/src/rpc/rpc.ts CHANGED
@@ -144,7 +144,11 @@ export function getRpcClient(
144
144
 
145
145
  // No response.
146
146
  if (!response) {
147
- inflight.reject(new Error("No response"));
147
+ inflight.reject(
148
+ new Error(
149
+ `No response for index ${index} - all responses: ${stringify(responses)}`,
150
+ ),
151
+ );
148
152
  }
149
153
  // Response is an error or error string.
150
154
  else if (response instanceof Error) {
@@ -32,15 +32,11 @@ export async function getSocialProfiles(args: {
32
32
  `${getThirdwebBaseUrl("social")}/v1/profiles/${address}`,
33
33
  );
34
34
 
35
- if (response.status !== 200) {
36
- try {
37
- const errorBody = await response.json();
38
- throw new Error(`Failed to fetch profile: ${errorBody.message}`);
39
- } catch {
40
- throw new Error(
41
- `Failed to fetch profile: ${response.status}\n${await response.text()}`,
42
- );
43
- }
35
+ if (!response.ok) {
36
+ const errorBody = await response.text().catch(() => "Unknown error");
37
+ throw new Error(
38
+ `Failed to fetch profile: ${response.status} ${response.statusText} - ${errorBody}`,
39
+ );
44
40
  }
45
41
 
46
42
  return (await response.json()).data as SocialProfile[];
@@ -99,8 +99,10 @@ export async function download(options: DownloadOptions) {
99
99
  });
100
100
 
101
101
  if (!res.ok) {
102
- res.body?.cancel();
103
- throw new Error(`Failed to download file: ${res.statusText}`);
102
+ const error = await res.text();
103
+ throw new Error(
104
+ `Failed to download file: ${res.status} ${res.statusText} ${error || ""}`,
105
+ );
104
106
  }
105
107
  return res;
106
108
  }
@@ -41,12 +41,14 @@ export async function unpin(options: UnpinOptions) {
41
41
  );
42
42
 
43
43
  if (!res.ok) {
44
- res.body?.cancel();
45
44
  if (res.status === 401) {
46
45
  throw new Error(
47
46
  "Unauthorized - You don't have permission to use this service.",
48
47
  );
49
48
  }
50
- throw new Error(`Failed to unpin file - ${res.status} - ${res.statusText}`);
49
+ const error = await res.text();
50
+ throw new Error(
51
+ `Failed to unpin file - ${res.status} - ${res.statusText} ${error || ""}`,
52
+ );
51
53
  }
52
54
  }
@@ -29,7 +29,6 @@ export async function uploadBatch<const TFiles extends UploadableFile[]>(
29
29
  );
30
30
 
31
31
  if (!res.ok) {
32
- res.body?.cancel();
33
32
  if (res.status === 401) {
34
33
  throw new Error(
35
34
  "Unauthorized - You don't have permission to use this service.",
@@ -21,6 +21,8 @@ describe("parseNft", () => {
21
21
  tokenId: 0n,
22
22
  tokenUri: "ipfs://",
23
23
  type: "ERC721",
24
+ tokenAddress: "0x1234567890123456789012345678901234567890",
25
+ chainId: 1,
24
26
  };
25
27
  const result = parseNFT(base, option);
26
28
  const expectedResult: NFT = {
@@ -29,6 +31,8 @@ describe("parseNft", () => {
29
31
  id: option.tokenId,
30
32
  tokenURI: option.tokenUri,
31
33
  type: option.type,
34
+ tokenAddress: option.tokenAddress,
35
+ chainId: option.chainId,
32
36
  };
33
37
  expect(result).toMatchObject(expectedResult);
34
38
  });
@@ -39,6 +43,8 @@ describe("parseNft", () => {
39
43
  tokenUri: "ipfs://",
40
44
  type: "ERC1155",
41
45
  supply: 10n,
46
+ tokenAddress: "0x1234567890123456789012345678901234567890",
47
+ chainId: 1,
42
48
  };
43
49
  const expectedResult: NFT = {
44
50
  metadata: base,
@@ -47,6 +53,8 @@ describe("parseNft", () => {
47
53
  tokenURI: option.tokenUri,
48
54
  type: option.type,
49
55
  supply: option.supply,
56
+ tokenAddress: option.tokenAddress,
57
+ chainId: option.chainId,
50
58
  };
51
59
  const result = parseNFT(base, option);
52
60
  expect(result).toMatchObject(expectedResult);
@@ -41,6 +41,8 @@ export type NFT =
41
41
  id: bigint;
42
42
  tokenURI: string;
43
43
  type: "ERC721";
44
+ tokenAddress: string;
45
+ chainId: number;
44
46
  }
45
47
  | {
46
48
  metadata: NFTMetadata;
@@ -49,6 +51,8 @@ export type NFT =
49
51
  tokenURI: string;
50
52
  type: "ERC1155";
51
53
  supply: bigint;
54
+ tokenAddress: string;
55
+ chainId: number;
52
56
  };
53
57
 
54
58
  /**
@@ -60,6 +64,8 @@ export type ParseNFTOptions =
60
64
  tokenUri: string;
61
65
  type: "ERC721";
62
66
  owner?: string | null;
67
+ tokenAddress: string;
68
+ chainId: number;
63
69
  }
64
70
  | {
65
71
  tokenId: bigint;
@@ -67,6 +73,8 @@ export type ParseNFTOptions =
67
73
  type: "ERC1155";
68
74
  owner?: string | null;
69
75
  supply: bigint;
76
+ tokenAddress: string;
77
+ chainId: number;
70
78
  };
71
79
 
72
80
  /**
@@ -85,6 +93,8 @@ export function parseNFT(base: NFTMetadata, options: ParseNFTOptions): NFT {
85
93
  id: options.tokenId,
86
94
  tokenURI: options.tokenUri,
87
95
  type: options.type,
96
+ tokenAddress: options.tokenAddress,
97
+ chainId: options.chainId,
88
98
  };
89
99
  case "ERC1155":
90
100
  return {
@@ -94,6 +104,8 @@ export function parseNFT(base: NFTMetadata, options: ParseNFTOptions): NFT {
94
104
  tokenURI: options.tokenUri,
95
105
  type: options.type,
96
106
  supply: options.supply,
107
+ tokenAddress: options.tokenAddress,
108
+ chainId: options.chainId,
97
109
  };
98
110
  default:
99
111
  throw new Error("Invalid NFT type");
@@ -17,7 +17,6 @@ async function resolveFunctionSignature(
17
17
  `${SIGNATURE_API}/signatures/?format=json&hex_signature=${hexSig}`,
18
18
  );
19
19
  if (!res.ok) {
20
- res.body?.cancel();
21
20
  return null;
22
21
  }
23
22
  const data = await res.json();
@@ -39,7 +38,6 @@ async function resolveEventSignature(
39
38
  `${SIGNATURE_API}/event-signatures/?format=json&hex_signature=${hexSig}`,
40
39
  );
41
40
  if (!res.ok) {
42
- res.body?.cancel();
43
41
  return null;
44
42
  }
45
43
  const data = await res.json();
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.95.0-nightly-64bd603301b3067b6a69a29f66a28dee7ffa38f5-20250416000349";
1
+ export const version = "5.95.0-nightly-4cf15a2475fce1c5b55d19f7cf51ab080e80e33f-20250418000341";
@@ -190,6 +190,9 @@ describe("getUser", () => {
190
190
  it("should handle fetch errors", async () => {
191
191
  mockFetch.mockResolvedValueOnce({
192
192
  ok: false,
193
+ status: 404,
194
+ statusText: "Not Found",
195
+ text: async () => "some message",
193
196
  });
194
197
 
195
198
  await expect(
@@ -197,7 +200,7 @@ describe("getUser", () => {
197
200
  client: mockClient,
198
201
  walletAddress: "0x123",
199
202
  }),
200
- ).rejects.toThrow("Failed to get profiles");
203
+ ).rejects.toThrow("Failed to get profiles. 404 Not Found: some message");
201
204
  });
202
205
 
203
206
  it("should return null if no user is found", async () => {
@@ -95,7 +95,10 @@ export async function getUser({
95
95
  const res = await clientFetch(url.toString());
96
96
 
97
97
  if (!res.ok) {
98
- throw new Error("Failed to get profiles");
98
+ const error = await res.text().catch(() => "Unknown error");
99
+ throw new Error(
100
+ `Failed to get profiles. ${res.status} ${res.statusText}: ${error}`,
101
+ );
99
102
  }
100
103
 
101
104
  const data = (await res.json()) as {
@@ -114,8 +114,8 @@ export async function predictAddress(args: {
114
114
  throw error;
115
115
  }
116
116
 
117
- // Exponential backoff: 2^(retries + 1) * 100ms (200ms, 400ms, 800ms)
118
- const delay = 2 ** (retries + 1) * 100;
117
+ // Exponential backoff: 2^(retries + 1) * 200ms (400ms, 800ms, 1600ms)
118
+ const delay = 2 ** (retries + 1) * 200;
119
119
  await new Promise((resolve) => setTimeout(resolve, delay));
120
120
  retries++;
121
121
  }
@@ -5,7 +5,9 @@ import {
5
5
  getChainSymbol,
6
6
  } from "../../chains/utils.js";
7
7
  import type { ThirdwebClient } from "../../client/client.js";
8
+ import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
8
9
  import { getContract } from "../../contract/contract.js";
10
+ import type { GetBalanceResult } from "../../extensions/erc20/read/getBalance.js";
9
11
  import { eth_getBalance } from "../../rpc/actions/eth_getBalance.js";
10
12
  import { getRpcClient } from "../../rpc/rpc.js";
11
13
  import { toTokens } from "../../utils/units.js";
@@ -20,13 +22,7 @@ export type GetWalletBalanceOptions = {
20
22
  tokenAddress?: string;
21
23
  };
22
24
 
23
- export type GetWalletBalanceResult = {
24
- value: bigint;
25
- decimals: number;
26
- displayValue: string;
27
- symbol: string;
28
- name: string;
29
- };
25
+ export type GetWalletBalanceResult = GetBalanceResult;
30
26
 
31
27
  /**
32
28
  * Retrieves the balance of a token or native currency for a given wallet.
@@ -75,5 +71,7 @@ export async function getWalletBalance(
75
71
  displayValue: toTokens(nativeBalance, nativeDecimals),
76
72
  symbol: nativeSymbol,
77
73
  name: nativeName,
74
+ tokenAddress: tokenAddress ?? NATIVE_TOKEN_ADDRESS,
75
+ chainId: chain.id,
78
76
  };
79
77
  }