Add method to settle funds

This commit is contained in:
Gary Wang 2020-08-18 04:23:24 -07:00
parent 4d1e45f815
commit db5635c1f6
4 changed files with 107 additions and 2 deletions

View File

@ -77,4 +77,24 @@ for (let fill of await market.loadFills(connection)) {
fill.side, fill.side,
); );
} }
// Settle funds
for (let openOrders of await market.findOpenOrdersAccountsForOwner(
connection,
owner.publicKey,
)) {
if (openOrders.baseTokenFree > 0 || openOrders.quoteTokenFree > 0) {
// spl-token accounts to which to send the proceeds from trades
let baseTokenAccount = new PublicKey('...');
let quoteTokenAccount = new PublicKey('...');
await market.settleFunds(
connection,
owner,
openOrders,
baseTokenAccount,
quoteTokenAccount,
);
}
}
``` ```

View File

@ -1,6 +1,6 @@
{ {
"name": "@project-serum/serum", "name": "@project-serum/serum",
"version": "0.5.0", "version": "0.5.1",
"description": "Library for interacting with the serum dex", "description": "Library for interacting with the serum dex",
"license": "MIT", "license": "MIT",
"repository": "project-serum/serum-js", "repository": "project-serum/serum-js",

View File

@ -51,6 +51,7 @@ INSTRUCTION_LAYOUT.inner.addVariant(
]), ]),
'cancelOrder', 'cancelOrder',
); );
INSTRUCTION_LAYOUT.inner.addVariant(5, struct([]), 'settleFunds');
export function encodeInstruction(instruction) { export function encodeInstruction(instruction) {
const b = Buffer.alloc(100); const b = Buffer.alloc(100);
@ -193,4 +194,33 @@ export class DexInstructions {
}), }),
}); });
} }
static settleFunds({
market,
openOrders,
owner,
baseVault,
quoteVault,
baseWallet,
quoteWallet,
vaultSigner,
}) {
return new TransactionInstruction({
keys: [
{ pubkey: market, isSigner: false, isWritable: true },
{ pubkey: openOrders, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: true, isWritable: false },
{ pubkey: baseVault, isSigner: false, isWritable: true },
{ pubkey: quoteVault, isSigner: false, isWritable: true },
{ pubkey: baseWallet, isSigner: false, isWritable: true },
{ pubkey: quoteWallet, isSigner: false, isWritable: true },
{ pubkey: vaultSigner, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
],
programId: DEX_PROGRAM_ID,
data: encodeInstruction({
settleFunds: {},
}),
});
}
} }

View File

@ -261,7 +261,13 @@ export class Market {
skipPreflight: this._skipPreflight, skipPreflight: this._skipPreflight,
}); });
if (this._confirmations > 0) { if (this._confirmations > 0) {
await connection.confirmTransaction(signature, this._confirmations); const { value } = await connection.confirmTransaction(
signature,
this._confirmations,
);
if (value?.err) {
throw new Error(JSON.stringify(value.err));
}
} }
return signature; return signature;
} }
@ -295,6 +301,55 @@ export class Market {
return transaction; return transaction;
} }
async settleFunds(
connection: Connection,
owner: Account,
openOrders: OpenOrders,
baseWallet: PublicKey,
quoteWallet: PublicKey,
) {
if (!openOrders.owner.equals(owner.publicKey)) {
throw new Error('Invalid open orders account');
}
const transaction = await this.makeSettleFundsTransaction(
connection,
openOrders,
baseWallet,
quoteWallet,
);
return await this._sendTransaction(connection, transaction, [owner]);
}
async makeSettleFundsTransaction(
connection: Connection,
openOrders: OpenOrders,
baseWallet: PublicKey,
quoteWallet: PublicKey,
) {
const tx = new Transaction();
// @ts-ignore
const vaultSigner = await PublicKey.createProgramAddress(
[
this.address.toBuffer(),
this._decoded.vaultSignerNonce.toArrayLike(Buffer, 'le', 8),
],
DEX_PROGRAM_ID,
);
tx.add(
DexInstructions.settleFunds({
market: this.address,
openOrders: openOrders.address,
owner: openOrders.owner,
baseVault: this._decoded.baseVault,
quoteVault: this._decoded.quoteVault,
baseWallet,
quoteWallet,
vaultSigner,
}),
);
return tx;
}
async loadRequestQueue(connection: Connection) { async loadRequestQueue(connection: Connection) {
const { data } = throwIfNull( const { data } = throwIfNull(
await connection.getAccountInfo(this._decoded.requestQueue), await connection.getAccountInfo(this._decoded.requestQueue),