Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Developer Documentation: Detailed Code Examples, Improved VAA Explanation, and Structure Refinement #48

Open
wants to merge 11 commits into
base: eshaben/enhance-prs
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ It's important to understand some [on-chain components](#) before sending and re
### Sending a Message

To send a message, regardless of the environment or chain, the Core Contract is invoked with a message argument from an [emitter](/learn/glossary/#emitter). This emitter may be your contract or an existing application such as the [Token Bridge](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003\_token\_bridge.md){target=\_blank}, or [NFT Bridge](https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0006\_nft\_bridge.md){target=\_blank}.

=== "EVM"

Using the [`IWormhole` interface](https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/interfaces/IWormhole.sol){target=\_blank}, you can publish a message directly to the [Core Contract](/learn/messaging/core-contracts/).
Expand All @@ -36,8 +35,7 @@ To send a message, regardless of the environment or chain, the Core Contract is
```

More details are available in the [Hello World example](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/solana/programs/01_hello_world/src/lib.rs){target=\_blank}.

Once the message is emitted from the Core Contract, the [Guardian Network](/learn/infrastructure/guardians/) will observe the message and sign the digest of an Attestation [VAA](/learn/infrastructure/vaas/). This will be discussed in more depth in the [Off-Chain](#off-chain) section below.
Once the message is emitted from the Core Contract, the [Guardian Network](/learn/infrastructure/guardians/) will observe the message and sign the digest of an Attestation [VAA](/learn/infrastructure/vaas/). This will be discussed in more depth in the [Off-Chain](#off-chain) section below.
404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved

VAAs are [multicast](/learn/messaging/core-contracts/#multicast) by default. This means there is no default target chain for a given message. The application developer decides on the format of the message and its treatment upon receipt.

Expand All @@ -54,7 +52,6 @@ The way a message is received and handled depends on the environment.
```

More details are available in the [Hello World example](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/evm/src/01\_hello\_world/HelloWorld.sol){target=\_blank}.

=== "Solana"

On Solana, the VAA is first posted and verified by the Core Contract, after which it can be read by the receiving contract and action taken.
Expand All @@ -65,13 +62,11 @@ The way a message is received and handled depends on the environment.

More details are available in the [Hello World Example](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/solana/programs/01\_hello\_world/src/lib.rs){target=\_blank}.


In addition to environment-specific checks that should be performed, a contract should take care to check other [fields in the body](/learn/infrastructure/vaas/), including:

- **Emitter** - is this coming from an expected emitter address and chain ID? Typically, contracts will provide a method to register a new emitter and check the incoming message against the set of emitters it trusts
- **Sequence** - is this the expected sequence number? How should out-of-order deliveries be handled?
- **Consistency level** - for the chain this message came from, is the [consistency level](/build/reference/consistency-levels/) enough to guarantee the transaction won't be reverted after taking some action?

Outside of the VAA body, but also relevant, is the VAA digest, which can be used for replay protection by checking if the digest has already been seen. Since the payload itself is application-specific, there may be other elements to check to ensure safety.

## Off-Chain Components
Expand All @@ -85,7 +80,6 @@ After enough Guardians have signed the message (at least two-thirds + 1 majority
A relayer is needed to deliver the VAA containing the message to the target chain. When the relayer is explicitly written for a custom application, it's called a specialized relayer.

A specialized relayer might be as simple as an in-browser process that polls the API for the availability of a VAA after submitting a transaction and delivers it to the target chain. It might also be implemented with a [Spy](/learn/infrastructure/spy/) coupled with some daemon listening for VAAs from a relevant `chainID` and `emitter` then taking action when one is observed.

#### Simple Relayer

Regardless of the environment, to get the VAA you intend to relay, you need:
Expand All @@ -101,21 +95,23 @@ With these three components, you're able to uniquely identify a VAA and fetch it
Using the `getSignedVAAWithRetry` function provided in the [SDK](/build/build-apps/wormhole-sdk/), you can poll the Guardian RPC until the signed VAA is ready.

```ts

--8<-- 'code/build/build-a-custom-multichain-protocol/get-started/choosing-a-relayer/specialized-relayer/getVAA.ts'
```


Once you have the VAA, the delivery method is chain-dependent.

=== "EVM"

On EVM chains, the bytes for the VAA can be passed directly as an argument to an ABI method.

On EVM chains, the bytes for the VAA can be passed directly as an argument to an ABI method.
```ts
--8<-- 'code/build/build-a-custom-multichain-protocol/get-started/choosing-a-relayer/specialized-relayer/deliverVAAEvm.ts'
```

=== "Solana"


On Solana, the VAA is first posted to the core bridge, and then a custom transaction is prepared to process and validate the VAA.

```ts
Expand All @@ -124,6 +120,11 @@ Once you have the VAA, the delivery method is chain-dependent.

<!-- See the [Specialized Relayer Tutorial](#) for a detailed guide. -->

## Reference
## Example: Building a Custom Relayer
404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved

Here's a simple example of creating a specialized relayer for a custom application. This example assumes you are familiar with the basics of setting up a Wormhole environment.

You can read more about the architecture and core components in the [Learn section](/learn/architecture/).
1. **Initialize the project**: Start by setting up a basic Node.js project and installing the Wormhole SDK.
2. **Set up environment variables**: Configure your environment to point to the correct Wormhole RPC endpoints.
3. **Write the relayer logic**: Implement the logic to listen for specific VAAs, fetch them, and submit them to the target chain.
4. **Test the relayer**: Deploy your relayer in a test environment to ensure it correctly processes and relays VAAs.
16 changes: 11 additions & 5 deletions build/build-a-custom-multichain-protocol/get-started/dev-env.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Local Dev Environment
description: Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more.
description: Learn how to configure a development environment to build with Wormhole, including using the CLI, local validators, testing on public test networks, and more.
---

# Development Environment
Expand All @@ -19,11 +19,11 @@ Different approaches to development and testing are recommended at various stage

During the initial development of an on-chain application, the best option is to use the native tools available in the environment. You can visit the following resources for more information:

- **[Environment](https://github.com/wormhole-foundation/wormhole){target=\_blank}** - select the folder for the desired network to learn about the recommended native toolset
- **[Mock Guardian](https://github.com/wormhole-foundation/wormhole/blob/main/sdk/js/src/mock/wormhole.ts){target=\_blank}** - it's recommended to set up a mock Guardian or Emitter to provide signed VAAsFor any program methods that require some message be sent or received.
- **[Environment](https://github.com/wormhole-foundation/wormhole){target=\_blank}** - select the folder for the desired network to learn about the recommended native toolset
- **[Mock Guardian](https://github.com/wormhole-foundation/wormhole/blob/main/sdk/js/src/mock/wormhole.ts){target=\_blank}** - it's recommended to set up a mock Guardian or Emitter to provide signed VAAs for any program methods that require some message be sent or received.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Thanks!

- **[Wormhole Scaffolding repository](https://github.com/wormhole-foundation/wormhole-scaffolding/blob/main/evm/ts-test/01_hello_world.ts){target=\_blank}** - example mock Guardian test

Relying on native tools when possible allows for more rapid prototyping and iteration.
Relying on native tools when possible allows for more rapid prototyping and iteration.

### Integration

Expand All @@ -49,4 +49,10 @@ When doing integration testing on TestNets, remember that a single Guardian node

### MainNet

The MainNet contract addresses are available on the page for each [environment](build/start-building/supported-networks/). The MainNet Guardian RPC configuration is available on the [SDK page](#).
The MainNet contract addresses are available on the page for each [environment](build/start-building/supported-networks/). The MainNet Guardian RPC configuration is available on the [SDK page](#).

404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved
## Enhancements for Developer Experience

- **Detailed setup instructions**: Expand the initial setup instructions to include more comprehensive details on installing and configuring the development environment, especially for newcomers.
- **Executable code examples**: Integrate interactive code snippets that developers can run within the documentation to better understand the setup process.
- **Troubleshooting guide**: Include a section on common issues faced during the setup of local validators, particularly using Tilt, and how to resolve them.
8 changes: 7 additions & 1 deletion learn/fundamentals/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,10 @@ More demos are available in the [demos page](#){target=\_blank}. <!-- demos page

Wormhole supports a growing number of blockchains.

<!-- List of Blockchains here -->
<!-- List of Blockchains here -->

404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved
## Enhancements for Developer Experience

- **Glossary and definitions**: Add a glossary of key terms, such as “guardian,” “set,” and “relayers,” with detailed explanations to help new developers quickly understand essential concepts.
- **Visual aids**: Include more diagrams and flowcharts to illustrate the architecture and data flow within the Wormhole protocol.
- **Links to additional resources**: Provide more links to related resources, such as detailed architecture documents and relevant GitHub repositories, directly within the introductory content.
16 changes: 16 additions & 0 deletions learn/infrastructure/spy.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ The messages available over gossip are things like:
## Source Code

The source code for the Spy is available on [GitHub](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go){target=\_blank}.

## Example: Building a Simple Spy
404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved

To create a basic Spy that listens for a specific type of VAA, follow these steps:

1. **Set Up Spy**: Use the existing Spy daemon to subscribe to all messages on the Guardian Network.
2. **Filter Messages**: Implement filtering logic to listen only for VAAs from specific emitters or with specific payloads.
3. **Process VAAs**: Once a relevant VAA is detected, process it by either logging the information or triggering further actions.

For example, you could build a Spy that listens for token transfer VAAs and triggers a notification or an automated process when a transfer exceeds a certain value.

## Enhancements for Developer Experience
404PJNotFound marked this conversation as resolved.
Show resolved Hide resolved

- **Detailed examples**: Provide more code examples of different Spy implementations, such as filtering based on specific VAA fields or integrating with external services like Slack for alerts.
- **Monitoring and logging best practices**: Include tips on how to efficiently log and monitor Spy activity, especially when dealing with a high volume of messages.
- **Security considerations**: Add a section on securing your Spy setup, such as using access controls and monitoring to ensure the integrity of the messages being processed.
9 changes: 5 additions & 4 deletions learn/infrastructure/vaas.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ The Guardians must validate messages emitted by contracts before sending them to

The message is wrapped up in a structure called a VAA, which combines the message with the Guardian signatures to form a proof.

VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the Guardian [RPC](#){target=\_blank} or the [API](https://docs.wormholescan.io/){target=\_blank} with this information.
<!-- sdk legacy link for rpc -->
VAAs are uniquely indexed by the (`emitter_chain`, `emitter_address`, `sequence`) tuple. To obtain a VAA, one can query the Guardian [RPC](#) or the [API](https://docs.wormholescan.io/){target=\_blank} with this information.

These VAAs are ultimately what a smart contract on a receiving chain must process to receive a Wormhole message.


## VAA Format

The basic VAA has two components: a header and a body.
Expand All @@ -34,6 +34,7 @@ Where each `signature` is:
- `index` ++"u8"++ - the index of this Guardian in the Guardian set
- `signature` ++"[65]byte"++ - the ECDSA signature


### Body

The body is _deterministically_ derived from an on-chain message. Any two Guardians processing the same message must derive the same resulting body. This requirement exists so that there is always a one-to-one relationship between VAAs and messages to avoid double-processing messages.
Expand All @@ -48,6 +49,7 @@ The body is _deterministically_ derived from an on-chain message. Any two Guardi

The body contains relevant information for entities, such as contracts, or other systems, that process or utilize VAAs. When a function like `parseAndVerifyVAA` is called, the body is returned, allowing verification of the `emitterAddress` to determine if the VAA originated from a trusted contract.


!!! note
Because VAAs have no destination, they are effectively multicast. Any Core Contract on any chain in the network will verify them as authentic. If a VAA has a specific destination, relayers are entirely responsible for completing that delivery appropriately.

Expand Down Expand Up @@ -122,7 +124,7 @@ Without knowing a token's decimal precision, Chain B cannot correctly mint the n

The Token Transfer with Message data structure is identical to the token-only data structure with the addition of a `payload` field containing arbitrary bytes. In this arbitrary byte field, an app may include additional data in the transfer to inform some application-specific behavior.

- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message
- `payload_id` ++"u8"++ - the ID of the payload. This should be set to `3` for a token transfer with message
- `amount` ++"u256"++ - amount of tokens being transferred
- `token_address` ++"u8[32]"++ - address on the source chain
- `token_chain` ++"u16"++ - numeric ID for the source chain
Expand Down Expand Up @@ -168,4 +170,3 @@ With the concepts now defined, it is possible to illustrate what a full flow for
1. **A message is emitted by a contract running on Chain A** - any contract can emit messages, and the Guardians are programmed to observe all chains for these events. Here, the Guardians are represented as a single entity to simplify the graphics, but the observation of the message must be performed individually by each of the 19 Guardians
2. **Signatures are aggregated** - Guardians observe and sign the message independently. Once enough Guardians have signed the message, the collection of signatures is combined with the message and metadata to produce a VAA
3. **VAA submitted to target chain** - the VAA acts as proof that the Guardians have collectively attested the existence of the message payload; to complete the final step, the VAA itself is submitted (or relayed) to the target chain to be processed by a receiving contract

Loading