thirdweb 5.86.7-nightly-f5f8a40320d5d768d5866813f53ee4880bdf7851-20250129000319 → 5.87.1
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.
- package/dist/cjs/exports/react.js +4 -3
- package/dist/cjs/exports/react.js.map +1 -1
- package/dist/cjs/exports/react.native.js +27 -1
- package/dist/cjs/exports/react.native.js.map +1 -1
- package/dist/cjs/react/{web/ui/prebuilt/Account → core/account}/provider.js +1 -1
- package/dist/cjs/react/core/account/provider.js.map +1 -0
- package/dist/cjs/react/core/utils/account.js +105 -0
- package/dist/cjs/react/core/utils/account.js.map +1 -0
- package/dist/cjs/react/core/utils/walletIcon.js +23 -0
- package/dist/cjs/react/core/utils/walletIcon.js.map +1 -1
- package/dist/cjs/react/core/utils/walletname.js +45 -0
- package/dist/cjs/react/core/utils/walletname.js.map +1 -0
- package/dist/cjs/react/core/wallet/provider.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/address.js +50 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/address.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/avatar.js +151 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/avatar.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/balance.js +130 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/balance.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/blobbie.js +58 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/blobbie.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/name.js +113 -0
- package/dist/cjs/react/native/ui/prebuilt/Account/name.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Wallet/icon.js +85 -0
- package/dist/cjs/react/native/ui/prebuilt/Wallet/icon.js.map +1 -0
- package/dist/cjs/react/native/ui/prebuilt/Wallet/name.js +66 -0
- package/dist/cjs/react/native/ui/prebuilt/Wallet/name.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/Blobbie.js +2 -18
- package/dist/cjs/react/web/ui/ConnectWallet/Blobbie.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js +5 -4
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/address.js +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/address.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/avatar.js +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/avatar.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/balance.js +8 -90
- package/dist/cjs/react/web/ui/prebuilt/Account/balance.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/blobbie.js +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/blobbie.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/name.js +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/name.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Wallet/icon.js +1 -23
- package/dist/cjs/react/web/ui/prebuilt/Wallet/icon.js.map +1 -1
- package/dist/cjs/react/web/ui/prebuilt/Wallet/name.js +2 -42
- package/dist/cjs/react/web/ui/prebuilt/Wallet/name.js.map +1 -1
- package/dist/cjs/utils/shortenLargeNumber.js +3 -0
- package/dist/cjs/utils/shortenLargeNumber.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/manager/index.js +3 -1
- package/dist/cjs/wallets/manager/index.js.map +1 -1
- package/dist/esm/exports/react.js +3 -3
- package/dist/esm/exports/react.js.map +1 -1
- package/dist/esm/exports/react.native.js +15 -0
- package/dist/esm/exports/react.native.js.map +1 -1
- package/dist/esm/react/{web/ui/prebuilt/Account → core/account}/provider.js +1 -1
- package/dist/esm/react/core/account/provider.js.map +1 -0
- package/dist/esm/react/core/utils/account.js +99 -0
- package/dist/esm/react/core/utils/account.js.map +1 -0
- package/dist/esm/react/core/utils/walletIcon.js +21 -0
- package/dist/esm/react/core/utils/walletIcon.js.map +1 -1
- package/dist/esm/react/core/utils/walletname.js +40 -0
- package/dist/esm/react/core/utils/walletname.js.map +1 -0
- package/dist/esm/react/core/wallet/provider.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Account/address.js +47 -0
- package/dist/esm/react/native/ui/prebuilt/Account/address.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Account/avatar.js +148 -0
- package/dist/esm/react/native/ui/prebuilt/Account/avatar.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Account/balance.js +127 -0
- package/dist/esm/react/native/ui/prebuilt/Account/balance.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Account/blobbie.js +54 -0
- package/dist/esm/react/native/ui/prebuilt/Account/blobbie.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Account/name.js +110 -0
- package/dist/esm/react/native/ui/prebuilt/Account/name.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Wallet/icon.js +81 -0
- package/dist/esm/react/native/ui/prebuilt/Wallet/icon.js.map +1 -0
- package/dist/esm/react/native/ui/prebuilt/Wallet/name.js +63 -0
- package/dist/esm/react/native/ui/prebuilt/Wallet/name.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/Blobbie.js +1 -17
- package/dist/esm/react/web/ui/ConnectWallet/Blobbie.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/ConnectButton.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Details.js +3 -2
- package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/address.js +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/address.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/avatar.js +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/avatar.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/balance.js +6 -85
- package/dist/esm/react/web/ui/prebuilt/Account/balance.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/blobbie.js +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/blobbie.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/name.js +1 -1
- package/dist/esm/react/web/ui/prebuilt/Account/name.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Wallet/icon.js +1 -22
- package/dist/esm/react/web/ui/prebuilt/Wallet/icon.js.map +1 -1
- package/dist/esm/react/web/ui/prebuilt/Wallet/name.js +1 -39
- package/dist/esm/react/web/ui/prebuilt/Wallet/name.js.map +1 -1
- package/dist/esm/utils/shortenLargeNumber.js +3 -0
- package/dist/esm/utils/shortenLargeNumber.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/manager/index.js +3 -1
- package/dist/esm/wallets/manager/index.js.map +1 -1
- package/dist/types/exports/react.d.ts +5 -4
- package/dist/types/exports/react.d.ts.map +1 -1
- package/dist/types/exports/react.native.d.ts +15 -0
- package/dist/types/exports/react.native.d.ts.map +1 -1
- package/dist/types/react/{web/ui/prebuilt/Account → core/account}/provider.d.ts +3 -4
- package/dist/types/react/core/account/provider.d.ts.map +1 -0
- package/dist/types/react/core/utils/account.d.ts +46 -0
- package/dist/types/react/core/utils/account.d.ts.map +1 -0
- package/dist/types/react/core/utils/walletIcon.d.ts +14 -0
- package/dist/types/react/core/utils/walletIcon.d.ts.map +1 -1
- package/dist/types/react/core/utils/walletname.d.ts +26 -0
- package/dist/types/react/core/utils/walletname.d.ts.map +1 -0
- package/dist/types/react/{web/ui/prebuilt/Wallet → core/wallet}/provider.d.ts +1 -1
- package/dist/types/react/core/wallet/provider.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Account/address.d.ts +54 -0
- package/dist/types/react/native/ui/prebuilt/Account/address.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Account/avatar.d.ts +141 -0
- package/dist/types/react/native/ui/prebuilt/Account/avatar.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Account/balance.d.ts +144 -0
- package/dist/types/react/native/ui/prebuilt/Account/balance.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Account/blobbie.d.ts +34 -0
- package/dist/types/react/native/ui/prebuilt/Account/blobbie.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Account/name.d.ts +118 -0
- package/dist/types/react/native/ui/prebuilt/Account/name.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Wallet/icon.d.ts +100 -0
- package/dist/types/react/native/ui/prebuilt/Wallet/icon.d.ts.map +1 -0
- package/dist/types/react/native/ui/prebuilt/Wallet/name.d.ts +94 -0
- package/dist/types/react/native/ui/prebuilt/Wallet/name.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/Blobbie.d.ts +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Blobbie.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/ConnectButton.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Details.d.ts +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/Account/avatar.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/Account/balance.d.ts +1 -42
- package/dist/types/react/web/ui/prebuilt/Account/balance.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/Account/blobbie.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/Wallet/icon.d.ts +2 -10
- package/dist/types/react/web/ui/prebuilt/Wallet/icon.d.ts.map +1 -1
- package/dist/types/react/web/ui/prebuilt/Wallet/name.d.ts +1 -18
- package/dist/types/react/web/ui/prebuilt/Wallet/name.d.ts.map +1 -1
- package/dist/types/utils/shortenLargeNumber.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/dist/types/wallets/manager/index.d.ts +1 -0
- package/dist/types/wallets/manager/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/exports/react.native.ts +47 -0
- package/src/exports/react.ts +5 -3
- package/src/react/{web/ui/prebuilt/Account → core/account}/provider.test.tsx +1 -1
- package/src/react/{web/ui/prebuilt/Account → core/account}/provider.tsx +3 -5
- package/src/react/core/utils/account.ts +146 -0
- package/src/react/core/utils/walletIcon.ts +28 -0
- package/src/react/core/utils/walletname.ts +53 -0
- package/src/react/{web/ui/prebuilt/Wallet → core/wallet}/provider.tsx +1 -1
- package/src/react/native/ui/prebuilt/Account/address.tsx +65 -0
- package/src/react/native/ui/prebuilt/Account/avatar.tsx +225 -0
- package/src/react/native/ui/prebuilt/Account/balance.tsx +221 -0
- package/src/react/native/ui/prebuilt/Account/blobbie.tsx +94 -0
- package/src/react/native/ui/prebuilt/Account/name.tsx +180 -0
- package/src/react/native/ui/prebuilt/Wallet/icon.tsx +124 -0
- package/src/react/native/ui/prebuilt/Wallet/name.tsx +112 -0
- package/src/react/web/ui/ConnectWallet/Blobbie.tsx +1 -18
- package/src/react/web/ui/ConnectWallet/ConnectButton.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/Details.test.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/Details.tsx +7 -7
- package/src/react/web/ui/prebuilt/Account/address.test.tsx +1 -1
- package/src/react/web/ui/prebuilt/Account/address.tsx +1 -1
- package/src/react/web/ui/prebuilt/Account/avatar.test.tsx +1 -1
- package/src/react/web/ui/prebuilt/Account/avatar.tsx +1 -2
- package/src/react/web/ui/prebuilt/Account/balance.test.tsx +7 -5
- package/src/react/web/ui/prebuilt/Account/balance.tsx +10 -130
- package/src/react/web/ui/prebuilt/Account/blobbie.tsx +1 -1
- package/src/react/web/ui/prebuilt/Account/name.test.tsx +1 -1
- package/src/react/web/ui/prebuilt/Account/name.tsx +1 -1
- package/src/react/web/ui/prebuilt/Wallet/icon.test.tsx +3 -2
- package/src/react/web/ui/prebuilt/Wallet/icon.tsx +6 -30
- package/src/react/web/ui/prebuilt/Wallet/name.test.tsx +6 -2
- package/src/react/web/ui/prebuilt/Wallet/name.tsx +2 -52
- package/src/utils/shortenLargeNumber.ts +3 -0
- package/src/version.ts +1 -1
- package/src/wallets/manager/index.ts +4 -1
- package/dist/cjs/react/web/ui/prebuilt/Account/provider.js.map +0 -1
- package/dist/cjs/react/web/ui/prebuilt/Wallet/provider.js.map +0 -1
- package/dist/esm/react/web/ui/prebuilt/Account/provider.js.map +0 -1
- package/dist/esm/react/web/ui/prebuilt/Wallet/provider.js.map +0 -1
- package/dist/types/react/web/ui/prebuilt/Account/provider.d.ts.map +0 -1
- package/dist/types/react/web/ui/prebuilt/Wallet/provider.d.ts.map +0 -1
- /package/dist/cjs/react/{web/ui/prebuilt/Wallet → core/wallet}/provider.js +0 -0
- /package/dist/esm/react/{web/ui/prebuilt/Wallet → core/wallet}/provider.js +0 -0
- /package/src/react/{web/ui/prebuilt/Wallet → core/wallet}/provider.test.tsx +0 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
import type { Chain } from "../../../chains/types.js";
|
2
|
+
import type { ThirdwebClient } from "../../../client/client.js";
|
3
|
+
import { NATIVE_TOKEN_ADDRESS } from "../../../constants/addresses.js";
|
4
|
+
import { convertCryptoToFiat } from "../../../pay/convert/cryptoToFiat.js";
|
5
|
+
import type { SupportedFiatCurrency } from "../../../pay/convert/type.js";
|
6
|
+
import { type Address, isAddress } from "../../../utils/address.js";
|
7
|
+
import { formatNumber } from "../../../utils/formatNumber.js";
|
8
|
+
import { shortenLargeNumber } from "../../../utils/shortenLargeNumber.js";
|
9
|
+
import { getWalletBalance } from "../../../wallets/utils/getWalletBalance.js";
|
10
|
+
|
11
|
+
export const COLOR_OPTIONS = [
|
12
|
+
["#fca5a5", "#b91c1c"],
|
13
|
+
["#fdba74", "#c2410c"],
|
14
|
+
["#fcd34d", "#b45309"],
|
15
|
+
["#fde047", "#a16207"],
|
16
|
+
["#a3e635", "#4d7c0f"],
|
17
|
+
["#86efac", "#15803d"],
|
18
|
+
["#67e8f9", "#0e7490"],
|
19
|
+
["#7dd3fc", "#0369a1"],
|
20
|
+
["#93c5fd", "#1d4ed8"],
|
21
|
+
["#a5b4fc", "#4338ca"],
|
22
|
+
["#c4b5fd", "#6d28d9"],
|
23
|
+
["#d8b4fe", "#7e22ce"],
|
24
|
+
["#f0abfc", "#a21caf"],
|
25
|
+
["#f9a8d4", "#be185d"],
|
26
|
+
["#fda4af", "#be123c"],
|
27
|
+
];
|
28
|
+
|
29
|
+
/**
|
30
|
+
* @component
|
31
|
+
* @wallet
|
32
|
+
*/
|
33
|
+
export type AccountBalanceInfo = {
|
34
|
+
/**
|
35
|
+
* Represents either token balance or fiat balance.
|
36
|
+
*/
|
37
|
+
balance: number;
|
38
|
+
/**
|
39
|
+
* Represents either token symbol or fiat symbol
|
40
|
+
*/
|
41
|
+
symbol: string;
|
42
|
+
};
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @internal Exported for tests
|
46
|
+
*/
|
47
|
+
export async function loadAccountBalance(props: {
|
48
|
+
chain?: Chain;
|
49
|
+
client: ThirdwebClient;
|
50
|
+
address: Address;
|
51
|
+
tokenAddress?: Address;
|
52
|
+
showBalanceInFiat?: SupportedFiatCurrency;
|
53
|
+
}): Promise<AccountBalanceInfo> {
|
54
|
+
const { chain, client, address, tokenAddress, showBalanceInFiat } = props;
|
55
|
+
if (!chain) {
|
56
|
+
throw new Error("chain is required");
|
57
|
+
}
|
58
|
+
|
59
|
+
if (
|
60
|
+
tokenAddress &&
|
61
|
+
tokenAddress?.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase()
|
62
|
+
) {
|
63
|
+
throw new Error(`Invalid tokenAddress - cannot be ${NATIVE_TOKEN_ADDRESS}`);
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!isAddress(address)) {
|
67
|
+
throw new Error("Invalid wallet address. Expected an EVM address");
|
68
|
+
}
|
69
|
+
|
70
|
+
if (tokenAddress && !isAddress(tokenAddress)) {
|
71
|
+
throw new Error("Invalid tokenAddress. Expected an EVM contract address");
|
72
|
+
}
|
73
|
+
|
74
|
+
const tokenBalanceData = await getWalletBalance({
|
75
|
+
chain,
|
76
|
+
client,
|
77
|
+
address,
|
78
|
+
tokenAddress,
|
79
|
+
}).catch(() => undefined);
|
80
|
+
|
81
|
+
if (!tokenBalanceData) {
|
82
|
+
throw new Error(
|
83
|
+
`Failed to retrieve ${tokenAddress ? `token: ${tokenAddress}` : "native token"} balance for address: ${address} on chainId:${chain.id}`,
|
84
|
+
);
|
85
|
+
}
|
86
|
+
|
87
|
+
if (showBalanceInFiat) {
|
88
|
+
const fiatData = await convertCryptoToFiat({
|
89
|
+
fromAmount: Number(tokenBalanceData.displayValue),
|
90
|
+
fromTokenAddress: tokenAddress || NATIVE_TOKEN_ADDRESS,
|
91
|
+
to: showBalanceInFiat,
|
92
|
+
chain,
|
93
|
+
client,
|
94
|
+
}).catch(() => undefined);
|
95
|
+
|
96
|
+
if (fiatData === undefined) {
|
97
|
+
throw new Error(
|
98
|
+
`Failed to resolve fiat value for ${tokenAddress ? `token: ${tokenAddress}` : "native token"} on chainId: ${chain.id}`,
|
99
|
+
);
|
100
|
+
}
|
101
|
+
const result = {
|
102
|
+
balance: fiatData?.result,
|
103
|
+
symbol: getFiatSymbol(showBalanceInFiat),
|
104
|
+
};
|
105
|
+
|
106
|
+
return result;
|
107
|
+
}
|
108
|
+
|
109
|
+
return {
|
110
|
+
balance: Number(tokenBalanceData.displayValue),
|
111
|
+
symbol: tokenBalanceData.symbol,
|
112
|
+
};
|
113
|
+
}
|
114
|
+
|
115
|
+
function getFiatSymbol(showBalanceInFiat: SupportedFiatCurrency) {
|
116
|
+
switch (showBalanceInFiat) {
|
117
|
+
case "USD":
|
118
|
+
return "$";
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Format the display balance for both crypto and fiat, in the Details button and Modal
|
124
|
+
* If both crypto balance and fiat balance exist, we have to keep the string very short to avoid UI issues.
|
125
|
+
* @internal
|
126
|
+
* Used internally for the Details button and the Details Modal
|
127
|
+
*/
|
128
|
+
export function formatAccountTokenBalance(
|
129
|
+
props: AccountBalanceInfo & { decimals: number },
|
130
|
+
): string {
|
131
|
+
const formattedTokenBalance = formatNumber(props.balance, props.decimals);
|
132
|
+
return `${formattedTokenBalance} ${props.symbol}`;
|
133
|
+
}
|
134
|
+
|
135
|
+
/**
|
136
|
+
* Used internally for the Details button and Details Modal
|
137
|
+
* @internal
|
138
|
+
*/
|
139
|
+
export function formatAccountFiatBalance(
|
140
|
+
props: AccountBalanceInfo & { decimals: number },
|
141
|
+
) {
|
142
|
+
const num = formatNumber(props.balance, props.decimals);
|
143
|
+
// Need to keep them short to avoid UI overflow issues
|
144
|
+
const formattedFiatBalance = shortenLargeNumber(num);
|
145
|
+
return `${props.symbol}${formattedFiatBalance}`;
|
146
|
+
}
|
@@ -1,4 +1,8 @@
|
|
1
|
+
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
|
2
|
+
import { getWalletInfo } from "../../../wallets/__generated__/getWalletInfo.js";
|
1
3
|
import type { AuthOption } from "../../../wallets/types.js";
|
4
|
+
import type { WalletId } from "../../../wallets/wallet-types.js";
|
5
|
+
import { useWalletContext } from "../wallet/provider.js";
|
2
6
|
|
3
7
|
// TODO make the social icons usable in RN too
|
4
8
|
const googleIconUri =
|
@@ -106,3 +110,27 @@ export function getSocialIcon(provider: AuthOption | ({} & string)): string {
|
|
106
110
|
return genericWalletIcon;
|
107
111
|
}
|
108
112
|
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* @internal
|
116
|
+
*/
|
117
|
+
export function useWalletIcon(props: {
|
118
|
+
queryOptions?: Omit<UseQueryOptions<string>, "queryFn" | "queryKey">;
|
119
|
+
}) {
|
120
|
+
const { id } = useWalletContext();
|
121
|
+
const imageQuery = useQuery({
|
122
|
+
queryKey: ["walletIcon", id],
|
123
|
+
queryFn: async () => fetchWalletImage({ id }),
|
124
|
+
...props.queryOptions,
|
125
|
+
});
|
126
|
+
return imageQuery;
|
127
|
+
}
|
128
|
+
|
129
|
+
/**
|
130
|
+
* @internal Exported for tests only
|
131
|
+
*/
|
132
|
+
export async function fetchWalletImage(props: {
|
133
|
+
id: WalletId;
|
134
|
+
}) {
|
135
|
+
return getWalletInfo(props.id, true);
|
136
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
2
|
+
import type { UseQueryOptions } from "@tanstack/react-query";
|
3
|
+
import { getFunctionId } from "../../../utils/function-id.js";
|
4
|
+
import { getWalletInfo } from "../../../wallets/__generated__/getWalletInfo.js";
|
5
|
+
import type { WalletId } from "../../../wallets/wallet-types.js";
|
6
|
+
import { useWalletContext } from "../wallet/provider.js";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @internal
|
10
|
+
*/
|
11
|
+
export function useWalletName(props: {
|
12
|
+
formatFn?: (str: string) => string;
|
13
|
+
queryOptions?: Omit<UseQueryOptions<string>, "queryFn" | "queryKey">;
|
14
|
+
}) {
|
15
|
+
const { id } = useWalletContext();
|
16
|
+
const nameQuery = useQuery({
|
17
|
+
queryKey: getQueryKeys({ id, formatFn: props.formatFn }),
|
18
|
+
queryFn: async () => fetchWalletName({ id, formatFn: props.formatFn }),
|
19
|
+
...props.queryOptions,
|
20
|
+
});
|
21
|
+
return nameQuery;
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @internal Exported for tests only
|
26
|
+
*/
|
27
|
+
export function getQueryKeys(props: {
|
28
|
+
id: WalletId;
|
29
|
+
formatFn?: (str: string) => string;
|
30
|
+
}) {
|
31
|
+
if (typeof props.formatFn === "function") {
|
32
|
+
return [
|
33
|
+
"walletName",
|
34
|
+
props.id,
|
35
|
+
{ resolver: getFunctionId(props.formatFn) },
|
36
|
+
] as const;
|
37
|
+
}
|
38
|
+
return ["walletName", props.id] as const;
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* @internal Exported for tests only
|
43
|
+
*/
|
44
|
+
export async function fetchWalletName(props: {
|
45
|
+
id: WalletId;
|
46
|
+
formatFn?: (str: string) => string;
|
47
|
+
}) {
|
48
|
+
const info = await getWalletInfo(props.id);
|
49
|
+
if (typeof props.formatFn === "function") {
|
50
|
+
return props.formatFn(info.name);
|
51
|
+
}
|
52
|
+
return info.name;
|
53
|
+
}
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
import type React from "react";
|
4
4
|
import { createContext, useContext } from "react";
|
5
|
-
import type { WalletId } from "
|
5
|
+
import type { WalletId } from "../../../wallets/wallet-types.js";
|
6
6
|
|
7
7
|
/**
|
8
8
|
* Props for the WalletProvider component
|
@@ -0,0 +1,65 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import { Text, type TextProps } from "react-native";
|
4
|
+
import { useAccountContext } from "../../../../core/account/provider.js";
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @component
|
8
|
+
* @wallet
|
9
|
+
*/
|
10
|
+
export interface AccountAddressProps extends Omit<TextProps, "children"> {
|
11
|
+
/**
|
12
|
+
* The function used to transform (format) the wallet address
|
13
|
+
* Specifically useful for shortening the wallet.
|
14
|
+
*
|
15
|
+
* This function should take in a string and output a string
|
16
|
+
*/
|
17
|
+
formatFn?: (str: string) => string;
|
18
|
+
className?: string;
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
*
|
23
|
+
* @returns a <span> containing the full wallet address of the account
|
24
|
+
*
|
25
|
+
* @example
|
26
|
+
* ### Basic usage
|
27
|
+
* ```tsx
|
28
|
+
* import { AccountProvider, AccountAddress } from "thirdweb/react";
|
29
|
+
*
|
30
|
+
* <AccountProvider address="0x12345674b599ce99958242b3D3741e7b01841DF3" client={TW_CLIENT}>
|
31
|
+
* <AccountAddress />
|
32
|
+
* </AccountProvider>
|
33
|
+
* ```
|
34
|
+
* Result:
|
35
|
+
* ```html
|
36
|
+
* <span>0x12345674b599ce99958242b3D3741e7b01841DF3</span>
|
37
|
+
* ```
|
38
|
+
*
|
39
|
+
*
|
40
|
+
* ### Shorten the address
|
41
|
+
* ```tsx
|
42
|
+
* import { AccountProvider, AccountAddress } from "thirdweb/react";
|
43
|
+
* import { shortenAddress } from "thirdweb/utils";
|
44
|
+
*
|
45
|
+
* <AccountProvider address="0x12345674b599ce99958242b3D3741e7b01841DF3" client={TW_CLIENT}>
|
46
|
+
* <AccountAddress formatFn={shortenAddress} />
|
47
|
+
* </AccountProvider>
|
48
|
+
* ```
|
49
|
+
* Result:
|
50
|
+
* ```html
|
51
|
+
* <span>0x1234...1DF3</span>
|
52
|
+
* ```
|
53
|
+
*
|
54
|
+
* @component
|
55
|
+
* @wallet
|
56
|
+
* @beta
|
57
|
+
*/
|
58
|
+
export function AccountAddress({
|
59
|
+
formatFn,
|
60
|
+
...restProps
|
61
|
+
}: AccountAddressProps) {
|
62
|
+
const { address } = useAccountContext();
|
63
|
+
const value = formatFn ? formatFn(address) : address;
|
64
|
+
return <Text {...restProps}>{value}</Text>;
|
65
|
+
}
|
@@ -0,0 +1,225 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import { type UseQueryOptions, useQuery } from "@tanstack/react-query";
|
4
|
+
import { Image, type ImageProps } from "react-native";
|
5
|
+
import { resolveAvatar } from "../../../../../extensions/ens/resolve-avatar.js";
|
6
|
+
import {
|
7
|
+
type ResolveNameOptions,
|
8
|
+
resolveName,
|
9
|
+
} from "../../../../../extensions/ens/resolve-name.js";
|
10
|
+
import { getSocialProfiles } from "../../../../../social/profiles.js";
|
11
|
+
import type { SocialProfile } from "../../../../../social/types.js";
|
12
|
+
import { parseAvatarRecord } from "../../../../../utils/ens/avatar.js";
|
13
|
+
import { useAccountContext } from "../../../../core/account/provider.js";
|
14
|
+
/**
|
15
|
+
* Props for the AccountAvatar component
|
16
|
+
* @component
|
17
|
+
* @wallet
|
18
|
+
*/
|
19
|
+
export interface AccountAvatarProps
|
20
|
+
extends Omit<ImageProps, "source">,
|
21
|
+
Omit<ResolveNameOptions, "client" | "address"> {
|
22
|
+
/**
|
23
|
+
* Use this prop to prioritize the social profile that you want to display
|
24
|
+
* This is useful for a wallet containing multiple social profiles.
|
25
|
+
* This component inherits all attributes of a HTML's <img />, so you can interact with it just like a normal <img />
|
26
|
+
*
|
27
|
+
* @example
|
28
|
+
* If you have ENS, Lens and Farcaster profiles linked to your wallet
|
29
|
+
* you can prioritize showing the image for Lens by:
|
30
|
+
* ```tsx
|
31
|
+
* <AccountAvatar
|
32
|
+
* socialType="lens" // Choose between: "farcaster" | "lens" | "ens"
|
33
|
+
* />
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
socialType?: SocialProfile["type"];
|
37
|
+
|
38
|
+
/**
|
39
|
+
* This component will be shown while the avatar of the account is being fetched
|
40
|
+
* If not passed, the component will return `null`.
|
41
|
+
*
|
42
|
+
* You can pass a loading sign or spinner to this prop.
|
43
|
+
* @example
|
44
|
+
* ```tsx
|
45
|
+
* <AccountAvatar loadingComponent={<Spinner />} />
|
46
|
+
* ```
|
47
|
+
*/
|
48
|
+
loadingComponent?: React.ComponentType;
|
49
|
+
/**
|
50
|
+
* This component will be shown if the request for fetching the avatar is done
|
51
|
+
* but could not retreive any result.
|
52
|
+
* You can pass a dummy avatar/image to this prop.
|
53
|
+
*
|
54
|
+
* If not passed, the component will return `null`
|
55
|
+
*
|
56
|
+
* @example
|
57
|
+
* ```tsx
|
58
|
+
* <AccountAvatar fallbackComponent={<DummyImage />} />
|
59
|
+
* ```
|
60
|
+
*/
|
61
|
+
fallbackComponent?: React.ComponentType;
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Optional query options for `useQuery`
|
65
|
+
*/
|
66
|
+
queryOptions?: Omit<UseQueryOptions<string>, "queryFn" | "queryKey">;
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* The component for showing the avatar of the account.
|
71
|
+
* If fetches all the social profiles linked to your wallet, including: Farcaster, ENS, Lens (more to be added)
|
72
|
+
* You can choose which social profile you want to display. Defaults to the first item in the list.
|
73
|
+
*
|
74
|
+
* @example
|
75
|
+
* ### Basic usage
|
76
|
+
* ```tsx
|
77
|
+
* import { AccountProvider, AccountAvatar } from "thirdweb/react";
|
78
|
+
*
|
79
|
+
* <AccountProvider address="0x...">
|
80
|
+
* <AccountAvatar />
|
81
|
+
* </AccountProvider>
|
82
|
+
* ```
|
83
|
+
* Result: An <img /> component, if the avatar is resolved successfully
|
84
|
+
* ```html
|
85
|
+
* <img alt="" src="resolved-url-for-the-avatar" />
|
86
|
+
* ```
|
87
|
+
*
|
88
|
+
* ### Show a loading sign when the avatar is being resolved
|
89
|
+
* ```tsx
|
90
|
+
* import { AccountProvider, AccountAvatar } from "thirdweb/react";
|
91
|
+
*
|
92
|
+
* <AccountProvider address="0x...">
|
93
|
+
* <AccountAvatar
|
94
|
+
* loadingComponent={<YourLoadingComponent />}
|
95
|
+
* />
|
96
|
+
* </AccountProvider>
|
97
|
+
* ```
|
98
|
+
*
|
99
|
+
* ### Fallback to something when the avatar fails to resolve
|
100
|
+
* ```tsx
|
101
|
+
* import { AccountProvider, AccountAvatar } from "thirdweb/react";
|
102
|
+
*
|
103
|
+
* <AccountProvider address="0x...">
|
104
|
+
* <AccountAvatar
|
105
|
+
* fallbackComponent={<DummyImage />}
|
106
|
+
* />
|
107
|
+
* </AccountProvider>
|
108
|
+
* ```
|
109
|
+
*
|
110
|
+
* ### Select a social profile to display
|
111
|
+
* If you wallet associates with more than one social profiles (Lens, Farcaster, ENS, etc.)
|
112
|
+
* You can specify which service you want to prioritize using the `socialType` props
|
113
|
+
* ```tsx
|
114
|
+
* import { AccountProvider, AccountAvatar } from "thirdweb/react";
|
115
|
+
*
|
116
|
+
* <AccountProvider address="0x...">
|
117
|
+
* <AccountAvatar
|
118
|
+
* // Choose between: "farcaster" | "lens" | "ens"
|
119
|
+
* socialType={"ens"}
|
120
|
+
* />
|
121
|
+
* </AccountProvider>
|
122
|
+
* ```
|
123
|
+
*
|
124
|
+
* ### Custom ENS resolver chain
|
125
|
+
* This component shares the same props with the ENS extension `resolveAvatar`
|
126
|
+
* ```tsx
|
127
|
+
* import { AccountProvider, AccountAvatar } from "thirdweb/react";
|
128
|
+
* import { base } from "thirdweb/chains";
|
129
|
+
*
|
130
|
+
* <AccountProvider address="0x...">
|
131
|
+
* <AccountAvatar
|
132
|
+
* resolverAddress={"0x..."}
|
133
|
+
* resolverChain={base}
|
134
|
+
* />
|
135
|
+
* </AccountProvider>
|
136
|
+
* ```
|
137
|
+
*
|
138
|
+
* ### Custom query options for useQuery
|
139
|
+
* This component uses `@tanstack-query`'s useQuery internally.
|
140
|
+
* You can use the `queryOptions` prop for more fine-grained control
|
141
|
+
* ```tsx
|
142
|
+
* <AccountAvatar
|
143
|
+
* queryOptions={{
|
144
|
+
* enabled: isEnabled,
|
145
|
+
* retry: 3,
|
146
|
+
* }}
|
147
|
+
* />
|
148
|
+
* ```
|
149
|
+
* @returns An <img /> if the avatar is resolved successfully
|
150
|
+
* @component
|
151
|
+
* @wallet
|
152
|
+
* @beta
|
153
|
+
*/
|
154
|
+
export function AccountAvatar({
|
155
|
+
socialType,
|
156
|
+
resolverAddress,
|
157
|
+
resolverChain,
|
158
|
+
loadingComponent,
|
159
|
+
fallbackComponent,
|
160
|
+
queryOptions,
|
161
|
+
...restProps
|
162
|
+
}: AccountAvatarProps) {
|
163
|
+
const { address, client } = useAccountContext();
|
164
|
+
const avatarQuery = useQuery({
|
165
|
+
queryKey: [
|
166
|
+
"account-avatar",
|
167
|
+
address,
|
168
|
+
{ socialType },
|
169
|
+
{ resolverAddress, resolverChain },
|
170
|
+
],
|
171
|
+
queryFn: async (): Promise<string> => {
|
172
|
+
const [socialData, ensName] = await Promise.all([
|
173
|
+
getSocialProfiles({ address, client }),
|
174
|
+
resolveName({
|
175
|
+
client,
|
176
|
+
address: address || "",
|
177
|
+
resolverAddress,
|
178
|
+
resolverChain,
|
179
|
+
}),
|
180
|
+
]);
|
181
|
+
|
182
|
+
const uri = socialData?.filter(
|
183
|
+
(p) => p.avatar && (socialType ? p.type === socialType : true),
|
184
|
+
)[0]?.avatar;
|
185
|
+
|
186
|
+
const [resolvedSocialAvatar, resolvedENSAvatar] = await Promise.all([
|
187
|
+
uri ? parseAvatarRecord({ client, uri }) : undefined,
|
188
|
+
ensName
|
189
|
+
? resolveAvatar({
|
190
|
+
client,
|
191
|
+
name: ensName,
|
192
|
+
})
|
193
|
+
: undefined,
|
194
|
+
]);
|
195
|
+
|
196
|
+
// If no social image + ens name found -> exit and show <Blobbie />
|
197
|
+
if (!resolvedSocialAvatar && !resolvedENSAvatar) {
|
198
|
+
throw new Error("Failed to resolve social + ens avatar");
|
199
|
+
}
|
200
|
+
|
201
|
+
// else, prioritize the social image first
|
202
|
+
if (resolvedSocialAvatar) {
|
203
|
+
return resolvedSocialAvatar;
|
204
|
+
}
|
205
|
+
|
206
|
+
if (resolvedENSAvatar) {
|
207
|
+
return resolvedENSAvatar;
|
208
|
+
}
|
209
|
+
|
210
|
+
throw new Error("Failed to resolve social + ens avatar");
|
211
|
+
},
|
212
|
+
retry: false,
|
213
|
+
...queryOptions,
|
214
|
+
});
|
215
|
+
|
216
|
+
if (avatarQuery.isLoading) {
|
217
|
+
return loadingComponent || null;
|
218
|
+
}
|
219
|
+
|
220
|
+
if (!avatarQuery.data) {
|
221
|
+
return fallbackComponent || null;
|
222
|
+
}
|
223
|
+
|
224
|
+
return <Image source={{ uri: avatarQuery.data }} {...restProps} />;
|
225
|
+
}
|