Skip to content

Commit

Permalink
bump client
Browse files Browse the repository at this point in the history
  • Loading branch information
binyebarwe committed Nov 23, 2023
1 parent cc17e92 commit 8333a14
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 78 deletions.
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openbook-dex/openbook-v2",
"version": "0.0.14",
"version": "0.0.15",
"description": "Typescript Client for openbook-v2 program.",
"repository": "https://github.com/openbook-dex/openbook-v2/",
"author": {
Expand Down Expand Up @@ -32,21 +32,22 @@
"dependencies": {
"@coral-xyz/anchor": "^0.28.0",
"@solana/spl-token": "0.3.8",
"@solana/web3.js": "^1.77.3"
"@solana/web3.js": "^1.77.3",
"big.js": "^6.2.1"
},
"devDependencies": {
"eslint-config-prettier": "^8.10.0",
"fs": "^0.0.1-security",
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"chai": "^4.3.4",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.10.0",
"eslint-config-standard-with-typescript": "^37.0.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise": "^6.0.0",
"fs": "^0.0.1-security",
"mocha": "^9.0.3",
"prettier": "^2.6.2",
"ts-mocha": "^10.0.0",
Expand Down
65 changes: 65 additions & 0 deletions ts/client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,71 @@ export class OpenBookV2Client {
return await this.sendAndConfirmTransaction([ix], { signers });
}

public async closeOpenOrdersIndexer(
owner: Keypair,
market: MarketAccount,
openOrdersIndexer?: PublicKey,
): Promise<TransactionSignature> {
if (openOrdersIndexer == null) {
openOrdersIndexer = this.findOpenOrdersIndexer(owner.publicKey);
}
if (openOrdersIndexer !== null) {
const ix = await this.program.methods
.closeOpenOrdersIndexer()
.accounts({
owner: owner.publicKey,
openOrdersIndexer: market.asks,
solDestination: market.bids,
tokenProgram: TOKEN_PROGRAM_ID,
})
.instruction();

const additionalSigners: Signer[] = [];
if (owner.publicKey !== this.walletPk) {
additionalSigners.push(owner);
}

return await this.sendAndConfirmTransaction([ix], {
additionalSigners,
});
}
throw new Error('No open order indexer for the specified owner');
}

public async closeOpenOrdersAccount(
payer: Keypair,
owner: Keypair = payer,
openOrdersPublicKey: PublicKey,
market: MarketAccount,
solDestination: PublicKey = this.walletPk,
openOrdersIndexer?: PublicKey,
): Promise<TransactionSignature> {
if (openOrdersIndexer == null) {
openOrdersIndexer = this.findOpenOrdersIndexer(owner.publicKey);
}
if (openOrdersIndexer !== null) {
const ix = await this.program.methods
.closeOpenOrdersAccount()
.accounts({
payer: payer.publicKey,
owner: owner.publicKey,
openOrdersIndexer,
openOrdersAccount: openOrdersPublicKey,
solDestination,
systemProgram: SystemProgram.programId,
})
.instruction();
const additionalSigners = [payer];
if (owner !== payer) {
additionalSigners.push(owner);
}
return await this.sendAndConfirmTransaction([ix], {
additionalSigners,
});
}
throw new Error('No open order indexer for the specified owner');
}

// Use getAccountsToConsume as a helper
public async consumeEvents(
marketPublicKey: PublicKey,
Expand Down
70 changes: 67 additions & 3 deletions ts/client/src/market.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@ import {
type AccountInfo,
type Message,
} from '@solana/web3.js';
import { OPENBOOK_PROGRAM_ID, getFilteredProgramAccounts } from './client';
import { utils, Program, type Provider, getProvider } from '@coral-xyz/anchor';

import {
type MarketAccount,
OPENBOOK_PROGRAM_ID,
getFilteredProgramAccounts,
} from './client';
import {
utils,
Program,
type Provider,
getProvider,
BN,
} from '@coral-xyz/anchor';
import { QUOTE_DECIMALS, toNative, toUiDecimals } from './utils/utils';
import Big from 'big.js';
import { IDL, type OpenbookV2 } from './openbook_v2';
const BATCH_TX_SIZE = 50;

Expand Down Expand Up @@ -110,3 +121,56 @@ export async function findAllMarkets(
}
return marketsAll;
}

function priceLotsToUiConverter(market: MarketAccount): number {
return new Big(10)
.pow(market.baseDecimals - QUOTE_DECIMALS)
.mul(new Big(this.quoteLotSize.toString()))
.div(new Big(this.baseLotSize.toString()))
.toNumber();
}

function baseLotsToUiConverter(market: MarketAccount): number {
return new Big(this.baseLotSize.toString())
.div(new Big(10).pow(market.baseDecimals))
.toNumber();
}
function quoteLotsToUiConverter(): number {
return new Big(this.quoteLotSize.toString())
.div(new Big(10).pow(QUOTE_DECIMALS))
.toNumber();
}

export function uiPriceToLots(market: MarketAccount, price: number): BN {
return toNative(price, QUOTE_DECIMALS)
.mul(market.baseLotSize)
.div(market.quoteLotSize.mul(new BN(Math.pow(10, market.baseDecimals))));
}

export function uiBaseToLots(market: MarketAccount, quantity: number): BN {
return toNative(quantity, market.baseDecimals).div(market.baseLotSize);
}

export function uiQuoteToLots(market: MarketAccount, uiQuote: number): BN {
return toNative(uiQuote, QUOTE_DECIMALS).div(market.quoteLotSize);
}

export function priceLotsToNative(market: MarketAccount, price: BN): BN {
return price.mul(market.quoteLotSize).div(market.baseLotSize);
}

export function priceLotsToUi(market: MarketAccount, price: BN): number {
return parseFloat(price.toString()) * priceLotsToUiConverter(market);
}

export function priceNativeToUi(market: MarketAccount, price: number): number {
return toUiDecimals(price, QUOTE_DECIMALS - market.baseDecimals);
}

export function baseLotsToUi(market: MarketAccount, quantity: BN): number {
return parseFloat(quantity.toString()) * baseLotsToUiConverter(market);
}

export function quoteLotsToUi(quantity: BN): number {
return parseFloat(quantity.toString()) * quoteLotsToUiConverter();
}
98 changes: 98 additions & 0 deletions ts/client/src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
import {
PublicKey,
SystemProgram,
TransactionInstruction,
} from '@solana/web3.js';
import BN from 'bn.js';
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
} from '@solana/spl-token';

export const Side = {
Bid: { bid: {} },
Ask: { ask: {} },
Expand All @@ -16,3 +27,90 @@ export const SelfTradeBehavior = {
CancelProvide: { cancelProvide: {} },
AbortTransaction: { abortTransaction: {} },
};

///
/// numeric helpers
///
export const U64_MAX_BN = new BN('18446744073709551615');
export const I64_MAX_BN = new BN('9223372036854775807').toTwos(64);

export function bpsToDecimal(bps: number): number {
return bps / 10000;
}

export function percentageToDecimal(percentage: number): number {
return percentage / 100;
}

export function toNative(uiAmount: number, decimals: number): BN {
return new BN((uiAmount * Math.pow(10, decimals)).toFixed(0));
}

export function toUiDecimals(nativeAmount: number, decimals: number): number {
return nativeAmount / Math.pow(10, decimals);
}

export const QUOTE_DECIMALS = 6;

export function toUiDecimalsForQuote(nativeAmount: number): number {
return toUiDecimals(nativeAmount, QUOTE_DECIMALS);
}

///

///
/// web3js extensions
///

/**
* Get the address of the associated token account for a given mint and owner
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Address of the associated token account
*/
export async function getAssociatedTokenAddress(
mint: PublicKey,
owner: PublicKey,
allowOwnerOffCurve = true,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID,
): Promise<PublicKey> {
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer()))
throw new Error('TokenOwnerOffCurve!');

const [address] = await PublicKey.findProgramAddress(
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
associatedTokenProgramId,
);

return address;
}

export async function createAssociatedTokenAccountIdempotentInstruction(
payer: PublicKey,
owner: PublicKey,
mint: PublicKey,
): Promise<TransactionInstruction> {
const account = await getAssociatedTokenAddress(mint, owner);
return new TransactionInstruction({
keys: [
{ pubkey: payer, isSigner: true, isWritable: true },
{ pubkey: account, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: false, isWritable: false },
{ pubkey: mint, isSigner: false, isWritable: false },
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
],
programId: ASSOCIATED_TOKEN_PROGRAM_ID,
data: Buffer.from([0x1]),
});
}
Loading

0 comments on commit 8333a14

Please sign in to comment.