Skip to content

Commit

Permalink
ts: builder api (#1324)
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante committed Jan 15, 2022
1 parent 1f95929 commit e121e4e
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 57 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion cli/src/lib.rs
Expand Up @@ -1021,7 +1021,7 @@ fn docker_build_bpf(
println!(
"Building {} manifest: {:?}",
binary_name,
manifest_path.display().to_string()
manifest_path.display()
);

// Execute the build.
Expand Down
113 changes: 58 additions & 55 deletions tests/cfo/tests/cfo.js
Expand Up @@ -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(
Expand All @@ -260,34 +255,36 @@ 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,
payer: program.provider.wallet.publicKey,
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,
dexProgram: DEX_PID,
systemProgram: SystemProgram.programId,
rent: SYSVAR_RENT_PUBKEY,
market: ORDERBOOK_ENV.marketA.address,
},
});
})
.rpc();
await program.rpc.createOfficerOpenOrders(openOrdersBumpB, {
accounts: {
officer,
Expand All @@ -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,
Expand All @@ -323,8 +321,8 @@ describe("cfo", () => {
dexProgram: DEX_PID,
tokenProgram: TOKEN_PID,
},
},
});
})
.rpc();
const afterTokenAccount = await serumCmn.getTokenAccount(
program.provider,
sweepVault
Expand All @@ -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 () => {
Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -467,17 +469,18 @@ 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,
srmVault,
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);
Expand Down
9 changes: 9 additions & 0 deletions ts/src/program/index.ts
Expand Up @@ -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";
Expand Down Expand Up @@ -206,6 +207,12 @@ export class Program<IDL extends Idl = Idl> {
*/
readonly state?: StateClient<IDL>;

/**
* 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<IDL>;

/**
* Address of the program.
*/
Expand Down Expand Up @@ -275,13 +282,15 @@ export class Program<IDL extends Idl = Idl> {
transaction,
account,
simulate,
methods,
state,
] = NamespaceFactory.build(idl, this._coder, programId, provider);
this.rpc = rpc;
this.instruction = instruction;
this.transaction = transaction;
this.account = account;
this.simulate = simulate;
this.methods = methods;
this.state = state;
}

Expand Down
12 changes: 12 additions & 0 deletions ts/src/program/namespace/index.ts
Expand Up @@ -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";
Expand All @@ -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 {
/**
Expand All @@ -36,12 +38,14 @@ export default class NamespaceFactory {
TransactionNamespace<IDL>,
AccountNamespace<IDL>,
SimulateNamespace<IDL>,
MethodsNamespace<IDL>,
StateClient<IDL> | undefined
] {
const rpc: RpcNamespace = {};
const instruction: InstructionNamespace = {};
const transaction: TransactionNamespace = {};
const simulate: SimulateNamespace = {};
const methods: MethodsNamespace = {};

const idlErrors = parseIdlErrors(idl);

Expand All @@ -64,13 +68,20 @@ export default class NamespaceFactory {
programId,
idl
);
const methodItem = MethodsBuilderFactory.build(
ixItem,
txItem,
rpcItem,
simulateItem
);

const name = camelCase(idlIx.name);

instruction[name] = ixItem;
transaction[name] = txItem;
rpc[name] = rpcItem;
simulate[name] = simulateItem;
methods[name] = methodItem;
});

const account: AccountNamespace<IDL> = idl.accounts
Expand All @@ -83,6 +94,7 @@ export default class NamespaceFactory {
transaction as TransactionNamespace<IDL>,
account,
simulate as SimulateNamespace<IDL>,
methods as MethodsNamespace<IDL>,
state,
];
}
Expand Down

0 comments on commit e121e4e

Please sign in to comment.