diff --git a/sdk/solana/connect/guides/send-legacy-transaction.md b/sdk/solana/connect/guides/send-legacy-transaction.md index 3c37b1e9012..6df4acd9b24 100644 --- a/sdk/solana/connect/guides/send-legacy-transaction.md +++ b/sdk/solana/connect/guides/send-legacy-transaction.md @@ -1,130 +1,71 @@ -# Send a legacy transaction - -Once a web application is connected to Phantom, it can prompt the user for permission to send transactions on their behalf. +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -In order to send a transaction, a web application must: - -1. Create an unsigned transaction. -2. Have the transaction be signed and submitted to the network by the user's Phantom wallet. -3. Optionally await network confirmation using a Solana JSON RPC connection. +# Send a legacy transaction -:::info -For more information about the nature of Solana transactions, refer to the [solana-web3.js](https://solana-foundation.github.io/solana-web3.js/) documentation and the [Solana Cookbook](https://solanacookbook.com/core-concepts/transactions.html#transactions). -::: +Solana supports [legacy transactions and versioned transactions](https://solana.com/developers/guides/advanced/versions). +Unlike versioned transactions, legacy transactions cannot include Address Lookup Tables, so they are capped at 32 addresses per transaction. -For a sample Phantom transaction, check out our [sandbox](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L160). +After connecting to MetaMask, your dapp can prompt a user to sign and send one or more Solana legacy transactions. +See the [Solana documentation](https://solana.com/docs/core/transactions) for more information about Solana transactions and how to create them. ## Sign and send a transaction -Once a transaction is created, the web application may ask the user's Phantom wallet to sign and send the transaction. If accepted, Phantom will sign the transaction with the user's private key and submit it via a Solana JSON RPC connection. By far the **easiest** and most **recommended** way of doing this is by using the `signAndSendTransaction` method on the provider, but it is also possible to do with `request`. In both cases, the call will return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for an object containing the `signature`. +After creating an unsigned legacy transaction, you can ask the user's MetaMask wallet to sign and send the transaction. +Use the `signAndSendTransaction` method on the provider, or use `signAndSendTransaction` with the provider's `request` method. +You can specify an optional [`SendOptions`](https://solana-foundation.github.io/solana-web3.js/types/SendOptions.html) object as a second parameter for `signAndSendTransaction`, or as an `options` parameter when using `request`. -### signAndSendTransaction() +The method returns a promise for an object containing the `signature`. -```javascript theme={null} -const provider = getProvider(); // see "Detecting the Provider" -const network = ""; + + + +```javascript +const provider = getProvider(); // TO DO: replace with provider snippet +const network = ''; const connection = new Connection(network); const transaction = new Transaction(); const { signature } = await provider.signAndSendTransaction(transaction); await connection.getSignatureStatus(signature); ``` -### request() + + -```javascript theme={null} -const provider = getProvider(); // see "Detecting the Provider" -const network = ""; +```javascript +const provider = getProvider(); // TO DO: replace with provider snippet +const network = ''; const connection = new Connection(network); const transaction = new Transaction(); const { signature } = await provider.request({ - method: "signAndSendTransaction", - params: { - message: bs58.encode(transaction.serializeMessage()), - }, + method: 'signAndSendTransaction', + params: { + message: bs58.encode(transaction.serializeMessage()), + }, }); await connection.getSignatureStatus(signature); ``` -You can also specify a `SendOptions` [object](https://solana-foundation.github.io/solana-web3.js/modules.html#SendOptions) as a second argument into `signAndSendTransaction` or as an `options` parameter when using `request`. - -For a live demo of `signAndSendTransaction`, refer to [handleSignAndSendTransaction](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L160) in our sandbox. + + ## Sign and send multiple transactions -It is also possible to sign and send multiple transactions at once. This is exposed through the `signAndSendAllTransactions` method on the provider. This method accepts an array of Solana transactions, and will optionally accept a [SendOptions](https://solana-foundation.github.io/solana-web3.js/types/SendOptions.html) object as a second parameter. If successful, it will return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for an object containing the array of string `signatures` and the `publicKey` of the signer. +After creating multiple unsigned legacy transactions, you can ask the user's MetaMask wallet to sign and send all the transactions at once. +Use the `signAndSendAllTransactions` method on the provider. +This method accepts an array of Solana transactions, and an optional [`SendOptions`](https://solana-foundation.github.io/solana-web3.js/types/SendOptions.html) object as a second parameter. -### signAndSendAllTransactions() +The method returns a promise for an object containing an array of `signatures` and the `publicKey` of the signer. -```typescript theme={null} -const provider = getProvider(); // see "Detecting the Provider" -const network = ""; +```typescript +const provider = getProvider(); // TO DO: replace with provider snippet +const network = ''; const connection = new Connection(network); const transactions = [new Transaction(), new Transaction()]; const { signatures, publicKey } = await provider.signAndSendAllTransactions(transactions); await connection.getSignatureStatuses(signatures); ``` -## Other signing methods - -The following methods are also supported, but are not recommended over `signAndSendTransaction`. It is safer for users, and a simpler API for developers, for Phantom to submit the transaction immediately after signing it instead of relying on the application to do so. - -:::warning -The following methods are not supported in the [wallet standard](#) implementation and may be removed in a future release. These methods are only available via the [window.solana object]. -::: - -## Sign a transaction (without sending) - -Once a transaction is created, a web application may ask the user's Phantom wallet to sign the transaction *without* also submitting it to the network. The easiest and most recommended way of doing this is via the `signTransaction` method on the provider, but it is also possible to do via `request`. In both cases, the call will return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for the signed transaction. After the transaction has been signed, an application may submit the transaction itself using [sendRawTransaction](https://solana-foundation.github.io/solana-web3.js/classes/Connection.html#sendRawTransaction) in web3.js. - -### signTransaction() - -```javascript theme={null} -const provider = getProvider(); -const network = ""; -const connection = new Connection(network); -const transaction = new Transaction(); -const signedTransaction = await provider.signTransaction(transaction); -const signature = await connection.sendRawTransaction(signedTransaction.serialize()); -``` - -### request() - -```javascript theme={null} -const provider = getProvider(); -const network = ""; -const connection = new Connection(network); -const transaction = new Transaction(); -const signedTransaction = await provider.request({ - method: "signTransaction", - params: { - message: bs58.encode(transaction.serializeMessage()), - }, -}); -const signature = await connection.sendRawTransaction(signedTransaction.serialize()); -``` - -For an example of `signTransaction`, refer to [handleSignTransaction](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L187) in our sandbox. - -## Sign multiple transactions - -For legacy integrations, Phantom supports signing multiple transactions at once without sending them. This is exposed through the `signAllTransactions` method on the provider. This method is **not recommended** for new integrations. Instead, developers should make use of `signAndSendAllTransactions`. - -### signAllTransactions() - -```javascript theme={null} -const signedTransactions = await provider.signAllTransactions(transactions); -``` - -### request() - -```javascript theme={null} -const message = transactions.map(transaction => { - return bs58.encode(transaction.serializeMessage()); -}); -const signedTransactions = await provider.request({ - method: "signAllTransactions", - params: { message }, -}); -``` +## Next steps -For an example of `signAllTransactions`, refer to [handleSignAllTransactions](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L213) in our sandbox. +To efficiently load more addresses in a single transaction, learn how to [send a versioned transaction](send-versioned-transaction.md) with Address Lookup Tables. diff --git a/sdk/solana/connect/guides/send-versioned-transaction.md b/sdk/solana/connect/guides/send-versioned-transaction.md index f4cbcc36037..b87635e7c91 100644 --- a/sdk/solana/connect/guides/send-versioned-transaction.md +++ b/sdk/solana/connect/guides/send-versioned-transaction.md @@ -1,31 +1,23 @@ -# Send a versioned transaction - -The Solana runtime supports two types of transactions: `legacy` (see [Send a legacy transaction]) and `v0` (transactions that can include Address Lookup Tables or LUTs). - -The goal of `v0` is to increase the maximum size of a transaction, and hence the number of accounts that can fit in a single atomic transaction. With LUTs, developers can now build transactions with a maximum of 256 accounts, as compared to the limit of 35 accounts in legacy transactions that do not utilize LUTs. +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -:::info -For a dive deep on versioned transactions, LUTs, and how the above changes affect the anatomy of a transaction, see [Versioned Transactions - Anvit Mangal's Blog](https://anvit.hashnode.dev/versioned-transactions). -::: - -On this page, we'll go over the following: +# Send a versioned transaction -1. Building a versioned tansaction. -2. Signing and sending a versioned transaction. -3. Building an Address LUT. -4. Extending an Address LUT. -5. Signing and sending a versioned transaction using a LUT. +Solana supports [legacy transactions and versioned transactions](https://solana.com/developers/guides/advanced/versions). +Unlike legacy transactions, versioned transactions (`v0`) can include [Address Lookup Tables](https://solana.com/developers/guides/advanced/lookup-tables) (ALTs or Address LUTs), enabling you to efficiently load up to 256 addresses in a single transaction. -## Build a versioned transaction +After connecting to MetaMask, your dapp can prompt a user to sign and send a Solana versioned transaction. -Versioned transactions are built in a very similar fashion to [legacy transactions](send-legacy-transaction.md). The only difference is that developers should use the `VersionedTransaction` class rather than the `Transaction` class. +## Create a versioned transaction -The following example shows how to build a simple transfer instruction. Once the transfer instruction is made, a `MessageV0` formatted transaction message is constructed with the transfer instruction. Finally, a new `VersionedTransaction` is created, parsing in the `v0` compatible message. +Solana versioned transactions are created in a similar way to [legacy transactions](https://solana.com/docs/core/transactions). +The only difference is to use the `VersionedTransaction` class instead of the `Transaction` class. -### createTransactionV0() +The following example shows how to create a simple transfer instruction, format the instruction into a `v0`-compatible transaction message, and create a versioned transaction that parses the message: -```typescript theme={null} -// create array of instructions +```typescript +// Create an array of instructions. +// This example uses a simple transfer instruction. const instructions = [ SystemProgram.transfer({ fromPubkey: publicKey, @@ -34,60 +26,49 @@ const instructions = [ }), ]; -// create v0 compatible message +// Create a v0-compatible message. const messageV0 = new TransactionMessage({ payerKey: publicKey, recentBlockhash: blockhash, instructions, }).compileToV0Message(); -// make a versioned transaction +// Create a versioned transaction. const transactionV0 = new VersionedTransaction(messageV0); ``` -For a live example of creating a versioned transaction, refer to [createTransferTransactionV0](https://github.com/phantom-labs/sandbox/blob/main/src/utils/createTransferTransactionV0.ts) in our sandbox. - ## Sign and send a versioned transaction -Once a Versioned transaction is created, it can be signed and sent via Phantom using the `signAndSendTransaction` method on the provider. The call will return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for an object containing the `signature`. This is the same way a legacy transaction is sent via the Phantom provider. +After creating an unsigned versioned transaction, you can ask the user's MetaMask wallet to sign and send the transaction. +Use the `signAndSendTransaction` method on the provider, which accepts an optional [`SendOptions`](https://solana-foundation.github.io/solana-web3.js/types/SendOptions.html) object as a second parameter. -### signAndSendTransaction() +The method returns a promise for an object containing the `signature`. -```javascript theme={null} -const provider = getProvider(); // see "Detecting the Provider" -const network = ""; +```javascript +const provider = getProvider(); // TO DO: replace with provider snippet +const network = ''; const connection = new Connection(network); -const versionedTransaction = new VersionedTransaction(); -const { signature } = await provider.signAndSendTransaction(versionedTransaction); +const { signature } = await provider.signAndSendTransaction(transactionV0); await connection.getSignatureStatus(signature); ``` -You can also specify a `SendOptions` [object](https://solana-foundation.github.io/solana-web3.js/modules.html#SendOptions) as a second argument into `signAndSendTransaction()` or as an `options` parameter when using `request`. - -For a live demo of signing and sending a versioned transaction, refer to [handleSignAndSendTransactionV0](https://github.com/phantom-labs/sandbox/blob/78dc35fe140140a961345a6af30a058e1e19a7aa/src/App.tsx#L191) in our sandbox. - -## Build an Address LUT - -Address LUTs can be used to load accounts into table-like data structures. These structures can then be referenced to significantly increase the number of accounts that can be loaded in a single transaction. - -This lookup method effectively "*compresses*" a 32-byte address into a 1-byte index value. This "*compression*" enables storing up to 256 address in a single LUT for use inside any given transaction. - -With the `@solana/web3.js` [createLookupTable](https://solana-foundation.github.io/solana-web3.js/classes/AddressLookupTableProgram.html#createLookupTable) method, developers can construct the instruction needed to create a new LUT, as well as determine its address. Once we have the LUT instruction, we can construct a transaction, sign it, and send it to create a LUT on-chain. Address LUTs can be created with either a `v0` transaction or a `legacy` transaction. However, the Solana runtime can only retrieve and handle the additional addresses within a LUT while using `v0` transactions. +## Create an Address Lookup Table -The following is a code snippet that creates a LUT. +Create an [Address Lookup Table (ALT)](https://solana.com/developers/guides/advanced/lookup-tables) to efficiently load addresses into tables, significantly increasing the number of addresses that can be used in a single transaction. -### createAddressLookupTable() +Use the [createLookupTable](https://solana-foundation.github.io/solana-web3.js/classes/AddressLookupTableProgram.html#createlookuptable) method to create the instruction needed to create a new ALT and determine its address. +With this instruction, you can create a transaction, sign it, and send it to create an ALT onchain. +For example: ```typescript theme={null} -// create an Address Lookup Table +// Create an Address Lookup Table. const [lookupTableInst, lookupTableAddress] = AddressLookupTableProgram.createLookupTable({ authority: publicKey, payer: publicKey, recentSlot: slot, }); -// To create the Address Lookup Table on chain: -// send the `lookupTableInst` instruction in a transaction +// To create the ALT onchain, send the lookupTableInst instruction in a transaction. const lookupMessage = new TransactionMessage({ payerKey: publicKey, recentBlockhash: blockhash, @@ -98,16 +79,14 @@ const lookupTransaction = new VersionedTransaction(lookupMessage); const lookupSignature = await signAndSendTransaction(provider, lookupTransaction); ``` -For a live demo of creating a LUT, refer to [handleSignAndSendTransactionV0WithLookupTable](https://github.com/phantom-labs/sandbox/blob/78dc35fe140140a961345a6af30a058e1e19a7aa/src/App.tsx#L218) in our sandbox. +## Extend an Address Lookup Table -## Extend an Address LUT +After creating an ALT, you can extend it by appending addresses to the table. +Use the [extendLookupTable](https://solana-foundation.github.io/solana-web3.js/classes/AddressLookupTableProgram.html#extendlookuptable) method to create a new extend instruction, and send it in a transaction. +For example: -Once an Address LUT is created, it can then be extended, which means that accounts can be appended to the table. Using the `@solana/web3.js` library, you can create a new `extend` instruction using the [extendLookupTable](https://solana-labs.github.io/solana-web3.js/classes/AddressLookupTableProgram.html#extendLookupTable) method. Once the extend instruction is created, it can be sent in a transaction. - -### extendAddressLookupTable() - -```typescript theme={null} -// add addresses to the `lookupTableAddress` table via an `extend` instruction +```typescript +// Add addresses to the lookupTableAddress table via an extend instruction. const extendInstruction = AddressLookupTableProgram.extendLookupTable({ payer: publicKey, authority: publicKey, @@ -115,12 +94,12 @@ const extendInstruction = AddressLookupTableProgram.extendLookupTable({ addresses: [ publicKey, SystemProgram.programId, - // more `publicKey` addresses can be listed here + // More publicKey addresses can be listed here. ], }); -// Send this `extendInstruction` in a transaction to the cluster -// to insert the listing of `addresses` into your lookup table with address `lookupTableAddress` +// Send this extendInstruction in a transaction to the cluster to insert +// the listing of addresses into your ALT with address lookupTableAddress. const extensionMessageV0 = new TransactionMessage({ payerKey: publicKey, recentBlockhash: blockhash, @@ -131,46 +110,35 @@ const extensionTransactionV0 = new VersionedTransaction(extensionMessageV0); const extensionSignature = await signAndSendTransaction(provider, extensionTransactionV0); ``` -For a live demo of extending a LUT, refer to the [handleSignAndSendTransactionV0WithLookupTable](https://github.com/phantom-labs/sandbox/blob/78dc35fe140140a961345a6af30a058e1e19a7aa/src/App.tsx#L218) function in our sandbox. - -## Sign and send a versioned transaction using a LUT - -Up until now, we have: - -1. Learned how to create a `VersionedTransaction`. -2. Created an Address LUT. -3. Extended the Address LUT. +## Create, sign, and send a versioned transaction with an ALT -At this point, we are now ready to sign and send a `VersionedTransaction` using an Address LUT. +After creating an ALT, you can create a versioned transaction with the ALT and ask the user's MetaMask wallet to sign and send it. -First, we need to fetch the account of the created Address LUT. +First, use the [`getAddressLookupTable`](https://solana-foundation.github.io/solana-web3.js/classes/Connection.html#getaddresslookuptable) method to fetch the account of the created ALT: -### getAddressLookupTable() - -```typescript theme={null} -// get the table from the cluster +```typescript +// Get the table from the cluster. const lookupTableAccount = await connection.getAddressLookupTable(lookupTableAddress).then((res) => res.value); -// `lookupTableAccount` will now be a `AddressLookupTableAccount` object +// lookupTableAccount will now be an AddressLookupTableAccount object. console.log('Table address from cluster:', lookupTableAccount.key.toBase58()); ``` -We can also parse and read all the addresses currently stores in the fetched Address LUT. - -## Parse and read addresses +Then, parse and read all the addresses currently stored in the fetched ALT: -```typescript theme={null} -// Loop through and parse all the address stored in the table +```typescript +// Loop through and parse all the address stored in the table. for (let i = 0; i < lookupTableAccount.state.addresses.length; i++) { const address = lookupTableAccount.state.addresses[i]; console.log(i, address.toBase58()); } ``` -We can now create the instructions array with an arbitrary transfer instruction, just the way we did while creating the `VersionedTransaction` earlier. This `VersionedTransaction` can then be sent using the `signAndSendTransaction()` provider function. +The following example creates a simple transfer instruction, formats the instruction into a `v0`-compatible transaction message using the ALT's account, and creates a versioned transaction that parses the message. +Sign and send the transaction using the `signAndSendTransaction` method on the provider. -```typescript theme={null} -// create an array with your desired `instructions` -// in this case, just a transfer instruction +```typescript +// Create an array of instructions. +// This example uses a simple transfer instruction. const instructions = [ SystemProgram.transfer({ fromPubkey: publicKey, @@ -179,16 +147,14 @@ const instructions = [ }), ]; -// create v0 compatible message +// Create a v0-compatible message. const messageV0 = new TransactionMessage({ payerKey: publicKey, recentBlockhash: blockhash, instructions, }).compileToV0Message([lookupTableAccount]); -// make a versioned transaction +// Create a versioned transaction. const transactionV0 = new VersionedTransaction(messageV0); const signature = await signAndSendTransaction(provider, transactionV0); ``` - -For a live demo of of signing and sending a versioned transaction using an Address LUT, refer to the [handleSignAndSendTransactionV0WithLookupTable](https://github.com/phantom-labs/sandbox/blob/78dc35fe140140a961345a6af30a058e1e19a7aa/src/App.tsx#L218) in our sandbox. diff --git a/sdk/solana/connect/guides/use-wallet-adapter.md b/sdk/solana/connect/guides/use-wallet-adapter.md index 6f40f8f93c3..90e278ea7c8 100644 --- a/sdk/solana/connect/guides/use-wallet-adapter.md +++ b/sdk/solana/connect/guides/use-wallet-adapter.md @@ -1,56 +1,88 @@ ---- -sidebar_label: Use the Wallet Adapter ---- +# Use the Wallet Adapter -# Use the Solana Wallet Adapter +To connect to Solana in MetaMask from your dapp, set up Solana's [Wallet Adapter](https://github.com/solana-labs/wallet-adapter). -If your dApp uses the [Solana Wallet Adapter](https://github.com/solana-labs/wallet-adapter), you just have to add the Solflare Wallet Adapter to the list of supported wallets. +You can use the [`create-solana-dapp`](https://github.com/solana-foundation/create-solana-dapp) CLI tool to quickly generate a Solana dapp with the Wallet Adapter built in, or follow this guide to manually set up the Wallet Adapter in an existing React dapp. -Install the latest *wallets* package with +:::info +See the [Solana documentation](https://solana.com/developers/cookbook/wallets/connect-wallet-react) for more information. +::: -```sh -npm install @solana/wallet-adapter-wallets@latest +## Steps + +### 1. Install dependencies + +Install the following dependencies: + +```bash +npm install @solana/web3.js \ + @solana/wallet-adapter-base \ + @solana/wallet-adapter-react \ + @solana/wallet-adapter-react-ui \ + @solana/wallet-adapter-wallets ``` -Then update the code to look like this: +### 2. Create the Solana provider -```javascript -import { - SolflareWalletAdapter, - /* ... other adapters ... */ -} from '@solana/wallet-adapter-wallets'; +Create a `SolanaProvider` that will be used to provide the Solana context to the application: -const wallets = useMemo( - () => [ - new SolflareWalletAdapter(), - // ... other adapters ... - ], - [] -); +```typescript title='components/SolanaProvider.tsx' +'use client'; - -``` +import React, { FC, ReactNode, useMemo } from 'react'; +import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react'; +import { WalletAdapterNetwork } from '@solana/wallet-adapter-base'; +import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'; +import { clusterApiUrl } from '@solana/web3.js'; -Alternatively, you can install only the Solflare adapter directly +// Default styles that can be overridden by your dapp. +import '@solana/wallet-adapter-react-ui/styles.css'; -```sh -npm install @solana/wallet-adapter-solflare@latest -``` +interface SolanaProviderProps { + children: ReactNode; +} -Then update the code: +export const SolanaProvider: FC = ({ children }) => { + // The network can be set to devnet, testnet, or mainnet-beta. + const network = WalletAdapterNetwork.Devnet; -```javascript -import { SolflareWalletAdapter } from '@solana/wallet-adapter-solflare'; -import { /* ... other adapters ... */ } from '@solana/wallet-adapter-wallets'; + // You can also provide a custom RPC endpoint. + const endpoint = useMemo(() => clusterApiUrl(network), [network]); + return ( + + + {children} + + + ); +}; +``` + +### 3. Wrap the application in the Solana Provider + +Add the `SolanaProvider` to the `RootLayout` in the `app` directory: -const wallets = useMemo( - () => [ - new SolflareWalletAdapter(), - // ... other adapters ... - ], - [] -); +```typescript +import './globals.css'; +import '@solana/wallet-adapter-react-ui/styles.css'; +import { SolanaProvider } from '@/components/SolanaProvider'; - +export default function RootLayout({ + children +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} ``` + +## Next steps + +See how to send a [legacy transaction](send-legacy-transaction.md) and a [versioned transaction](send-versioned-transaction.md). diff --git a/sdk/solana/index.md b/sdk/solana/index.md index e3420ca7a66..ed629803946 100644 --- a/sdk/solana/index.md +++ b/sdk/solana/index.md @@ -15,9 +15,7 @@ After adding Solana to MetaMask Flask, [show test networks](https://support.meta ## Wallet Standard -MetaMask implements the [Wallet Standard](https://github.com/wallet-standard/wallet-standard), so MetaMask is supported out-of-the-box for Solana dapps that use the Wallet Standard or that integrate Solana's [Wallet Adapter](https://github.com/anza-xyz/wallet-adapter/blob/master/APP.md). - -Learn more in Solana's [Interact With Wallets](https://solana.com/developers/courses/intro-to-solana/interact-with-wallets) documentation. +MetaMask implements the [Wallet Standard](https://github.com/wallet-standard/wallet-standard), so MetaMask is supported out-of-the-box for Solana dapps that use the Wallet Standard or that integrate Solana's [Wallet Adapter](https://github.com/anza-xyz/wallet-adapter). :::note With the Wallet Standard, MetaMask does not appear as a connection option for users that don't already have MetaMask installed. @@ -31,4 +29,4 @@ Several third-party libraries for Solana dapps detect and handle MetaMask out-of - [Dynamic](https://docs.dynamic.xyz/introduction/welcome) - [Privy](https://docs.privy.io/welcome) - [Reown](https://docs.reown.com/overview) -- [Web3Auth](https://web3auth.io/docs) +- [Embedded Wallets](/embedded-wallets)