TypeScript SDK for interacting with the 01 Solana program, built on top of Project Serum.
Devnet | Mainnet | |
---|---|---|
Program ID | Zo1ThtSHMh9tZGECwBDL81WJRL6s3QTHf733Tyko7KQ |
Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk |
State | KwcWW7WvgSXLJcyjKZJBHLbfriErggzYHpjS9qjVD5F |
71yykwxq1zQqy99PgRsgZJXi2HHK2UDx9G4va7pH6qRv |
- 01 is in active development so all APIs and protocols are subject to change.
- The code is unaudited. Use at your own risk.
Using npm
npm install
You can use the Devnet token faucet to get Devnet only tokens to test on the Devnet program. Replace <WALLET>
, <MINT>
, and <AMOUNT>
curl -XPOST 'https://devnet-faucet.01.xyz?owner=<WALLET>&mint=<MINT>&amount=<AMOUNT>'
SOL is deposited directly using native lamports. You can get SOL either through Solana cli airdrop or at any airdrop faucet.
For markets specs on Mainnet, please visit docs.01.xyz/trading/perpetual-futures/perpetuals-specs
Symbol | Cluster | Base Lots | Quote Lots | Base Decimals | Normalization Factor |
---|---|---|---|---|---|
BTC-PERP | Devnet | 100 | 10 | 6 | n/a |
SOL-PERP | Devnet | 100000000 | 100 | 9 | n/a |
SOL-SQUARE | Devnet | 10000 | 100 | 9 | 1 |
For collateral specs on Mainnet, please visit docs.01.xyz/margin/collateral
Symbol | Cluster | Mint | Decimals |
---|---|---|---|
USDC | Devnet | 7UT1javY6X1M9R2UrPGrwcZ78SX3huaXyETff5hm5YdX |
6 |
SOL | Devnet | So11111111111111111111111111111111111111112 |
9 |
BTC | Devnet | 3n3sMJMnZhgNDaxp6cfywvjHLrV1s34ndfa6xAaYvpRs |
6 |
Symbol | Cluster | Serum Market Key |
---|---|---|
BTC-USDC | Devnet | 9vNzQmmG7c3aXuTdKKULQW2oGrYsfGZ1uRsMtgZ2APJF |
SOL-USDC | Devnet | E5gEK3WUVHzGDB6JSWZEwemJ7JZDZqHmG5gGX6NjgW2v |
Setup | Deposit/ Withdraw/ Swap | Trading
The following example shows how to run basic setup instructions.
// Setup provider (see anchor docs for more instructions on setting up a provider using your wallet)
import * as anchor from "@project-serum/anchor";
const provider = anchor.Provider.local("https://api.devnet.solana.com"); // or your own endpoint
// Setup the program
const program = createProgram(provider, Cluster.Mainnet); // or Devnet
// Load the state
const state: State = await State.load(program, stateKey);
// Create a margin account (which also creates a control account)
const margin: Margin = await Margin.create(program, state);
// Create a PerpOpenOrders account (to be created for every market)
// This step is optional. Placing an order on a new market will also create the account automatically.
const MARKET_SYMBOL = "BTC-PERP";
await margin.createPerpOpenOrders(MARKET_SYMBOL);
The following example shows how to deposit, withdraw and swap from a margin account.
// Deposit
const depositSize = 50_250.25; // $50,250.25 USDC
const repayOnly = false;
await margin.deposit(usdcMintKey, depositSize, repayOnly);
// Withdraw
const withdrawSize = 0.001; // 0.001 BTC
const allowWithdrawBorrow = false;
await margin.withdraw(btcMintKey, withdrawSize, allowWithdrawBorrow);
// Swap USDC to Token B (or vice versa)
const buy = true;
const fromSize = 50_000; // $50,000.00 USDC
const toSize = 1; // 1 BTC
const slippage = 0.1; // 10% slippage tolerance
const allowSwapBorrow = false;
await margin.swap({
buy,
tokenMint: btcMintKey,
fromSize,
toSize,
slippage,
allowBorrow: allowSwapBorrow,
serumMarket: btcUsdcSerumMarketKey,
});
The following example shows to perform trading actions.
// Place an order (automatically creates an openOrders account for you if placing on a new market)
const price = 50_000; // $50,000.00 per BTC
const size = 0.004; // 0.004 BTC
const isLong = true;
const clientId = 12; // optional clientId to uniquely tag orders (used in CancelPerpOrderByClientId)
const orderType: OrderType = { limit: {} };
await margin.placePerpOrder({
symbol: MARKET_SYMBOL,
orderType,
isLong,
price,
size,
clientId, // optional arg
});
// Fetch Market
const marketKey = state.getMarketKeyBySymbol(MARKET_SYMBOL);
const market = await ZoMarket.load(
program.provider.connection,
marketKey,
{},
DEX_PROGRAM_ID,
);
// Fetch orders per user
const orders = await market.loadOrdersForOwner(
program.provider.connection,
margin.control.pubkey,
);
// Fetch orderbook
const bids = await market.loadBids(program.provider.connection);
const asks = await market.loadAsks(program.provider.connection);
// L2 orderbook data
for (const [price, size] of bids.getL2(20)) {
console.log(price, size);
}
// Full orderbook data
for (const order of asks) {
console.log(
order.orderId,
order.price,
order.size,
order.side, // 'buy' or 'sell'
);
}
// Fetch funding info (daily, hourly)
const fundingInfo = state.getFundingInfo(MARKET_SYMBOL);
// Cancel an order by order id
const orderIsLong = true;
const orderId = orders[0]; // or whichever order that is being cancelled
await margin.cancelPerpOrder({ symbol: MARKET_SYMBOL, isLong: orderIsLong, orderId: orderId });
// Cancel an order by client id
await margin.cancelPerpOrder({ symbol: MARKET_SYMBOL, clientId: clientId });
// Settle funds
await margin.settleFunds(MARKET_SYMBOL);
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate. _ _ _ _