From 72029802e0fe03093ed277c9b305e8bc49fe8e5f Mon Sep 17 00:00:00 2001 From: HoangVD2 <102846781+HoangVD2@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:21:43 +0700 Subject: [PATCH] docs: create content for Libraries Integration (#8) --- .vitepress/config.ts | 10 +- developers/blocknative-xdefi-integration.md | 27 ++ developers/cosmoskit-xdefi-integration.md | 43 +++ developers/introduction.md | 6 +- developers/libraries-integration.md | 10 + developers/rainbowkit-xdefi-integration.md | 122 +++++++ .../solana-adapter-xdefi-integration.md | 344 ++++++++++++++++++ 7 files changed, 554 insertions(+), 8 deletions(-) create mode 100644 developers/cosmoskit-xdefi-integration.md create mode 100644 developers/libraries-integration.md create mode 100644 developers/rainbowkit-xdefi-integration.md create mode 100644 developers/solana-adapter-xdefi-integration.md diff --git a/.vitepress/config.ts b/.vitepress/config.ts index ea001f0b0..7aa2fe90f 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -422,7 +422,7 @@ function sidebarHome() { collapsed: true, items: [ { - text: "XDEFI Wallet integration", + text: "XDEFI Wallet Integration", link: "/developers/xdefi-wallet-integration", collapsed: true, items: [ @@ -499,7 +499,7 @@ function sidebarHome() { ], }, { - text: "Blockhains Integration", + text: "Blockchains Integration", link: "/developers/blockchains-integration", collapsed: true, items: [ @@ -566,7 +566,7 @@ function sidebarHome() { ], }, { - text: "Libraries integration", + text: "Libraries Integration", link: "/developers/libraries-integration", collapsed: true, items: [ @@ -576,11 +576,11 @@ function sidebarHome() { link: "/developers/blocknative-xdefi-integration", }, { - text: "Cosmos Kit", + text: "CosmosKit", link: "/developers/cosmoskit-xdefi-integration", }, { - text: "Rainbowkit", + text: "RainbowKit", link: "/developers/rainbowkit-xdefi-integration", }, { diff --git a/developers/blocknative-xdefi-integration.md b/developers/blocknative-xdefi-integration.md index ff74bfea2..aff3d4c20 100644 --- a/developers/blocknative-xdefi-integration.md +++ b/developers/blocknative-xdefi-integration.md @@ -1 +1,28 @@ # BlockNative XDEFI Integration + +First, your app need to install the core Onboard library, the injected wallets module and optionally ethers js to support browser extension and mobile wallets: + +```bash +yarn add @web3-onboard/core @web3-onboard/injected-wallets ethers +``` + +Then initialize in your app: + +```javascript +import Onboard from "@web3-onboard/core"; +import xdefiWalletModule from "@web3-onboard/xdefi"; + +// initialize the module with options +const xdefiWalletSdk = xdefiWalletModule(); + +const onboard = Onboard({ + // ... other Onboard options + wallets: [ + xdefiWalletSdk(), + //... other wallets + ], +}); + +const connectedWallets = await onboard.connectWallet(); +console.log(connectedWallets); +``` diff --git a/developers/cosmoskit-xdefi-integration.md b/developers/cosmoskit-xdefi-integration.md new file mode 100644 index 000000000..a07d6a250 --- /dev/null +++ b/developers/cosmoskit-xdefi-integration.md @@ -0,0 +1,43 @@ +# CosmosKit XDEFI Integration + +First, your app need to install 2 packages for the XDEFI: + +- `@cosmos-kit/xdefi` +- `@cosmos-kit/xdefi-extension` + +`@cosmos-kit/xdefi` export all available xdefi wallets (currently only extension available), while if you only want to add a particular one, choose `@cosmos-kit/xdefi-extension` + +> Note: all these packages export `wallets` and it's an array of `MainWalletBase` + +Take `@cosmos-kit/xdefi` for example + +### add `@cosmos-kit/xdefi` + +```bash +yarn add @cosmos-kit/xdefi +``` + +### import the wallets + +```javascript +import { wallets as xdefi } from "@cosmos-kit/xdefi"; +``` + +### add to your provider + +```javascript +function MyCosmosApp({ Component, pageProps }: AppProps) { + return ( + + + + ); +} + +export default MyCosmosApp; +``` diff --git a/developers/introduction.md b/developers/introduction.md index ba6541860..466097a56 100644 --- a/developers/introduction.md +++ b/developers/introduction.md @@ -53,7 +53,7 @@ XDEFI Wallet is also integrated in a large panel of libraries to make it accessi You can acces the list from here: -- [BlockNative](./blocknative-xdefi-integration -- [Cosmos Kit](./cosmoskit-xdefi-integration) -- [Rainbowkit](./rainbowkit-xdefi-integration) +- [BlockNative](./blocknative-xdefi-integration) +- [CosmosKit](./cosmoskit-xdefi-integration) +- [RainbowKit](./rainbowkit-xdefi-integration) - [Solana Adapter](./solana-adapter-xdefi-integration) diff --git a/developers/libraries-integration.md b/developers/libraries-integration.md new file mode 100644 index 000000000..728ba9263 --- /dev/null +++ b/developers/libraries-integration.md @@ -0,0 +1,10 @@ +# Libraries Integration + +XDEFI Wallet is also integrated in a large panel of libraries to make it accessible to any developer's needs. + +You can access the list from here: + +- [BlockNative](./blocknative-xdefi-integration) +- [CosmosKit](./cosmoskit-xdefi-integration) +- [RainbowKit](./rainbowkit-xdefi-integration) +- [Solana Adapter](./solana-adapter-xdefi-integration) diff --git a/developers/rainbowkit-xdefi-integration.md b/developers/rainbowkit-xdefi-integration.md new file mode 100644 index 000000000..15f9fb89a --- /dev/null +++ b/developers/rainbowkit-xdefi-integration.md @@ -0,0 +1,122 @@ +# RainbowKit XDEFI Integration + +You can import individual wallets from `'@rainbow-me/rainbowkit/wallets'` along with the `connectorsForWallets` function to build your own list of wallets with their necessary connectors. This way you have full control over which wallets to display, and in which order. + +For example, you can choose to only show Rainbow along with generic fallback wallets. + +```javascript +import { connectorsForWallets } from "@rainbow-me/rainbowkit"; +import { + rainbowWallet, + walletConnectWallet, +} from "@rainbow-me/rainbowkit/wallets"; + +const connectors = connectorsForWallets( + [ + { + groupName: "Recommended", + wallets: [rainbowWallet, walletConnectWallet], + }, + ], + { + appName: "My RainbowKit App", + projectId: "YOUR_PROJECT_ID", + }, +); +``` + +You can then pass your connectors to Wagmi's `createConfig`. + +```javascript +import { connectorsForWallets } from '@rainbow-me/rainbowkit'; +import { createConfig } from 'wagmi'; + +const connectors = connectorsForWallets(/* ... */); + +const config = createConfig({ + connectors, + {/* Wagmi config */} +}); + +const queryClient = new QueryClient(); + +const App = () => ( + + + + {/* Your App */} + + + +); +``` + +### Built-in XDEFI Wallets + +First, you need to install the `@rainbow-me/rainbowkit/wallets` package and then import the dApp: + +```javascript +import { xdefiWallet } from "@rainbow-me/rainbowkit/wallets"; +``` + +### Examples + +Here are examples: Show Rainbow, MetaMask, Coinbase and XDEFI along with generic fallback wallets. + +```javascript +import { connectorsForWallets } from '@rainbow-me/rainbowkit'; +import { + rainbowWallet, + xdefiWallet + metaMaskWallet, + coinbaseWallet, + walletConnectWallet, +} from '@rainbow-me/rainbowkit/wallets'; + +const connectors = connectorsForWallets( + [ + { + groupName: 'Suggested', + wallets: [ + rainbowWallet, + xdefiWallet, + metaMaskWallet, + coinbaseWallet, + walletConnectWallet, + ], + }, + ], + { appName: 'RainbowKit App', projectId: 'YOUR_PROJECT_ID' }, +); +``` + +> Reminder: The order of the wallets array defines the order in which wallets will be displayed in the UI. + +You also can use the `groupName` key to name different wallet groups. This is useful if you want to communicate to your users which wallets you recommend, as well as other possible wallets. + +Recommend Rainbow and MetaMask, but also offer Coinbase along with generic fallback wallets. + +```javascript +import { connectorsForWallets } from "@rainbow-me/rainbowkit"; +import { + rainbowWallet, + xdefiWallet, + metaMaskWallet, + coinbaseWallet, + walletConnectWallet, +} from "@rainbow-me/rainbowkit/wallets"; + +const connectors = connectorsForWallets( + [ + { + groupName: "Recommended", + wallets: [rainbowWallet, metaMaskWallet], + }, + { + groupName: "Others", + wallets: [xdefiWallet, coinbaseWallet, walletConnectWallet], + }, + ], + { appName: "RainbowKit App", projectId: "YOUR_PROJECT_ID" }, +); +``` diff --git a/developers/solana-adapter-xdefi-integration.md b/developers/solana-adapter-xdefi-integration.md new file mode 100644 index 000000000..52acccd48 --- /dev/null +++ b/developers/solana-adapter-xdefi-integration.md @@ -0,0 +1,344 @@ +# Solana Adapter XDEFI Integration + +First, your app need to install dependencies for Solana Adapter and XDEFI. These imports include event emitters, error types, transaction-related types, and the PublicKey class. + +- `@solana/wallet-adapter-base` +- `@solana/web3.js` + +Then import dependencies and declare the `XDEFIWallet` and `XDEFIWalletWindow` interfaces: + +```typescript +import type { EventEmitter, WalletName } from "@solana/wallet-adapter-base"; +import { + BaseMessageSignerWalletAdapter, + scopePollingDetectionStrategy, + WalletAccountError, + WalletConnectionError, + WalletDisconnectedError, + WalletDisconnectionError, + WalletNotConnectedError, + WalletNotReadyError, + WalletPublicKeyError, + WalletReadyState, + WalletSignMessageError, + WalletSignTransactionError, +} from "@solana/wallet-adapter-base"; +import type { + SendOptions, + Transaction, + TransactionSignature, +} from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; + +interface XDEFIWalletEvents { + connect(...args: unknown[]): unknown; + disconnect(...args: unknown[]): unknown; +} + +interface XDEFIWallet extends EventEmitter { + isXDEFI?: boolean; + publicKey?: { toBytes(): Uint8Array }; + isConnected: boolean; + signTransaction(transaction: Transaction): Promise; + signAllTransactions(transactions: Transaction[]): Promise; + signAndSendTransaction( + transaction: Transaction, + options?: SendOptions, + ): Promise<{ signature: TransactionSignature }>; + signMessage(message: Uint8Array): Promise<{ signature: Uint8Array }>; + connect(): Promise; + disconnect(): Promise; +} + +interface XDEFIWalletWindow extends Window { + xfi?: { + solana?: XDEFIWallet; + }; +} +``` + +Next, constructor a new class that extends `BaseMessageSignerWalletAdapter` and implements the `XDEFIWallet` interface: + +```typescript +declare const window: XDEFIWalletWindow; + +export interface XDEFIWalletAdapterConfig {} + +export const XDEFIWalletName = "XDEFI" as WalletName<"XDEFI">; + +export class XDEFIWalletAdapter extends BaseMessageSignerWalletAdapter { + name = XDEFIWalletName; + url = "https://xdefi.io"; + icon = + "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0LjI2MjggMTMuNDAxM0MxMi40MjI4IDE0LjUzMDcgOS45NTk5NyAxNS4xMTI0IDcuNDY1NjkgMTQuOTg4MUM1LjM2ODU1IDE0Ljg4NjUgMy42NDg1NSAxNC4xNDExIDIuNjA4NTUgMTIuOTE1N0MxLjY5NDI2IDExLjgyMDEgMS4zMzk5OCAxMC4zNzQ1IDEuNTc5OTggOC43MTE0M0MxLjY2MTMyIDguMTU4NzQgMS44MjgwMiA3LjYyMTY2IDIuMDc0MjYgNy4xMTg5NkwyLjEwODU1IDcuMDQ4MzdDMi45NzE4IDUuNDA1OTUgNC4yNTI5MyA0LjAxMzk3IDUuODI1ODQgMy4wMDk0MkM3LjM5ODc1IDIuMDA0ODYgOS4yMDkyNCAxLjQyMjM2IDExLjA3OTEgMS4zMTkyNEMxMi45NDkgMS4yMTYxMSAxNC44MTM4IDEuNTk1OTIgMTYuNDkwMSAyLjQyMTI4QzE4LjE2NjMgMy4yNDY2NSAxOS41OTYyIDQuNDg5MTIgMjAuNjM5IDYuMDI2NDFDMjEuNjgxOSA3LjU2MzcxIDIyLjMwMTcgOS4zNDI4NSAyMi40Mzc0IDExLjE4ODdDMjIuNTczMiAxMy4wMzQ2IDIyLjIyMDMgMTQuODgzNiAyMS40MTM0IDE2LjU1MzhDMjAuNjA2NSAxOC4yMjQgMTkuMzczNSAxOS42NTc3IDE3LjgzNTYgMjAuNzE0QzE2LjI5NzggMjEuNzcwMiAxNC41MDgxIDIyLjQxMjYgMTIuNjQyOCAyMi41Nzc4TDEyLjc1NzEgMjMuODczOEMxNC44NTE0IDIzLjY4OTQgMTYuODYxIDIyLjk2OTEgMTguNTg3OCAyMS43ODM3QzIwLjMxNDcgMjAuNTk4NCAyMS42OTkzIDE4Ljk4ODkgMjIuNjA1MiAxNy4xMTM4QzIzLjUxMTEgMTUuMjM4NyAyMy45MDcxIDEzLjE2MjcgMjMuNzU0MiAxMS4wOTA0QzIzLjYwMTIgOS4wMTgwOCAyMi45MDQ2IDcuMDIwODggMjEuNzMyOSA1LjI5NTU1QzIwLjU2MTMgMy41NzAyMiAxOC45NTUgMi4xNzYzIDE3LjA3MjQgMS4yNTExMUMxNS4xODk4IDAuMzI1OTA5IDEzLjA5NTcgLTAuMDk4NjQxMSAxMC45OTY1IDAuMDE5Mjc4N0M4Ljg5NzMzIDAuMTM3MTk4IDYuODY1NDQgMC43OTM1MiA1LjEwMTAyIDEuOTIzNTlDMy4zMzY2IDMuMDUzNjUgMS45MDA1MyA0LjYxODQ4IDAuOTM0MjY0IDYuNDYzOUwwLjg4ODU0OCA2LjU1NzA3QzAuNTgzMDgzIDcuMTgwOSAwLjM3Njg0NyA3Ljg0NzU2IDAuMjc3MTIgOC41MzM1NEMtMC4wMDg1OTQ1IDEwLjU2MDggMC40MzQyNiAxMi4zNjUxIDEuNTkxNCAxMy43NTQyQzIuODU3MTIgMTUuMjczMyA0LjkxNzEyIDE2LjE3NjggNy4zODg1NSAxNi4yOTU0QzEwLjM5NzEgMTYuNDQ1MSAxMy4zODg1IDE1LjYzNDcgMTUuNTExNCAxNC4xNDM5TDE0LjI2MjggMTMuNDAxM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNi43OCAxNC44NzUxQzE1LjU4MjkgMTUuOTAyOSAxMi44IDE3Ljc2NjQgOC4xODI4NiAxOC4wMjA1QzMuMDE0MjkgMTguMzAyOSAwLjg2MDAwMSAxNi42NDI3IDAuODQwMDAxIDE2LjYyNTdMMC40MjI4NTYgMTcuMTMzOUwwLjg0Mjg1NiAxNi42MzQyTDAgMTcuNjMzN0MwLjA5MTQyODYgMTcuNzA5OSAyLjE1NzE0IDE5LjM1ODkgNy4wMDg1NyAxOS4zNTg5QzcuNDA1NzEgMTkuMzU4OSA3LjgyMjg2IDE5LjM1ODkgOC4yNTcxNCAxOS4zMjVDMTMuODM3MSAxOS4wMTcyIDE2LjkwMjkgMTYuNjExNiAxNy45NzE0IDE1LjU4MzhMMTYuNzggMTQuODc1MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xOS4wMiAxNi4yMTkyQzE4LjMxMjEgMTcuMTM4NyAxNy40NDA4IDE3LjkyMzMgMTYuNDQ4NiAxOC41MzQ1QzEyLjk1MTUgMjAuNzY1IDguNTAyODkgMjEuMDUzIDUuMzg4NiAyMC44OTc4TDUuMzIyODkgMjIuMTk5NEM1Ljg0NTc1IDIyLjIyNDggNi4zNDg2MSAyMi4yMzYxIDYuODM3MTggMjIuMjM2MUMxNS42MiAyMi4yMzYxIDE5LjE2ODYgMTguMjgzMiAyMC4xNiAxNi44NzE0TDE5LjAxNzIgMTYuMjA3OSIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTE4LjY4NTcgMTEuMjkyMkMxOS4yNjggMTEuMjkyMiAxOS43NCAxMC44MjU3IDE5Ljc0IDEwLjI1MDNDMTkuNzQgOS42NzQ4OSAxOS4yNjggOS4yMDg0MiAxOC42ODU3IDkuMjA4NDJDMTguMTAzNCA5LjIwODQyIDE3LjYzMTQgOS42NzQ4OSAxNy42MzE0IDEwLjI1MDNDMTcuNjMxNCAxMC44MjU3IDE4LjEwMzQgMTEuMjkyMiAxOC42ODU3IDExLjI5MjJaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K"; + readonly supportedTransactionVersions = null; + + private _connecting: boolean; + private _wallet: XDEFIWallet | null; + private _publicKey: PublicKey | null; + private _readyState: WalletReadyState = + typeof window === "undefined" || typeof document === "undefined" + ? WalletReadyState.Unsupported + : WalletReadyState.NotDetected; + + constructor(config: XDEFIWalletAdapterConfig = {}) { + super(); + this._connecting = false; + this._wallet = null; + this._publicKey = null; + + if (this._readyState !== WalletReadyState.Unsupported) { + scopePollingDetectionStrategy(() => { + if (window.xfi?.solana?.isXDEFI) { + this._readyState = WalletReadyState.Installed; + this.emit("readyStateChange", this._readyState); + return true; + } + return false; + }); + } + } + // Define the `connect`, `disconnect`, `signTransaction`, `signAllTransactions`, `signAndSendTransaction`, and `signMessage` methods like other wallet adapters. +} +``` + +Be sure to handle the `connect` and `disconnect` methods to update the `publicKey` and `isConnected` properties of the wallet adapter. + +### Example + +Here is an example of a Solana Adapter for XDEFI integration: + +```typescript +import type { EventEmitter, WalletName } from "@solana/wallet-adapter-base"; +import { + BaseMessageSignerWalletAdapter, + scopePollingDetectionStrategy, + WalletAccountError, + WalletConnectionError, + WalletDisconnectedError, + WalletDisconnectionError, + WalletNotConnectedError, + WalletNotReadyError, + WalletPublicKeyError, + WalletReadyState, + WalletSignMessageError, + WalletSignTransactionError, +} from "@solana/wallet-adapter-base"; +import type { + SendOptions, + Transaction, + TransactionSignature, +} from "@solana/web3.js"; +import { PublicKey } from "@solana/web3.js"; + +interface XDEFIWalletEvents { + connect(...args: unknown[]): unknown; + disconnect(...args: unknown[]): unknown; +} + +interface XDEFIWallet extends EventEmitter { + isXDEFI?: boolean; + publicKey?: { toBytes(): Uint8Array }; + isConnected: boolean; + signTransaction(transaction: Transaction): Promise; + signAllTransactions(transactions: Transaction[]): Promise; + signAndSendTransaction( + transaction: Transaction, + options?: SendOptions, + ): Promise<{ signature: TransactionSignature }>; + signMessage(message: Uint8Array): Promise<{ signature: Uint8Array }>; + connect(): Promise; + disconnect(): Promise; +} + +interface XDEFIWalletWindow extends Window { + xfi?: { + solana?: XDEFIWallet; + }; +} + +declare const window: XDEFIWalletWindow; + +export interface XDEFIWalletAdapterConfig {} + +export const XDEFIWalletName = "XDEFI" as WalletName<"XDEFI">; + +export class XDEFIWalletAdapter extends BaseMessageSignerWalletAdapter { + name = XDEFIWalletName; + url = "https://xdefi.io"; + icon = + "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0LjI2MjggMTMuNDAxM0MxMi40MjI4IDE0LjUzMDcgOS45NTk5NyAxNS4xMTI0IDcuNDY1NjkgMTQuOTg4MUM1LjM2ODU1IDE0Ljg4NjUgMy42NDg1NSAxNC4xNDExIDIuNjA4NTUgMTIuOTE1N0MxLjY5NDI2IDExLjgyMDEgMS4zMzk5OCAxMC4zNzQ1IDEuNTc5OTggOC43MTE0M0MxLjY2MTMyIDguMTU4NzQgMS44MjgwMiA3LjYyMTY2IDIuMDc0MjYgNy4xMTg5NkwyLjEwODU1IDcuMDQ4MzdDMi45NzE4IDUuNDA1OTUgNC4yNTI5MyA0LjAxMzk3IDUuODI1ODQgMy4wMDk0MkM3LjM5ODc1IDIuMDA0ODYgOS4yMDkyNCAxLjQyMjM2IDExLjA3OTEgMS4zMTkyNEMxMi45NDkgMS4yMTYxMSAxNC44MTM4IDEuNTk1OTIgMTYuNDkwMSAyLjQyMTI4QzE4LjE2NjMgMy4yNDY2NSAxOS41OTYyIDQuNDg5MTIgMjAuNjM5IDYuMDI2NDFDMjEuNjgxOSA3LjU2MzcxIDIyLjMwMTcgOS4zNDI4NSAyMi40Mzc0IDExLjE4ODdDMjIuNTczMiAxMy4wMzQ2IDIyLjIyMDMgMTQuODgzNiAyMS40MTM0IDE2LjU1MzhDMjAuNjA2NSAxOC4yMjQgMTkuMzczNSAxOS42NTc3IDE3LjgzNTYgMjAuNzE0QzE2LjI5NzggMjEuNzcwMiAxNC41MDgxIDIyLjQxMjYgMTIuNjQyOCAyMi41Nzc4TDEyLjc1NzEgMjMuODczOEMxNC44NTE0IDIzLjY4OTQgMTYuODYxIDIyLjk2OTEgMTguNTg3OCAyMS43ODM3QzIwLjMxNDcgMjAuNTk4NCAyMS42OTkzIDE4Ljk4ODkgMjIuNjA1MiAxNy4xMTM4QzIzLjUxMTEgMTUuMjM4NyAyMy45MDcxIDEzLjE2MjcgMjMuNzU0MiAxMS4wOTA0QzIzLjYwMTIgOS4wMTgwOCAyMi45MDQ2IDcuMDIwODggMjEuNzMyOSA1LjI5NTU1QzIwLjU2MTMgMy41NzAyMiAxOC45NTUgMi4xNzYzIDE3LjA3MjQgMS4yNTExMUMxNS4xODk4IDAuMzI1OTA5IDEzLjA5NTcgLTAuMDk4NjQxMSAxMC45OTY1IDAuMDE5Mjc4N0M4Ljg5NzMzIDAuMTM3MTk4IDYuODY1NDQgMC43OTM1MiA1LjEwMTAyIDEuOTIzNTlDMy4zMzY2IDMuMDUzNjUgMS45MDA1MyA0LjYxODQ4IDAuOTM0MjY0IDYuNDYzOUwwLjg4ODU0OCA2LjU1NzA3QzAuNTgzMDgzIDcuMTgwOSAwLjM3Njg0NyA3Ljg0NzU2IDAuMjc3MTIgOC41MzM1NEMtMC4wMDg1OTQ1IDEwLjU2MDggMC40MzQyNiAxMi4zNjUxIDEuNTkxNCAxMy43NTQyQzIuODU3MTIgMTUuMjczMyA0LjkxNzEyIDE2LjE3NjggNy4zODg1NSAxNi4yOTU0QzEwLjM5NzEgMTYuNDQ1MSAxMy4zODg1IDE1LjYzNDcgMTUuNTExNCAxNC4xNDM5TDE0LjI2MjggMTMuNDAxM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNi43OCAxNC44NzUxQzE1LjU4MjkgMTUuOTAyOSAxMi44IDE3Ljc2NjQgOC4xODI4NiAxOC4wMjA1QzMuMDE0MjkgMTguMzAyOSAwLjg2MDAwMSAxNi42NDI3IDAuODQwMDAxIDE2LjYyNTdMMC40MjI4NTYgMTcuMTMzOUwwLjg0Mjg1NiAxNi42MzQyTDAgMTcuNjMzN0MwLjA5MTQyODYgMTcuNzA5OSAyLjE1NzE0IDE5LjM1ODkgNy4wMDg1NyAxOS4zNTg5QzcuNDA1NzEgMTkuMzU4OSA3LjgyMjg2IDE5LjM1ODkgOC4yNTcxNCAxOS4zMjVDMTMuODM3MSAxOS4wMTcyIDE2LjkwMjkgMTYuNjExNiAxNy45NzE0IDE1LjU4MzhMMTYuNzggMTQuODc1MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xOS4wMiAxNi4yMTkyQzE4LjMxMjEgMTcuMTM4NyAxNy40NDA4IDE3LjkyMzMgMTYuNDQ4NiAxOC41MzQ1QzEyLjk1MTUgMjAuNzY1IDguNTAyODkgMjEuMDUzIDUuMzg4NiAyMC44OTc4TDUuMzIyODkgMjIuMTk5NEM1Ljg0NTc1IDIyLjIyNDggNi4zNDg2MSAyMi4yMzYxIDYuODM3MTggMjIuMjM2MUMxNS42MiAyMi4yMzYxIDE5LjE2ODYgMTguMjgzMiAyMC4xNiAxNi44NzE0TDE5LjAxNzIgMTYuMjA3OSIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTE4LjY4NTcgMTEuMjkyMkMxOS4yNjggMTEuMjkyMiAxOS43NCAxMC44MjU3IDE5Ljc0IDEwLjI1MDNDMTkuNzQgOS42NzQ4OSAxOS4yNjggOS4yMDg0MiAxOC42ODU3IDkuMjA4NDJDMTguMTAzNCA5LjIwODQyIDE3LjYzMTQgOS42NzQ4OSAxNy42MzE0IDEwLjI1MDNDMTcuNjMxNCAxMC44MjU3IDE4LjEwMzQgMTEuMjkyMiAxOC42ODU3IDExLjI5MjJaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K"; + readonly supportedTransactionVersions = null; + + private _connecting: boolean; + private _wallet: XDEFIWallet | null; + private _publicKey: PublicKey | null; + private _readyState: WalletReadyState = + typeof window === "undefined" || typeof document === "undefined" + ? WalletReadyState.Unsupported + : WalletReadyState.NotDetected; + + constructor(config: XDEFIWalletAdapterConfig = {}) { + super(); + this._connecting = false; + this._wallet = null; + this._publicKey = null; + + if (this._readyState !== WalletReadyState.Unsupported) { + scopePollingDetectionStrategy(() => { + if (window.xfi?.solana?.isXDEFI) { + this._readyState = WalletReadyState.Installed; + this.emit("readyStateChange", this._readyState); + return true; + } + return false; + }); + } + } + + get publicKey() { + return this._publicKey; + } + + get connecting() { + return this._connecting; + } + + get connected() { + return !!this._wallet?.isConnected; + } + + get readyState() { + return this._readyState; + } + + async connect(): Promise { + try { + if (this.connected || this.connecting) return; + if (this._readyState !== WalletReadyState.Installed) + throw new WalletNotReadyError(); + + this._connecting = true; + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const wallet = window.xfi!.solana!; + + if (!wallet.isConnected) { + try { + await wallet.connect(); + } catch (error: any) { + throw new WalletConnectionError(error?.message, error); + } + } + + if (!wallet.publicKey) throw new WalletAccountError(); + + let publicKey: PublicKey; + try { + publicKey = new PublicKey(wallet.publicKey.toBytes()); + } catch (error: any) { + throw new WalletPublicKeyError(error?.message, error); + } + + wallet.on("disconnect", this._disconnected); + + this._wallet = wallet; + this._publicKey = publicKey; + + this.emit("connect", publicKey); + } catch (error: any) { + this.emit("error", error); + throw error; + } finally { + this._connecting = false; + } + } + + async disconnect(): Promise { + const wallet = this._wallet; + if (wallet) { + wallet.off("disconnect", this._disconnected); + + this._wallet = null; + this._publicKey = null; + + try { + await wallet.disconnect(); + } catch (error: any) { + this.emit("error", new WalletDisconnectionError(error?.message, error)); + } + } + + this.emit("disconnect"); + } + + async signTransaction(transaction: T): Promise { + try { + const wallet = this._wallet; + if (!wallet) throw new WalletNotConnectedError(); + + try { + return ( + ((await wallet.signTransaction(transaction)) as T) || transaction + ); + } catch (error: any) { + throw new WalletSignTransactionError(error?.message, error); + } + } catch (error: any) { + this.emit("error", error); + throw error; + } + } + + async signAllTransactions( + transactions: T[], + ): Promise { + try { + const wallet = this._wallet; + if (!wallet) throw new WalletNotConnectedError(); + + try { + return ( + ((await wallet.signAllTransactions(transactions)) as T[]) || + transactions + ); + } catch (error: any) { + throw new WalletSignTransactionError(error?.message, error); + } + } catch (error: any) { + this.emit("error", error); + throw error; + } + } + + async signMessage(message: Uint8Array): Promise { + try { + const wallet = this._wallet; + if (!wallet) throw new WalletNotConnectedError(); + + try { + const { signature } = await wallet.signMessage(message); + return signature; + } catch (error: any) { + throw new WalletSignMessageError(error?.message, error); + } + } catch (error: any) { + this.emit("error", error); + throw error; + } + } + + private _disconnected = () => { + const wallet = this._wallet; + if (wallet) { + wallet.off("disconnect", this._disconnected); + + this._wallet = null; + this._publicKey = null; + + this.emit("error", new WalletDisconnectedError()); + this.emit("disconnect"); + } + }; +} +```