Skip to content

Commit 9b99e0f

Browse files
eth wallet integration (#279)
* feat(packages): eth wallet integration --------- Co-authored-by: Govard Barkhatov <[email protected]>
1 parent 8d99d18 commit 9b99e0f

File tree

31 files changed

+21714
-22528
lines changed

31 files changed

+21714
-22528
lines changed

package-lock.json

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

packages/babylon-wallet-connector/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,18 @@
5555
"@ledgerhq/hw-transport": "6.31.10",
5656
"@ledgerhq/hw-transport-webhid": "6.30.6",
5757
"@ledgerhq/hw-transport-webusb": "6.29.10",
58+
"@reown/appkit": "1.8.6",
59+
"@reown/appkit-adapter-wagmi": "1.8.6",
5860
"@tomo-inc/ledger-bitcoin-babylon": "0.3.5-alpha.0",
5961
"@tomo-inc/wallet-connect-sdk": "0.3.24",
6062
"bip174": "2.1.1",
6163
"bitcoinjs-lib": "6.1.5",
6264
"buffer": "6.0.3",
6365
"nanoevents": "9.1.0",
6466
"usehooks-ts": "3.0.2",
65-
"uuid": "11.1.0"
67+
"uuid": "11.1.0",
68+
"viem": "2.37.7",
69+
"wagmi": "2.17.0"
6670
},
6771
"files": [
6872
"dist"

packages/babylon-wallet-connector/src/components/WalletProvider/constants.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,18 @@ export const config: ChainConfigArr = [
4040
chainData: bbnTestnet,
4141
},
4242
},
43+
{
44+
chain: "ETH",
45+
config: {
46+
chainId: 31337, // Anvil local node
47+
chainName: "Anvil Local",
48+
rpcUrl: "http://127.0.0.1:8545",
49+
explorerUrl: "http://localhost:8545",
50+
nativeCurrency: {
51+
name: "Ether",
52+
symbol: "ETH",
53+
decimals: 18,
54+
},
55+
},
56+
},
4357
];

packages/babylon-wallet-connector/src/components/WalletProvider/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface WalletProviderProps {
1919
config: Readonly<ChainConfigArr>;
2020
onError?: (e: Error) => void;
2121
disabledWallets?: string[];
22-
requiredChains?: ("BTC" | "BBN")[];
22+
requiredChains?: ("BTC" | "BBN" | "ETH")[];
2323
}
2424

