Skip to content

Commit 1fa2dba

Browse files
committed
spike: add dynamic fe wallet support
1 parent a1daf50 commit 1fa2dba

28 files changed

+3190
-429
lines changed

packages/demo/backend/src/config/verbs.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { Verbs, type VerbsConfig } from '@eth-optimism/verbs-sdk'
1+
import {
2+
createVerbs,
3+
type Verbs,
4+
type VerbsConfig,
5+
} from '@eth-optimism/verbs-sdk/node'
26
import { PrivyClient } from '@privy-io/server-auth'
37
import { baseSepolia, unichain } from 'viem/chains'
48

@@ -57,7 +61,7 @@ export function createVerbsConfig(): VerbsConfig<'privy'> {
5761

5862
export function initializeVerbs(config?: VerbsConfig<'privy'>): void {
5963
const verbsConfig = config || createVerbsConfig()
60-
verbsInstance = new Verbs(verbsConfig)
64+
verbsInstance = createVerbs(verbsConfig)
6165
}
6266

6367
export function getVerbs() {

packages/sdk/package.json

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,23 @@
1919
"src/*"
2020
],
2121
"exports": {
22-
".": "./dist/index.js"
22+
".": {
23+
"react": "./dist/index.react.js",
24+
"import": "./dist/index.node.js",
25+
"default": "./dist/index.node.js"
26+
},
27+
"./react": "./dist/index.react.js",
28+
"./node": "./dist/index.node.js"
29+
},
30+
"typesVersions": {
31+
"*": {
32+
"react": [
33+
"dist/index.react.d.ts"
34+
],
35+
"node": [
36+
"dist/index.node.d.ts"
37+
]
38+
}
2339
},
2440
"scripts": {
2541
"build": "tsc && resolve-tspaths",
@@ -47,6 +63,9 @@
4763
"viem": "^2.24.1"
4864
},
4965
"peerDependencies": {
66+
"@dynamic-labs/ethereum": ">=4.31.4",
67+
"@dynamic-labs/wallet-connector-core": ">=4.31.4",
68+
"@dynamic-labs/waas-evm": ">=4.31.4",
5069
"@privy-io/server-auth": ">=1.28.0"
5170
},
5271
"devDependencies": {

packages/sdk/src/index.node.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from '@/index.js'
2+
export { createVerbs } from '@/nodeVerbsFactory.js'
3+
export { PrivyWallet } from '@/wallet/PrivyWallet.js'
4+
export { PrivyHostedWalletProvider } from '@/wallet/providers/PrivyHostedWalletProvider.js'

packages/sdk/src/index.react.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from '@/index.js'
2+
export { createVerbs } from '@/reactVerbsFactory.js'

packages/sdk/src/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ export type {
2424
WalletConfig,
2525
} from '@/types/index.js'
2626
export { isAssetSupportedOnChain } from '@/utils/assets.js'
27-
export { Verbs } from '@/verbs.js'
27+
export type { Verbs } from '@/verbs.js'
2828
export { SmartWallet } from '@/wallet/base/SmartWallet.js'
2929
export { Wallet } from '@/wallet/base/Wallet.js'
30-
export { PrivyWallet } from '@/wallet/PrivyWallet.js'
31-
export { SmartWalletProvider } from '@/wallet/providers/base/SmartWalletProvider.js'
32-
export { PrivyHostedWalletProvider } from '@/wallet/providers/PrivyHostedWalletProvider.js'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { VerbsConfig } from '@/types/verbs.js'
2+
import { Verbs } from '@/verbs.js'
3+
import { NodeHostedWalletProviderRegistry } from '@/wallet/providers/NodeHostedWalletProviderRegistry.js'
4+
5+
/**
6+
* Creates a Node environment Verbs factory
7+
*
8+
* Creates a Verbs instance wired with the Node-specific HostedWalletProviderRegistry.
9+
* This ensures browser-only providers are never imported in Node,
10+
* avoiding runtime/module-resolution issues on the backend.
11+
* @param config Verbs configuration
12+
* @returns Verbs instance using the NodeHostedWalletProviderRegistry
13+
*/
14+
export function createVerbs(config: VerbsConfig<'privy'>) {
15+
return new Verbs(config, { registry: new NodeHostedWalletProviderRegistry() })
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { VerbsConfig } from '@/types/verbs.js'
2+
import { Verbs } from '@/verbs.js'
3+
import { ReactHostedWalletProviderRegistry } from '@/wallet/providers/ReactHostedWalletProviderRegistry.js'
4+
5+
/**
6+
* Creates a React/browser environment Verbs factory
7+
*
8+
* Creates a Verbs instance wired with the React-specific HostedWalletProviderRegistry.
9+
* This registry enables browser-only hosted providers and defers
10+
* their imports to the client environment to keep server builds clean.
11+
* @param config Verbs configuration
12+
* @returns Verbs instance using the ReactHostedWalletProviderRegistry
13+
*/
14+
export function createVerbs(config: VerbsConfig<'dynamic'>) {
15+
return new Verbs(config, {
16+
registry: new ReactHostedWalletProviderRegistry(),
17+
})
18+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { unichain } from 'viem/op-stack'
2+
import { vi } from 'vitest'
3+
4+
import type { ChainManager } from '@/services/ChainManager.js'
5+
import { MockChainManager } from '@/test/MockChainManager.js'
6+
import type { DynamicHostedWalletToVerbsWalletOptions } from '@/types/wallet.js'
7+
import type { Wallet } from '@/wallet/base/Wallet.js'
8+
import { HostedWalletProvider } from '@/wallet/providers/base/HostedWalletProvider.js'
9+
10+
/**
11+
* Minimal mock implementation matching the shape of HostedWalletProvider<'dynamic'>
12+
* for use in unit tests without importing browser-only dependencies.
13+
*/
14+
export class DynamicHostedWalletProviderMock extends HostedWalletProvider<'dynamic'> {
15+
// Exposed mock for assertions if needed
16+
public readonly toVerbsWalletMock = vi.fn(
17+
async (
18+
_params: DynamicHostedWalletToVerbsWalletOptions,
19+
): Promise<Wallet> => {
20+
return {} as unknown as Wallet
21+
},
22+
)
23+
24+
constructor() {
25+
const mockChainManager = new MockChainManager({
26+
supportedChains: [unichain.id],
27+
}) as unknown as ChainManager
28+
super(mockChainManager)
29+
}
30+
31+
async toVerbsWallet(
32+
params: DynamicHostedWalletToVerbsWalletOptions,
33+
): Promise<Wallet> {
34+
return this.toVerbsWalletMock(params)
35+
}
36+
}

packages/sdk/src/types/wallet.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Wallet as DynamicWallet } from '@dynamic-labs/wallet-connector-core'
12
import type { Address, LocalAccount } from 'viem'
23
import type { WebAuthnAccount } from 'viem/account-abstraction'
34

@@ -24,10 +25,18 @@ export type GetSmartWalletOptions = {
2425
}
2526

2627
/**
27-
* Options for converting a hosted wallet to a Verbs wallet
28+
* Options for converting a Privy hosted wallet to a Verbs wallet
2829
* @description Parameters for converting a hosted wallet to a Verbs wallet
2930
*/
30-
export type HostedWalletToVerbsWalletOptions = {
31+
export type PrivyHostedWalletToVerbsWalletOptions = {
3132
walletId: string
3233
address: string
3334
}
35+
36+
/**
37+
* Options for converting a Dynamic hosted wallet to a Verbs wallet
38+
* @description Parameters for converting a hosted wallet to a Verbs wallet
39+
*/
40+
export type DynamicHostedWalletToVerbsWalletOptions = {
41+
wallet: DynamicWallet
42+
}

0 commit comments

Comments
 (0)