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

Update doc site and SDK related recommendations #477

Merged
merged 6 commits into from
Nov 7, 2024
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
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).
Copy link
Member

Choose a reason for hiding this comment

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

nit: percent encoding in the url looks kinda ugly here. Is it needed?


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