Skip to content

Commit d40d02c

Browse files
abstract wallet support
1 parent 46d0b4b commit d40d02c

File tree

35 files changed

+3259
-613
lines changed

35 files changed

+3259
-613
lines changed
65.3 KB
Loading

packages/thirdweb/scripts/wallets/extra-wallets.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,33 @@
9191
"native": null,
9292
"universal": null
9393
}
94+
},
95+
{
96+
"id": "abstract",
97+
"name": "Abstract Global Wallet",
98+
"homepage": "https://abs.xyz/",
99+
"image_id": "abstract.png",
100+
"app": {
101+
"browser": null,
102+
"ios": null,
103+
"android": null,
104+
"mac": null,
105+
"windows": null,
106+
"linux": null,
107+
"chrome": null,
108+
"firefox": null,
109+
"safari": null,
110+
"edge": null,
111+
"opera": null
112+
},
113+
"rdns": "xyz.abs",
114+
"mobile": {
115+
"native": null,
116+
"universal": null
117+
},
118+
"desktop": {
119+
"native": null,
120+
"universal": null
121+
}
94122
}
95123
]
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import type { EIP1193Provider } from "viem";
2+
import { trackConnect } from "../analytics/track/connect.js";
3+
import type { Chain } from "../chains/types.js";
4+
import { getCachedChainIfExists } from "../chains/utils.js";
5+
import type { ThirdwebClient } from "../client/client.js";
6+
import {} from "../utils/address.js";
7+
import {} from "../utils/encoding/hex.js";
8+
import {
9+
autoConnectEip1193Wallet,
10+
connectEip1193Wallet,
11+
} from "../wallets/injected/index.js";
12+
import type { Account, Wallet } from "../wallets/interfaces/wallet.js";
13+
import { createWalletEmitter } from "../wallets/wallet-emitter.js";
14+
import type { WalletId } from "../wallets/wallet-types.js";
15+
16+
export type Eip1193AdapterOptions = {
17+
client: ThirdwebClient;
18+
provider: EIP1193Provider | (() => Promise<EIP1193Provider>);
19+
walletId?: WalletId;
20+
chain?: Chain;
21+
};
22+
23+
/**
24+
* Converts an EIP1193 provider to a Thirdweb wallet.
25+
* @param options - The options for converting an EIP1193 provider to a Thirdweb wallet.
26+
* @returns A Thirdweb wallet.
27+
* @example
28+
* ```ts
29+
* import { fromEip1193Provider } from "thirdweb/wallets";
30+
* const wallet = fromEip1193Provider({ provider, client, walletId });
31+
* ```
32+
* @walletUtils
33+
*/
34+
export function fromEip1193Provider(options: Eip1193AdapterOptions): Wallet {
35+
const id: WalletId = options.walletId ?? "adapter";
36+
const emitter = createWalletEmitter();
37+
let account: Account | undefined = undefined;
38+
let chain: Chain | undefined = undefined;
39+
let provider: EIP1193Provider | undefined = undefined;
40+
const getProvider = async () => {
41+
if (!provider) {
42+
provider =
43+
typeof options.provider === "function"
44+
? await options.provider()
45+
: options.provider;
46+
}
47+
return provider;
48+
};
49+
50+
const unsubscribeChain = emitter.subscribe("chainChanged", (newChain) => {
51+
chain = newChain;
52+
});
53+
54+
function reset() {
55+
account = undefined;
56+
chain = undefined;
57+
}
58+
59+
let handleDisconnect = async () => {};
60+
61+
const unsubscribeDisconnect = emitter.subscribe("disconnect", () => {
62+
reset();
63+
unsubscribeChain();
64+
unsubscribeDisconnect();
65+
});
66+
67+
emitter.subscribe("accountChanged", (_account) => {
68+
account = _account;
69+
});
70+
71+
let handleSwitchChain: (chain: Chain) => Promise<void> = async () => {
72+
throw new Error("Not implemented");
73+
};
74+
75+
return {
76+
id: options.walletId as WalletId,
77+
subscribe: emitter.subscribe,
78+
getConfig: () => undefined,
79+
getChain() {
80+
if (!chain) {
81+
return undefined;
82+
}
83+
84+
chain = getCachedChainIfExists(chain.id) || chain;
85+
return chain;
86+
},
87+
getAccount: () => account,
88+
connect: async () => {
89+
const [connectedAccount, connectedChain, doDisconnect, doSwitchChain] =
90+
await connectEip1193Wallet({
91+
id,
92+
provider: await getProvider(),
93+
client: options.client,
94+
chain: options.chain,
95+
emitter,
96+
});
97+
// set the states
98+
account = connectedAccount;
99+
chain = connectedChain;
100+
handleDisconnect = doDisconnect;
101+
handleSwitchChain = doSwitchChain;
102+
trackConnect({
103+
client: options.client,
104+
walletType: id,
105+
walletAddress: account.address,
106+
});
107+
// return account
108+
return account;
109+
},
110+
autoConnect: async () => {
111+
const [connectedAccount, connectedChain, doDisconnect, doSwitchChain] =
112+
await autoConnectEip1193Wallet({
113+
id,
114+
provider: await getProvider(),
115+
emitter,
116+
chain: options.chain,
117+
client: options.client,
118+
});
119+
// set the states
120+
account = connectedAccount;
121+
chain = connectedChain;
122+
handleDisconnect = doDisconnect;
123+
handleSwitchChain = doSwitchChain;
124+
trackConnect({
125+
client: options.client,
126+
walletType: id,
127+
walletAddress: account.address,
128+
});
129+
// return account
130+
return account;
131+
},
132+
disconnect: async () => {
133+
reset();
134+
await handleDisconnect();
135+
},
136+
switchChain: (c) => handleSwitchChain(c),
137+
};
138+
}

