Implement cancellation, update instruction layout
This commit is contained in:
parent
c405061e92
commit
f6858ef533
|
@ -34,29 +34,18 @@ INSTRUCTION_LAYOUT.inner.addVariant(
|
|||
1,
|
||||
struct([
|
||||
sideLayout('side'),
|
||||
zeros(3),
|
||||
u64('limitPrice'),
|
||||
u64('maxQuantity'),
|
||||
orderTypeLayout('orderType'),
|
||||
zeros(3),
|
||||
]),
|
||||
'newOrder',
|
||||
);
|
||||
INSTRUCTION_LAYOUT.inner.addVariant(
|
||||
2,
|
||||
struct([u16('limit'), blob(2)]),
|
||||
'matchOrders',
|
||||
);
|
||||
INSTRUCTION_LAYOUT.inner.addVariant(
|
||||
3,
|
||||
struct([u16('limit'), blob(2)]),
|
||||
'consumeEvents',
|
||||
);
|
||||
INSTRUCTION_LAYOUT.inner.addVariant(2, struct([u16('limit')]), 'matchOrders');
|
||||
INSTRUCTION_LAYOUT.inner.addVariant(3, struct([u16('limit')]), 'consumeEvents');
|
||||
INSTRUCTION_LAYOUT.inner.addVariant(
|
||||
4,
|
||||
struct([
|
||||
sideLayout('side'),
|
||||
zeros(3),
|
||||
u128('orderId'),
|
||||
publicKeyLayout('owner'),
|
||||
u8('ownerSlot'),
|
||||
|
@ -128,9 +117,9 @@ export class DexInstructions {
|
|||
keys: [
|
||||
{ pubkey: market, isSigner: false, isWritable: false },
|
||||
{ pubkey: openOrders, isSigner: false, isWritable: true },
|
||||
{ pubkey: requestQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: payer, isSigner: false, isWritable: true },
|
||||
{ pubkey: owner, isSigner: true, isWritable: false },
|
||||
{ pubkey: requestQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: baseVault, isSigner: false, isWritable: true },
|
||||
{ pubkey: quoteVault, isSigner: false, isWritable: true },
|
||||
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
||||
|
@ -170,13 +159,13 @@ export class DexInstructions {
|
|||
static consumeEvents({ market, eventQueue, openOrdersAccounts, limit }) {
|
||||
return new TransactionInstruction({
|
||||
keys: [
|
||||
{ pubkey: market, isSigner: false, isWritable: true },
|
||||
{ pubkey: eventQueue, isSigner: false, isWritable: true },
|
||||
...openOrdersAccounts.map((account) => ({
|
||||
pubkey: account,
|
||||
isSigner: false,
|
||||
isWritable: true,
|
||||
})),
|
||||
{ pubkey: market, isSigner: false, isWritable: true },
|
||||
{ pubkey: eventQueue, isSigner: false, isWritable: true },
|
||||
],
|
||||
programId: DEX_PROGRAM_ID,
|
||||
data: encodeInstruction({ consumeEvents: { limit } }),
|
||||
|
|
|
@ -131,11 +131,11 @@ class EnumLayout extends UInt {
|
|||
}
|
||||
|
||||
export function sideLayout(property) {
|
||||
return new EnumLayout({ buy: 0, sell: 1 }, 1, property);
|
||||
return new EnumLayout({ buy: 0, sell: 1 }, 4, property);
|
||||
}
|
||||
|
||||
export function orderTypeLayout(property) {
|
||||
return new EnumLayout({ limit: 0, ioc: 1, postOnly: 2 }, 1, property);
|
||||
return new EnumLayout({ limit: 0, ioc: 1, postOnly: 2 }, 4, property);
|
||||
}
|
||||
|
||||
export function setLayoutDecoder(layout, decoder) {
|
||||
|
|
101
src/market.js
101
src/market.js
|
@ -61,8 +61,8 @@ export class Market {
|
|||
throw new Error('Invalid market state');
|
||||
}
|
||||
this._decoded = decoded;
|
||||
this._baseMintDecimals = baseMintDecimals;
|
||||
this._quoteMintDecimals = quoteMintDecimals;
|
||||
this._baseSplTokenDecimals = baseMintDecimals;
|
||||
this._quoteSplTokenDecimals = quoteMintDecimals;
|
||||
}
|
||||
|
||||
static get LAYOUT() {
|
||||
|
@ -202,16 +202,62 @@ export class Market {
|
|||
return { transaction, signers };
|
||||
}
|
||||
|
||||
async cancelOrder(connection, order) {
|
||||
throw new Error('not yet implemented');
|
||||
async cancelOrder(connection, owner, order) {
|
||||
const transaction = await this.makeCancelOrderTransaction(
|
||||
connection,
|
||||
order,
|
||||
);
|
||||
return await connection.sendTransaction(transaction, [owner]);
|
||||
}
|
||||
|
||||
async makeCancelOrderTransaction(connection, order) {
|
||||
const openOrdersAccount = await this.findOpenOrdersAccountForOrder(
|
||||
connection,
|
||||
order,
|
||||
);
|
||||
if (openOrdersAccount === null) {
|
||||
throw new Error('Order not found');
|
||||
}
|
||||
const transaction = new Transaction();
|
||||
transaction.add(
|
||||
DexInstructions.cancelOrder({
|
||||
market: this.address,
|
||||
openOrders: openOrdersAccount.address,
|
||||
owner: order.owner,
|
||||
requestQueue: this._decoded.requestQueue,
|
||||
side: order.side,
|
||||
orderId: order.orderId,
|
||||
ownerSlot: order.ownerSlot,
|
||||
}),
|
||||
);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
async findOpenOrdersAccountForOrder(connection, order) {
|
||||
const openOrdersAccounts = await this.findOpenOrdersAccountsForOwner(
|
||||
connection,
|
||||
order.owner,
|
||||
);
|
||||
for (const account of openOrdersAccounts) {
|
||||
if (account.orders.some((orderId) => orderId.eq(order.orderId))) {
|
||||
return account;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get _baseSplTokenMultiplier() {
|
||||
return new BN(10).pow(new BN(this._baseSplTokenDecimals));
|
||||
}
|
||||
|
||||
get _quoteSplTokenMultiplier() {
|
||||
return new BN(10).pow(new BN(this._quoteSplTokenDecimals));
|
||||
}
|
||||
|
||||
priceLotsToNumber(price) {
|
||||
return divideBnToNumber(
|
||||
price
|
||||
.mul(this._decoded.quoteLotSize)
|
||||
.mul(new BN(10).pow(this._baseMintDecimals)),
|
||||
this._decoded.baseLotSize.mul(new BN(10).pow(this._quoteMintDecimals)),
|
||||
price.mul(this._decoded.quoteLotSize).mul(this._baseSplTokenMultiplier),
|
||||
this._decoded.baseLotSize.mul(this._quoteSplTokenMultiplier),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -219,9 +265,9 @@ export class Market {
|
|||
return new BN(
|
||||
Math.round(
|
||||
(price *
|
||||
Math.pow(10, this._quoteMintDecimals) *
|
||||
Math.pow(10, this._quoteSplTokenDecimals) *
|
||||
this._decoded.baseLotSize.toNumber()) /
|
||||
(Math.pow(10, this._baseMintDecimals) *
|
||||
(Math.pow(10, this._baseSplTokenDecimals) *
|
||||
this._decoded.quoteLotSize.toNumber()),
|
||||
),
|
||||
);
|
||||
|
@ -230,13 +276,13 @@ export class Market {
|
|||
baseSizeLotsToNumber(size) {
|
||||
return divideBnToNumber(
|
||||
size.mul(this._decoded.baseLotSize),
|
||||
new BN(10).pow(this._baseMintDecimals),
|
||||
this._baseSplTokenMultiplier,
|
||||
);
|
||||
}
|
||||
|
||||
baseSizeNumberToLots(size) {
|
||||
const native = new BN(
|
||||
Math.round(size * Math.pow(10, this._baseMintDecimals)),
|
||||
Math.round(size * Math.pow(10, this._baseSplTokenDecimals)),
|
||||
);
|
||||
// rounds down to the nearest lot size
|
||||
return native.div(this._decoded.baseLotSize);
|
||||
|
@ -245,17 +291,34 @@ export class Market {
|
|||
quoteSizeLotsToNumber(size) {
|
||||
return divideBnToNumber(
|
||||
size.mul(this._decoded.quoteLotSize),
|
||||
new BN(10).pow(this._quoteMintDecimals),
|
||||
this._quoteSplTokenMultiplier,
|
||||
);
|
||||
}
|
||||
|
||||
quoteSizeNumberToLots(size) {
|
||||
const native = new BN(
|
||||
Math.round(size * Math.pow(10, this._quoteMintDecimals)),
|
||||
Math.round(size * Math.pow(10, this._quoteSplTokenDecimals)),
|
||||
);
|
||||
// rounds down to the nearest lot size
|
||||
return native.div(this._decoded.quoteLotSize);
|
||||
}
|
||||
|
||||
async matchOrders(connection, feePayer, limit) {
|
||||
const tx = new Transaction();
|
||||
tx.add(
|
||||
DexInstructions.matchOrders({
|
||||
market: this.address,
|
||||
requestQueue: this._decoded.requestQueue,
|
||||
eventQueue: this._decoded.eventQueue,
|
||||
bids: this._decoded.bids,
|
||||
asks: this._decoded.asks,
|
||||
baseVault: this._decoded.baseVault,
|
||||
quoteVault: this._decoded.quoteVault,
|
||||
limit,
|
||||
}),
|
||||
);
|
||||
return await connection.sendTransaction(tx, [feePayer]);
|
||||
}
|
||||
}
|
||||
|
||||
export const OPEN_ORDERS_LAYOUT = struct([
|
||||
|
@ -264,11 +327,11 @@ export const OPEN_ORDERS_LAYOUT = struct([
|
|||
publicKeyLayout('market'),
|
||||
publicKeyLayout('owner'),
|
||||
|
||||
// These are in native (i.e. not lot) units
|
||||
u64('baseTotal'),
|
||||
u64('baseFree'),
|
||||
u64('quoteTotal'),
|
||||
u64('quoteFree'),
|
||||
// These are in spl-token (i.e. not lot) units
|
||||
u64('baseTokenFree'),
|
||||
u64('baseTokenTotal'),
|
||||
u64('quoteTokenFree'),
|
||||
u64('quoteTokenTotal'),
|
||||
|
||||
u128('freeSlotBits'),
|
||||
u128('isBidBits'),
|
||||
|
|
Loading…
Reference in New Issue