Skip to content

Commit a6c781c

Browse files
committed
update
1 parent c48e0c9 commit a6c781c

27 files changed

+1558
-123
lines changed

.changeset/fair-plants-pretend.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
The Connected-details button now shows USD value next to the token balance.
5+
6+
### Breaking change to the AccountBalance
7+
The formatFn props now takes in an object of type `AccountBalanceInfo`. The old `formatFn` was inflexible because it only allowed you to format the balance value.
8+
With this new version, you have access to both the balance and symbol.
9+
```tsx
10+
import { AccountBalance, type AccountBalanceInfo } from "thirdweb/react";
11+
12+
<AccountBalance
13+
// Show the symbol in lowercase, before the balance
14+
formatFn={(props: AccountBalanceInfo) => `${props.symbol.toLowerCase()} ${props.balance}`}
15+
/>
16+
```
17+
18+
AccountBalance now supports showing the token balance in fiat value (only USD supported at the moment)
19+
```tsx
20+
<AccountBalance
21+
showBalanceInFiat="USD"
22+
/>
23+
```
24+
25+
The `formatFn` prop now takes in an object of type `AccountBalanceInfo` and outputs a string
26+
```tsx
27+
import { AccountBalance, type AccountBalanceInfo } from "thirdweb/react";
28+
29+
<AccountBalance
30+
formatFn={(props: AccountBalanceInfo) => `${props.balance}---${props.symbol.toLowerCase()}`}
31+
/>
32+
33+
// Result: 11.12---eth
34+
```
35+
36+
### ConnectButton also supports displaying balance in fiat since it uses AccountBalance internally
37+
```tsx
38+
<ConnectButton
39+
// Show USD value on the button
40+
detailsButton={{
41+
showBalanceInFiat: "USD",
42+
}}
43+
44+
// Show USD value on the modal
45+
detailsModal={{
46+
showBalanceInFiat: "USD",
47+
}}
48+
/>
49+
```
50+
51+
### Export utils functions:
52+
formatNumber: Round up a number to a certain decimal place
53+
```tsx
54+
import { formatNumber } from "thirdweb/utils";
55+
const value = formatNumber(12.1214141, 1); // 12.1
56+
```
57+
58+
shortenLargeNumber: Shorten the string for large value. Mainly used for the AccountBalance's `formatFn`
59+
```tsx
60+
import { shortenLargeNumber } from "thirdweb/utils";
61+
const numStr = shortenLargeNumber(1_000_000_000)
62+
```
63+
64+
### Fix to ConnectButton
65+
The social image of the Details button now display correctly for non-square image.

packages/thirdweb/src/exports/react.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ export {
221221
export {
222222
AccountBalance,
223223
type AccountBalanceProps,
224+
type AccountBalanceInfo,
224225
} from "../react/web/ui/prebuilt/Account/balance.js";
225226
export {
226227
AccountName,

packages/thirdweb/src/exports/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,6 @@ export type {
204204
AbiConstructor,
205205
AbiFallback,
206206
} from "abitype";
207+
208+
export { shortenLargeNumber } from "../utils/shortenLargeNumber.js";
209+
export { formatNumber } from "../utils/formatNumber.js";

packages/thirdweb/src/pay/convert/cryptoToFiat.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from "vitest";
1+
import { describe, expect, it, vi } from "vitest";
22
import { TEST_CLIENT } from "~test/test-clients.js";
33
import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
44
import { base } from "../../chains/chain-definitions/base.js";
@@ -92,4 +92,24 @@ describe.runIf(process.env.TW_SECRET_KEY)("Pay: crypto-to-fiat", () => {
9292
`Error: ${TEST_ACCOUNT_A.address} on chainId: ${base.id} is not a valid contract address.`,
9393
);
9494
});
95+
it("should throw if response is not OK", async () => {
96+
global.fetch = vi.fn();
97+
global.fetch = vi.fn().mockResolvedValue({
98+
ok: false,
99+
status: 400,
100+
statusText: "Bad Request",
101+
});
102+
await expect(() =>
103+
convertCryptoToFiat({
104+
chain: base,
105+
fromTokenAddress: NATIVE_TOKEN_ADDRESS,
106+
fromAmount: 1,
107+
to: "USD",
108+
client: TEST_CLIENT,
109+
}),
110+
).rejects.toThrowError(
111+
`Failed to fetch USD value for token (${NATIVE_TOKEN_ADDRESS}) on chainId: ${base.id}`,
112+
);
113+
vi.restoreAllMocks();
114+
});
95115
});

packages/thirdweb/src/pay/convert/cryptoToFiat.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getContract } from "../../contract/contract.js";
77
import { isAddress } from "../../utils/address.js";
88
import { getClientFetch } from "../../utils/fetch.js";
99
import { getPayConvertCryptoToFiatEndpoint } from "../utils/definitions.js";
10+
import type { SupportedFiatCurrency } from "./type.js";
1011

1112
/**
1213
* Props for the `convertCryptoToFiat` function
@@ -31,7 +32,7 @@ export type ConvertCryptoToFiatParams = {
3132
* The fiat symbol. e.g "USD"
3233
* Only USD is supported at the moment.
3334
*/
34-
to: "USD";
35+
to: SupportedFiatCurrency;
3536
};
3637

