Skip to content

Commit b54ca2e

Browse files
feat: Add wagmi adapter for in-app wallet
1 parent 0aa2416 commit b54ca2e

File tree

8 files changed

+316
-5
lines changed

8 files changed

+316
-5
lines changed

packages/wagmi-adapter/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Wagmi Adapter
2+
3+
This package enables the use of thirdweb's in-app wallets with wagmi.

packages/wagmi-adapter/package.json

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"name": "@thirdweb-dev/wagmi-adapter",
3+
"version": "1.0.0",
4+
"repository": {
5+
"type": "git",
6+
"url": "git+https://github.com/thirdweb-dev/js.git#main"
7+
},
8+
"license": "Apache-2.0",
9+
"bugs": {
10+
"url": "https://github.com/thirdweb-dev/js/issues"
11+
},
12+
"author": "thirdweb eng <eng@thirdweb.com>",
13+
"type": "module",
14+
"main": "./dist/cjs/exports/thirdweb.js",
15+
"module": "./dist/esm/exports/thirdweb.js",
16+
"types": "./dist/types/exports/thirdweb.d.ts",
17+
"typings": "./dist/types/exports/thirdweb.d.ts",
18+
"exports": {
19+
".": {
20+
"types": "./dist/types/exports/thirdweb.d.ts",
21+
"import": "./dist/esm/exports/thirdweb.js",
22+
"default": "./dist/cjs/exports/thirdweb.js"
23+
},
24+
"./package.json": "./package.json"
25+
},
26+
"files": ["dist/*", "src/*"],
27+
"dependencies": {},
28+
"devDependencies": {
29+
"@wagmi/core": "2.15.2",
30+
"thirdweb": "workspace:*",
31+
"rimraf": "6.0.1"
32+
},
33+
"peerDependencies": {
34+
"@wagmi/core": "^2",
35+
"thirdweb": "^5",
36+
"typescript": ">=5.0.4"
37+
},
38+
"peerDependenciesMeta": {
39+
"typescript": {
40+
"optional": true
41+
}
42+
},
43+
"scripts": {
44+
"format": "biome format ./src --write",
45+
"lint": "biome check ./src",
46+
"fix": "biome check ./src --fix",
47+
"build": "pnpm clean && pnpm build:cjs && pnpm build:esm && pnpm build:types",
48+
"build:cjs": "tsc --project ./tsconfig.build.json --module commonjs --outDir ./dist/cjs --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
49+
"build:esm": "tsc --project ./tsconfig.build.json --module es2020 --outDir ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
50+
"build:types": "tsc --project ./tsconfig.build.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
51+
"clean": "rimraf dist"
52+
},
53+
"engines": {
54+
"node": ">=18"
55+
}
56+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { type CreateConnectorFn, createConnector } from "@wagmi/core";
2+
import type { Prettify } from "@wagmi/core/chains";
3+
import { createThirdwebClient, defineChain, getAddress } from "thirdweb";
4+
import {
5+
EIP1193,
6+
type InAppWalletConnectionOptions,
7+
ecosystemWallet,
8+
inAppWallet as thirdwebInAppWallet,
9+
} from "thirdweb/wallets";
10+
import type { InAppWalletCreationOptions } from "thirdweb/wallets/in-app";
11+
12+
export type InAppWalletParameters = Prettify<
13+
Omit<InAppWalletConnectionOptions, "client"> &
14+
InAppWalletCreationOptions & {
15+
clientId: string;
16+
ecosystemId?: `ecosystem.${string}`;
17+
}
18+
>;
19+
20+
/**
21+
* Connect to an in-app wallet using the auth strategy of your choice.
22+
* @param args - Options for the in-app wallet connection.
23+
* @returns A wagmi connector.
24+
* @example
25+
* ```ts
26+
* import { http, createConfig } from "wagmi";
27+
* import { inAppWalletConnector } from "@thirdweb-rev/wagmi-adapter";
28+
*
29+
* export const config = createConfig({
30+
* chains: [sepolia],
31+
* connectors: [
32+
* inAppWalletConnector({
33+
* clientId: "...",
34+
* strategy: "google",
35+
* }),
36+
* ],
37+
* transports: {
38+
* [sepolia.id]: http(),
39+
* },
40+
* });
41+
* ```
42+
*/
43+
export function inAppWalletConnector(
44+
args: InAppWalletParameters,
45+
): CreateConnectorFn {
46+
const client = createThirdwebClient({ clientId: args.clientId });
47+
const wallet = args.ecosystemId
48+
? ecosystemWallet(args.ecosystemId, { partnerId: args.partnerId })
49+
: thirdwebInAppWallet(args);
50+
return createConnector((config) => ({
51+
id: "in-app-wallet",
52+
name: "In-App wallet",
53+
type: "in-app",
54+
connect: async (params) => {
55+
const chain = defineChain(params?.chainId || 1);
56+
const options = {
57+
client,
58+
chain,
59+
...args,
60+
} as unknown as InAppWalletConnectionOptions;
61+
const account = params?.isReconnecting
62+
? await wallet.autoConnect({
63+
client,
64+
chain,
65+
})
66+
: await wallet.connect(options);
67+
return { accounts: [getAddress(account.address)], chainId: chain.id };
68+
},
69+
disconnect: async () => {
70+
await wallet.disconnect();
71+
},
72+
getAccounts: async () => {
73+
const account = wallet.getAccount();
74+
if (!account) {
75+
throw new Error("Wallet not connected");
76+
}
77+
return [getAddress(account.address)];
78+
},
79+
getChainId: async () => {
80+
return wallet.getChain()?.id || 1;
81+
},
82+
getProvider: async (params) => {
83+
return EIP1193.toProvider({
84+
wallet,
85+
client,
86+
chain: wallet.getChain() || defineChain(params?.chainId || 1),
87+
});
88+
},
89+
isAuthorized: async () => true,
90+
switchChain: async (params) => {
91+
const chain = config.chains.find((x) => x.id === params.chainId);
92+
if (!chain) {
93+
throw new Error(`Chain ${params.chainId} not supported`);
94+
}
95+
await wallet.switchChain(defineChain(chain.id));
96+
return chain;
97+
},
98+
onAccountsChanged: () => {
99+
// no-op
100+
},
101+
onChainChanged: () => {
102+
// no-op
103+
},
104+
onDisconnect: () => {
105+
// no-op
106+
},
107+
}));
108+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { inAppWalletConnector, type InAppWalletParameters } from "../connector.js";
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
// This tsconfig file contains the shared config for the build (tsconfig.build.json) and type checking (tsconfig.json) config.
3+
"include": [],
4+
"compilerOptions": {
5+
// Incremental builds
6+
// NOTE: Enabling incremental builds speeds up `tsc`. Keep in mind though that it does not reliably bust the cache when the `tsconfig.json` file changes.
7+
"incremental": false,
8+
9+
// Type checking
10+
"strict": true,
11+
"useDefineForClassFields": true, // Not enabled by default in `strict` mode unless we bump `target` to ES2022.
12+
"noFallthroughCasesInSwitch": true, // Not enabled by default in `strict` mode.
13+
"noImplicitReturns": true, // Not enabled by default in `strict` mode.
14+
"useUnknownInCatchVariables": true, // TODO: This would normally be enabled in `strict` mode but would require some adjustments to the codebase.
15+
"noImplicitOverride": true, // Not enabled by default in `strict` mode.
16+
"noUnusedLocals": true, // Not enabled by default in `strict` mode.
17+
"noUnusedParameters": true, // Not enabled by default in `strict` mode.
18+
"exactOptionalPropertyTypes": false, // Not enabled by default in `strict` mode.
19+
"noUncheckedIndexedAccess": true, // Not enabled by default in `strict` mode.
20+
21+
// JavaScript support
22+
"allowJs": false,
23+
"checkJs": false,
24+
25+
// Interop constraints
26+
"esModuleInterop": false,
27+
"allowSyntheticDefaultImports": true,
28+
"forceConsistentCasingInFileNames": true,
29+
"verbatimModuleSyntax": true,
30+
"importHelpers": true, // This is only used for build validation. Since we do not have `tslib` installed, this will fail if we accidentally make use of anything that'd require injection of helpers.
31+
32+
// Language and environment
33+
"moduleResolution": "NodeNext",
34+
"module": "NodeNext",
35+
"target": "ES2021", // Setting this to `ES2021` enables native support for `Node v16+`: https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping.
36+
"lib": [
37+
"ES2022", // By using ES2022 we get access to the `.cause` property on `Error` instances.
38+
"DOM" // We are adding `DOM` here to get the `fetch`, etc. types. This should be removed once these types are available via DefinitelyTyped.
39+
],
40+
41+
// Skip type checking for node modules
42+
"skipLibCheck": true,
43+
44+
// jsx for "/react" portion
45+
"jsx": "react-jsx"
46+
}
47+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"include": ["src"],
4+
"exclude": [
5+
"src/**/*.test.ts",
6+
"src/**/*.test.tsx",
7+
"src/**/*.test-d.ts",
8+
"src/**/*.bench.ts",
9+
"src/**/*.macro.ts"
10+
],
11+
"compilerOptions": {
12+
"moduleResolution": "node",
13+
"sourceMap": true,
14+
"rootDir": "./src"
15+
}
16+
}

packages/wagmi-adapter/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
// This configuration is used for local development and type checking.
3+
"extends": "./tsconfig.base.json",
4+
"include": ["src", "test"],
5+
"exclude": [],
6+
// "references": [{ "path": "./scripts/tsconfig.json" }],
7+
"compilerOptions": {
8+
"baseUrl": ".",
9+
"paths": {
10+
"~test/*": ["./test/src/*"]
11+
}
12+
}
13+
}

pnpm-lock.yaml

Lines changed: 72 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)