From 2067c6c2b982f0278cb51d2a3bb8679c6e901bc2 Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Sat, 15 Jan 2022 16:22:48 -0500 Subject: [PATCH 1/4] ts: builder api --- tests/cfo/tests/cfo.js | 113 ++++++++++----------- tests/cfo/tests/utils/index.js | 120 +++++++++++----------- tests/cfo/tests/utils/stake.js | 31 +++--- ts/src/program/index.ts | 9 ++ ts/src/program/namespace/index.ts | 12 +++ ts/src/program/namespace/methods.ts | 143 +++++++++++++++++++++++++++ ts/src/program/namespace/simulate.ts | 2 +- 7 files changed, 304 insertions(+), 126 deletions(-) create mode 100644 ts/src/program/namespace/methods.ts diff --git a/tests/cfo/tests/cfo.js b/tests/cfo/tests/cfo.js index 8bf06ce800..c118d81d56 100644 --- a/tests/cfo/tests/cfo.js +++ b/tests/cfo/tests/cfo.js @@ -225,29 +225,24 @@ describe("cfo", () => { stake: stakeBump, treasury: treasuryBump, }; - await program.rpc.createOfficer( - bumps, - distribution, - registrar, - msrmRegistrar, - { - accounts: { - officer, - srmVault, - usdcVault, - stake, - treasury, - srmMint: ORDERBOOK_ENV.mintA, - usdcMint: ORDERBOOK_ENV.usdc, - authority: program.provider.wallet.publicKey, - dexProgram: DEX_PID, - swapProgram: SWAP_PID, - tokenProgram: TOKEN_PID, - systemProgram: SystemProgram.programId, - rent: SYSVAR_RENT_PUBKEY, - }, - } - ); + await program.methods + .createOfficer(bumps, distribution, registrar, msrmRegistrar) + .accounts({ + officer, + srmVault, + usdcVault, + stake, + treasury, + srmMint: ORDERBOOK_ENV.mintA, + usdcMint: ORDERBOOK_ENV.usdc, + authority: program.provider.wallet.publicKey, + dexProgram: DEX_PID, + swapProgram: SWAP_PID, + tokenProgram: TOKEN_PID, + systemProgram: SystemProgram.programId, + rent: SYSVAR_RENT_PUBKEY, + }) + .rpc(); officerAccount = await program.account.officer.fetch(officer); assert.ok( @@ -260,8 +255,9 @@ describe("cfo", () => { }); it("Creates a token account for the officer associated with the market", async () => { - await program.rpc.createOfficerToken(bBump, { - accounts: { + await program.methods + .createOfficerToken(bBump) + .accounts({ officer, token: bVault, mint: ORDERBOOK_ENV.mintB, @@ -269,16 +265,17 @@ describe("cfo", () => { systemProgram: SystemProgram.programId, tokenProgram: TOKEN_PID, rent: SYSVAR_RENT_PUBKEY, - }, - }); + }) + .rpc(); const tokenAccount = await B_TOKEN_CLIENT.getAccountInfo(bVault); assert.ok(tokenAccount.state === 1); assert.ok(tokenAccount.isInitialized); }); it("Creates an open orders account for the officer", async () => { - await program.rpc.createOfficerOpenOrders(openOrdersBump, { - accounts: { + await program.methods + .createOfficerOpenOrders(openOrdersBump) + .accounts({ officer, openOrders, payer: program.provider.wallet.publicKey, @@ -286,8 +283,8 @@ describe("cfo", () => { systemProgram: SystemProgram.programId, rent: SYSVAR_RENT_PUBKEY, market: ORDERBOOK_ENV.marketA.address, - }, - }); + }) + .rpc(); await program.rpc.createOfficerOpenOrders(openOrdersBumpB, { accounts: { officer, @@ -310,8 +307,9 @@ describe("cfo", () => { program.provider, sweepVault ); - await program.rpc.sweepFees({ - accounts: { + await program.methods + .sweepFees() + .accounts({ officer, sweepVault, mint: ORDERBOOK_ENV.usdc, @@ -323,8 +321,8 @@ describe("cfo", () => { dexProgram: DEX_PID, tokenProgram: TOKEN_PID, }, - }, - }); + }) + .rpc(); const afterTokenAccount = await serumCmn.getTokenAccount( program.provider, sweepVault @@ -336,26 +334,28 @@ describe("cfo", () => { }); it("Creates a market auth token", async () => { - await program.rpc.authorizeMarket(marketAuthBump, { - accounts: { + await program.methods + .authorizeMarket(marketAuthBump) + .accounts({ officer, authority: program.provider.wallet.publicKey, marketAuth, payer: program.provider.wallet.publicKey, market: ORDERBOOK_ENV.marketA.address, systemProgram: SystemProgram.programId, - }, - }); - await program.rpc.authorizeMarket(marketAuthBumpB, { - accounts: { + }) + .rpc(); + await program.methods + .authorizeMarket(marketAuthBumpB) + .accounts({ officer, authority: program.provider.wallet.publicKey, marketAuth: marketAuthB, payer: program.provider.wallet.publicKey, market: ORDERBOOK_ENV.marketB.address, systemProgram: SystemProgram.programId, - }, - }); + }) + .rpc(); }); it("Transfers into the mintB vault", async () => { @@ -378,8 +378,9 @@ describe("cfo", () => { quoteDecimals: 6, strict: false, }; - await program.rpc.swapToUsdc(minExchangeRate, { - accounts: { + await program.methods + .swapToUsdc(minExchangeRate) + .accounts({ officer, market: { market: marketBClient.address, @@ -402,8 +403,8 @@ describe("cfo", () => { tokenProgram: TOKEN_PID, instructions: SYSVAR_INSTRUCTIONS_PUBKEY, rent: SYSVAR_RENT_PUBKEY, - }, - }); + }) + .rpc(); const bVaultAfter = await B_TOKEN_CLIENT.getAccountInfo(bVault); const usdcVaultAfter = await USDC_TOKEN_CLIENT.getAccountInfo(usdcVault); @@ -424,8 +425,9 @@ describe("cfo", () => { quoteDecimals: 6, strict: false, }; - await program.rpc.swapToSrm(minExchangeRate, { - accounts: { + await program.methods + .swapToSrm(minExchangeRate) + .accounts({ officer, market: { market: marketAClient.address, @@ -449,8 +451,8 @@ describe("cfo", () => { tokenProgram: TOKEN_PID, instructions: SYSVAR_INSTRUCTIONS_PUBKEY, rent: SYSVAR_RENT_PUBKEY, - }, - }); + }) + .rpc(); const srmVaultAfter = await SRM_TOKEN_CLIENT.getAccountInfo(srmVault); const usdcVaultAfter = await USDC_TOKEN_CLIENT.getAccountInfo(usdcVault); @@ -467,8 +469,9 @@ describe("cfo", () => { const stakeBefore = await SRM_TOKEN_CLIENT.getAccountInfo(stake); const mintInfoBefore = await SRM_TOKEN_CLIENT.getMintInfo(); - await program.rpc.distribute({ - accounts: { + await program.methods + .distribute() + .accounts({ officer, treasury, stake, @@ -476,8 +479,8 @@ describe("cfo", () => { srmMint: ORDERBOOK_ENV.mintA, tokenProgram: TOKEN_PID, dexProgram: DEX_PID, - }, - }); + }) + .rpc(); const srmVaultAfter = await SRM_TOKEN_CLIENT.getAccountInfo(srmVault); const treasuryAfter = await SRM_TOKEN_CLIENT.getAccountInfo(treasury); diff --git a/tests/cfo/tests/utils/index.js b/tests/cfo/tests/utils/index.js index 3988262aa1..e2754fa86d 100644 --- a/tests/cfo/tests/utils/index.js +++ b/tests/cfo/tests/utils/index.js @@ -206,39 +206,43 @@ async function setupMarket({ ); for (let k = 0; k < asks.length; k += 1) { let ask = asks[k]; - const { transaction, signers } = - await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { - owner: marketMaker.account, - payer: marketMaker.baseToken, - side: "sell", - price: ask[0], - size: ask[1], - orderType: "postOnly", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { + transaction, + signers, + } = await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { + owner: marketMaker.account, + payer: marketMaker.baseToken, + side: "sell", + price: ask[0], + size: ask[1], + orderType: "postOnly", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); await provider.send(transaction, signers.concat(marketMaker.account)); } for (let k = 0; k < bids.length; k += 1) { let bid = bids[k]; - const { transaction, signers } = - await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { - owner: marketMaker.account, - payer: marketMaker.quoteToken, - side: "buy", - price: bid[0], - size: bid[1], - orderType: "postOnly", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { + transaction, + signers, + } = await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { + owner: marketMaker.account, + payer: marketMaker.quoteToken, + side: "buy", + price: bid[0], + size: bid[1], + orderType: "postOnly", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); await provider.send(transaction, signers.concat(marketMaker.account)); } @@ -513,38 +517,42 @@ async function runTradeBot(market, provider, iterations = undefined) { } // Post ask. - const { transaction: tx_ask, signers: sigs_ask } = - await marketClient.makePlaceOrderTransaction(provider.connection, { - owner: maker, - payer: baseToken, - side: "sell", - price, - size, - orderType: "postOnly", - clientId, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { + transaction: tx_ask, + signers: sigs_ask, + } = await marketClient.makePlaceOrderTransaction(provider.connection, { + owner: maker, + payer: baseToken, + side: "sell", + price, + size, + orderType: "postOnly", + clientId, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); let txSig = await provider.send(tx_ask, sigs_ask.concat(maker)); console.log("Ask", txSig); // Take. - const { transaction: tx_bid, signers: sigs_bid } = - await marketClient.makePlaceOrderTransaction(provider.connection, { - owner: taker, - payer: quoteToken, - side: "buy", - price, - size, - orderType: "ioc", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { + transaction: tx_bid, + signers: sigs_bid, + } = await marketClient.makePlaceOrderTransaction(provider.connection, { + owner: taker, + payer: quoteToken, + side: "buy", + price, + size, + orderType: "ioc", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); txSig = await provider.send(tx_bid, sigs_bid.concat(taker)); console.log("Bid", txSig); diff --git a/tests/cfo/tests/utils/stake.js b/tests/cfo/tests/utils/stake.js index 09054a13bd..35d6d8d22e 100644 --- a/tests/cfo/tests/utils/stake.js +++ b/tests/cfo/tests/utils/stake.js @@ -32,11 +32,13 @@ const WHITELIST_SIZE = 10; async function setupStakePool(mint, god) { // Registry genesis. - const [_registrarSigner, _nonce] = - await anchor.web3.PublicKey.findProgramAddress( - [registrar.publicKey.toBuffer()], - registry.programId - ); + const [ + _registrarSigner, + _nonce, + ] = await anchor.web3.PublicKey.findProgramAddress( + [registrar.publicKey.toBuffer()], + registry.programId + ); registrarSigner = _registrarSigner; nonce = _nonce; poolMint = await serumCmn.createMint(provider, registrarSigner); @@ -94,11 +96,13 @@ async function setupStakePool(mint, god) { seed, registry.programId ); - const [_memberSigner, nonce2] = - await anchor.web3.PublicKey.findProgramAddress( - [registrar.publicKey.toBuffer(), member.toBuffer()], - registry.programId - ); + const [ + _memberSigner, + nonce2, + ] = await anchor.web3.PublicKey.findProgramAddress( + [registrar.publicKey.toBuffer(), member.toBuffer()], + registry.programId + ); memberSigner = _memberSigner; const [mainTx, _balances] = await utils.createBalanceSandbox( provider, @@ -129,10 +133,9 @@ async function setupStakePool(mint, god) { newAccountPubkey: member, basePubkey: registry.provider.wallet.publicKey, seed, - lamports: - await registry.provider.connection.getMinimumBalanceForRentExemption( - registry.account.member.size - ), + lamports: await registry.provider.connection.getMinimumBalanceForRentExemption( + registry.account.member.size + ), space: registry.account.member.size, programId: registry.programId, }), diff --git a/ts/src/program/index.ts b/ts/src/program/index.ts index 6e6f06bc65..7971fa396a 100644 --- a/ts/src/program/index.ts +++ b/ts/src/program/index.ts @@ -10,6 +10,7 @@ import NamespaceFactory, { AccountNamespace, StateClient, SimulateNamespace, + MethodsNamespace, } from "./namespace/index.js"; import { utf8 } from "../utils/bytes/index.js"; import { EventManager } from "./event.js"; @@ -206,6 +207,12 @@ export class Program { */ readonly state?: StateClient; + /** + * The namespace provides a builder API for all APIs on the program. + * This is an alternative to using namespace the other namespaces.. + */ + readonly methods: MethodsNamespace; + /** * Address of the program. */ @@ -275,6 +282,7 @@ export class Program { transaction, account, simulate, + methods, state, ] = NamespaceFactory.build(idl, this._coder, programId, provider); this.rpc = rpc; @@ -282,6 +290,7 @@ export class Program { this.transaction = transaction; this.account = account; this.simulate = simulate; + this.methods = methods; this.state = state; } diff --git a/ts/src/program/namespace/index.ts b/ts/src/program/namespace/index.ts index 53b34100dc..365b3cf152 100644 --- a/ts/src/program/namespace/index.ts +++ b/ts/src/program/namespace/index.ts @@ -11,6 +11,7 @@ import AccountFactory, { AccountNamespace } from "./account.js"; import SimulateFactory, { SimulateNamespace } from "./simulate.js"; import { parseIdlErrors } from "../common.js"; import { AllInstructions } from "./types.js"; +import { MethodsBuilderFactory, MethodsNamespace } from "./methods"; // Re-exports. export { StateClient } from "./state.js"; @@ -20,6 +21,7 @@ export { RpcNamespace, RpcFn } from "./rpc.js"; export { AccountNamespace, AccountClient, ProgramAccount } from "./account.js"; export { SimulateNamespace, SimulateFn } from "./simulate.js"; export { IdlAccounts, IdlTypes } from "./types.js"; +export { MethodsBuilderFactory, MethodsNamespace } from "./methods"; export default class NamespaceFactory { /** @@ -36,12 +38,14 @@ export default class NamespaceFactory { TransactionNamespace, AccountNamespace, SimulateNamespace, + MethodsNamespace, StateClient | undefined ] { const rpc: RpcNamespace = {}; const instruction: InstructionNamespace = {}; const transaction: TransactionNamespace = {}; const simulate: SimulateNamespace = {}; + const methods: MethodsNamespace = {}; const idlErrors = parseIdlErrors(idl); @@ -64,6 +68,12 @@ export default class NamespaceFactory { programId, idl ); + const methodItem = MethodsBuilderFactory.build( + ixItem, + txItem, + rpcItem, + simulateItem + ); const name = camelCase(idlIx.name); @@ -71,6 +81,7 @@ export default class NamespaceFactory { transaction[name] = txItem; rpc[name] = rpcItem; simulate[name] = simulateItem; + methods[name] = methodItem; }); const account: AccountNamespace = idl.accounts @@ -83,6 +94,7 @@ export default class NamespaceFactory { transaction as TransactionNamespace, account, simulate as SimulateNamespace, + methods as MethodsNamespace, state, ]; } diff --git a/ts/src/program/namespace/methods.ts b/ts/src/program/namespace/methods.ts new file mode 100644 index 0000000000..7085ede395 --- /dev/null +++ b/ts/src/program/namespace/methods.ts @@ -0,0 +1,143 @@ +import { + ConfirmOptions, + AccountMeta, + Signer, + Transaction, + TransactionInstruction, + TransactionSignature, + PublicKey, +} from "@solana/web3.js"; +import { SimulateResponse } from "./simulate"; +import { TransactionFn } from "./transaction.js"; +import { Idl } from "../../idl.js"; +import { + AllInstructions, + InstructionContextFn, + MakeInstructionsNamespace, +} from "./types"; +import { InstructionFn } from "./instruction"; +import { RpcFn } from "./rpc"; +import { SimulateFn } from "./simulate"; + +export class MethodsBuilderFactory { + public static build>( + ixFn: InstructionFn, + txFn: TransactionFn, + rpcFn: RpcFn, + simulateFn: SimulateFn + ): MethodFn { + const request: MethodFn = (...args) => { + return new MethodsBuilder(args, ixFn, txFn, rpcFn, simulateFn); + }; + return request; + } +} + +export class MethodsBuilder> { + private _accounts: { [name: string]: PublicKey } = {}; + private _remainingAccounts: Array = []; + private _signers: Array = []; + private _preInstructions: Array = []; + private _postInstructions: Array = []; + + constructor( + private _args: Array, + private _ixFn: InstructionFn, + private _txFn: TransactionFn, + private _rpcFn: RpcFn, + private _simulateFn: SimulateFn + ) {} + + // TODO: don't use any. + public accounts(accounts: any): MethodsBuilder { + Object.assign(this._accounts, accounts); + return this; + } + + public remainingAccounts( + accounts: Array + ): MethodsBuilder { + this._remainingAccounts = this._remainingAccounts.concat(accounts); + return this; + } + + public preInstructions( + ixs: Array + ): MethodsBuilder { + this._preInstructions = this._preInstructions.concat(ixs); + return this; + } + + public postInstructions( + ixs: Array + ): MethodsBuilder { + this._postInstructions = this._postInstructions.concat(ixs); + return this; + } + + public async rpc(options: ConfirmOptions): Promise { + await this.resolvePdas(); + // @ts-ignore + return this._rpcFn(...this._args, { + accounts: this._accounts, + signers: this._signers, + remainingAccounts: this._remainingAccounts, + preInstructions: this._preInstructions, + postInstructions: this._postInstructions, + options: options, + }); + } + + public async simulate( + options: ConfirmOptions + ): Promise> { + await this.resolvePdas(); + // @ts-ignore + return this._simulateFn(...this._args, { + accounts: this._accounts, + signers: this._signers, + remainingAccounts: this._remainingAccounts, + preInstructions: this._preInstructions, + postInstructions: this._postInstructions, + options: options, + }); + } + + public async instruction(): Promise { + await this.resolvePdas(); + // @ts-ignore + return this._ixFn(...this._args, { + accounts: this._accounts, + signers: this._signers, + remainingAccounts: this._remainingAccounts, + preInstructions: this._preInstructions, + postInstructions: this._postInstructions, + }); + } + + public async transaction(): Promise { + await this.resolvePdas(); + // @ts-ignore + return this._txFn(...this._args, { + accounts: this._accounts, + signers: this._signers, + remainingAccounts: this._remainingAccounts, + preInstructions: this._preInstructions, + postInstructions: this._postInstructions, + }); + } + + private async resolvePdas() { + // TODO: resolve all PDAs and accounts not provided. + } +} + +export type MethodsNamespace< + IDL extends Idl = Idl, + I extends AllInstructions = AllInstructions +> = MakeInstructionsNamespace; // TODO: don't use any. + +export type MethodFn< + IDL extends Idl = Idl, + I extends AllInstructions = AllInstructions +> = InstructionContextFn>; diff --git a/ts/src/program/namespace/simulate.ts b/ts/src/program/namespace/simulate.ts index e15dfd985d..96408b9595 100644 --- a/ts/src/program/namespace/simulate.ts +++ b/ts/src/program/namespace/simulate.ts @@ -134,7 +134,7 @@ export type SimulateFn< Promise, IdlTypes>> >; -type SimulateResponse = { +export type SimulateResponse = { events: readonly Event[]; raw: readonly string[]; }; From 8f278c617977231c4a76468d016a3c102327cb45 Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Sat, 15 Jan 2022 16:26:40 -0500 Subject: [PATCH 2/4] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d66ef8708..070c67392b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ incremented for features. * lang: Add `seeds::program` constraint for specifying which program_id to use when deriving PDAs.([#1197](https://github.com/project-serum/anchor/pull/1197)) * ts: Remove error logging in the event parser when log websocket encounters a program error. ([#1313](https://github.com/project-serum/anchor/pull/1313)) +* ts: Add new `methods` namespace to the program client, introducing a more ergonomic builder API ([#1324](https://github.com/project-serum/anchor/pull/1324)). ### Breaking From 35bd79be04637492dfd42121093490176ebce982 Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Sat, 15 Jan 2022 16:36:43 -0500 Subject: [PATCH 3/4] Satisfy clippy --- cli/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 05d3e6fc00..d0c048ee19 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -1021,7 +1021,7 @@ fn docker_build_bpf( println!( "Building {} manifest: {:?}", binary_name, - manifest_path.display().to_string() + manifest_path.display() ); // Execute the build. From 9c88dac1eae426f9ee98a326c78ce8d9e7e9747c Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Sat, 15 Jan 2022 16:45:07 -0500 Subject: [PATCH 4/4] Run litner on tests --- tests/cfo/tests/utils/index.js | 120 +++++++++++++++------------------ tests/cfo/tests/utils/stake.js | 31 ++++----- 2 files changed, 70 insertions(+), 81 deletions(-) diff --git a/tests/cfo/tests/utils/index.js b/tests/cfo/tests/utils/index.js index e2754fa86d..3988262aa1 100644 --- a/tests/cfo/tests/utils/index.js +++ b/tests/cfo/tests/utils/index.js @@ -206,43 +206,39 @@ async function setupMarket({ ); for (let k = 0; k < asks.length; k += 1) { let ask = asks[k]; - const { - transaction, - signers, - } = await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { - owner: marketMaker.account, - payer: marketMaker.baseToken, - side: "sell", - price: ask[0], - size: ask[1], - orderType: "postOnly", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { transaction, signers } = + await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { + owner: marketMaker.account, + payer: marketMaker.baseToken, + side: "sell", + price: ask[0], + size: ask[1], + orderType: "postOnly", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); await provider.send(transaction, signers.concat(marketMaker.account)); } for (let k = 0; k < bids.length; k += 1) { let bid = bids[k]; - const { - transaction, - signers, - } = await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { - owner: marketMaker.account, - payer: marketMaker.quoteToken, - side: "buy", - price: bid[0], - size: bid[1], - orderType: "postOnly", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { transaction, signers } = + await MARKET_A_USDC.makePlaceOrderTransaction(provider.connection, { + owner: marketMaker.account, + payer: marketMaker.quoteToken, + side: "buy", + price: bid[0], + size: bid[1], + orderType: "postOnly", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); await provider.send(transaction, signers.concat(marketMaker.account)); } @@ -517,42 +513,38 @@ async function runTradeBot(market, provider, iterations = undefined) { } // Post ask. - const { - transaction: tx_ask, - signers: sigs_ask, - } = await marketClient.makePlaceOrderTransaction(provider.connection, { - owner: maker, - payer: baseToken, - side: "sell", - price, - size, - orderType: "postOnly", - clientId, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { transaction: tx_ask, signers: sigs_ask } = + await marketClient.makePlaceOrderTransaction(provider.connection, { + owner: maker, + payer: baseToken, + side: "sell", + price, + size, + orderType: "postOnly", + clientId, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); let txSig = await provider.send(tx_ask, sigs_ask.concat(maker)); console.log("Ask", txSig); // Take. - const { - transaction: tx_bid, - signers: sigs_bid, - } = await marketClient.makePlaceOrderTransaction(provider.connection, { - owner: taker, - payer: quoteToken, - side: "buy", - price, - size, - orderType: "ioc", - clientId: undefined, - openOrdersAddressKey: undefined, - openOrdersAccount: undefined, - feeDiscountPubkey: null, - selfTradeBehavior: "abortTransaction", - }); + const { transaction: tx_bid, signers: sigs_bid } = + await marketClient.makePlaceOrderTransaction(provider.connection, { + owner: taker, + payer: quoteToken, + side: "buy", + price, + size, + orderType: "ioc", + clientId: undefined, + openOrdersAddressKey: undefined, + openOrdersAccount: undefined, + feeDiscountPubkey: null, + selfTradeBehavior: "abortTransaction", + }); txSig = await provider.send(tx_bid, sigs_bid.concat(taker)); console.log("Bid", txSig); diff --git a/tests/cfo/tests/utils/stake.js b/tests/cfo/tests/utils/stake.js index 35d6d8d22e..09054a13bd 100644 --- a/tests/cfo/tests/utils/stake.js +++ b/tests/cfo/tests/utils/stake.js @@ -32,13 +32,11 @@ const WHITELIST_SIZE = 10; async function setupStakePool(mint, god) { // Registry genesis. - const [ - _registrarSigner, - _nonce, - ] = await anchor.web3.PublicKey.findProgramAddress( - [registrar.publicKey.toBuffer()], - registry.programId - ); + const [_registrarSigner, _nonce] = + await anchor.web3.PublicKey.findProgramAddress( + [registrar.publicKey.toBuffer()], + registry.programId + ); registrarSigner = _registrarSigner; nonce = _nonce; poolMint = await serumCmn.createMint(provider, registrarSigner); @@ -96,13 +94,11 @@ async function setupStakePool(mint, god) { seed, registry.programId ); - const [ - _memberSigner, - nonce2, - ] = await anchor.web3.PublicKey.findProgramAddress( - [registrar.publicKey.toBuffer(), member.toBuffer()], - registry.programId - ); + const [_memberSigner, nonce2] = + await anchor.web3.PublicKey.findProgramAddress( + [registrar.publicKey.toBuffer(), member.toBuffer()], + registry.programId + ); memberSigner = _memberSigner; const [mainTx, _balances] = await utils.createBalanceSandbox( provider, @@ -133,9 +129,10 @@ async function setupStakePool(mint, god) { newAccountPubkey: member, basePubkey: registry.provider.wallet.publicKey, seed, - lamports: await registry.provider.connection.getMinimumBalanceForRentExemption( - registry.account.member.size - ), + lamports: + await registry.provider.connection.getMinimumBalanceForRentExemption( + registry.account.member.size + ), space: registry.account.member.size, programId: registry.programId, }),