Skip to content

Commit

Permalink
Update doc site and SDK related recommendations (#477)
Browse files Browse the repository at this point in the history
* Update recommendations. Fix links to documentation. Restructure sidebar. Add overview of client and core SDKs on documentation site. Add installation guide for legacy SDK.

* Fix sidebar label

* Fix broken links

* Reposition image on welcome page

* Resolve comments

---------

Co-authored-by: calintje <[email protected]>
  • Loading branch information
calintje and calintje authored Nov 7, 2024
1 parent 1b6f92d commit 852a822
Show file tree
Hide file tree
Showing 24 changed files with 403 additions and 73 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,15 @@ The program has been audited several times by different security firms.

## Usage

***The new whirlpool SDKs are still in development and are not recommended for production use yet. Please see [Legacy](#legacy)***

This repository contains several libraries that can be used to interact with the Whirlpools contract. For most purposes you can use the full library (`@orca-so/whirlpools` and `orca_whirlpools`).
This repository contains several libraries that can be used to interact with the Whirlpools contract. For most purposes you can use our high-level SDKs, `@orca-so/whirlpools` for Typescript projects, and `orca_whirlpools` (currently in development) for Rust projects.

For specific use-cases you can opt for integrating with lower level packages such as:
* `@orca-so/whirlpools-client` & `orca_whirlpools_client` - auto-generated client for the Whirlpools program that contains account, instruction and error parsing.
* `@orca-so/whirlpools-core` & `orca_whirlpools_core` - utility, math and quoting functions used by other packages.

### Legacy
The legacy Typescript SDK (`@orca-so/whirlpools-sdk`) remains a solid choice, and it’s currently the only option if your project uses Solana Web3.js versions below v2.

The legacy Typescript SDK (`@orca-so/whirlpools-sdk`) is still available for use. Documentation can be found on the [Orca Developer Portal](https://orca-so.gitbook.io/orca-developer-portal/orca/welcome). While the new packages are still in development the legacy sdk is still the recommended way to interact with the Whirlpools program.
For a more detailed overview of our SDK suite and usage examples, visit our [developer documentation](https://orca-so.github.io/whirlpools/) site.

## Local Development

Expand Down
4 changes: 2 additions & 2 deletions docs/whirlpool/docs/01-Welcome.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ On both the Solana and Eclipse networks, the Whirlpool Program runs as an open-s

## Overview of Orca Whirlpools SDK suite

![Overview of Orca Whirlpools SDK suite](../static/img/01-Welcome/orca-sdks-overview.png)

Orca provides a range of SDKs that cater to different levels of development needs for interacting with the Whirlpool Program on Solana and Eclipse. Whether you are managing liquidity, building applications that require pool infrastructure, or building automation tools that interact with the program, our SDKs cover a spectrum of functionality from low-level granular control to high-level abstractions.

What follows is a brief overview of our SDK suite, distinguishing between the Whirlpools SDKs and the Legacy SDK, and explaining their intended purposes and relationships.

### Whirlpools SDKs

![Overview of Orca Whirlpools SDK suite](../static/img/01-Welcome/orca-sdks-overview.png)

The Whirlpools SDKs are our primary set of SDKs designed to provide enhanced, modular interaction with the Whirlpool Program. This offering is divided into three main components:

#### 1. High-Level SDK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
![Account Architecture](../../static/img/02-Architecture%20Overview/architecture-overview.png)

## WhirlpoolsConfig
The owner of a Config account has the authority to define the many authorities over the pools that it owns (ex. default fees, collect protocol fees etc) . Whirlpools visible on the ORCA UI are all derived and controlled by a WhirlpoolsConfig account owned by the ORCA foundation. To learn more about managing pools, start [here](../03-Whirlpools%20SDK/02-Whirlpool%20Management/01-Create%20Pool.md).
The owner of a Config account has the authority to define the many authorities over the pools that it owns (ex. default fees, collect protocol fees etc) . Whirlpools visible on the ORCA UI are all derived and controlled by a WhirlpoolsConfig account owned by the ORCA foundation. To learn more about managing pools, start [here](../03-Whirlpools%20SDKs/03-Whirlpools/03-Whirlpool%20Management/01-Create%20Pool.md).

Users and other protocols are free to deploy their own WhirlpoolsConfig account on our Whirlpool program to spawn their own set of liquidity pools.

Expand Down
200 changes: 200 additions & 0 deletions docs/whirlpool/docs/03-Whirlpools SDKs/01-Whirlpools Client.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
sidebar_label: Whirlpools Client
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Orca Whirlpools Client SDK

## Overview
This SDK provides developers with low-level functionalities for interacting with the Whirlpool Program on Solana. It serves as a foundational tool that allows developers to manage and integrate detailed operations into their Typescript projects, particularly those related to Orca's Whirlpool Program. While a high-level SDK is available for easier integration, this package offers more granular control for advanced use cases.

## Key Features
- **Codama Client**: The package includes a set of generated client code based on the Whirlpool Program IDL. This ensures all the necessary program information is easily accessible in a structured format and handles all decoding and encoding of instructions and account data, making it much easier to interact with the program.
- **GPA (Get Program Accounts) Filters**: This feature contains utilities to add filters to program accounts, allowing developers to fetch program account data more selectively and efficiently.
- **PDA (Program Derived Addresses) Utilities**: This feature contains utility functions that help derive Program Derived Addresses (PDAs) for accounts within the Whirlpool Program, simplifying address generation for developers.

## Installation:

<Tabs groupId="programming-languages">
<TabItem value="ts" label="Typescript" default>
**NOTE**: This SDK requires Solana Web3.js SDK v2, which is currently in Release Candidate (RC) status. It is not compatible with the widely used v1.x.x version.
```bash
npm install @orca-so/whirlpools-client
```
</TabItem>
<TabItem value="rust" label="Rust">
**NOTE**: This SDK requires Solana Web3.js SDK v2.
```bash
cargo add orca_whirlpools_client
```
</TabItem>
</Tabs>

## Usage
Here are some basic examples of how to use the package.

### Fetching Whirlpool Accounts with Filters
The following example demonstrates how to fetch Whirlpools accounts based on specific filters, using the GPA utilities:

<Tabs groupId="programming-languages">
<TabItem value="ts" label="Typescript" default>
```tsx
import { createSolanaRpc, address, devnet } from '@solana/web3.js';
import { fetchAllWhirlpoolWithFilter, whirlpoolTokenMintAFilter } from "@orca-so/whirlpools-client";

const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

const tokenMintA = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const filter = whirlpoolTokenMintAFilter(tokenMintA);

const accounts = await fetchAllWhirlpoolWithFilter(rpc, filter);
console.log(accounts);
```
</TabItem>
<TabItem value="rust" label="Rust">
`orca_whirlpools_client` currently does not support fetching accounts with filters.
</TabItem>
</Tabs>



### Deriving a PDA
To derive a PDA for a Whirlpool account, you can use the `getWhirlpoolAddress` PDA utility.

<Tabs groupId="programming-languages">
<TabItem value="ts" label="Typescript" default>
```tsx
import { getWhirlpoolAddress } from "@orca-so/whirlpools-client";
import { address } from '@solana/web3.js';

const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); //wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); //DevUSDC
const tickSpacing = 64;

const whirlpoolPda = await getWhirlpoolAddress(
whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tickSpacing,
);
console.log(whirlpoolPda);
```
</TabItem>
<TabItem value="rust" label="Rust">
```rust
use orca_whirlpools_client::get_whirlpool_address;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;

fn main() {
let whirlpool_config_address = Pubkey::from_str("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR").unwrap();
let token_mint_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap(); // wSOL
let token_mint_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // DevUSDC
let tick_spacing = 64;

let (whirlpool_pda, _bump) = get_whirlpool_address(&whirlpool_config_address, &token_mint_a, &token_mint_b, tick_spacing).unwrap();
println!("{:?}", whirlpool_pda);
}
```
</TabItem>
</Tabs>

### Example: Initialize Pool Instruction
The following example demonstrates how to create an InitializePool instruction using the Codama-IDL autogenerated code:

<Tabs groupId="programming-languages">
<TabItem value="ts" label="Typescript" default>
```tsx
import { getInitializePoolV2Instruction, getTokenBadgeAddress, getWhirlpoolAddress, getFeeTierAddress } from "@orca-so/whirlpools-client";
import { address, generateKeyPairSigner } from '@solana/web3.js';

const whirlpoolConfigAddress = address("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR");
const tokenMintA = address("So11111111111111111111111111111111111111112"); // wSOL
const tokenMintB = address("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k"); // DevUSDC
const tokenBadgeA = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintA)
const tokenBadgeB = await getTokenBadgeAddress(whirlpoolConfigAddress, tokenMintB)
const wallet = await generateKeyPairSigner(); // CAUTION: this wallet is not persistent
const tickSpacing = 8;
const whirlpool = await getWhirlpoolAddress(whirlpoolConfigAddress, tokenMintA, tokenMintB, tickSpacing);
const tokenVaultA = await generateKeyPairSigner();
const tokenVaultB = await generateKeyPairSigner();
const feeTier = await getFeeTierAddress(whirlpoolConfigAddress, tickSpacing);
const tokenProgramA = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const tokenProgramB = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
const initialSqrtPrice = BigInt(7459106261056563200n);

const initializePoolInstruction = getInitializePoolV2Instruction({
whirlpoolsConfig: whirlpoolConfigAddress,
tokenMintA,
tokenMintB,
tokenBadgeA,
tokenBadgeB,
funder: wallet,
whirlpool,
tokenVaultA,
tokenVaultB,
feeTier,
whirlpoolBump: 1,
tickSpacing,
tokenProgramA,
tokenProgramB,
initialSqrtPrice
});

console.log(initializePoolInstruction);
```
</TabItem>
<TabItem value="rust" label="Rust">
```rust
use orca_whirlpools_client::{
instructions::InitializePoolV2Builder,
get_fee_tier_address,
get_token_badge_address,
get_whirlpool_address,
};
use solana_sdk::{
pubkey::Pubkey,
signer::{keypair::Keypair, Signer},
};
use std::str::FromStr;

fn main() {
let whirlpool_config_address = Pubkey::from_str("FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR").unwrap();
let token_mint_a = Pubkey::from_str("So11111111111111111111111111111111111111112").unwrap(); // wSOL
let token_mint_b = Pubkey::from_str("BRjpCHtyQLNCo8gqRUr8jtdAj5AjPYQaoqbvcZiHok1k").unwrap(); // DevUSDC
let (token_badge_a, _bump) = get_token_badge_address(&whirlpool_config_address, &token_mint_a).unwrap();
let (token_badge_b, _bump) = get_token_badge_address(&whirlpool_config_address, &token_mint_b).unwrap();
let wallet = Keypair::new(); // CAUTION: this wallet is not persistent
let tick_spacing = 8;
let (whirlpool_pda, _bump) = get_whirlpool_address(&whirlpool_config_address, &token_mint_a, &token_mint_b, tick_spacing).unwrap();
let token_vault_a = Keypair::new();
let token_vault_b = Keypair::new();
let (fee_tier, _bump) = get_fee_tier_address(&whirlpool_config_address, tick_spacing).unwrap();
let token_program_a = Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").unwrap();
let token_program_b = Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").unwrap();
let initial_sqrt_price = 7459106261056563200u128;

let initialize_pool_v2_instruction = InitializePoolV2Builder::new()
.whirlpools_config(whirlpool_config_address)
.token_mint_a(token_mint_a)
.token_mint_b(token_mint_b)
.token_badge_a(token_badge_a)
.token_badge_b(token_badge_b)
.funder(wallet.pubkey())
.whirlpool(whirlpool_pda)
.token_vault_a(token_vault_a.pubkey())
.token_vault_b(token_vault_b.pubkey())
.fee_tier(fee_tier)
.token_program_a(token_program_a)
.token_program_b(token_program_b)
.tick_spacing(tick_spacing)
.initial_sqrt_price(initial_sqrt_price)
.instruction();

println!("{:?}", initialize_pool_v2_instruction);
}
```
</TabItem>
</Tabs>
Loading

0 comments on commit 852a822

Please sign in to comment.