thirdweb 5.105.7-nightly-4c6a421d64336d7c18956a4128fea40866b9c9b1-20250706232018 → 5.105.7
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/react/web/ui/Bridge/BridgeOrchestrator.js +2 -2
- package/dist/cjs/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js +0 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js +0 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/QuoteLoader.js +5 -1
- package/dist/cjs/react/web/ui/Bridge/QuoteLoader.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js +0 -1
- package/dist/cjs/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/PayEmbed.js +1 -1
- package/dist/cjs/react/web/ui/PayEmbed.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/cjs/wallets/create-wallet.js +1 -9
- package/dist/cjs/wallets/create-wallet.js.map +1 -1
- package/dist/cjs/wallets/native/create-wallet.js +1 -9
- package/dist/cjs/wallets/native/create-wallet.js.map +1 -1
- package/dist/cjs/wallets/wallet-connect/controller.js +103 -62
- package/dist/cjs/wallets/wallet-connect/controller.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js +2 -2
- package/dist/esm/react/web/ui/Bridge/BridgeOrchestrator.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js +0 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js +0 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/QuoteLoader.js +5 -1
- package/dist/esm/react/web/ui/Bridge/QuoteLoader.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/TransactionWidget.js +0 -1
- package/dist/esm/react/web/ui/Bridge/TransactionWidget.js.map +1 -1
- package/dist/esm/react/web/ui/PayEmbed.js +1 -1
- package/dist/esm/react/web/ui/PayEmbed.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/esm/wallets/create-wallet.js +1 -9
- package/dist/esm/wallets/create-wallet.js.map +1 -1
- package/dist/esm/wallets/native/create-wallet.js +1 -9
- package/dist/esm/wallets/native/create-wallet.js.map +1 -1
- package/dist/esm/wallets/wallet-connect/controller.js +104 -63
- package/dist/esm/wallets/wallet-connect/controller.js.map +1 -1
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/QuoteLoader.d.ts +4 -4
- package/dist/types/react/web/ui/Bridge/QuoteLoader.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/TransactionWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/PayEmbed.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/create-wallet.d.ts.map +1 -1
- package/dist/types/wallets/native/create-wallet.d.ts.map +1 -1
- package/dist/types/wallets/wallet-connect/controller.d.ts +2 -2
- package/dist/types/wallets/wallet-connect/controller.d.ts.map +1 -1
- package/dist/types/wallets/wallet-connect/types.d.ts +3 -12
- package/dist/types/wallets/wallet-connect/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/react/web/ui/Bridge/BridgeOrchestrator.tsx +1 -1
- package/src/react/web/ui/Bridge/BuyWidget.tsx +0 -1
- package/src/react/web/ui/Bridge/CheckoutWidget.tsx +0 -1
- package/src/react/web/ui/Bridge/QuoteLoader.tsx +9 -5
- package/src/react/web/ui/Bridge/TransactionWidget.tsx +0 -1
- package/src/react/web/ui/PayEmbed.tsx +3 -0
- package/src/version.ts +1 -1
- package/src/wallets/create-wallet.ts +1 -8
- package/src/wallets/native/create-wallet.ts +1 -8
- package/src/wallets/wallet-connect/controller.ts +164 -101
- package/src/wallets/wallet-connect/types.ts +16 -12
@@ -1,19 +1,10 @@
|
|
1
|
+
import type { EthereumProvider } from "@walletconnect/ethereum-provider";
|
1
2
|
import type { Chain } from "../../chains/types.js";
|
2
3
|
import type { ThirdwebClient } from "../../client/client.js";
|
3
4
|
import type { Prettify } from "../../utils/type-utils.js";
|
4
5
|
import type { AppMetadata } from "../types.js";
|
5
|
-
type
|
6
|
-
|
7
|
-
themeVariables?: Record<string, string>;
|
8
|
-
desktopWallets?: Record<string, unknown>[];
|
9
|
-
enableExplorer?: boolean;
|
10
|
-
explorerRecommendedWalletIds?: string[];
|
11
|
-
explorerExcludedWalletIds?: string[];
|
12
|
-
mobileWallets?: Record<string, unknown>[];
|
13
|
-
privacyPolicyUrl?: string;
|
14
|
-
termsOfServiceUrl?: string;
|
15
|
-
walletImages?: Record<string, string>;
|
16
|
-
};
|
6
|
+
type EthereumProviderOptions = Parameters<(typeof EthereumProvider)["init"]>[0];
|
7
|
+
type WalletConnectQRCodeModalOptions = Pick<NonNullable<EthereumProviderOptions["qrModalOptions"]>, "themeMode" | "themeVariables" | "desktopWallets" | "enableExplorer" | "explorerRecommendedWalletIds" | "explorerExcludedWalletIds" | "mobileWallets" | "privacyPolicyUrl" | "termsOfServiceUrl" | "walletImages">;
|
17
8
|
export type WalletConnectConfig = {
|
18
9
|
/**
|
19
10
|
* Your project’s unique identifier that can be obtained at https://cloud.walletconnect.com/
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/wallets/wallet-connect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/wallets/wallet-connect/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,KAAK,uBAAuB,GAAG,UAAU,CAAC,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,KAAK,+BAA+B,GAAG,IAAI,CACzC,WAAW,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC,EACpD,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,8BAA8B,GAC9B,2BAA2B,GAC3B,eAAe,GACf,kBAAkB,GAClB,mBAAmB,GACnB,cAAc,CACjB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd;;;;;;;;;;;;;;OAcG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB,aAAa,CAAC,EAAE,QAAQ,CACtB,mBAAmB,GAAG;QACpB;;;;;;;;;;;;;;;;;;;;;;;;;WAyBG;QACH,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC;QACzB;;;;;;;;;;;;;;;;;WAiBG;QACH,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB;;WAEG;QACH,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;;WAGG;QACH,cAAc,CAAC,EAAE,+BAA+B,CAAC;QACjD;;;;;;;;;;;;;WAaG;QACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KACvC,CACF,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;;;;;;;;;;;OAcG;IACH,MAAM,EAAE,cAAc,CAAC;IAEvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAExC,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC"}
|
package/package.json
CHANGED
@@ -23,8 +23,8 @@
|
|
23
23
|
"@radix-ui/react-tooltip": "1.2.7",
|
24
24
|
"@storybook/react": "9.0.15",
|
25
25
|
"@tanstack/react-query": "5.81.5",
|
26
|
+
"@walletconnect/ethereum-provider": "2.20.1",
|
26
27
|
"@walletconnect/sign-client": "2.20.1",
|
27
|
-
"@walletconnect/universal-provider": "2.21.4",
|
28
28
|
"abitype": "1.0.8",
|
29
29
|
"cross-spawn": "7.0.6",
|
30
30
|
"fuse.js": "7.1.0",
|
@@ -375,7 +375,7 @@
|
|
375
375
|
}
|
376
376
|
},
|
377
377
|
"typings": "./dist/types/exports/thirdweb.d.ts",
|
378
|
-
"version": "5.105.7
|
378
|
+
"version": "5.105.7",
|
379
379
|
"scripts": {
|
380
380
|
"bench": "vitest -c ./test/vitest.config.ts bench",
|
381
381
|
"bench:compare": "bun run ./benchmarks/run.ts",
|
@@ -292,7 +292,6 @@ export function BridgeOrchestrator({
|
|
292
292
|
amount={state.context.destinationAmount}
|
293
293
|
client={client}
|
294
294
|
destinationToken={state.context.destinationToken}
|
295
|
-
mode={uiOptions.mode}
|
296
295
|
onBack={() => {
|
297
296
|
send({ type: "BACK" });
|
298
297
|
}}
|
@@ -302,6 +301,7 @@ export function BridgeOrchestrator({
|
|
302
301
|
paymentMethod={state.context.selectedPaymentMethod}
|
303
302
|
purchaseData={purchaseData}
|
304
303
|
receiver={state.context.receiverAddress}
|
304
|
+
uiOptions={uiOptions}
|
305
305
|
/>
|
306
306
|
)}
|
307
307
|
|
@@ -17,6 +17,7 @@ import { Container } from "../components/basic.js";
|
|
17
17
|
import { Spacer } from "../components/Spacer.js";
|
18
18
|
import { Spinner } from "../components/Spinner.js";
|
19
19
|
import { Text } from "../components/text.js";
|
20
|
+
import type { UIOptions } from "./BridgeOrchestrator.js";
|
20
21
|
|
21
22
|
interface QuoteLoaderProps {
|
22
23
|
/**
|
@@ -78,14 +79,13 @@ interface QuoteLoaderProps {
|
|
78
79
|
paymentLinkId?: string;
|
79
80
|
|
80
81
|
/**
|
81
|
-
*
|
82
|
+
* UI options
|
82
83
|
*/
|
83
|
-
|
84
|
-
mode: "fund_wallet" | "direct_payment" | "transaction";
|
84
|
+
uiOptions: UIOptions;
|
85
85
|
}
|
86
86
|
|
87
87
|
export function QuoteLoader({
|
88
|
-
|
88
|
+
uiOptions,
|
89
89
|
destinationToken,
|
90
90
|
paymentMethod,
|
91
91
|
amount,
|
@@ -96,10 +96,14 @@ export function QuoteLoader({
|
|
96
96
|
onError,
|
97
97
|
purchaseData,
|
98
98
|
paymentLinkId,
|
99
|
-
feePayer,
|
100
99
|
}: QuoteLoaderProps) {
|
101
100
|
// For now, we'll use a simple buy operation
|
102
101
|
// This will be expanded to handle different bridge types based on the payment method
|
102
|
+
const feePayer =
|
103
|
+
uiOptions.mode === "direct_payment"
|
104
|
+
? uiOptions.paymentInfo.feePayer
|
105
|
+
: undefined;
|
106
|
+
const mode = uiOptions.mode;
|
103
107
|
const request: BridgePrepareRequest = getBridgeParams({
|
104
108
|
amount,
|
105
109
|
client,
|
@@ -380,6 +380,9 @@ export function PayEmbed(props: PayEmbedProps) {
|
|
380
380
|
chain={props.payOptions.paymentInfo.chain}
|
381
381
|
client={props.client}
|
382
382
|
description={metadata?.description}
|
383
|
+
feePayer={
|
384
|
+
props.payOptions.paymentInfo.feePayer === "sender" ? "user" : "seller"
|
385
|
+
}
|
383
386
|
image={metadata?.image}
|
384
387
|
name={metadata?.name || "Checkout"}
|
385
388
|
onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
|
package/src/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = "5.105.7
|
1
|
+
export const version = "5.105.7";
|
@@ -399,14 +399,7 @@ export function createWallet<const ID extends WalletId>(
|
|
399
399
|
getConfig: () => args[1],
|
400
400
|
id,
|
401
401
|
subscribe: emitter.subscribe,
|
402
|
-
switchChain:
|
403
|
-
try {
|
404
|
-
await handleSwitchChain(c);
|
405
|
-
chain = c;
|
406
|
-
} catch (e) {
|
407
|
-
console.error("Error switching chain", e);
|
408
|
-
}
|
409
|
-
},
|
402
|
+
switchChain: (c) => handleSwitchChain(c),
|
410
403
|
};
|
411
404
|
return wallet;
|
412
405
|
}
|
@@ -230,14 +230,7 @@ export function createWallet<const ID extends WalletId>(
|
|
230
230
|
getConfig: () => args[1],
|
231
231
|
id,
|
232
232
|
subscribe: emitter.subscribe,
|
233
|
-
switchChain:
|
234
|
-
try {
|
235
|
-
await handleSwitchChain(c);
|
236
|
-
chain = c;
|
237
|
-
} catch (e) {
|
238
|
-
console.error("Error switching chain", e);
|
239
|
-
}
|
240
|
-
},
|
233
|
+
switchChain: (c) => handleSwitchChain(c),
|
241
234
|
};
|
242
235
|
return wallet;
|
243
236
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type {
|
1
|
+
import type { EthereumProvider } from "@walletconnect/ethereum-provider";
|
2
2
|
import type { Address } from "abitype";
|
3
3
|
import {
|
4
4
|
getTypesForEIP712Domain,
|
@@ -11,7 +11,11 @@ import {
|
|
11
11
|
} from "viem";
|
12
12
|
import { trackTransaction } from "../../analytics/track/transaction.js";
|
13
13
|
import type { Chain } from "../../chains/types.js";
|
14
|
-
import {
|
14
|
+
import {
|
15
|
+
getCachedChain,
|
16
|
+
getChainMetadata,
|
17
|
+
getRpcUrlForChain,
|
18
|
+
} from "../../chains/utils.js";
|
15
19
|
import type { ThirdwebClient } from "../../client/client.js";
|
16
20
|
import { getAddress } from "../../utils/address.js";
|
17
21
|
import {
|
@@ -36,6 +40,7 @@ import type {
|
|
36
40
|
Wallet,
|
37
41
|
} from "../interfaces/wallet.js";
|
38
42
|
import type { DisconnectFn, SwitchChainFn } from "../types.js";
|
43
|
+
import { getValidPublicRPCUrl } from "../utils/chains.js";
|
39
44
|
import { getDefaultAppMetadata } from "../utils/defaultDappMetadata.js";
|
40
45
|
import { normalizeChainId } from "../utils/normalizeChainId.js";
|
41
46
|
import type { WalletEmitter } from "../wallet-emitter.js";
|
@@ -43,9 +48,7 @@ import type { WalletId } from "../wallet-types.js";
|
|
43
48
|
import { DEFAULT_PROJECT_ID, NAMESPACE } from "./constants.js";
|
44
49
|
import type { WCAutoConnectOptions, WCConnectOptions } from "./types.js";
|
45
50
|
|
46
|
-
type WCProvider = InstanceType<typeof
|
47
|
-
|
48
|
-
let cachedProvider: WCProvider | null = null;
|
51
|
+
type WCProvider = InstanceType<typeof EthereumProvider>;
|
49
52
|
|
50
53
|
type SavedConnectParams = {
|
51
54
|
optionalChains?: Chain[];
|
@@ -53,6 +56,10 @@ type SavedConnectParams = {
|
|
53
56
|
pairingTopic?: string;
|
54
57
|
};
|
55
58
|
|
59
|
+
const ADD_ETH_CHAIN_METHOD = "wallet_addEthereumChain";
|
60
|
+
|
61
|
+
const defaultShowQrModal = true;
|
62
|
+
|
56
63
|
const storageKeys = {
|
57
64
|
lastUsedChainId: "tw.wc.lastUsedChainId",
|
58
65
|
requestedChains: "tw.wc.requestedChains",
|
@@ -116,56 +123,37 @@ export async function connectWC(
|
|
116
123
|
}
|
117
124
|
}
|
118
125
|
|
119
|
-
|
120
|
-
|
126
|
+
const {
|
127
|
+
rpcMap,
|
128
|
+
requiredChain,
|
129
|
+
optionalChains: chainsToRequest,
|
130
|
+
} = getChainsToRequest({
|
121
131
|
chain: chainToRequest,
|
122
132
|
client: options.client,
|
123
133
|
optionalChains: optionalChains,
|
124
134
|
});
|
125
135
|
|
126
|
-
if (
|
127
|
-
// For UniversalProvider, we need to connect with namespaces
|
136
|
+
if (provider.session) {
|
128
137
|
await provider.connect({
|
129
138
|
...(wcOptions?.pairingTopic
|
130
139
|
? { pairingTopic: wcOptions?.pairingTopic }
|
131
140
|
: {}),
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
events: ["chainChanged", "accountsChanged"],
|
136
|
-
methods: [
|
137
|
-
"eth_sendTransaction",
|
138
|
-
"eth_signTransaction",
|
139
|
-
"eth_sign",
|
140
|
-
"personal_sign",
|
141
|
-
"eth_signTypedData",
|
142
|
-
"wallet_switchEthereumChain",
|
143
|
-
"wallet_addEthereumChain",
|
144
|
-
],
|
145
|
-
rpcMap,
|
146
|
-
},
|
147
|
-
},
|
141
|
+
chains: requiredChain ? [requiredChain.id] : undefined,
|
142
|
+
optionalChains: chainsToRequest,
|
143
|
+
rpcMap: rpcMap,
|
148
144
|
});
|
149
145
|
}
|
150
146
|
|
151
|
-
setRequestedChainsIds(
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
const currentChainId = chainsToRequest[0]?.split(":")[1] || 1;
|
156
|
-
const providerChainId = normalizeChainId(currentChainId);
|
157
|
-
const accounts: string[] = await provider.request(
|
158
|
-
{
|
159
|
-
method: "eth_requestAccounts",
|
160
|
-
params: [],
|
161
|
-
},
|
162
|
-
`eip155:${providerChainId}`,
|
163
|
-
);
|
164
|
-
const address = accounts[0];
|
147
|
+
setRequestedChainsIds(chainsToRequest, storage);
|
148
|
+
// If session exists and chains are authorized, enable provider for required chain
|
149
|
+
const addresses = await provider.enable();
|
150
|
+
const address = addresses[0];
|
165
151
|
if (!address) {
|
166
152
|
throw new Error("No accounts found on provider.");
|
167
153
|
}
|
168
154
|
|
155
|
+
const providerChainId = normalizeChainId(provider.chainId);
|
156
|
+
|
169
157
|
const chain =
|
170
158
|
options.chain && options.chain.id === providerChainId
|
171
159
|
? options.chain
|
@@ -221,19 +209,16 @@ export async function autoConnectWC(
|
|
221
209
|
},
|
222
210
|
walletId,
|
223
211
|
sessionHandler,
|
212
|
+
true, // is auto connect
|
224
213
|
);
|
225
214
|
|
226
|
-
|
227
|
-
const addresses = await provider.enable();
|
228
|
-
const address = addresses[0];
|
215
|
+
const address = provider.accounts[0];
|
229
216
|
|
230
217
|
if (!address) {
|
231
218
|
throw new Error("No accounts found on provider.");
|
232
219
|
}
|
233
220
|
|
234
|
-
|
235
|
-
const currentChainId = options.chain?.id || 1;
|
236
|
-
const providerChainId = normalizeChainId(currentChainId);
|
221
|
+
const providerChainId = normalizeChainId(provider.chainId);
|
237
222
|
|
238
223
|
const chain =
|
239
224
|
options.chain && options.chain.id === providerChainId
|
@@ -249,15 +234,12 @@ async function initProvider(
|
|
249
234
|
options: WCConnectOptions,
|
250
235
|
walletId: WCSupportedWalletIds | "walletConnect",
|
251
236
|
sessionRequestHandler?: (uri: string) => void | Promise<void>,
|
237
|
+
isAutoConnect = false,
|
252
238
|
) {
|
253
|
-
if (cachedProvider) {
|
254
|
-
return cachedProvider;
|
255
|
-
}
|
256
|
-
|
257
239
|
const walletInfo = await getWalletInfo(walletId);
|
258
240
|
const wcOptions = options.walletConnect;
|
259
|
-
const {
|
260
|
-
"@walletconnect/
|
241
|
+
const { EthereumProvider, OPTIONAL_EVENTS, OPTIONAL_METHODS } = await import(
|
242
|
+
"@walletconnect/ethereum-provider"
|
261
243
|
);
|
262
244
|
|
263
245
|
let optionalChains: Chain[] | undefined = wcOptions?.optionalChains;
|
@@ -271,7 +253,19 @@ async function initProvider(
|
|
271
253
|
}
|
272
254
|
}
|
273
255
|
|
274
|
-
const
|
256
|
+
const {
|
257
|
+
rpcMap,
|
258
|
+
requiredChain,
|
259
|
+
optionalChains: chainsToRequest,
|
260
|
+
} = getChainsToRequest({
|
261
|
+
chain: chainToRequest,
|
262
|
+
client: options.client,
|
263
|
+
optionalChains: optionalChains,
|
264
|
+
});
|
265
|
+
|
266
|
+
const provider = await EthereumProvider.init({
|
267
|
+
chains: requiredChain ? [requiredChain.id] : undefined,
|
268
|
+
disableProviderPing: true,
|
275
269
|
metadata: {
|
276
270
|
description:
|
277
271
|
wcOptions?.appMetadata?.description ||
|
@@ -282,11 +276,31 @@ async function initProvider(
|
|
282
276
|
name: wcOptions?.appMetadata?.name || getDefaultAppMetadata().name,
|
283
277
|
url: wcOptions?.appMetadata?.url || getDefaultAppMetadata().url,
|
284
278
|
},
|
279
|
+
optionalChains: chainsToRequest,
|
280
|
+
optionalEvents: OPTIONAL_EVENTS,
|
281
|
+
optionalMethods: OPTIONAL_METHODS,
|
285
282
|
projectId: wcOptions?.projectId || DEFAULT_PROJECT_ID,
|
283
|
+
qrModalOptions: wcOptions?.qrModalOptions,
|
284
|
+
rpcMap: rpcMap,
|
285
|
+
showQrModal:
|
286
|
+
wcOptions?.showQrModal === undefined
|
287
|
+
? sessionRequestHandler
|
288
|
+
? false
|
289
|
+
: defaultShowQrModal
|
290
|
+
: wcOptions.showQrModal,
|
286
291
|
});
|
287
292
|
|
288
293
|
provider.events.setMaxListeners(Number.POSITIVE_INFINITY);
|
289
294
|
|
295
|
+
// disconnect the provider if chains are stale when (if not auto connecting)
|
296
|
+
if (!isAutoConnect) {
|
297
|
+
// const isStale = await isChainsStale(provider, chainsToRequest);
|
298
|
+
|
299
|
+
if (provider.session) {
|
300
|
+
await provider.disconnect();
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
290
304
|
if (walletId !== "walletConnect") {
|
291
305
|
async function handleSessionRequest() {
|
292
306
|
const walletLinkToOpen =
|
@@ -300,16 +314,12 @@ async function initProvider(
|
|
300
314
|
}
|
301
315
|
}
|
302
316
|
|
303
|
-
|
304
|
-
provider.on("session_request_sent", handleSessionRequest);
|
317
|
+
provider.signer.client.on("session_request_sent", handleSessionRequest);
|
305
318
|
provider.events.addListener("disconnect", () => {
|
306
|
-
provider.off("session_request_sent", handleSessionRequest);
|
307
|
-
cachedProvider = null;
|
319
|
+
provider.signer.client.off("session_request_sent", handleSessionRequest);
|
308
320
|
});
|
309
321
|
}
|
310
322
|
|
311
|
-
cachedProvider = provider;
|
312
|
-
|
313
323
|
return provider;
|
314
324
|
}
|
315
325
|
|
@@ -317,31 +327,26 @@ function createAccount({
|
|
317
327
|
provider,
|
318
328
|
address,
|
319
329
|
client,
|
320
|
-
chain,
|
321
330
|
}: {
|
322
331
|
provider: WCProvider;
|
323
332
|
address: string;
|
324
333
|
client: ThirdwebClient;
|
325
|
-
chain: Chain;
|
326
334
|
}) {
|
327
335
|
const account: Account = {
|
328
336
|
address: getAddress(address),
|
329
337
|
async sendTransaction(tx: SendTransactionOption) {
|
330
|
-
const transactionHash = (await provider.request(
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
},
|
343
|
-
`eip155:${tx.chainId}`,
|
344
|
-
)) as Hex;
|
338
|
+
const transactionHash = (await provider.request({
|
339
|
+
method: "eth_sendTransaction",
|
340
|
+
params: [
|
341
|
+
{
|
342
|
+
data: tx.data,
|
343
|
+
from: getAddress(address),
|
344
|
+
gas: tx.gas ? numberToHex(tx.gas) : undefined,
|
345
|
+
to: tx.to as Address,
|
346
|
+
value: tx.value ? numberToHex(tx.value) : undefined,
|
347
|
+
},
|
348
|
+
],
|
349
|
+
})) as Hex;
|
345
350
|
|
346
351
|
trackTransaction({
|
347
352
|
chainId: tx.chainId,
|
@@ -367,13 +372,10 @@ function createAccount({
|
|
367
372
|
}
|
368
373
|
return message.raw;
|
369
374
|
})();
|
370
|
-
return provider.request(
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
},
|
375
|
-
`eip155:${chain.id}`,
|
376
|
-
);
|
375
|
+
return provider.request({
|
376
|
+
method: "personal_sign",
|
377
|
+
params: [messageToSign, this.address],
|
378
|
+
});
|
377
379
|
},
|
378
380
|
async signTypedData(_data) {
|
379
381
|
const data = parseTypedData(_data);
|
@@ -396,13 +398,10 @@ function createAccount({
|
|
396
398
|
types,
|
397
399
|
});
|
398
400
|
|
399
|
-
return await provider.request(
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
},
|
404
|
-
`eip155:${chain.id}`,
|
405
|
-
);
|
401
|
+
return await provider.request({
|
402
|
+
method: "eth_signTypedData_v4",
|
403
|
+
params: [this.address, typedData],
|
404
|
+
});
|
406
405
|
},
|
407
406
|
};
|
408
407
|
|
@@ -417,14 +416,13 @@ function onConnect(
|
|
417
416
|
storage: AsyncStorage,
|
418
417
|
client: ThirdwebClient,
|
419
418
|
): [Account, Chain, DisconnectFn, SwitchChainFn] {
|
420
|
-
const account = createAccount({ address,
|
419
|
+
const account = createAccount({ address, client, provider });
|
421
420
|
|
422
421
|
async function disconnect() {
|
423
422
|
provider.removeListener("accountsChanged", onAccountsChanged);
|
424
423
|
provider.removeListener("chainChanged", onChainChanged);
|
425
424
|
provider.removeListener("disconnect", onDisconnect);
|
426
425
|
await provider.disconnect();
|
427
|
-
cachedProvider = null;
|
428
426
|
}
|
429
427
|
|
430
428
|
function onDisconnect() {
|
@@ -438,7 +436,6 @@ function onConnect(
|
|
438
436
|
if (accounts[0]) {
|
439
437
|
const newAccount = createAccount({
|
440
438
|
address: getAddress(accounts[0]),
|
441
|
-
chain,
|
442
439
|
client,
|
443
440
|
provider,
|
444
441
|
});
|
@@ -464,14 +461,66 @@ function onConnect(
|
|
464
461
|
account,
|
465
462
|
chain,
|
466
463
|
disconnect,
|
467
|
-
(newChain) => switchChainWC(provider, newChain),
|
464
|
+
(newChain) => switchChainWC(provider, newChain, storage),
|
468
465
|
];
|
469
466
|
}
|
470
467
|
|
471
|
-
|
468
|
+
// Storage utils -----------------------------------------------------------------------------------------------
|
469
|
+
|
470
|
+
function getNamespaceMethods(provider: WCProvider) {
|
471
|
+
return provider.session?.namespaces[NAMESPACE]?.methods || [];
|
472
|
+
}
|
473
|
+
|
474
|
+
function getNamespaceChainsIds(provider: WCProvider): number[] {
|
475
|
+
const chainIds = provider.session?.namespaces[NAMESPACE]?.chains?.map(
|
476
|
+
(chain) => Number.parseInt(chain.split(":")[1] || ""),
|
477
|
+
);
|
478
|
+
|
479
|
+
return chainIds ?? [];
|
480
|
+
}
|
481
|
+
|
482
|
+
async function switchChainWC(
|
483
|
+
provider: WCProvider,
|
484
|
+
chain: Chain,
|
485
|
+
storage: AsyncStorage,
|
486
|
+
) {
|
472
487
|
const chainId = chain.id;
|
473
488
|
try {
|
474
|
-
provider
|
489
|
+
const namespaceChains = getNamespaceChainsIds(provider);
|
490
|
+
const namespaceMethods = getNamespaceMethods(provider);
|
491
|
+
const isChainApproved = namespaceChains.includes(chainId);
|
492
|
+
|
493
|
+
if (!isChainApproved && namespaceMethods.includes(ADD_ETH_CHAIN_METHOD)) {
|
494
|
+
const apiChain = await getChainMetadata(chain);
|
495
|
+
|
496
|
+
const blockExplorerUrls = [
|
497
|
+
...new Set([
|
498
|
+
...(chain.blockExplorers?.map((x) => x.url) || []),
|
499
|
+
...(apiChain.explorers?.map((x) => x.url) || []),
|
500
|
+
]),
|
501
|
+
];
|
502
|
+
|
503
|
+
await provider.request({
|
504
|
+
method: ADD_ETH_CHAIN_METHOD,
|
505
|
+
params: [
|
506
|
+
{
|
507
|
+
blockExplorerUrls:
|
508
|
+
blockExplorerUrls.length > 0 ? blockExplorerUrls : undefined,
|
509
|
+
chainId: numberToHex(apiChain.chainId),
|
510
|
+
chainName: apiChain.name,
|
511
|
+
nativeCurrency: apiChain.nativeCurrency, // no clientId on purpose
|
512
|
+
rpcUrls: getValidPublicRPCUrl(apiChain),
|
513
|
+
},
|
514
|
+
],
|
515
|
+
});
|
516
|
+
const requestedChains = await getRequestedChainsIds(storage);
|
517
|
+
requestedChains.push(chainId);
|
518
|
+
setRequestedChainsIds(requestedChains, storage);
|
519
|
+
}
|
520
|
+
await provider.request({
|
521
|
+
method: "wallet_switchEthereumChain",
|
522
|
+
params: [{ chainId: numberToHex(chainId) }],
|
523
|
+
});
|
475
524
|
} catch (error) {
|
476
525
|
const message =
|
477
526
|
typeof error === "string" ? error : (error as ProviderRpcError)?.message;
|
@@ -494,23 +543,35 @@ function setRequestedChainsIds(
|
|
494
543
|
storage?.setItem(storageKeys.requestedChains, stringify(chains));
|
495
544
|
}
|
496
545
|
|
546
|
+
/**
|
547
|
+
* Get the last requested chains from the storage.
|
548
|
+
* @internal
|
549
|
+
*/
|
550
|
+
async function getRequestedChainsIds(storage: AsyncStorage): Promise<number[]> {
|
551
|
+
const data = await storage.getItem(storageKeys.requestedChains);
|
552
|
+
return data ? JSON.parse(data) : [];
|
553
|
+
}
|
554
|
+
|
555
|
+
type ArrayOneOrMore<T> = {
|
556
|
+
0: T;
|
557
|
+
} & Array<T>;
|
558
|
+
|
497
559
|
function getChainsToRequest(options: {
|
498
560
|
chain?: Chain;
|
499
561
|
optionalChains?: Chain[];
|
500
562
|
client: ThirdwebClient;
|
501
563
|
}): {
|
502
564
|
rpcMap: Record<number, string>;
|
503
|
-
|
565
|
+
requiredChain: Chain | undefined;
|
566
|
+
optionalChains: ArrayOneOrMore<number>;
|
504
567
|
} {
|
505
568
|
const rpcMap: Record<number, string> = {};
|
506
|
-
const chainIds: number[] = [];
|
507
569
|
|
508
570
|
if (options.chain) {
|
509
571
|
rpcMap[options.chain.id] = getRpcUrlForChain({
|
510
572
|
chain: options.chain,
|
511
573
|
client: options.client,
|
512
574
|
});
|
513
|
-
chainIds.push(options.chain.id);
|
514
575
|
}
|
515
576
|
|
516
577
|
// limit optional chains to 10
|
@@ -521,16 +582,18 @@ function getChainsToRequest(options: {
|
|
521
582
|
chain: chain,
|
522
583
|
client: options.client,
|
523
584
|
});
|
524
|
-
chainIds.push(chain.id);
|
525
585
|
}
|
526
586
|
|
527
587
|
if (!options.chain && optionalChains.length === 0) {
|
528
588
|
rpcMap[1] = getCachedChain(1).rpc;
|
529
|
-
chainIds.push(1);
|
530
589
|
}
|
531
590
|
|
532
591
|
return {
|
533
|
-
|
592
|
+
optionalChains:
|
593
|
+
optionalChains.length > 0
|
594
|
+
? (optionalChains.map((x) => x.id) as ArrayOneOrMore<number>)
|
595
|
+
: [1],
|
596
|
+
requiredChain: options.chain ? options.chain : undefined,
|
534
597
|
rpcMap,
|
535
598
|
};
|
536
599
|
}
|