3738
/**

packages/thirdweb/src/pay/convert/fiatToCrypto.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from "vitest";
1+
import { describe, expect, it, vi } from "vitest";
22
import { TEST_CLIENT } from "~test/test-clients.js";
33
import { TEST_ACCOUNT_A } from "~test/test-wallets.js";
44
import { base } from "../../chains/chain-definitions/base.js";
@@ -93,4 +93,24 @@ describe.runIf(process.env.TW_SECRET_KEY)("Pay: fiatToCrypto", () => {
9393
`Error: ${TEST_ACCOUNT_A.address} on chainId: ${base.id} is not a valid contract address.`,
9494
);
9595
});
96+
it("should throw if response is not OK", async () => {
97+
global.fetch = vi.fn();
98+
global.fetch = vi.fn().mockResolvedValue({
99+
ok: false,
100+
status: 400,
101+
statusText: "Bad Request",
102+
});
103+
await expect(() =>
104+
convertFiatToCrypto({
105+
chain: ethereum,
106+
to: NATIVE_TOKEN_ADDRESS,
107+
fromAmount: 1,
108+
from: "USD",
109+
client: TEST_CLIENT,
110+
}),
111+
).rejects.toThrowError(
112+
`Failed to convert USD value to token (${NATIVE_TOKEN_ADDRESS}) on chainId: 1`,
113+
);
114+
vi.restoreAllMocks();
115+
});
96116
});

packages/thirdweb/src/pay/convert/fiatToCrypto.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getContract } from "../../contract/contract.js";
77
import { isAddress } from "../../utils/address.js";
88
import { getClientFetch } from "../../utils/fetch.js";
99
import { getPayConvertFiatToCryptoEndpoint } from "../utils/definitions.js";
10+
import type { SupportedFiatCurrency } from "./type.js";
1011

1112
/**
1213
* Props for the `convertFiatToCrypto` function
@@ -18,7 +19,7 @@ export type ConvertFiatToCryptoParams = {
1819
* The fiat symbol. e.g: "USD"
1920
* Currently only USD is supported.
2021
*/
21-
from: "USD";
22+
from: SupportedFiatCurrency;
2223
/**
2324
* The total amount of fiat to convert
2425
* e.g: If you want to convert 2 cents to USD, enter `0.02`
@@ -101,7 +102,7 @@ export async function convertFiatToCrypto(
101102
const response = await getClientFetch(client)(url);
102103
if (!response.ok) {
103104
throw new Error(
104-
`Failed to convert ${to} value to token (${to}) on chainId: ${chain.id}`,
105+
`Failed to convert ${from} value to token (${to}) on chainId: ${chain.id}`,
105106
);
106107
}
107108

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const SUPPORTED_FIAT_CURRENCIES = ["USD"] as const;
2+
/**
3+
* @internal
4+
*/
5+
export type SupportedFiatCurrency = (typeof SUPPORTED_FIAT_CURRENCIES)[number];

packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Chain } from "../../../../chains/types.js";
33
import type { ThirdwebClient } from "../../../../client/client.js";
44
import type { BuyWithCryptoStatus } from "../../../../pay/buyWithCrypto/getStatus.js";
55
import type { BuyWithFiatStatus } from "../../../../pay/buyWithFiat/getStatus.js";
6+
import type { SupportedFiatCurrency } from "../../../../pay/convert/type.js";
67
import type { FiatProvider } from "../../../../pay/utils/commonTypes.js";
78
import type { AssetTabs } from "../../../../react/web/ui/ConnectWallet/screens/ViewAssets.js";
89
import type { PreparedTransaction } from "../../../../transaction/prepare-transaction.js";
@@ -320,6 +321,12 @@ export type ConnectButton_detailsModalOptions = {
320321
* Note: If an empty array is passed, the [View Funds] button will be hidden
321322
*/
322323
assetTabs?: AssetTabs[];
324+
325+
/**
326+
* Show the token balance's value in fiat.
327+
* Note: Not all tokens are resolvable to a fiat value. In that case, nothing will be shown.
328+
*/
329+
showBalanceInFiat?: SupportedFiatCurrency;
323330
};
324331

325332
/**
@@ -377,6 +384,12 @@ export type ConnectButton_detailsButtonOptions = {
377384
* Use custom avatar URL for the connected wallet image in the `ConnectButton` details button, overriding ENS avatar or Blobbie icon.
378385
*/
379386
connectedAccountAvatarUrl?: string;
387+
388+
/**
389+
* Show the token balance's value in fiat.
390+
* Note: Not all tokens are resolvable to a fiat value. In that case, nothing will be shown.
391+
*/
392+
showBalanceInFiat?: SupportedFiatCurrency;
380393
};
381394

382395
/**

packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.test.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,19 @@ describe("ConnectButton", () => {
5050
);
5151
expect(screen.getByText("Sign In")).toBeInTheDocument();
5252
});
53+
54+
it("should render with fiat balance props", () => {
55+
render(
56+
<ConnectButton
57+
client={TEST_CLIENT}
58+
detailsButton={{
59+
showBalanceInFiat: "USD",
60+
}}
61+
detailsModal={{
62+
showBalanceInFiat: "USD",
63+
}}
64+
/>,
65+
);
66+
expect(screen.getByText("Connect Wallet")).toBeInTheDocument();
67+
});
5368
});

0 commit comments

Comments
 (0)