npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@omnipair/dusk-sdk

v2.0.2

Published

Omnipair Dusk (v2) SDK for program writes, RPC reads, previews, and indexer data

Readme

@omnipair/dusk-sdk

TypeScript SDK for Omnipair Dusk (v2).

A Dusk instance is an enriched Anchor program facade. It exposes the raw Anchor program through dusk.program, alongside typed on-chain reads and previews through dusk.get, transaction builders through dusk.write, and indexed historical data through dusk.fetch.

The package exports the generated Anchor IDL/types, PDA helpers, typed preview decoders, a small write/read facade over the Dusk program, and an indexer client for historical API data.

Install

npm install @omnipair/dusk-sdk
# or
yarn add @omnipair/dusk-sdk

Dusk Client

import { AnchorProvider } from "@coral-xyz/anchor";
import { Connection } from "@solana/web3.js";
import { Dusk } from "@omnipair/dusk-sdk";

const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const provider = new AnchorProvider(connection, wallet, { commitment: "confirmed" });

const dusk = new Dusk({
  provider,
  indexerBaseUrl: "https://api.indexer.omnipair.fi/api/v1",
});

The client is intentionally split by source of truth:

  • dusk.write: Anchor instruction, transaction, and RPC builders.
  • dusk.get: PDA helpers, direct RPC account fetches, and typed simulation previews.
  • dusk.fetch: historical/indexed HTTP API methods.

Write Instructions

const ix = await dusk.write.swapInstruction(
  {
    exactAssetIn: amountIn,
    minAssetOut: minAmountOut,
  },
  {
    market,
    accounts: {
      market,
      futarchyAuthority,
      trader,
      assetInMint,
      assetOutMint,
      reserveInVault,
      reserveOutVault,
      traderAssetInAccount,
      traderAssetOutAccount,
      tokenProgram,
      token2022Program,
      eventAuthority,
      program: dusk.program.programId,
    },
    remainingAccounts: [
      // Token-2022 transfer-hook extras only. The SDK preserves this tail.
    ],
  }
);

swapBuilder(...), swapInstruction(...), swapTransaction(...), and swapRpc(...) fetch the market before building the swap. Whenever either hLP side has nonzero supply or residual exposure, they prepend the canonical five-account prefix exactly once: [yLP mint, base hLP yLP vault, quote hLP yLP vault, base interest vault, quote interest vault]. Caller-provided Token-2022 transfer-hook extras remain after that prefix.

write.builder(...), write.transaction(...), and write.rpc(...) expose the same generic path for every Dusk instruction in the IDL.

hLP deposits and withdrawals use async composite builders because both asset-denominated YieldAccount PDAs must exist before the liquidity instruction runs. The SDK validates their owner, exact layout size, and Anchor discriminator. If either account is missing or is only a prefunded System PDA, it prepends the permissionless, idempotent initializer in the same transaction:

const { transaction, setupInstructions, baseYieldAccount, quoteYieldAccount } =
  await dusk.write.depositSingleSided(
    { depositAmount, minHlpAmount },
    {
      payer: owner,
      owner,
      market,
      targetHlpMint,
      baseMint,
      quoteMint,
      accounts: depositAccounts,
    }
  );

// setupInstructions is empty when both canonical accounts are already valid.
await provider.sendAndConfirm(transaction);

withdrawSingleSided(...) has the same return shape and setup behavior. The initializer is safe to compose unconditionally, including when a third party has transferred lamports to the PDA address before initialization.

LP token accounts should be owned by a wallet that can sign Dusk instructions, or by a PDA whose controlling program invokes Dusk with invoke_signed. SPL multisig-owned LP accounts are unsupported: Token-2022 transfers can checkpoint yield to that owner, but the multisig account itself cannot sign Dusk's claim or recipient-update instruction.

Referral Interest Sharing

Futarchy first lists a referrer and configures its share of realized protocol interest revenue:

const configureTx = await dusk.write.configureReferralPartnerTransaction({
  authoritySigner: futarchySigner.publicKey,
  referrer,
  interestShareBps: 2_500,
  active: true,
});

The listed referrer may then designate the wallet that receives claims:

