Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a66fe3d
chore: update yellowstone to rust bindings version
jackwaller Jan 5, 2026
28dccbb
sdk: release v2.153.0-beta.2
github-actions[bot] Jan 7, 2026
0c5840d
Nick/external init account support (#2067)
lowkeynicc Jan 7, 2026
fde9d60
sdk: release v2.153.0-beta.3
github-actions[bot] Jan 7, 2026
b9407d2
Merge pull request #2063 from drift-labs/jack/updated-triton-grpc
jackwaller Jan 7, 2026
8def72d
Revert "chore: update yellowstone to rust bindings version"
jackwaller Jan 7, 2026
f2eeb60
Merge pull request #2069 from drift-labs/revert-2063-jack/updated-tri…
jackwaller Jan 7, 2026
d547905
sdk: release v2.153.0-beta.4
github-actions[bot] Jan 7, 2026
f44666e
chore: update for channelOption changes
jackwaller Jan 8, 2026
86f702d
fix: merge conflict
jackwaller Jan 8, 2026
8b64655
v2.154.0
wphan Jan 8, 2026
2f2e106
sdk: release v2.155.0-beta.0
github-actions[bot] Jan 8, 2026
386f81f
chore: add changelog
jackwaller Jan 9, 2026
f5414e6
Merge pull request #2070 from drift-labs/jack/updated-triton-grpc
jackwaller Jan 11, 2026
2001ba9
fix: lint
jackwaller Jan 11, 2026
010b1cd
sdk: release v2.155.0-beta.1
github-actions[bot] Jan 11, 2026
e1dbad4
Revert "Jack/updated triton grpc"
jackwaller Jan 13, 2026
ef7a176
Merge pull request #2071 from drift-labs/revert-2070-jack/updated-tri…
jackwaller Jan 13, 2026
1bce596
sdk: release v2.155.0-beta.2
github-actions[bot] Jan 13, 2026
e44bbaa
refactor: replace pyth-solana-receiver with copied over code (#2068)
LukasDeco Jan 14, 2026
8c2b96d
sdk: release v2.155.0-beta.3
github-actions[bot] Jan 14, 2026
a297dea
ui: reduce param checking for titan swaps (#2074)
cha-kos Jan 14, 2026
904a87e
sdk: release v2.155.0-beta.4
github-actions[bot] Jan 14, 2026
68edfec
lukas/isolated positions sdk (#1965)
LukasDeco Jan 15, 2026
0ad0f42
sdk: release v2.155.0-beta.5
github-actions[bot] Jan 15, 2026
5af1dbc
migrate spot assets (#2057)
moosecat2 Jan 19, 2026
d93bd2d
sdk: release v2.155.0-beta.6
github-actions[bot] Jan 19, 2026
bd8e72e
program: more logging for amm trading (#2078)
crispheaney Jan 21, 2026
85024a4
program: allow delegate to transfer isolated pos deposit in sub accou…
crispheaney Jan 21, 2026
4699064
program: use load_maps in update_amms (#2081)
crispheaney Jan 21, 2026
590049e
v2.155.0
wphan Jan 21, 2026
39ba768
sdk: release v2.156.0-beta.0
github-actions[bot] Jan 21, 2026
d8e74df
fix: buggy getHealth for iso positions (#2083)
LukasDeco Jan 22, 2026
b90193b
feat: pyth lazer subscriber with better resiliency (#2073)
LukasDeco Jan 22, 2026
98821f7
sdk: release v2.156.0-beta.1
github-actions[bot] Jan 22, 2026
f661320
fix: ci jobs missing node 24 (#2084)
LukasDeco Jan 23, 2026
902a005
sdk: release v2.156.0-beta.2
github-actions[bot] Jan 23, 2026
6e9e6ef
fix: sdk version tag release error (#2085)
LukasDeco Jan 23, 2026
ebe6fb3
sdk: release v2.156.0-beta.3
github-actions[bot] Jan 23, 2026
ae5bd97
sdk: support jupiter api key (#2086)
wphan Jan 24, 2026
7d7a9bc
sdk: release v2.156.0-beta.4
github-actions[bot] Jan 24, 2026
dd856fc
add other funxyz address (#2089)
lowkeynicc Jan 26, 2026
a0aa7d1
fix: use latest tag for our beta versions for now (#2090)
LukasDeco Jan 26, 2026
b629051
sdk: release v2.156.0-beta.5
github-actions[bot] Jan 26, 2026
667feb9
feat: more pyth type exports (#2091)
LukasDeco Jan 26, 2026
4394ff7
sdk: release v2.156.0-beta.6
github-actions[bot] Jan 26, 2026
bcaf43e
v2.156.0
wphan Jan 27, 2026
516151a
sdk: release v2.157.0-beta.0
github-actions[bot] Jan 27, 2026
2d43d82
add scale orders ix
lowkeynicc Jan 28, 2026
d402be7
fix tests
lowkeynicc Jan 28, 2026
a706c4f
allow up to 32 orders
lowkeynicc Jan 28, 2026
65e2692
flip start/end price logic
lowkeynicc Jan 28, 2026
3e735fe
cleanup
lowkeynicc Jan 28, 2026
e6da376
add spot
lowkeynicc Jan 28, 2026
7b4e9bd
refactor
lowkeynicc Feb 3, 2026
b4d88a7
address feedback
lowkeynicc Feb 4, 2026
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
29 changes: 22 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: "22.14.x"
node-version: "24.x.x"
registry-url: "https://registry.npmjs.org"
- name: Install yarn
run: yarn
Expand All @@ -89,13 +89,14 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: "22.14.x"
node-version: "24.x.x"
registry-url: "https://registry.npmjs.org"
- name: Install yarn
run: yarn
- name: Run lint
run: yarn lint
anchor-tests:
name: Anchor tests
runs-on: ubicloud
timeout-minutes: 60
steps:
Expand Down Expand Up @@ -128,7 +129,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: "22.14.x"
node-version: "24.x.x"
registry-url: "https://registry.npmjs.org"

- name: Setup yarn
Expand Down Expand Up @@ -161,7 +162,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "22.14.x"
node-version: "24.x.x"
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
Expand Down Expand Up @@ -224,7 +225,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: "22.14.x"
node-version: "24.x.x"
registry-url: "https://registry.npmjs.org"
- name: Build sdk
run: yarn
Expand All @@ -249,7 +250,14 @@ jobs:
}
echo "version=$PACKAGE_VERSION" >> $GITHUB_OUTPUT
- name: Publish to npm
run: npm publish --access=public
run: |
if [[ "$PACKAGE_VERSION" == *beta* ]]; then
npm publish --access=public --tag latest
elif [[ "$PACKAGE_VERSION" == *alpha* ]]; then
npm publish --access=public --tag alpha
else
npm publish --access=public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Build sdk for browser
Expand All @@ -259,7 +267,14 @@ jobs:
# Update package name for browser version while keeping the same version
node -e "const pkg = require('./package.json'); pkg.name = pkg.name + '-browser'; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));"
- name: Publish browser version to npm
run: npm publish --access=public
run: |
if [[ "$PACKAGE_VERSION" == *beta* ]]; then
npm publish --access=public --tag beta
elif [[ "$PACKAGE_VERSION" == *alpha* ]]; then
npm publish --access=public --tag alpha
else
npm publish --access=public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Notify Slack on failure
Expand Down
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

### Fixes

### Breaking

## [2.156.0] - 2026-01-26

### Features

### Fixes

### Breaking

## [2.155.0] - 2026-01-20

### Features

- program: additional logging for amm fills [#2078](https://github.com/drift-labs/protocol-v2/pull/2078)
- program: allow delegate to transfer isolated pos deposit in sub account [#2079](https://github.com/drift-labs/protocol-v2/pull/2079)
- program: use load_maps in update_amms [#2081](https://github.com/drift-labs/protocol-v2/pull/2081)

### Fixes

### Breaking

## [2.154.0] - 2026-01-08

### Features

- program: isolated positions [#1757](https://github.com/drift-labs/protocol-v2/pull/1757)
- program: delete serum/openbook configs [#2066](https://github.com/drift-labs/protocol-v2/pull/2066)

### Fixes

### Breaking

## [2.153.0] - 2025-12-30

### Features

- ui: save titan tx when quoted and reuse on swap by @cha-kos in [#2055](https://github.com/drift-labs/protocol-v2/pull/2055)
- feat: minified with esbuild by @LukasDeco in [#2056](https://github.com/drift-labs/protocol-v2/pull/2056)
- ui: fix falsely failing quotes from titan by @cha-kos in [#2058](https://github.com/drift-labs/protocol-v2/pull/2058)

### Fixes

- security patch: check feed id after pyth pull atomic update [84b5011](https://github.com/drift-labs/protocol-v2/commit/84b50116c15050c7d19608cd01745a8f7fc39b92)

### Breaking

## [2.152.0] - 2025-12-12

### Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
},
"dependencies": {
"@ellipsis-labs/phoenix-sdk": "1.4.2",
"@pythnetwork/pyth-solana-receiver": "0.8.0",
"@switchboard-xyz/common": "3.0.14",
"@switchboard-xyz/on-demand": "2.4.1",
"anchor-bankrun": "0.3.0",
Expand Down
2 changes: 1 addition & 1 deletion programs/drift/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "drift"
version = "2.152.0"
version = "2.156.0"
description = "Created with Anchor"
edition = "2018"

Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/controller/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,7 @@ fn fulfill_perp_order(
};

if fulfillment_methods.is_empty() {
msg!("no fulfillment methods found");
return Ok((0, 0));
}

Expand Down
4 changes: 4 additions & 0 deletions programs/drift/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,10 @@ pub enum ErrorCode {
MarketIndexNotFoundAmmCache,
#[msg("Invalid Isolated Perp Market")]
InvalidIsolatedPerpMarket,
#[msg("Invalid scale order count - must be between 2 and 10")]
InvalidOrderScaleOrderCount,
#[msg("Invalid scale order price range")]
InvalidOrderScalePriceRange,
}

#[macro_export]
Expand Down
6 changes: 4 additions & 2 deletions programs/drift/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,7 @@ pub const WHITELISTED_SWAP_PROGRAMS: &[solana_program::pubkey::Pubkey] = &[
titan_mainnet_argos_v1::id(),
];

pub const WHITELISTED_EXTERNAL_DEPOSITORS: [Pubkey; 1] =
[pubkey!("zApVWDs3nSychNnUXSS2czhY78Ycopa15zELrK2gAdM")];
pub const WHITELISTED_EXTERNAL_DEPOSITORS: [Pubkey; 2] = [
pubkey!("zApVWDs3nSychNnUXSS2czhY78Ycopa15zELrK2gAdM"),
pubkey!("4B62MS5gxpRZ2hwkGCNAAayA5f7LYZRW4z1ASSfU3SXo"),
];
14 changes: 10 additions & 4 deletions programs/drift/src/instructions/keeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2905,13 +2905,19 @@ pub fn handle_update_amms<'c: 'info, 'info>(
let state = &ctx.accounts.state;

let remaining_accounts_iter = &mut ctx.remaining_accounts.iter().peekable();
let oracle_map = &mut OracleMap::load(remaining_accounts_iter, clock.slot, None)?;
let market_map = &mut PerpMarketMap::load(
&get_market_set_from_list(market_indexes),
let AccountMaps {
mut perp_market_map,
mut oracle_map,
..
} = load_maps(
remaining_accounts_iter,
&get_market_set_from_list(market_indexes),
&MarketSet::new(),
clock.slot,
Some(state.oracle_guard_rails),
)?;

controller::repeg::update_amms(market_map, oracle_map, state, &clock)?;
controller::repeg::update_amms(&mut perp_market_map, &mut oracle_map, state, &clock)?;

Ok(())
}
Expand Down
61 changes: 55 additions & 6 deletions programs/drift/src/instructions/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ use crate::state::order_params::{
PlaceOrderOptions, PostOnlyParam,
};
use crate::state::paused_operations::{PerpOperation, SpotOperation};
use crate::state::scale_order_params::ScaleOrderParams;
use crate::state::perp_market::MarketStatus;
use crate::state::perp_market_map::{get_writable_perp_market_set, MarketSet};
use crate::state::protected_maker_mode_config::ProtectedMakerModeConfig;
Expand Down Expand Up @@ -2606,6 +2607,31 @@ pub fn handle_modify_order_by_user_order_id<'c: 'info, 'info>(
pub fn handle_place_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: Vec<OrderParams>,
) -> Result<()> {
place_orders(&ctx, PlaceOrdersInput::Orders(params))
}

#[access_control(
exchange_not_paused(&ctx.accounts.state)
)]
pub fn handle_place_scale_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: ScaleOrderParams,
) -> Result<()> {
place_orders(&ctx, PlaceOrdersInput::ScaleOrders(params))
}

/// Input for place_orders - either direct OrderParams or ScaleOrderParams to expand
enum PlaceOrdersInput {
Orders(Vec<OrderParams>),
ScaleOrders(ScaleOrderParams),
}

/// Internal implementation for placing multiple orders.
/// Used by both handle_place_orders and handle_place_scale_orders.
fn place_orders<'c: 'info, 'info>(
ctx: &Context<'_, '_, 'c, 'info, PlaceOrder>,
input: PlaceOrdersInput,
) -> Result<()> {
let clock = &Clock::get()?;
let state = &ctx.accounts.state;
Expand All @@ -2625,17 +2651,40 @@ pub fn handle_place_orders<'c: 'info, 'info>(

let high_leverage_mode_config = get_high_leverage_mode_config(&mut remaining_accounts)?;

// Convert input to order params, expanding scale orders if needed
let order_params = match input {
PlaceOrdersInput::Orders(params) => params,
PlaceOrdersInput::ScaleOrders(scale_params) => {
let order_step_size = match scale_params.market_type {
MarketType::Perp => {
let market = perp_market_map.get_ref(&scale_params.market_index)?;
market.amm.order_step_size
}
MarketType::Spot => {
let market = spot_market_map.get_ref(&scale_params.market_index)?;
market.order_step_size
}
};

scale_params.expand_to_order_params(order_step_size)
.map_err(|e| {
msg!("Failed to expand scale order params: {:?}", e);
ErrorCode::InvalidOrder
})?
}
};

validate!(
params.len() <= 32,
order_params.len() <= 32,
ErrorCode::DefaultError,
"max 32 order params"
)?;

let user_key = ctx.accounts.user.key();
let mut user = load_mut!(ctx.accounts.user)?;

let num_orders = params.len();
for (i, params) in params.iter().enumerate() {
let num_orders = order_params.len();
for (i, params) in order_params.iter().enumerate() {
validate!(
!params.is_immediate_or_cancel(),
ErrorCode::InvalidOrderIOC,
Expand All @@ -2654,7 +2703,7 @@ pub fn handle_place_orders<'c: 'info, 'info>(

if params.market_type == MarketType::Perp {
controller::orders::place_perp_order(
&ctx.accounts.state,
state,
&mut user,
user_key,
&perp_market_map,
Expand All @@ -2668,7 +2717,7 @@ pub fn handle_place_orders<'c: 'info, 'info>(
)?;
} else {
controller::orders::place_spot_order(
&ctx.accounts.state,
state,
&mut user,
user_key,
&perp_market_map,
Expand Down Expand Up @@ -4842,7 +4891,7 @@ pub struct TransferIsolatedPerpPositionDeposit<'info> {
pub user: AccountLoader<'info, User>,
#[account(
mut,
has_one = authority
constraint = is_stats_for_user(&user, &user_stats)?
)]
pub user_stats: AccountLoader<'info, UserStats>,
pub authority: Signer<'info>,
Expand Down
8 changes: 8 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::controller::position::PositionDirection;
use crate::state::if_rebalance_config::IfRebalanceConfigParams;
use crate::state::oracle::PrelaunchOracleParams;
use crate::state::order_params::{ModifyOrderParams, OrderParams};
use crate::state::scale_order_params::ScaleOrderParams;
use crate::state::perp_market::{ContractTier, MarketStatus};
use crate::state::settle_pnl_mode::SettlePnlMode;
use crate::state::spot_market::AssetTier;
Expand Down Expand Up @@ -367,6 +368,13 @@ pub mod drift {
handle_place_orders(ctx, params)
}

pub fn place_scale_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: ScaleOrderParams,
) -> Result<()> {
handle_place_scale_orders(ctx, params)
}

pub fn begin_swap<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, Swap<'info>>,
in_market_index: u16,
Expand Down
14 changes: 13 additions & 1 deletion programs/drift/src/math/fulfillment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::error::DriftResult;
use crate::math::casting::Cast;
use crate::math::matching::do_orders_cross;
use crate::math::safe_unwrap::SafeUnwrap;
use crate::msg;
use crate::state::fulfillment::{PerpFulfillmentMethod, SpotFulfillmentMethod};
use crate::state::perp_market::AMM;
use crate::state::user::Order;
Expand Down Expand Up @@ -73,7 +74,18 @@ pub fn determine_perp_fulfillment_methods(

if amm_is_available {
let taker_crosses_amm = match limit_price {
Some(taker_price) => do_orders_cross(maker_direction, amm_price, taker_price),
Some(taker_price) => {
let crosses = do_orders_cross(maker_direction, amm_price, taker_price);
if !crosses && fulfillment_methods.is_empty() {
msg!(
"taker does not cross amm: taker price {} amm price {}",
taker_price,
amm_price
);
}
crosses
}

None => true,
};

Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod oracle;
pub mod oracle_map;
pub mod order_params;
pub mod paused_operations;
pub mod scale_order_params;
pub mod perp_market;
pub mod perp_market_map;
pub mod protected_maker_mode_config;
Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/state/order_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,3 +1027,4 @@ pub fn parse_optional_params(optional_params: Option<u32>) -> (u8, u8) {
None => (0, 100),
}
}

Loading
Loading