Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0b79037
SDK new structure PoC
alexandratran Sep 23, 2025
44a6248
edits
alexandratran Sep 24, 2025
f234baf
remove custom reference component
alexandratran Sep 24, 2025
f331654
edits
alexandratran Sep 25, 2025
e2f4b8b
Merge branch 'main' into sdk-new-structure
alexandratran Sep 30, 2025
ef20ee1
fix links, update redirects, "metamask wallet sdk"
alexandratran Sep 30, 2025
39b9b16
Merge branch 'main' into sdk-new-structure
alexandratran Oct 16, 2025
905d9a8
add simplified api reference with two examples
alexandratran Oct 18, 2025
549887c
missing files
alexandratran Oct 18, 2025
1b97b2c
Merge branch 'main' into sdk-new-structure
alexandratran Oct 20, 2025
bb103fb
remove starknet docs
alexandratran Oct 21, 2025
8216d8b
copy over solana docs
alexandratran Oct 21, 2025
34aed2c
Merge branch 'main' into sdk-new-structure
alexandratran Oct 22, 2025
d64e8a4
Merge branch 'main' into sdk-new-structure
alexandratran Oct 23, 2025
e02092a
Update terminology and restructure EVM docs
alexandratran Oct 23, 2025
956c09a
fix broken links
alexandratran Oct 23, 2025
86d2dfc
Merge branch 'main' into sdk-new-structure
alexandratran Nov 4, 2025
f70f940
fix broken links
alexandratran Nov 4, 2025
e1e0008
Add/update Solana Wallet Adapter docs (#2443)
alexandratran Nov 7, 2025
37a4d06
Merge branch 'main' into sdk-new-structure
alexandratran Nov 10, 2025
30d0439
Update mobile products menu
alexandratran Nov 10, 2025
3db005f
Update MM Connect EVM JS code samples with potential new usage (#2454)
alexandratran Nov 12, 2025
d122361
Merge branch 'main' into sdk-new-structure
alexandratran Nov 13, 2025
360383d
Remove ParserOpenRPC component and replace usage in Linea services
alexandratran Nov 14, 2025
98476fe
Merge branch 'main' into sdk-new-structure
alexandratran Nov 18, 2025
c04fb6d
fix broken link
alexandratran Nov 18, 2025
b034e01
Add more multichain info (#2479)
alexandratran Nov 18, 2025
77bb9a9
Merge branch 'main' into sdk-new-structure
alexandratran Nov 27, 2025
b4716d6
Enhance JS section {WIP} (#2450)
shahbaz17 Nov 27, 2025
2a6e4ab
Add view & wagmi options
shahbaz17 Nov 27, 2025
6cf2880
Merge branch 'main' into sdk-new-structure
alexandratran Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
copy over solana docs
  • Loading branch information
alexandratran committed Oct 21, 2025
commit 8216d8bb794f069bc26146e5fbbc87ec831a88fe
11 changes: 11 additions & 0 deletions sdk-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ const sdkSidebar = {
],
solana: [
'solana/index',
{
type: 'category',
label: 'Guides',
collapsible: false,
collapsed: false,
items: [
'solana/connect/guides/use-wallet-adapter',
'solana/connect/guides/send-legacy-transaction',
'solana/connect/guides/send-versioned-transaction',
],
},
],
}

Expand Down
130 changes: 130 additions & 0 deletions sdk/solana/connect/guides/send-legacy-transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# 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.

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.

:::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).
:::

For a sample Phantom transaction, check out our [sandbox](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L160).

## 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`.

### signAndSendTransaction()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const network = "<NETWORK_URL>";
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 = "<NETWORK_URL>";
const connection = new Connection(network);
const transaction = new Transaction();
const { signature } = await provider.request({
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.

### signAndSendAllTransactions()

```typescript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const network = "<NETWORK_URL>";
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](/solana/detecting-the-provider).
:::

## 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 = "<NETWORK_URL>";
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 = "<NETWORK_URL>";
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 },
});
```

For an example of `signAllTransactions`, refer to [handleSignAllTransactions](https://github.com/phantom-labs/sandbox/blob/b57fdd0e65ce4f01290141a01e33d17fd2f539b9/src/App.tsx#L213) in our sandbox.
194 changes: 194 additions & 0 deletions sdk/solana/connect/guides/send-versioned-transaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Send a versioned transaction

The Solana runtime supports two types of transactions: `legacy` (see [Send a legacy transaction](/solana/sending-a-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.

:::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:

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.

## Build a versioned transaction

Versioned transactions are built in a very similar fashion to [legacy transactions](sending-a-transaction). The only difference is that developers should use the `VersionedTransaction` class rather than the `Transaction` class.

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.

### createTransactionV0()

```typescript theme={null}
// create array of instructions
const instructions = [
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: publicKey,
lamports: 10,
}),
];

// create v0 compatible message
const messageV0 = new TransactionMessage({
payerKey: publicKey,
recentBlockhash: blockhash,
instructions,
}).compileToV0Message();

// make 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.

### signAndSendTransaction()

```javascript theme={null}
const provider = getProvider(); // see "Detecting the Provider"
const network = "<NETWORK_URL>";
const connection = new Connection(network);
const versionedTransaction = new VersionedTransaction();
const { signature } = await provider.signAndSendTransaction(versionedTransaction);
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.

The following is a code snippet that creates a LUT.

### createAddressLookupTable()

```typescript theme={null}
// 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
const lookupMessage = new TransactionMessage({
payerKey: publicKey,
recentBlockhash: blockhash,
instructions: [lookupTableInst],
}).compileToV0Message();

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 LUT

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
const extendInstruction = AddressLookupTableProgram.extendLookupTable({
payer: publicKey,
authority: publicKey,
lookupTable: lookupTableAddress,
addresses: [
publicKey,
SystemProgram.programId,
// 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`
const extensionMessageV0 = new TransactionMessage({
payerKey: publicKey,
recentBlockhash: blockhash,
instructions: [extendInstruction],
}).compileToV0Message();

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.

At this point, we are now ready to sign and send a `VersionedTransaction` using an Address LUT.

First, we need to fetch the account of the created Address LUT.

### getAddressLookupTable()

```typescript theme={null}
// get the table from the cluster
const lookupTableAccount = await connection.getAddressLookupTable(lookupTableAddress).then((res) => res.value);
// `lookupTableAccount` will now be a `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

```typescript theme={null}
// 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.

```typescript theme={null}
// create an array with your desired `instructions`
// in this case, just a transfer instruction
const instructions = [
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: publicKey,
lamports: minRent,
}),
];

// create v0 compatible message
const messageV0 = new TransactionMessage({
payerKey: publicKey,
recentBlockhash: blockhash,
instructions,
}).compileToV0Message([lookupTableAccount]);

// make 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.
Loading
Loading