diff --git a/README.md b/README.md
index 34d600f2..aca48f84 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Documentation
-[Docs](https://docs.neonfoundation.io/) are built using [Docusaurus 2](https://docusaurus.io/).
+[Docs](https://neonevm.org) are built using [Docusaurus 3](https://docusaurus.io/).
### Installation
diff --git a/docs/api/neon-api.mdx b/docs/api/neon-api.mdx
index 49a16b8b..eb38ac1f 100644
--- a/docs/api/neon-api.mdx
+++ b/docs/api/neon-api.mdx
@@ -42,7 +42,7 @@ import neon_solanaVersion_response from "@site/static/schemas/neon-api/v1/neon_s
:::danger
-This page is wip :construction_worker:
+This page is wip đź‘·
:::
@@ -107,14 +107,14 @@ The method [neon_gasPrice](#get-neon-gas-price) returns data on gas price.
### 3. Neon transaction data
-- [neon_getLogs](#get-transaction-logs): returns transaction log data
-- [neon_getTransactionReceipt](#get-transaction-receipt): returns transaction receipt data
-- [neon_getSolanaTransactionByNeonTransaction](#get-solana-transactions): returns a list of Solana transactions that correspond to a given Neon transaction
-- [neon_emulate](#emulate-a-neon-transaction): returns details of an emultated transaction
+- [neon_getLogs](#get-transaction-logs--): returns transaction log data
+- [neon_getTransactionReceipt](#get-transaction-receipt--): returns transaction receipt data
+- [neon_getSolanaTransactionByNeonTransaction](#get-solana-transactions--): returns a list of Solana transactions that correspond to a given Neon transaction
+- [neon_emulate](#emulate-a-neon-transaction--): returns details of an emultated transaction
### 4. Parameters
-[neon_getEvmParams](#get-parameters): returns parameters of the Neon EVM program deployed on Solana.
+[neon_getEvmParams](#get-parameters--): returns parameters of the Neon EVM program deployed on Solana.
## Get versions
@@ -186,7 +186,7 @@ The [JSON](#get-neon-gas-price-response-as-json) for this response schema is ava
## Get transaction data
-### Get transaction logs :construction_worker:
+### Get transaction logs đź‘·
The `neon_getLogs` method returns transaction log data. This is an extended variant of the [eth_getLogs](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getlogs) API method.
@@ -221,7 +221,7 @@ The `neon_getLogs` method returns transaction log data. This is an extended vari
-### Get transaction receipt :construction_worker:
+### Get transaction receipt đź‘·
The `neon_getTransactionReceipt` method returns transaction receipt data.
@@ -255,7 +255,7 @@ The `neon_getTransactionReceipt` method returns transaction receipt data.
-### Get Solana transactions :construction_worker:
+### Get Solana transactions đź‘·
The `neon_getSolanaTransactionByNeonTransaction` method returns a list of Solana transactions that correspond to a given Neon transaction.
@@ -290,7 +290,7 @@ The `neon_getSolanaTransactionByNeonTransaction` method returns a list of Solana
-## Emulate a Neon transaction :construction_worker:
+## Emulate a Neon transaction đź‘·
The `neon_emulate` method returns details of an emultated transaction.
@@ -321,10 +321,10 @@ The [JSON](#get-neon-emulate-response-as-json) for this response schema is avail
-## Get Parameters :construction_worker:
+## Get Parameters đź‘·
-The `neon_getEVMParams` method returns details of the EVM.
+The `neon_getEvmParams` method returns details of the EVM.
@@ -333,7 +333,7 @@ The [JSON](#get-neon-evm-parameters-request-as-json) for this request schema is
-#### Get Neon EVM parameters request as JSON
+The `neon_getEvmParams` method returns details of the EVM.
{JSON.stringify(neon_getEvmParams_request, null, 2)}
@@ -351,4 +351,4 @@ The [JSON](#get-neon-evm-parameters-response-as-json) for this response schema i
{JSON.stringify(neon_getEvmParams_response, null, 2)}
-
\ No newline at end of file
+
diff --git a/docs/composability/call_solana_interface.md b/docs/composability/call_solana_interface.md
new file mode 100644
index 00000000..1b619625
--- /dev/null
+++ b/docs/composability/call_solana_interface.md
@@ -0,0 +1,70 @@
+---
+title: 'ICallSolana Interface'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+To use the **Composability** feature of Solana, let us learn about the interface and the functions included in the interface that will be used to interact with the Solana programs via the precompile `0xFF00000000000000000000000000000000000006`.
+
+The interface contract `ICallSolana.sol` can be found in this [Github Repository](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/contracts/TestCallSolana/interfaces/ICallSolana.sol).
+
+## Struct Variables
+
+1. `AccountMeta` : For each account needed by an instruction, the following details must be provided -
+ - **account:** The account's on-chain address in bytes32.
+ - **is_writable:** Indicates if the account's data will be modified in boolean.
+ - **is_signer:** Indicates if the account needs to sign the transaction in boolean.
+2. `Instruction` : Instruction struct variable includes the following -
+ - **program_id:** The address of the program that contains the execution logic for the invoked instruction.
+ - **accounts:** Contains the AccountMeta for each account required by an instruction.
+ - **instruction_data:** The instruction data as a buffer of bytes.
+
+## Functions
+
+| getNeonAddress(address) -> bytes32 |
+| :--------------------------------------------------------------------------------- |
+| This function returns the Solana address in bytes32 format for a Neon EVM address. |
+
+| getResourceAddress(bytes32 salt) -> bytes32 |
+| :-------------------------------------------------------------------------------------------------------------- |
+| This function returns the Solana address in bytes32 format of a resource represented by the salt for contracts. |
+
+| createResource(bytes32 salt, uint64 space, uint64 lamports, bytes32 owner) -> bytes32 |
+| :--------------------------------------------------------------------------------------------------------------------------------- |
+| This function creates a resource with the specified salt and returns the Solana address of the created resource in bytes32 format. |
+
+| getSolanaPDA(bytes32 program_id, bytes memory seeds) -> bytes32 |
+| :------------------------------------------------------------------------------------------------------------ |
+| This function returns the Solana PDA in bytes32 format generated from the specified `program_id` and `seeds`. |
+
+| getExtAuthority(bytes32 salt) -> bytes32 |
+| :------------------------------------------------------------------------------------------------------------ |
+| This function returns the Solana address in bytes32 format of the external authority represented by the salt. |
+
+| getPayer() -> bytes32 |
+| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| This function returns the Solana address of the payer account in bytes32 format. Payer account is required if an instruction needs an account to fund newly created accounts. |
+
+| execute(uint64 lamports, Instruction memory instruction) -> bytes |
+| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| This function executes the instruction with a call to the Solana program and returns the data of the executed instruction in bytes format. The `lamports` parameter specifies the amount of lamports that will be required to create new accounts during execution. These lamports are transferred to the `payer` account. The `instruction` parameter is the struct variable with the values of program_id, accounts and instruction_data. |
+
+| executeWithSeed(uint64 lamports, bytes32 salt, Instruction memory instruction) -> bytes |
+| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| This function executes the instruction with a call to the Solana program and returns the data of the executed instruction in bytes format. The `lamports` parameter specifies the amount of lamports that will be required to create new accounts during execution. These lamports are transferred to the `payer` account. The `salt` parameter is to generate an address of external authority. The `instruction` parameter is the struct variable with the values of program_id, accounts and instruction_data. |
+
+| execute(uint64 lamports, bytes memory instruction) -> bytes |
+| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| This function executes the instruction with a call to the Solana program and returns the data of the executed instruction in bytes format. The `lamports` parameter specifies the amount of lamports that will be required to create new accounts during execution. These lamports are transferred to the `payer` account. The `instruction` is the bincode serialized instruction which needs to be executed. This method uses PDA of the sender to authorize the operation. |
+
+| executeWithSeed(uint64 lamports, bytes32 salt, bytes memory instruction) -> bytes |
+| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| This function executes the instruction with a call to the Solana program and returns the data of the executed instruction in bytes format. The `lamports` parameter specifies the amount of lamports that will be required to create new accounts during execution. These lamports are transferred to the `payer` account. The `salt` parameter is to generate an address of external authority. The `instruction` is the bincode serialized instruction which needs to be executed. This method uses external authority to authorize the operation. |
+
+| getReturnData() -> bytes32, bytes |
+| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| This function returns the `program_id` and returned data of the last executed instruction. Note: This method should be called after `execute` / `executeWithSeed` methods. |
diff --git a/docs/composability/common_solana_terminology.md b/docs/composability/common_solana_terminology.md
new file mode 100644
index 00000000..be7e8ebc
--- /dev/null
+++ b/docs/composability/common_solana_terminology.md
@@ -0,0 +1,90 @@
+---
+title: 'Common Solana Terminology'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+To learn about Solana's Composability feature, we first need to understand Solana’s core concepts and features that differentiates it from other blockchains.
+
+## What is Solana?
+
+Solana is a blockchain designed for widespread adoption, offering a high-performance network suited for various applications such as finance, NFTs, payments, and gaming. It functions as a single global state machine, ensuring openness, interoperability, and decentralization.
+
+Solana's parallel processing architecture marks a major breakthrough in blockchain technology, delivering exceptional scalability, throughput, and low-latency transaction confirmations. By utilizing parallelism across various levels of its framework, Solana attains high performance while maintaining decentralization and security.
+
+## Core concepts of Solana
+
+### Accounts
+
+Since Solana programs are stateless, hence the data on Solana is stored in what are known as "accounts". Each account is uniquely identified by a 32-byte address formatted as an Ed25519 PublicKey. This address acts as the account's unique identifier. Some of the key characteristic of accounts are -
+
+1. Accounts can store up to 10MB of data, which may include executable program code or program state.
+2. Accounts require a rent deposit in SOL, proportional to the amount of data stored. This deposit is fully refundable when the account is closed.
+3. Each account has a program "owner". Only the owning program can modify the account's data or reduce its lamport balance, but anyone can increase the balance.
+
+Every account in Solana has the structure called `AccountInfo` which includes the following fields -
+
+- `data`: A byte array that holds the state of an account. If the account is a program (smart contract), it contains the executable program code. This field is commonly known as "account data".
+- `executable`: A boolean flag indicating whether the account is a program.
+- `lamports`: A numerical representation of the account's balance in lamports, the smallest unit of SOL (1 SOL = 1 billion lamports).
+- `owner`: Indicates the public key (program ID) of the program that owns the account.
+
+Solana account types can be divided into two broad categories - Executable and non-executable programs.
+
+1. **Executable Programs**: Executable programs consist of immutable code that can own and create other accounts to store state. This code is written in a language such as Rust and then compiled into eBPF, a form of bytecode.
+
+ The following are the two types of executable accounts -
+
+ - `Native Programs`: Executable native programs are integral to the Solana ecosystem, handling tasks such as maintaining and operating validator nodes. The most notable example is the **System Program**, responsible for creating new system accounts (commonly referred to as "wallets") and transferring SOL. Other examples of native programs include the **Stake Program**, which manages the staking mechanism, and the BPF Loader, which functions similarly to Ethereum’s EVM.
+ - `SPL Programs`: SPL Programs facilitate numerous on-chain activities, including token creation, swapping, and lending, as well as the establishment of stake pools and the management of an on-chain name service. While the **SPL Token Program** can be accessed directly through the CLI, others, such as the **Associated Token Account Program**, are often utilized in conjunction with custom programs.
+ - `Custom Programs`: Custom programs on Solana are developer-created smart contracts tailored to specific use cases and functionalities beyond what is provided by native and SPL (Solana Program Library) programs. These programs allow developers to create a wide range of decentralized applications (dApps) like Orca DEX, and services that leverage the high performance and scalability of the Solana blockchain. A perfect example of this type of programs is the **Neon EVM Program**, which comprises of the EVM converted to BPF bytecode.
+
+2. **Non-executable Accounts**: Non-executable accounts are "storage" or "data" accounts that hold various types of data, such as program variables, token balances, NFTs, and fungible currencies. These accounts reflect state changes that occur after each transaction within the protocol.
+
+ This type of accounts can be further divided into -
+
+ - `System Accounts` : System accounts are essential for the network's functionality and manage the basic aspects of account creation and transaction processing. They are managed by the Solana runtime and are necessary for performing fundamental actions like creating, funding, and managing accounts.
+ - `Token Accounts`Â : Token accounts are owned by the Token Program and tracks the number of units of a specific type of token (mint account) owned by a particular address. Token accounts are specialized accounts used to manage and interact with tokens that adhere to the Solana Token Program (often referred to as SPL Token Program). These accounts facilitate the creation, transfer, and management of SPL tokens.
+
+ - An `Associated Token Account` is a token account with an address deterministically derived from the owner's address and the mint account's address. These accounts store the SPL token balances for each individual user.
+
+ - `Program Derived Address (PDA)` : A Program Derived Address (PDA) is a special type of account address that is derived from a program ID and some seed data. PDAs are used to create deterministic and secure addresses for program-owned accounts. These addresses are not directly controlled by any private key, but are instead controlled by the program itself, which can authorize transactions on behalf of the PDA.
+ - `Data Accounts` : Data accounts are specialized accounts that store data associated with Solana programs (smart contracts). These accounts are crucial for maintaining the state and data of decentralized applications running on the Solana blockchain.
+
+Please refer to the accounts types in details on [Solana Account Model](https://solana.com/docs/core/accounts).
+
+### Transactions and Instructions:
+
+1. `Transactions`**:** On Solana, transactions are sent to interact with the network. Each transaction consists of one or more instructions, each representing a specific operation to be executed. The execution logic for these instructions resides in programs deployed on the Solana network, with each program containing its own set of instructions.
+
+ Couple of key points about transaction execution -
+
+ - **Execution Order:** multiple instructions in a transaction are processed in the order they appear in the transaction.
+ - **Atomicity:** A transaction either fully completes with all instructions successfully processed, or it fails entirely. If any instruction within the transaction fails, none of the instructions are executed.
+
+2. `Instructions`: An instruction is a request to perform a specific action on-chain and represents the smallest unit of execution logic within a program.
+
+ An instruction must include the following information -
+
+ - **Program Address:** It specifies the program being called.
+ - **Accounts:** Lists all accounts that the instruction will read from or write to, including other programs, using the AccountMeta struct.
+ - **Instruction Data:** A byte array that indicates which instruction handler on the program to invoke, along with any additional data required by the instruction handler (function arguments).
+
+Please refer to transactions and instructions details on [Transactions and Instructions](https://solana.com/docs/core/transactions).
+
+### Cross Program Invocation (CPI):
+
+A Cross Program Invocation (CPI) occurs when one program calls the instructions of another program. This mechanism enables the **_Composability_** of Solana programs.
+
+Some important points to note about CPI -
+
+1. CPIs allow Solana program instructions to directly call instructions on another program.
+2. Signer privileges from the calling program are extended to the called program.
+3. When performing a CPI, programs can "sign" on behalf of PDAs derived from their own program ID.
+4. The called program can make additional CPIs to other programs, with a maximum depth of 4.
+
+Please refer to the details about CPI on [Cross Program Invocation](https://solana.com/docs/core/cpi).
diff --git a/docs/composability/using_composability/setup_configure.md b/docs/composability/using_composability/setup_configure.md
new file mode 100644
index 00000000..f68d03eb
--- /dev/null
+++ b/docs/composability/using_composability/setup_configure.md
@@ -0,0 +1,82 @@
+---
+title: 'Setup and Configure'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+import mm_p_key from '@site/static/img/doc-images/developing/deploy_facilities/foundry-metamask.png';
+
+## Introduction
+
+The tutorials on the next pages are based on the [Github example](https://github.com/neonlabsorg/neon-tutorials/tree/main/hardhat) and will walk you through them to test different Composability features on Neon EVM Devnet and Solana Devnet.
+
+- [TestCallSolana.sol](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/contracts/TestCallSolana/TestCallSolana.sol) - This is a solidity smart contract which interacts with the precompile `0xFF00000000000000000000000000000000000006` via the `ICallSolana.sol` interface contract described in details [here](docs/composability/call_solana_interface.md).
+- [config.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/config.js) - This is a script which includes the contract address of the deployed `TestCallSolana.sol` and the helper functions required to execute the instructions on Solana via the deployed smart contract.
+
+### Step 1: Installation
+
+> **Note:** For more details on installing Hardhat, refer to the [_Hardhat documentation_](https://hardhat.org/hardhat-runner/docs/getting-started#overview).
+
+Using Git, clone the example Hardhat project from the remote repository and navigate to it:
+
+```sh
+git clone https://github.com/neonlabsorg/neon-tutorials
+cd neon-tutorials/hardhat
+```
+
+Then, run the following command:
+
+```sh
+npm install
+```
+
+This will install all the necessary packages to continue with the example tutorials. These packages include the `Hardhat` library and most importantly `@solana/web3.js` .
+
+If the above command results in an error, run:
+
+```sh
+npm cache clear --force
+npm install
+```
+
+**About `@solana/web3.js` library:**
+
+In our tutorials, we use the @solana/web3.js library because it's an invaluable tool for preparing and passing Solana instructions to on-chain requests. This library supports a comprehensive set of instructions essential for the development cycle. We strongly recommend using it as it formats the instructions in the exact way that the Composability precompile expects.
+
+### Step 2: Set Up MetaMask Accounts
+
+:::info
+This step requires an EVM-compatible wallet such as MetaMask, connected to Neon Devnet, with a balance in Devnet NEON available from [NeonFaucet](https://neonfaucet.org/).
+
+The following tutorials will assist you to meet these prerequisites:
+
+- Learn how to [install a MetaMask wallet and connect it to Devnet](/docs/wallet/metamask_setup)
+- Or [connect an existing wallet to Devnet](/docs/developing/connect_rpc#connect-via-chainlist)
+
+:::
+
+2.1 Obtain the private key for your wallet account.
+
+> To obtain the private key from MetaMask, from the hamburger menu, click **Account Details** > **Show Private Key**, enter your password, and click **Confirm** for access to the private key for that account.
+>
+
+2.2 Create a .env file and add these lines:
+
+```sh
+PRIVATE_KEY_OWNER=`YOUR_PRIVATE_KEY`
+USER1_KEY=`2ND_PRIVATE_KEY`
+```
+
+:::important
+Replace `OWNER_PRIVATE_KEY` and `2ND_PRIVATE_KEY` with the private keys of your wallet.
+:::
+
+### Step 3: Compile Contracts
+
+All of the contracts are located in the project's `contracts/` directory. Before these contracts can be run, they must first be compiled. To compile the project's contracts, run the following command:
+
+```sh
+npx hardhat compile
+```
diff --git a/docs/composability/using_composability/swap_on_orca.md b/docs/composability/using_composability/swap_on_orca.md
new file mode 100644
index 00000000..16c07151
--- /dev/null
+++ b/docs/composability/using_composability/swap_on_orca.md
@@ -0,0 +1,310 @@
+---
+title: 'Swap on Orca DEX'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+This tutorial will walk you through the steps of performing a swap on The Orca DEX where the input swap token is **devUSDC** and the output swap token is **devSAMO.**
+
+:::info
+You can request devUSDCs and devSAMO from https://everlastingsong.github.io/nebula/
+:::
+
+This example code is based on the script [OrcaSwap.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/OrcaSwap.js). This script is designed to perform a token swap on the [Orca decentralized exchange (DEX)](https://www.orca.so/) on the Solana blockchain. It uses the Anchor SDK to interact with the blockchain and requires specific environment variables to be set for execution.
+
+## How the script works
+
+Let us breakdown the main components of the script `OrcaSwap.js` to get into more depth of the process of swapping tokens on Orca DEX.
+
+### Initial Checks and Imports
+
+```jsx
+if (process.env.ANCHOR_PROVIDER_URL == undefined || process.env.ANCHOR_WALLET == undefined) {
+ return console.log(
+ "This script uses the @coral-xyz/anchor library which requires the variables ANCHOR_PROVIDER_URL and ANCHOR_WALLET to be set. Please create id.json in the root of the hardhat project with your Solana's private key and run the following command in the terminal in order to proceed with the script execution - export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com && export ANCHOR_WALLET=./id.json"
+ );
+}
+
+const { ethers } = require('hardhat');
+const web3 = require('@solana/web3.js');
+const { getAssociatedTokenAddress, getAccount } = require('@solana/spl-token');
+const { config } = require('./config');
+const { AnchorProvider } = require('@coral-xyz/anchor');
+const {
+ WhirlpoolContext,
+ buildWhirlpoolClient,
+ ORCA_WHIRLPOOL_PROGRAM_ID,
+ PDAUtil,
+ swapQuoteByInputToken,
+ IGNORE_CACHE,
+ getAllWhirlpoolAccountsForConfig,
+ WhirlpoolIx,
+ SwapUtils
+} = require('@orca-so/whirlpools-sdk');
+const { DecimalUtil, Percentage } = require('@orca-so/common-sdk');
+const { Decimal } = require('decimal.js');
+```
+
+This code block checks if the required environment variables `ANCHOR_PROVIDER_URL` and `ANCHOR_WALLET` are set. It then imports necessary libraries and modules. `ANCHOR_PROVIDER_URL` is Solana's RPC URL and `ANCHOR_WALLET` is Solana's private key in json byte array format.
+
+- Store your Solana’s private key in the file `id.json` and place it in the root of your hardhat project folder. This key will be used only for the Anchor SDK initialization, and not for signing or submitting any transactions.
+- Run this in your terminal -
+ ```bash
+ export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
+ export ANCHOR_WALLET=./id.json
+ ```
+
+### Setup and Initialization
+
+```jsx
+async function main() {
+ const [user1] = await ethers.getSigners();
+ const connection = new web3.Connection(config.SOLANA_NODE, "processed");
+ const provider = AnchorProvider.env();
+ const ctx = WhirlpoolContext.withProvider(provider, ORCA_WHIRLPOOL_PROGRAM_ID);
+ const client = buildWhirlpoolClient(ctx);
+ const DEVNET_WHIRLPOOLS_CONFIG = new web3.PublicKey("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
+
+ const TestCallSolanaFactory = await ethers.getContractFactory("TestCallSolana");
+ let TestCallSolanaAddress = config.CALL_SOLANA_SAMPLE_CONTRACT;
+ let TestCallSolana;
+ let solanaTx;
+ let tx;
+ let receipt;
+
+ if (ethers.isAddress(TestCallSolanaAddress)) {
+ TestCallSolana = TestCallSolanaFactory.attach(TestCallSolanaAddress);
+ } else {
+ TestCallSolana = await ethers.deployContract("TestCallSolana");
+ await TestCallSolana.waitForDeployment();
+
+ TestCallSolanaAddress = TestCallSolana.target;
+ console.log(`TestCallSolana deployed to ${TestCallSolana.target}`);
+ }
+```
+
+This block of code sets up the connection to the Solana blockchain and initializes the Anchor provider. It also creates or attaches to the already deployed `TestCallSolana` smart contract. It also defines the public key of the Orca pool contract account on Solana `DEVNET_WHIRLPOOLS_CONFIG` .
+
+### Retrieving Contract Public Key and Token Mints
+
+```jsx
+const contractPublicKeyInBytes = await TestCallSolana.getNeonAddress(TestCallSolanaAddress);
+const contractPublicKey = ethers.encodeBase58(contractPublicKeyInBytes);
+console.log(contractPublicKey, 'contractPublicKey');
+
+const TokenA = {
+ mint: new web3.PublicKey('Jd4M8bfJG3sAkd82RsGWyEXoaBXQP7njFzBwEaCTuDa'),
+ decimals: 9
+}; // devSAMO
+const TokenB = {
+ mint: new web3.PublicKey('BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k'),
+ decimals: 6
+}; // devUSDC
+```
+
+This code block retrieves the public key for the `TestCallSolana` contract and sets up the token mint addresses for devSAMO and devUSDC.
+
+### Whirlpool Configuration
+
+```jsx
+const whirlpool_pubkey = PDAUtil.getWhirlpool(
+ ORCA_WHIRLPOOL_PROGRAM_ID,
+ DEVNET_WHIRLPOOLS_CONFIG,
+ TokenA.mint, // devSAMO
+ TokenB.mint, // devUSDC
+ 64 // tick spacing
+).publicKey;
+const whirlpool = await client.getPool(whirlpool_pubkey);
+```
+
+This section configures the Whirlpool for the specified tokens and retrieves the Whirlpool client.
+
+### Checking and Initializing Token Accounts
+
+```jsx
+const amountIn = new Decimal('0.1'); // 0.1 devUSDC
+
+const ataContractTokenA = await getAssociatedTokenAddress(
+ TokenA.mint,
+ new web3.PublicKey(contractPublicKey),
+ true
+);
+let ataContractTokenAInfo = await connection.getAccountInfo(ataContractTokenA);
+
+const ataContractTokenB = await getAssociatedTokenAddress(
+ TokenB.mint,
+ new web3.PublicKey(contractPublicKey),
+ true
+);
+
+let ataContractTokenBInfo = await connection.getAccountInfo(ataContractTokenB);
+if (!ataContractTokenAInfo || !ataContractTokenBInfo) {
+ if (!ataContractTokenAInfo) {
+ console.log(
+ 'Account ' + contractPublicKey + ' does not have initialized ATA account for TokenA.'
+ );
+ }
+ if (!ataContractTokenBInfo) {
+ console.log(
+ 'Account ' + contractPublicKey + ' does not have initialized ATA account for TokenB.'
+ );
+ }
+ return;
+} else if (
+ Number((await getAccount(connection, ataContractTokenB)).amount) <
+ Number(DecimalUtil.toBN(amountIn, TokenB.decimals))
+) {
+ console.log(
+ 'Account ' +
+ contractPublicKey +
+ ' does not have enough TokenB amount to proceed with the swap execution.'
+ );
+ return;
+}
+```
+
+This section computes the contract’s Associated Token Addresses (ATAs) for devSAMO and devUSDC and checks if they are initialized. It also ensures the contract's account has enough devUSDC balance for the swap.
+
+If the contract’s ATA’s are not initialized for both the tokens devSAMO and devUSDC, then follow the steps below -
+
+- Open `CreateATA.js` file and add devSAMO account address `Jd4M8bfJG3sAkd82RsGWyEXoaBXQP7njFzBwEaCTuDa` to this variable -
+ ```jsx
+ const tokenMintPublicKey = '';
+ ```
+ Run `npx hardhat run scripts/TestCallSolana/CreateATA.js --network neondevnet` and this will create an ATA for the contract for devSAMO.
+- Repeat the previous step for devUSDC account address `BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k` to create an ATA for the contract for devUSDC.
+
+### Swap Estimation and Execution
+
+```jsx
+ const quote = await swapQuoteByInputToken(
+ whirlpool,
+ TokenB.mint, // devUSDC
+ DecimalUtil.toBN(amountIn, TokenB.decimals), // Input Token Mint amount
+ Percentage.fromFraction(10, 1000), // Acceptable slippage (10/1000 = 1%)
+ ctx.program.programId,
+ ctx.fetcher,
+ IGNORE_CACHE
+ );
+ console.log(quote, 'quote');
+
+ console.log("estimatedAmountIn:", DecimalUtil.fromBN(quote.estimatedAmountIn, TokenB.decimals).toString(), "TokenB");
+ console.log("estimatedAmountOut:", DecimalUtil.fromBN(quote.estimatedAmountOut, TokenA.decimals).toString(), "TokenA");
+ console.log("otherAmountThreshold:", DecimalUtil.fromBN(quote.otherAmountThreshold, TokenA.decimals).toString(), "TokenA");
+
+ console.log('Executing executeComposabilityMethod with Orca\'s swap instruction ...');
+ solanaTx = new web3.Transaction();
+ solanaTx.add(
+ WhirlpoolIx.swapIx(
+ ctx.program,
+ SwapUtils.getSwapParamsFromQuote(
+ quote,
+ ctx,
+ whirlpool,
+ ataContractTokenB,
+ ataContractTokenA,
+ new web3.PublicKey(contractPublicKey)
+ )
+ )
+ );
+
+ [tx, receipt] = await config.utils.executeComposabilityMethod(
+ solanaTx.instructions[0],
+ 0,
+ TestCallSolana,
+ undefined,
+ user1
+ );
+ console.log(tx, 'tx');
+ console.log(receipt.logs[0].args, 'receipt args');
+}
+```
+
+This code block obtains a swap quote for the input amount, logs the estimation details, prepares the swap instruction, and executes the transaction.
+
+## How to run the script
+
+To test the example script `OrcaSwap.js` , run this command in the terminal -
+
+```bash
+npx hardhat run scripts/TestCallSolana/OrcaSwap.js --network neondevnet
+```
+
+After running the above command successfully, you should get the output similar to this -
+
+```bash
+54Mfrfbv16neQhrP7o29FnsAfEtmLitTDG7fuP71YKYL contractPublicKey
+{
+ estimatedAmountIn: ,
+ estimatedAmountOut: ,
+ estimatedEndTickIndex: -115126,
+ estimatedEndSqrtPrice: ,
+ estimatedFeeAmount: ,
+ amount: ,
+ amountSpecifiedIsInput: true,
+ aToB: false,
+ otherAmountThreshold: ,
+ sqrtPriceLimit: ,
+ tickArray0: PublicKey [PublicKey(9H4aVdyXbnnmbSJLjYahvZzrgdHyWVMq8i1v1fD7jqBt)] {
+ _bn:
+ },
+ tickArray1: PublicKey [PublicKey(9H4aVdyXbnnmbSJLjYahvZzrgdHyWVMq8i1v1fD7jqBt)] {
+ _bn:
+ },
+ tickArray2: PublicKey [PublicKey(9H4aVdyXbnnmbSJLjYahvZzrgdHyWVMq8i1v1fD7jqBt)] {
+ _bn:
+ }
+} quote
+estimatedAmountIn: 0.1 TokenB
+estimatedAmountOut: 9.970350988 TokenA
+otherAmountThreshold: 9.871634641 TokenA
+Executing executeComposabilityMethod with Orca's swap instruction ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x8c546929ba84ac22b38c310c2f670696a02c5594d9d006698e7c1c20d07e41b0',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23142,
+ gasLimit: 165000n,
+ gasPrice: 256947462431n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x121f31510e03685f8e909053e458121c66f5a76aedc7706aa11c82f8aa952a8f2b7879a900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000004e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000cb644ca2669849d7472e9b7f94dcbe8368a8a265c3d2af8a922c7bb242d5dc2f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e232db5b493652f09b55c17fb53aab8443178034742f1526722752d6a9ecfd400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88322e785613ef2c35786bf91d8006a035fb7312bc3a6684bffbda93b1ad6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000179698dd5a7e6625086e3be1203de392b1a65a23a5d1099ec5a28318e2a4e88b800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001313e1c144a550aeaa99a29830910036800efbb8af592a87d705fe7938698f1c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017afad55b43064520bec49256da6fc91853aa00fe5a354d830b032b08f3817427000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017afad55b43064520bec49256da6fc91853aa00fe5a354d830b032b08f3817427000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017afad55b43064520bec49256da6fc91853aa00fe5a354d830b032b08f38174270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000127116a2b94f55339f566164cb265fd3ab70d4b91e594e8c555a3be76d69e9ecb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002af8c69e91e17587c8a086010000000000d130654c02000000af331ba8327fbb35b1c4feff00000000010000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0xfb762b500e4a7551102f7cebfe17d207317496853240ded7283f2851c07d41f2", s: "0x6adcaeb774f416206b4b2f6970b32a7d0573d3cc74a5465865040ef86f48ffe6", yParity: 1, networkV: 490045888 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+```
+
+:::important
+The full code of the script can be viewed here [OrcaSwap.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/OrcaSwap.js).
+:::
diff --git a/docs/composability/using_composability/transfer_sols.md b/docs/composability/using_composability/transfer_sols.md
new file mode 100644
index 00000000..357d4dd2
--- /dev/null
+++ b/docs/composability/using_composability/transfer_sols.md
@@ -0,0 +1,383 @@
+---
+title: 'Transfer SOLs between accounts'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+This tutorial will walk you through the steps of creating two accounts on Solana using the `createAccountWithSeed` instruction and then transferring 1 SOL from one account to the other using a solidity smart contract on Neon EVM Devnet.
+
+This example code is based on the script [TransferSOLsBetweenAccounts.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/TransferSOLsBetweenAccounts.js). This script is designed to demonstrate the creation of two accounts (SenderAccount and ReceiverAccount) on the Solana blockchain and perform a couple of SOL transfer transactions involving these accounts.
+
+## How the script works
+
+Let us breakdown the main components of the script `TransferSOLsBetweenAccounts.js` to get into more depth of the process of transferring of SOLs from one account to another.
+
+### Importing Dependencies
+
+```jsx
+const { ethers } = require('hardhat');
+const web3 = require('@solana/web3.js');
+const { config } = require('./config');
+```
+
+These lines import the necessary libraries: `ethers` for Ethereum-related operations, `@solana/web3.js` for Solana operations, and the configuration file.
+
+### Establishing Connection
+
+```jsx
+const connection = new web3.Connection(config.SOLANA_NODE, 'processed');
+```
+
+This establishes a connection to the Solana node specified in the configuration file.
+
+### Getting Signers and Contract Factory
+
+```jsx
+const [user1] = await ethers.getSigners();
+const TestCallSolanaFactory = await ethers.getContractFactory('TestCallSolana');
+```
+
+This gets the signer from the `ethers` library and retrieves the contract factory for deploying or interacting with the `TestCallSolana.sol` contract.
+
+### Deploying or Attaching to the Contract
+
+```jsx
+let TestCallSolanaAddress = config.CALL_SOLANA_SAMPLE_CONTRACT;
+let TestCallSolana;
+
+if (ethers.isAddress(TestCallSolanaAddress)) {
+ TestCallSolana = TestCallSolanaFactory.attach(TestCallSolanaAddress);
+} else {
+ TestCallSolana = await ethers.deployContract('TestCallSolana');
+ await TestCallSolana.waitForDeployment();
+ TestCallSolanaAddress = TestCallSolana.target;
+ console.log(`TestCallSolana deployed to ${TestCallSolana.target}`);
+}
+```
+
+This block of code either attaches to an existing contract or deploys a new one if the address is not valid.
+
+### Getting Payer and Contract Public Key
+
+```jsx
+const payer = ethers.encodeBase58(await TestCallSolana.getPayer());
+const contractPublicKeyInBytes = await TestCallSolana.getNeonAddress(TestCallSolanaAddress);
+const contractPublicKey = ethers.encodeBase58(contractPublicKeyInBytes);
+```
+
+This retrieves the payer address and the public key of the contract in base58 encoding.
+
+### Calculating Minimum Balance for Rent Exemption
+
+```jsx
+const minBalance = await connection.getMinimumBalanceForRentExemption(0);
+```
+
+This gets the minimum balance required for an account to be rent-exempt on Solana.
+
+### Creating Accounts with Seed
+
+```jsx
+const seedSender = 'salt' + Date.now().toString();
+const seedReceiver = seedSender + '1';
+
+const SenderAccount = await web3.PublicKey.createWithSeed(
+ new web3.PublicKey(contractPublicKey),
+ seedSender,
+ web3.SystemProgram.programId
+);
+const ReceiverAccount = await web3.PublicKey.createWithSeed(
+ new web3.PublicKey(contractPublicKey),
+ seedReceiver,
+ web3.SystemProgram.programId
+);
+```
+
+These lines generate unique seeds, `seedSender` and `seedReceiver` , for the sender and receiver accounts and create the public keys for these accounts using the seeds.
+
+### Checking and Creating Accounts if Necessary
+
+```jsx
+const senderAccountData = await connection.getAccountInfo(SenderAccount);
+const receiverAccountData = await connection.getAccountInfo(ReceiverAccount);
+
+// if sender's account has not been created yet
+if (senderAccountData == null) {
+ console.log('Creating SenderAccount through createAccountWithSeed instruction ...');
+ solanaTx = new web3.Transaction();
+ solanaTx.add(
+ web3.SystemProgram.createAccountWithSeed({
+ fromPubkey: new web3.PublicKey(payer),
+ basePubkey: new web3.PublicKey(contractPublicKey),
+ newAccountPubkey: SenderAccount,
+ seed: seedSender,
+ lamports: minBalance, // rent exempt
+ space: 0,
+ programId: web3.SystemProgram.programId
+ })
+ );
+ [tx, receipt] = await config.utils.executeComposabilityMethod(
+ solanaTx.instructions[0],
+ minBalance,
+ TestCallSolana,
+ undefined,
+ owner
+ );
+ console.log(tx, 'tx');
+ console.log(receipt.logs[0].args, 'receipt args');
+}
+
+// if receiver's account has not been created yet
+if (receiverAccountData == null) {
+ console.log('Creating ReceiverAccount through createAccountWithSeed instruction ...');
+ solanaTx = new web3.Transaction();
+ solanaTx.add(
+ web3.SystemProgram.createAccountWithSeed({
+ fromPubkey: new web3.PublicKey(payer),
+ basePubkey: new web3.PublicKey(contractPublicKey),
+ newAccountPubkey: ReceiverAccount,
+ seed: seedReceiver,
+ lamports: minBalance, // rent exempt
+ space: 0,
+ programId: web3.SystemProgram.programId
+ })
+ );
+ [tx, receipt] = await config.utils.executeComposabilityMethod(
+ solanaTx.instructions[0],
+ minBalance,
+ TestCallSolana,
+ undefined,
+ owner
+ );
+ console.log(tx, 'tx');
+ console.log(receipt.logs[0].args, 'receipt args');
+}
+```
+
+This checks if the accounts already exist. If not, it creates them using the `createAccountWithSeed` instruction.
+
+### Funding Sender Account with SOL
+
+```jsx
+const amount = 1000000000; // 1 SOL
+solanaTx = new web3.Transaction();
+solanaTx.add(
+ web3.SystemProgram.transfer({
+ fromPubkey: new web3.PublicKey(payer),
+ toPubkey: new web3.PublicKey(SenderAccount),
+ lamports: amount
+ })
+);
+```
+
+This funds the `SenderAccount` with 1 SOL from the payer.
+
+### Transferring SOL from Sender to Receiver
+
+```jsx
+solanaTx.add(
+ web3.SystemProgram.transfer({
+ fromPubkey: SenderAccount,
+ basePubkey: new web3.PublicKey(contractPublicKey),
+ toPubkey: ReceiverAccount,
+ lamports: amount,
+ seed: seedSender,
+ programId: web3.SystemProgram.programId
+ })
+);
+```
+
+This adds an instruction to transfer 1 SOL from the `SenderAccount` to the `ReceiverAccount`.
+
+### Executing Transactions
+
+```jsx
+console.log('Executing batchExecuteComposabilityMethod with all instructions ...');
+[tx, receipt] = await config.utils.batchExecuteComposabilityMethod(
+ solanaTx.instructions,
+ [amount, 0],
+ TestCallSolana,
+ undefined,
+ owner
+);
+```
+
+This executes the batch of transactions, including funding the `SenderAccount` and transferring SOL to the `ReceiverAccount`.
+
+## How to run the script
+
+To test the example script `TransferSOLsBetweenAccounts.js` , run this command in the terminal -
+
+```bash
+npx hardhat run scripts/TestCallSolana/TransferSOLsBetweenAccounts.js --network neondevnet
+```
+
+After running the above command successfully, you should get the output similar to this -
+
+```bash
+4FiNE9Rj3nKCBWmJgQVte7hRoSt2TeMNFe8FzZpsgnDD payer
+54Mfrfbv16neQhrP7o29FnsAfEtmLitTDG7fuP71YKYL contractPublicKey
+890880 minBalance
+PublicKey [PublicKey(5YqXxPNAy8kd2WZRR3mPsE6iUbX7uiFo7oDtzWfKkh8r)] {
+ _bn:
+} SenderAccount
+PublicKey [PublicKey(7EhujXfAQ16KAoyLBtHyukkWTf6m9v1Hx9Jix1DSP1qB)] {
+ _bn:
+} ReceiverAccount
+Creating SenderAccount through createAccountWithSeed instruction ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0xf13646a5ee2131f34bfa4c56774c6a2d5ef372036a74af53bcae1096466e819f',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23127,
+ gasLimit: 980880n,
+ gasPrice: 240531817980n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x121f3151000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d9800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014396a149293487b0ac9142284b9d73c18be3cf3ac873be72ae4f338f66fa93bf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d030000003c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9110000000000000073616c743137313932333237343230303500980d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0x57a11b47d638cdae7d67e747548a501dd4ea5e8605ca11f80cfdf0f621d5792e", s: "0x677db2cb039f71ca3f1dcc058d1c71484d3ebf05df03ceb93794b7542d43217b", yParity: 1, networkV: 490045888 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+Creating ReceiverAccount through createAccountWithSeed instruction ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x293eeda18afee57a5f23aa61f2f52ea3e7f2680719fcbec0dc4d384e009cf660',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23128,
+ gasLimit: 980880n,
+ gasPrice: 240433899348n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x121f3151000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000d9800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000015ca8eda1bd5f2405805847cbecab552247f8cfb6ae4ac9862bf67477d9a670ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e030000003c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9120000000000000073616c74313731393233323734323030353100980d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0xabd472ac74b40a5431e3c526bc5cee9346ece8b5b1050b55275a97e89e55a5e4", s: "0x41602c22715ea1987526419f22ca42ae3ada06e80bcd262c63689292cb07f8df", yParity: 1, networkV: 490045888 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+{
+ data: ,
+ executable: false,
+ lamports: 890880,
+ owner: PublicKey [PublicKey(11111111111111111111111111111111)] {
+ _bn:
+ },
+ rentEpoch: 18446744073709552000,
+ space: 0
+} getAccountInfo SenderAccount
+{
+ data: ,
+ executable: false,
+ lamports: 890880,
+ owner: PublicKey [PublicKey(11111111111111111111111111111111)] {
+ _bn:
+ },
+ rentEpoch: 18446744073709552000,
+ space: 0
+} getAccountInfo SenderAccount
+Executing batchExecuteComposabilityMethod with all instructions ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x266e43f084a81bba13d7da77d808029d3502acd6edcc333453733f862cf89daf',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23129,
+ gasLimit: 1000185000n,
+ gasPrice: 240400985720n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x59cfc5e400000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000023057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014396a149293487b0ac9142284b9d73c18be3cf3ac873be72ae4f338f66fa93bf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000034396a149293487b0ac9142284b9d73c18be3cf3ac873be72ae4f338f66fa93bf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000005ca8eda1bd5f2405805847cbecab552247f8cfb6ae4ac9862bf67477d9a670ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c0200000000ca9a3b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450b00000000ca9a3b00000000110000000000000073616c743137313932333237343230303500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0x2b3a2fba9eeed450aefd68097add3a0aba34b6a8b7d67c327bf627253ec2c2aa", s: "0x6ae14fe47acf41ffb71d01eb0cafc70f0fd2657fcfd41629f09ef8f71d85090b", yParity: 1, networkV: 490045888 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args instruction # 0
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args instruction # 1
+```
+
+:::important
+The full code of the script can be viewed here [TransferSOLsBetweenAccounts.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/TransferSOLsBetweenAccounts.js).
+:::
diff --git a/docs/composability/using_composability/transfer_spl_token.md b/docs/composability/using_composability/transfer_spl_token.md
new file mode 100644
index 00000000..041c64ee
--- /dev/null
+++ b/docs/composability/using_composability/transfer_spl_token.md
@@ -0,0 +1,432 @@
+---
+title: 'Transfer SPL Token between accounts'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+This tutorial will walk you through the steps of creating two accounts on Solana using the `createAccountWithSeed` instruction, minting an SPL token to one account and then transferring the SPL token from that account to another using a solidity smart contract on Neon EVM Devnet.
+
+This example code is based on the script [TransferSPLTokenBetweenAccounts.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/TransferSPLTokenBetweenAccounts.js). This script demonstrates creating two accounts on Solana using the `createAccountWithSeed` instruction, minting tokens to one account, and transferring those tokens to another account. It illustrates the process of handling SPL Token transfers between accounts. For this example, we are using an SPL Token with account address `8LkbY4Q1jGEF1BwedHz1ALM3q4zZRhZpCMWRe6SbrbKj` on Solana Devnet.
+
+## How the script works
+
+Let us breakdown the main components of the script `TransferSPLTokenBetweenAccounts.js` to get into more depth of the process of minting and transferring of an SPL Token from one account to another.
+
+### Importing Dependencies
+
+```jsx
+const { ethers } = require('hardhat');
+const web3 = require('@solana/web3.js');
+const { config } = require('./config');
+const {
+ ACCOUNT_SIZE,
+ TOKEN_PROGRAM_ID,
+ createMintToInstruction,
+ createTransferInstruction,
+ createInitializeAccount2Instruction
+} = require('@solana/spl-token');
+```
+
+These lines import the necessary libraries: `ethers` for Ethereum-related operations, `@solana/web3.js` and `@solana/spl-token` for Solana operations, and the configuration file.
+
+### Establishing Connection
+
+```jsx
+const connection = new web3.Connection(config.SOLANA_NODE, 'processed');
+```
+
+This establishes a connection to the Solana node specified in the configuration file.
+
+### Getting Signers, Contract Factory and the SPL Token account
+
+```jsx
+const [user1, user2] = await ethers.getSigners();
+const tokenMintPublicKey = '8LkbY4Q1jGEF1BwedHz1ALM3q4zZRhZpCMWRe6SbrbKj';
+if (tokenMintPublicKey == '') {
+ return console.error(
+ 'Before proceeding with instructions execution please set value for the tokenMintPublicKey variable.'
+ );
+}
+const token = new web3.PublicKey(tokenMintPublicKey);
+
+const TestCallSolanaFactory = await ethers.getContractFactory('TestCallSolana');
+```
+
+This gets the signers from the `ethers` library, retrieves the contract factory for deploying or interacting with the `TestCallSolana.sol` contract and also retrieves the SPL Token account public key.
+
+### Deploying or Attaching to the Contract
+
+```jsx
+let TestCallSolanaAddress = config.CALL_SOLANA_SAMPLE_CONTRACT;
+let TestCallSolana;
+let solanaTx;
+let tx;
+let receipt;
+
+if (ethers.isAddress(TestCallSolanaAddress)) {
+ TestCallSolana = TestCallSolanaFactory.attach(TestCallSolanaAddress);
+} else {
+ TestCallSolana = await ethers.deployContract('TestCallSolana');
+ await TestCallSolana.waitForDeployment();
+
+ TestCallSolanaAddress = TestCallSolana.target;
+ console.log(`TestCallSolana deployed to ${TestCallSolana.target}`);
+}
+```
+
+This block of code either attaches to an existing contract or deploys a new one if the address is not valid.
+
+### Getting Payer and Contract Public Key
+
+```jsx
+const payer = ethers.encodeBase58(await TestCallSolana.getPayer());
+const contractPublicKeyInBytes = await TestCallSolana.getNeonAddress(TestCallSolanaAddress);
+const contractPublicKey = ethers.encodeBase58(contractPublicKeyInBytes);
+```
+
+This retrieves the payer address and the public key of the contract in base58 encoding.
+
+### Calculating Minimum Balance for Rent Exemption
+
+```jsx
+const minBalance = await connection.getMinimumBalanceForRentExemption(0);
+```
+
+This gets the minimum balance required for an account to be rent-exempt on Solana.
+
+### Creating Accounts with Seed
+
+```jsx
+const seedSender = 'salt' + Date.now().toString();
+const seedReceiver = seedSender + '1';
+
+const SenderAccount = await web3.PublicKey.createWithSeed(
+ new web3.PublicKey(contractPublicKey),
+ seedSender,
+ web3.SystemProgram.programId
+);
+const ReceiverAccount = await web3.PublicKey.createWithSeed(
+ new web3.PublicKey(contractPublicKey),
+ seedReceiver,
+ web3.SystemProgram.programId
+);
+```
+
+These lines generate unique seeds, `seedSender` and `seedReceiver` , for the sender and receiver accounts and create the public keys for these accounts using the seeds.
+
+### Checking and Creating Accounts (ATAs and Token Accounts) if Necessary
+
+```jsx
+const senderAccountData = await connection.getAccountInfo(SenderAccount);
+const receiverAccountData = await connection.getAccountInfo(ReceiverAccount);
+
+// if sender's account has not been created yet
+if (senderAccountData == null) {
+ console.log('Creating SenderAccount through createAccountWithSeed instruction ...');
+ solanaTx = new web3.Transaction();
+ solanaTx.add(
+ web3.SystemProgram.createAccountWithSeed({
+ fromPubkey: new web3.PublicKey(payer),
+ basePubkey: new web3.PublicKey(contractPublicKey),
+ newAccountPubkey: SenderAccount,
+ seed: seedSender,
+ lamports: minBalance,
+ space: ACCOUNT_SIZE,
+ programId: TOKEN_PROGRAM_ID
+ })
+ );
+
+ solanaTx.add(
+ createInitializeAccount2Instruction(SenderAccount, token, new web3.PublicKey(contractPublicKey))
+ );
+
+ [tx, receipt] = await config.utils.batchExecuteComposabilityMethod(
+ solanaTx.instructions,
+ [minBalance, 0],
+ TestCallSolana,
+ undefined,
+ user1
+ );
+ console.log(tx, 'tx');
+ console.log(receipt.logs[0].args, 'receipt args');
+ console.log(receipt.logs[1].args, 'receipt args');
+}
+
+// if receiver's account has not been created yet
+if (receiverAccountData == null) {
+ console.log('Creating ReceiverAccount through createAccountWithSeed instruction ...');
+ solanaTx = new web3.Transaction();
+ solanaTx.add(
+ web3.SystemProgram.createAccountWithSeed({
+ fromPubkey: new web3.PublicKey(payer),
+ basePubkey: new web3.PublicKey(contractPublicKey),
+ newAccountPubkey: ReceiverAccount,
+ seed: seedReceiver,
+ lamports: minBalance,
+ space: ACCOUNT_SIZE,
+ programId: TOKEN_PROGRAM_ID
+ })
+ );
+
+ solanaTx.add(
+ createInitializeAccount2Instruction(
+ ReceiverAccount,
+ token,
+ new web3.PublicKey(contractPublicKey)
+ )
+ );
+
+ [tx, receipt] = await config.utils.batchExecuteComposabilityMethod(
+ solanaTx.instructions,
+ [minBalance, 0],
+ TestCallSolana,
+ undefined,
+ user1
+ );
+ console.log(tx, 'tx');
+ console.log(receipt.logs[0].args, 'receipt args');
+ console.log(receipt.logs[1].args, 'receipt args');
+}
+
+console.log(await connection.getAccountInfo(SenderAccount), 'getAccountInfo SenderAccount');
+console.log(await connection.getAccountInfo(ReceiverAccount), 'getAccountInfo SenderAccount');
+```
+
+This checks if the accounts already exist. If not, it creates them using the `createAccountWithSeed` instruction. This also creates a Token Account for the `SenderAccount` and `ReceiverAccount` for the SPL Token with respect to the contract.
+
+### Minting Tokens to the SenderAccount
+
+```jsx
+console.log('Minting SPL Tokens to SenderAccount and transferring them to ReceiverAccount...');
+solanaTx = new web3.Transaction();
+solanaTx.add(
+ createMintToInstruction(
+ token,
+ SenderAccount,
+ new web3.PublicKey(contractPublicKey),
+ 1000 * 10 ** 9 // mint 1000 tokens
+ )
+);
+```
+
+This block of code mints 1000 tokens to `SenderAccount`.
+
+### Transferring Tokens from SenderAccount to ReceiverAccount
+
+```jsx
+solanaTx.add(
+ createTransferInstruction(
+ SenderAccount,
+ ReceiverAccount,
+ contractPublicKey,
+ 10 * 10 ** 9, // transfers 10 tokens
+ []
+ )
+);
+```
+
+This code block transfers 10 tokens from `SenderAccount` to `ReceiverAccount`.
+
+### Executing Transactions
+
+```jsx
+console.log('Executing batchExecuteComposabilityMethod ...');
+[tx, receipt] = await config.utils.batchExecuteComposabilityMethod(
+ solanaTx.instructions,
+ [0, 0, 0, 0, 0],
+ TestCallSolana,
+ undefined,
+ user1
+);
+```
+
+This executes the batch of transactions, including minting SPL Token to the `SenderAccount` and transferring SPL Token from `SenderAccount` to the `ReceiverAccount`.
+
+## How to run the script
+
+To test the example script `TransferSPLTokenBetweenAccounts.js` , run this command in the terminal -
+
+```bash
+npx hardhat run scripts/TestCallSolana/TransferSPLTokenBetweenAccounts.js --network neondevnet
+```
+
+After running the above command successfully, you should get the output similar to this -
+
+```bash
+4FiNE9Rj3nKCBWmJgQVte7hRoSt2TeMNFe8FzZpsgnDD payer
+54Mfrfbv16neQhrP7o29FnsAfEtmLitTDG7fuP71YKYL contractPublicKey
+2039280 minBalance
+PublicKey [PublicKey(5FhKDhKNZWtYq2mRUEm6FgwrFTMdu52bRqXss31wykw5)] {
+ _bn:
+} SenderAccount
+PublicKey [PublicKey(GJxCHgh814MgbzztZzzWNzHuS22PqvM8wW2Z3mNJMdib)] {
+ _bn:
+} ReceiverAccount
+Creating SenderAccount through createAccountWithSeed instruction ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0xb091f3a5c3d4e000d95bd149c7f98ce518b60262311be5b490523a2d693a8dcb',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23139,
+ gasLimit: 2234280n,
+ gasPrice: 255970522754n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x59cfc5e400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000033057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000013f32765caee0fe06ea9c34fc0fa68ef11468029c0a1e5b1b64b242eebeb012ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033f32765caee0fe06ea9c34fc0fa68ef11468029c0a1e5b1b64b242eebeb012ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016d11232b2c3c728347030537ca3de7dbce997aed3dec98b863b180ab1192a32e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006d030000003c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9110000000000000073616c7431373139343333383135363431f01d1f0000000000a50000000000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021103c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001f1df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0x3e25ceffc80be57819cd45f98e2ebabb94ed77f00581caa9cccc92d55b52e211", s: "0x25f0f27067d0516e035057d6629a7c9c77ae285d281c1cb7180a7a9172fb1273", yParity: 0, networkV: 490045887 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+Creating ReceiverAccount through createAccountWithSeed instruction ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x175650f95f0fcb89a5ff1792720474053672519ca6c8e7a375ecb26073112e55',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23140,
+ gasLimit: 2234280n,
+ gasPrice: 256208913865n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x59cfc5e400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000054000000000000000000000000000000000000000000000000000000000000005a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000033057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea3000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e378961e4791977a2a9307ad30e8aae05652bbb1f46a3173c0970e8b709607cc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e378961e4791977a2a9307ad30e8aae05652bbb1f46a3173c0970e8b709607cc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016d11232b2c3c728347030537ca3de7dbce997aed3dec98b863b180ab1192a32e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000006e030000003c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9120000000000000073616c743137313934333338313536343131f01d1f0000000000a50000000000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021103c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001f1df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0xc3169850f21b5fa07a73db2357a74447cfe22f8386c4e4c47655e3f01194fef4", s: "0x20f8cfe17aa2e415d3ba96c8fc1fcd821c0679499ca9dca099b81dd68d110f80", yParity: 1, networkV: 490045888 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+{
+ data: ,
+ executable: false,
+ lamports: 2039280,
+ owner: PublicKey [PublicKey(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)] {
+ _bn:
+ },
+ rentEpoch: 18446744073709552000,
+ space: 165
+} getAccountInfo SenderAccount
+{
+ data: ,
+ executable: false,
+ lamports: 2039280,
+ owner: PublicKey [PublicKey(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)] {
+ _bn:
+ },
+ rentEpoch: 18446744073709552000,
+ space: 165
+} getAccountInfo SenderAccount
+Minting SPLTokens to SenderAccount and transfering them to ReceiverAccount ...
+Executing batchExecuteComposabilityMethod ...
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x4f7b817631fcd27067c2d4aca5aa01ea2a77f8b198934b557d4e2a547bf1ccd2',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23141,
+ gasLimit: 195000n,
+ gasPrice: 256301137725n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x59cfc5e400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000206ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a906ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000036d11232b2c3c728347030537ca3de7dbce997aed3dec98b863b180ab1192a32e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013f32765caee0fe06ea9c34fc0fa68ef11468029c0a1e5b1b64b242eebeb012ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033f32765caee0fe06ea9c34fc0fa68ef11468029c0a1e5b1b64b242eebeb012ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e378961e4791977a2a9307ad30e8aae05652bbb1f46a3173c0970e8b709607cc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013c4adc98a3372450da1f1000ba8ec47c94f9533127f4b2589a40ebe7424de9b9000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000009070010a5d4e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090300e40b54020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0xb50acd94d4c01c27a738206a37763f7cc45ee52b2f4c82975145603dbdfd9eb7", s: "0x7cef71ea1e788239c18ecc20becd6a651af87447f81b24bd7f171f79efe52917", yParity: 0, networkV: 490045887 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args instruction # 0
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args instruction # 1
+```
+
+:::important
+The full code of the script can be viewed here [TransferSPLTokenBetweenAccounts.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/TransferSPLTokenBetweenAccounts.js).
+:::
diff --git a/docs/composability/using_composability/using_vrf.md b/docs/composability/using_composability/using_vrf.md
new file mode 100644
index 00000000..7f142a2c
--- /dev/null
+++ b/docs/composability/using_composability/using_vrf.md
@@ -0,0 +1,202 @@
+---
+title: 'Using Verifiable Random Function (VRF)'
+proofedDate: 20240627
+iterationBy: na
+includedInSite: false
+approvedBy: na
+---
+
+## Introduction
+
+This tutorial will walk you through the steps of requesting on-chain randomness on Solana using ORAO VRF (Verifiable Random Function) program.
+
+This example code is based on the script [OraoNetworkVRF.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/OraoNetworkVRF.js). This script is designed to submit a VRF request to the ORAO VRF network program. You can generate on-chain randomness on Solana with ORAO's Verifiable Random Function. This tool offers unbiased, fast, and affordable randomness for your Solana programs. You can use it to create unique NFT characteristics, generate random levels for games and weapons, randomize airdrops, and provide secure, verifiable lotteries. It is built using the Anchor framework.
+
+## How the script works
+
+Let us breakdown the main components of the script `OraoNetworkVRF.js` to get into more depth of the process of generating randomness on Solana using ORAO’s VRF.
+
+### Initial Checks and Imports
+
+```jsx
+if (process.env.ANCHOR_PROVIDER_URL == undefined || process.env.ANCHOR_WALLET == undefined) {
+ return console.log(
+ "This script uses the @coral-xyz/anchor library which requires the variables ANCHOR_PROVIDER_URL and ANCHOR_WALLET to be set. Please create id.json in the root of the hardhat project with your Solana's private key and run the following command in the terminal in order to proceed with the script execution - export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com && export ANCHOR_WALLET=./id.json"
+ );
+}
+
+const { ethers } = require('hardhat');
+const web3 = require('@solana/web3.js');
+const { config } = require('./config');
+const { AnchorProvider } = require('@coral-xyz/anchor');
+const { Orao } = require('@orao-network/solana-vrf');
+```
+
+This code block checks if the required environment variables `ANCHOR_PROVIDER_URL` and `ANCHOR_WALLET` are set. It then imports necessary libraries and modules. `ANCHOR_PROVIDER_URL` is Solana's RPC URL and `ANCHOR_WALLET` is Solana's private key in json byte array format.
+
+- Store your Solana’s private key in the file `id.json` and place it in the root of your hardhat project folder. This key will be used only for the Anchor SDK initialization, and not for signing or submitting any transactions.
+- Run this in your terminal -
+ ```bash
+ export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
+ export ANCHOR_WALLET=./id.json
+ ```
+
+### Setup and Initialization
+
+```jsx
+async function main() {
+ const [user1] = await ethers.getSigners();
+ const provider = AnchorProvider.env();
+ const vrf = new Orao(provider);
+
+ const TestCallSolanaFactory = await ethers.getContractFactory("TestCallSolana");
+ let TestCallSolanaAddress = config.CALL_SOLANA_SAMPLE_CONTRACT;
+ let TestCallSolana;
+ let solanaTx;
+ let tx;
+ let receipt;
+
+ if (ethers.isAddress(TestCallSolanaAddress)) {
+ TestCallSolana = TestCallSolanaFactory.attach(TestCallSolanaAddress);
+ } else {
+ TestCallSolana = await ethers.deployContract("TestCallSolana");
+ await TestCallSolana.waitForDeployment();
+
+ TestCallSolanaAddress = TestCallSolana.target;
+ console.log(
+ `TestCallSolana deployed to ${TestCallSolana.target}`
+ );
+ }
+```
+
+This block of code sets up the connection to the Solana blockchain and initializes the Anchor provider and an Orao VRF instance. It also creates or attaches to the already deployed `TestCallSolana` smart contract.
+
+### Getting Payer and Contract Public Key
+
+```jsx
+const payer = ethers.encodeBase58(await TestCallSolana.getPayer());
+console.log(payer, 'payer');
+
+const contractPublicKeyInBytes = await TestCallSolana.getNeonAddress(TestCallSolanaAddress);
+const contractPublicKey = ethers.encodeBase58(contractPublicKeyInBytes);
+console.log(contractPublicKey, 'contractPublicKey');
+```
+
+This block of code retrieves the payer and contract public key from the `TestCallSolana` contract.
+
+### Generating VRF Seed and Building Request
+
+```jsx
+const randomKeypair = web3.Keypair.generate();
+const seed = randomKeypair._keypair.publicKey; // use new generated keypair publicKey as VRF seed
+
+let req = await vrf.request(seed);
+let instruction = await req.build();
+```
+
+This code block generates a random keypair, and its public key is used as the VRF seed. A VRF request is then built using this seed.
+
+### Preparing and Submitting the Transaction
+
+```jsx
+const data = vrf.coder.instruction.encode('requestV2', { seed: instruction._args[0] });
+const programId = vrf.programId;
+const keys = [
+ { pubkey: new web3.PublicKey(payer), isSigner: true, isWritable: true },
+ { pubkey: instruction._accounts.networkState, isSigner: false, isWritable: true },
+ { pubkey: instruction._accounts.treasury, isSigner: false, isWritable: true },
+ { pubkey: instruction._accounts.request, isSigner: false, isWritable: true },
+ { pubkey: web3.SystemProgram.programId, isSigner: false, isWritable: false }
+];
+
+solanaTx = new web3.Transaction();
+solanaTx.add(
+ new web3.TransactionInstruction({
+ keys: keys,
+ programId: programId,
+ data: data
+ })
+);
+
+[tx, receipt] = await config.utils.executeComposabilityMethod(
+ solanaTx.instructions[0],
+ 7103920,
+ TestCallSolana,
+ undefined,
+ user1
+);
+console.log(tx, 'tx');
+console.log(receipt.logs[0].args, 'receipt args');
+```
+
+This section of code encodes the VRF request and prepares a transaction instruction, including the necessary keys and program ID. It then submits the transaction.
+
+### Waiting for Randomness and Outputting the Result
+
+```jsx
+ const randomness = await vrf.waitFulfilled(seed);
+ console.log(Buffer.from(randomness.randomness).readBigUInt64LE(), 'randomness');
+}
+```
+
+This section of code waits for the VRF request to be fulfilled and then outputs the generated randomness.
+
+## How to run the script
+
+To test the example script `OraoNetworkVRF.js` , run this command in the terminal -
+
+```bash
+npx hardhat run scripts/TestCallSolana/OraoNetworkVRF.js --network neondevnet
+```
+
+After running the above command successfully, you should get the output similar to this -
+
+```bash
+4FiNE9Rj3nKCBWmJgQVte7hRoSt2TeMNFe8FzZpsgnDD payer
+54Mfrfbv16neQhrP7o29FnsAfEtmLitTDG7fuP71YKYL contractPublicKey
+ContractTransactionResponse {
+ provider: HardhatEthersProvider {
+ _hardhatProvider: LazyInitializationProviderAdapter {
+ _providerFactory: [AsyncFunction (anonymous)],
+ _emitter: [EventEmitter],
+ _initializingPromise: [Promise],
+ provider: [BackwardsCompatibilityProviderAdapter]
+ },
+ _networkName: 'neondevnet',
+ _blockListeners: [],
+ _transactionHashListeners: Map(0) {},
+ _eventListeners: [],
+ _isHardhatNetworkCached: false,
+ _transactionHashPollingTimeout: undefined
+ },
+ blockNumber: null,
+ blockHash: null,
+ index: undefined,
+ hash: '0x9ddfafcab442ba954b8ff5100187c8f78c727f75a852c3605d86e9c050370552',
+ type: 0,
+ to: '0x004FB641e6C998Fc7dbdfB595F723727c8d07535',
+ from: '0x9CE2A03A7a258fB96d04Afb8Dd84b69A748B5959',
+ nonce: 23138,
+ gasLimit: 7213920n,
+ gasPrice: 253928464918n,
+ maxPriorityFeePerGas: null,
+ maxFeePerGas: null,
+ maxFeePerBlobGas: null,
+ data: '0x121f31510747b11afa91b4d1f922f27b0ebac1dab23b2129a4bef34f32a47b58f5cefc7800000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000006c65b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053057f6fad62a3ecae4e8d197bc418c4c578bca456ebeeaff45778fd91964ea30000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000013ede735db98b5ca2accac3bc1269e54b5409e5ea2c2bf6b2be0d80db10ee8f8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017f2dcd2aa425a24abf0d8fe12b60aa8f4768370d0fd99c738aefe6f2150f03b800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b245c746e0e26b8dc90f054fc08abda07b00ef400837ba3a9cd018f7825a02500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282697d106c3661cd9809d438e6a37aa86282621e719d1722e68e08dcf77f8fbc2df49bf340145006b000000000000000000000000000000000000000000000000',
+ value: 0n,
+ chainId: 245022926n,
+ signature: Signature { r: "0xb53f1976bcf6795a7c5468045782747995acc6e099c2acc77ad97793712fcd15", s: "0x78bcbc24ae253083588e6624725ed2000e580bcd7f81eadb04e7a127effcf43a", yParity: 0, networkV: 490045887 },
+ accessList: null,
+ blobVersionedHashes: null
+} tx
+Result(3) [
+ '0x',
+ '0x0000000000000000000000000000000000000000000000000000000000000000',
+ '0x'
+] receipt args
+17369911603807770235n randomness
+```
+
+:::important
+The full code of the script can be viewed here [OraoNetworkVRF.js](https://github.com/neonlabsorg/neon-tutorials/blob/main/hardhat/scripts/TestCallSolana/OraoNetworkVRF.js).
+:::
diff --git a/docs/evm_compatibility/json_rpc_api_methods.md b/docs/evm_compatibility/json_rpc_api_methods.md
index 04fa8e5d..1afe0717 100644
--- a/docs/evm_compatibility/json_rpc_api_methods.md
+++ b/docs/evm_compatibility/json_rpc_api_methods.md
@@ -62,6 +62,7 @@ Split this into standard ETH-supported methods // Not supported methods // AND a
| 39 | [eth_getTransactionByBlockNumberAndIndex](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyblocknumberandindex) | _Returns information about a transaction by block number and transaction index position_ | ![done](img/done.ico) |
| 40 | [eth_getTransactionReceipt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionrecepit) | _Returns the receipt of a transaction by transaction hash_ | ![done](img/done.ico) |
+Methods `eth_getTransactionByHash`, `eth_getTransactionByBlockHashAndIndex`, `eth_getTransactionByBlockNumberAndIndex`, `eth_getBlockByHash` and `eth_getBlockByNumber` also return the `chainId` property in addition to the [specified](https://ethereum.org/en/developers/docs/apis/json-rpc) output.
## JSON-RPC methods according to the [Web3 Module API](https://openethereum.github.io/JSONRPC-web3-module)
diff --git a/docs/faq/neon-brief-faq.md b/docs/faq/neon-brief-faq.md
index fa68415e..fb3f6f0d 100644
--- a/docs/faq/neon-brief-faq.md
+++ b/docs/faq/neon-brief-faq.md
@@ -17,7 +17,7 @@ Neon EVM is an Ethereum Virtual Machine operating as a smart contract on Solana.
### How does Neon EVM Work?
-Neon EVM is a smart contract on Solana acting as the Ethereum Virtual Machine. It's compiled into Berkeley Packet Filter bytecode, a format that can be executed on Solana. This allows Neon EVM to receive Solana transactions that contain wrapped Ethereum-like transactions and process them on Solana according to Ethereum rules. Get more details [here](https://docs.neonfoundation.io/docs/about/how_it_works).
+Neon EVM is a smart contract on Solana acting as the Ethereum Virtual Machine. It's compiled into Berkeley Packet Filter bytecode, a format that can be executed on Solana. This allows Neon EVM to receive Solana transactions that contain wrapped Ethereum-like transactions and process them on Solana according to Ethereum rules. Get more details [here](https://neonevm.org/docs/about/how_it_works).
### How can I start building on Neon?
@@ -45,7 +45,7 @@ The following tools are available on Neon:
### How do I transfer SPL tokens between Solana and Neon?
-[NeonPass](/docs/token_transferring/neonpass_usage) is an open-source service that facilitates token transfers between Solana and Neon EVM, including the NEON SPL token. To use NeonPass, you must have access to two wallets: a Solana wallet, such as [Phantom](https://phantom.app/), and an EVM wallet, such as [MetaMask](https://metamask.io/).
+[NeonPass](/docs/token_transferring/neonpass_usage) is an open-source service that facilitates token transfers between Solana and Neon EVM, including the NEON SPL token. To use NeonPass, you must have access to two wallets: a Solana wallet, such as [Phantom](https://phantom.app/download), and an EVM wallet, such as [MetaMask](https://metamask.io/).
### What is Neon's roadmap?
@@ -59,7 +59,7 @@ Neon has an active community: check out our [community page](https://neonevm.org
### Where can I see a list of projects in the ecosystem?
-You can see the list of projects building on Neon [here](https://docs.neonfoundation.io/docs/about/neon_ecosystem).
+You can see the list of projects building on Neon [here](https://neonevm.org/docs/about/neon_ecosystem).
### Where can I see a list of upcoming events involving Neon?
@@ -71,4 +71,4 @@ Upcoming events in the Neon community are listed on our [events page](https://ne
If you still have a question about the Neon EVM that isn't answered in the following FAQ pages, please join us on our [Discord server](https://discord.gg/neonevm). Our AI support channel, `#ai-support`, will answer your questions day or night. If the AI is not smart enough, don't worry; our support team will be glad to help you.
-> Discord [invite link](https://discord.com/invite/ApZRBDqYcN)
\ No newline at end of file
+> Discord [invite link](https://discord.com/invite/ApZRBDqYcN)
diff --git a/docs/governance/technical_implementation/vote.md b/docs/governance/technical_implementation/vote.md
index 6013f3ba..6a388f29 100644
--- a/docs/governance/technical_implementation/vote.md
+++ b/docs/governance/technical_implementation/vote.md
@@ -113,7 +113,7 @@ Your device will display **”Processing”** and then **Your device is now read
#### Step 3: Install the Phantom wallet and connect Ledger to Phantom
-3.1 Install the Phantom wallet on your browser by visiting the Phantom website: [https://phantom.app/](https://phantom.app/).
+3.1 Install the Phantom wallet on your browser by visiting the [Phantom website](https://phantom.app/download).
3.2 Next, connect your Ledger wallet as per [Ledger's documentation](https://support.ledger.com/hc/en-us/articles/4408131265169-Set-up-and-use-Phantom-to-access-your-Ledger-Solana-SOL-account)
diff --git a/docusaurus.config.js b/docusaurus.config.js
index bcd4490c..cbd7a810 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -6,7 +6,7 @@ const darkCodeTheme = require('prism-react-renderer').themes.dracula;
const config = {
title: 'Neon Docs',
tagline: 'Neon EVM is an open source project implementing the Ethereum virtual machine on Solana.',
- url: 'https://docs.neonfoundation.io',
+ url: 'https://neonevm.org',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenAnchors: 'ignore',
@@ -174,6 +174,9 @@ const config = {
'@docusaurus/preset-classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
+ googleTagManager: {
+ containerId: 'GTM-NKNPBQ2S',
+ },
gtag: {
trackingID: 'G-Y5QG48111W'
},
diff --git a/linkcheck.config.json b/linkcheck.config.json
index 2487bfdb..d57adb82 100644
--- a/linkcheck.config.json
+++ b/linkcheck.config.json
@@ -45,6 +45,9 @@
},
{
"pattern": "^https://thegraph.neonevm.org/index-node/graphql"
+ },
+ {
+ "pattern": "^https://phantom.app"
}
],
"aliveStatusCodes": [
diff --git a/package-lock.json b/package-lock.json
index 50c65dac..c30601f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,7 +19,7 @@
"docusaurus-json-schema-plugin": "^1.11.0",
"docusaurus-plugin-image-zoom": "^2.0.0",
"markdown-link-check": "^3.11.2",
- "neon-web-components": "^1.0.2",
+ "neon-web-components": "^1.1.2",
"prism-react-renderer": "^2.3.1",
"raw-loader": "^4.0.2",
"react": "^18.2.0",
@@ -10963,9 +10963,9 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node_modules/neon-web-components": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/neon-web-components/-/neon-web-components-1.0.2.tgz",
- "integrity": "sha512-7PfyoiHRl2jPYEME/RKsE3tv7+IgSDzclRXzaUptcDpiYqTXhogZoteK3HCpryP1NxJ+uryNoTT1TYdVw508+g=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/neon-web-components/-/neon-web-components-1.1.2.tgz",
+ "integrity": "sha512-M6ovVVGx68SL9eqashJ65hSxQmVHcneETlmsY6ZDrE0Oc2glxG9ukMKoOr7Lf7uJzoD+3gnHr3TwSycNfhCfxg=="
},
"node_modules/no-case": {
"version": "3.0.4",
diff --git a/package.json b/package.json
index 09ecf219..2331602e 100644
--- a/package.json
+++ b/package.json
@@ -15,18 +15,18 @@
"typecheck": "tsc"
},
"dependencies": {
- "@docusaurus/core": "^3.2.1",
- "@docusaurus/plugin-client-redirects": "^3.2.1",
- "@docusaurus/plugin-google-analytics": "^3.2.1",
- "@docusaurus/preset-classic": "^3.2.1",
- "@docusaurus/theme-search-algolia": "^3.2.1",
+ "@docusaurus/core": "^3.4.0",
+ "@docusaurus/plugin-client-redirects": "^3.4.0",
+ "@docusaurus/plugin-google-analytics": "^3.4.0",
+ "@docusaurus/preset-classic": "^3.4.0",
+ "@docusaurus/theme-search-algolia": "^3.4.0",
"@mdx-js/react": "^3.0.1",
"algolia": "^0.0.0",
"clsx": "^2.1.0",
"docusaurus-json-schema-plugin": "^1.11.0",
"docusaurus-plugin-image-zoom": "^2.0.0",
"markdown-link-check": "^3.11.2",
- "neon-web-components": "^1.0.2",
+ "neon-web-components": "^1.1.2",
"prism-react-renderer": "^2.3.1",
"raw-loader": "^4.0.2",
"react": "^18.2.0",
@@ -36,7 +36,7 @@
},
"devDependencies": {
"@babel/plugin-transform-react-jsx": "^7.23.4",
- "@docusaurus/module-type-aliases": "^3.2.1",
+ "@docusaurus/module-type-aliases": "^3.4.0",
"@tsconfig/docusaurus": "^2.0.2",
"typescript": "^5.3.3"
},
diff --git a/sidebars.js b/sidebars.js
index 168125c0..13bb821b 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -116,6 +116,29 @@ const sidebars = {
id: 'developing/dev_environment/local_proxy_remote_solana'
},
{ type: 'html', value: '' },
+ { type: 'html', value: '' },
+ {
+ type: 'doc',
+ label: 'Common Solana Terminology',
+ id: 'composability/common_solana_terminology'
+ },
+ {
+ type: 'doc',
+ label: 'ICallSolana Interface',
+ id: 'composability/call_solana_interface'
+ },
+ {
+ type: 'category',
+ label: 'Using Composability',
+ items: [
+ 'composability/using_composability/setup_configure',
+ 'composability/using_composability/transfer_sols',
+ 'composability/using_composability/transfer_spl_token',
+ 'composability/using_composability/swap_on_orca',
+ 'composability/using_composability/using_vrf'
+ ]
+ },
+ { type: 'html', value: '' },
{ type: 'html', value: '' },
{
type: 'category',
diff --git a/static/schemas/neon-api/v1/neon_emulate/request.json b/static/schemas/neon-api/v1/neon_emulate/request.json
index 801bb0ee..10eb5c7e 100644
--- a/static/schemas/neon-api/v1/neon_emulate/request.json
+++ b/static/schemas/neon-api/v1/neon_emulate/request.json
@@ -15,7 +15,7 @@
"id": {
"type": "number",
"examples": [
- "OpEgqw7r98qwerqwehkjhwe8"
+ "1716308324042"
],
"description": "End-user provided identifier for the request; returned with payload."
},
@@ -28,4 +28,4 @@
"jsonrpc",
"method"
]
-}
\ No newline at end of file
+}
diff --git a/static/schemas/neon-api/v1/neon_emulate/response.json b/static/schemas/neon-api/v1/neon_emulate/response.json
index af2bc0f5..a9182e2a 100644
--- a/static/schemas/neon-api/v1/neon_emulate/response.json
+++ b/static/schemas/neon-api/v1/neon_emulate/response.json
@@ -15,60 +15,51 @@
"description": "End-user provided identifier for the request."
},
"result": {
- "accounts": [
- {
- "account": "2iBArBKoWNTG2gJ8KfEMtGv63CFPfTnwfsvarBncLtRX",
- "additional_resize_steps": 0,
- "address": "0xa59cd271578da4931c093f7611488b0a1a4bd198",
- "new": false,
- "size": 71,
- "size_current": 71,
- "writable": true
- },
- {
- "account": "7Q8xmg4pHEfxTdwrKKpho6WfX6eFYRsDUuABsnk9iMB8",
- "additional_resize_steps": 0,
- "address": "0x549b5cb2d324f901aed6938a3838fb9b10898441",
- "new": false,
- "size": 11427,
- "size_current": 11427,
- "writable": false
- },
- {
- "account": "AJthh52LdmRpif8HevQUF5TN4tuLCqGMQbm1rDuSkpzZ",
- "additional_resize_steps": 0,
- "address": "0x6dcdd1620ce77b595e6490701416f6dbf20d2f67",
- "new": false,
- "size": 10550,
- "size_current": 10550,
- "writable": false
- }
- ],
- "solana_accounts": [
- {
- "is_writable": false,
- "pubkey": "AUmmih1fr3Spj6rd8LFYB1EhfyMV24NqusM8QbWAoBad"
- },
- {
- "is_writable": false,
- "pubkey": "CnvWtQMgWiG7KzYMTBYXwk8PB2YYxRzPAZBaPWhRkctJ"
- },
- {
- "is_writable": false,
- "pubkey": "HFVUvrCzh26DTFpxjGzSn8cHn2sCtZGJogk3YhmBmzQ4"
- }
- ],
- "actions": [
- {
- "EvmIncrementNonce": {
- "address": "0xa59cd271578da4931c093f7611488b0a1a4bd198"
- }
- }
- ],
- "exit_status": "revert",
- "result": "08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002645524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63650000000000000000000000000000000000000000000000000000",
- "steps_executed": 919,
- "used_gas": 30000
+ "exitCode": "revert",
+ "externalSolanaCall": false,
+ "revertBeforeSolanaCall": true,
+ "revertAfterSolanaCall": false,
+ "result": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000007a45787465726e616c2063616c6c206661696c7320546f6b656e6b65675166655a79694e77414a624e62474b50465843577542766639537336323356513544413a204572726f722070726f63657373696e6720496e737472756374696f6e20303a20637573746f6d2070726f6772616d206572726f723a20307834000000000000",
+ "numEvmSteps": 441,
+ "gasUsed": 25000,
+ "numIterations": 3,
+ "solanaAccounts": [
+ {
+ "pubkey": "7pjifx9FL83gidWbR3KvwwRJb1ThJe3NabhBG3VtjdC3",
+ "isWritable": true,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "6gANWp6ZbZpdpt5GhBoCopNAJv1iTnA9kf7L7VRj2ivj",
+ "isWritable": false,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "4dWQAaevdp89Jqr5GQV8KTZkG7Un9kvj7QY8fUnJHCgc",
+ "isWritable": true,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "EMDBr8bmj7FjSWEmsKeBZZfikuFXhWTJKhQSj41NFLaB",
+ "isWritable": true,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
+ "isWritable": false,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "DR6toPZGbKRdgfQ7krDRrdbX8NDatuttteuXtAcFm4mF",
+ "isWritable": false,
+ "isLegacy": false
+ },
+ {
+ "pubkey": "9WY2FENzKGCDQgoi8dXxJrvAqPqoWpKmnXvu7KgADSeb",
+ "isWritable": false,
+ "isLegacy": false
+ }
+ ]
}
},
"required": [
@@ -76,4 +67,4 @@
"id",
"result"
]
-}
\ No newline at end of file
+}
diff --git a/static/schemas/neon-api/v1/neon_getEvmParams/request.json b/static/schemas/neon-api/v1/neon_getEvmParams/request.json
index 951a7a1a..f7f9d3ed 100644
--- a/static/schemas/neon-api/v1/neon_getEvmParams/request.json
+++ b/static/schemas/neon-api/v1/neon_getEvmParams/request.json
@@ -14,15 +14,15 @@
},
"method": {
"type": "string",
- "const": "nneon_getEvmParams",
+ "const": "neon_getEvmParams",
"description": "The method name."
},
"id": {
"type": "number",
"examples": [
- "OpEgqw7r98qwerqwehkjhwe8"
+ "1712927726192"
],
"description": "End-user provided identifier for the request; returned with payload."
}
}
-}
\ No newline at end of file
+}
diff --git a/static/schemas/neon-api/v1/neon_getEvmParams/response.json b/static/schemas/neon-api/v1/neon_getEvmParams/response.json
index d5efe49b..7b64ece0 100644
--- a/static/schemas/neon-api/v1/neon_getEvmParams/response.json
+++ b/static/schemas/neon-api/v1/neon_getEvmParams/response.json
@@ -20,30 +20,16 @@
"description": "End-user provided identifier for the request."
},
"result": {
- "NEON_ACCOUNT_SEED_VERSION": "3",
- "NEON_ADDITIONAL_FEE": "0",
- "NEON_CHAIN_ID": "245022926",
- "NEON_COMPUTE_BUDGET_HEAP_FRAME": "262144",
- "NEON_COMPUTE_BUDGET_UNITS": "500000",
- "NEON_EVM_STEPS_LAST_ITERATION_MAX": "1",
- "NEON_EVM_STEPS_MIN": "500",
- "NEON_GAS_LIMIT_MULTIPLIER_NO_CHAINID": "1000",
- "NEON_HOLDER_MSG_SIZE": "950",
- "NEON_OPERATOR_PRIORITY_SLOTS": "16",
- "NEON_PAYMENT_TO_DEPOSIT": "5000",
- "NEON_PAYMENT_TO_TREASURE": "5000",
- "NEON_PKG_VERSION": "0.15.13",
- "NEON_POOL_COUNT": "128",
- "NEON_POOL_SEED": "treasury_pool",
- "NEON_REQUEST_UNITS_ADDITIONAL_FEE": "0",
- "NEON_REVISION": "9a4bbf29359e752336c0a1ff5fcb03e3ad303b7a",
- "NEON_STATUS_NAME": "WORK",
- "NEON_STORAGE_ENTRIES_IN_CONTRACT_ACCOUNT": "64",
- "NEON_TOKEN_MINT": "89dre8rZjLNft7HoupGiyxu3MNftR577ZYu8bHe2kK7g",
- "NEON_TOKEN_MINT_DECIMALS": "9",
- "NEON_TREASURY_POOL_COUNT": "128",
- "NEON_TREASURY_POOL_SEED": "treasury_pool",
- "NEON_EVM_ID": "eeLSJgWzzxrqKv1UxtRVVH8FX3qCQWUs9QuAjJpETGU"
+ "neonAccountSeedVersion": "3",
+ "neonMaxEvmStepsInLastIteration": "1",
+ "neonMinEvmStepsInIteration": "500",
+ "neonGasLimitMultiplierWithoutChainId": "1000",
+ "neonHolderMessageSize": "950",
+ "neonPaymentToTreasury": "5000",
+ "neonStorageEntriesInContractAccount": "64",
+ "neonTreasuryPoolCount": "128",
+ "neonTreasuryPoolSeed": "treasury_pool",
+ "neonEvmProgramId": "53DfF883gyixYNXnM7s5xhdeyV8mVk9T4i2hGV9vG9io"
}
}
-}
\ No newline at end of file
+}