CLI tool
orca-so/whirlpools avatar
orca-so/whirlpools

Whirlpools, Orca's concentrated liquidity AMM on Solana

Open source concentrated liquidity AMM contract on Solana

559 stars353 forksTypeScriptNOASSERTION

At a glance

What is it?
Whirlpools is the open-source Rust program behind Orca's concentrated liquidity automated market maker on Solana, together with the TypeScript and Rust SDKs that talk to it. The contract is deployed and verifiable on chain, has been audited six times, and the repository is a Yarn and Nx monorepo that builds the program, the SDKs and the docs together.
Who is it for?
Whirlpools suits a developer building on Orca's concentrated liquidity pools who wants to read the contract source, verify the deployed program and use SDKs that are generated from the program's own interface definition. It does not suit a project that has to support a different chain or a different AMM family, since the contract and the SDKs are Solana specific.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The contract, not a service

Whirlpools is an open-source concentrated liquidity AMM contract on the Solana blockchain, and the repository contains the Rust smart contract and SDKs to interact with a deployed program.

That framing matters, because a smart contract repository is not a piece of software you deploy and then own. The program is already deployed, and the repository is the source of what is on chain. The official deployment is at the address `whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc`, on both Solana mainnet and devnet, with explorer links given for each.

So the relationship between the code and the chain is one of correspondence, not of deployment. You do not run this contract, you interact with a specific deployed instance, and the repository tells you what that instance is supposed to be.

That is why the next feature in the README is the one that makes the whole setup verifiable. The contract is deployed using verifiable build, so that you can ensure that the hash of the on-chain program matches the hash of the program in this codebase. The tooling is the Solana Verify CLI from Ellipsis Labs, and there is a verification result published on the Osec API for that program address.

This is a meaningfully stronger property than the usual claim that the source is on GitHub. A verifiable build means the build is reproducible: someone, with the right toolchain, can rebuild the program from the source in the repository and confirm that the resulting binary is byte-for-byte the one deployed at that address. For a contract holding user funds, that closes the gap between the code you read and the code that runs, and it is the difference between trusting a repository and checking one.

The project is Orca's, the primary language is TypeScript, and the topics name anchor-lang, crypto, defi, rust, solana, typescript and web3. The licence is recorded as a custom type that GitHub cannot classify, with a LICENSE file in the repository holding the terms, which is a detail to read before you build on the code.

Six audits from four firms, and what they cover

The audit list is the other half of the trust story, and it is specific enough to be worth reading closely.

The programme has been audited several times by different security firms: Kudelski Security on Jan 28th, 2022, Neodyme on May 5th, 2022, OtterSec on Aug 21st, 2024, and Sec3 three times, on Feb 28th 2025, Jun 23rd 2025 and Aug 22nd 2025. The reports are in the repository, in the `.audits/` directory, one PDF per audit with the date in the filename.

Two things stand out. The first is the gap. There is a two-and-a-half year stretch between the May 2022 audit and the August 2024 one, and in that period the contract was live and handling funds. The second is the concentration in 2025, with three Sec3 audits in six months, which reads as a response to a period of active development rather than a routine annual review.

The reading to take from a list like this is narrower than the claim that an audited contract is safe. An audit is a snapshot of a specific version of a specific codebase, and it is worth noticing that the README dates the audits but does not say which version each one covered, so mapping a report to a release requires reading the reports. The presence of the PDFs in the repository rather than a link to a third-party page is a good sign, because the reports are then versioned with the code.

The verifiable build and the audits cover different risks, and it is worth being clear about which is which. The verifiable build answers the question of whether the deployed program is the code in this repository. The audits answer the question of whether that code has known problems. Neither addresses the question of whether the deployed program is safe to use with real value, which also depends on the economic design of the pool, the parameters chosen by the pool owner, and the behaviour of the surrounding protocols.

For a concentrated liquidity AMM, that last point is not a formality. The design concentrates liquidity into a price range, which improves capital efficiency and makes the pool's behaviour sensitive to the range being in the right place relative to the market price. That is a mechanism-level property of the design, and it is the kind of thing an audit of the contract will not tell you much about.

Four layers of SDK, and which one to pick

The SDK surface is layered, and the README is explicit about which layer suits which case.

For most purposes you can use the high-level SDKs, `@orca-so/whirlpools` for TypeScript projects and `orca_whirlpools` for Rust projects.

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

The split is sensible. The high-level SDK is the one that lets you quote a swap, build a transaction and send it without assembling instruction data by hand. The generated client is the layer where the program's own interface definition has been turned into typed account, instruction and error types, and it is what you want when you are doing something the high-level SDK does not cover, or when you want to be certain the instruction encoding matches the on-chain program.

