forked from coral-xyz/anchor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
anchor_spl crate and example (coral-xyz#24)
- Loading branch information
1 parent
b5ca210
commit 11272e3
Showing
14 changed files
with
414 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,4 +27,5 @@ members = [ | |
"syn", | ||
"attribute/*", | ||
"derive/*", | ||
"spl", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cluster = "localnet" | ||
wallet = "~/.config/solana/id.json" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[workspace] | ||
members = [ | ||
"programs/*" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "token-proxy" | ||
version = "0.1.0" | ||
description = "Created with Anchor" | ||
edition = "2018" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "lib"] | ||
name = "token_proxy" | ||
|
||
[features] | ||
no-entrypoint = [] | ||
cpi = ["no-entrypoint"] | ||
|
||
[dependencies] | ||
anchor-lang = { git = "https://github.com/project-serum/anchor", features = ["derive"] } | ||
anchor-spl = { git = "https://github.com/project-serum/anchor", features = ["derive"] } | ||
serum-borsh = { version = "0.8.0-serum.1", features = ["serum-program"] } | ||
solana-program = "1.4.3" | ||
solana-sdk = { version = "1.3.14", default-features = false, features = ["program"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[target.bpfel-unknown-unknown.dependencies.std] | ||
features = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
//! This example demonstrates the use of the `anchor_spl::token` CPI client. | ||
|
||
#![feature(proc_macro_hygiene)] | ||
|
||
use anchor_lang::prelude::*; | ||
use anchor_spl::token::{self, Burn, MintTo, Transfer}; | ||
|
||
#[program] | ||
mod token_proxy { | ||
use super::*; | ||
|
||
pub fn proxy_transfer(ctx: Context<ProxyTransfer>, amount: u64) -> ProgramResult { | ||
token::transfer(ctx.accounts.into(), amount) | ||
} | ||
|
||
pub fn proxy_mint_to(ctx: Context<ProxyMintTo>, amount: u64) -> ProgramResult { | ||
token::mint_to(ctx.accounts.into(), amount) | ||
} | ||
|
||
pub fn proxy_burn(ctx: Context<ProxyBurn>, amount: u64) -> ProgramResult { | ||
token::burn(ctx.accounts.into(), amount) | ||
} | ||
} | ||
|
||
#[derive(Accounts)] | ||
pub struct ProxyTransfer<'info> { | ||
#[account(signer)] | ||
pub authority: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub from: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub to: AccountInfo<'info>, | ||
pub token_program: AccountInfo<'info>, | ||
} | ||
|
||
#[derive(Accounts)] | ||
pub struct ProxyMintTo<'info> { | ||
#[account(signer)] | ||
pub authority: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub mint: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub to: AccountInfo<'info>, | ||
pub token_program: AccountInfo<'info>, | ||
} | ||
|
||
#[derive(Accounts)] | ||
pub struct ProxyBurn<'info> { | ||
#[account(signer)] | ||
pub authority: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub mint: AccountInfo<'info>, | ||
#[account(mut)] | ||
pub to: AccountInfo<'info>, | ||
pub token_program: AccountInfo<'info>, | ||
} | ||
|
||
impl<'a, 'b, 'c, 'info> From<&mut ProxyTransfer<'info>> | ||
for CpiContext<'a, 'b, 'c, 'info, Transfer<'info>> | ||
{ | ||
fn from(accounts: &mut ProxyTransfer<'info>) -> CpiContext<'a, 'b, 'c, 'info, Transfer<'info>> { | ||
let cpi_accounts = Transfer { | ||
from: accounts.from.clone(), | ||
to: accounts.to.clone(), | ||
authority: accounts.authority.clone(), | ||
}; | ||
let cpi_program = accounts.token_program.clone(); | ||
CpiContext::new(cpi_program, cpi_accounts) | ||
} | ||
} | ||
|
||
impl<'a, 'b, 'c, 'info> From<&mut ProxyMintTo<'info>> | ||
for CpiContext<'a, 'b, 'c, 'info, MintTo<'info>> | ||
{ | ||
fn from(accounts: &mut ProxyMintTo<'info>) -> CpiContext<'a, 'b, 'c, 'info, MintTo<'info>> { | ||
let cpi_accounts = MintTo { | ||
mint: accounts.mint.clone(), | ||
to: accounts.to.clone(), | ||
authority: accounts.authority.clone(), | ||
}; | ||
let cpi_program = accounts.token_program.clone(); | ||
CpiContext::new(cpi_program, cpi_accounts) | ||
} | ||
} | ||
|
||
impl<'a, 'b, 'c, 'info> From<&mut ProxyBurn<'info>> for CpiContext<'a, 'b, 'c, 'info, Burn<'info>> { | ||
fn from(accounts: &mut ProxyBurn<'info>) -> CpiContext<'a, 'b, 'c, 'info, Burn<'info>> { | ||
let cpi_accounts = Burn { | ||
mint: accounts.mint.clone(), | ||
to: accounts.to.clone(), | ||
authority: accounts.authority.clone(), | ||
}; | ||
let cpi_program = accounts.token_program.clone(); | ||
CpiContext::new(cpi_program, cpi_accounts) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
const anchor = require("@project-serum/anchor"); | ||
const assert = require("assert"); | ||
|
||
describe("token", () => { | ||
const provider = anchor.Provider.local(); | ||
|
||
// Configure the client to use the local cluster. | ||
anchor.setProvider(provider); | ||
|
||
const program = anchor.workspace.TokenProxy; | ||
|
||
let mint = null; | ||
let from = null; | ||
let to = null; | ||
|
||
it("Initializes test state", async () => { | ||
mint = await createMint(provider); | ||
from = await createTokenAccount(provider, mint, provider.wallet.publicKey); | ||
to = await createTokenAccount(provider, mint, provider.wallet.publicKey); | ||
}); | ||
|
||
it("Mints a token", async () => { | ||
await program.rpc.proxyMintTo(new anchor.BN(1000), { | ||
accounts: { | ||
authority: provider.wallet.publicKey, | ||
mint, | ||
to: from, | ||
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID, | ||
}, | ||
}); | ||
|
||
const fromAccount = await getTokenAccount(provider, from); | ||
|
||
assert.ok(fromAccount.amount.eq(new anchor.BN(1000))); | ||
}); | ||
|
||
it("Transfers a token", async () => { | ||
await program.rpc.proxyTransfer(new anchor.BN(500), { | ||
accounts: { | ||
authority: provider.wallet.publicKey, | ||
to, | ||
from, | ||
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID, | ||
}, | ||
}); | ||
|
||
const fromAccount = await getTokenAccount(provider, from); | ||
const toAccount = await getTokenAccount(provider, to); | ||
|
||
assert.ok(fromAccount.amount.eq(new anchor.BN(500))); | ||
assert.ok(fromAccount.amount.eq(new anchor.BN(500))); | ||
}); | ||
|
||
it("Burns a token", async () => { | ||
await program.rpc.proxyBurn(new anchor.BN(499), { | ||
accounts: { | ||
authority: provider.wallet.publicKey, | ||
mint, | ||
to, | ||
tokenProgram: TokenInstructions.TOKEN_PROGRAM_ID, | ||
}, | ||
}); | ||
|
||
const toAccount = await getTokenAccount(provider, to); | ||
assert.ok(toAccount.amount.eq(new anchor.BN(1))); | ||
}); | ||
}); | ||
|
||
// SPL token client boilerplate for test initialization. Everything below here is | ||
// mostly irrelevant to the point of the example. | ||
|
||
const serumCmn = require("@project-serum/common"); | ||
const TokenInstructions = require("@project-serum/serum").TokenInstructions; | ||
|
||
async function getTokenAccount(provider, addr) { | ||
return await serumCmn.getTokenAccount(provider, addr); | ||
} | ||
|
||
async function createMint(provider, authority) { | ||
if (authority === undefined) { | ||
authority = provider.wallet.publicKey; | ||
} | ||
const mint = new anchor.web3.Account(); | ||
const instructions = await createMintInstructions( | ||
provider, | ||
authority, | ||
mint.publicKey | ||
); | ||
|
||
const tx = new anchor.web3.Transaction(); | ||
tx.add(...instructions); | ||
|
||
await provider.send(tx, [mint]); | ||
|
||
return mint.publicKey; | ||
} | ||
|
||
async function createMintInstructions(provider, authority, mint) { | ||
let instructions = [ | ||
anchor.web3.SystemProgram.createAccount({ | ||
fromPubkey: provider.wallet.publicKey, | ||
newAccountPubkey: mint, | ||
space: 82, | ||
lamports: await provider.connection.getMinimumBalanceForRentExemption(82), | ||
programId: TokenInstructions.TOKEN_PROGRAM_ID, | ||
}), | ||
TokenInstructions.initializeMint({ | ||
mint, | ||
decimals: 0, | ||
mintAuthority: authority, | ||
}), | ||
]; | ||
return instructions; | ||
} | ||
|
||
async function createTokenAccount(provider, mint, owner) { | ||
const vault = new anchor.web3.Account(); | ||
const tx = new anchor.web3.Transaction(); | ||
tx.add( | ||
...(await createTokenAccountInstrs(provider, vault.publicKey, mint, owner)) | ||
); | ||
await provider.send(tx, [vault]); | ||
return vault.publicKey; | ||
} | ||
|
||
async function createTokenAccountInstrs( | ||
provider, | ||
newAccountPubkey, | ||
mint, | ||
owner, | ||
lamports | ||
) { | ||
if (lamports === undefined) { | ||
lamports = await provider.connection.getMinimumBalanceForRentExemption(165); | ||
} | ||
return [ | ||
anchor.web3.SystemProgram.createAccount({ | ||
fromPubkey: provider.wallet.publicKey, | ||
newAccountPubkey, | ||
space: 165, | ||
lamports, | ||
programId: TokenInstructions.TOKEN_PROGRAM_ID, | ||
}), | ||
TokenInstructions.initializeAccount({ | ||
account: newAccountPubkey, | ||
mint, | ||
owner, | ||
}), | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "anchor-spl" | ||
version = "0.0.0-alpha.0" | ||
authors = ["Armani Ferrante <[email protected]>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
anchor-lang = { path = "../", features = ["derive"] } | ||
solana-program = "1.4.3" | ||
spl-token = { version = "3.0.1", features = ["no-entrypoint"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod token; |
Oops, something went wrong.