Skip to content

Commit

Permalink
feat: add thirdweb wallet connector
Browse files Browse the repository at this point in the history
  • Loading branch information
vanya2h committed May 24, 2024
1 parent d18cbe0 commit 29d27bc
Show file tree
Hide file tree
Showing 28 changed files with 1,318 additions and 81 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ lerna-debug.log
.env.*
.yarnrc
.parcel-cache
*.pem
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"@rarible/prettier": "~0.10.0-alpha.37",
"@solana/web3.js": "~1.54.0",
"@types/jest": "^29.5.12",
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^7.10.0",
"@typescript-eslint/parser": "^7.10.0",
"cpy-cli": "^5.0.0",
Expand Down
55 changes: 55 additions & 0 deletions packages/connectors/evm/thirdweb/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "@rarible/connector-thirdweb",
"version": "0.13.68-fix.23",
"homepage": "https://docs.rarible.org/reference/getting-started",
"license": "ISC",
"exports": {
".": {
"types": {
"require": "./build/index.d.ts",
"import": "./esm/index.d.ts"
},
"require": "./build/index.js",
"import": "./esm/index.js",
"default": "./build/index.js"
},
"./package.json": "./package.json",
"./build/": "./build/",
"./esm/": "./esm/",
"./*": {
"types": {
"require": "./build/*.d.ts",
"import": "./esm/*.d.ts"
},
"require": "./build/*.js",
"import": "./esm/*.js",
"default": "./build/*.js"
}
},
"main": "./build/index.js",
"module": "./esm/index.js",
"types": "./build/index.d.ts",
"files": [
"build",
"esm"
],
"scripts": {
"build": "run-s build:*",
"build:cjs": "tsc --project tsconfig.cjs.json",
"build:esm": "tsc --project tsconfig.esm.json",
"clean": "run-s clean:*",
"clean:build": "rimraf ./build ./esm",
"clean:tsbuildinfo": "rimraf ./tsconfig.tsbuildinfo",
"verify": "tsc"
},
"dependencies": {
"@rarible/connector": "^0.13.68-fix.23",
"bignumber.js": "^9.1.2",
"thirdweb": "^5.24.0",
"tiny-typed-emitter": "^2.1.0"
},
"peerDependenciesMeta": {},
"publishConfig": {
"access": "public"
}
}
52 changes: 52 additions & 0 deletions packages/connectors/evm/thirdweb/src/domain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Chain, CreateThirdwebClientOptions, ThirdwebClient } from "thirdweb"
import type { WalletConnectionOption, WalletId } from "thirdweb/wallets"

export type ThirdwebWalletOptionsExtra<Id extends WalletId> = Omit<WalletConnectionOption<Id>, "client" | "chain">

export type ThirdwebChainOrChainId =
| {
/**
* Most chains should be supported. Whole list see below
* @see https://thirdweb.com/chainlist
*
* otherwise you might want to use `chain` prop
*/
chainId: number
}
| {
/**
* Provide chain with RPC nodes and other meta
* information (useful for custom and rare chains)
*/
chain: Chain
}

export type ThirdwebProviderConfig<Id extends WalletId> = (
| {
/**
* pass explicit client to be used, it may reduce fetch time
* on client side.
*
* @note Supports thirdweb v5 client
*/
client: ThirdwebClient
}
| CreateThirdwebClientOptions
) & {
/**
* If you don't support thirdweb v5 in your project
* then pass explicit options to setup a connection with thirdweb.
*
* Otherwise (in case you use thirdweb v5) you may re-use
* your existing client by passing `client`
*/
options: ThirdwebWalletOptionsExtra<Id>
/**
* Pass `chainId` or `chain` object to select default chain
* List of supported chains you may find on the link below
* @see https://thirdweb.com/chainlist
*
* Pass `chainId` or `chain` object
*/
defaultChain?: ThirdwebChainOrChainId
}
3 changes: 3 additions & 0 deletions packages/connectors/evm/thirdweb/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./provider"
export * from "./to-eip-1193"
export * from "./domain"
86 changes: 86 additions & 0 deletions packages/connectors/evm/thirdweb/src/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { startWith, map, switchMap, shareReplay, first } from "rxjs/operators"
import type { Wallet, WalletId } from "thirdweb/wallets"
import { createThirdwebClient } from "thirdweb"
import { AbstractConnectionProvider, connectToWeb3, getStateConnecting } from "@rarible/connector"
import type { EthereumProviderConnectionResult } from "@rarible/connector"
import type { Observable } from "rxjs"
import { from, of } from "rxjs"
import type { InAppWalletCreationOptions } from "thirdweb/dist/types/wallets/in-app/core/wallet/types"
import type { ThirdwebProviderConfig } from "./domain"
import { EIP1193ProviderAdapter } from "./to-eip-1193"

const PROVIDER_ID = "thirdweb" as const

export class ThirdwebBaseProvider<Id extends WalletId> extends AbstractConnectionProvider<
ThirdwebProviderId<Id>,
EthereumProviderConnectionResult
> {
protected readonly client = getClient(this.config)

protected readonly adapter$ = this.wallet$.pipe(
map(wallet => new EIP1193ProviderAdapter(this.config.defaultChain, this.client, wallet, this.config.options)),
shareReplay(1),
)

private readonly connection$ = this.adapter$.pipe(
switchMap(adapter =>
from(adapter.enable()).pipe(
switchMap(() =>
connectToWeb3(adapter, {
disconnect: () => adapter.wallet.disconnect(),
}),
),
),
),
startWith(
getStateConnecting({
providerId: PROVIDER_ID,
}),
),
)

constructor(
private readonly id: Id,
private readonly config: ThirdwebProviderConfig<Id>,
private readonly wallet$: Observable<Wallet<Id>>,
) {
super()
}

getId = () => PROVIDER_ID

getConnection = () => this.connection$

isAutoConnected = async () => false

getOption = async () => getProviderId(this.id)

isConnected = async () => {
const adapter = await this.adapter$.pipe(first()).toPromise()
return Boolean(adapter.wallet.getAccount())
}
}

export class ThirdwebInAppProvider extends ThirdwebBaseProvider<"inApp"> {
constructor(config: ThirdwebProviderConfig<"inApp">, options: InAppWalletCreationOptions = {}) {
super(
"inApp",
config,
of(null).pipe(
switchMap(() => import("thirdweb/wallets")),
map(x => x.createWallet("inApp", options)),
shareReplay(1),
),
)
}
}

type ThirdwebProviderId<T extends WalletId> = `thirdweb-${T}`
function getProviderId<T extends WalletId>(id: T): ThirdwebProviderId<T> {
return `thirdweb-${id}`
}

function getClient(config: ThirdwebProviderConfig<WalletId>) {
if ("client" in config) return config.client
return createThirdwebClient(config)
}
Loading

0 comments on commit 29d27bc

Please sign in to comment.