packages/thirdweb/src/analytics/track/transaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type TransactionEvent = {
99
ecosystem?: Ecosystem;
1010
transactionHash?: string;
1111
walletAddress?: string;
12-
walletType?: WalletId;
12+
walletType?: WalletId | ({} & string);
1313
chainId?: number;
1414
contractAddress?: string;
1515
functionName?: string;

packages/thirdweb/src/exports/wallets.native.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ export type {
134134
WalletConnectSession,
135135
} from "../wallets/wallet-connect/receiver/types.js";
136136

137+
// eip1193
138+
export { fromEip1193Provider } from "../adapters/eip1193-adapter.js";
139+
137140
// NOT SUPPORTED
138141

139142
export const injectedProvider = () => {

packages/thirdweb/src/exports/wallets.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ export type {
144144
WalletConnectSession,
145145
} from "../wallets/wallet-connect/receiver/types.js";
146146

147+
// eip1193
148+
export { fromEip1193Provider } from "../adapters/eip1193-adapter.js";
149+
147150
// WEB ONLY EXPORTS
148151

149152
// injected

packages/thirdweb/src/gas/fee-data.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { eth_getBlockByNumber } from "../rpc/actions/eth_getBlockByNumber.js";
44
import { eth_maxPriorityFeePerGas } from "../rpc/actions/eth_maxPriorityFeePerGas.js";
55
import { getRpcClient } from "../rpc/rpc.js";
66
import type { PreparedTransaction } from "../transaction/prepare-transaction.js";
7+
import { isZkSyncChain } from "../utils/any-evm/zksync/isZkSyncChain.js";
78
import { resolvePromisedValue } from "../utils/promise/resolve-promised-value.js";
89
import { toUnits } from "../utils/units.js";
910
import { getGasPrice } from "./get-gas-price.js";
@@ -70,6 +71,8 @@ export async function getGasOverridesForTransaction(
7071
transaction.chain,
7172
);
7273

74+
console.log("defaultGasOverrides", defaultGasOverrides);
75+
7376
if (transaction.chain.experimental?.increaseZeroByteCount) {
7477
// otherwise adjust each value
7578
if (defaultGasOverrides.gasPrice) {
@@ -146,6 +149,9 @@ async function getDynamicFeeData(
146149

147150
const rpcRequest = getRpcClient({ client, chain });
148151

152+
if (await isZkSyncChain(chain)) {
153+
}
154+
149155
const [block, maxPriorityFeePerGas] = await Promise.all([
150156
eth_getBlockByNumber(rpcRequest, { blockTag: "latest" }),
151157
eth_maxPriorityFeePerGas(rpcRequest).catch(() => null),

packages/thirdweb/src/react/core/hooks/wallets/useAdminWallet.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useConnectedWallets } from "./useConnectedWallets.js";
55
* Get the admin wallet for the active wallet
66
* Useful for smart wallets to get the underlying personal account
77
* @returns The admin wallet for the active wallet, or the active wallet if it doesn't have an admin account
8+
* @walletConnection
89
*/
910
export function useAdminWallet() {
1011
const activeWallet = useActiveWallet();

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/AnyWalletConnectUI.tsx

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import type {
99
InjectedSupportedWalletIds,
1010
WCSupportedWalletIds,
1111
} from "../../../../../wallets/__generated__/wallet-ids.js";
12-
import { COINBASE } from "../../../../../wallets/constants.js";
1312
import { isEcosystemWallet } from "../../../../../wallets/ecosystem/is-ecosystem-wallet.js";
1413
import { getInstalledWalletProviders } from "../../../../../wallets/injected/mipdStore.js";
1514
import type { Wallet } from "../../../../../wallets/interfaces/wallet.js";
@@ -197,27 +196,6 @@ export function AnyWalletConnectUI(props: {
197196
);
198197
}
199198

200-
// coinbase wallet sdk
201-
if (props.wallet.id === COINBASE) {
202-
return (
203-
<Suspense fallback={<LoadingScreen />}>
204-
<CoinbaseSDKWalletConnectUI
205-
locale={locale}
206-
onGetStarted={() => {
207-
setScreen("get-started");
208-
}}
209-
onBack={props.onBack}
210-
done={props.done}
211-
wallet={props.wallet as Wallet<typeof COINBASE>}
212-
walletInfo={walletInfo.data}
213-
chain={props.chain}
214-
client={props.client}
215-
size={props.size}
216-
/>
217-
</Suspense>
218-
);
219-
}
220-
221199
// wallet connect
222200
if (walletInfo.data.mobile.native || walletInfo.data.mobile.universal) {
223201
return (
@@ -294,6 +272,27 @@ export function AnyWalletConnectUI(props: {
294272
);
295273
}
296274

275+
// coinbase wallet sdk
276+
if (props.wallet.id) {
277+
return (
278+
<Suspense fallback={<LoadingScreen />}>
279+
<CoinbaseSDKWalletConnectUI
280+
locale={locale}
281+
onGetStarted={() => {
282+
setScreen("get-started");
283+
}}
284+
onBack={props.onBack}
285+
done={props.done}
286+
wallet={props.wallet}
287+
walletInfo={walletInfo.data}
288+
chain={props.chain}
289+
client={props.client}
290+
size={props.size}
291+
/>
292+
</Suspense>
293+
);
294+
}
295+
297296
// if can't connect in any way - show get started screen
298297
return (
299298
<GetStartedScreen

packages/thirdweb/src/react/web/wallets/shared/CoinbaseSDKConnection.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { useCallback, useEffect, useRef, useState } from "react";
22
import type { Chain } from "../../../../chains/types.js";
33
import type { ThirdwebClient } from "../../../../client/client.js";
4-
import type { COINBASE } from "../../../../wallets/constants.js";
54
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
65
import type { WalletInfo } from "../../../../wallets/wallet-info.js";
76
import type { InjectedWalletLocale } from "../injected/locale/types.js";
@@ -10,12 +9,12 @@ import { ConnectingScreen } from "./ConnectingScreen.js";
109
/**
1110
* @internal
1211
*/
13-
function CoinbaseSDKWalletConnectUI(props: {
12+
function ExternalWalletConnectUI(props: {
1413
onBack?: () => void;
1514
onGetStarted: () => void;
1615
done: () => void;
1716
locale: InjectedWalletLocale;
18-
wallet: Wallet<typeof COINBASE>;
17+
wallet: Wallet;
1918
walletInfo: WalletInfo;
2019
client: ThirdwebClient;
2120
chain: Chain | undefined;
@@ -70,4 +69,4 @@ function CoinbaseSDKWalletConnectUI(props: {
7069
);
7170
}
7271

73-
export default CoinbaseSDKWalletConnectUI;
72+
export default ExternalWalletConnectUI;

0 commit comments

Comments
 (0)