const partnerTx = await dusk.write.setReferralRecipientTransaction({
  authority: referrer.publicKey,
  recipient,
});

The referred-action builders derive the partner and its per-market, per-mint accrual account, initialize the accrual idempotently, and compose setup with the debt-opening instruction:

const { transaction, referralPartner, referralAccrual } =
  await dusk.write.referredBorrow(
    {
      borrowAmount,
      minDebtAmountOut,
      minLiquidationCfBps,
    },
    {
      payer: borrower,
      referrer,
      market,
      debtMint,
      accounts: borrowAccounts,
    }
  );

referredOpenLeverage(...) provides the equivalent leverage-opening flow. Existing borrow debt sides and leverage positions retain their bound partner on later debt increases. The program snapshots the partner share, capped by the current runtime maximum, when the binding is created. Deactivation or later rate/cap updates affect new bindings only. Referral does not change requested principal, position debt, interest, health, or liquidation terms.

When interest is realized, the partner accrues a governed share of the DAO's interest revenue. Claims always pay a token account owned by the partner's current recipient, and the SDK resolves Token-2022 transfer-hook accounts:

const claimTx = await dusk.write.claimReferralInterestTransaction({
  authority: referrer,
  market,
  mint: debtMint,
  recipientTokenAccount,
});

referralBindingInterestShareBps(...) computes the admission-time capped share. Pass that stored share to quoteReferralInterestShare(...) to mirror the on-chain floor rounding for realized interest.

Get On-Chain State

const [market] = dusk.get.pda.market(baseMint, quoteMint, paramsHash);
const account = await dusk.get.market(market);

const swap = await dusk.get.previewSwap({
  market,
  assetInMint: baseMint,
  assetOutMint: quoteMint,
  exactAssetIn: amountIn,
});

Preview methods use Solana simulateTransaction and decode typed Anchor return data. They replace the old log-parsing getter workaround.

Available typed previews:

  • previewMarket(market).
  • previewSwap({ market, assetInMint, assetOutMint, exactAssetIn }).
  • previewBorrowCapacity({ market, collateralAssetMint, debtAssetMint, collateralAmount, projectedBorrowAmount }).
  • previewBorrowPosition({ market, borrowPosition }).

previewBorrowCapacity exposes both the health-limited result of the on-chain binary search and the final limit after cash and daily-borrow constraints:

const capacity = await dusk.get.previewBorrowCapacity({
  market,
  collateralAssetMint: baseMint,
  debtAssetMint: quoteMint,
  collateralAmount,
  // Optional: quote CF and health terms for this requested principal.
  projectedBorrowAmount,
});

capacity.maxDebtByHealth;
capacity.maxDebtByCash;
capacity.maxDebtByDailyLimit;
capacity.maxDebt;
capacity.maxBorrowAmount;
capacity.maxCfBps;
capacity.liquidationCfBps;
capacity.projectedGlobalHealthContribution;
capacity.projectedGlobalMarketHealthBps;
capacity.projectedEffectiveExistingDebtNad;

Fetch Historical Data

const pools = await dusk.fetch.pools({ limit: 50, sortBy: "tvl", sortOrder: "desc" });
const activity = await dusk.fetch.poolActivity(market, {
  categories: ["swaps", "liquidity", "lending"],
  limit: 100,
});
const snapshots = await dusk.fetch.userPortfolioSnapshots(owner, "30D");

The indexer client wraps the Omnipair /api/v1 routes for pools, stats, users, positions, GeckoTerminal, CoinGecko, and CMC-compatible data. Use dusk.fetch.request(path, options) for new or unwrapped endpoints.

Raw Program Exports

import {
  createDuskProgram,
  deriveMarketAddress,
  IDL,
  PROGRAM_ID,
  type DuskIdl,
} from "@omnipair/dusk-sdk";

const program = createDuskProgram({ provider });

DUSK_PROGRAM_ID is exported for integrations that prefer an explicit program name over the generic PROGRAM_ID constant.

ESM Compatibility

This package ships strict ESM-compatible output. Relative module specifiers include .js extensions in emitted files.

License

MIT