The core package is the interesting third layer, because it holds the quoting functions, and quoting is where a concentrated liquidity AMM is mathematically awkward. The price of a swap in such a pool depends on how much liquidity sits in each tick range between the current price and the price the trade would reach, so a quote needs the tick bitmap and the position list, not just a formula. Having that in a shared package that the generated client, the high-level SDK and the Rust SDK all use means there is one implementation of the maths rather than three.

There is also a legacy path, and the README flags it as a live option rather than a deprecated one. The legacy TypeScript SDK, `@orca-so/whirlpools-sdk`, remains a solid choice, and it is currently the only option if your project uses Solana Web3.js.

That last clause is a practical compatibility statement rather than a technical one. The newer SDKs are built on the modern Solana stack, and a project still on Web3.js has to stay on the legacy SDK or migrate. The repository keeps the legacy SDK, its integration tests and its own directory, `legacy-sdk/`, so the migration path is a directory move rather than a rewrite.

The developer documentation at dev.orca.so holds the detailed overview and usage examples, and the support channel is the Orca Discord dev-questions channel.

Building it locally, and what the toolchain demands

Local development has an automated path and a manual one, and the requirements are pinned tightly.

The requirements are Anchor v0.32.1 and Solana v2.1.0. Those are exact versions, not minimums, which tells you the contract is built against a specific toolchain and that a different version may produce different output. That matters for the verifiable build story, since reproducibility is the point of the whole exercise.

The setup script is the recommended route.

bash
chmod +x scripts/setup.sh
./scripts/setup.sh

The script installs all required dependencies and builds the project. It is designed for fresh environments, cloud VMs, containers and new machines, and it does not check for existing versions. The README also says the script serves as a reference for understanding which dependencies are needed at each stage, which is a candid way of saying it is a teaching artifact as well as a convenience.

The manual route lists the steps: install the system dependencies, which are build tools, Node.js, Rust, the Solana CLI and Anchor, with the setup script as the reference for exact versions. Then clone the repository with `git clone https://github.com/orca-so/whirlpools`, install the JavaScript dependencies with `yarn`, build with `yarn build`, and set up a Solana wallet if needed.

The wallet steps are the part worth copying, because they are the difference between a build that runs and a build that can be tested on chain. You create a keypair with `solana-keygen new`, check the address with `solana address`, point the local config at devnet with `solana config set --url https://api.devnet.solana.com`, airdrop one SOL with `solana airdrop 1` for transaction fees, and confirm the balance with `solana balance`.

The Docker path exists as well. The compose file defines a set of named profiles, build-program for building only the Solana program, build-packages for the packages, build for everything, test-sdks, test-whirlpools-program and lint. The comments in the file state the intended commands, docker compose --profile build up for local development and docker compose --profile build-packages up for CI, and note that the latter assumes the program artifacts already exist in `target/`.

The images are pinned too, with the anchor build using `solanafoundation/anchor:v0.32.1` on the linux/amd64 platform, and the other services on `rust:1.86.0` with Node 22 installed on top and Yarn 4.13.0 activated through corepack.

Nx, Yarn workspaces and the release process

The repository uses Nx to manage the Rust and TypeScript codebases, and the stated reason is that it allows a monorepo with multiple packages and shared code between them, with dependencies between packages resolved automatically by Nx.

The directory layout follows from that. `/programs/*` holds the Rust programs that are deployed on Solana, `/ts-sdk/*` the TypeScript SDKs, `/rust-sdk/*` the Rust SDKs, `/docs/*` the documentation, and `/legacy-sdk/*` the legacy TypeScript SDKs and integration tests. The root also carries `Anchor.toml` for the Anchor configuration, `idl/` for the interface definition that the generated client is produced from, `nx.json` for the Nx configuration, and a `rust-toolchain.toml`.

The command model is worth understanding because it has a sharp edge. All commands should be run from the root of the repository, and Nx will try to run a command with the same name for each individual component, skipping the component if that command does not exist. So `yarn build` builds everything, `yarn clean` cleans up, `yarn test` runs the tests, and `yarn format` formats the code.

But the individual commands should not be run by themselves, because they will not resolve the right dependencies and will not execute the prerequisites. The way to target a single package is to name it, with `yarn build programs/whirlpool` or `yarn test legacy-sdk/whirlpool`. The root scripts confirm the shape, since they are all `nx run-many --target <target> --projects` invocations, and the test script excludes the integration test package explicitly with `--exclude=@orca-so/whirlpools-sdk-integration`.

That exclusion is worth noting. The SDK integration tests are excluded from the default `yarn test` run, presumably because they need a running validator or a deployed program, which is exactly the kind of dependency you do not want in a default test run on a laptop.

