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:
acheron 2022-11-17 15:17:22 +01:00 committed by GitHub
parent 5c474c6dfb
commit af115999c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 231 additions and 2579 deletions

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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",

View File

@ -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" }

View File

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

View File

@ -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 {}

View File

@ -19,4 +19,4 @@ default = []
overflow-checks = true
[dependencies]
anchor-lang = { path = "../../../../lang" }
anchor-lang = { path = "../../../../lang" }

View File

@ -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 {}

View File

@ -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 {}

View File

@ -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));

View File

@ -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);

View File

@ -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",

View File

@ -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"

View File

@ -6,4 +6,3 @@ for D in */;
cd $D && yarn init:yarn; cd ..;
fi
done

View File

@ -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";
/**

View File

@ -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;
}
}

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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"),
]);

View File

@ -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");
}
}

View File

@ -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);
}
}

View File

@ -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)
);

View File

@ -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");
}
}

View File

@ -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");
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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>;

View File

@ -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);
}

View File

@ -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: [],
},
],
};

View File

@ -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