thirdweb 5.102.2 → 5.102.3
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/bridge/Buy.js +7 -1
- package/dist/cjs/bridge/Buy.js.map +1 -1
- package/dist/cjs/bridge/Token.js +153 -0
- package/dist/cjs/bridge/Token.js.map +1 -0
- package/dist/cjs/bridge/index.js +3 -1
- package/dist/cjs/bridge/index.js.map +1 -1
- package/dist/cjs/extensions/erc1155/read/getNFTs.js +9 -2
- package/dist/cjs/extensions/erc1155/read/getNFTs.js.map +1 -1
- package/dist/cjs/extensions/erc721/read/getNFTs.js +9 -2
- package/dist/cjs/extensions/erc721/read/getNFTs.js.map +1 -1
- package/dist/cjs/pay/convert/cryptoToFiat.js +6 -38
- package/dist/cjs/pay/convert/cryptoToFiat.js.map +1 -1
- package/dist/cjs/pay/convert/fiatToCrypto.js +6 -38
- package/dist/cjs/pay/convert/fiatToCrypto.js.map +1 -1
- package/dist/cjs/pay/convert/get-token.js +19 -0
- package/dist/cjs/pay/convert/get-token.js.map +1 -0
- package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js +2 -2
- package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/cjs/react/core/utils/wallet.js +0 -48
- package/dist/cjs/react/core/utils/wallet.js.map +1 -1
- package/dist/cjs/react/native/ui/connect/ConnectedModal.js +5 -5
- package/dist/cjs/react/native/ui/connect/ConnectedModal.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js +7 -7
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/TransactionButton/DepositScreen.js +2 -2
- package/dist/cjs/react/web/ui/TransactionButton/DepositScreen.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/manager/index.js +1 -2
- package/dist/cjs/wallets/manager/index.js.map +1 -1
- package/dist/cjs/wallets/smart/is-smart-wallet.js +62 -5
- package/dist/cjs/wallets/smart/is-smart-wallet.js.map +1 -1
- package/dist/esm/bridge/Buy.js +7 -1
- package/dist/esm/bridge/Buy.js.map +1 -1
- package/dist/esm/bridge/Token.js +150 -0
- package/dist/esm/bridge/Token.js.map +1 -0
- package/dist/esm/bridge/index.js +1 -0
- package/dist/esm/bridge/index.js.map +1 -1
- package/dist/esm/extensions/erc1155/read/getNFTs.js +9 -2
- package/dist/esm/extensions/erc1155/read/getNFTs.js.map +1 -1
- package/dist/esm/extensions/erc721/read/getNFTs.js +9 -2
- package/dist/esm/extensions/erc721/read/getNFTs.js.map +1 -1
- package/dist/esm/pay/convert/cryptoToFiat.js +6 -38
- package/dist/esm/pay/convert/cryptoToFiat.js.map +1 -1
- package/dist/esm/pay/convert/fiatToCrypto.js +6 -38
- package/dist/esm/pay/convert/fiatToCrypto.js.map +1 -1
- package/dist/esm/pay/convert/get-token.js +16 -0
- package/dist/esm/pay/convert/get-token.js.map +1 -0
- package/dist/esm/react/core/hooks/transaction/useSendTransaction.js +1 -1
- package/dist/esm/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/esm/react/core/utils/wallet.js +0 -47
- package/dist/esm/react/core/utils/wallet.js.map +1 -1
- package/dist/esm/react/native/ui/connect/ConnectedModal.js +5 -5
- package/dist/esm/react/native/ui/connect/ConnectedModal.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Details.js +7 -7
- package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.js.map +1 -1
- package/dist/esm/react/web/ui/TransactionButton/DepositScreen.js +1 -1
- package/dist/esm/react/web/ui/TransactionButton/DepositScreen.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/manager/index.js +1 -2
- package/dist/esm/wallets/manager/index.js.map +1 -1
- package/dist/esm/wallets/smart/is-smart-wallet.js +61 -5
- package/dist/esm/wallets/smart/is-smart-wallet.js.map +1 -1
- package/dist/types/bridge/Buy.d.ts +7 -1
- package/dist/types/bridge/Buy.d.ts.map +1 -1
- package/dist/types/bridge/Token.d.ts +140 -0
- package/dist/types/bridge/Token.d.ts.map +1 -0
- package/dist/types/bridge/index.d.ts +1 -0
- package/dist/types/bridge/index.d.ts.map +1 -1
- package/dist/types/extensions/erc1155/read/getNFTs.d.ts.map +1 -1
- package/dist/types/pay/convert/cryptoToFiat.d.ts.map +1 -1
- package/dist/types/pay/convert/fiatToCrypto.d.ts.map +1 -1
- package/dist/types/pay/convert/get-token.d.ts +3 -0
- package/dist/types/pay/convert/get-token.d.ts.map +1 -0
- package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts.map +1 -1
- package/dist/types/react/core/utils/wallet.d.ts +1 -5
- package/dist/types/react/core/utils/wallet.d.ts.map +1 -1
- package/dist/types/react/native/ui/connect/ConnectedModal.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/manager/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/is-smart-wallet.d.ts +5 -1
- package/dist/types/wallets/smart/is-smart-wallet.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bridge/Buy.ts +7 -1
- package/src/bridge/Token.test.ts +90 -0
- package/src/bridge/Token.ts +184 -0
- package/src/bridge/index.ts +1 -0
- package/src/extensions/erc1155/read/getNFTs.ts +8 -2
- package/src/extensions/erc721/read/getNFTs.ts +8 -2
- package/src/pay/convert/cryptoToFiat.test.ts +1 -18
- package/src/pay/convert/cryptoToFiat.ts +6 -52
- package/src/pay/convert/fiatToCrypto.test.ts +1 -18
- package/src/pay/convert/fiatToCrypto.ts +6 -51
- package/src/pay/convert/get-token.ts +24 -0
- package/src/react/core/hooks/transaction/useSendTransaction.ts +1 -1
- package/src/react/core/utils/wallet.ts +1 -49
- package/src/react/native/ui/connect/ConnectedModal.tsx +5 -5
- package/src/react/web/ui/ConnectWallet/Details.tsx +7 -7
- package/src/react/web/ui/ConnectWallet/screens/Buy/TransactionModeScreen.tsx +1 -1
- package/src/react/web/ui/TransactionButton/DepositScreen.tsx +1 -1
- package/src/version.ts +1 -1
- package/src/wallets/manager/index.ts +1 -2
- package/src/wallets/smart/is-smart-wallet.test.ts +163 -1
- package/src/wallets/smart/is-smart-wallet.ts +62 -5
- package/dist/cjs/react/core/utils/isSmartWallet.js +0 -12
- package/dist/cjs/react/core/utils/isSmartWallet.js.map +0 -1
- package/dist/cjs/wallets/smart/get-smart-wallet-config.js +0 -23
- package/dist/cjs/wallets/smart/get-smart-wallet-config.js.map +0 -1
- package/dist/esm/react/core/utils/isSmartWallet.js +0 -9
- package/dist/esm/react/core/utils/isSmartWallet.js.map +0 -1
- package/dist/esm/wallets/smart/get-smart-wallet-config.js +0 -20
- package/dist/esm/wallets/smart/get-smart-wallet-config.js.map +0 -1
- package/dist/types/react/core/utils/isSmartWallet.d.ts +0 -3
- package/dist/types/react/core/utils/isSmartWallet.d.ts.map +0 -1
- package/dist/types/wallets/smart/get-smart-wallet-config.d.ts +0 -13
- package/dist/types/wallets/smart/get-smart-wallet-config.d.ts.map +0 -1
- package/src/react/core/utils/isSmartWallet.test.ts +0 -19
- package/src/react/core/utils/isSmartWallet.ts +0 -12
- package/src/react/core/utils/wallet.test.ts +0 -77
- package/src/wallets/smart/get-smart-wallet-config.test.ts +0 -67
- package/src/wallets/smart/get-smart-wallet-config.ts +0 -24
@@ -0,0 +1,184 @@
|
|
1
|
+
import type { ThirdwebClient } from "../client/client.js";
|
2
|
+
import { getThirdwebBaseUrl } from "../utils/domains.js";
|
3
|
+
import { getClientFetch } from "../utils/fetch.js";
|
4
|
+
import { ApiError } from "./types/Errors.js";
|
5
|
+
import type { Token } from "./types/Token.js";
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Retrieves supported Universal Bridge tokens based on the provided filters.
|
9
|
+
*
|
10
|
+
* When multiple filters are specified, a token must satisfy all filters to be included (it acts as an AND operator).
|
11
|
+
*
|
12
|
+
* @example
|
13
|
+
* ```typescript
|
14
|
+
* import { Bridge } from "thirdweb";
|
15
|
+
*
|
16
|
+
* const tokens = await Bridge.tokens({
|
17
|
+
* client: thirdwebClient,
|
18
|
+
* });
|
19
|
+
* ```
|
20
|
+
*
|
21
|
+
* Returned tokens might look something like:
|
22
|
+
* ```typescript
|
23
|
+
* [
|
24
|
+
* {
|
25
|
+
* chainId: 1,
|
26
|
+
* address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
|
27
|
+
* decimals: 18,
|
28
|
+
* symbol: "ETH",
|
29
|
+
* name: "Ethereum",
|
30
|
+
* iconUri: "https://assets.relay.link/icons/1/light.png",
|
31
|
+
* priceUsd: 2000.50
|
32
|
+
* },
|
33
|
+
* {
|
34
|
+
* chainId: 1,
|
35
|
+
* address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
36
|
+
* decimals: 6,
|
37
|
+
* symbol: "USDC",
|
38
|
+
* name: "USD Coin",
|
39
|
+
* iconUri: "https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png",
|
40
|
+
* priceUsd: 1.00
|
41
|
+
* }
|
42
|
+
* ]
|
43
|
+
* ```
|
44
|
+
*
|
45
|
+
* You can filter for specific chains or tokens:
|
46
|
+
* ```typescript
|
47
|
+
* import { Bridge } from "thirdweb";
|
48
|
+
*
|
49
|
+
* // Get all tokens on Ethereum mainnet
|
50
|
+
* const ethTokens = await Bridge.tokens({
|
51
|
+
* chainId: 1,
|
52
|
+
* client: thirdwebClient,
|
53
|
+
* });
|
54
|
+
* ```
|
55
|
+
*
|
56
|
+
* You can search for tokens by symbol or name:
|
57
|
+
* ```typescript
|
58
|
+
* import { Bridge } from "thirdweb";
|
59
|
+
*
|
60
|
+
* // Search for USDC tokens
|
61
|
+
* const usdcTokens = await Bridge.tokens({
|
62
|
+
* symbol: "USDC",
|
63
|
+
* client: thirdwebClient,
|
64
|
+
* });
|
65
|
+
*
|
66
|
+
* // Search for tokens by name
|
67
|
+
* const ethereumTokens = await Bridge.tokens({
|
68
|
+
* name: "Ethereum",
|
69
|
+
* client: thirdwebClient,
|
70
|
+
* });
|
71
|
+
* ```
|
72
|
+
*
|
73
|
+
* You can filter by a specific token address:
|
74
|
+
* ```typescript
|
75
|
+
* import { Bridge } from "thirdweb";
|
76
|
+
*
|
77
|
+
* // Get a specific token
|
78
|
+
* const token = await Bridge.tokens({
|
79
|
+
* tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
80
|
+
* client: thirdwebClient,
|
81
|
+
* });
|
82
|
+
* ```
|
83
|
+
*
|
84
|
+
* The returned tokens will be limited based on the API. You can paginate through the results using the `limit` and `offset` parameters:
|
85
|
+
* ```typescript
|
86
|
+
* import { Bridge } from "thirdweb";
|
87
|
+
*
|
88
|
+
* // Get the first 50 tokens
|
89
|
+
* const tokens = await Bridge.tokens({
|
90
|
+
* limit: 50,
|
91
|
+
* offset: 0,
|
92
|
+
* client: thirdwebClient,
|
93
|
+
* });
|
94
|
+
*
|
95
|
+
* // Get the next 50 tokens
|
96
|
+
* const nextTokens = await Bridge.tokens({
|
97
|
+
* limit: 50,
|
98
|
+
* offset: 50,
|
99
|
+
* client: thirdwebClient,
|
100
|
+
* });
|
101
|
+
* ```
|
102
|
+
*
|
103
|
+
* @param options - The options for retrieving tokens.
|
104
|
+
* @param options.client - Your thirdweb client.
|
105
|
+
* @param options.chainId - Filter by a specific chain ID.
|
106
|
+
* @param options.tokenAddress - Filter by a specific token address.
|
107
|
+
* @param options.symbol - Filter by token symbol.
|
108
|
+
* @param options.name - Filter by token name.
|
109
|
+
* @param options.limit - Number of tokens to return (min: 1, default: 100).
|
110
|
+
* @param options.offset - Number of tokens to skip (min: 0, default: 0).
|
111
|
+
*
|
112
|
+
* @returns A promise that resolves to an array of tokens.
|
113
|
+
*
|
114
|
+
* @throws Will throw an error if there is an issue fetching the tokens.
|
115
|
+
* @bridge
|
116
|
+
* @beta
|
117
|
+
*/
|
118
|
+
export async function tokens(options: tokens.Options): Promise<tokens.Result> {
|
119
|
+
const { client, chainId, tokenAddress, symbol, name, limit, offset } =
|
120
|
+
options;
|
121
|
+
|
122
|
+
const clientFetch = getClientFetch(client);
|
123
|
+
const url = new URL(`${getThirdwebBaseUrl("bridge")}/v1/tokens`);
|
124
|
+
|
125
|
+
if (chainId !== null && chainId !== undefined) {
|
126
|
+
url.searchParams.set("chainId", chainId.toString());
|
127
|
+
}
|
128
|
+
if (tokenAddress) {
|
129
|
+
url.searchParams.set("tokenAddress", tokenAddress);
|
130
|
+
}
|
131
|
+
if (symbol) {
|
132
|
+
url.searchParams.set("symbol", symbol);
|
133
|
+
}
|
134
|
+
if (name) {
|
135
|
+
url.searchParams.set("name", name);
|
136
|
+
}
|
137
|
+
if (limit !== undefined) {
|
138
|
+
url.searchParams.set("limit", limit.toString());
|
139
|
+
}
|
140
|
+
if (offset !== null && offset !== undefined) {
|
141
|
+
url.searchParams.set("offset", offset.toString());
|
142
|
+
}
|
143
|
+
|
144
|
+
const response = await clientFetch(url.toString());
|
145
|
+
if (!response.ok) {
|
146
|
+
const errorJson = await response.json();
|
147
|
+
throw new ApiError({
|
148
|
+
code: errorJson.code || "UNKNOWN_ERROR",
|
149
|
+
message: errorJson.message || response.statusText,
|
150
|
+
correlationId: errorJson.correlationId || undefined,
|
151
|
+
statusCode: response.status,
|
152
|
+
});
|
153
|
+
}
|
154
|
+
|
155
|
+
const { data }: { data: Token[] } = await response.json();
|
156
|
+
return data;
|
157
|
+
}
|
158
|
+
|
159
|
+
export declare namespace tokens {
|
160
|
+
/**
|
161
|
+
* Input parameters for {@link Bridge.tokens}.
|
162
|
+
*/
|
163
|
+
type Options = {
|
164
|
+
/** Your {@link ThirdwebClient} instance. */
|
165
|
+
client: ThirdwebClient;
|
166
|
+
/** Filter by a specific chain ID. */
|
167
|
+
chainId?: number | null;
|
168
|
+
/** Filter by a specific token address. */
|
169
|
+
tokenAddress?: string;
|
170
|
+
/** Filter by token symbol. */
|
171
|
+
symbol?: string;
|
172
|
+
/** Filter by token name. */
|
173
|
+
name?: string;
|
174
|
+
/** Number of tokens to return (min: 1, default: 100). */
|
175
|
+
limit?: number;
|
176
|
+
/** Number of tokens to skip (min: 0, default: 0). */
|
177
|
+
offset?: number | null;
|
178
|
+
};
|
179
|
+
|
180
|
+
/**
|
181
|
+
* The result returned from {@link Bridge.tokens}.
|
182
|
+
*/
|
183
|
+
type Result = Token[];
|
184
|
+
}
|
package/src/bridge/index.ts
CHANGED
@@ -6,6 +6,7 @@ export * as Webhook from "./Webhook.js";
|
|
6
6
|
export { status } from "./Status.js";
|
7
7
|
export { routes } from "./Routes.js";
|
8
8
|
export { chains } from "./Chains.js";
|
9
|
+
export { tokens } from "./Token.js";
|
9
10
|
export { parse } from "./Webhook.js";
|
10
11
|
|
11
12
|
export type { Chain } from "./types/Chain.js";
|
@@ -84,8 +84,14 @@ async function getNFTsFromInsight(
|
|
84
84
|
Math.max(0, Number(supply) - currentOffset),
|
85
85
|
);
|
86
86
|
if (result.length < expectedResultLength) {
|
87
|
-
|
88
|
-
|
87
|
+
try {
|
88
|
+
// fresh contracts might be delayed in indexing, so we fallback to RPC
|
89
|
+
// must use await here
|
90
|
+
return await getNFTsFromRPC(options);
|
91
|
+
} catch {
|
92
|
+
// if RPC fails, we return the result from insight
|
93
|
+
return result;
|
94
|
+
}
|
89
95
|
}
|
90
96
|
return result;
|
91
97
|
}
|
@@ -132,8 +132,14 @@ async function getNFTsFromInsight(
|
|
132
132
|
),
|
133
133
|
);
|
134
134
|
if (result.length < expectedResultLength) {
|
135
|
-
|
136
|
-
|
135
|
+
try {
|
136
|
+
// fresh contracts might be delayed in indexing, so we fallback to RPC
|
137
|
+
// must use await here
|
138
|
+
return await getNFTsFromRPC(options);
|
139
|
+
} catch {
|
140
|
+
// if RPC fails, we return the result from insight
|
141
|
+
return result;
|
142
|
+
}
|
137
143
|
}
|
138
144
|
|
139
145
|
return result;
|
@@ -3,10 +3,7 @@ import { TEST_CLIENT } from "~test/test-clients.js";
|
|
3
3
|
import { base } from "../../chains/chain-definitions/base.js";
|
4
4
|
import { ethereum } from "../../chains/chain-definitions/ethereum.js";
|
5
5
|
import { sepolia } from "../../chains/chain-definitions/sepolia.js";
|
6
|
-
import {
|
7
|
-
NATIVE_TOKEN_ADDRESS,
|
8
|
-
ZERO_ADDRESS,
|
9
|
-
} from "../../constants/addresses.js";
|
6
|
+
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
|
10
7
|
import { convertCryptoToFiat } from "./cryptoToFiat.js";
|
11
8
|
|
12
9
|
describe.runIf(process.env.TW_SECRET_KEY)("Pay: crypto-to-fiat", () => {
|
@@ -78,18 +75,4 @@ describe.runIf(process.env.TW_SECRET_KEY)("Pay: crypto-to-fiat", () => {
|
|
78
75
|
"Invalid fromTokenAddress. Expected a valid EVM contract address",
|
79
76
|
);
|
80
77
|
});
|
81
|
-
|
82
|
-
it("should throw error if fromTokenAddress is set to a wallet address", async () => {
|
83
|
-
await expect(
|
84
|
-
convertCryptoToFiat({
|
85
|
-
chain: base,
|
86
|
-
fromTokenAddress: ZERO_ADDRESS,
|
87
|
-
fromAmount: 1,
|
88
|
-
to: "USD",
|
89
|
-
client: TEST_CLIENT,
|
90
|
-
}),
|
91
|
-
).rejects.toThrowError(
|
92
|
-
`Error: ${ZERO_ADDRESS} on chainId: ${base.id} is not a valid contract address.`,
|
93
|
-
);
|
94
|
-
});
|
95
78
|
});
|
@@ -1,15 +1,8 @@
|
|
1
|
-
import { getV1TokensPrice } from "@thirdweb-dev/insight";
|
2
1
|
import type { Address } from "abitype";
|
3
2
|
import type { Chain } from "../../chains/types.js";
|
4
3
|
import type { ThirdwebClient } from "../../client/client.js";
|
5
|
-
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
|
6
|
-
import { getBytecode } from "../../contract/actions/get-bytecode.js";
|
7
|
-
import { getContract } from "../../contract/contract.js";
|
8
4
|
import { isAddress } from "../../utils/address.js";
|
9
|
-
import {
|
10
|
-
import { getClientFetch } from "../../utils/fetch.js";
|
11
|
-
import { stringify } from "../../utils/json.js";
|
12
|
-
import { withCache } from "../../utils/promise/withCache.js";
|
5
|
+
import { getTokenPrice } from "./get-token.js";
|
13
6
|
import type { SupportedFiatCurrency } from "./type.js";
|
14
7
|
|
15
8
|
/**
|
@@ -63,7 +56,7 @@ export type ConvertCryptoToFiatParams = {
|
|
63
56
|
export async function convertCryptoToFiat(
|
64
57
|
options: ConvertCryptoToFiatParams,
|
65
58
|
): Promise<{ result: number }> {
|
66
|
-
const { client, fromTokenAddress,
|
59
|
+
const { client, fromTokenAddress, chain, fromAmount } = options;
|
67
60
|
if (Number(fromAmount) === 0) {
|
68
61
|
return { result: 0 };
|
69
62
|
}
|
@@ -80,50 +73,11 @@ export async function convertCryptoToFiat(
|
|
80
73
|
"Invalid fromTokenAddress. Expected a valid EVM contract address",
|
81
74
|
);
|
82
75
|
}
|
83
|
-
|
84
|
-
if (
|
85
|
-
const bytecode = await getBytecode(
|
86
|
-
getContract({
|
87
|
-
address: fromTokenAddress,
|
88
|
-
chain,
|
89
|
-
client,
|
90
|
-
}),
|
91
|
-
).catch(() => undefined);
|
92
|
-
if (!bytecode || bytecode === "0x") {
|
93
|
-
throw new Error(
|
94
|
-
`Error: ${fromTokenAddress} on chainId: ${chain.id} is not a valid contract address.`,
|
95
|
-
);
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
const result = await withCache(
|
100
|
-
() =>
|
101
|
-
getV1TokensPrice({
|
102
|
-
baseUrl: `https://${getThirdwebDomains().insight}`,
|
103
|
-
fetch: getClientFetch(client),
|
104
|
-
query: {
|
105
|
-
address: fromTokenAddress,
|
106
|
-
chain_id: [chain.id],
|
107
|
-
},
|
108
|
-
}),
|
109
|
-
{
|
110
|
-
cacheKey: `convert-fiat-to-crypto-${to}-${chain.id}`,
|
111
|
-
cacheTime: 1000 * 60, // 1 minute cache
|
112
|
-
},
|
113
|
-
);
|
114
|
-
|
115
|
-
if (result.error) {
|
116
|
-
throw new Error(
|
117
|
-
`Failed to fetch ${to} value for token (${fromTokenAddress}) on chainId: ${chain.id} - ${result.response.status} ${result.response.statusText} - ${result.error ? stringify(result.error) : "Unknown error"}`,
|
118
|
-
);
|
119
|
-
}
|
120
|
-
|
121
|
-
const firstResult = result.data?.data[0];
|
122
|
-
|
123
|
-
if (!firstResult) {
|
76
|
+
const price = await getTokenPrice(client, fromTokenAddress, chain.id);
|
77
|
+
if (!price) {
|
124
78
|
throw new Error(
|
125
|
-
`Failed to fetch
|
79
|
+
`Error: Failed to fetch price for token ${fromTokenAddress} on chainId: ${chain.id}`,
|
126
80
|
);
|
127
81
|
}
|
128
|
-
return { result:
|
82
|
+
return { result: price * fromAmount };
|
129
83
|
}
|
@@ -3,10 +3,7 @@ import { TEST_CLIENT } from "~test/test-clients.js";
|
|
3
3
|
import { base } from "../../chains/chain-definitions/base.js";
|
4
4
|
import { ethereum } from "../../chains/chain-definitions/ethereum.js";
|
5
5
|
import { sepolia } from "../../chains/chain-definitions/sepolia.js";
|
6
|
-
import {
|
7
|
-
NATIVE_TOKEN_ADDRESS,
|
8
|
-
ZERO_ADDRESS,
|
9
|
-
} from "../../constants/addresses.js";
|
6
|
+
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
|
10
7
|
import { convertFiatToCrypto } from "./fiatToCrypto.js";
|
11
8
|
|
12
9
|
describe.runIf(process.env.TW_SECRET_KEY)("Pay: fiatToCrypto", () => {
|
@@ -81,18 +78,4 @@ describe.runIf(process.env.TW_SECRET_KEY)("Pay: fiatToCrypto", () => {
|
|
81
78
|
"Invalid `to`. Expected a valid EVM contract address",
|
82
79
|
);
|
83
80
|
});
|
84
|
-
|
85
|
-
it("should throw error if `to` is set to a wallet address", async () => {
|
86
|
-
await expect(
|
87
|
-
convertFiatToCrypto({
|
88
|
-
chain: base,
|
89
|
-
to: ZERO_ADDRESS,
|
90
|
-
fromAmount: 1,
|
91
|
-
from: "USD",
|
92
|
-
client: TEST_CLIENT,
|
93
|
-
}),
|
94
|
-
).rejects.toThrowError(
|
95
|
-
`Error: ${ZERO_ADDRESS} on chainId: ${base.id} is not a valid contract address.`,
|
96
|
-
);
|
97
|
-
});
|
98
81
|
});
|
@@ -1,15 +1,8 @@
|
|
1
|
-
import { getV1TokensPrice } from "@thirdweb-dev/insight";
|
2
1
|
import type { Address } from "abitype";
|
3
2
|
import type { Chain } from "../../chains/types.js";
|
4
3
|
import type { ThirdwebClient } from "../../client/client.js";
|
5
|
-
import { NATIVE_TOKEN_ADDRESS } from "../../constants/addresses.js";
|
6
|
-
import { getBytecode } from "../../contract/actions/get-bytecode.js";
|
7
|
-
import { getContract } from "../../contract/contract.js";
|
8
4
|
import { isAddress } from "../../utils/address.js";
|
9
|
-
import {
|
10
|
-
import { getClientFetch } from "../../utils/fetch.js";
|
11
|
-
import { stringify } from "../../utils/json.js";
|
12
|
-
import { withCache } from "../../utils/promise/withCache.js";
|
5
|
+
import { getTokenPrice } from "./get-token.js";
|
13
6
|
import type { SupportedFiatCurrency } from "./type.js";
|
14
7
|
|
15
8
|
/**
|
@@ -64,7 +57,7 @@ export type ConvertFiatToCryptoParams = {
|
|
64
57
|
export async function convertFiatToCrypto(
|
65
58
|
options: ConvertFiatToCryptoParams,
|
66
59
|
): Promise<{ result: number }> {
|
67
|
-
const { client,
|
60
|
+
const { client, to, chain, fromAmount } = options;
|
68
61
|
if (Number(fromAmount) === 0) {
|
69
62
|
return { result: 0 };
|
70
63
|
}
|
@@ -79,49 +72,11 @@ export async function convertFiatToCrypto(
|
|
79
72
|
if (!isAddress(to)) {
|
80
73
|
throw new Error("Invalid `to`. Expected a valid EVM contract address");
|
81
74
|
}
|
82
|
-
|
83
|
-
if (
|
84
|
-
const bytecode = await getBytecode(
|
85
|
-
getContract({
|
86
|
-
address: to,
|
87
|
-
chain,
|
88
|
-
client,
|
89
|
-
}),
|
90
|
-
).catch(() => undefined);
|
91
|
-
if (!bytecode || bytecode === "0x") {
|
92
|
-
throw new Error(
|
93
|
-
`Error: ${to} on chainId: ${chain.id} is not a valid contract address.`,
|
94
|
-
);
|
95
|
-
}
|
96
|
-
}
|
97
|
-
const result = await withCache(
|
98
|
-
() =>
|
99
|
-
getV1TokensPrice({
|
100
|
-
baseUrl: `https://${getThirdwebDomains().insight}`,
|
101
|
-
fetch: getClientFetch(client),
|
102
|
-
query: {
|
103
|
-
address: to,
|
104
|
-
chain_id: [chain.id],
|
105
|
-
},
|
106
|
-
}),
|
107
|
-
{
|
108
|
-
cacheKey: `convert-fiat-to-crypto-${to}-${chain.id}`,
|
109
|
-
cacheTime: 1000 * 60, // 1 minute cache
|
110
|
-
},
|
111
|
-
);
|
112
|
-
|
113
|
-
if (result.error) {
|
114
|
-
throw new Error(
|
115
|
-
`Failed to fetch ${from} value for token (${to}) on chainId: ${chain.id} - ${result.response.status} ${result.response.statusText} - ${result.error ? stringify(result.error) : "Unknown error"}`,
|
116
|
-
);
|
117
|
-
}
|
118
|
-
|
119
|
-
const firstResult = result.data?.data[0];
|
120
|
-
|
121
|
-
if (!firstResult || firstResult.price_usd === 0) {
|
75
|
+
const price = await getTokenPrice(client, to, chain.id);
|
76
|
+
if (!price || price === 0) {
|
122
77
|
throw new Error(
|
123
|
-
`Failed to fetch
|
78
|
+
`Error: Failed to fetch price for token ${to} on chainId: ${chain.id}`,
|
124
79
|
);
|
125
80
|
}
|
126
|
-
return { result: fromAmount /
|
81
|
+
return { result: fromAmount / price };
|
127
82
|
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { tokens } from "../../bridge/Token.js";
|
2
|
+
import type { ThirdwebClient } from "../../client/client.js";
|
3
|
+
import { withCache } from "../../utils/promise/withCache.js";
|
4
|
+
|
5
|
+
export async function getTokenPrice(
|
6
|
+
client: ThirdwebClient,
|
7
|
+
tokenAddress: string,
|
8
|
+
chainId: number,
|
9
|
+
) {
|
10
|
+
return withCache(
|
11
|
+
async () => {
|
12
|
+
const result = await tokens({
|
13
|
+
client,
|
14
|
+
tokenAddress,
|
15
|
+
chainId,
|
16
|
+
});
|
17
|
+
return result[0]?.priceUsd;
|
18
|
+
},
|
19
|
+
{
|
20
|
+
cacheKey: `get-token-price-${tokenAddress}-${chainId}`,
|
21
|
+
cacheTime: 1000 * 60, // 1 minute
|
22
|
+
},
|
23
|
+
);
|
24
|
+
}
|
@@ -13,12 +13,12 @@ import { getTransactionGasCost } from "../../../../transaction/utils.js";
|
|
13
13
|
import type { Hex } from "../../../../utils/encoding/hex.js";
|
14
14
|
import { resolvePromisedValue } from "../../../../utils/promise/resolve-promised-value.js";
|
15
15
|
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
|
16
|
+
import { hasSponsoredTransactionsEnabled } from "../../../../wallets/smart/is-smart-wallet.js";
|
16
17
|
import { getTokenBalance } from "../../../../wallets/utils/getTokenBalance.js";
|
17
18
|
import { getWalletBalance } from "../../../../wallets/utils/getWalletBalance.js";
|
18
19
|
import type { LocaleId } from "../../../web/ui/types.js";
|
19
20
|
import type { Theme } from "../../design-system/index.js";
|
20
21
|
import type { SupportedTokens } from "../../utils/defaultTokens.js";
|
21
|
-
import { hasSponsoredTransactionsEnabled } from "../../utils/wallet.js";
|
22
22
|
|
23
23
|
/**
|
24
24
|
* Configuration for the "Pay Modal" that opens when the user doesn't have enough funds to send a transaction.
|
@@ -7,8 +7,7 @@ import { resolveName } from "../../../extensions/ens/resolve-name.js";
|
|
7
7
|
import { shortenAddress } from "../../../utils/address.js";
|
8
8
|
import { parseAvatarRecord } from "../../../utils/ens/avatar.js";
|
9
9
|
import { getWalletInfo } from "../../../wallets/__generated__/getWalletInfo.js";
|
10
|
-
import {
|
11
|
-
import type { Account, Wallet } from "../../../wallets/interfaces/wallet.js";
|
10
|
+
import type { Account } from "../../../wallets/interfaces/wallet.js";
|
12
11
|
import type { WalletInfo } from "../../../wallets/wallet-info.js";
|
13
12
|
import type { WalletId } from "../../../wallets/wallet-types.js";
|
14
13
|
import { useWalletBalance } from "../hooks/others/useWalletBalance.js";
|
@@ -215,50 +214,3 @@ export function useWalletImage(id: WalletId | undefined) {
|
|
215
214
|
enabled: !!id,
|
216
215
|
});
|
217
216
|
}
|
218
|
-
|
219
|
-
/**
|
220
|
-
* @internal
|
221
|
-
*/
|
222
|
-
export function hasSponsoredTransactionsEnabled(wallet: Wallet | undefined) {
|
223
|
-
if (!wallet) {
|
224
|
-
return false;
|
225
|
-
}
|
226
|
-
let sponsoredTransactionsEnabled = false;
|
227
|
-
if (wallet && wallet.id === "smart") {
|
228
|
-
const options = (wallet as Wallet<"smart">).getConfig();
|
229
|
-
if ("sponsorGas" in options) {
|
230
|
-
sponsoredTransactionsEnabled = options.sponsorGas;
|
231
|
-
}
|
232
|
-
if ("gasless" in options) {
|
233
|
-
sponsoredTransactionsEnabled = options.gasless;
|
234
|
-
}
|
235
|
-
}
|
236
|
-
if (wallet && (wallet.id === "inApp" || isEcosystemWallet(wallet))) {
|
237
|
-
const options = (wallet as Wallet<"inApp">).getConfig();
|
238
|
-
if (options && "smartAccount" in options && options.smartAccount) {
|
239
|
-
const smartOptions = options.smartAccount;
|
240
|
-
if ("sponsorGas" in smartOptions) {
|
241
|
-
sponsoredTransactionsEnabled = smartOptions.sponsorGas;
|
242
|
-
}
|
243
|
-
if ("gasless" in smartOptions) {
|
244
|
-
sponsoredTransactionsEnabled = smartOptions.gasless;
|
245
|
-
}
|
246
|
-
}
|
247
|
-
if (options?.executionMode) {
|
248
|
-
const execMode = options.executionMode;
|
249
|
-
if (execMode.mode === "EIP4337") {
|
250
|
-
const smartOptions = execMode.smartAccount;
|
251
|
-
if (smartOptions && "sponsorGas" in smartOptions) {
|
252
|
-
sponsoredTransactionsEnabled = smartOptions.sponsorGas;
|
253
|
-
}
|
254
|
-
if (smartOptions && "gasless" in smartOptions) {
|
255
|
-
sponsoredTransactionsEnabled = smartOptions.gasless;
|
256
|
-
}
|
257
|
-
}
|
258
|
-
if (execMode.mode === "EIP7702") {
|
259
|
-
sponsoredTransactionsEnabled = execMode.sponsorGas || false;
|
260
|
-
}
|
261
|
-
}
|
262
|
-
}
|
263
|
-
return sponsoredTransactionsEnabled;
|
264
|
-
}
|
@@ -5,6 +5,7 @@ import { getContract } from "../../../../contract/contract.js";
|
|
5
5
|
import { isContractDeployed } from "../../../../utils/bytecode/is-contract-deployed.js";
|
6
6
|
import { formatNumber } from "../../../../utils/formatNumber.js";
|
7
7
|
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
|
8
|
+
import { isSmartWallet } from "../../../../wallets/smart/is-smart-wallet.js";
|
8
9
|
import type { Theme } from "../../../core/design-system/index.js";
|
9
10
|
import { useSiweAuth } from "../../../core/hooks/auth/useSiweAuth.js";
|
10
11
|
import type { ConnectButtonProps } from "../../../core/hooks/connection/ConnectButtonProps.js";
|
@@ -13,7 +14,6 @@ import { useActiveAccount } from "../../../core/hooks/wallets/useActiveAccount.j
|
|
13
14
|
import { useActiveWallet } from "../../../core/hooks/wallets/useActiveWallet.js";
|
14
15
|
import { useActiveWalletChain } from "../../../core/hooks/wallets/useActiveWalletChain.js";
|
15
16
|
import { useDisconnect } from "../../../core/hooks/wallets/useDisconnect.js";
|
16
|
-
import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js";
|
17
17
|
import { useConnectedWalletDetails } from "../../../core/utils/wallet.js";
|
18
18
|
import { fontSize, radius, spacing } from "../../design-system/index.js";
|
19
19
|
import { Address } from "../components/Address.js";
|
@@ -326,14 +326,14 @@ function SmartAccountBadge(props: {
|
|
326
326
|
}) {
|
327
327
|
const activeAccount = useActiveAccount();
|
328
328
|
const activeWallet = useActiveWallet();
|
329
|
-
const
|
329
|
+
const isSW = isSmartWallet(activeWallet);
|
330
330
|
const chain = useActiveWalletChain();
|
331
331
|
const { client, theme } = props;
|
332
332
|
|
333
333
|
const [isSmartWalletDeployed, setIsSmartWalletDeployed] = useState(false);
|
334
334
|
|
335
335
|
useEffect(() => {
|
336
|
-
if (activeAccount &&
|
336
|
+
if (activeAccount && isSW && activeAccount.address && chain) {
|
337
337
|
const contract = getContract({
|
338
338
|
address: activeAccount.address,
|
339
339
|
chain,
|
@@ -346,7 +346,7 @@ function SmartAccountBadge(props: {
|
|
346
346
|
} else {
|
347
347
|
setIsSmartWalletDeployed(false);
|
348
348
|
}
|
349
|
-
}, [activeAccount, chain, client,
|
349
|
+
}, [activeAccount, chain, client, isSW]);
|
350
350
|
|
351
351
|
const content = (
|
352
352
|
<View
|
@@ -377,7 +377,7 @@ function SmartAccountBadge(props: {
|
|
377
377
|
</View>
|
378
378
|
);
|
379
379
|
|
380
|
-
if (chain && activeAccount &&
|
380
|
+
if (chain && activeAccount && isSW) {
|
381
381
|
return (
|
382
382
|
<>
|
383
383
|
<Spacer size="smd" />
|
@@ -30,6 +30,7 @@ import { webLocalStorage } from "../../../../utils/storage/webStorage.js";
|
|
30
30
|
import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js";
|
31
31
|
import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js";
|
32
32
|
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
|
33
|
+
import { isSmartWallet } from "../../../../wallets/smart/is-smart-wallet.js";
|
33
34
|
import type { SmartWalletOptions } from "../../../../wallets/smart/types.js";
|
34
35
|
import {
|
35
36
|
type AppMetadata,
|
@@ -77,7 +78,6 @@ import type {
|
|
77
78
|
SupportedNFTs,
|
78
79
|
SupportedTokens,
|
79
80
|
} from "../../../core/utils/defaultTokens.js";
|
80
|
-
import { hasSmartAccount } from "../../../core/utils/isSmartWallet.js";
|
81
81
|
import { useWalletInfo } from "../../../core/utils/wallet.js";
|
82
82
|
import { WalletUIStatesProvider } from "../../providers/wallet-ui-states-provider.js";
|
83
83
|
import { ChainActiveDot } from "../components/ChainActiveDot.js";
|
@@ -1186,14 +1186,14 @@ export function ConnectedToSmartWallet(props: {
|
|
1186
1186
|
}) {
|
1187
1187
|
const activeAccount = useActiveAccount();
|
1188
1188
|
const activeWallet = useActiveWallet();
|
1189
|
-
const
|
1189
|
+
const isSW = isSmartWallet(activeWallet);
|
1190
1190
|
const chain = useActiveWalletChain();
|
1191
1191
|
const { client, connectLocale: locale } = props;
|
1192
1192
|
|
1193
1193
|
const [isSmartWalletDeployed, setIsSmartWalletDeployed] = useState(false);
|
1194
1194
|
|
1195
1195
|
useEffect(() => {
|
1196
|
-
if (activeAccount &&
|
1196
|
+
if (activeAccount && isSW && activeAccount.address && chain) {
|
1197
1197
|
const contract = getContract({
|
1198
1198
|
address: activeAccount.address,
|
1199
1199
|
chain,
|
@@ -1206,7 +1206,7 @@ export function ConnectedToSmartWallet(props: {
|
|
1206
1206
|
} else {
|
1207
1207
|
setIsSmartWalletDeployed(false);
|
1208
1208
|
}
|
1209
|
-
}, [activeAccount, chain, client,
|
1209
|
+
}, [activeAccount, chain, client, isSW]);
|
1210
1210
|
|
1211
1211
|
const content = (
|
1212
1212
|
<Container flex="row" gap="3xs" center="y">
|
@@ -1216,7 +1216,7 @@ export function ConnectedToSmartWallet(props: {
|
|
1216
1216
|
</Container>
|
1217
1217
|
);
|
1218
1218
|
|
1219
|
-
if (chain && activeAccount &&
|
1219
|
+
if (chain && activeAccount && isSW) {
|
1220
1220
|
return (
|
1221
1221
|
<>
|
1222
1222
|
{isSmartWalletDeployed ? (
|
@@ -1251,7 +1251,7 @@ export function InAppWalletUserInfo(props: {
|
|
1251
1251
|
const activeWallet = useActiveWallet();
|
1252
1252
|
const adminWallet = useAdminWallet();
|
1253
1253
|
const { data: walletInfo } = useWalletInfo(activeWallet?.id);
|
1254
|
-
const
|
1254
|
+
const isSW = isSmartWallet(activeWallet);
|
1255
1255
|
const { data: walletName } = useQuery({
|
1256
1256
|
queryKey: [
|
1257
1257
|
"wallet-name",
|
@@ -1317,7 +1317,7 @@ export function InAppWalletUserInfo(props: {
|
|
1317
1317
|
enabled: !!adminWallet,
|
1318
1318
|
});
|
1319
1319
|
|
1320
|
-
if (!userInfoQuery.data &&
|
1320
|
+
if (!userInfoQuery.data && isSW) {
|
1321
1321
|
return <ConnectedToSmartWallet client={client} connectLocale={locale} />;
|
1322
1322
|
}
|
1323
1323
|
|