ts: Remove SPL coders from Anchor package (#2155)
* ts: Remove SPL coders from Anchor package * Replace old SPL custom coder tests * Build and link new SPL packages before tests and decode token account for AccountStore * Fix Github actions ts setup * Fix u64 buffer length * Update submodules * Update CHANGELOG * Checkout correct submodule commits * Add filler program to generate idls in order for anchor test to pass
This commit is contained in:
parent
5c474c6dfb
commit
af115999c6
|
@ -22,8 +22,11 @@ runs:
|
|||
key: solana-${{ runner.os }}-v0000-${{ env.NODE_VERSION }}-${{ hashFiles('./ts/**/*.ts') }}
|
||||
- run: cd ts/packages/anchor && yarn --frozen-lockfile && yarn build:node && yarn link && cd ../../../
|
||||
shell: bash
|
||||
- run: cd ts/packages/spl-associated-token-account && yarn --frozen-lockfile && yarn build:node && yarn link && cd ../../../
|
||||
shell: bash
|
||||
- run: cd ts/packages/spl-token && yarn --frozen-lockfile && yarn build:node && yarn link && cd ../../../
|
||||
shell: bash
|
||||
- run: cd examples/tutorial && yarn link @project-serum/anchor && yarn --frozen-lockfile && cd ../../
|
||||
shell: bash
|
||||
- run: cd tests && yarn link @project-serum/anchor && yarn --frozen-lockfile && cd ..
|
||||
- run: cd tests && yarn link @project-serum/anchor && yarn link @project-serum/spl-associated-token-account && yarn link @project-serum/spl-token && yarn --frozen-lockfile && cd ..
|
||||
shell: bash
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
* ts: Update seeds inference to allow nested user defined structs within the seeds ([#2198](https://github.com/coral-xyz/anchor/pull/2198))
|
||||
* event: Fix multiple event listeners with the same name. ([#2165](https://github.com/coral-xyz/anchor/pull/2165))
|
||||
|
||||
### Breaking
|
||||
|
||||
* ts: SPL coders have been removed from the main Anchor package. ([#2155](https://github.com/coral-xyz/anchor/pull/2155))
|
||||
|
||||
## [0.25.0] - 2022-07-05
|
||||
|
||||
### Features
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
[programs.localnet]
|
||||
custom_coder = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
|
||||
spl_token = "FmpfPa1LHEYRbueNMnwNVd2JvyQ89GXGWdyZEXNNKV8w"
|
||||
native_system = "9NxAd91hhJ3ZBTHytYP894y4ESRKG7n8VbLgdyYGJFLB"
|
||||
spl_associated_token = "4dUGnkre6uBhX1abB4ofkoecGN4aDXdiWSaWLUjVw6bh"
|
||||
spl_token = "FmpfPa1LHEYRbueNMnwNVd2JvyQ89GXGWdyZEXNNKV8w"
|
||||
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
|
@ -13,5 +12,3 @@ wallet = "~/.config/solana/id.json"
|
|||
|
||||
[scripts]
|
||||
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "custom-coder",
|
||||
"version": "0.20.0",
|
||||
"version": "0.25.0",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"homepage": "https://github.com/coral-xyz/anchor#readme",
|
||||
"bugs": {
|
||||
|
@ -14,7 +14,7 @@
|
|||
"node": ">=11"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "anchor test"
|
||||
"test": "anchor test --skip-lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"mocha": "^10.0.0",
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
[package]
|
||||
name = "custom-coder"
|
||||
version = "0.1.0"
|
||||
description = "Created with Anchor"
|
||||
rust-version = "1.56"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
name = "custom_coder"
|
||||
|
||||
[features]
|
||||
no-entrypoint = []
|
||||
no-idl = []
|
||||
no-log-ix-name = []
|
||||
cpi = ["no-entrypoint"]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../lang" }
|
|
@ -1,2 +0,0 @@
|
|||
[target.bpfel-unknown-unknown.dependencies.std]
|
||||
features = []
|
|
@ -1,14 +0,0 @@
|
|||
use anchor_lang::prelude::*;
|
||||
|
||||
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
|
||||
|
||||
#[program]
|
||||
pub mod custom_coder {
|
||||
use super::*;
|
||||
pub fn initialize(_ctx: Context<Initialize>, a: Option<u8>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize {}
|
|
@ -19,4 +19,4 @@ default = []
|
|||
overflow-checks = true
|
||||
|
||||
[dependencies]
|
||||
anchor-lang = { path = "../../../../lang" }
|
||||
anchor-lang = { path = "../../../../lang" }
|
||||
|
|
|
@ -1,33 +1,9 @@
|
|||
// This file is autogenerated with https://github.com/acheroncrypto/native-to-anchor
|
||||
// See https://github.com/coral-xyz/anchor/blob/master/ts/packages/spl-associated-token-account/program/lib.rs
|
||||
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
declare_id!("4dUGnkre6uBhX1abB4ofkoecGN4aDXdiWSaWLUjVw6bh");
|
||||
|
||||
// See https://solana.stackexchange.com/a/1858/471
|
||||
#[program]
|
||||
pub mod spl_associated_token {
|
||||
use super::*;
|
||||
|
||||
pub fn create(ctx: Context<Create>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Create<'info> {
|
||||
#[account(mut)]
|
||||
authority: Signer<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
associated_account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
owner: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
system_program: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
token_program: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
rent: AccountInfo<'info>,
|
||||
}
|
||||
pub mod spl_associated_token {}
|
||||
|
|
|
@ -1,339 +1,9 @@
|
|||
// See https://github.com/coral-xyz/anchor/blob/master/ts/packages/spl-token/program/lib.rs
|
||||
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
declare_id!("FmpfPa1LHEYRbueNMnwNVd2JvyQ89GXGWdyZEXNNKV8w");
|
||||
|
||||
// This program is simply used to generate the IDL for the token program.
|
||||
//
|
||||
// Note that we manually add the COption<Pubkey> type to the IDL after
|
||||
// compiling.
|
||||
//
|
||||
// See https://solana.stackexchange.com/a/1858/471
|
||||
#[program]
|
||||
pub mod spl_token {
|
||||
use super::*;
|
||||
|
||||
pub fn initialize_mint(
|
||||
ctx: Context<InitializeMint>,
|
||||
decimals: u8,
|
||||
mint_authority: Pubkey,
|
||||
// freeze_authority: COption<Pubkey>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_account(ctx: Context<InitializeAccount>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_multisig(ctx: Context<InitializeMultisig>, m: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn transfer(ctx: Context<Transfer>, amount: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn approve(ctx: Context<Approve>, amount: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn revoke(ctx: Context<Revoke>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_authority(
|
||||
ctx: Context<SetAuthority>,
|
||||
authority_type: u8,
|
||||
// new_authority: COption<Pubkey>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mint_to(ctx: Context<MintTo>, amount: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn burn(ctx: Context<Burn>, amount: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn close_account(ctx: Context<CloseAccount>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn freeze_account(ctx: Context<FreezeAccount>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn thaw_account(ctx: Context<ThawAccount>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn transfer_checked(
|
||||
ctx: Context<TransferChecked>,
|
||||
amount: u64,
|
||||
decimals: u8,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn approve_checked(
|
||||
ctx: Context<ApproveChecked>,
|
||||
amount: u64,
|
||||
decimals: u8,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mint_to_checked(
|
||||
ctx: Context<MintToChecked>,
|
||||
amount: u64,
|
||||
decimals: u8,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn burn_checked(ctx: Context<BurnChecked>, amount: u64, decimals: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_account_2(
|
||||
ctx: Context<InitializeAccount2>,
|
||||
authority: Pubkey,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn sync_native(ctx: Context<SyncNative>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_account3(
|
||||
ctx: Context<InitializeAccount3>,
|
||||
authority: Pubkey,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_multisig_2(ctx: Context<InitializeMultisig2>, m: u8) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize_mint_2(
|
||||
ctx: Context<InitializeMint2>,
|
||||
decimals: u8,
|
||||
mint_authority: Pubkey,
|
||||
// freeze_authority: COption<Pubkey>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeMint<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
rent: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeAccount<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
authority: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
rent: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeMultisig<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
rent: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Transfer<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
destination: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Approve<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
delegate: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Revoke<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct SetAuthority<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
pub mint: AccountInfo<'info>,
|
||||
pub authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct MintTo<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
pub mint: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
pub to: AccountInfo<'info>,
|
||||
pub authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Burn<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct CloseAccount<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
destination: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
authority: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct FreezeAccount<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct ThawAccount<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct TransferChecked<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
destination: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct ApproveChecked<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
delegate: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct MintToChecked<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
to: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct BurnChecked<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
source: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
authority: Signer<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeAccount2<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
rent: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct SyncNative<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeAccount3<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeMultisig2<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
account: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct InitializeMint2<'info> {
|
||||
#[account(mut)]
|
||||
/// CHECK:
|
||||
mint: AccountInfo<'info>,
|
||||
}
|
||||
pub mod spl_token {}
|
||||
|
|
|
@ -1,28 +1,27 @@
|
|||
import * as anchor from "@project-serum/anchor";
|
||||
import { Native, Spl } from "@project-serum/anchor";
|
||||
import { Keypair, PublicKey } from "@solana/web3.js";
|
||||
import { Native, AnchorProvider, setProvider } from "@project-serum/anchor";
|
||||
import { splAssociatedTokenAccountProgram } from "@project-serum/spl-associated-token-account";
|
||||
import { splTokenProgram } from "@project-serum/spl-token";
|
||||
import { Keypair, PublicKey, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
|
||||
import * as assert from "assert";
|
||||
import BN from "bn.js";
|
||||
|
||||
describe("spl-associated-token-coder", () => {
|
||||
// Configure the client to use the local cluster.
|
||||
const provider = anchor.AnchorProvider.env();
|
||||
anchor.setProvider(provider);
|
||||
const provider = AnchorProvider.env();
|
||||
setProvider(provider);
|
||||
|
||||
// Client.
|
||||
const program = Spl.associatedToken();
|
||||
const program = splAssociatedTokenAccountProgram({
|
||||
provider,
|
||||
});
|
||||
const systemProgram = Native.system();
|
||||
const tokenProgram = Spl.token();
|
||||
const tokenProgram = splTokenProgram({
|
||||
provider,
|
||||
});
|
||||
|
||||
it("Creates an account", async () => {
|
||||
// arrange
|
||||
const mintKeypair = Keypair.generate();
|
||||
const mintDecimals = 6;
|
||||
const mintSize = tokenProgram.coder.accounts.size(
|
||||
tokenProgram.idl.accounts[0]
|
||||
);
|
||||
const mintRentExemption =
|
||||
await provider.connection.getMinimumBalanceForRentExemption(mintSize);
|
||||
const [associatedToken] = await PublicKey.findProgramAddress(
|
||||
[
|
||||
provider.publicKey.toBuffer(),
|
||||
|
@ -36,28 +35,21 @@ describe("spl-associated-token-coder", () => {
|
|||
await program.methods
|
||||
.create()
|
||||
.accounts({
|
||||
authority: provider.wallet.publicKey,
|
||||
mint: mintKeypair.publicKey,
|
||||
owner: provider.wallet.publicKey,
|
||||
associatedAccount: associatedToken,
|
||||
associatedAccountAddress: associatedToken,
|
||||
fundingAddress: provider.wallet.publicKey,
|
||||
systemProgram: systemProgram.programId,
|
||||
tokenMintAddress: mintKeypair.publicKey,
|
||||
tokenProgram: tokenProgram.programId,
|
||||
walletAddress: provider.wallet.publicKey,
|
||||
})
|
||||
.preInstructions(
|
||||
await Promise.all([
|
||||
systemProgram.methods
|
||||
.createAccount(
|
||||
new BN(mintRentExemption),
|
||||
new BN(mintSize),
|
||||
tokenProgram.programId
|
||||
)
|
||||
.accounts({
|
||||
from: provider.wallet.publicKey,
|
||||
to: mintKeypair.publicKey,
|
||||
})
|
||||
.instruction(),
|
||||
tokenProgram.account.mint.createInstruction(mintKeypair),
|
||||
tokenProgram.methods
|
||||
.initializeMint(mintDecimals, provider.wallet.publicKey, null)
|
||||
.accounts({
|
||||
mint: mintKeypair.publicKey,
|
||||
rent: SYSVAR_RENT_PUBKEY,
|
||||
})
|
||||
.instruction(),
|
||||
])
|
||||
|
@ -65,7 +57,7 @@ describe("spl-associated-token-coder", () => {
|
|||
.signers([mintKeypair])
|
||||
.rpc();
|
||||
// assert
|
||||
const tokenAccount = await tokenProgram.account.token.fetch(
|
||||
const tokenAccount = await tokenProgram.account.account.fetch(
|
||||
associatedToken
|
||||
);
|
||||
assert.ok(tokenAccount.mint.equals(mintKeypair.publicKey));
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import * as anchor from "@project-serum/anchor";
|
||||
import { Spl } from "@project-serum/anchor";
|
||||
import { assert } from "chai";
|
||||
import { AnchorProvider, setProvider } from "@project-serum/anchor";
|
||||
import { splTokenProgram } from "@project-serum/spl-token";
|
||||
import { Keypair, SYSVAR_RENT_PUBKEY, PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { Keypair, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
|
||||
import { assert } from "chai";
|
||||
|
||||
describe("custom-coder", () => {
|
||||
describe("spl-token", () => {
|
||||
// Configure the client to use the local cluster.
|
||||
const provider = anchor.AnchorProvider.env();
|
||||
anchor.setProvider(provider);
|
||||
const provider = AnchorProvider.env();
|
||||
setProvider(provider);
|
||||
|
||||
// Client.
|
||||
const program = Spl.token();
|
||||
const program = splTokenProgram({
|
||||
provider,
|
||||
});
|
||||
|
||||
// Constants.
|
||||
const mintKeypair = Keypair.generate();
|
||||
|
@ -19,18 +21,21 @@ describe("custom-coder", () => {
|
|||
const rent = SYSVAR_RENT_PUBKEY;
|
||||
|
||||
it("Creates a mint", async () => {
|
||||
await program.rpc.initializeMint(6, provider.wallet.publicKey, null, {
|
||||
accounts: {
|
||||
await program.methods
|
||||
.initializeMint(6, provider.wallet.publicKey, null)
|
||||
.accounts({
|
||||
mint: mintKeypair.publicKey,
|
||||
rent,
|
||||
},
|
||||
signers: [mintKeypair],
|
||||
preInstructions: [
|
||||
})
|
||||
.signers([mintKeypair])
|
||||
.preInstructions([
|
||||
await program.account.mint.createInstruction(mintKeypair),
|
||||
],
|
||||
});
|
||||
])
|
||||
.rpc();
|
||||
const mintAccount = await program.account.mint.fetch(mintKeypair.publicKey);
|
||||
assert.isTrue(mintAccount.mintAuthority.equals(provider.wallet.publicKey));
|
||||
assert.isTrue(
|
||||
(mintAccount.mintAuthority as PublicKey).equals(provider.wallet.publicKey)
|
||||
);
|
||||
assert.isNull(mintAccount.freezeAuthority);
|
||||
assert.strictEqual(mintAccount.decimals, 6);
|
||||
assert.isTrue(mintAccount.isInitialized);
|
||||
|
@ -38,41 +43,43 @@ describe("custom-coder", () => {
|
|||
});
|
||||
|
||||
it("Creates a token account for alice", async () => {
|
||||
await program.rpc.initializeAccount({
|
||||
accounts: {
|
||||
await program.methods
|
||||
.initializeAccount()
|
||||
.accounts({
|
||||
account: aliceTokenKeypair.publicKey,
|
||||
mint: mintKeypair.publicKey,
|
||||
authority: provider.wallet.publicKey,
|
||||
owner: provider.wallet.publicKey,
|
||||
rent,
|
||||
},
|
||||
signers: [aliceTokenKeypair],
|
||||
preInstructions: [
|
||||
await program.account.token.createInstruction(aliceTokenKeypair),
|
||||
],
|
||||
});
|
||||
const token = await program.account.token.fetch(
|
||||
})
|
||||
.signers([aliceTokenKeypair])
|
||||
.preInstructions([
|
||||
await program.account.account.createInstruction(aliceTokenKeypair),
|
||||
])
|
||||
.rpc();
|
||||
const token = await program.account.account.fetch(
|
||||
aliceTokenKeypair.publicKey
|
||||
);
|
||||
assert.isTrue(token.authority.equals(provider.wallet.publicKey));
|
||||
assert.isTrue(token.owner.equals(provider.wallet.publicKey));
|
||||
assert.isTrue(token.mint.equals(mintKeypair.publicKey));
|
||||
assert.strictEqual(token.amount.toNumber(), 0);
|
||||
assert.isNull(token.delegate);
|
||||
assert.strictEqual(token.state, 1);
|
||||
assert.strictEqual(Object.keys(token.state)[0], "initialized");
|
||||
assert.isNull(token.isNative);
|
||||
assert.strictEqual(token.delegatedAmount.toNumber(), 0);
|
||||
assert.isNull(token.closeAuthority);
|
||||
});
|
||||
|
||||
it("Mints a token to alice", async () => {
|
||||
await program.rpc.mintTo(new BN(2), {
|
||||
accounts: {
|
||||
await program.methods
|
||||
.mintTo(new BN(2))
|
||||
.accounts({
|
||||
mint: mintKeypair.publicKey,
|
||||
to: aliceTokenKeypair.publicKey,
|
||||
authority: provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
account: aliceTokenKeypair.publicKey,
|
||||
owner: provider.wallet.publicKey,
|
||||
})
|
||||
.rpc();
|
||||
|
||||
const token = await program.account.token.fetch(
|
||||
const token = await program.account.account.fetch(
|
||||
aliceTokenKeypair.publicKey
|
||||
);
|
||||
const mint = await program.account.mint.fetch(mintKeypair.publicKey);
|
||||
|
@ -81,32 +88,34 @@ describe("custom-coder", () => {
|
|||
});
|
||||
|
||||
it("Creates a token for bob", async () => {
|
||||
await program.rpc.initializeAccount({
|
||||
accounts: {
|
||||
await program.methods
|
||||
.initializeAccount()
|
||||
.accounts({
|
||||
account: bobTokenKeypair.publicKey,
|
||||
mint: mintKeypair.publicKey,
|
||||
authority: provider.wallet.publicKey,
|
||||
owner: provider.wallet.publicKey,
|
||||
rent,
|
||||
},
|
||||
signers: [bobTokenKeypair],
|
||||
preInstructions: [
|
||||
await program.account.token.createInstruction(bobTokenKeypair),
|
||||
],
|
||||
});
|
||||
})
|
||||
.signers([bobTokenKeypair])
|
||||
.preInstructions([
|
||||
await program.account.account.createInstruction(bobTokenKeypair),
|
||||
])
|
||||
.rpc();
|
||||
});
|
||||
|
||||
it("Transfer a token from alice to bob", async () => {
|
||||
await program.rpc.transfer(new BN(1), {
|
||||
accounts: {
|
||||
await program.methods
|
||||
.transfer(new BN(1))
|
||||
.accounts({
|
||||
source: aliceTokenKeypair.publicKey,
|
||||
destination: bobTokenKeypair.publicKey,
|
||||
authority: provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
const aliceToken = await program.account.token.fetch(
|
||||
})
|
||||
.rpc();
|
||||
const aliceToken = await program.account.account.fetch(
|
||||
aliceTokenKeypair.publicKey
|
||||
);
|
||||
const bobToken = await program.account.token.fetch(
|
||||
const bobToken = await program.account.account.fetch(
|
||||
bobTokenKeypair.publicKey
|
||||
);
|
||||
assert.strictEqual(aliceToken.amount.toNumber(), 1);
|
||||
|
@ -114,14 +123,15 @@ describe("custom-coder", () => {
|
|||
});
|
||||
|
||||
it("Alice burns a token", async () => {
|
||||
await program.rpc.burn(new BN(1), {
|
||||
accounts: {
|
||||
source: aliceTokenKeypair.publicKey,
|
||||
await program.methods
|
||||
.burn(new BN(1))
|
||||
.accounts({
|
||||
account: aliceTokenKeypair.publicKey,
|
||||
mint: mintKeypair.publicKey,
|
||||
authority: provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
const aliceToken = await program.account.token.fetch(
|
||||
})
|
||||
.rpc();
|
||||
const aliceToken = await program.account.account.fetch(
|
||||
aliceTokenKeypair.publicKey
|
||||
);
|
||||
const mint = await program.account.mint.fetch(mintKeypair.publicKey);
|
|
@ -41,6 +41,8 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "file:../ts/packages/anchor",
|
||||
"@project-serum/spl-associated-token-account": "file:../ts/packages/spl-associated-token-account",
|
||||
"@project-serum/spl-token": "file:../ts/packages/spl-token",
|
||||
"@project-serum/common": "^0.0.1-beta.3",
|
||||
"@project-serum/serum": "^0.13.60",
|
||||
"@solana/spl-token": "^0.1.8",
|
||||
|
|
136
tests/yarn.lock
136
tests/yarn.lock
|
@ -37,20 +37,47 @@
|
|||
"@ethersproject/logger" "^5.5.0"
|
||||
hash.js "1.1.7"
|
||||
|
||||
"@native-to-anchor/buffer-layout@=0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@native-to-anchor/buffer-layout/-/buffer-layout-0.1.0.tgz#ff0cb66341bc820b8ee73bb1d1d43bae7e3554b0"
|
||||
integrity sha512-7Ykz9KRAm53XqHj5blDUKPX+OXAPO4GZBW4zJhfHGIAbzmqsUFh9kMqR66Bak3mp6wyv1OVTwSr8ZGHKswPxDg==
|
||||
dependencies:
|
||||
"@solana/buffer-layout" "=4.0.0"
|
||||
"@solana/buffer-layout-utils" "=0.2.0"
|
||||
|
||||
"@noble/ed25519@^1.7.0":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.1.tgz#6899660f6fbb97798a6fbd227227c4589a454724"
|
||||
integrity sha512-Rk4SkJFaXZiznFyC/t77Q0NKS4FL7TLJJsVG2V2oiEq3kJVeTdxysEe/yRWSpnWMe808XRDJ+VFh5pt/FN5plw==
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.0.tgz#583ac38340a479314b9e348d4572101ed9492f9d"
|
||||
integrity sha512-LeAxFK0+181zQOhOUuKE8Jnd3duzYhDNd3iCLxpmzA5K+e4I1FdbrK3Ot0ZHBwZMeRD/6EojyUfTbpHZ+hkQHg==
|
||||
|
||||
"@noble/hashes@^1.1.2":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.3.tgz#360afc77610e0a61f3417e497dcf36862e4f8111"
|
||||
integrity sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183"
|
||||
integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==
|
||||
|
||||
"@noble/secp256k1@^1.6.3":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.0.tgz#d15357f7c227e751d90aa06b05a0e5cf993ba8c1"
|
||||
integrity sha512-kbacwGSsH/CTout0ZnZWxnW1B+jH/7r/WAAKLBtrRJ/+CUH7lgmQzl3GTrQua3SGKWNSDsS6lmjnDpIJ5Dxyaw==
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz#7eed12d9f4404b416999d0c87686836c4c5c9b94"
|
||||
integrity sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==
|
||||
|
||||
"@project-serum/anchor@=0.25.0", "@project-serum/anchor@file:../ts/packages/anchor":
|
||||
version "0.25.0"
|
||||
dependencies:
|
||||
"@project-serum/borsh" "^0.2.5"
|
||||
"@solana/web3.js" "^1.64.0"
|
||||
base64-js "^1.5.1"
|
||||
bn.js "^5.1.2"
|
||||
bs58 "^4.0.1"
|
||||
buffer-layout "^1.2.2"
|
||||
camelcase "^5.3.1"
|
||||
cross-fetch "^3.1.5"
|
||||
crypto-hash "^1.3.0"
|
||||
eventemitter3 "^4.0.7"
|
||||
js-sha256 "^0.9.0"
|
||||
pako "^2.0.3"
|
||||
snake-case "^3.0.4"
|
||||
superstruct "^0.15.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@project-serum/anchor@^0.11.1":
|
||||
version "0.11.1"
|
||||
|
@ -72,33 +99,6 @@
|
|||
snake-case "^3.0.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@project-serum/anchor@file:../ts/packages/anchor":
|
||||
version "0.25.0"
|
||||
dependencies:
|
||||
"@project-serum/borsh" "^0.2.5"
|
||||
"@solana/web3.js" "^1.64.0"
|
||||
base64-js "^1.5.1"
|
||||
bn.js "^5.1.2"
|
||||
bs58 "^4.0.1"
|
||||
buffer-layout "^1.2.2"
|
||||
camelcase "^5.3.1"
|
||||
cross-fetch "^3.1.5"
|
||||
crypto-hash "^1.3.0"
|
||||
eventemitter3 "^4.0.7"
|
||||
js-sha256 "^0.9.0"
|
||||
pako "^2.0.3"
|
||||
snake-case "^3.0.4"
|
||||
superstruct "^0.15.4"
|
||||
toml "^3.0.0"
|
||||
|
||||
"@project-serum/borsh@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.2.tgz#63e558f2d6eb6ab79086bf499dea94da3182498f"
|
||||
integrity sha512-Ms+aWmGVW6bWd3b0+MWwoaYig2QD0F90h0uhr7AzY3dpCb5e2S6RsRW02vFTfa085pY2VLB7nTZNbFECQ1liTg==
|
||||
dependencies:
|
||||
bn.js "^5.1.2"
|
||||
buffer-layout "^1.2.0"
|
||||
|
||||
"@project-serum/borsh@^0.2.5":
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@project-serum/borsh/-/borsh-0.2.5.tgz#6059287aa624ecebbfc0edd35e4c28ff987d8663"
|
||||
|
@ -127,6 +127,35 @@
|
|||
bn.js "^5.1.2"
|
||||
buffer-layout "^1.2.0"
|
||||
|
||||
"@project-serum/spl-associated-token-account@file:../ts/packages/spl-associated-token-account":
|
||||
version "1.1.1"
|
||||
dependencies:
|
||||
"@native-to-anchor/buffer-layout" "=0.1.0"
|
||||
"@project-serum/anchor" "=0.25.0"
|
||||
|
||||
"@project-serum/spl-token@file:../ts/packages/spl-token":
|
||||
version "3.3.0"
|
||||
dependencies:
|
||||
"@native-to-anchor/buffer-layout" "=0.1.0"
|
||||
"@project-serum/anchor" "=0.25.0"
|
||||
|
||||
"@solana/buffer-layout-utils@=0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout-utils/-/buffer-layout-utils-0.2.0.tgz#b45a6cab3293a2eb7597cceb474f229889d875ca"
|
||||
integrity sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==
|
||||
dependencies:
|
||||
"@solana/buffer-layout" "^4.0.0"
|
||||
"@solana/web3.js" "^1.32.0"
|
||||
bigint-buffer "^1.1.5"
|
||||
bignumber.js "^9.0.1"
|
||||
|
||||
"@solana/buffer-layout@=4.0.0", "@solana/buffer-layout@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734"
|
||||
integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==
|
||||
dependencies:
|
||||
buffer "~6.0.3"
|
||||
|
||||
"@solana/buffer-layout@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326"
|
||||
|
@ -134,13 +163,6 @@
|
|||
dependencies:
|
||||
buffer "~6.0.3"
|
||||
|
||||
"@solana/buffer-layout@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734"
|
||||
integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==
|
||||
dependencies:
|
||||
buffer "~6.0.3"
|
||||
|
||||
"@solana/spl-token@^0.1.6", "@solana/spl-token@^0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.1.8.tgz#f06e746341ef8d04165e21fc7f555492a2a0faa6"
|
||||
|
@ -153,7 +175,7 @@
|
|||
buffer-layout "^1.2.0"
|
||||
dotenv "10.0.0"
|
||||
|
||||
"@solana/web3.js@^1.17.0", "@solana/web3.js@^1.21.0":
|
||||
"@solana/web3.js@^1.21.0":
|
||||
version "1.30.2"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.30.2.tgz#e85da75e0825dc64f53eb64a1ff0115b27bec135"
|
||||
integrity sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg==
|
||||
|
@ -173,6 +195,27 @@
|
|||
superstruct "^0.14.2"
|
||||
tweetnacl "^1.0.0"
|
||||
|
||||
"@solana/web3.js@^1.32.0":
|
||||
version "1.66.2"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.66.2.tgz#80b43c5868b846124fe3ebac7d3943930c3fa60c"
|
||||
integrity sha512-RyaHMR2jGmaesnYP045VLeBGfR/gAW3cvZHzMFGg7bkO+WOYOYp1nEllf0/la4U4qsYGKCsO9eEevR5fhHiVHg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@noble/ed25519" "^1.7.0"
|
||||
"@noble/hashes" "^1.1.2"
|
||||
"@noble/secp256k1" "^1.6.3"
|
||||
"@solana/buffer-layout" "^4.0.0"
|
||||
bigint-buffer "^1.1.5"
|
||||
bn.js "^5.0.0"
|
||||
borsh "^0.7.0"
|
||||
bs58 "^4.0.1"
|
||||
buffer "6.0.1"
|
||||
fast-stable-stringify "^1.0.0"
|
||||
jayson "^3.4.4"
|
||||
node-fetch "2"
|
||||
rpc-websockets "^7.5.0"
|
||||
superstruct "^0.14.2"
|
||||
|
||||
"@solana/web3.js@^1.64.0":
|
||||
version "1.64.0"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.64.0.tgz#b7f5a976976039a0161242e94d6e1224ab5d30f9"
|
||||
|
@ -346,6 +389,11 @@ bigint-buffer@^1.1.5:
|
|||
dependencies:
|
||||
bindings "^1.3.0"
|
||||
|
||||
bignumber.js@^9.0.1:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.0.tgz#8d340146107fe3a6cb8d40699643c302e8773b62"
|
||||
integrity sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
|
|
|
@ -6,4 +6,3 @@ for D in */;
|
|||
cd $D && yarn init:yarn; cd ..;
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import { IdlEvent, IdlTypeDef } from "../idl.js";
|
|||
import { Event } from "../program/event.js";
|
||||
|
||||
export * from "./borsh/index.js";
|
||||
export * from "./spl-token/index.js";
|
||||
export * from "./system/index.js";
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import { AccountsCoder } from "../index.js";
|
||||
import { Idl, IdlTypeDef } from "../../idl.js";
|
||||
import { accountSize } from "../common";
|
||||
|
||||
export class SplAssociatedTokenAccountsCoder<A extends string = string>
|
||||
implements AccountsCoder
|
||||
{
|
||||
constructor(private idl: Idl) {}
|
||||
|
||||
public async encode<T = any>(accountName: A, account: T): Promise<Buffer> {
|
||||
switch (accountName) {
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public decode<T = any>(accountName: A, ix: Buffer): T {
|
||||
return this.decodeUnchecked(accountName, ix);
|
||||
}
|
||||
|
||||
public decodeUnchecked<T = any>(accountName: A, ix: Buffer): T {
|
||||
switch (accountName) {
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this won't use the appendData.
|
||||
public memcmp(accountName: A, _appendData?: Buffer): any {
|
||||
switch (accountName) {
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public size(idlAccount: IdlTypeDef): number {
|
||||
return accountSize(this.idl, idlAccount) ?? 0;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import { EventCoder } from "../index.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
import { Event } from "../../program/event";
|
||||
import { IdlEvent } from "../../idl";
|
||||
|
||||
export class SplAssociatedTokenEventsCoder implements EventCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
decode<E extends IdlEvent = IdlEvent, T = Record<string, string>>(
|
||||
_log: string
|
||||
): Event<E, T> | null {
|
||||
throw new Error("SPL associated token program does not have events");
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import { Idl } from "../../idl.js";
|
||||
import { Coder } from "../index.js";
|
||||
import { SplAssociatedTokenInstructionCoder } from "./instruction.js";
|
||||
import { SplAssociatedTokenStateCoder } from "./state.js";
|
||||
import { SplAssociatedTokenAccountsCoder } from "./accounts.js";
|
||||
import { SplAssociatedTokenEventsCoder } from "./events.js";
|
||||
import { SplAssociatedTokenTypesCoder } from "./types.js";
|
||||
|
||||
/**
|
||||
* Coder for the SPL token program.
|
||||
*/
|
||||
export class SplAssociatedTokenCoder implements Coder {
|
||||
readonly instruction: SplAssociatedTokenInstructionCoder;
|
||||
readonly accounts: SplAssociatedTokenAccountsCoder;
|
||||
readonly state: SplAssociatedTokenStateCoder;
|
||||
readonly events: SplAssociatedTokenEventsCoder;
|
||||
readonly types: SplAssociatedTokenTypesCoder;
|
||||
|
||||
constructor(idl: Idl) {
|
||||
this.instruction = new SplAssociatedTokenInstructionCoder(idl);
|
||||
this.accounts = new SplAssociatedTokenAccountsCoder(idl);
|
||||
this.events = new SplAssociatedTokenEventsCoder(idl);
|
||||
this.state = new SplAssociatedTokenStateCoder(idl);
|
||||
this.types = new SplAssociatedTokenTypesCoder(idl);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import camelCase from "camelcase";
|
||||
import { Idl } from "../../idl.js";
|
||||
import { InstructionCoder } from "../index.js";
|
||||
|
||||
export class SplAssociatedTokenInstructionCoder implements InstructionCoder {
|
||||
constructor(_: Idl) {}
|
||||
|
||||
encode(ixName: string, _: any): Buffer {
|
||||
switch (camelCase(ixName)) {
|
||||
case "create": {
|
||||
return Buffer.alloc(0);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid instruction: ${ixName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encodeState(_ixName: string, _ix: any): Buffer {
|
||||
throw new Error("SPL associated token does not have state");
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { StateCoder } from "../index.js";
|
||||
import { Idl } from "../../idl";
|
||||
|
||||
export class SplAssociatedTokenStateCoder implements StateCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _account: T): Promise<Buffer> {
|
||||
throw new Error("SPL associated token does not have state");
|
||||
}
|
||||
decode<T = any>(_ix: Buffer): T {
|
||||
throw new Error("SPL associated token does not have state");
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { TypesCoder } from "../index.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
|
||||
export class SplAssociatedTokenTypesCoder implements TypesCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _type: T): Buffer {
|
||||
throw new Error("SPL associated token does not have user-defined types");
|
||||
}
|
||||
decode<T = any>(_name: string, _typeData: Buffer): T {
|
||||
throw new Error("SPL associated token does not have user-defined types");
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
import * as BufferLayout from "buffer-layout";
|
||||
import { publicKey, uint64, coption, bool } from "./buffer-layout.js";
|
||||
import { AccountsCoder } from "../index.js";
|
||||
import { Idl, IdlTypeDef } from "../../idl.js";
|
||||
import { accountSize } from "../common";
|
||||
|
||||
export class SplTokenAccountsCoder<A extends string = string>
|
||||
implements AccountsCoder
|
||||
{
|
||||
constructor(private idl: Idl) {}
|
||||
|
||||
public async encode<T = any>(accountName: A, account: T): Promise<Buffer> {
|
||||
switch (accountName) {
|
||||
case "token": {
|
||||
const buffer = Buffer.alloc(165);
|
||||
const len = TOKEN_ACCOUNT_LAYOUT.encode(account, buffer);
|
||||
return buffer.slice(0, len);
|
||||
}
|
||||
case "mint": {
|
||||
const buffer = Buffer.alloc(82);
|
||||
const len = MINT_ACCOUNT_LAYOUT.encode(account, buffer);
|
||||
return buffer.slice(0, len);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public decode<T = any>(accountName: A, ix: Buffer): T {
|
||||
return this.decodeUnchecked(accountName, ix);
|
||||
}
|
||||
|
||||
public decodeUnchecked<T = any>(accountName: A, ix: Buffer): T {
|
||||
switch (accountName) {
|
||||
case "token": {
|
||||
return decodeTokenAccount(ix);
|
||||
}
|
||||
case "mint": {
|
||||
return decodeMintAccount(ix);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this won't use the appendData.
|
||||
public memcmp(accountName: A, _appendData?: Buffer): any {
|
||||
switch (accountName) {
|
||||
case "token": {
|
||||
return {
|
||||
dataSize: 165,
|
||||
};
|
||||
}
|
||||
case "mint": {
|
||||
return {
|
||||
dataSize: 82,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid account name: ${accountName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public size(idlAccount: IdlTypeDef): number {
|
||||
return accountSize(this.idl, idlAccount) ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
function decodeMintAccount<T = any>(ix: Buffer): T {
|
||||
return MINT_ACCOUNT_LAYOUT.decode(ix) as T;
|
||||
}
|
||||
|
||||
function decodeTokenAccount<T = any>(ix: Buffer): T {
|
||||
return TOKEN_ACCOUNT_LAYOUT.decode(ix) as T;
|
||||
}
|
||||
|
||||
const MINT_ACCOUNT_LAYOUT = BufferLayout.struct([
|
||||
coption(publicKey(), "mintAuthority"),
|
||||
uint64("supply"),
|
||||
BufferLayout.u8("decimals"),
|
||||
bool("isInitialized"),
|
||||
coption(publicKey(), "freezeAuthority"),
|
||||
]);
|
||||
|
||||
const TOKEN_ACCOUNT_LAYOUT = BufferLayout.struct([
|
||||
publicKey("mint"),
|
||||
publicKey("authority"),
|
||||
uint64("amount"),
|
||||
coption(publicKey(), "delegate"),
|
||||
BufferLayout.u8("state"),
|
||||
coption(uint64(), "isNative"),
|
||||
uint64("delegatedAmount"),
|
||||
coption(publicKey(), "closeAuthority"),
|
||||
]);
|
|
@ -1,14 +0,0 @@
|
|||
import { EventCoder } from "../index.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
import { Event } from "../../program/event";
|
||||
import { IdlEvent } from "../../idl";
|
||||
|
||||
export class SplTokenEventsCoder implements EventCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
decode<E extends IdlEvent = IdlEvent, T = Record<string, string>>(
|
||||
_log: string
|
||||
): Event<E, T> | null {
|
||||
throw new Error("SPL token program does not have events");
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import { Idl } from "../../idl.js";
|
||||
import { Coder } from "../index.js";
|
||||
import { SplTokenInstructionCoder } from "./instruction.js";
|
||||
import { SplTokenStateCoder } from "./state.js";
|
||||
import { SplTokenAccountsCoder } from "./accounts.js";
|
||||
import { SplTokenEventsCoder } from "./events.js";
|
||||
import { SplTokenTypesCoder } from "./types.js";
|
||||
|
||||
/**
|
||||
* Coder for the SPL token program.
|
||||
*/
|
||||
export class SplTokenCoder implements Coder {
|
||||
readonly instruction: SplTokenInstructionCoder;
|
||||
readonly accounts: SplTokenAccountsCoder;
|
||||
readonly state: SplTokenStateCoder;
|
||||
readonly events: SplTokenEventsCoder;
|
||||
readonly types: SplTokenTypesCoder;
|
||||
|
||||
constructor(idl: Idl) {
|
||||
this.instruction = new SplTokenInstructionCoder(idl);
|
||||
this.accounts = new SplTokenAccountsCoder(idl);
|
||||
this.events = new SplTokenEventsCoder(idl);
|
||||
this.state = new SplTokenStateCoder(idl);
|
||||
this.types = new SplTokenTypesCoder(idl);
|
||||
}
|
||||
}
|
|
@ -1,349 +0,0 @@
|
|||
import * as BufferLayout from "buffer-layout";
|
||||
import camelCase from "camelcase";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { InstructionCoder } from "../index.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
|
||||
export class SplTokenInstructionCoder implements InstructionCoder {
|
||||
constructor(_: Idl) {}
|
||||
|
||||
encode(ixName: string, ix: any): Buffer {
|
||||
switch (camelCase(ixName)) {
|
||||
case "initializeMint": {
|
||||
return encodeInitializeMint(ix);
|
||||
}
|
||||
case "initializeAccount": {
|
||||
return encodeInitializeAccount(ix);
|
||||
}
|
||||
case "initializeMultisig": {
|
||||
return encodeInitializeMultisig(ix);
|
||||
}
|
||||
case "transfer": {
|
||||
return encodeTransfer(ix);
|
||||
}
|
||||
case "approve": {
|
||||
return encodeApprove(ix);
|
||||
}
|
||||
case "revoke": {
|
||||
return encodeRevoke(ix);
|
||||
}
|
||||
case "setAuthority": {
|
||||
return encodeSetAuthority(ix);
|
||||
}
|
||||
case "mintTo": {
|
||||
return encodeMintTo(ix);
|
||||
}
|
||||
case "burn": {
|
||||
return encodeBurn(ix);
|
||||
}
|
||||
case "closeAccount": {
|
||||
return encodeCloseAccount(ix);
|
||||
}
|
||||
case "freezeAccount": {
|
||||
return encodeFreezeAccount(ix);
|
||||
}
|
||||
case "thawAccount": {
|
||||
return encodeThawAccount(ix);
|
||||
}
|
||||
case "transferChecked": {
|
||||
return encodeTransferChecked(ix);
|
||||
}
|
||||
case "approvedChecked": {
|
||||
return encodeApproveChecked(ix);
|
||||
}
|
||||
case "mintToChecked": {
|
||||
return encodeMintToChecked(ix);
|
||||
}
|
||||
case "burnChecked": {
|
||||
return encodeBurnChecked(ix);
|
||||
}
|
||||
case "intializeAccount2": {
|
||||
return encodeInitializeAccount2(ix);
|
||||
}
|
||||
case "syncNative": {
|
||||
return encodeSyncNative(ix);
|
||||
}
|
||||
case "initializeAccount3": {
|
||||
return encodeInitializeAccount3(ix);
|
||||
}
|
||||
case "initializeMultisig2": {
|
||||
return encodeInitializeMultisig2(ix);
|
||||
}
|
||||
case "initializeMint2": {
|
||||
return encodeInitializeMint2(ix);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Invalid instruction: ${ixName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
encodeState(_ixName: string, _ix: any): Buffer {
|
||||
throw new Error("SPL token does not have state");
|
||||
}
|
||||
}
|
||||
|
||||
function encodeInitializeMint({
|
||||
decimals,
|
||||
mintAuthority,
|
||||
freezeAuthority,
|
||||
}: any): Buffer {
|
||||
return encodeData({
|
||||
initializeMint: {
|
||||
decimals,
|
||||
mintAuthority: mintAuthority.toBuffer(),
|
||||
freezeAuthorityOption: !!freezeAuthority,
|
||||
freezeAuthority: (freezeAuthority || PublicKey.default).toBuffer(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeAccount(_ix: any): Buffer {
|
||||
return encodeData({
|
||||
initializeAccount: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeMultisig({ m }: any): Buffer {
|
||||
return encodeData({
|
||||
initializeMultisig: {
|
||||
m,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeTransfer({ amount }: any): Buffer {
|
||||
return encodeData({
|
||||
transfer: { amount },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeApprove({ amount }: any): Buffer {
|
||||
return encodeData({
|
||||
approve: { amount },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeRevoke(_ix: any): Buffer {
|
||||
return encodeData({
|
||||
revoke: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeSetAuthority({ authorityType, newAuthority }: any): Buffer {
|
||||
return encodeData({
|
||||
setAuthority: { authorityType, newAuthority },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeMintTo({ amount }: any): Buffer {
|
||||
return encodeData({
|
||||
mintTo: { amount },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeBurn({ amount }: any): Buffer {
|
||||
return encodeData({
|
||||
burn: { amount },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeCloseAccount(_: any): Buffer {
|
||||
return encodeData({
|
||||
closeAccount: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeFreezeAccount(_: any): Buffer {
|
||||
return encodeData({
|
||||
freezeAccount: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeThawAccount(_: any): Buffer {
|
||||
return encodeData({
|
||||
thawAccount: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeTransferChecked({ amount, decimals }: any): Buffer {
|
||||
return encodeData({
|
||||
transferChecked: { amount, decimals },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeApproveChecked({ amount, decimals }: any): Buffer {
|
||||
return encodeData({
|
||||
approveChecked: { amount, decimals },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeMintToChecked({ amount, decimals }: any): Buffer {
|
||||
return encodeData({
|
||||
mintToChecked: { amount, decimals },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeBurnChecked({ amount, decimals }: any): Buffer {
|
||||
return encodeData({
|
||||
burnChecked: { amount, decimals },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeAccount2({ authority }: any): Buffer {
|
||||
return encodeData({
|
||||
initilaizeAccount2: { authority },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeSyncNative(_: any): Buffer {
|
||||
return encodeData({
|
||||
syncNative: {},
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeAccount3({ authority }: any): Buffer {
|
||||
return encodeData({
|
||||
initializeAccount3: { authority },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeMultisig2({ m }: any): Buffer {
|
||||
return encodeData({
|
||||
initializeMultisig2: { m },
|
||||
});
|
||||
}
|
||||
|
||||
function encodeInitializeMint2({
|
||||
decimals,
|
||||
mintAuthority,
|
||||
freezeAuthority,
|
||||
}: any): Buffer {
|
||||
return encodeData({
|
||||
encodeInitializeMint2: { decimals, mintAuthority, freezeAuthority },
|
||||
});
|
||||
}
|
||||
|
||||
const LAYOUT = BufferLayout.union(BufferLayout.u8("instruction"));
|
||||
LAYOUT.addVariant(
|
||||
0,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.u8("decimals"),
|
||||
BufferLayout.blob(32, "mintAuthority"),
|
||||
BufferLayout.u8("freezeAuthorityOption"),
|
||||
publicKey("freezeAuthority"),
|
||||
]),
|
||||
"initializeMint"
|
||||
);
|
||||
LAYOUT.addVariant(1, BufferLayout.struct([]), "initializeAccount");
|
||||
LAYOUT.addVariant(
|
||||
2,
|
||||
BufferLayout.struct([BufferLayout.u8("m")]),
|
||||
"initializeMultisig"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
3,
|
||||
BufferLayout.struct([BufferLayout.nu64("amount")]),
|
||||
"transfer"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
4,
|
||||
BufferLayout.struct([BufferLayout.nu64("amount")]),
|
||||
"approve"
|
||||
);
|
||||
LAYOUT.addVariant(5, BufferLayout.struct([]), "revoke");
|
||||
LAYOUT.addVariant(
|
||||
6,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.u8("authorityType"),
|
||||
BufferLayout.u8("newAuthorityOption"),
|
||||
publicKey("newAuthority"),
|
||||
]),
|
||||
"setAuthority"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
7,
|
||||
BufferLayout.struct([BufferLayout.nu64("amount")]),
|
||||
"mintTo"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
8,
|
||||
BufferLayout.struct([BufferLayout.nu64("amount")]),
|
||||
"burn"
|
||||
);
|
||||
LAYOUT.addVariant(9, BufferLayout.struct([]), "closeAccount");
|
||||
LAYOUT.addVariant(10, BufferLayout.struct([]), "freezeAccount");
|
||||
LAYOUT.addVariant(11, BufferLayout.struct([]), "thawAccount");
|
||||
LAYOUT.addVariant(
|
||||
12,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.nu64("amount"),
|
||||
BufferLayout.u8("decimals"),
|
||||
]),
|
||||
"transferChecked"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
13,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.nu64("amount"),
|
||||
BufferLayout.u8("decimals"),
|
||||
]),
|
||||
"approvedChecked"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
14,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.nu64("amount"),
|
||||
BufferLayout.u8("decimals"),
|
||||
]),
|
||||
"mintToChecked"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
15,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.nu64("amount"),
|
||||
BufferLayout.u8("decimals"),
|
||||
]),
|
||||
"burnedChecked"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
16,
|
||||
BufferLayout.struct([publicKey("authority")]),
|
||||
"InitializeAccount2"
|
||||
);
|
||||
LAYOUT.addVariant(17, BufferLayout.struct([]), "syncNative");
|
||||
LAYOUT.addVariant(
|
||||
18,
|
||||
BufferLayout.struct([publicKey("authority")]),
|
||||
"initializeAccount3"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
19,
|
||||
BufferLayout.struct([BufferLayout.u8("m")]),
|
||||
"initializeMultisig2"
|
||||
);
|
||||
LAYOUT.addVariant(
|
||||
20,
|
||||
BufferLayout.struct([
|
||||
BufferLayout.u8("decimals"),
|
||||
publicKey("mintAuthority"),
|
||||
BufferLayout.u8("freezeAuthorityOption"),
|
||||
publicKey("freezeAuthority"),
|
||||
]),
|
||||
"initializeMint2"
|
||||
);
|
||||
|
||||
function publicKey(property: string): any {
|
||||
return BufferLayout.blob(32, property);
|
||||
}
|
||||
|
||||
function encodeData(instruction: any): Buffer {
|
||||
let b = Buffer.alloc(instructionMaxSpan);
|
||||
let span = LAYOUT.encode(instruction, b);
|
||||
return b.slice(0, span);
|
||||
}
|
||||
|
||||
const instructionMaxSpan = Math.max(
|
||||
// @ts-ignore
|
||||
...Object.values(LAYOUT.registry).map((r) => r.span)
|
||||
);
|
|
@ -1,13 +0,0 @@
|
|||
import { StateCoder } from "../index.js";
|
||||
import { Idl } from "../../idl";
|
||||
|
||||
export class SplTokenStateCoder implements StateCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _account: T): Promise<Buffer> {
|
||||
throw new Error("SPL token does not have state");
|
||||
}
|
||||
decode<T = any>(_ix: Buffer): T {
|
||||
throw new Error("SPL token does not have state");
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { TypesCoder } from "../index.js";
|
||||
import { Idl } from "../../idl.js";
|
||||
|
||||
export class SplTokenTypesCoder implements TypesCoder {
|
||||
constructor(_idl: Idl) {}
|
||||
|
||||
encode<T = any>(_name: string, _type: T): Buffer {
|
||||
throw new Error("SPL token does not have user-defined types");
|
||||
}
|
||||
decode<T = any>(_name: string, _typeData: Buffer): T {
|
||||
throw new Error("SPL token does not have user-defined types");
|
||||
}
|
||||
}
|
|
@ -17,7 +17,6 @@ export { CustomAccountResolver } from "./program/accounts-resolver.js";
|
|||
export * from "./coder/index.js";
|
||||
export * as utils from "./utils/index.js";
|
||||
export * from "./program/index.js";
|
||||
export * from "./spl/index.js";
|
||||
export * from "./native/index.js";
|
||||
|
||||
export declare const workspace: any;
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
IdlAccountItem,
|
||||
IdlAccounts,
|
||||
IdlTypeDef,
|
||||
IdlTypeDefStruct,
|
||||
IdlTypeDefTyStruct,
|
||||
IdlType,
|
||||
} from "../idl.js";
|
||||
|
@ -21,8 +20,8 @@ import { TOKEN_PROGRAM_ID, ASSOCIATED_PROGRAM_ID } from "../utils/token.js";
|
|||
import { AllInstructions } from "./namespace/types.js";
|
||||
import Provider from "../provider.js";
|
||||
import { AccountNamespace } from "./namespace/account.js";
|
||||
import { coder } from "../spl/token";
|
||||
import { BorshAccountsCoder } from "src/coder/index.js";
|
||||
import { decodeTokenAccount } from "./token-account-layout";
|
||||
import { Program } from "./index.js";
|
||||
|
||||
type Accounts = { [name: string]: PublicKey | Accounts };
|
||||
|
@ -36,7 +35,7 @@ export type CustomAccountResolver<IDL extends Idl> = (params: {
|
|||
}) => Promise<{ accounts: Accounts; resolved: number }>;
|
||||
|
||||
// Populates a given accounts context with PDAs and common missing accounts.
|
||||
export class AccountsResolver<IDL extends Idl, I extends AllInstructions<IDL>> {
|
||||
export class AccountsResolver<IDL extends Idl> {
|
||||
_args: Array<any>;
|
||||
static readonly CONST_ACCOUNTS = {
|
||||
associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
|
||||
|
@ -489,7 +488,7 @@ export class AccountStore<IDL extends Idl> {
|
|||
if (accountInfo === null) {
|
||||
throw new Error(`invalid account info for ${address}`);
|
||||
}
|
||||
const data = coder().accounts.decode("token", accountInfo.data);
|
||||
const data = decodeTokenAccount(accountInfo.data);
|
||||
this._cache.set(address, data);
|
||||
} else if (name) {
|
||||
const accounts = await this.ensureIdl(programId);
|
||||
|
|
|
@ -79,7 +79,7 @@ export class MethodsBuilder<IDL extends Idl, I extends AllInstructions<IDL>> {
|
|||
private _signers: Array<Signer> = [];
|
||||
private _preInstructions: Array<TransactionInstruction> = [];
|
||||
private _postInstructions: Array<TransactionInstruction> = [];
|
||||
private _accountsResolver: AccountsResolver<IDL, I>;
|
||||
private _accountsResolver: AccountsResolver<IDL>;
|
||||
private _autoResolveAccounts: boolean = true;
|
||||
private _args: Array<any>;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as BufferLayout from "buffer-layout";
|
|||
import { Layout } from "buffer-layout";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
export function uint64(property?: string): Layout<u64 | null> {
|
||||
function uint64(property?: string): Layout<u64 | null> {
|
||||
return new WrappedLayout(
|
||||
BufferLayout.blob(8),
|
||||
(b: Buffer) => u64.fromBuffer(b),
|
||||
|
@ -12,11 +12,7 @@ export function uint64(property?: string): Layout<u64 | null> {
|
|||
);
|
||||
}
|
||||
|
||||
export function bool(property?: string): Layout<boolean> {
|
||||
return new WrappedLayout(BufferLayout.u8(), decodeBool, encodeBool, property);
|
||||
}
|
||||
|
||||
export function publicKey(property?: string): Layout<PublicKey> {
|
||||
function publicKey(property?: string): Layout<PublicKey> {
|
||||
return new WrappedLayout(
|
||||
BufferLayout.blob(32),
|
||||
(b: Buffer) => new PublicKey(b),
|
||||
|
@ -25,10 +21,7 @@ export function publicKey(property?: string): Layout<PublicKey> {
|
|||
);
|
||||
}
|
||||
|
||||
export function coption<T>(
|
||||
layout: Layout<T>,
|
||||
property?: string
|
||||
): Layout<T | null> {
|
||||
function coption<T>(layout: Layout<T>, property?: string): Layout<T | null> {
|
||||
return new COptionLayout<T>(layout, property);
|
||||
}
|
||||
|
||||
|
@ -62,7 +55,7 @@ class WrappedLayout<T, U> extends Layout<U> {
|
|||
}
|
||||
}
|
||||
|
||||
export class COptionLayout<T> extends Layout<T | null> {
|
||||
class COptionLayout<T> extends Layout<T | null> {
|
||||
layout: Layout<T>;
|
||||
discriminator: Layout<number>;
|
||||
|
||||
|
@ -95,20 +88,7 @@ export class COptionLayout<T> extends Layout<T | null> {
|
|||
}
|
||||
}
|
||||
|
||||
function decodeBool(value: number): boolean {
|
||||
if (value === 0) {
|
||||
return false;
|
||||
} else if (value === 1) {
|
||||
return true;
|
||||
}
|
||||
throw new Error("Invalid bool: " + value);
|
||||
}
|
||||
|
||||
function encodeBool(value: boolean): number {
|
||||
return value ? 1 : 0;
|
||||
}
|
||||
|
||||
export class u64 extends BN {
|
||||
class u64 extends BN {
|
||||
/**
|
||||
* Convert to Buffer representation
|
||||
*/
|
||||
|
@ -143,3 +123,24 @@ export class u64 extends BN {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
const TOKEN_ACCOUNT_LAYOUT = BufferLayout.struct([
|
||||
publicKey("mint"),
|
||||
publicKey("owner"),
|
||||
uint64("amount"),
|
||||
coption(publicKey(), "delegate"),
|
||||
((p: string) => {
|
||||
const U = BufferLayout.union(BufferLayout.u8("discriminator"), null, p);
|
||||
U.addVariant(0, BufferLayout.struct([]), "uninitialized");
|
||||
U.addVariant(1, BufferLayout.struct([]), "initialized");
|
||||
U.addVariant(2, BufferLayout.struct([]), "frozen");
|
||||
return U;
|
||||
})("state"),
|
||||
coption(uint64(), "isNative"),
|
||||
uint64("delegatedAmount"),
|
||||
coption(publicKey(), "closeAuthority"),
|
||||
]);
|
||||
|
||||
export function decodeTokenAccount(b: Buffer) {
|
||||
return TOKEN_ACCOUNT_LAYOUT.decode(b);
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
import { PublicKey } from "@solana/web3.js";
|
||||
import { Program } from "../program/index.js";
|
||||
import Provider from "../provider.js";
|
||||
import { SplAssociatedTokenCoder } from "../coder/spl-associated-token/index.js";
|
||||
|
||||
const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey(
|
||||
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
|
||||
);
|
||||
|
||||
export function program(provider?: Provider): Program<SplAssociatedToken> {
|
||||
return new Program<SplAssociatedToken>(
|
||||
IDL,
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
provider,
|
||||
coder()
|
||||
);
|
||||
}
|
||||
|
||||
export function coder(): SplAssociatedTokenCoder {
|
||||
return new SplAssociatedTokenCoder(IDL);
|
||||
}
|
||||
|
||||
/**
|
||||
* SplAssociatedToken IDL.
|
||||
*/
|
||||
export type SplAssociatedToken = {
|
||||
version: "0.1.0";
|
||||
name: "spl_associated_token";
|
||||
instructions: [
|
||||
{
|
||||
name: "create";
|
||||
accounts: [
|
||||
{
|
||||
name: "authority";
|
||||
isMut: true;
|
||||
isSigner: true;
|
||||
},
|
||||
{
|
||||
name: "associatedAccount";
|
||||
isMut: true;
|
||||
isSigner: false;
|
||||
},
|
||||
{
|
||||
name: "owner";
|
||||
isMut: false;
|
||||
isSigner: false;
|
||||
},
|
||||
{
|
||||
name: "mint";
|
||||
isMut: false;
|
||||
isSigner: false;
|
||||
},
|
||||
{
|
||||
name: "systemProgram";
|
||||
isMut: false;
|
||||
isSigner: false;
|
||||
},
|
||||
{
|
||||
name: "tokenProgram";
|
||||
isMut: false;
|
||||
isSigner: false;
|
||||
},
|
||||
{
|
||||
name: "rent";
|
||||
isMut: false;
|
||||
isSigner: false;
|
||||
}
|
||||
];
|
||||
args: [];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
export const IDL: SplAssociatedToken = {
|
||||
version: "0.1.0",
|
||||
name: "spl_associated_token",
|
||||
instructions: [
|
||||
{
|
||||
name: "create",
|
||||
accounts: [
|
||||
{
|
||||
name: "authority",
|
||||
isMut: true,
|
||||
isSigner: true,
|
||||
},
|
||||
{
|
||||
name: "associatedAccount",
|
||||
isMut: true,
|
||||
isSigner: false,
|
||||
},
|
||||
{
|
||||
name: "owner",
|
||||
isMut: false,
|
||||
isSigner: false,
|
||||
},
|
||||
{
|
||||
name: "mint",
|
||||
isMut: false,
|
||||
isSigner: false,
|
||||
},
|
||||
{
|
||||
name: "systemProgram",
|
||||
isMut: false,
|
||||
isSigner: false,
|
||||
},
|
||||
{
|
||||
name: "tokenProgram",
|
||||
isMut: false,
|
||||
isSigner: false,
|
||||
},
|
||||
{
|
||||
name: "rent",
|
||||
isMut: false,
|
||||
isSigner: false,
|
||||
},
|
||||
],
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -1,20 +0,0 @@
|
|||
import { Program, Provider } from "../index.js";
|
||||
import {
|
||||
program as associatedTokenProgram,
|
||||
SplAssociatedToken,
|
||||
} from "./associated-token.js";
|
||||
import { program as tokenProgram, SplToken } from "./token.js";
|
||||
|
||||
export { SplToken } from "./token.js";
|
||||
|
||||
export class Spl {
|
||||
public static token(provider?: Provider): Program<SplToken> {
|
||||
return tokenProgram(provider);
|
||||
}
|
||||
|
||||
public static associatedToken(
|
||||
provider?: Provider
|
||||
): Program<SplAssociatedToken> {
|
||||
return associatedTokenProgram(provider);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue