Documentation and tutorials init

This commit is contained in:
armaniferrante 2021-01-02 16:24:35 -08:00
parent c2d2041759
commit 322c9bb548
No known key found for this signature in database
GPG Key ID: 58BEF301E91F7828
36 changed files with 8505 additions and 104 deletions

12
Cargo.lock generated
View File

@ -103,7 +103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "basic-program"
name = "basic-program-0"
version = "0.1.0"
dependencies = [
"anchor",
@ -260,6 +260,16 @@ dependencies = [
"syn",
]
[[package]]
name = "constraints-program"
version = "0.1.0"
dependencies = [
"anchor",
"borsh",
"solana-program",
"solana-sdk",
]
[[package]]
name = "crypto-mac"
version = "0.7.0"

View File

@ -25,4 +25,5 @@ members = [
"attributes/*",
"derive",
"examples/basic",
"examples/tutorial/basic-0/program",
]

12
docs/.gitignore vendored Executable file
View File

@ -0,0 +1,12 @@
pids
logs
node_modules
npm-debug.log
coverage/
run
dist
.DS_Store
.nyc_output
.basement
config.local.js
basement_dist

19
docs/package.json Executable file
View File

@ -0,0 +1,19 @@
{
"name": "anchor",
"version": "0.0.1",
"description": "",
"main": "index.js",
"authors": {
"name": "",
"email": ""
},
"repository": "/anchor",
"scripts": {
"dev": "vuepress dev src",
"build": "vuepress build src"
},
"license": "MIT",
"devDependencies": {
"vuepress": "^1.5.3"
}
}

View File

@ -0,0 +1,15 @@
<template>
<p class="demo">
{{ msg }}
</p>
</template>
<script>
export default {
data () {
return {
msg: 'Hello this is <Foo-Bar>'
}
}
}
</script>

View File

@ -0,0 +1,3 @@
<template>
<p class="demo">This is another component</p>
</template>

View File

@ -0,0 +1,15 @@
<template>
<p class="demo">
{{ msg }}
</p>
</template>
<script>
export default {
data() {
return {
msg: 'Hello this is <demo-component>'
}
}
}
</script>

58
docs/src/.vuepress/config.js Executable file
View File

@ -0,0 +1,58 @@
const { description } = require('../../package')
module.exports = {
/**
* Refhttps://v1.vuepress.vuejs.org/config/#title
*/
title: 'Anchor',
/**
* Refhttps://v1.vuepress.vuejs.org/config/#description
*/
description: description,
/**
* Extra tags to be injected to the page HTML `<head>`
*
* refhttps://v1.vuepress.vuejs.org/config/#head
*/
head: [
['meta', { name: 'theme-color', content: '#3eaf7c' }],
['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }]
],
/**
* Theme configuration, here is the default theme configuration for VuePress.
*
* refhttps://v1.vuepress.vuejs.org/theme/default-theme-config.html
*/
themeConfig: {
repo: '',
editLinks: false,
docsDir: '',
editLinkText: '',
lastUpdated: false,
sidebar: {
'/guide/': [
{
title: 'Getting Started',
collapsable: false,
children: [
'',
'prerequisites',
'tutorial-0',
'tutorial-1',
]
}
],
}
},
/**
* Apply pluginsrefhttps://v1.vuepress.vuejs.org/zh/plugin/
*/
plugins: [
'@vuepress/plugin-back-to-top',
'@vuepress/plugin-medium-zoom',
]
}

View File

@ -0,0 +1,14 @@
/**
* Client app enhancement file.
*
* https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements
*/
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
// ...apply enhancements for the site.
}

View File

@ -0,0 +1,8 @@
/**
* Custom Styles here.
*
* refhttps://v1.vuepress.vuejs.org/config/#index-styl
*/
.home .hero img
max-width 450px!important

View File

@ -0,0 +1,10 @@
/**
* Custom palette here.
*
* refhttps://v1.vuepress.vuejs.org/zh/config/#palette-styl
*/
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34

15
docs/src/config/README.md Executable file
View File

@ -0,0 +1,15 @@
---
sidebar: auto
---
# Config
## foo
- Type: `string`
- Default: `/`
## bar
- Type: `string`
- Default: `/`

21
docs/src/guide/README.md Executable file
View File

@ -0,0 +1,21 @@
# Introduction
Anchor is a framework for Solana's [Sealevel](https://medium.com/solana-labs/sealevel-parallel-processing-thousands-of-smart-contracts-d814b378192) runtime, exposing a safer and more convenient programming model to the Solana developer by providing a
* Rust Crate for writing Solana programs
* CLI for extracting an [IDL](https://en.wikipedia.org/wiki/Interface_description_language) from source
* TypeScript package for generating clients from IDL
If you're familiar with developing in Ethereum's [Solidity](https://docs.soliditylang.org/en/v0.7.4/) and [web3.js](https://github.com/ethereum/web3.js) or Parity's [Ink!](https://github.com/paritytech/ink), then the experience will be familiar. Although the DSL syntax and semantics are targeted at Solana, the high level flow of writing RPC request handlers, emitting an IDL, and generating clients from IDL is the same.
Here, we'll walkthrough a tutorial demonstrating how to use Anchor. To skip the tutorial and jump straight to a full example, go [here](https://github.com/armaniferrante/anchor/tree/master/examples/basic).
## Contributing
It would be great to have clients generated for languages other than TypeScript. If you're
interested in developing a client generator, feel free to reach out, or go ahead and just
do it :P.
## Note
Anchor is in active development, so all APIs are subject to change. If you have feedback, please reach out by [filing an issue](https://github.com/armaniferrante/anchor/issues/new). This documentation is a work in progress and is expected to change dramatically as features continue to be built out. If you have any problems, consult the [source](https://github.com/armaniferrante/anchor) or feel free to ask questions on the [Serum Discord](https://discord.com/channels/739225212658122886/752530209848295555).

View File

@ -0,0 +1,32 @@
# Prerequisites
Before getting started, make sure to setup all the prerequisite tools on your local machine.
## Install Rust
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustup component add rustfmt
```
For an introduction to Rust, see the excellent Rust [book](https://doc.rust-lang.org/book/).
## Install Anchor
For now, we can use Cargo.
```bash
cargo install --git https://github.com/project-serum/anchor anchor-cli
```
## Install Solana
```bash
curl -sSf https://raw.githubusercontent.com/solana-labs/solana/v1.4.14/install/solana-install-init.sh | sh -s - v1.4.14
export PATH="/home/ubuntu/.local/share/solana/install/active_release/bin:$PATH"
```
## Setup a Localnet
The easiest way to run a local cluster is to run the docker container provided by Solana. Instructions can be found [here](https://solana-labs.github.io/solana-web3.js/). (Note: `solana-test-validator` is the new, preferred way to run a local validator, though I haven't tested it yet).

View File

@ -0,0 +1,108 @@
# Tutorial 0: A Minimal Example
Here, we introduce a minimal example demonstrating the Anchor workflow and core syntax
elements. This tutorial assumes all [prerequisites](./prerequisites.md) are installed and
a local network is running.
## Clone the repo
To get started, clone the repo.
```bash
git clone https://github.com/armaniferrante/anchor
```
And change directories to the [example](https://github.com/armaniferrante/anchor/tree/master/examples/basic-0).
```bash
cd anchor/examples/tutorial/basic-0
```
## Defining a program
We define the minimum viable program as follows.
<<< @/../examples/tutorial/basic-0/program/src/lib.rs
There are a couple of syntax elements to point out here.
### `#[program]`
First, notice that a program is defined with the `#[program]` attribute, where each
inner method defines an RPC request handler, or, in Solana parlance, an "instruction"
handler. These handlers are the entrypoints to your program that clients may invoke, as
we will see soon.
### `Context<Initialize>`
The first parameter of *every* RPC handler is the `Context` struct, which is a simple
container for the currently executing `program_id` generic over
`Accounts`--here, the `Initialize` struct.
### `#[derive(Accounts)]`
The `Accounts` derive macro marks a struct containing all the accounts that must be
specified for a given instruction. To understand Accounts on Solana, see the
[docs](https://docs.solana.com/developing/programming-model/accounts).
In subsequent tutorials, we'll demonstrate how an `Accounts` struct can be used to
specify constraints on accounts given to your program. Since this example doesn't touch any
accounts, we skip this (important) detail.
## Building a program
This program can be built in same way as any other Solana program.
```bash
cargo build-bpf
```
## Deploying a program
Similarly, we can deploy the program using the `solana deploy` command.
```bash
solana deploy <path-to-your-repo>/anchor/target/deploy/basic_program_0.so
```
Making sure to susbstitute paths to match your local filesystem. Now, save the address
the program was deployed with. It will be useful later.
## Emmiting an IDL
After creating a program, one can use the Anchor CLI to emit an IDL, from which clients
can be generated.
```bash
anchor idl -f src/lib.rs -o idl.js
```
Inspecting the contents of `idl.js` one should see
```json
{
"version": "0.0.0",
"name": "basic",
"instructions": [
{
"name": "initialize",
"accounts": [],
"args": []
}
]
}
```
For experienced Ethereum developers, this is analogous to an `abi.json` file.
## Generating a Client
Now that we have an IDL, we can use it to create a client.
<<< @/../examples/tutorial/basic-0/app/client.js#main
Notice how the program dynamically created the `initialize` method under
the `rpc` namespace.
## Next Steps
So far we've seen the basics of how to create, deploy, and make RPCs to a program on Solana
using Anchor. But a program isn't all that interesting without interacting with it's
peristent state, which is what we'll cover next.

View File

@ -0,0 +1,16 @@
# Tutorial 1: Accounts, Arguments, and Types
It's recommended to read [Tutorial 0](./tutorial-0.md) first, as this tutorial will
build on top of it. The full example can be found [here](https://github.com/armaniferrante/anchor/tree/master/examples/basic-1).
## Defining a program
We define our program as follows
<<< @/../examples/tutorial/basic-1/program/src/lib.rs#program
Some new syntax elements are introduced here.
First notice, the `data` argument passed into the program. This argument any other valid
Rust types can be passed to the instruction to define inputs to the program. Additionally,
notice how we take a `mutable` reference to `my_account` and assign to it.

15
docs/src/index.md Executable file
View File

@ -0,0 +1,15 @@
---
home: true
heroImage: https://v1.vuepress.vuejs.org/hero.png
tagline:
actionText: Quick Start →
actionLink: /guide/
features:
- title: Feature 1 Title
details: Feature 1 Description
- title: Feature 2 Title
details: Feature 2 Description
- title: Feature 3 Title
details: Feature 3 Description
footer: Made by with ❤️
---

7875
docs/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

7
examples/Makefile Normal file
View File

@ -0,0 +1,7 @@
.PHONY: examples
ANCHOR=$(PWD)/../target/debug/anchor
examples:
cd tutorial/basic-0/program && cargo build-bpf && $(ANCHOR) idl -f src/lib.rs -o ../idl.json
cd basic && cargo build-bpf && $(ANCHOR) idl -f src/lib.rs -o idl.json

View File

@ -1,12 +1,12 @@
[package]
name = "basic-program"
name = "constraints-program"
version = "0.1.0"
description = "Basic example"
description = "An example illustrating anchor constraints"
edition = "2018"
[lib]
crate-type = ["cdylib"]
name = "basic_program"
name = "cosntraints_program"
[dependencies]
borsh = { git = "https://github.com/project-serum/borsh", branch = "serum", features = ["serum-program"] }

View File

@ -3,7 +3,7 @@
"name": "example",
"instructions": [
{
"name": "create_root",
"name": "createRoot",
"accounts": [
{
"name": "root",
@ -23,7 +23,7 @@
]
},
{
"name": "update_root",
"name": "updateRoot",
"accounts": [
{
"name": "authority",
@ -44,7 +44,7 @@
]
},
{
"name": "create_leaf",
"name": "createLeaf",
"accounts": [
{
"name": "root",
@ -71,7 +71,7 @@
]
},
{
"name": "update_leaf",
"name": "updateLeaf",
"accounts": [
{
"name": "authority",
@ -160,7 +160,7 @@
"kind": "struct",
"fields": [
{
"name": "my_data",
"name": "myData",
"type": "u64"
},
{

View File

@ -4,6 +4,7 @@ use anchor::prelude::*;
// Define the program's RPC handlers.
// #region program
#[program]
mod example {
use super::*;
@ -45,6 +46,7 @@ mod example {
Ok(())
}
}
// #endregion program
// Define the validated accounts for each handler.

View File

@ -1,18 +0,0 @@
/*
use solana_client_gen::solana_client_gen;
#[solana_client_gen]
mod instruction {
pub enum Example {
CreateRoot,
}
}
#[test]
fn example() {
let (client, genesis) = serum_common_tests::genesis::<client::Client>();
let accs = vec![];
client.initialize(&accs);
}
*/

View File

@ -0,0 +1,27 @@
// TODO: replace path once the package is published.
//
// Before running this script, make sure to run `yarn && yarn build` inside
// the `ts` directory.
const anchor = require('../../../../ts');
const fs = require('fs');
// Configure the local cluster.
anchor.setProvider(anchor.Provider.local());
// #region main
async function main() {
// Read the generated IDL.
const idl = JSON.parse(fs.readFileSync('../idl.json', 'utf8'));
// Address of the deployed program.
const programId = new anchor.web3.PublicKey('<YOUR-PROGRAM-ID>');
// Generate the program client from IDL.
const program = new anchor.Program(idl, programId);
// Execute the RPC.
await program.rpc.initialize();
}
// #endregion main
main();

View File

@ -0,0 +1,11 @@
{
"version": "0.0.0",
"name": "basic",
"instructions": [
{
"name": "initialize",
"accounts": [],
"args": []
}
]
}

View File

@ -0,0 +1,15 @@
[package]
name = "basic-program-0"
version = "0.1.0"
description = "A minimal example of an anchor program"
edition = "2018"
[lib]
crate-type = ["cdylib"]
name = "basic_program_0"
[dependencies]
borsh = { git = "https://github.com/project-serum/borsh", branch = "serum", features = ["serum-program"] }
solana-program = "1.4.3"
solana-sdk = { version = "1.3.14", default-features = false, features = ["program"] }
anchor = { path = "../../../../", features = ["derive"] }

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -0,0 +1,14 @@
#![feature(proc_macro_hygiene)]
use anchor::prelude::*;
#[program]
mod basic {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}

View File

@ -0,0 +1,36 @@
{
"version": "0.0.0",
"name": "basic_0",
"instructions": [
{
"name": "initialize",
"accounts": [
{
"name": "myAccount",
"isMut": true,
"isSigner": false
}
],
"args": [
{
"name": "data",
"type": "u64"
}
]
}
],
"accounts": [
{
"name": "MyAccount",
"type": {
"kind": "struct",
"fields": [
{
"name": "data",
"type": "u64"
}
]
}
}
]
}

View File

@ -0,0 +1,15 @@
[package]
name = "basic-program-0"
version = "0.1.0"
description = "A minimal example of an anchor program"
edition = "2018"
[lib]
crate-type = ["cdylib"]
name = "basic_program_0"
[dependencies]
borsh = { git = "https://github.com/project-serum/borsh", branch = "serum", features = ["serum-program"] }
solana-program = "1.4.3"
solana-sdk = { version = "1.3.14", default-features = false, features = ["program"] }
anchor = { path = "../../../", features = ["derive"] }

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -0,0 +1,25 @@
#![feature(proc_macro_hygiene)]
use anchor::prelude::*;
#[program]
mod basic {
use super::*;
pub fn initialize(ctx: Context<Initialize>, data: u64) -> ProgramResult {
let my_account = &mut ctx.accounts.my_account;
my_account.data = data;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub my_account: ProgramAccount<'info, MyAccount>,
}
#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct MyAccount {
pub data: u64,
}

View File

@ -60,10 +60,20 @@ pub fn generate(accs: AccountsStruct) -> proc_macro2::TokenStream {
.collect();
let name = &accs.ident;
let generics = &accs.generics;
let (combined_generics, trait_generics, strct_generics) = match accs.generics.lt_token {
None => (
quote!{<'info>},
quote!{<'info>},
quote!{},
),
Some(_) => {
let g = &accs.generics;
(quote!{#g}, quote!{#g}, quote!{#g})
}
};
quote! {
impl#generics Accounts#generics for #name#generics {
impl#combined_generics Accounts#trait_generics for #name#strct_generics {
fn try_anchor(program_id: &Pubkey, accounts: &[AccountInfo<'info>]) -> Result<Self, ProgramError> {
let acc_infos = &mut accounts.iter();
@ -77,7 +87,7 @@ pub fn generate(accs: AccountsStruct) -> proc_macro2::TokenStream {
}
}
impl#generics #name#generics {
impl#strct_generics #name#strct_generics {
pub fn exit(&self) -> ProgramResult {
#(#on_save)*
Ok(())

View File

@ -7,6 +7,8 @@ use quote::ToTokens;
use std::collections::{HashMap, HashSet};
use std::fs::File;
use std::io::Read;
use heck::MixedCase;
use heck::CamelCase;
static DERIVE_NAME: &'static str = "Accounts";
@ -47,7 +49,7 @@ pub fn parse(filename: &str) -> Result<Idl> {
arg.raw_arg.ty.to_tokens(&mut tts);
let ty = tts.to_string().parse().unwrap();
IdlField {
name: arg.name.to_string(),
name: arg.name.to_string().to_mixed_case(),
ty,
}
})
@ -58,13 +60,13 @@ pub fn parse(filename: &str) -> Result<Idl> {
.fields
.iter()
.map(|acc| IdlAccount {
name: acc.ident.to_string(),
name: acc.ident.to_string().to_mixed_case(),
is_mut: acc.is_mut,
is_signer: acc.is_signer,
})
.collect::<Vec<_>>();
IdlInstruction {
name: rpc.ident.to_string(),
name: rpc.ident.to_string().to_mixed_case(),
accounts,
args,
}
@ -162,7 +164,12 @@ fn parse_ty_defs(f: &syn::File) -> Result<Vec<IdlTypeDef>> {
let mut tts = proc_macro2::TokenStream::new();
f.ty.to_tokens(&mut tts);
Ok(IdlField {
name: f.ident.as_ref().unwrap().to_string(),
name: f
.ident
.as_ref()
.unwrap()
.to_string()
.to_mixed_case(),
ty: tts.to_string().parse()?,
})
})

View File

@ -60,7 +60,7 @@ type RpcOptions = ConfirmOptions;
*/
type RpcContext = {
// Accounts the instruction will use.
accounts: RpcAccounts;
accounts?: RpcAccounts;
// Instructions to run *before* the specified rpc instruction.
instructions?: TransactionInstruction[];
// Accounts that must sign the transaction.
@ -105,22 +105,24 @@ export class RpcFactory {
ixFns[name] = ix;
});
idl.accounts.forEach((idlAccount) => {
// todo
const accountFn = async (address: PublicKey): Promise<any> => {
const provider = getProvider();
if (provider === null) {
throw new Error("Provider not set");
}
const accountInfo = await provider.connection.getAccountInfo(address);
if (accountInfo === null) {
throw new Error(`Entity does not exist ${address}`);
}
return coder.accounts.decode(idlAccount.name, accountInfo.data);
};
const name = camelCase(idlAccount.name);
accountFns[name] = accountFn;
});
if (idl.accounts) {
idl.accounts.forEach((idlAccount) => {
// todo
const accountFn = async (address: PublicKey): Promise<any> => {
const provider = getProvider();
if (provider === null) {
throw new Error("Provider not set");
}
const accountInfo = await provider.connection.getAccountInfo(address);
if (accountInfo === null) {
throw new Error(`Entity does not exist ${address}`);
}
return coder.accounts.decode(idlAccount.name, accountInfo.data);
};
const name = camelCase(idlAccount.name);
accountFns[name] = accountFn;
});
}
return [rpcs, ixFns, accountFns];
}
@ -181,7 +183,7 @@ function splitArgsAndCtx(
idlIx: IdlInstruction,
args: any[]
): [any[], RpcContext] {
let options = undefined;
let options = {};
const inputLen = idlIx.args ? idlIx.args.length : 0;
if (args.length > inputLen) {

View File

@ -1,16 +1,16 @@
const assert = require('assert');
const anchor = require('.');
import * as assert from 'assert';
import * as anchor from '../../';
import { readFileSync } from 'fs';
// Global workspace settings.
const WORKSPACE = {
idl: JSON.parse(require('fs').readFileSync('../examples/basic/idl.json', 'utf8')),
idl: JSON.parse(readFileSync('../examples/basic/idl.json', 'utf8')),
programId: new anchor.web3.PublicKey('CrQZpSbUnkXxwf1FnepmefoZ7VsbYE6HXmG1TjChH6y'),
provider: anchor.Provider.local(),
};
async function test() {
console.log('Starting test.');
describe('Constraints program tests', () => {
it('Runs against a localnetwork', async () => {
// Configure the local cluster.
anchor.setProvider(WORKSPACE.provider);
@ -31,19 +31,19 @@ async function test() {
// 3) Accounts for the program's instruction. Ordering does *not* matter,
// only that they names are as specified in the IDL.
await program.rpc.createRoot(WORKSPACE.provider.wallet.publicKey, new anchor.BN(1234), {
accounts: {
root: root.publicKey,
},
signers: [root],
instructions: [
anchor.web3.SystemProgram.createAccount({
fromPubkey: WORKSPACE.provider.wallet.publicKey,
newAccountPubkey: root.publicKey,
space: 41,
lamports: await WORKSPACE.provider.connection.getMinimumBalanceForRentExemption(41),
programId: WORKSPACE.programId,
}),
],
accounts: {
root: root.publicKey,
},
signers: [root],
instructions: [
anchor.web3.SystemProgram.createAccount({
fromPubkey: WORKSPACE.provider.wallet.publicKey,
newAccountPubkey: root.publicKey,
space: 41,
lamports: await WORKSPACE.provider.connection.getMinimumBalanceForRentExemption(41),
programId: WORKSPACE.programId,
}),
],
});
// Read the newly created account data.
@ -54,10 +54,10 @@ async function test() {
// Execute another RPC to update the data.
await program.rpc.updateRoot(new anchor.BN(999), {
accounts: {
root: root.publicKey,
authority: WORKSPACE.provider.wallet.publicKey,
},
accounts: {
root: root.publicKey,
authority: WORKSPACE.provider.wallet.publicKey,
},
});
// Check the update actually persisted.
@ -68,20 +68,20 @@ async function test() {
const leaf = new anchor.web3.Account();
let customType = { myData: new anchor.BN(4), key: WORKSPACE.programId };
await program.rpc.createLeaf(new anchor.BN(2), customType, {
accounts: {
root: root.publicKey,
leaf: leaf.publicKey,
},
signers: [leaf],
instructions: [
anchor.web3.SystemProgram.createAccount({
fromPubkey: WORKSPACE.provider.wallet.publicKey,
newAccountPubkey: leaf.publicKey,
space: 100,
lamports: await WORKSPACE.provider.connection.getMinimumBalanceForRentExemption(100),
programId: WORKSPACE.programId,
}),
],
accounts: {
root: root.publicKey,
leaf: leaf.publicKey,
},
signers: [leaf],
instructions: [
anchor.web3.SystemProgram.createAccount({
fromPubkey: WORKSPACE.provider.wallet.publicKey,
newAccountPubkey: leaf.publicKey,
space: 100,
lamports: await WORKSPACE.provider.connection.getMinimumBalanceForRentExemption(100),
programId: WORKSPACE.programId,
}),
],
});
// Check the account was initialized.
@ -94,11 +94,11 @@ async function test() {
// Update the account.
await program.rpc.updateLeaf(new anchor.BN(5), null, {
accounts: {
authority: WORKSPACE.provider.wallet.publicKey,
root: root.publicKey,
leaf: leaf.publicKey,
},
accounts: {
authority: WORKSPACE.provider.wallet.publicKey,
root: root.publicKey,
leaf: leaf.publicKey,
},
});
// Check it was updated.
@ -108,11 +108,11 @@ async function test() {
// Now update with the option.
customType = { myData: new anchor.BN(7), key: WORKSPACE.programId };
await program.rpc.updateLeaf(new anchor.BN(6), customType, {
accounts: {
authority: WORKSPACE.provider.wallet.publicKey,
root: root.publicKey,
leaf: leaf.publicKey,
},
accounts: {
authority: WORKSPACE.provider.wallet.publicKey,
root: root.publicKey,
leaf: leaf.publicKey,
},
});
// Check it was updated.
@ -120,8 +120,5 @@ async function test() {
assert.ok(account.data.eq(new anchor.BN(6)));
assert.ok(account.custom.myData.eq(new anchor.BN(7)));
assert.ok(account.custom.key.equals(WORKSPACE.programId));
console.log('Test complete.');
}
test();
});
});