diff --git a/.changeset/purple-books-pay.md b/.changeset/purple-books-pay.md new file mode 100644 index 0000000..dab62cf --- /dev/null +++ b/.changeset/purple-books-pay.md @@ -0,0 +1,5 @@ +--- +"@babylonlabs-io/bbn-wallet-connect": patch +--- + +add babylon wallet - leap diff --git a/package-lock.json b/package-lock.json index 8bffe5b..d58fad9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@babylonlabs-io/bbn-wallet-connect", - "version": "0.1.35", + "version": "0.1.38", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@babylonlabs-io/bbn-wallet-connect", - "version": "0.1.35", + "version": "0.1.38", "dependencies": { "@cosmjs/stargate": "^0.32.4", "@keplr-wallet/types": "^0.12.156", diff --git a/src/core/wallets/bbn/index.ts b/src/core/wallets/bbn/index.ts index 747a0c9..92e008a 100644 --- a/src/core/wallets/bbn/index.ts +++ b/src/core/wallets/bbn/index.ts @@ -3,12 +3,13 @@ import { BBNConfig, ChainMetadata, IBBNProvider } from "@/core/types"; import icon from "./babylon.jpeg"; import injectable from "./injectable"; import keplr from "./keplr"; +import leap from "./leap"; const metadata: ChainMetadata<"BBN", IBBNProvider, BBNConfig> = { chain: "BBN", name: "Babylon Chain", icon, - wallets: [injectable, keplr], + wallets: [injectable, keplr, leap], }; export default metadata; diff --git a/src/core/wallets/bbn/leap/index.ts b/src/core/wallets/bbn/leap/index.ts new file mode 100644 index 0000000..282d754 --- /dev/null +++ b/src/core/wallets/bbn/leap/index.ts @@ -0,0 +1,16 @@ +import { IBBNProvider, Network, type BBNConfig, type WalletMetadata } from "@/core/types"; + +import logo from "./logo.svg"; +import { LeapProvider, WALLET_PROVIDER_NAME } from "./provider"; + +const metadata: WalletMetadata = { + id: "leap", + name: WALLET_PROVIDER_NAME, + icon: logo, + docs: "https://www.leapwallet.io/", + wallet: "leap", + createProvider: (wallet, config) => new LeapProvider(wallet, config), + networks: [Network.MAINNET, Network.SIGNET], +}; + +export default metadata; diff --git a/src/core/wallets/bbn/leap/logo.svg b/src/core/wallets/bbn/leap/logo.svg new file mode 100644 index 0000000..66a23cf --- /dev/null +++ b/src/core/wallets/bbn/leap/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/core/wallets/bbn/leap/provider.ts b/src/core/wallets/bbn/leap/provider.ts new file mode 100644 index 0000000..dab1a2b --- /dev/null +++ b/src/core/wallets/bbn/leap/provider.ts @@ -0,0 +1,98 @@ +import { OfflineAminoSigner, OfflineDirectSigner } from "@keplr-wallet/types/src/cosmjs"; +import { Buffer } from "buffer"; + +import { BBNConfig, IBBNProvider, WalletInfo } from "@/core/types"; + +import logo from "./logo.svg"; + +export const WALLET_PROVIDER_NAME = "Leap"; + +export class LeapProvider implements IBBNProvider { + private walletInfo: WalletInfo | undefined; + private chainId: string | undefined; + private rpc: string | undefined; + private chainData: BBNConfig["chainData"]; + + constructor( + private wallet: any, + config: BBNConfig, + ) { + if (!wallet) { + throw new Error("Leap extension not found"); + } + this.chainId = config.chainId; + this.rpc = config.rpc; + this.chainData = config.chainData; + } + + async connectWallet(): Promise { + if (!this.chainId) throw new Error("Chain ID is not initialized"); + if (!this.rpc) throw new Error("RPC URL is not initialized"); + if (!this.wallet) throw new Error("Leap extension not found"); + + try { + await this.wallet.enable(this.chainId); + } catch (error: Error | any) { + if (error?.message.includes(this.chainId) || error?.message.includes("chain id")) { + try { + // User has no BBN chain in their wallet + await this.wallet.experimentalSuggestChain(this.chainData); + await this.wallet.enable(this.chainId); + } catch { + throw new Error("Failed to add BBN chain"); + } + } else { + if (error?.message.includes("rejected")) { + throw new Error("Leap wallet connection request rejected"); + } else if (error?.message.includes("context invalidated")) { + throw new Error("Leap extension context invalidated"); + } else { + throw new Error(error?.message || "Failed to connect to Leap"); + } + } + } + const key = await this.wallet.getKey(this.chainId); + + if (!key) throw new Error("Failed to get Leap key"); + + const { bech32Address, pubKey } = key; + + if (bech32Address && pubKey) { + this.walletInfo = { + publicKeyHex: Buffer.from(key.pubKey).toString("hex"), + address: bech32Address, + }; + } else { + throw new Error("Could not connect to Leap"); + } + } + + async getAddress(): Promise { + if (!this.walletInfo) throw new Error("Wallet not connected"); + return this.walletInfo.address; + } + + async getPublicKeyHex(): Promise { + if (!this.walletInfo) throw new Error("Wallet not connected"); + return this.walletInfo.publicKeyHex; + } + + async getWalletProviderName(): Promise { + return WALLET_PROVIDER_NAME; + } + + async getWalletProviderIcon(): Promise { + return logo; + } + + async getOfflineSigner(): Promise { + if (!this.wallet) throw new Error("Leap extension not found"); + if (!this.chainId) throw new Error("Chain ID is not initialized"); + + try { + return this.wallet.getOfflineSigner(this.chainId); + } catch { + throw new Error("Failed to get offline signer"); + } + } +} diff --git a/src/core/wallets/btc/unisat/provider.ts b/src/core/wallets/btc/unisat/provider.ts index 628cbf2..c215046 100644 --- a/src/core/wallets/btc/unisat/provider.ts +++ b/src/core/wallets/btc/unisat/provider.ts @@ -41,7 +41,6 @@ export class UnisatProvider implements IBTCProvider { } connectWallet = async (): Promise => { - console.log("new version 18"); let accounts; try { accounts = await this.provider.requestAccounts();