For log streaming there is a flag, `--output-style stream`, which allows you to view the logs as they are produced and is useful for longer running tasks like integration tests.

The release process uses changesets. When contributing you should include a changeset with your changes, created with `yarn changeset`, and if the changes are not related to any of the packages you can create an empty one with `yarn changeset --empty`. You do not have to manually update version numbers in a pull request, and publishing is done by running the publish GitHub action, which updates the versions of the packages and publishes them to npm and cargo.

What the repository does not settle

Three things a reader should take from this repository as it stands.

The first is that the contract is a given, not a component. Everything in the repository is arranged around a program that is already deployed at a known address and that you cannot change. There is no upgrade path described for the program itself, and for a deployed Solana program that is a property of the platform rather than of this project. If you need a modified version of the AMM, you are writing a new program, and this repository is a reference rather than a starting point.

The second is the version gap between the contract and the SDKs. The recorded releases are the SDK versions, v1.0.2 from 2025-01-03, v1.0.1 from 2024-12-16 and v1.0.0 from 2024-12-05, while the last push to the repository was on 2026-10-13. The audit list runs to June 2025 in terms of dates, and the most recent one is from August 2025. So there is activity on the branch, audits that postdate the last tagged SDK release, and no tag that tells you which program version any given SDK talks to. A version-aware integrator needs to check the interface definition in `idl/` against the deployed program, not just the SDK version.

The third is the licence. The repository's licence is a custom type that GitHub cannot classify, with a LICENSE file holding the actual terms. For a permissive open-source contract you would expect to recognise the licence at a glance, and here you cannot, and a source-available contract with a custom licence can include terms that a standard one does not. Whatever the terms turn out to be, they are the answer to the question of what you may do with this code, and reading the file is the only way to know.

On the alternatives, the honest comparison is with other Solana AMMs and with other concentrated liquidity designs. A constant product AMM puts all liquidity in one curve, which is simple to reason about and to integrate, and gives up capital efficiency. A concentrated liquidity design like this one puts liquidity in a price range, which is more efficient and considerably more complex, and the complexity lands on the integrator as more parameters, more tick arithmetic and more ways for a quoting library to be subtly wrong. So the choice is between a simple pool you can integrate in an afternoon and an efficient one whose maths you will be trusting to a shared package.

For a project that wants capital efficiency on Solana specifically, and is prepared to read the contract source and the quoting code before trusting it, this repository is the more transparent option, because the source, the audits and the deployed program are all in the same place.

Editorial conclusion

Whirlpools suits a developer building on Orca's concentrated liquidity pools who wants to read the contract source, verify the deployed program and use SDKs that are generated from the program's own interface definition. It does not suit a project that has to support a different chain or a different AMM family, since the contract and the SDKs are Solana specific. Verify first that the program at the deployed address matches the code in this repository through the verifiable build tooling, that the audit reports in the `.audits/` directory cover the version you are integrating with, and that the licence file in the repository, which GitHub cannot classify, permits what you intend to do with the code.

Frequently asked questions

What is the Whirlpools repository?

It contains the Rust smart contract for Whirlpools, Orca's open-source concentrated liquidity AMM on Solana, together with the TypeScript and Rust SDKs for interacting with the deployed program. The official deployment is at the address whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc on mainnet and devnet.

How can I check that the deployed Whirlpools program matches the source?

The contract is deployed using verifiable build, so the hash of the on-chain program can be compared with the hash of the program in the codebase. The README links the Solana Verify CLI from Ellipsis Labs and a verification result published on the Osec API for that program address.

Which SDK should I use to integrate with Whirlpools?

For most cases the high-level SDKs, @orca-so/whirlpools for TypeScript and orca_whirlpools for Rust. For specific use cases there is the auto-generated client with account, instruction and error parsing, and the core package with utility, math and quoting functions. The legacy @orca-so/whirlpools-sdk remains the only option for projects on Solana Web3.js.

What are the requirements for local development on Whirlpools?

Anchor v0.32.1 and Solana v2.1.0, plus Node.js, Rust and the build tools. The setup script scripts/setup.sh installs the dependencies and builds the project, and the manual route is documented with a wallet setup that creates a keypair, points the config at devnet and airdrops SOL for fees.

How does the Whirlpools repository handle releases?

With changesets. Contributors include a changeset created with yarn changeset, or an empty one with yarn changeset --empty when the change affects no package, and version numbers are not updated manually in a pull request. Publishing runs the publish GitHub action, which updates versions and publishes the packages to npm and cargo.

Official sources

  1. Issues
  2. orca-so/whirlpools on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/orca-so-whirlpools.svg)](https://hysenlabs.com/projects/orca-so-whirlpools)

Was this useful?