Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions examples/oapp-aptos-move/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,17 @@ Ensure that in move.layerzero.config.ts, all of your evm contracts have the owne
]
```

If you are wiring solana to move-vm, create a file in `deployments/solana-mainnet/MyOFT.json` (or `deployments/solana-testnet/MyOFT.json` if you are using testnet) and add the following field:
If you are wiring solana to move-vm, in your config add:

```json
{
"address": <oft-store-address-from-solana-deployment-folder>
}
```ts
const solanaContract: OmniPointHardhat = {
eid: EndpointId.SOLANA_V2_TESTNET as EndpointId,
address: "YOUR_DEPLOYED_SOLANA_OAPP_ADDRESS",
};
```

Note: Solana OApp must be deployed with the Solana example.

Commands:

### To wire from EVM to Move-VM:
Expand Down
39 changes: 27 additions & 12 deletions examples/oapp-aptos-move/scripts/aptos-move-send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import {
Account,
AccountAddressInput,
Aptos,
AptosConfig,
Ed25519PrivateKey,
Expand All @@ -21,25 +22,26 @@ import {
SimpleTransaction,
} from '@aptos-labs/ts-sdk'
import * as dotenv from 'dotenv'
import { ethers } from 'ethers'

import { EndpointId } from '@layerzerolabs/lz-definitions'
import { Chain, EndpointId, getNetworkForChainId } from '@layerzerolabs/lz-definitions'
import { Options } from '@layerzerolabs/lz-v2-utilities'

// Load environment variables from .env file
dotenv.config()

// Validate required environment variables
if (!process.env.APTOS_PRIVATE_KEY || !process.env.ACCOUNT_ADDRESS) {
throw new Error('Please set APTOS_PRIVATE_KEY and ACCOUNT_ADDRESS in your .env file')
if (!process.env.APTOS_PRIVATE_KEY || !process.env.APTOS_ACCOUNT_ADDRESS) {
throw new Error('Please set APTOS_PRIVATE_KEY and APTOS_ACCOUNT_ADDRESS in your .env file')
}

// Configuration constants
const APTOS_PRIVATE_KEY = process.env.APTOS_PRIVATE_KEY
const ACCOUNT_ADDRESS = process.env.ACCOUNT_ADDRESS
const ACCOUNT_ADDRESS = process.env.APTOS_ACCOUNT_ADDRESS

// OApp configuration
const OAPP_ADDRESS = '' // Set your OApp's address on Aptos
const REMOTE_EID = EndpointId.BSC_V2_TESTNET // Destination chain endpoint ID
const OAPP_ADDRESS = '0x' // Set your OApp's address on Aptos
const REMOTE_EID = EndpointId.SOLANA_V2_TESTNET // Destination chain endpoint ID
const NETWORK = Network.TESTNET // Aptos network configuration

// Initialize Aptos account and client
Expand All @@ -59,10 +61,23 @@ async function send() {
const options = Options.newOptions().addExecutorLzReceiveOption(BigInt(30000))
const extraOptions = options.toBytes()

// Prepare the message
const message = 'Hello, EVM!'
const messageBytes = new TextEncoder().encode(message)
const messageArray = new Uint8Array(messageBytes)
let messageArray: Uint8Array
if (getNetworkForChainId(REMOTE_EID).chainName === Chain.SOLANA) {
const message = 'Hello, Solana!'

const messageHex = ethers.utils.solidityPack(
['uint256', 'bytes'],
[ethers.utils.toUtf8Bytes(message).length, ethers.utils.toUtf8Bytes(message)]
)
// Convert hex string to Uint8Array
messageArray = ethers.utils.arrayify(messageHex)
} else {
const message = 'Hello, EVM!'
const messageBytes = new TextEncoder().encode(message)
messageArray = new Uint8Array(messageBytes)
}

// The Following is the code required for packaging a string message to be sent to Solana:

// Get fee quote for the cross-chain message
const quote = await aptos.view({
Expand All @@ -79,7 +94,7 @@ async function send() {
console.log('ZRO fee:', quote[1])

// Verify account has sufficient balance
const balance = await aptos.account.getAccountAPTAmount({ accountAddress: ACCOUNT_ADDRESS })
const balance = await aptos.account.getAccountAPTAmount({ accountAddress: ACCOUNT_ADDRESS as AccountAddressInput })
console.log('Account balance:', Number(balance) / 100000000, 'APT')

if (Number(balance) < Number(quote[0])) {
Expand All @@ -96,7 +111,7 @@ async function send() {

// Create the transaction
const transaction: SimpleTransaction = await aptos.transaction.build.simple({
sender: ACCOUNT_ADDRESS,
sender: ACCOUNT_ADDRESS as AccountAddressInput,
data: payload,
options: {
maxGasAmount: 100000,
Expand Down
121 changes: 121 additions & 0 deletions examples/oapp-solana/docs/move.layerzero.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// NOTE: This config is an example for wiring Solana -> Aptos.
// See wiring-to-aptos.md for more information.
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities'
import { OAppOmniGraphHardhat, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat'

enum MsgType {
SEND = 1,
SEND_AND_CALL = 2,
}
const aptosContract: OmniPointHardhat = {
eid: EndpointId.APTOS_V2_TESTNET as EndpointId,
address: 'YOUR_DEPLOYED_APTOS_CONTRACT_ADDRESS',
}
const solanaContract: OmniPointHardhat = {
eid: EndpointId.SOLANA_V2_TESTNET as EndpointId,
address: 'YOUR_DEPLOYED_SOLANA_OAPP_ADDRESS',
}

const layerZeroDVNAptosAddress = '0x756f8ab056688d22687740f4a9aeec3b361170b28d08b719e28c4d38eed1043e'
Comment thread
AlexanderLiteplo marked this conversation as resolved.
const layerZeroDVNSolanaAddress = '4VDjp6XQaxoZf5RGwiPU9NR1EXSZn2TP4ATMmiSzLfhb'

const config: OAppOmniGraphHardhat = {
Comment thread
AlexanderLiteplo marked this conversation as resolved.
contracts: [
{
contract: solanaContract,
config: {
owner: 'YOUR_SOLANA_OWNER_ADDRESS',
delegate: 'YOUR_SOLANA_OWNER_ADDRESS',
},
},
{
contract: aptosContract,
config: {
owner: 'YOUR_APTOS_ACCOUNT_ADDRESS',
delegate: 'YOUR_APTOS_ACCOUNT_ADDRESS',
},
},
],
connections: [
{
from: aptosContract,
to: solanaContract,
config: {
enforcedOptions: [
{
msgType: MsgType.SEND_AND_CALL,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 5_000,
value: 0,
},
],
sendLibrary: '0xcc1c03aed42e2841211865758b5efe93c0dde2cb7a2a5dc6cf25a4e33ad23690',
receiveLibraryConfig: {
receiveLibrary: '0xcc1c03aed42e2841211865758b5efe93c0dde2cb7a2a5dc6cf25a4e33ad23690',
gracePeriod: BigInt(0),
},
sendConfig: {
executorConfig: {
maxMessageSize: 10_000,
executor: '0x93353700091200ef9fdc536ce6a86182cc7e62da25f94356be9421c6310b9585',
},
ulnConfig: {
confirmations: BigInt(10),
requiredDVNs: [layerZeroDVNAptosAddress],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
receiveConfig: {
ulnConfig: {
confirmations: BigInt(15),
requiredDVNs: [layerZeroDVNAptosAddress],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
},
},
{
from: solanaContract,
to: aptosContract,
config: {
enforcedOptions: [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 200_000,
value: 0,
},
],
sendLibrary: '7a4WjyR8VZ7yZz5XJAKm39BUGn5iT9CKcv2pmG9tdXVH',
receiveLibraryConfig: {
receiveLibrary: '7a4WjyR8VZ7yZz5XJAKm39BUGn5iT9CKcv2pmG9tdXVH',
gracePeriod: BigInt(0),
},
sendConfig: {
executorConfig: {
maxMessageSize: 10_000,
executor: 'AwrbHeCyniXaQhiJZkLhgWdUCteeWSGaSN1sTfLiY7xK',
},
ulnConfig: {
confirmations: BigInt(15),
requiredDVNs: [layerZeroDVNSolanaAddress],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
receiveConfig: {
ulnConfig: {
confirmations: BigInt(10),
requiredDVNs: [layerZeroDVNSolanaAddress],
optionalDVNs: [],
optionalDVNThreshold: 0,
},
},
},
},
],
}
export default config
63 changes: 63 additions & 0 deletions examples/oapp-solana/docs/wiring-to-aptos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
### Wiring Solana to Move-VM (Aptos, Initia, Movement, etc.)

:warning: **Important Limitations for Solana ↔ Move-VM Pathways**

Currently, you can only perform **one-way wiring from Solana → Move-VM** using this example. For the reverse pathway (Move-VM → Solana), you must use the [OApp Aptos Move example](https://github.com/LayerZero-Labs/devtools/tree/main/examples/oapp-aptos-move). Please follow the deployment instructions in the README.md of the `oapp-aptos-move` example for deploying to Move-VM and configuring the Move-VM → Solana pathway.

#### Configuration Steps for Solana → Aptos

:information_source: **For bidirectional Solana ↔ Aptos communication, deploy both examples:**

- **Solana → Aptos**: Use this example
- **Aptos → Solana**: Use the [OApp Aptos Move example](https://github.com/LayerZero-Labs/devtools/tree/main/examples/oapp-aptos-move)

#### Deployment Process

1. **Create and Deploy Solana Example**

- Create the Solana example: `LZ_ENABLE_SOLANA_OAPP_EXAMPLE=1 npx create-lz-oapp@latest`
- Deploy to Solana following the deployment instructions in the Solana example README

2. **Create and Deploy Aptos Move Example**

- Create the Aptos Move example: `LZ_ENABLE_EXPERIMENTAL_MOVE_VM_EXAMPLES=1 npx create-lz-oapp@latest`
- Deploy to Aptos following the deployment and initialization instructions in the Aptos example README

Your directory structure should look like this:

```
your-folder/
├── your-aptos-example/
└── your-solana-example/
```

3. **Configure Solana Example**

- Navigate to the Solana example directory
- Use the example configuration at `./docs/move.layerzero.config.ts`
- Fill out the configuration with your desired values
- Replace `./layerzero.config.ts` with the completed `move.layerzero.config.ts` file

4. **Wire Solana to Aptos**

Execute the following commands in the Solana example directory:

```bash
npx hardhat lz:oapp:solana:init-config --oapp-config move.layerzero.config.ts
```

```bash
npx hardhat lz:oapp:wire --oapp-config move.layerzero.config.ts
```

If these commands succeed, you have successfully wired the Solana contract to the Aptos Move contract.

5. **Wire Aptos to Solana**

- Transfer the `move.layerzero.config.ts` file from the Solana example to the Aptos Move example directory
- In the Aptos Move example directory, run:
```bash
pnpm run lz:sdk:move:wire --oapp-config move.layerzero.config.ts
```

If this command succeeds, you are ready to test the bidirectional pathway.
Loading