2525
export function WalletProvider({

packages/babylon-wallet-connector/src/context/Chain.context.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import { WalletConnector } from "@/core/WalletConnector";
55
import type {
66
BBNConfig,
77
BTCConfig,
8+
ETHConfig,
89
ExternalConnector,
910
HashMap,
1011
IBBNProvider,
1112
IBTCProvider,
13+
IETHProvider,
1214
IProvider,
1315
} from "@/core/types";
1416
import metadata from "@/core/wallets";
@@ -27,6 +29,7 @@ interface ChainConfig<K extends string = string, P extends IProvider = IProvider
2729
export type ChainConfigArr = (
2830
| ChainConfig<"BTC", IBTCProvider, BTCConfig>
2931
| ChainConfig<"BBN", IBBNProvider, BBNConfig>
32+
| ChainConfig<"ETH", IETHProvider, ETHConfig>
3033
)[];
3134

3235
interface ProviderProps {
@@ -36,17 +39,19 @@ interface ProviderProps {
3639
config: Readonly<ChainConfigArr>;
3740
onError?: (e: Error) => void;
3841
disabledWallets?: string[];
39-
requiredChains?: ("BTC" | "BBN")[];
42+
requiredChains?: ("BTC" | "BBN" | "ETH")[];
4043
}
4144

4245
export interface Connectors {
4346
BTC: WalletConnector<"BTC", IBTCProvider, BTCConfig> | null;
4447
BBN: WalletConnector<"BBN", IBBNProvider, BBNConfig> | null;
48+
ETH: WalletConnector<"ETH", IETHProvider, ETHConfig> | null;
4549
}
4650

4751
const defaultState: Connectors = {
4852
BTC: null,
4953
BBN: null,
54+
ETH: null,
5055
};
5156

5257
export const Context = createContext<Connectors>(defaultState);
@@ -93,7 +98,7 @@ export function ChainProvider({
9398
const visibleChains = useMemo(
9499
() =>
95100
requiredChains && requiredChains.length
96-
? supportedChains.filter((chain) => requiredChains.includes(chain!.id as "BTC" | "BBN"))
101+
? supportedChains.filter((chain) => requiredChains.includes(chain!.id as "BTC" | "BBN" | "ETH"))
97102
: supportedChains,
98103
[supportedChains, requiredChains],
99104
);

packages/babylon-wallet-connector/src/context/TomoProvider.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { TomoContextProvider } from "@tomo-inc/wallet-connect-sdk";
22
import "@tomo-inc/wallet-connect-sdk/style.css";
33
import { useMemo, type PropsWithChildren } from "react";
44

5-
import { BBNConfig, BTCConfig } from "@/core/types";
5+
import { BBNConfig, BTCConfig, ETHConfig } from "@/core/types";
66

77
import { ChainConfigArr } from "./Chain.context";
88

@@ -32,6 +32,15 @@ const CONFIG_ADAPTERS = {
3232
},
3333
logo: config.chainData.chainSymbolImageUrl,
3434
}),
35+
ETH: (config: ETHConfig) => ({
36+
id: 3,
37+
name: config.chainName,
38+
type: "ethereum",
39+
chainId: config.chainId,
40+
rpcUrl: config.rpcUrl,
41+
explorerUrl: config.explorerUrl,
42+
nativeCurrency: config.nativeCurrency,
43+
}),
3544
};
3645

3746
export const TomoConnectionProvider = ({ children, theme, config }: PropsWithChildren<TomoProviderProps>) => {

packages/babylon-wallet-connector/src/core/types.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,134 @@ export type BBNConfig = {
6262
coinSymbol: string;
6363
};
6464

65+
export interface ETHConfig {
66+
chainId: number;
67+
chainName: string;
68+
rpcUrl: string;
69+
explorerUrl: string;
70+
nativeCurrency: {
71+
name: string;
72+
symbol: string;
73+
decimals: number;
74+
};
75+
}
76+
77+
// Ethereum specific types
78+
export interface ETHTransactionRequest {
79+
to: string;
80+
value?: string;
81+
data?: string;
82+
gasLimit?: bigint;
83+
maxFeePerGas?: bigint;
84+
maxPriorityFeePerGas?: bigint;
85+
nonce?: number;
86+
}
87+
88+
export interface ETHTypedData {
89+
domain: {
90+
name?: string;
91+
version?: string;
92+
chainId?: number;
93+
verifyingContract?: string;
94+
salt?: string;
95+
};
96+
types: Record<string, Array<{ name: string; type: string }>>;
97+
primaryType: string;
98+
message: Record<string, any>;
99+
}
100+
101+
export interface NetworkInfo {
102+
name: string;
103+
chainId: string;
104+
}
105+
106+
export interface IETHProvider extends IProvider {
107+
/**
108+
* Signs a human-readable message using personal_sign
109+
* @param message - The message to sign
110+
* @returns A promise that resolves to the signature
111+
*/
112+
signMessage(message: string): Promise<string>;
113+
114+
/**
115+
* Signs structured data using eth_signTypedData_v4 (EIP-712)
116+
* @param typedData - The structured data to sign
117+
* @returns A promise that resolves to the signature
118+
*/
119+
signTypedData(typedData: ETHTypedData): Promise<string>;
120+
121+
/**
122+
* Sends a transaction to the blockchain
123+
* @param tx - The transaction request
124+
* @returns A promise that resolves to the transaction hash
125+
*/
126+
sendTransaction(tx: ETHTransactionRequest): Promise<string>;
127+
128+
/**
129+
* Estimates gas for a transaction
130+
* @param tx - The transaction request
131+
* @returns A promise that resolves to the estimated gas
132+
*/
133+
estimateGas(tx: ETHTransactionRequest): Promise<bigint>;
134+
135+
/**
136+
* Gets the current chain ID
137+
* @returns A promise that resolves to the chain ID
138+
*/
139+
getChainId(): Promise<number>;
140+
141+
/**
142+
* Switches to a different chain
143+
* @param chainId - The chain ID to switch to
144+
* @returns A promise that resolves when the switch is complete
145+
*/
146+
switchChain(chainId: number): Promise<void>;
147+
148+
/**
149+
* Gets the account balance
150+
* @returns A promise that resolves to the balance in wei
151+
*/
152+
getBalance(): Promise<bigint>;
153+
154+
/**
155+
* Gets the account nonce
156+
* @returns A promise that resolves to the nonce
157+
*/
158+
getNonce(): Promise<number>;
159+
160+
/**
161+
* Gets network information
162+
* @returns A promise that resolves to network info
163+
*/
164+
getNetworkInfo(): Promise<NetworkInfo>;
165+
166+
/**
167+
* Gets the wallet provider name
168+
* @returns The name of the wallet provider
169+
*/
170+
getWalletProviderName(): string;
171+
172+
/**
173+
* Gets the wallet provider icon
174+
* @returns The icon of the wallet provider
175+
*/
176+
getWalletProviderIcon(): string;
177+
178+
/**
179+
* Registers an event listener for the specified event
180+
* @param eventName - The name of the event to listen for
181+
* @param handler - The callback function to be executed when the event occurs
182+
*/
183+
on(eventName: string, handler: Function): void;
184+
185+
/**
186+
* Unregisters an event listener for the specified event
187+
* @param eventName - The name of the event to listen for
188+
* @param handler - The callback function to be executed when the event occurs
189+
*/
190+
off(eventName: string, handler: Function): void;
191+
}
192+
65193
export interface IProvider {
66194
connectWallet: () => Promise<void>;
67195
getAddress: () => Promise<string>;

packages/babylon-wallet-connector/src/core/wallets/btc/ledger/provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import Transport from "@ledgerhq/hw-transport";
22
import TransportWebHID from "@ledgerhq/hw-transport-webhid";
33
import TransportWebUSB from "@ledgerhq/hw-transport-webusb";
44
import { Transaction } from "@scure/btc-signer";
5-
import { Buffer } from "buffer";
65
import AppClient, { DefaultWalletPolicy, signMessage, signPsbt } from "@tomo-inc/ledger-bitcoin-babylon";
6+
import { Buffer } from "buffer";
77

88
import type { BTCConfig, InscriptionIdentifier, SignPsbtOptions } from "@/core/types";
99
import { IBTCProvider, Network } from "@/core/types";
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { createConfig, http } from "wagmi";
2+
import { mainnet, sepolia, localhost } from "wagmi/chains";
3+
4+
/**
5+
* Fallback wagmi configuration
6+
*
7+
* This config is used when no shared wagmi config is provided by the application.
8+
* It supports:
9+
* - Ethereum Mainnet (chainId: 1)
10+
* - Sepolia Testnet (chainId: 11155111)
11+
* - Localhost/Anvil (chainId: 31337)
12+
*/
13+
export const wagmiConfig = createConfig({
14+
chains: [mainnet, sepolia, localhost],
15+
transports: {
16+
[mainnet.id]: http(),
17+
[sepolia.id]: http(),
18+
[localhost.id]: http("http://127.0.0.1:8545"), // Default Anvil RPC URL
19+
},
20+
});
21+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { ETHConfig, IETHProvider, WalletMetadata } from "@/core/types";
2+
import { Network } from "@/core/types";
3+
import { AppKitProvider } from "./provider";
4+
5+
const WALLET_PROVIDER_NAME = "AppKit";
6+
7+
/**
8+
* AppKit wallet metadata for ETH chain
9+
*
10+
* Provides connection to 600+ Ethereum wallets through Reown's AppKit:
11+
* - MetaMask, Rainbow, WalletConnect, Coinbase Wallet, Trust Wallet, etc.
12+
* - Browser extension wallets (EIP-6963)
13+
* - Mobile wallets via WalletConnect
14+
* - Hardware wallets (Ledger, Trezor)
15+
*/
16+
const metadata: WalletMetadata<IETHProvider, ETHConfig> = {
17+
id: "appkit-eth-connector",
18+
name: WALLET_PROVIDER_NAME,
19+
icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzYyN0VFQSIvPgogIDxwYXRoIGQ9Ik0xNiA0TDcuNSAxNi4yNUwxNiAyMkwyNC41IDE2LjI1TDE2IDR6IiBmaWxsPSJ3aGl0ZSIvPgogIDxwYXRoIGQ9Ik0xNiAyMi43NUw3LjUgMTdMMTYgMjhMMjQuNSAxN0wxNiAyMi43NXoiIGZpbGw9IndoaXRlIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8L3N2Zz4=",
20+
docs: "https://docs.reown.com/appkit/overview",
21+
wallet: "ethereum", // Global identifier for Ethereum providers
22+
createProvider: (_wallet: any, config: ETHConfig) => new AppKitProvider(config),
23+
networks: [
24+
Network.MAINNET, // ETH mainnet (chainId: 1)
25+
Network.TESTNET, // ETH testnet (chainId: 11155111 - Sepolia)
26+
],
27+
label: "Connect ETH Wallet",
28+
};
29+
30+
export default metadata;

0 commit comments

Comments
 (0)