Explorar el Código

anchor cpiguard example

John hace 1 año
padre
commit
665189ad73

+ 7 - 0
tokens/token-2022/cpi-guard/anchor/.gitignore

@@ -0,0 +1,7 @@
+.anchor
+.DS_Store
+target
+**/*.rs.bk
+node_modules
+test-ledger
+.yarn

+ 7 - 0
tokens/token-2022/cpi-guard/anchor/.prettierignore

@@ -0,0 +1,7 @@
+.anchor
+.DS_Store
+target
+node_modules
+dist
+build
+test-ledger

+ 18 - 0
tokens/token-2022/cpi-guard/anchor/Anchor.toml

@@ -0,0 +1,18 @@
+[toolchain]
+
+[features]
+resolution = true
+skip-lint = false
+
+[programs.localnet]
+cpi_guard = "6tU3MEowU6oxxeDZLSxEwzcEZsZrhBJsfUR6xECvShid"
+
+[registry]
+url = "https://api.apr.dev"
+
+[provider]
+cluster = "Localnet"
+wallet = "~/.config/solana/id.json"
+
+[scripts]
+test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

+ 14 - 0
tokens/token-2022/cpi-guard/anchor/Cargo.toml

@@ -0,0 +1,14 @@
+[workspace]
+members = [
+    "programs/*"
+]
+resolver = "2"
+
+[profile.release]
+overflow-checks = true
+lto = "fat"
+codegen-units = 1
+[profile.release.build-override]
+opt-level = 3
+incremental = false
+codegen-units = 1

+ 12 - 0
tokens/token-2022/cpi-guard/anchor/migrations/deploy.ts

@@ -0,0 +1,12 @@
+// Migrations are an early feature. Currently, they're nothing more than this
+// single deploy script that's invoked from the CLI, injecting a provider
+// configured from the workspace's Anchor.toml.
+
+const anchor = require("@coral-xyz/anchor");
+
+module.exports = async function (provider) {
+  // Configure client to use the provider.
+  anchor.setProvider(provider);
+
+  // Add your deploy script here.
+};

+ 20 - 0
tokens/token-2022/cpi-guard/anchor/package.json

@@ -0,0 +1,20 @@
+{
+  "scripts": {
+    "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
+    "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
+  },
+  "dependencies": {
+    "@coral-xyz/anchor": "^0.30.0",
+    "@solana/spl-token": "^0.4.6"
+  },
+  "devDependencies": {
+    "@types/bn.js": "^5.1.0",
+    "@types/chai": "^4.3.0",
+    "@types/mocha": "^9.0.0",
+    "chai": "^4.3.4",
+    "mocha": "^9.0.3",
+    "prettier": "^2.6.2",
+    "ts-mocha": "^10.0.0",
+    "typescript": "^4.3.5"
+  }
+}

+ 21 - 0
tokens/token-2022/cpi-guard/anchor/programs/cpi-guard/Cargo.toml

@@ -0,0 +1,21 @@
+[package]
+name = "cpi-guard"
+version = "0.1.0"
+description = "Created with Anchor"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib", "lib"]
+name = "cpi_guard"
+
+[features]
+default = []
+cpi = ["no-entrypoint"]
+no-entrypoint = []
+no-idl = []
+no-log-ix-name = []
+idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]
+
+[dependencies]
+anchor-lang = { version = "0.30.0", features = ["init-if-needed"] }
+anchor-spl = "0.30.0"

+ 2 - 0
tokens/token-2022/cpi-guard/anchor/programs/cpi-guard/Xargo.toml

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

+ 56 - 0
tokens/token-2022/cpi-guard/anchor/programs/cpi-guard/src/lib.rs

@@ -0,0 +1,56 @@
+use anchor_lang::prelude::*;
+use anchor_spl::{
+    token_2022::{transfer_checked, TransferChecked},
+    token_interface::{Mint, Token2022, TokenAccount},
+};
+
+// Note that you cannot initialize or update the CpiGuard extension through a CPI
+// https://github.com/solana-labs/solana-program-library/blob/6968859e2ee0a1764da572de340cdb58e2b4586f/token/program-2022/src/extension/cpi_guard/processor.rs#L44-L46
+declare_id!("6tU3MEowU6oxxeDZLSxEwzcEZsZrhBJsfUR6xECvShid");
+
+#[program]
+pub mod cpi_guard {
+    use super::*;
+
+    pub fn cpi_transfer(ctx: Context<CpiTransfer>) -> Result<()> {
+        transfer_checked(
+            CpiContext::new(
+                ctx.accounts.token_program.to_account_info(),
+                TransferChecked {
+                    from: ctx.accounts.sender_token_account.to_account_info(),
+                    mint: ctx.accounts.mint_account.to_account_info(),
+                    to: ctx.accounts.recipient_token_account.to_account_info(),
+                    authority: ctx.accounts.sender.to_account_info(),
+                },
+            ),
+            1,
+            ctx.accounts.mint_account.decimals,
+        )?;
+        Ok(())
+    }
+}
+
+#[derive(Accounts)]
+pub struct CpiTransfer<'info> {
+    #[account(mut)]
+    pub sender: Signer<'info>,
+
+    #[account(
+        mut,
+        token::mint = mint_account
+    )]
+    pub sender_token_account: InterfaceAccount<'info, TokenAccount>,
+    #[account(
+        init_if_needed,
+        payer = sender,
+        seeds = [b"pda"],
+        bump,
+        token::mint = mint_account,
+        token::authority = recipient_token_account,
+        token::token_program = token_program
+    )]
+    pub recipient_token_account: InterfaceAccount<'info, TokenAccount>,
+    pub mint_account: InterfaceAccount<'info, Mint>,
+    pub token_program: Program<'info, Token2022>,
+    pub system_program: Program<'info, System>,
+}

+ 139 - 0
tokens/token-2022/cpi-guard/anchor/tests/cpi-guard.ts

@@ -0,0 +1,139 @@
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { CpiGuard } from "../target/types/cpi_guard";
+import {
+  ExtensionType,
+  TOKEN_2022_PROGRAM_ID,
+  createEnableCpiGuardInstruction,
+  createInitializeAccountInstruction,
+  createMint,
+  disableCpiGuard,
+  getAccountLen,
+  mintTo,
+} from "@solana/spl-token";
+import {
+  sendAndConfirmTransaction,
+  SystemProgram,
+  Transaction,
+} from "@solana/web3.js";
+
+describe("cpi-guard", () => {
+  // Configure the client to use the local cluster.
+  const provider = anchor.AnchorProvider.env();
+  const connection = provider.connection;
+  const wallet = provider.wallet as anchor.Wallet;
+  anchor.setProvider(provider);
+
+  const program = anchor.workspace.CpiGuard as Program<CpiGuard>;
+
+  const mintKeypair = new anchor.web3.Keypair();
+  const tokenKeypair = new anchor.web3.Keypair();
+
+  it("Create Token Account with CpiGuard extension", async () => {
+    await createMint(
+      connection,
+      wallet.payer, // Payer of the transaction and initialization fees
+      wallet.publicKey, // Mint Authority
+      null, // Optional Freeze Authority
+      2, // Decimals of Mint
+      mintKeypair, // Optional keypair
+      undefined, // Options for confirming the transaction
+      TOKEN_2022_PROGRAM_ID // Token Extension Program ID
+    );
+
+    // Size of Token Account with extension
+    const accountLen = getAccountLen([ExtensionType.CpiGuard]);
+    // Minimum lamports required for Token Account
+    const lamports = await connection.getMinimumBalanceForRentExemption(
+      accountLen
+    );
+
+    // Instruction to invoke System Program to create new account
+    const createAccountInstruction = SystemProgram.createAccount({
+      fromPubkey: wallet.publicKey, // Account that will transfer lamports to created account
+      newAccountPubkey: tokenKeypair.publicKey, // Address of the account to create
+      space: accountLen, // Amount of bytes to allocate to the created account
+      lamports, // Amount of lamports transferred to created account
+      programId: TOKEN_2022_PROGRAM_ID, // Program assigned as owner of created account
+    });
+
+    // Instruction to initialize Token Account data
+    const initializeAccountInstruction = createInitializeAccountInstruction(
+      tokenKeypair.publicKey, // Token Account Address
+      mintKeypair.publicKey, // Mint Account
+      wallet.publicKey, // Token Account Owner
+      TOKEN_2022_PROGRAM_ID // Token Extension Program ID
+    );
+
+    // Instruction to initialize the CpiGuard Extension
+    const enableCpiGuiardInstruction = createEnableCpiGuardInstruction(
+      tokenKeypair.publicKey,
+      wallet.publicKey,
+      [],
+      TOKEN_2022_PROGRAM_ID
+    );
+
+    const transaction = new Transaction().add(
+      createAccountInstruction,
+      initializeAccountInstruction,
+      enableCpiGuiardInstruction
+    );
+
+    const transactionSignature = await sendAndConfirmTransaction(
+      connection,
+      transaction,
+      [wallet.payer, tokenKeypair] // Signers
+    );
+
+    await mintTo(
+      connection,
+      wallet.payer,
+      mintKeypair.publicKey,
+      tokenKeypair.publicKey,
+      wallet.payer,
+      1,
+      [],
+      null,
+      TOKEN_2022_PROGRAM_ID
+    );
+
+    console.log("Your transaction signature", transactionSignature);
+  });
+
+  it("Transfer, expect fail", async () => {
+    try {
+      await program.methods
+        .cpiTransfer()
+        .accounts({
+          sender: wallet.publicKey,
+          senderTokenAccount: tokenKeypair.publicKey,
+          mintAccount: mintKeypair.publicKey,
+        })
+        .rpc({ skipPreflight: true });
+    } catch (error) {
+      console.log("\nExpect Error:", error.message);
+    }
+  });
+
+  it("Disable CpiGuard", async () => {
+    const transactionSignature = await disableCpiGuard(
+      connection,
+      wallet.payer,
+      tokenKeypair.publicKey,
+      wallet.publicKey
+    );
+    console.log("Your transaction signature", transactionSignature);
+  });
+
+  it("Transfer, expect success", async () => {
+    const transactionSignature = await program.methods
+      .cpiTransfer()
+      .accounts({
+        sender: wallet.publicKey,
+        senderTokenAccount: tokenKeypair.publicKey,
+        mintAccount: mintKeypair.publicKey,
+      })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", transactionSignature);
+  });
+});

+ 10 - 0
tokens/token-2022/cpi-guard/anchor/tsconfig.json

@@ -0,0 +1,10 @@
+{
+  "compilerOptions": {
+    "types": ["mocha", "chai"],
+    "typeRoots": ["./node_modules/@types"],
+    "lib": ["es2015"],
+    "module": "commonjs",
+    "target": "es6",
+    "esModuleInterop": true
+  }
+}

+ 1 - 1
tokens/token-2022/memo-transfer/anchor/programs/memo-transfer/Cargo.toml

@@ -17,5 +17,5 @@ no-log-ix-name = []
 idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]
 
 [dependencies]
-anchor-lang = { version = "0.30.0", features = ["init-if-needed"] }
+anchor-lang = "0.30.0"
 anchor-spl = "0.30.0"