John 2 lat temu
rodzic
commit
2c0880bb8d
74 zmienionych plików z 2376 dodań i 2365 usunięć
  1. 7 2
      basics/account-data/solang/solidity/account-data.sol
  2. 18 19
      basics/account-data/solang/tests/account-data.ts
  3. 10 10
      basics/account-data/solang/tsconfig.json
  4. 1 1
      basics/checking-accounts/solang/solidity/checking-accounts.sol
  5. 24 23
      basics/checking-accounts/solang/tests/checking-accounts.ts
  6. 9 9
      basics/checking-accounts/solang/tsconfig.json
  7. 1 1
      basics/counter/solang/solidity/counter.sol
  8. 1 1
      basics/counter/solang/tests/counter.ts
  9. 9 9
      basics/counter/solang/tsconfig.json
  10. 1 1
      basics/cross-program-invocation/solang/solidity/hand.sol
  11. 1 1
      basics/cross-program-invocation/solang/solidity/lever.sol
  12. 31 31
      basics/cross-program-invocation/solang/tests/test.ts
  13. 9 9
      basics/cross-program-invocation/solang/tsconfig.json
  14. 1 1
      basics/hello-solana/solang/solidity/hello-solana.sol
  15. 13 13
      basics/hello-solana/solang/tests/hello-solana.ts
  16. 9 9
      basics/hello-solana/solang/tsconfig.json
  17. 14 14
      basics/pda-rent-payer/solang/libraries/system_instruction.sol
  18. 7 8
      basics/pda-rent-payer/solang/solidity/pda-rent-payer.sol
  19. 26 26
      basics/pda-rent-payer/solang/tests/pda-rent-payer.ts
  20. 9 9
      basics/pda-rent-payer/solang/tsconfig.json
  21. 1 1
      basics/processing-instructions/solang/solidity/processing-instructions.sol
  22. 16 16
      basics/processing-instructions/solang/tests/processing-instructions.ts
  23. 9 9
      basics/processing-instructions/solang/tsconfig.json
  24. 5 4
      basics/program-derived-addresses/solang/solidity/program-derived-addresses.sol
  25. 21 21
      basics/program-derived-addresses/solang/tests/program-derived-addresses.ts
  26. 9 10
      basics/program-derived-addresses/solang/tsconfig.json
  27. 0 0
      basics/rent/solang/libraries/minimum_balance.sol
  28. 14 14
      basics/rent/solang/libraries/system_instruction.sol
  29. 4 4
      basics/rent/solang/solidity/rent.sol
  30. 19 19
      basics/rent/solang/tests/rent.ts
  31. 9 9
      basics/rent/solang/tsconfig.json
  32. 14 14
      basics/transfer-sol/solang/libraries/system_instruction.sol
  33. 7 6
      basics/transfer-sol/solang/solidity/transfer-sol.sol
  34. 37 37
      basics/transfer-sol/solang/tests/transfer-sol.ts
  35. 1 1
      tokens/create-token/solang/libraries/mpl_metadata.sol
  36. 10 10
      tokens/create-token/solang/libraries/spl_token.sol
  37. 14 14
      tokens/create-token/solang/libraries/system_instruction.sol
  38. 2 1
      tokens/create-token/solang/package.json
  39. 4 4
      tokens/create-token/solang/solidity/create-token.sol
  40. 31 31
      tokens/create-token/solang/tests/create-token.ts
  41. 9 9
      tokens/create-token/solang/tsconfig.json
  42. 1 1
      tokens/nft-minter/solang/libraries/mpl_metadata.sol
  43. 10 10
      tokens/nft-minter/solang/libraries/spl_token.sol
  44. 300 0
      tokens/nft-minter/solang/libraries/system_instruction.sol
  45. 1 0
      tokens/nft-minter/solang/package.json
  46. 5 5
      tokens/nft-minter/solang/solidity/nft-minter.sol
  47. 0 300
      tokens/nft-minter/solang/solidity/system_instruction.sol
  48. 30 30
      tokens/nft-minter/solang/tests/nft-minter.ts
  49. 1 1
      tokens/pda-mint-authority/solang/libraries/mpl_metadata.sol
  50. 10 10
      tokens/pda-mint-authority/solang/libraries/spl_token.sol
  51. 300 0
      tokens/pda-mint-authority/solang/libraries/system_instruction.sol
  52. 1 0
      tokens/pda-mint-authority/solang/package.json
  53. 10 9
      tokens/pda-mint-authority/solang/solidity/pda-mint-authority.sol
  54. 0 300
      tokens/pda-mint-authority/solang/solidity/system_instruction.sol
  55. 31 30
      tokens/pda-mint-authority/solang/tests/pda-mint-authority.ts
  56. 9 9
      tokens/pda-mint-authority/solang/tsconfig.json
  57. 1 1
      tokens/spl-token-minter/solang/libraries/mpl_metadata.sol
  58. 10 10
      tokens/spl-token-minter/solang/libraries/spl_token.sol
  59. 300 0
      tokens/spl-token-minter/solang/libraries/system_instruction.sol
  60. 1 0
      tokens/spl-token-minter/solang/package.json
  61. 6 6
      tokens/spl-token-minter/solang/solidity/spl-token-minter.sol
  62. 0 300
      tokens/spl-token-minter/solang/solidity/system_instruction.sol
  63. 30 31
      tokens/spl-token-minter/solang/tests/spl-token-minter.ts
  64. 9 9
      tokens/spl-token-minter/solang/tsconfig.json
  65. 134 0
      tokens/transfer-tokens/solang/libraries/mpl_metadata.sol
  66. 387 0
      tokens/transfer-tokens/solang/libraries/spl_token.sol
  67. 300 0
      tokens/transfer-tokens/solang/libraries/system_instruction.sol
  68. 1 0
      tokens/transfer-tokens/solang/package.json
  69. 0 134
      tokens/transfer-tokens/solang/solidity/mpl_metadata.sol
  70. 0 387
      tokens/transfer-tokens/solang/solidity/spl_token.sol
  71. 0 300
      tokens/transfer-tokens/solang/solidity/system_instruction.sol
  72. 6 6
      tokens/transfer-tokens/solang/solidity/transfer-tokens.sol
  73. 36 36
      tokens/transfer-tokens/solang/tests/transfer-tokens.ts
  74. 9 9
      tokens/transfer-tokens/solang/tsconfig.json

+ 7 - 2
basics/account-data/solang/solidity/account-data.sol

@@ -14,8 +14,13 @@ contract account_data {
     }
 
     @payer(payer) // "payer" is the account that pays to create the dataAccount
-    @space(space) // "space" allocated to the account (maximum 10240 bytes, maximum space that can be reallocate when creating account in program via a CPI)
-    constructor(address payer, uint16 space, string _name, uint8 _houseNumber, string _street, string _city) {
+    constructor(
+        @space uint16 space, // "space" allocated to the account (maximum 10240 bytes, maximum space that can be reallocate when creating account in program via a CPI) 
+        string _name, 
+        uint8 _houseNumber, 
+        string _street, 
+        string _city
+    ) {
         // The AddressInfo instance is initialized with the data passed to the constructor
         addressInfo = AddressInfo(_name, _houseNumber, _street, _city);
     }

+ 18 - 19
basics/account-data/solang/tests/account-data.ts

@@ -1,16 +1,16 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { AccountData } from "../target/types/account_data"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { AccountData } from "../target/types/account_data";
 
 describe("account-data", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new random keypair for the data account.
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const program = anchor.workspace.AccountData as Program<AccountData>
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const program = anchor.workspace.AccountData as Program<AccountData>;
 
   // Create the new account
   // Using 10240 bytes of space, because its unclear how to correctly calculate the minimum space needed for the account
@@ -18,7 +18,6 @@ describe("account-data", () => {
   it("Is initialized!", async () => {
     const tx = await program.methods
       .new(
-        wallet.publicKey, // payer
         10240, // space (10240 bytes is the maximum space allowed when allocating space through a program)
         "Joe C", // name
         136, // house number
@@ -27,18 +26,18 @@ describe("account-data", () => {
       )
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   // Get the account data
   it("Get AddressInfo Data", async () => {
     const val = await program.methods
       .get()
       .accounts({ dataAccount: dataAccount.publicKey })
-      .view()
-    console.log("State:", val)
-  })
+      .view();
+    console.log("State:", val);
+  });
 
   // Get the account data size
   // Testing how much space is used to store the account data
@@ -47,7 +46,7 @@ describe("account-data", () => {
     const size = await program.methods
       .getAddressInfoSize()
       .accounts({ dataAccount: dataAccount.publicKey })
-      .view()
-    console.log("Size:", size.toNumber())
-  })
-})
+      .view();
+    console.log("Size:", size.toNumber());
+  });
+});

+ 10 - 10
basics/account-data/solang/tsconfig.json

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

+ 1 - 1
basics/checking-accounts/solang/solidity/checking-accounts.sol

@@ -6,7 +6,7 @@ contract checking_accounts {
 
     // The dataAccount is unused in this example, but is a required account when using Solang
     @payer(payer) // "payer" is the account that pays to create the dataAccount
-    constructor(address payer) {}
+    constructor() {}
 
     function checkAccounts(address accountToChange, address accountToCreate) public view {
         print("Number of Accounts Provided: {:}".format(tx.accounts.length));

+ 24 - 23
basics/checking-accounts/solang/tests/checking-accounts.ts

@@ -1,38 +1,39 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { CheckingAccounts } from "../target/types/checking_accounts"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { CheckingAccounts } from "../target/types/checking_accounts";
 import {
   SystemProgram,
   Transaction,
   sendAndConfirmTransaction,
-} from "@solana/web3.js"
+} from "@solana/web3.js";
 
 describe("checking-accounts", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new random keypair for the data account.
-  const dataAccount = anchor.web3.Keypair.generate()
+  const dataAccount = anchor.web3.Keypair.generate();
 
   // Generate a new keypair to represent the account we will change.
-  const accountToChange = anchor.web3.Keypair.generate()
+  const accountToChange = anchor.web3.Keypair.generate();
   // Generate a new keypair to represent the account we will create.
-  const accountToCreate = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet as anchor.Wallet
-  const connection = provider.connection
+  const accountToCreate = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet as anchor.Wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.CheckingAccounts as Program<CheckingAccounts>
+  const program = anchor.workspace
+    .CheckingAccounts as Program<CheckingAccounts>;
 
   it("Is initialized!", async () => {
     // Create the new dataAccount, this is an account required by Solang even though we don't use it
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an account owned by our program", async () => {
     // Create the new account owned by our program by directly calling the system program
@@ -42,13 +43,13 @@ describe("checking-accounts", () => {
       lamports: await connection.getMinimumBalanceForRentExemption(0),
       space: 0,
       programId: program.programId, // Our program
-    })
+    });
 
     await sendAndConfirmTransaction(connection, new Transaction().add(ix), [
       wallet.payer,
       accountToChange,
-    ])
-  })
+    ]);
+  });
 
   it("Check Accounts", async () => {
     // Invoke the checkAccounts instruction on our program, passing in the account we want to "check"
@@ -68,7 +69,7 @@ describe("checking-accounts", () => {
         },
       ])
       .signers([accountToCreate])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
basics/checking-accounts/solang/tsconfig.json

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

+ 1 - 1
basics/counter/solang/solidity/counter.sol

@@ -6,7 +6,7 @@ contract counter {
 
     // The constructor is used to create a new counter account
     @payer(payer)  // The "payer" pays for the counter account creation
-    constructor(address payer) {
+    constructor() {
         // Initialize the count to zero
         count = 0;
     }

+ 1 - 1
basics/counter/solang/tests/counter.ts

@@ -17,7 +17,7 @@ describe("counter", () => {
   it("Is initialized!", async () => {
     // Initialize new Counter account
     const tx = await program.methods
-      .new(wallet.publicKey) // wallet.publicKey is the payer for the new account
+      .new() // wallet.publicKey is the payer for the new account
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount]) // dataAccount keypair is a required signer because we're using it to create a new account
       .rpc()

+ 9 - 9
basics/counter/solang/tsconfig.json

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

+ 1 - 1
basics/cross-program-invocation/solang/solidity/hand.sol

@@ -13,7 +13,7 @@ contract hand {
     // Creating a data account is required by Solang, but the account is not used in this example.
     // We only interact with the lever program.
     @payer(payer) // payer for the data account
-    constructor(address payer) {}
+    constructor() {}
 
     // "Pull the lever" by calling the switchPower instruction on the lever program via a Cross Program Invocation.
     function pullLever(address dataAccount, string name) public {

+ 1 - 1
basics/cross-program-invocation/solang/solidity/lever.sol

@@ -5,7 +5,7 @@ contract lever {
     bool private isOn = true;
 
     @payer(payer) // payer for the data account
-    constructor(address payer) {}
+    constructor() {}
 
     // Switch the power on or off
     function switchPower(string name) public {

+ 31 - 31
basics/cross-program-invocation/solang/tests/test.ts

@@ -1,49 +1,49 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { Lever } from "../target/types/lever"
-import { Hand } from "../target/types/hand"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { Lever } from "../target/types/lever";
+import { Hand } from "../target/types/hand";
 
 describe("cross-program-invocation", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new keypair for the data accounts for each program
-  const dataAccountLever = anchor.web3.Keypair.generate()
-  const dataAccountHand = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
+  const dataAccountLever = anchor.web3.Keypair.generate();
+  const dataAccountHand = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
 
   // The lever program and hand program
-  const leverProgram = anchor.workspace.Lever as Program<Lever>
-  const handProgram = anchor.workspace.Hand as Program<Hand>
+  const leverProgram = anchor.workspace.Lever as Program<Lever>;
+  const handProgram = anchor.workspace.Hand as Program<Hand>;
 
   it("Initialize the lever!", async () => {
     // Initialize data account for the lever program
     const tx = await leverProgram.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccountLever.publicKey })
       .signers([dataAccountLever])
-      .rpc()
-    console.log("Your transaction signature", tx)
+      .rpc();
+    console.log("Your transaction signature", tx);
 
     // Fetch the state of the data account
     const val = await leverProgram.methods
       .get()
       .accounts({ dataAccount: dataAccountLever.publicKey })
-      .view()
+      .view();
 
-    console.log("State:", val)
-  })
+    console.log("State:", val);
+  });
 
   it("Pull the lever!", async () => {
     // Initialize data account for the hand program
     // This is required by Solang, but the account is not used
     const tx = await handProgram.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccountHand.publicKey })
       .signers([dataAccountHand])
-      .rpc()
-    console.log("Your transaction signature", tx)
+      .rpc();
+    console.log("Your transaction signature", tx);
 
     // Call the pullLever instruction on the hand program, which invokes the lever program via CPI
     const tx2 = await handProgram.methods
@@ -61,17 +61,17 @@ describe("cross-program-invocation", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx2)
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx2);
 
     // Fetch the state of the data account
     const val = await leverProgram.methods
       .get()
       .accounts({ dataAccount: dataAccountLever.publicKey })
-      .view()
+      .view();
 
-    console.log("State:", val)
-  })
+    console.log("State:", val);
+  });
 
   it("Pull it again!", async () => {
     // Call the pullLever instruction on the hand program, which invokes the lever program via CPI
@@ -90,16 +90,16 @@ describe("cross-program-invocation", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
+      .rpc({ skipPreflight: true });
 
-    console.log("Your transaction signature", tx)
+    console.log("Your transaction signature", tx);
 
     // Fetch the state of the data account
     const val = await leverProgram.methods
       .get()
       .accounts({ dataAccount: dataAccountLever.publicKey })
-      .view()
+      .view();
 
-    console.log("State:", val)
-  })
-})
+    console.log("State:", val);
+  });
+});

+ 9 - 9
basics/cross-program-invocation/solang/tsconfig.json

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

+ 1 - 1
basics/hello-solana/solang/solidity/hello-solana.sol

@@ -4,7 +4,7 @@ contract hello_solana {
     // The constructor is used to create a new account
     // Here we create a new account that stores no data and only prints messages to the program logs when the constructor is called.
     @payer(payer) // The "payer" pays for the account creation
-    constructor(address payer) {
+    constructor() {
         // We get the program ID by calling 'type(hello_solana).program_id', where "hello_solana" is the name of the contract.
         address programId = type(hello_solana).program_id;
 

+ 13 - 13
basics/hello-solana/solang/tests/hello-solana.ts

@@ -1,25 +1,25 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { HelloSolana } from "../target/types/hello_solana"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { HelloSolana } from "../target/types/hello_solana";
 
 describe("hello-solana", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new random keypair for the data account.
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
 
-  const program = anchor.workspace.HelloSolana as Program<HelloSolana>
+  const program = anchor.workspace.HelloSolana as Program<HelloSolana>;
 
   it("Is initialized!", async () => {
     // Initialize a new data account
     const tx = await program.methods
-      .new(wallet.publicKey) // wallet.publicKey is the payer for the new account
+      .new() // wallet.publicKey is the payer for the new account
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount]) // dataAccount keypair is a required signer because we're using it to create a new account
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
basics/hello-solana/solang/tsconfig.json

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

+ 14 - 14
basics/pda-rent-payer/solang/solidity/system_instruction.sol → basics/pda-rent-payer/solang/libraries/system_instruction.sol

@@ -34,7 +34,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: true, is_writable: true})
@@ -54,7 +54,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
@@ -81,7 +81,7 @@ library SystemInstruction {
     ///
     /// @param pubkey the public key for the account whose owner is going to be reassigned
     /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
+    function assign(address pubkey, address owner) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
         ];
@@ -96,7 +96,7 @@ library SystemInstruction {
     /// @param base the base address that derived the 'addr' key using the seed
     /// @param seed the string utilized to created the 'addr' public key
     /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -119,7 +119,7 @@ library SystemInstruction {
     /// @param from public key for the funding account
     /// @param to public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
+    function transfer(address from, address to, uint64 lamports) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true})
@@ -138,7 +138,7 @@ library SystemInstruction {
     /// @param from_owner owner to use to derive the funding account address
     /// @param to_pubkey the public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
@@ -160,7 +160,7 @@ library SystemInstruction {
     ///
     /// @param pub_key account for which to allocate space
     /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
+    function allocate(address pub_key, uint64 space) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
         ];
@@ -177,7 +177,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param space number of bytes of memory to allocate
     /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -204,7 +204,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
         create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -223,7 +223,7 @@ library SystemInstruction {
     /// @param nonce the public key for the nonce account to be created
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
         create_account(from, nonce, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -240,7 +240,7 @@ library SystemInstruction {
     ///
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
@@ -257,7 +257,7 @@ library SystemInstruction {
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param to_pubkey the recipient account
     /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
         AccountMeta[5] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
@@ -275,7 +275,7 @@ library SystemInstruction {
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
@@ -289,7 +289,7 @@ library SystemInstruction {
     ///
     /// @param nonce the public key for the nonce account
     // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
+    function upgrade_nonce_account(address nonce) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
         ];

+ 7 - 8
basics/pda-rent-payer/solang/solidity/pda-rent-payer.sol

@@ -1,14 +1,12 @@
 
-import "./system_instruction.sol";
+import "../libraries/system_instruction.sol";
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract pda_rent_payer {
-    bool private value = true;
 
     @payer(payer) // "payer" is the account that pays for creating the account
     @seed("rent_vault") // hardcoded seed
-    @bump(bump) // bump seed to derive the pda
-    constructor(address payer, bytes1 bump, uint64 fundLamports) {
+    constructor(@bump bytes1 bump, uint64 fundLamports) {
         // Independently derive the PDA address from the seeds, bump, and programId
         (address pda, bytes1 _bump) = try_find_program_address(["rent_vault"], type(pda_rent_payer).program_id);
 
@@ -18,7 +16,7 @@ contract pda_rent_payer {
 
         // Fund the pda account with additional lamports
         SystemInstruction.transfer(
-            payer, // from
+            tx.accounts.payer.key, // from
             address(this), // to (the address of the account being created)
             fundLamports // amount of lamports to transfer
         );
@@ -30,8 +28,9 @@ contract pda_rent_payer {
 
         print("From: {:}".format(from.key));
         print("To: {:}".format(to.key));
-
-        from.lamports -= lamports;
-        to.lamports += lamports;
+        
+        // // Not working with Solang 0.3.1
+        // from.lamports -= lamports;
+        // to.lamports += lamports;
     }
 }

+ 26 - 26
basics/pda-rent-payer/solang/tests/pda-rent-payer.ts

@@ -1,45 +1,45 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { PdaRentPayer } from "../target/types/pda_rent_payer"
-import { PublicKey } from "@solana/web3.js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { PdaRentPayer } from "../target/types/pda_rent_payer";
+import { PublicKey } from "@solana/web3.js";
 
 describe("pda-rent-payer", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.PdaRentPayer as Program<PdaRentPayer>
+  const program = anchor.workspace.PdaRentPayer as Program<PdaRentPayer>;
 
   // Amount of additional lamports to fund the dataAccount with.
-  const fundLamports = 1 * anchor.web3.LAMPORTS_PER_SOL
+  const fundLamports = 1 * anchor.web3.LAMPORTS_PER_SOL;
 
   // Derive the PDA that will be used to initialize the dataAccount.
   const [dataAccountPDA, bump] = PublicKey.findProgramAddressSync(
     [Buffer.from("rent_vault")],
     program.programId
-  )
+  );
 
   it("Initialize the Rent Vault", async () => {
     // Add your test here.
     const tx = await program.methods
-      .new(wallet.publicKey, [bump], new anchor.BN(fundLamports))
+      .new([bump], new anchor.BN(fundLamports))
       .accounts({ dataAccount: dataAccountPDA })
-      .rpc()
-    console.log("Your transaction signature", tx)
+      .rpc();
+    console.log("Your transaction signature", tx);
 
-    const accountInfo = await connection.getAccountInfo(dataAccountPDA)
-    console.log("AccountInfo Lamports:", accountInfo.lamports)
-  })
+    const accountInfo = await connection.getAccountInfo(dataAccountPDA);
+    console.log("AccountInfo Lamports:", accountInfo.lamports);
+  });
 
   it("Create a new account using the Rent Vault", async () => {
-    const newAccount = anchor.web3.Keypair.generate()
-    const space = 100 // number of bytes
+    const newAccount = anchor.web3.Keypair.generate();
+    const space = 100; // number of bytes
 
     // Get the minimum balance for the account to be rent exempt.
-    const lamports = await connection.getMinimumBalanceForRentExemption(space)
+    const lamports = await connection.getMinimumBalanceForRentExemption(space);
 
     // Invoke the createNewAccount instruction on our program
     const tx = await program.methods
@@ -52,10 +52,10 @@ describe("pda-rent-payer", () => {
           isSigner: false,
         },
       ])
-      .rpc()
-    console.log("Your transaction signature", tx)
+      .rpc();
+    console.log("Your transaction signature", tx);
 
-    const accountInfo = await connection.getAccountInfo(newAccount.publicKey)
-    console.log("AccountInfo Lamports:", accountInfo.lamports)
-  })
-})
+    const accountInfo = await connection.getAccountInfo(newAccount.publicKey);
+    console.log("AccountInfo Lamports:", accountInfo.lamports);
+  });
+});

+ 9 - 9
basics/pda-rent-payer/solang/tsconfig.json

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

+ 1 - 1
basics/processing-instructions/solang/solidity/processing-instructions.sol

@@ -3,7 +3,7 @@
 contract processing_instructions {
 
     @payer(payer) // payer for the data account, required by Solang but not used in this example
-    constructor(address payer) {}
+    constructor() {}
 
     function goToPark(string name, uint32 height) public pure {
         // Print messages to the program logs

+ 16 - 16
basics/processing-instructions/solang/tests/processing-instructions.ts

@@ -1,40 +1,40 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { ProcessingInstructions } from "../target/types/processing_instructions"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { ProcessingInstructions } from "../target/types/processing_instructions";
 
 describe("processing-instructions", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new keypair for the data account for the program
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
 
   const program = anchor.workspace
-    .ProcessingInstructions as Program<ProcessingInstructions>
+    .ProcessingInstructions as Program<ProcessingInstructions>;
 
   it("Is initialized!", async () => {
     // Initialize data account for the program, which is required by Solang
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Go to the park!", async () => {
     // Call the goToPark instruction on the program, providing the instruction data
     await program.methods
       .goToPark("Jimmy", 3)
       .accounts({ dataAccount: dataAccount.publicKey })
-      .rpc()
+      .rpc();
 
     // Call the goToPark instruction on the program, providing the instruction data
     await program.methods
       .goToPark("Mary", 10)
       .accounts({ dataAccount: dataAccount.publicKey })
-      .rpc()
-  })
-})
+      .rpc();
+  });
+});

+ 9 - 9
basics/processing-instructions/solang/tsconfig.json

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

+ 5 - 4
basics/program-derived-addresses/solang/solidity/program-derived-addresses.sol

@@ -17,11 +17,12 @@ contract program_derived_addresses {
     // The seeds, bump, and programId are used to derive a unique and deterministic pda (program derived address) to use as the account address
     @payer(payer) // "payer" is the account that pays for creating the account
     @seed("page_visits") // hardcoded seed
-    @seed(abi.encode(payer)) // additional seed using the payer address
-    @bump(bump) // bump seed to derive the pda
-    constructor(address payer, bytes1 bump) {
+    constructor(
+        @seed bytes payer, // additional seed using the payer address
+        @bump bytes1 bump // bump seed to derive the pda
+    ) {
         // Independently derive the PDA address from the seeds, bump, and programId
-        (address pda, bytes1 _bump) = try_find_program_address(["page_visits", abi.encode(payer)], type(program_derived_addresses).program_id);
+        (address pda, bytes1 _bump) = try_find_program_address(["page_visits", payer], type(program_derived_addresses).program_id);
 
         // Verify that the bump passed to the constructor matches the bump derived from the seeds and programId
         // This ensures that only the canonical pda address can be used to create the account (first bump that generates a valid pda address)

+ 21 - 21
basics/program-derived-addresses/solang/tests/program-derived-addresses.ts

@@ -1,23 +1,23 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { ProgramDerivedAddresses } from "../target/types/program_derived_addresses"
-import { PublicKey } from "@solana/web3.js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { ProgramDerivedAddresses } from "../target/types/program_derived_addresses";
+import { PublicKey } from "@solana/web3.js";
 
 describe("program-derived-addresses", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
-  const wallet = provider.wallet
+  const wallet = provider.wallet;
 
   const program = anchor.workspace
-    .ProgramDerivedAddresses as Program<ProgramDerivedAddresses>
+    .ProgramDerivedAddresses as Program<ProgramDerivedAddresses>;
 
   // Derive the PDA that will be used to initialize the dataAccount.
   const [dataAccountPDA, bump] = PublicKey.findProgramAddressSync(
     [Buffer.from("page_visits"), wallet.publicKey.toBuffer()],
     program.programId
-  )
+  );
 
   it("Is initialized!", async () => {
     // Initialize the dataAccount using a PDA as the address.
@@ -25,36 +25,36 @@ describe("program-derived-addresses", () => {
     // This is a feature of PDAs that allows programs to "sign" for PDA that are derived from their programId.
     const tx = await program.methods
       .new(
-        wallet.publicKey, // wallet.publicKey is the payer for the new account
+        wallet.publicKey.toBuffer(), // wallet.publicKey is the payer for the new account
         [bump] // bump seed for the PDA found using findProgramAddress
       )
       .accounts({ dataAccount: dataAccountPDA })
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
 
     // Get the current state of the dataAccount.
     const val = await program.methods
       .get()
       .accounts({ dataAccount: dataAccountPDA })
-      .view()
+      .view();
 
-    console.log("State:", val)
-  })
+    console.log("State:", val);
+  });
 
   it("Visit the page!", async () => {
     // Increment the page visits counter.
     const tx = await program.methods
       .incrementPageVisits()
       .accounts({ dataAccount: dataAccountPDA })
-      .rpc()
-    console.log("Your transaction signature", tx)
+      .rpc();
+    console.log("Your transaction signature", tx);
 
     // Get the current state of the dataAccount.
     const val = await program.methods
       .get()
       .accounts({ dataAccount: dataAccountPDA })
-      .view()
+      .view();
 
-    console.log("State:", val)
-  })
-})
+    console.log("State:", val);
+  });
+});

+ 9 - 10
basics/program-derived-addresses/solang/tsconfig.json

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

+ 0 - 0
basics/rent/solang/solidity/minimum_balance.sol → basics/rent/solang/libraries/minimum_balance.sol


+ 14 - 14
basics/rent/solang/solidity/system_instruction.sol → basics/rent/solang/libraries/system_instruction.sol

@@ -34,7 +34,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: true, is_writable: true})
@@ -54,7 +54,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
@@ -81,7 +81,7 @@ library SystemInstruction {
     ///
     /// @param pubkey the public key for the account whose owner is going to be reassigned
     /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
+    function assign(address pubkey, address owner) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
         ];
@@ -96,7 +96,7 @@ library SystemInstruction {
     /// @param base the base address that derived the 'addr' key using the seed
     /// @param seed the string utilized to created the 'addr' public key
     /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -119,7 +119,7 @@ library SystemInstruction {
     /// @param from public key for the funding account
     /// @param to public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
+    function transfer(address from, address to, uint64 lamports) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true})
@@ -138,7 +138,7 @@ library SystemInstruction {
     /// @param from_owner owner to use to derive the funding account address
     /// @param to_pubkey the public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
@@ -160,7 +160,7 @@ library SystemInstruction {
     ///
     /// @param pub_key account for which to allocate space
     /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
+    function allocate(address pub_key, uint64 space) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
         ];
@@ -177,7 +177,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param space number of bytes of memory to allocate
     /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -204,7 +204,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
         create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -223,7 +223,7 @@ library SystemInstruction {
     /// @param nonce the public key for the nonce account to be created
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
         create_account(from, nonce, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -240,7 +240,7 @@ library SystemInstruction {
     ///
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
@@ -257,7 +257,7 @@ library SystemInstruction {
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param to_pubkey the recipient account
     /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
         AccountMeta[5] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
@@ -275,7 +275,7 @@ library SystemInstruction {
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
@@ -289,7 +289,7 @@ library SystemInstruction {
     ///
     /// @param nonce the public key for the nonce account
     // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
+    function upgrade_nonce_account(address nonce) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
         ];

+ 4 - 4
basics/rent/solang/solidity/rent.sol

@@ -1,14 +1,14 @@
 
-import "./system_instruction.sol";
-import 'minimum_balance.sol';
+import "../libraries/system_instruction.sol";
+import '../libraries/minimum_balance.sol';
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract rent {
 
     @payer(payer) // The "payer" pays for the data account creation
-    constructor(address payer) {}
+    constructor() {}
 
-    function createSystemAccount(address payer, address newAccount, uint64 space) public view {
+    function createSystemAccount(address payer, address newAccount, uint64 space) public {
         // The minimum lamports required for the amount of space allocated to the account
         uint64 lamports = minimum_balance(space);
 

+ 19 - 19
basics/rent/solang/tests/rent.ts

@@ -1,34 +1,34 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { Rent } from "../target/types/rent"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { Rent } from "../target/types/rent";
 
 describe("rent", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new keypair for the data account for the program
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.Rent as Program<Rent>
+  const program = anchor.workspace.Rent as Program<Rent>;
 
   it("Is initialized!", async () => {
     // Initialize data account for the program, which is required by Solang
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create new account", async () => {
     // Generate a new keypair for the new account
-    const newAccount = anchor.web3.Keypair.generate()
+    const newAccount = anchor.web3.Keypair.generate();
     // Number of bytes of space to allocate for the account
-    const space = 100
+    const space = 100;
 
     // Create a new account via a Cross Program Invocation to the system program
     const tx = await program.methods
@@ -51,7 +51,7 @@ describe("rent", () => {
           isSigner: true,
         },
       ])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
basics/rent/solang/tsconfig.json

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

+ 14 - 14
basics/transfer-sol/solang/solidity/system_instruction.sol → basics/transfer-sol/solang/libraries/system_instruction.sol

@@ -34,7 +34,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: true, is_writable: true})
@@ -54,7 +54,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
@@ -81,7 +81,7 @@ library SystemInstruction {
     ///
     /// @param pubkey the public key for the account whose owner is going to be reassigned
     /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
+    function assign(address pubkey, address owner) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
         ];
@@ -96,7 +96,7 @@ library SystemInstruction {
     /// @param base the base address that derived the 'addr' key using the seed
     /// @param seed the string utilized to created the 'addr' public key
     /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -119,7 +119,7 @@ library SystemInstruction {
     /// @param from public key for the funding account
     /// @param to public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
+    function transfer(address from, address to, uint64 lamports) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true})
@@ -138,7 +138,7 @@ library SystemInstruction {
     /// @param from_owner owner to use to derive the funding account address
     /// @param to_pubkey the public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
@@ -160,7 +160,7 @@ library SystemInstruction {
     ///
     /// @param pub_key account for which to allocate space
     /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
+    function allocate(address pub_key, uint64 space) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
         ];
@@ -177,7 +177,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param space number of bytes of memory to allocate
     /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -204,7 +204,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
         create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -223,7 +223,7 @@ library SystemInstruction {
     /// @param nonce the public key for the nonce account to be created
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
         create_account(from, nonce, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -240,7 +240,7 @@ library SystemInstruction {
     ///
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
@@ -257,7 +257,7 @@ library SystemInstruction {
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param to_pubkey the recipient account
     /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
         AccountMeta[5] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
@@ -275,7 +275,7 @@ library SystemInstruction {
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
@@ -289,7 +289,7 @@ library SystemInstruction {
     ///
     /// @param nonce the public key for the nonce account
     // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
+    function upgrade_nonce_account(address nonce) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
         ];

+ 7 - 6
basics/transfer-sol/solang/solidity/transfer-sol.sol

@@ -1,16 +1,16 @@
 
-import "./system_instruction.sol";
+import "../libraries/system_instruction.sol";
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract transfer_sol {
 
     @payer(payer) // payer to create new data account
-    constructor(address payer) {
+    constructor() {
         // No data is stored in the account in this example
     }
 
     // Transfer SOL from one account to another using CPI (Cross Program Invocation) to the System program
-    function transferSolWithCpi(address from, address to, uint64 lamports) public view {
+    function transferSolWithCpi(address from, address to, uint64 lamports) public {
         // CPI to transfer SOL using "system_instruction" library
         SystemInstruction.transfer(from, to, lamports);
     }
@@ -23,8 +23,9 @@ contract transfer_sol {
 
         print("From: {:}".format(from.key));
         print("To: {:}".format(to.key));
-
-        from.lamports -= lamports;
-        to.lamports += lamports;
+        
+        // // // Not working with Solang 0.3.1
+        // from.lamports -= lamports;
+        // to.lamports += lamports;
     }
 }

+ 37 - 37
basics/transfer-sol/solang/tests/transfer-sol.ts

@@ -1,39 +1,39 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { TransferSol } from "../target/types/transfer_sol"
-import { PublicKey } from "@solana/web3.js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { TransferSol } from "../target/types/transfer_sol";
+import { PublicKey } from "@solana/web3.js";
 
 describe("transfer-sol", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate new keypair to use as data account
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.TransferSol as Program<TransferSol>
+  const program = anchor.workspace.TransferSol as Program<TransferSol>;
 
   // Amount to transfer in lamports
-  const transferAmount = 1 * anchor.web3.LAMPORTS_PER_SOL // 1 SOL
+  const transferAmount = 1 * anchor.web3.LAMPORTS_PER_SOL; // 1 SOL
 
   it("Is initialized!", async () => {
     // Create the new data account
     // The dataAccount is required by Solang even though it is not use in the transfer instruction
     const tx = await program.methods
-      .new(wallet.publicKey) // payer
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Transfer SOL using CPI to the system program", async () => {
     // Generate new keypair to use as recipient for the transfer
-    const recipient = anchor.web3.Keypair.generate() // test1 recipient
+    const recipient = anchor.web3.Keypair.generate(); // test1 recipient
 
-    await getBalances(wallet.publicKey, recipient.publicKey, "Beginning")
+    await getBalances(wallet.publicKey, recipient.publicKey, "Beginning");
 
     const tx = await program.methods
       .transferSolWithCpi(
@@ -54,15 +54,15 @@ describe("transfer-sol", () => {
           isSigner: false,
         },
       ])
-      .rpc()
+      .rpc();
 
-    await getBalances(wallet.publicKey, recipient.publicKey, "Resulting")
+    await getBalances(wallet.publicKey, recipient.publicKey, "Resulting");
 
-    console.log("Your transaction signature", tx)
-  })
+    console.log("Your transaction signature", tx);
+  });
 
   it("Transfer SOL to program owned account", async () => {
-    await getBalances(wallet.publicKey, dataAccount.publicKey, "Beginning")
+    await getBalances(wallet.publicKey, dataAccount.publicKey, "Beginning");
 
     const tx = await program.methods
       .transferSolWithCpi(
@@ -83,15 +83,15 @@ describe("transfer-sol", () => {
           isSigner: false,
         },
       ])
-      .rpc()
+      .rpc();
 
-    await getBalances(wallet.publicKey, dataAccount.publicKey, "Resulting")
+    await getBalances(wallet.publicKey, dataAccount.publicKey, "Resulting");
 
-    console.log("Your transaction signature", tx)
-  })
+    console.log("Your transaction signature", tx);
+  });
 
   it("Transfer SOL from program owned account", async () => {
-    await getBalances(dataAccount.publicKey, wallet.publicKey, "Beginning")
+    await getBalances(dataAccount.publicKey, wallet.publicKey, "Beginning");
 
     const tx = await program.methods
       .transferSolWithProgram(
@@ -105,12 +105,12 @@ describe("transfer-sol", () => {
           isSigner: true,
         },
       ])
-      .rpc()
+      .rpc();
 
-    await getBalances(dataAccount.publicKey, wallet.publicKey, "Resulting")
+    await getBalances(dataAccount.publicKey, wallet.publicKey, "Resulting");
 
-    console.log("Your transaction signature", tx)
-  })
+    console.log("Your transaction signature", tx);
+  });
 
   // Helper function to get balances and log them to the console
   async function getBalances(
@@ -118,12 +118,12 @@ describe("transfer-sol", () => {
     recipientPubkey: PublicKey,
     timeframe: string
   ) {
-    let payerBalance = await connection.getBalance(payerPubkey)
-    let recipientBalance = await connection.getBalance(recipientPubkey)
-    console.log(`${timeframe} balances:`)
-    console.log(`   Payer: ${payerBalance / anchor.web3.LAMPORTS_PER_SOL}`) // convert lamports to SOL
+    let payerBalance = await connection.getBalance(payerPubkey);
+    let recipientBalance = await connection.getBalance(recipientPubkey);
+    console.log(`${timeframe} balances:`);
+    console.log(`   Payer: ${payerBalance / anchor.web3.LAMPORTS_PER_SOL}`); // convert lamports to SOL
     console.log(
       `   Recipient: ${recipientBalance / anchor.web3.LAMPORTS_PER_SOL}` // convert lamports to SOL
-    )
+    );
   }
-})
+});

+ 1 - 1
tokens/nft-minter/solang/solidity/mpl_metadata.sol → tokens/create-token/solang/libraries/mpl_metadata.sol

@@ -77,7 +77,7 @@ library MplMetadata {
 		string name,
 		string symbol,
 		string uri
-	) public view {
+	) public {
         // // Example of how to add a Creator[] array to the DataV2 struct
 		// Creator[] memory creators = new Creator[](1);
         // creators[0] = Creator({

+ 10 - 10
tokens/nft-minter/solang/solidity/spl_token.sol → tokens/create-token/solang/libraries/spl_token.sol

@@ -45,7 +45,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-	function initialize_account(address tokenAccount, address mint, address owner) internal view{
+	function initialize_account(address tokenAccount, address mint, address owner) internal{
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.InitializeAccount);
@@ -65,7 +65,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal view {
+    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal {
         AccountMeta[6] metas = [
 			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
 			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
@@ -94,7 +94,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
     	InitializeMintInstruction instr = InitializeMintInstruction({
             instruction: 20,
             decimals: decimals,
@@ -117,7 +117,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
 		// Invoke System Program to create a new account for the mint account
         // Program owner is set to the Token program
         SystemInstruction.create_account(
@@ -149,7 +149,7 @@ library SplToken {
 	/// @param account the token account where the minted tokens should go
 	/// @param authority the public key of the mint authority
 	/// @param amount the amount of tokens to mint
-	function mint_to(address mint, address account, address authority, uint64 amount) internal view {
+	function mint_to(address mint, address account, address authority, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.MintTo);
@@ -171,7 +171,7 @@ library SplToken {
 	/// @param to the account to transfer tokens to
 	/// @param owner the publickey of the from account owner keypair
 	/// @param amount the amount to transfer
-	function transfer(address from, address to, address owner, uint64 amount) internal view {
+	function transfer(address from, address to, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Transfer);
@@ -192,7 +192,7 @@ library SplToken {
 	/// @param mint the mint for this token
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to transfer
-	function burn(address account, address mint, address owner, uint64 amount) internal view {
+	function burn(address account, address mint, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Burn);
@@ -213,7 +213,7 @@ library SplToken {
 	/// @param delegate the delegate publickey
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to approve
-	function approve(address account, address delegate, address owner, uint64 amount) internal view {
+	function approve(address account, address delegate, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Approve);
@@ -233,7 +233,7 @@ library SplToken {
 	///
 	/// @param account the account for which a delegate should be approved
 	/// @param owner the publickey of the account owner keypair
-	function revoke(address account, address owner) internal view {
+	function revoke(address account, address owner) internal {
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.Revoke);
@@ -371,7 +371,7 @@ library SplToken {
 	///
 	/// @param mintAccount the public key for the mint account
 	/// @param mintAuthority the public for the mint authority
-	function remove_mint_authority(address mintAccount, address mintAuthority) public view {
+	function remove_mint_authority(address mintAccount, address mintAuthority) public {
 		AccountMeta[2] metas = [
 			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
 			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})

+ 14 - 14
tokens/create-token/solang/solidity/system_instruction.sol → tokens/create-token/solang/libraries/system_instruction.sol

@@ -34,7 +34,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: true, is_writable: true})
@@ -54,7 +54,7 @@ library SystemInstruction {
     /// @param lamports amount of lamports to be transfered to the new account
     /// @param space the size in bytes that is going to be made available for the account
     /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
@@ -81,7 +81,7 @@ library SystemInstruction {
     ///
     /// @param pubkey the public key for the account whose owner is going to be reassigned
     /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
+    function assign(address pubkey, address owner) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
         ];
@@ -96,7 +96,7 @@ library SystemInstruction {
     /// @param base the base address that derived the 'addr' key using the seed
     /// @param seed the string utilized to created the 'addr' public key
     /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -119,7 +119,7 @@ library SystemInstruction {
     /// @param from public key for the funding account
     /// @param to public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
+    function transfer(address from, address to, uint64 lamports) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
             AccountMeta({pubkey: to, is_signer: false, is_writable: true})
@@ -138,7 +138,7 @@ library SystemInstruction {
     /// @param from_owner owner to use to derive the funding account address
     /// @param to_pubkey the public key for the recipient account
     /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
@@ -160,7 +160,7 @@ library SystemInstruction {
     ///
     /// @param pub_key account for which to allocate space
     /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
+    function allocate(address pub_key, uint64 space) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
         ];
@@ -177,7 +177,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param space number of bytes of memory to allocate
     /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: base, is_signer: true, is_writable: false})
@@ -204,7 +204,7 @@ library SystemInstruction {
     /// @param seed the string utilized to create the 'addr' public key
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
         create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -223,7 +223,7 @@ library SystemInstruction {
     /// @param nonce the public key for the nonce account to be created
     /// @param authority The entity authorized to execute nonce instructions on the account
     /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
         create_account(from, nonce, lamports, state_size, systemAddress);
 
         AccountMeta[3] metas = [
@@ -240,7 +240,7 @@ library SystemInstruction {
     ///
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
         AccountMeta[3] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
@@ -257,7 +257,7 @@ library SystemInstruction {
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param to_pubkey the recipient account
     /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
         AccountMeta[5] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
@@ -275,7 +275,7 @@ library SystemInstruction {
     /// @param nonce_pubkey the public key for the nonce account
     /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
     /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
         AccountMeta[2] metas = [
             AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
             AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
@@ -289,7 +289,7 @@ library SystemInstruction {
     ///
     /// @param nonce the public key for the nonce account
     // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
+    function upgrade_nonce_account(address nonce) internal {
         AccountMeta[1] meta = [
             AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
         ];

+ 2 - 1
tokens/create-token/solang/package.json

@@ -5,7 +5,8 @@
     },
     "dependencies": {
         "@coral-xyz/anchor": "^0.28.0",
-        "@metaplex-foundation/js": "^0.19.4"
+        "@metaplex-foundation/js": "^0.19.4",
+        "@project-serum/anchor": "^0.26.0"
     },
     "devDependencies": {
         "@types/bn.js": "^5.1.0",

+ 4 - 4
tokens/create-token/solang/solidity/create-token.sol

@@ -1,6 +1,6 @@
 
-import "./spl_token.sol";
-import "./mpl_metadata.sol";
+import "../libraries/spl_token.sol";
+import "../libraries/mpl_metadata.sol";
 
 @program_id("8eZPhSaXfHqbcrfskVThtCG68kq8MfVHqmtm6wYf4TLb")
 contract create_token {
@@ -8,7 +8,7 @@ contract create_token {
     // Creating a dataAccount is required by Solang
     // The account is unused in this example
     @payer(payer) // payer account
-    constructor(address payer) {}
+    constructor() {}
 
     function createTokenMint(
         address payer, // payer account
@@ -20,7 +20,7 @@ contract create_token {
         string name, // name for the metadata account
         string symbol, // symbol for the metadata account
         string uri // uri for the metadata account
-    ) public view {
+    ) public {
         // Invoke System Program to create a new account for the mint account and,
         // Invoke Token Program to initialize the mint account
         // Set mint authority, freeze authority, and decimals for the mint account

+ 31 - 31
tokens/create-token/solang/tests/create-token.ts

@@ -1,45 +1,45 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { CreateToken } from "../target/types/create_token"
-import { Metaplex } from "@metaplex-foundation/js"
-import { SYSVAR_RENT_PUBKEY, SystemProgram, PublicKey } from "@solana/web3.js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { CreateToken } from "../target/types/create_token";
+import { Metaplex } from "@metaplex-foundation/js";
+import { SYSVAR_RENT_PUBKEY, SystemProgram, PublicKey } from "@solana/web3.js";
 
 describe("create-token", () => {
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
-  const program = anchor.workspace.CreateToken as Program<CreateToken>
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
+  const program = anchor.workspace.CreateToken as Program<CreateToken>;
 
   // Generate new keypair to use as data account
-  const dataAccount = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const dataAccount = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
   // Metadata for the token
-  const tokenTitle = "Solana Gold"
-  const tokenSymbol = "GOLDSOL"
+  const tokenTitle = "Solana Gold";
+  const tokenSymbol = "GOLDSOL";
   const tokenUri =
-    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json"
+    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json";
 
   it("Is initialized!", async () => {
     // Initialize data account for the program, which is required by Solang
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an SPL Token!", async () => {
     // Generate a new keypair for the mint
-    const mintKeypair = anchor.web3.Keypair.generate()
+    const mintKeypair = anchor.web3.Keypair.generate();
 
     // Get the metadata address for the mint
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     const tx = await program.methods
       .createTokenMint(
@@ -71,20 +71,20 @@ describe("create-token", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an NFT!", async () => {
     // Generate a new keypair for the mint
-    const mintKeypair = anchor.web3.Keypair.generate()
+    const mintKeypair = anchor.web3.Keypair.generate();
 
     // Get the metadata address for the mint
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     const tx = await program.methods
       .createTokenMint(
@@ -116,7 +116,7 @@ describe("create-token", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
tokens/create-token/solang/tsconfig.json

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

+ 1 - 1
tokens/pda-mint-authority/solang/solidity/mpl_metadata.sol → tokens/nft-minter/solang/libraries/mpl_metadata.sol

@@ -77,7 +77,7 @@ library MplMetadata {
 		string name,
 		string symbol,
 		string uri
-	) public view {
+	) public {
         // // Example of how to add a Creator[] array to the DataV2 struct
 		// Creator[] memory creators = new Creator[](1);
         // creators[0] = Creator({

+ 10 - 10
tokens/pda-mint-authority/solang/solidity/spl_token.sol → tokens/nft-minter/solang/libraries/spl_token.sol

@@ -45,7 +45,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-	function initialize_account(address tokenAccount, address mint, address owner) internal view{
+	function initialize_account(address tokenAccount, address mint, address owner) internal{
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.InitializeAccount);
@@ -65,7 +65,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal view {
+    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal {
         AccountMeta[6] metas = [
 			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
 			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
@@ -94,7 +94,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
     	InitializeMintInstruction instr = InitializeMintInstruction({
             instruction: 20,
             decimals: decimals,
@@ -117,7 +117,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
 		// Invoke System Program to create a new account for the mint account
         // Program owner is set to the Token program
         SystemInstruction.create_account(
@@ -149,7 +149,7 @@ library SplToken {
 	/// @param account the token account where the minted tokens should go
 	/// @param authority the public key of the mint authority
 	/// @param amount the amount of tokens to mint
-	function mint_to(address mint, address account, address authority, uint64 amount) internal view {
+	function mint_to(address mint, address account, address authority, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.MintTo);
@@ -171,7 +171,7 @@ library SplToken {
 	/// @param to the account to transfer tokens to
 	/// @param owner the publickey of the from account owner keypair
 	/// @param amount the amount to transfer
-	function transfer(address from, address to, address owner, uint64 amount) internal view {
+	function transfer(address from, address to, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Transfer);
@@ -192,7 +192,7 @@ library SplToken {
 	/// @param mint the mint for this token
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to transfer
-	function burn(address account, address mint, address owner, uint64 amount) internal view {
+	function burn(address account, address mint, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Burn);
@@ -213,7 +213,7 @@ library SplToken {
 	/// @param delegate the delegate publickey
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to approve
-	function approve(address account, address delegate, address owner, uint64 amount) internal view {
+	function approve(address account, address delegate, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Approve);
@@ -233,7 +233,7 @@ library SplToken {
 	///
 	/// @param account the account for which a delegate should be approved
 	/// @param owner the publickey of the account owner keypair
-	function revoke(address account, address owner) internal view {
+	function revoke(address account, address owner) internal {
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.Revoke);
@@ -371,7 +371,7 @@ library SplToken {
 	///
 	/// @param mintAccount the public key for the mint account
 	/// @param mintAuthority the public for the mint authority
-	function remove_mint_authority(address mintAccount, address mintAuthority) public view {
+	function remove_mint_authority(address mintAccount, address mintAuthority) public {
 		AccountMeta[2] metas = [
 			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
 			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})

+ 300 - 0
tokens/nft-minter/solang/libraries/system_instruction.sol

@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: Apache-2.0
+
+// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
+// it has not been audited for security, so use it at your own risk.
+
+import 'solana';
+
+library SystemInstruction {
+    address constant systemAddress = address"11111111111111111111111111111111";
+    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
+    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+    uint64 constant state_size = 80;
+
+    enum Instruction {
+        CreateAccount,
+        Assign,
+        Transfer,
+        CreateAccountWithSeed,
+        AdvanceNounceAccount,
+        WithdrawNonceAccount,
+        InitializeNonceAccount,
+        AuthorizeNonceAccount,
+        Allocate,
+        AllocateWithSeed,
+        AssignWithSeed,
+        TransferWithSeed,
+        UpgradeNonceAccount // This is not available on Solana v1.9.15
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to public key for the account to be created
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'to' address using the seed
+    /// @param seed the string utilized to created the 'to' public key
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        uint32 buffer_size = 92 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = seed.length + 44;
+        bincode.writeUint64LE(lamports, offset);
+        offset += 8;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Assign account to a program (owner)
+    ///
+    /// @param pubkey the public key for the account whose owner is going to be reassigned
+    /// @param owner the public key for the new account owner
+    function assign(address pubkey, address owner) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
+        ];
+        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Assign account to a program (owner) based on a seed
+    ///
+    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to created the 'addr' public key
+    /// @param owner the public key for the new program owner
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+
+        uint32 buffer_size = 76 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        bincode.writeAddress(owner, 44 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports between accounts
+    ///
+    /// @param from public key for the funding account
+    /// @param to public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer(address from, address to, uint64 lamports) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports from a derived address
+    ///
+    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
+    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
+    /// @param seed the string utilized to create the 'from_pubkey' public key
+    /// @param from_owner owner to use to derive the funding account address
+    /// @param to_pubkey the public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
+        ];
+
+        uint32 buffer_size = seed.length + 52;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
+        bincode.writeUint64LE(lamports, 4);
+        bincode.writeUint64LE(seed.length, 12);
+        bincode.writeString(seed, 20);
+        bincode.writeAddress(from_owner, 20 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Allocate space in a (possibly new) account without funding
+    ///
+    /// @param pub_key account for which to allocate space
+    /// @param space number of bytes of memory to allocate
+    function allocate(address pub_key, uint64 space) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Allocate space for an assign an account at an address derived from a base public key and a seed
+    ///
+    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param space number of bytes of memory to allocate
+    /// @param owner owner to use to derive the 'addr' account address
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = new bytes(seed.length + 84);
+        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(seed.length, 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = 44 + seed.length;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new nonce account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
+    /// @param base the base address that derived the 'nonce' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
+        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the nonce account to be created
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
+        create_account(from, nonce, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Consumes a stored nonce, replacing it with a successor
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Withdraw funds from a nonce account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param to_pubkey the recipient account
+    /// @param lamports the number of lamports to withdraw
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[5] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Change the entity authorized to execute nonce instructions on the account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param new_authority
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
+    ///
+    /// @param nonce the public key for the nonce account
+    // This is not available on Solana v1.9.15
+    function upgrade_nonce_account(address nonce) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
+        systemAddress.call{accounts: meta}(bincode);
+    }
+}

+ 1 - 0
tokens/nft-minter/solang/package.json

@@ -6,6 +6,7 @@
     "dependencies": {
         "@coral-xyz/anchor": "^0.28.0",
         "@metaplex-foundation/js": "^0.19.4",
+        "@project-serum/anchor": "^0.26.0",
         "@solana/spl-token": "^0.3.8"
     },
     "devDependencies": {

+ 5 - 5
tokens/nft-minter/solang/solidity/nft-minter.sol

@@ -1,12 +1,12 @@
 
-import "./spl_token.sol";
-import "./mpl_metadata.sol";
+import "../libraries/spl_token.sol";
+import "../libraries/mpl_metadata.sol";
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract nft_minter {
 
     @payer(payer)
-    constructor(address payer) {}
+    constructor() {}
 
     function createTokenMint(
         address payer, // payer account
@@ -18,7 +18,7 @@ contract nft_minter {
         string name, // name for the metadata account
         string symbol, // symbol for the metadata account
         string uri // uri for the metadata account
-    ) public view {
+    ) public {
         // Invoke System Program to create a new account for the mint account and,
         // Invoke Token Program to initialize the mint account
         // Set mint authority, freeze authority, and decimals for the mint account
@@ -43,7 +43,7 @@ contract nft_minter {
         );
     }
 
-    function mintTo(address payer, address tokenAccount, address mint, address owner) public view {
+    function mintTo(address payer, address tokenAccount, address mint, address owner) public {
         // Create an associated token account for the owner to receive the minted token
         SplToken.create_associated_token_account(
             payer, // payer account

+ 0 - 300
tokens/nft-minter/solang/solidity/system_instruction.sol

@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
-// it has not been audited for security, so use it at your own risk.
-
-import 'solana';
-
-library SystemInstruction {
-    address constant systemAddress = address"11111111111111111111111111111111";
-    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
-    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-    uint64 constant state_size = 80;
-
-    enum Instruction {
-        CreateAccount,
-        Assign,
-        Transfer,
-        CreateAccountWithSeed,
-        AdvanceNounceAccount,
-        WithdrawNonceAccount,
-        InitializeNonceAccount,
-        AuthorizeNonceAccount,
-        Allocate,
-        AllocateWithSeed,
-        AssignWithSeed,
-        TransferWithSeed,
-        UpgradeNonceAccount // This is not available on Solana v1.9.15
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to public key for the account to be created
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'to' address using the seed
-    /// @param seed the string utilized to created the 'to' public key
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        uint32 buffer_size = 92 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = seed.length + 44;
-        bincode.writeUint64LE(lamports, offset);
-        offset += 8;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Assign account to a program (owner)
-    ///
-    /// @param pubkey the public key for the account whose owner is going to be reassigned
-    /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
-        ];
-        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Assign account to a program (owner) based on a seed
-    ///
-    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to created the 'addr' public key
-    /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-
-        uint32 buffer_size = 76 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        bincode.writeAddress(owner, 44 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports between accounts
-    ///
-    /// @param from public key for the funding account
-    /// @param to public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports from a derived address
-    ///
-    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
-    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
-    /// @param seed the string utilized to create the 'from_pubkey' public key
-    /// @param from_owner owner to use to derive the funding account address
-    /// @param to_pubkey the public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
-        ];
-
-        uint32 buffer_size = seed.length + 52;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
-        bincode.writeUint64LE(lamports, 4);
-        bincode.writeUint64LE(seed.length, 12);
-        bincode.writeString(seed, 20);
-        bincode.writeAddress(from_owner, 20 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Allocate space in a (possibly new) account without funding
-    ///
-    /// @param pub_key account for which to allocate space
-    /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Allocate space for an assign an account at an address derived from a base public key and a seed
-    ///
-    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param space number of bytes of memory to allocate
-    /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = new bytes(seed.length + 84);
-        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(seed.length, 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = 44 + seed.length;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new nonce account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
-    /// @param base the base address that derived the 'nonce' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
-        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the nonce account to be created
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
-        create_account(from, nonce, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Consumes a stored nonce, replacing it with a successor
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Withdraw funds from a nonce account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param to_pubkey the recipient account
-    /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[5] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Change the entity authorized to execute nonce instructions on the account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
-    ///
-    /// @param nonce the public key for the nonce account
-    // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
-        systemAddress.call{accounts: meta}(bincode);
-    }
-}

+ 30 - 30
tokens/nft-minter/solang/tests/nft-minter.ts

@@ -1,52 +1,52 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { NftMinter } from "../target/types/nft_minter"
-import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js"
-import { Metaplex } from "@metaplex-foundation/js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { NftMinter } from "../target/types/nft_minter";
+import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
+import { Metaplex } from "@metaplex-foundation/js";
 import {
   ASSOCIATED_TOKEN_PROGRAM_ID,
   getAssociatedTokenAddressSync,
   TOKEN_PROGRAM_ID,
-} from "@solana/spl-token"
+} from "@solana/spl-token";
 
 describe("nft-minter", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new keypair for the data account for the program
-  const dataAccount = anchor.web3.Keypair.generate()
+  const dataAccount = anchor.web3.Keypair.generate();
 
   // Generate a mint keypair
-  const mintKeypair = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const mintKeypair = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.NftMinter as Program<NftMinter>
+  const program = anchor.workspace.NftMinter as Program<NftMinter>;
 
   // Metadata for the NFT
-  const nftTitle = "Homer NFT"
-  const nftSymbol = "HOMR"
+  const nftTitle = "Homer NFT";
+  const nftSymbol = "HOMR";
   const nftUri =
-    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json"
+    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json";
 
   it("Is initialized!", async () => {
     // Initialize data account for the program, which is required by Solang
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an NFT!", async () => {
     // Get the metadata address for the mint
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     const tx = await program.methods
       .createTokenMint(
@@ -78,16 +78,16 @@ describe("nft-minter", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Mint the NFT to your wallet!", async () => {
     // Derive wallet's associated token account address for mint
     const tokenAccount = getAssociatedTokenAddressSync(
       mintKeypair.publicKey,
       wallet.publicKey
-    )
+    );
 
     const tx = await program.methods
       .mintTo(
@@ -117,7 +117,7 @@ describe("nft-minter", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
+});

+ 1 - 1
tokens/spl-token-minter/solang/solidity/mpl_metadata.sol → tokens/pda-mint-authority/solang/libraries/mpl_metadata.sol

@@ -77,7 +77,7 @@ library MplMetadata {
 		string name,
 		string symbol,
 		string uri
-	) public view {
+	) public {
         // // Example of how to add a Creator[] array to the DataV2 struct
 		// Creator[] memory creators = new Creator[](1);
         // creators[0] = Creator({

+ 10 - 10
tokens/spl-token-minter/solang/solidity/spl_token.sol → tokens/pda-mint-authority/solang/libraries/spl_token.sol

@@ -45,7 +45,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-	function initialize_account(address tokenAccount, address mint, address owner) internal view{
+	function initialize_account(address tokenAccount, address mint, address owner) internal{
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.InitializeAccount);
@@ -65,7 +65,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal view {
+    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal {
         AccountMeta[6] metas = [
 			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
 			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
@@ -94,7 +94,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
     	InitializeMintInstruction instr = InitializeMintInstruction({
             instruction: 20,
             decimals: decimals,
@@ -117,7 +117,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
 		// Invoke System Program to create a new account for the mint account
         // Program owner is set to the Token program
         SystemInstruction.create_account(
@@ -149,7 +149,7 @@ library SplToken {
 	/// @param account the token account where the minted tokens should go
 	/// @param authority the public key of the mint authority
 	/// @param amount the amount of tokens to mint
-	function mint_to(address mint, address account, address authority, uint64 amount) internal view {
+	function mint_to(address mint, address account, address authority, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.MintTo);
@@ -171,7 +171,7 @@ library SplToken {
 	/// @param to the account to transfer tokens to
 	/// @param owner the publickey of the from account owner keypair
 	/// @param amount the amount to transfer
-	function transfer(address from, address to, address owner, uint64 amount) internal view {
+	function transfer(address from, address to, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Transfer);
@@ -192,7 +192,7 @@ library SplToken {
 	/// @param mint the mint for this token
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to transfer
-	function burn(address account, address mint, address owner, uint64 amount) internal view {
+	function burn(address account, address mint, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Burn);
@@ -213,7 +213,7 @@ library SplToken {
 	/// @param delegate the delegate publickey
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to approve
-	function approve(address account, address delegate, address owner, uint64 amount) internal view {
+	function approve(address account, address delegate, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Approve);
@@ -233,7 +233,7 @@ library SplToken {
 	///
 	/// @param account the account for which a delegate should be approved
 	/// @param owner the publickey of the account owner keypair
-	function revoke(address account, address owner) internal view {
+	function revoke(address account, address owner) internal {
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.Revoke);
@@ -371,7 +371,7 @@ library SplToken {
 	///
 	/// @param mintAccount the public key for the mint account
 	/// @param mintAuthority the public for the mint authority
-	function remove_mint_authority(address mintAccount, address mintAuthority) public view {
+	function remove_mint_authority(address mintAccount, address mintAuthority) public {
 		AccountMeta[2] metas = [
 			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
 			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})

+ 300 - 0
tokens/pda-mint-authority/solang/libraries/system_instruction.sol

@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: Apache-2.0
+
+// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
+// it has not been audited for security, so use it at your own risk.
+
+import 'solana';
+
+library SystemInstruction {
+    address constant systemAddress = address"11111111111111111111111111111111";
+    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
+    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+    uint64 constant state_size = 80;
+
+    enum Instruction {
+        CreateAccount,
+        Assign,
+        Transfer,
+        CreateAccountWithSeed,
+        AdvanceNounceAccount,
+        WithdrawNonceAccount,
+        InitializeNonceAccount,
+        AuthorizeNonceAccount,
+        Allocate,
+        AllocateWithSeed,
+        AssignWithSeed,
+        TransferWithSeed,
+        UpgradeNonceAccount // This is not available on Solana v1.9.15
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to public key for the account to be created
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'to' address using the seed
+    /// @param seed the string utilized to created the 'to' public key
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        uint32 buffer_size = 92 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = seed.length + 44;
+        bincode.writeUint64LE(lamports, offset);
+        offset += 8;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Assign account to a program (owner)
+    ///
+    /// @param pubkey the public key for the account whose owner is going to be reassigned
+    /// @param owner the public key for the new account owner
+    function assign(address pubkey, address owner) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
+        ];
+        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Assign account to a program (owner) based on a seed
+    ///
+    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to created the 'addr' public key
+    /// @param owner the public key for the new program owner
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+
+        uint32 buffer_size = 76 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        bincode.writeAddress(owner, 44 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports between accounts
+    ///
+    /// @param from public key for the funding account
+    /// @param to public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer(address from, address to, uint64 lamports) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports from a derived address
+    ///
+    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
+    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
+    /// @param seed the string utilized to create the 'from_pubkey' public key
+    /// @param from_owner owner to use to derive the funding account address
+    /// @param to_pubkey the public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
+        ];
+
+        uint32 buffer_size = seed.length + 52;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
+        bincode.writeUint64LE(lamports, 4);
+        bincode.writeUint64LE(seed.length, 12);
+        bincode.writeString(seed, 20);
+        bincode.writeAddress(from_owner, 20 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Allocate space in a (possibly new) account without funding
+    ///
+    /// @param pub_key account for which to allocate space
+    /// @param space number of bytes of memory to allocate
+    function allocate(address pub_key, uint64 space) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Allocate space for an assign an account at an address derived from a base public key and a seed
+    ///
+    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param space number of bytes of memory to allocate
+    /// @param owner owner to use to derive the 'addr' account address
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = new bytes(seed.length + 84);
+        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(seed.length, 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = 44 + seed.length;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new nonce account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
+    /// @param base the base address that derived the 'nonce' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
+        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the nonce account to be created
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
+        create_account(from, nonce, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Consumes a stored nonce, replacing it with a successor
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Withdraw funds from a nonce account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param to_pubkey the recipient account
+    /// @param lamports the number of lamports to withdraw
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[5] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Change the entity authorized to execute nonce instructions on the account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param new_authority
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
+    ///
+    /// @param nonce the public key for the nonce account
+    // This is not available on Solana v1.9.15
+    function upgrade_nonce_account(address nonce) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
+        systemAddress.call{accounts: meta}(bincode);
+    }
+}

+ 1 - 0
tokens/pda-mint-authority/solang/package.json

@@ -6,6 +6,7 @@
     "dependencies": {
         "@coral-xyz/anchor": "^0.28.0",
         "@metaplex-foundation/js": "^0.19.4",
+        "@project-serum/anchor": "^0.26.0",
         "@solana/spl-token": "^0.3.8"
     },
     "devDependencies": {

+ 10 - 9
tokens/pda-mint-authority/solang/solidity/pda-mint-authority.sol

@@ -1,5 +1,5 @@
 
-import "./spl_token.sol";
+import "../libraries/spl_token.sol";
 import "solana";
 
 @program_id("J2eUKE878XKXJZaP7vXwxgWnWnNQMqHSkMPoRFQwa86b")
@@ -8,8 +8,9 @@ contract pda_mint_authority {
 
     @payer(payer)
     @seed("mint_authority") // hard-coded seed
-    @bump(_bump) // bump for the pda address
-    constructor(address payer, bytes1 _bump) {
+    constructor(
+        @bump bytes1 _bump  // bump for the pda address
+    ) {
         // Independently derive the PDA address from the seeds, bump, and programId
         (address pda, bytes1 pdaBump) = try_find_program_address(["mint_authority"], type(pda_mint_authority).program_id);
 
@@ -30,7 +31,7 @@ contract pda_mint_authority {
         string name, // name for the metadata account
         string symbol, // symbol for the metadata account
         string uri // uri for the metadata account
-    ) public view {
+    ) public {
         // Invoke System Program to create a new account for the mint account and,
         // Invoke Token Program to initialize the mint account
         // Set mint authority, freeze authority, and decimals for the mint account
@@ -65,7 +66,7 @@ contract pda_mint_authority {
 		string name, // token name
 		string symbol, // token symbol
 		string uri // token uri
-    ) private view {
+    ) private {
         // // Independently derive the PDA address from the seeds, bump, and programId
         (address pda, bytes1 _bump) = try_find_program_address(["mint_authority"], type(pda_mint_authority).program_id);
 
@@ -119,7 +120,7 @@ contract pda_mint_authority {
         bool usesPresent; // To handle Rust Option<> in Solidity
     }
 
-    function mintTo(address payer, address tokenAccount, address mint, address owner) public view {
+    function mintTo(address payer, address tokenAccount, address mint, address owner) public {
         // Create an associated token account for the owner to receive the minted token
         SplToken.create_associated_token_account(
             payer, // payer account
@@ -142,7 +143,7 @@ contract pda_mint_authority {
     }
 
     // Invoke the token program to mint tokens to a token account, using a PDA as the mint authority
-    function _mintTo(address mint, address account, uint64 amount) private view {
+    function _mintTo(address mint, address account, uint64 amount) private {
         // Independently derive the PDA address from the seeds, bump, and programId
         (address pda, bytes1 _bump) = try_find_program_address(["mint_authority"], type(pda_mint_authority).program_id);
         require(address(this) == pda, 'INVALID_PDA');
@@ -150,7 +151,7 @@ contract pda_mint_authority {
         // Prepare instruction data
         bytes instructionData = new bytes(9);
         instructionData[0] = uint8(7); // MintTo instruction index
-        instructionData.writeUint64LE(1, 1); // Amount to mint
+        instructionData.writeUint64LE(amount, 1); // Amount to mint
 
         // Prepare accounts required by instruction
         AccountMeta[3] metas = [
@@ -163,7 +164,7 @@ contract pda_mint_authority {
         SplToken.tokenProgramId.call{accounts: metas, seeds: [["mint_authority", abi.encode(_bump)]]}(instructionData);
     }
 
-    function _removeMintAuthority(address mintAccount) private view {
+    function _removeMintAuthority(address mintAccount) private {
         // Independently derive the PDA address from the seeds, bump, and programId
         (address pda, bytes1 _bump) = try_find_program_address(["mint_authority"], type(pda_mint_authority).program_id);
         require(address(this) == pda, 'INVALID_PDA');

+ 0 - 300
tokens/pda-mint-authority/solang/solidity/system_instruction.sol

@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
-// it has not been audited for security, so use it at your own risk.
-
-import 'solana';
-
-library SystemInstruction {
-    address constant systemAddress = address"11111111111111111111111111111111";
-    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
-    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-    uint64 constant state_size = 80;
-
-    enum Instruction {
-        CreateAccount,
-        Assign,
-        Transfer,
-        CreateAccountWithSeed,
-        AdvanceNounceAccount,
-        WithdrawNonceAccount,
-        InitializeNonceAccount,
-        AuthorizeNonceAccount,
-        Allocate,
-        AllocateWithSeed,
-        AssignWithSeed,
-        TransferWithSeed,
-        UpgradeNonceAccount // This is not available on Solana v1.9.15
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to public key for the account to be created
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'to' address using the seed
-    /// @param seed the string utilized to created the 'to' public key
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        uint32 buffer_size = 92 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = seed.length + 44;
-        bincode.writeUint64LE(lamports, offset);
-        offset += 8;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Assign account to a program (owner)
-    ///
-    /// @param pubkey the public key for the account whose owner is going to be reassigned
-    /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
-        ];
-        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Assign account to a program (owner) based on a seed
-    ///
-    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to created the 'addr' public key
-    /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-
-        uint32 buffer_size = 76 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        bincode.writeAddress(owner, 44 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports between accounts
-    ///
-    /// @param from public key for the funding account
-    /// @param to public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports from a derived address
-    ///
-    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
-    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
-    /// @param seed the string utilized to create the 'from_pubkey' public key
-    /// @param from_owner owner to use to derive the funding account address
-    /// @param to_pubkey the public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
-        ];
-
-        uint32 buffer_size = seed.length + 52;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
-        bincode.writeUint64LE(lamports, 4);
-        bincode.writeUint64LE(seed.length, 12);
-        bincode.writeString(seed, 20);
-        bincode.writeAddress(from_owner, 20 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Allocate space in a (possibly new) account without funding
-    ///
-    /// @param pub_key account for which to allocate space
-    /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Allocate space for an assign an account at an address derived from a base public key and a seed
-    ///
-    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param space number of bytes of memory to allocate
-    /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = new bytes(seed.length + 84);
-        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(seed.length, 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = 44 + seed.length;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new nonce account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
-    /// @param base the base address that derived the 'nonce' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
-        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the nonce account to be created
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
-        create_account(from, nonce, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Consumes a stored nonce, replacing it with a successor
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Withdraw funds from a nonce account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param to_pubkey the recipient account
-    /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[5] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Change the entity authorized to execute nonce instructions on the account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
-    ///
-    /// @param nonce the public key for the nonce account
-    // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
-        systemAddress.call{accounts: meta}(bincode);
-    }
-}

+ 31 - 30
tokens/pda-mint-authority/solang/tests/pda-mint-authority.ts

@@ -1,51 +1,52 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { PdaMintAuthority } from "../target/types/pda_mint_authority"
-import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js"
-import { Metaplex } from "@metaplex-foundation/js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { PdaMintAuthority } from "../target/types/pda_mint_authority";
+import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
+import { Metaplex } from "@metaplex-foundation/js";
 import {
   ASSOCIATED_TOKEN_PROGRAM_ID,
   getAssociatedTokenAddressSync,
   TOKEN_PROGRAM_ID,
-} from "@solana/spl-token"
+} from "@solana/spl-token";
 
 describe("pda-mint-authority", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
-  const mintKeypair = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet
-  const connection = provider.connection
+  const mintKeypair = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.PdaMintAuthority as Program<PdaMintAuthority>
+  const program = anchor.workspace
+    .PdaMintAuthority as Program<PdaMintAuthority>;
 
   // Derive the PDA that will be used to initialize the dataAccount.
   const [dataAccountPDA, bump] = PublicKey.findProgramAddressSync(
     [Buffer.from("mint_authority")],
     program.programId
-  )
+  );
 
-  const nftTitle = "Homer NFT"
-  const nftSymbol = "HOMR"
+  const nftTitle = "Homer NFT";
+  const nftSymbol = "HOMR";
   const nftUri =
-    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json"
+    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json";
 
   it("Is initialized!", async () => {
     // Add your test here.
     const tx = await program.methods
-      .new(wallet.publicKey, [bump])
+      .new([bump])
       .accounts({ dataAccount: dataAccountPDA })
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an NFT!", async () => {
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     // Add your test here.
     const tx = await program.methods
@@ -78,16 +79,16 @@ describe("pda-mint-authority", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Mint the NFT to your wallet!", async () => {
     // Derive wallet's associated token account address for mint
     const tokenAccount = getAssociatedTokenAddressSync(
       mintKeypair.publicKey,
       wallet.publicKey
-    )
+    );
 
     const tx = await program.methods
       .mintTo(
@@ -118,7 +119,7 @@ describe("pda-mint-authority", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
tokens/pda-mint-authority/solang/tsconfig.json

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

+ 1 - 1
tokens/create-token/solang/solidity/mpl_metadata.sol → tokens/spl-token-minter/solang/libraries/mpl_metadata.sol

@@ -77,7 +77,7 @@ library MplMetadata {
 		string name,
 		string symbol,
 		string uri
-	) public view {
+	) public {
         // // Example of how to add a Creator[] array to the DataV2 struct
 		// Creator[] memory creators = new Creator[](1);
         // creators[0] = Creator({

+ 10 - 10
tokens/create-token/solang/solidity/spl_token.sol → tokens/spl-token-minter/solang/libraries/spl_token.sol

@@ -45,7 +45,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-	function initialize_account(address tokenAccount, address mint, address owner) internal view{
+	function initialize_account(address tokenAccount, address mint, address owner) internal{
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.InitializeAccount);
@@ -65,7 +65,7 @@ library SplToken {
 	/// @param tokenAccount the public key of the token account to initialize
 	/// @param mint the public key of the mint account for this new token account
 	/// @param owner the public key of the owner of this new token account
-    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal view {
+    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal {
         AccountMeta[6] metas = [
 			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
 			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
@@ -94,7 +94,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
     	InitializeMintInstruction instr = InitializeMintInstruction({
             instruction: 20,
             decimals: decimals,
@@ -117,7 +117,7 @@ library SplToken {
 	/// @param mintAuthority the public key of the mint authority
 	/// @param freezeAuthority the public key of the freeze authority
 	/// @param decimals the decimals of the mint
-	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
+	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
 		// Invoke System Program to create a new account for the mint account
         // Program owner is set to the Token program
         SystemInstruction.create_account(
@@ -149,7 +149,7 @@ library SplToken {
 	/// @param account the token account where the minted tokens should go
 	/// @param authority the public key of the mint authority
 	/// @param amount the amount of tokens to mint
-	function mint_to(address mint, address account, address authority, uint64 amount) internal view {
+	function mint_to(address mint, address account, address authority, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.MintTo);
@@ -171,7 +171,7 @@ library SplToken {
 	/// @param to the account to transfer tokens to
 	/// @param owner the publickey of the from account owner keypair
 	/// @param amount the amount to transfer
-	function transfer(address from, address to, address owner, uint64 amount) internal view {
+	function transfer(address from, address to, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Transfer);
@@ -192,7 +192,7 @@ library SplToken {
 	/// @param mint the mint for this token
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to transfer
-	function burn(address account, address mint, address owner, uint64 amount) internal view {
+	function burn(address account, address mint, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Burn);
@@ -213,7 +213,7 @@ library SplToken {
 	/// @param delegate the delegate publickey
 	/// @param owner the publickey of the account owner keypair
 	/// @param amount the amount to approve
-	function approve(address account, address delegate, address owner, uint64 amount) internal view {
+	function approve(address account, address delegate, address owner, uint64 amount) internal {
 		bytes instr = new bytes(9);
 
 		instr[0] = uint8(TokenInstruction.Approve);
@@ -233,7 +233,7 @@ library SplToken {
 	///
 	/// @param account the account for which a delegate should be approved
 	/// @param owner the publickey of the account owner keypair
-	function revoke(address account, address owner) internal view {
+	function revoke(address account, address owner) internal {
 		bytes instr = new bytes(1);
 
 		instr[0] = uint8(TokenInstruction.Revoke);
@@ -371,7 +371,7 @@ library SplToken {
 	///
 	/// @param mintAccount the public key for the mint account
 	/// @param mintAuthority the public for the mint authority
-	function remove_mint_authority(address mintAccount, address mintAuthority) public view {
+	function remove_mint_authority(address mintAccount, address mintAuthority) public {
 		AccountMeta[2] metas = [
 			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
 			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})

+ 300 - 0
tokens/spl-token-minter/solang/libraries/system_instruction.sol

@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: Apache-2.0
+
+// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
+// it has not been audited for security, so use it at your own risk.
+
+import 'solana';
+
+library SystemInstruction {
+    address constant systemAddress = address"11111111111111111111111111111111";
+    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
+    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+    uint64 constant state_size = 80;
+
+    enum Instruction {
+        CreateAccount,
+        Assign,
+        Transfer,
+        CreateAccountWithSeed,
+        AdvanceNounceAccount,
+        WithdrawNonceAccount,
+        InitializeNonceAccount,
+        AuthorizeNonceAccount,
+        Allocate,
+        AllocateWithSeed,
+        AssignWithSeed,
+        TransferWithSeed,
+        UpgradeNonceAccount // This is not available on Solana v1.9.15
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to public key for the account to be created
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'to' address using the seed
+    /// @param seed the string utilized to created the 'to' public key
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        uint32 buffer_size = 92 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = seed.length + 44;
+        bincode.writeUint64LE(lamports, offset);
+        offset += 8;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Assign account to a program (owner)
+    ///
+    /// @param pubkey the public key for the account whose owner is going to be reassigned
+    /// @param owner the public key for the new account owner
+    function assign(address pubkey, address owner) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
+        ];
+        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Assign account to a program (owner) based on a seed
+    ///
+    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to created the 'addr' public key
+    /// @param owner the public key for the new program owner
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+
+        uint32 buffer_size = 76 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        bincode.writeAddress(owner, 44 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports between accounts
+    ///
+    /// @param from public key for the funding account
+    /// @param to public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer(address from, address to, uint64 lamports) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports from a derived address
+    ///
+    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
+    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
+    /// @param seed the string utilized to create the 'from_pubkey' public key
+    /// @param from_owner owner to use to derive the funding account address
+    /// @param to_pubkey the public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
+        ];
+
+        uint32 buffer_size = seed.length + 52;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
+        bincode.writeUint64LE(lamports, 4);
+        bincode.writeUint64LE(seed.length, 12);
+        bincode.writeString(seed, 20);
+        bincode.writeAddress(from_owner, 20 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Allocate space in a (possibly new) account without funding
+    ///
+    /// @param pub_key account for which to allocate space
+    /// @param space number of bytes of memory to allocate
+    function allocate(address pub_key, uint64 space) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Allocate space for an assign an account at an address derived from a base public key and a seed
+    ///
+    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param space number of bytes of memory to allocate
+    /// @param owner owner to use to derive the 'addr' account address
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = new bytes(seed.length + 84);
+        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(seed.length, 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = 44 + seed.length;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new nonce account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
+    /// @param base the base address that derived the 'nonce' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
+        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the nonce account to be created
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
+        create_account(from, nonce, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Consumes a stored nonce, replacing it with a successor
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Withdraw funds from a nonce account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param to_pubkey the recipient account
+    /// @param lamports the number of lamports to withdraw
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[5] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Change the entity authorized to execute nonce instructions on the account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param new_authority
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
+    ///
+    /// @param nonce the public key for the nonce account
+    // This is not available on Solana v1.9.15
+    function upgrade_nonce_account(address nonce) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
+        systemAddress.call{accounts: meta}(bincode);
+    }
+}

+ 1 - 0
tokens/spl-token-minter/solang/package.json

@@ -6,6 +6,7 @@
     "dependencies": {
         "@coral-xyz/anchor": "^0.28.0",
         "@metaplex-foundation/js": "^0.19.4",
+        "@project-serum/anchor": "^0.26.0",
         "@solana/spl-token": "^0.3.8"
     },
     "devDependencies": {

+ 6 - 6
tokens/spl-token-minter/solang/solidity/spl-token-minter.sol

@@ -1,11 +1,11 @@
 
-import "./spl_token.sol";
-import "./mpl_metadata.sol";
+import "../libraries/spl_token.sol";
+import "../libraries/mpl_metadata.sol";
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract spl_token_minter {
     @payer(payer)
-    constructor(address payer) {}
+    constructor() {}
 
     function createTokenMint(
         address payer, // payer account
@@ -17,7 +17,7 @@ contract spl_token_minter {
         string name, // name for the metadata account
         string symbol, // symbol for the metadata account
         string uri // uri for the metadata account
-    ) public view {
+    ) public {
         // Invoke System Program to create a new account for the mint account and,
         // Invoke Token Program to initialize the mint account
         // Set mint authority, freeze authority, and decimals for the mint account
@@ -42,12 +42,12 @@ contract spl_token_minter {
         );
     }
 
-    function mintTo(address payer, address tokenAccount, address mint, address owner, uint64 amount) public view {
+    function mintTo(address mintAuthority, address tokenAccount, address mint, uint64 amount) public {
         // Mint tokens to the token account
         SplToken.mint_to(
             mint, // mint account
             tokenAccount, // token account
-            payer, // mint authority
+            mintAuthority, // mint authority
             amount // amount
         );
     }

+ 0 - 300
tokens/spl-token-minter/solang/solidity/system_instruction.sol

@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
-// it has not been audited for security, so use it at your own risk.
-
-import 'solana';
-
-library SystemInstruction {
-    address constant systemAddress = address"11111111111111111111111111111111";
-    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
-    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-    uint64 constant state_size = 80;
-
-    enum Instruction {
-        CreateAccount,
-        Assign,
-        Transfer,
-        CreateAccountWithSeed,
-        AdvanceNounceAccount,
-        WithdrawNonceAccount,
-        InitializeNonceAccount,
-        AuthorizeNonceAccount,
-        Allocate,
-        AllocateWithSeed,
-        AssignWithSeed,
-        TransferWithSeed,
-        UpgradeNonceAccount // This is not available on Solana v1.9.15
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to public key for the account to be created
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'to' address using the seed
-    /// @param seed the string utilized to created the 'to' public key
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        uint32 buffer_size = 92 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = seed.length + 44;
-        bincode.writeUint64LE(lamports, offset);
-        offset += 8;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Assign account to a program (owner)
-    ///
-    /// @param pubkey the public key for the account whose owner is going to be reassigned
-    /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
-        ];
-        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Assign account to a program (owner) based on a seed
-    ///
-    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to created the 'addr' public key
-    /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-
-        uint32 buffer_size = 76 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        bincode.writeAddress(owner, 44 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports between accounts
-    ///
-    /// @param from public key for the funding account
-    /// @param to public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports from a derived address
-    ///
-    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
-    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
-    /// @param seed the string utilized to create the 'from_pubkey' public key
-    /// @param from_owner owner to use to derive the funding account address
-    /// @param to_pubkey the public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
-        ];
-
-        uint32 buffer_size = seed.length + 52;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
-        bincode.writeUint64LE(lamports, 4);
-        bincode.writeUint64LE(seed.length, 12);
-        bincode.writeString(seed, 20);
-        bincode.writeAddress(from_owner, 20 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Allocate space in a (possibly new) account without funding
-    ///
-    /// @param pub_key account for which to allocate space
-    /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Allocate space for an assign an account at an address derived from a base public key and a seed
-    ///
-    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param space number of bytes of memory to allocate
-    /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = new bytes(seed.length + 84);
-        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(seed.length, 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = 44 + seed.length;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new nonce account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
-    /// @param base the base address that derived the 'nonce' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
-        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the nonce account to be created
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
-        create_account(from, nonce, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Consumes a stored nonce, replacing it with a successor
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Withdraw funds from a nonce account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param to_pubkey the recipient account
-    /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[5] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Change the entity authorized to execute nonce instructions on the account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
-    ///
-    /// @param nonce the public key for the nonce account
-    // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
-        systemAddress.call{accounts: meta}(bincode);
-    }
-}

+ 30 - 31
tokens/spl-token-minter/solang/tests/spl-token-minter.ts

@@ -1,51 +1,51 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { SplTokenMinter } from "../target/types/spl_token_minter"
-import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js"
-import { Metaplex } from "@metaplex-foundation/js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { SplTokenMinter } from "../target/types/spl_token_minter";
+import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
+import { Metaplex } from "@metaplex-foundation/js";
 import {
   ASSOCIATED_TOKEN_PROGRAM_ID,
   getOrCreateAssociatedTokenAccount,
   TOKEN_PROGRAM_ID,
-} from "@solana/spl-token"
+} from "@solana/spl-token";
 
 describe("spl-token-minter", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   // Generate a new keypair for the data account for the program
-  const dataAccount = anchor.web3.Keypair.generate()
+  const dataAccount = anchor.web3.Keypair.generate();
   // Generate a mint keypair
-  const mintKeypair = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet as anchor.Wallet
-  const connection = provider.connection
+  const mintKeypair = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet as anchor.Wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.SplTokenMinter as Program<SplTokenMinter>
+  const program = anchor.workspace.SplTokenMinter as Program<SplTokenMinter>;
 
   // Metadata for the Token
-  const tokenTitle = "Solana Gold"
-  const tokenSymbol = "GOLDSOL"
+  const tokenTitle = "Solana Gold";
+  const tokenSymbol = "GOLDSOL";
   const tokenUri =
-    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json"
+    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json";
 
   it("Is initialized!", async () => {
     // Initialize data account for the program, which is required by Solang
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an SPL Token!", async () => {
     // Get the metadata address for the mint
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     // Create the token mint
     const tx = await program.methods
@@ -78,9 +78,9 @@ describe("spl-token-minter", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Mint some tokens to your wallet!", async () => {
     // Wallet's associated token account address for mint
@@ -89,14 +89,13 @@ describe("spl-token-minter", () => {
       wallet.payer, // payer
       mintKeypair.publicKey, // mint
       wallet.publicKey // owner
-    )
+    );
 
     const tx = await program.methods
       .mintTo(
         wallet.publicKey, // payer
         tokenAccount.address, // associated token account address
         mintKeypair.publicKey, // mint
-        wallet.publicKey, // owner of token account
         new anchor.BN(150) // amount to mint
       )
       .accounts({ dataAccount: dataAccount.publicKey })
@@ -120,7 +119,7 @@ describe("spl-token-minter", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
tokens/spl-token-minter/solang/tsconfig.json

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

+ 134 - 0
tokens/transfer-tokens/solang/libraries/mpl_metadata.sol

@@ -0,0 +1,134 @@
+import 'solana';
+
+// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L449
+// Solidity does not support Rust Option<> type, so we need to handle it manually
+// Requires creating a struct for each combination of Option<> types
+// If bool for Option<> type is false, comment out the corresponding struct field otherwise instruction fails with "invalid account data"
+// TODO: figure out better way to handle Option<> types
+library MplMetadata {
+	address constant metadataProgramId = address"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
+	address constant systemAddress = address"11111111111111111111111111111111";
+    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L31
+	struct CreateMetadataAccountArgsV3 {
+        DataV2 data;
+        bool isMutable;
+        bool collectionDetailsPresent; // To handle Rust Option<> in Solidity
+        // CollectionDetails collectionDetails;
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/data.rs#L22
+    struct DataV2 {
+        string name;
+        string symbol;
+        string uri;
+        uint16 sellerFeeBasisPoints;
+        bool creatorsPresent; // To handle Rust Option<> in Solidity
+        // Creator[] creators;
+        bool collectionPresent; // To handle Rust Option<> in Solidity
+        // Collection collection;
+        bool usesPresent; // To handle Rust Option<> in Solidity
+        // Uses uses;
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L10
+    struct Creator {
+        address creatorAddress;
+        bool verified;
+        uint8 share;
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L66
+    struct Collection {
+        bool verified;
+        address key;
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/collection.rs#L57
+    struct CollectionDetails {
+        CollectionDetailsType detailType;
+        uint64 size;
+    }
+    enum CollectionDetailsType {
+        V1
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L43
+    struct Uses {
+        UseMethod useMethod;
+        uint64 remaining;
+        uint64 total;
+    }
+
+	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L35
+    enum UseMethod {
+        Burn,
+        Multiple,
+        Single
+    }
+
+	function create_metadata_account(
+		address metadata,
+		address mint,
+		address mintAuthority,
+		address payer,
+		address updateAuthority,
+		string name,
+		string symbol,
+		string uri
+	) public {
+        // // Example of how to add a Creator[] array to the DataV2 struct
+		// Creator[] memory creators = new Creator[](1);
+        // creators[0] = Creator({
+        //     creatorAddress: payer,
+        //     verified: false,
+        //     share: 100
+        // });
+
+        DataV2 data = DataV2({
+            name: name,
+            symbol: symbol,
+            uri: uri,
+            sellerFeeBasisPoints: 0,
+            creatorsPresent: false,
+             // creators: creators,
+            collectionPresent: false,
+            // collection: Collection({
+            //     verified: false,
+            //     key: address(0)
+            // }),
+            usesPresent: false
+            // uses: Uses({
+            //     useMethod: UseMethod.Burn,
+            //     remaining: 0,
+            //     total: 0
+            // })
+        });
+
+        CreateMetadataAccountArgsV3 args = CreateMetadataAccountArgsV3({
+            data: data,
+            isMutable: true,
+            collectionDetailsPresent: false
+			// collectionDetails: CollectionDetails({
+            //     detailType: CollectionDetailsType.V1,
+            //     size: 0
+            // })
+        });
+
+        AccountMeta[7] metas = [
+            AccountMeta({pubkey: metadata, is_writable: true, is_signer: false}),
+            AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
+            AccountMeta({pubkey: mintAuthority, is_writable: false, is_signer: true}),
+            AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
+            AccountMeta({pubkey: updateAuthority, is_writable: false, is_signer: false}),
+            AccountMeta({pubkey: systemAddress, is_writable: false, is_signer: false}),
+            AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false})
+        ];
+
+        bytes1 discriminator = 33;
+        bytes instructionData = abi.encode(discriminator, args);
+
+        metadataProgramId.call{accounts: metas}(instructionData);
+    }
+}

+ 387 - 0
tokens/transfer-tokens/solang/libraries/spl_token.sol

@@ -0,0 +1,387 @@
+import 'solana';
+import 'system_instruction.sol';
+
+library SplToken {
+	address constant tokenProgramId = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+	address constant associatedTokenProgramId = address"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
+	address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+	enum TokenInstruction {
+		InitializeMint, // 0
+		InitializeAccount, // 1
+		InitializeMultisig, // 2
+		Transfer, // 3
+		Approve, // 4
+		Revoke, // 5
+		SetAuthority, // 6
+		MintTo, // 7
+		Burn, // 8
+		CloseAccount, // 9
+		FreezeAccount, // 10
+		ThawAccount, // 11
+		TransferChecked, // 12
+		ApproveChecked, // 13
+		MintToChecked, // 14
+		BurnChecked, // 15
+		InitializeAccount2, // 16
+		SyncNative, // 17
+		InitializeAccount3, // 18
+		InitializeMultisig2, // 19
+		InitializeMint2, // 20
+		GetAccountDataSize, // 21
+		InitializeImmutableOwner, // 22
+		AmountToUiAmount, // 23
+		UiAmountToAmount, // 24
+		InitializeMintCloseAuthority, // 25
+		TransferFeeExtension, // 26
+		ConfidentialTransferExtension, // 27
+		DefaultAccountStateExtension, // 28
+		Reallocate, // 29
+		MemoTransferExtension, // 30
+		CreateNativeMint // 31
+	}
+
+	/// Initialize a new token account.
+	///
+	/// @param tokenAccount the public key of the token account to initialize
+	/// @param mint the public key of the mint account for this new token account
+	/// @param owner the public key of the owner of this new token account
+	function initialize_account(address tokenAccount, address mint, address owner) internal{
+		bytes instr = new bytes(1);
+
+		instr[0] = uint8(TokenInstruction.InitializeAccount);
+		AccountMeta[4] metas = [
+			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Initialize a new associated token account.
+	///
+	/// @param payer the public key of the payer to create the associated token account
+	/// @param tokenAccount the public key of the token account to initialize
+	/// @param mint the public key of the mint account for this new token account
+	/// @param owner the public key of the owner of this new token account
+    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal {
+        AccountMeta[6] metas = [
+			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
+			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: SystemInstruction.systemAddress, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: SplToken.tokenProgramId, is_writable: false, is_signer: false})
+		];
+
+        bytes instructionData = abi.encode((0));
+		associatedTokenProgramId.call{accounts: metas}(instructionData);
+    }
+
+	// Initialize mint instruction data
+	struct InitializeMintInstruction {
+        uint8 instruction;
+        uint8 decimals;
+        address mintAuthority;
+        uint8 freezeAuthorityOption;
+        address freezeAuthority;
+    }
+
+	/// Initialize a new mint account.
+	///
+	/// @param mint the public key of the mint account to initialize
+	/// @param mintAuthority the public key of the mint authority
+	/// @param freezeAuthority the public key of the freeze authority
+	/// @param decimals the decimals of the mint
+	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
+    	InitializeMintInstruction instr = InitializeMintInstruction({
+            instruction: 20,
+            decimals: decimals,
+            mintAuthority: mintAuthority,
+            freezeAuthorityOption: 1,
+            freezeAuthority: freezeAuthority
+        });
+
+		AccountMeta[1] metas = [
+			AccountMeta({pubkey: mint, is_writable: true, is_signer: false})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Create and initialize a new mint account in one instruction
+	///
+	/// @param payer the public key of the account paying to create the mint account
+	/// @param mint the public key of the mint account to initialize
+	/// @param mintAuthority the public key of the mint authority
+	/// @param freezeAuthority the public key of the freeze authority
+	/// @param decimals the decimals of the mint
+	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal {
+		// Invoke System Program to create a new account for the mint account
+        // Program owner is set to the Token program
+        SystemInstruction.create_account(
+            payer,   // lamports sent from this account (payer)
+            mint,    // lamports sent to this account (account to be created)
+            1461600, // lamport amount (minimum lamports for mint account)
+            82,      // space required for the account (mint account)
+            SplToken.tokenProgramId // new program owner
+        );
+
+		InitializeMintInstruction instr = InitializeMintInstruction({
+            instruction: 20,
+            decimals: decimals,
+            mintAuthority: mintAuthority,
+            freezeAuthorityOption: 1,
+            freezeAuthority: freezeAuthority
+        });
+
+		AccountMeta[1] metas = [
+			AccountMeta({pubkey: mint, is_writable: true, is_signer: false})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Mint new tokens. The transaction should be signed by the mint authority keypair
+	///
+	/// @param mint the account of the mint
+	/// @param account the token account where the minted tokens should go
+	/// @param authority the public key of the mint authority
+	/// @param amount the amount of tokens to mint
+	function mint_to(address mint, address account, address authority, uint64 amount) internal {
+		bytes instr = new bytes(9);
+
+		instr[0] = uint8(TokenInstruction.MintTo);
+		instr.writeUint64LE(amount, 1);
+
+		AccountMeta[3] metas = [
+			AccountMeta({pubkey: mint, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: authority, is_writable: true, is_signer: true})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Transfer @amount token from @from to @to. The transaction should be signed by the owner
+	/// keypair of the from account.
+	///
+	/// @param from the account to transfer tokens from
+	/// @param to the account to transfer tokens to
+	/// @param owner the publickey of the from account owner keypair
+	/// @param amount the amount to transfer
+	function transfer(address from, address to, address owner, uint64 amount) internal {
+		bytes instr = new bytes(9);
+
+		instr[0] = uint8(TokenInstruction.Transfer);
+		instr.writeUint64LE(amount, 1);
+
+		AccountMeta[3] metas = [
+			AccountMeta({pubkey: from, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: to, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: true, is_signer: true})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Burn @amount tokens in account. This transaction should be signed by the owner.
+	///
+	/// @param account the acount for which tokens should be burned
+	/// @param mint the mint for this token
+	/// @param owner the publickey of the account owner keypair
+	/// @param amount the amount to transfer
+	function burn(address account, address mint, address owner, uint64 amount) internal {
+		bytes instr = new bytes(9);
+
+		instr[0] = uint8(TokenInstruction.Burn);
+		instr.writeUint64LE(amount, 1);
+
+		AccountMeta[3] metas = [
+			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: mint, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: true, is_signer: true})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Approve an amount to a delegate. This transaction should be signed by the owner
+	///
+	/// @param account the account for which a delegate should be approved
+	/// @param delegate the delegate publickey
+	/// @param owner the publickey of the account owner keypair
+	/// @param amount the amount to approve
+	function approve(address account, address delegate, address owner, uint64 amount) internal {
+		bytes instr = new bytes(9);
+
+		instr[0] = uint8(TokenInstruction.Approve);
+		instr.writeUint64LE(amount, 1);
+
+		AccountMeta[3] metas = [
+			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: delegate, is_writable: false, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: false, is_signer: true})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Revoke a previously approved delegate. This transaction should be signed by the owner. After
+	/// this transaction, no delgate is approved for any amount.
+	///
+	/// @param account the account for which a delegate should be approved
+	/// @param owner the publickey of the account owner keypair
+	function revoke(address account, address owner) internal {
+		bytes instr = new bytes(1);
+
+		instr[0] = uint8(TokenInstruction.Revoke);
+
+		AccountMeta[2] metas = [
+			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
+			AccountMeta({pubkey: owner, is_writable: false, is_signer: true})
+		];
+
+		tokenProgramId.call{accounts: metas}(instr);
+	}
+
+	/// Get the total supply for the mint, i.e. the total amount in circulation
+	/// @param mint the mint for this token
+	function total_supply(address mint) internal view returns (uint64) {
+		AccountInfo account = get_account_info(mint);
+
+		return account.data.readUint64LE(36);
+	}
+
+	/// Get the balance for an account.
+	///
+	/// @param account the account for which we want to know a balance
+	function get_balance(address account) internal view returns (uint64) {
+		AccountInfo ai = get_account_info(account);
+
+		return ai.data.readUint64LE(64);
+	}
+
+	/// Get the account info for an account. This walks the transaction account infos
+	/// and find the account info, or the transaction fails.
+	///
+	/// @param account the account for which we want to have the acount info.
+	function get_account_info(address account) internal view returns (AccountInfo) {
+		for (uint64 i = 0; i < tx.accounts.length; i++) {
+			AccountInfo ai = tx.accounts[i];
+			if (ai.key == account) {
+				return ai;
+			}
+		}
+
+		revert("account missing");
+	}
+
+	/// This enum represents the state of a token account
+	enum AccountState {
+		Uninitialized,
+		Initialized,
+		Frozen
+	}
+
+	/// This struct is the return of 'get_token_account_data'
+	struct TokenAccountData {
+		address mintAccount;
+		address owner;
+		uint64 balance;
+		bool delegate_present;
+		address delegate;
+		AccountState state;
+		bool is_native_present;
+		uint64 is_native;
+		uint64 delegated_amount;
+		bool close_authority_present;
+		address close_authority;
+	}
+
+	/// Fetch the owner, mint account and balance for an associated token account.
+	///
+	/// @param tokenAccount The token account
+	/// @return struct TokenAccountData
+	function get_token_account_data(address tokenAccount) public view returns (TokenAccountData) {
+		AccountInfo ai = get_account_info(tokenAccount);
+
+		TokenAccountData data = TokenAccountData(
+			{
+				mintAccount: ai.data.readAddress(0),
+				owner: ai.data.readAddress(32),
+			 	balance: ai.data.readUint64LE(64),
+				delegate_present: ai.data.readUint32LE(72) > 0,
+				delegate: ai.data.readAddress(76),
+				state: AccountState(ai.data[108]),
+				is_native_present: ai.data.readUint32LE(109) > 0,
+				is_native: ai.data.readUint64LE(113),
+				delegated_amount: ai.data.readUint64LE(121),
+				close_authority_present: ai.data.readUint32LE(129) > 10,
+				close_authority: ai.data.readAddress(133)
+			}
+		);
+
+		return data;
+	}
+
+	// This struct is the return of 'get_mint_account_data'
+	struct MintAccountData {
+		bool authority_present;
+		address mint_authority;
+		uint64 supply;
+		uint8 decimals;
+		bool is_initialized;
+		bool freeze_authority_present;
+		address freeze_authority;
+	}
+
+	/// Retrieve the information saved in a mint account
+	///
+	/// @param mintAccount the account whose information we want to retrive
+	/// @return the MintAccountData struct
+	function get_mint_account_data(address mintAccount) public view returns (MintAccountData) {
+		AccountInfo ai = get_account_info(mintAccount);
+
+		uint32 authority_present = ai.data.readUint32LE(0);
+		uint32 freeze_authority_present = ai.data.readUint32LE(46);
+		MintAccountData data = MintAccountData( {
+			authority_present: authority_present > 0,
+			mint_authority: ai.data.readAddress(4),
+			supply: ai.data.readUint64LE(36),
+			decimals: uint8(ai.data[44]),
+			is_initialized: ai.data[45] > 0,
+			freeze_authority_present: freeze_authority_present > 0,
+			freeze_authority: ai.data.readAddress(50)
+		});
+
+		return data;
+	}
+
+	// A mint account has an authority, whose type is one of the members of this struct.
+	enum AuthorityType {
+		MintTokens,
+		FreezeAccount,
+		AccountOwner,
+		CloseAccount
+	}
+
+	/// Remove the mint authority from a mint account
+	///
+	/// @param mintAccount the public key for the mint account
+	/// @param mintAuthority the public for the mint authority
+	function remove_mint_authority(address mintAccount, address mintAuthority) public {
+		AccountMeta[2] metas = [
+			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
+			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})
+		];
+
+		bytes data = new bytes(9);
+		data[0] = uint8(TokenInstruction.SetAuthority);
+		data[1] = uint8(AuthorityType.MintTokens);
+		data[3] = 0;
+
+		tokenProgramId.call{accounts: metas}(data);
+	}
+}

+ 300 - 0
tokens/transfer-tokens/solang/libraries/system_instruction.sol

@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: Apache-2.0
+
+// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
+// it has not been audited for security, so use it at your own risk.
+
+import 'solana';
+
+library SystemInstruction {
+    address constant systemAddress = address"11111111111111111111111111111111";
+    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
+    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
+    uint64 constant state_size = 80;
+
+    enum Instruction {
+        CreateAccount,
+        Assign,
+        Transfer,
+        CreateAccountWithSeed,
+        AdvanceNounceAccount,
+        WithdrawNonceAccount,
+        InitializeNonceAccount,
+        AuthorizeNonceAccount,
+        Allocate,
+        AllocateWithSeed,
+        AssignWithSeed,
+        TransferWithSeed,
+        UpgradeNonceAccount // This is not available on Solana v1.9.15
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to public key for the account to be created
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'to' address using the seed
+    /// @param seed the string utilized to created the 'to' public key
+    /// @param lamports amount of lamports to be transfered to the new account
+    /// @param space the size in bytes that is going to be made available for the account
+    /// @param owner public key for the program that will own the account being created
+    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        uint32 buffer_size = 92 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = seed.length + 44;
+        bincode.writeUint64LE(lamports, offset);
+        offset += 8;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Assign account to a program (owner)
+    ///
+    /// @param pubkey the public key for the account whose owner is going to be reassigned
+    /// @param owner the public key for the new account owner
+    function assign(address pubkey, address owner) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
+        ];
+        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Assign account to a program (owner) based on a seed
+    ///
+    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to created the 'addr' public key
+    /// @param owner the public key for the new program owner
+    function assign_with_seed(address addr, address base, string seed, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+
+        uint32 buffer_size = 76 + seed.length;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(uint64(seed.length), 36);
+        bincode.writeString(seed, 44);
+        bincode.writeAddress(owner, 44 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports between accounts
+    ///
+    /// @param from public key for the funding account
+    /// @param to public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer(address from, address to, uint64 lamports) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
+            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Transfer lamports from a derived address
+    ///
+    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
+    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
+    /// @param seed the string utilized to create the 'from_pubkey' public key
+    /// @param from_owner owner to use to derive the funding account address
+    /// @param to_pubkey the public key for the recipient account
+    /// @param lamports amount of lamports to transfer
+    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
+        ];
+
+        uint32 buffer_size = seed.length + 52;
+        bytes bincode = new bytes(buffer_size);
+        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
+        bincode.writeUint64LE(lamports, 4);
+        bincode.writeUint64LE(seed.length, 12);
+        bincode.writeString(seed, 20);
+        bincode.writeAddress(from_owner, 20 + seed.length);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Allocate space in a (possibly new) account without funding
+    ///
+    /// @param pub_key account for which to allocate space
+    /// @param space number of bytes of memory to allocate
+    function allocate(address pub_key, uint64 space) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
+
+        systemAddress.call{accounts: meta}(bincode);
+    }
+
+    /// Allocate space for an assign an account at an address derived from a base public key and a seed
+    ///
+    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
+    /// @param base the base address that derived the 'addr' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param space number of bytes of memory to allocate
+    /// @param owner owner to use to derive the 'addr' account address
+    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = new bytes(seed.length + 84);
+        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
+        bincode.writeAddress(base, 4);
+        bincode.writeUint64LE(seed.length, 36);
+        bincode.writeString(seed, 44);
+        uint32 offset = 44 + seed.length;
+        bincode.writeUint64LE(space, offset);
+        offset += 8;
+        bincode.writeAddress(owner, offset);
+
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new nonce account on Solana using a public key derived from a seed
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
+    /// @param base the base address that derived the 'nonce' key using the seed
+    /// @param seed the string utilized to create the 'addr' public key
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal {
+        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Create a new account on Solana
+    ///
+    /// @param from public key for the account from which to transfer lamports to the new account
+    /// @param nonce the public key for the nonce account to be created
+    /// @param authority The entity authorized to execute nonce instructions on the account
+    /// @param lamports amount of lamports to be transfered to the new account
+    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal {
+        create_account(from, nonce, lamports, state_size, systemAddress);
+
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Consumes a stored nonce, replacing it with a successor
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
+    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal {
+        AccountMeta[3] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Withdraw funds from a nonce account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param to_pubkey the recipient account
+    /// @param lamports the number of lamports to withdraw
+    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal {
+        AccountMeta[5] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// Change the entity authorized to execute nonce instructions on the account
+    ///
+    /// @param nonce_pubkey the public key for the nonce account
+    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
+    /// @param new_authority
+    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal {
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
+            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
+        systemAddress.call{accounts: metas}(bincode);
+    }
+
+    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
+    ///
+    /// @param nonce the public key for the nonce account
+    // This is not available on Solana v1.9.15
+    function upgrade_nonce_account(address nonce) internal {
+        AccountMeta[1] meta = [
+            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
+        ];
+
+        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
+        systemAddress.call{accounts: meta}(bincode);
+    }
+}

+ 1 - 0
tokens/transfer-tokens/solang/package.json

@@ -6,6 +6,7 @@
     "dependencies": {
         "@coral-xyz/anchor": "^0.28.0",
         "@metaplex-foundation/js": "^0.19.4",
+        "@project-serum/anchor": "^0.26.0",
         "@solana/spl-token": "^0.3.8"
     },
     "devDependencies": {

+ 0 - 134
tokens/transfer-tokens/solang/solidity/mpl_metadata.sol

@@ -1,134 +0,0 @@
-import 'solana';
-
-// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L449
-// Solidity does not support Rust Option<> type, so we need to handle it manually
-// Requires creating a struct for each combination of Option<> types
-// If bool for Option<> type is false, comment out the corresponding struct field otherwise instruction fails with "invalid account data"
-// TODO: figure out better way to handle Option<> types
-library MplMetadata {
-	address constant metadataProgramId = address"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s";
-	address constant systemAddress = address"11111111111111111111111111111111";
-    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L31
-	struct CreateMetadataAccountArgsV3 {
-        DataV2 data;
-        bool isMutable;
-        bool collectionDetailsPresent; // To handle Rust Option<> in Solidity
-        // CollectionDetails collectionDetails;
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/data.rs#L22
-    struct DataV2 {
-        string name;
-        string symbol;
-        string uri;
-        uint16 sellerFeeBasisPoints;
-        bool creatorsPresent; // To handle Rust Option<> in Solidity
-        // Creator[] creators;
-        bool collectionPresent; // To handle Rust Option<> in Solidity
-        // Collection collection;
-        bool usesPresent; // To handle Rust Option<> in Solidity
-        // Uses uses;
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L10
-    struct Creator {
-        address creatorAddress;
-        bool verified;
-        uint8 share;
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L66
-    struct Collection {
-        bool verified;
-        address key;
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/collection.rs#L57
-    struct CollectionDetails {
-        CollectionDetailsType detailType;
-        uint64 size;
-    }
-    enum CollectionDetailsType {
-        V1
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L43
-    struct Uses {
-        UseMethod useMethod;
-        uint64 remaining;
-        uint64 total;
-    }
-
-	// Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L35
-    enum UseMethod {
-        Burn,
-        Multiple,
-        Single
-    }
-
-	function create_metadata_account(
-		address metadata,
-		address mint,
-		address mintAuthority,
-		address payer,
-		address updateAuthority,
-		string name,
-		string symbol,
-		string uri
-	) public view {
-        // // Example of how to add a Creator[] array to the DataV2 struct
-		// Creator[] memory creators = new Creator[](1);
-        // creators[0] = Creator({
-        //     creatorAddress: payer,
-        //     verified: false,
-        //     share: 100
-        // });
-
-        DataV2 data = DataV2({
-            name: name,
-            symbol: symbol,
-            uri: uri,
-            sellerFeeBasisPoints: 0,
-            creatorsPresent: false,
-             // creators: creators,
-            collectionPresent: false,
-            // collection: Collection({
-            //     verified: false,
-            //     key: address(0)
-            // }),
-            usesPresent: false
-            // uses: Uses({
-            //     useMethod: UseMethod.Burn,
-            //     remaining: 0,
-            //     total: 0
-            // })
-        });
-
-        CreateMetadataAccountArgsV3 args = CreateMetadataAccountArgsV3({
-            data: data,
-            isMutable: true,
-            collectionDetailsPresent: false
-			// collectionDetails: CollectionDetails({
-            //     detailType: CollectionDetailsType.V1,
-            //     size: 0
-            // })
-        });
-
-        AccountMeta[7] metas = [
-            AccountMeta({pubkey: metadata, is_writable: true, is_signer: false}),
-            AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
-            AccountMeta({pubkey: mintAuthority, is_writable: false, is_signer: true}),
-            AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
-            AccountMeta({pubkey: updateAuthority, is_writable: false, is_signer: false}),
-            AccountMeta({pubkey: systemAddress, is_writable: false, is_signer: false}),
-            AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false})
-        ];
-
-        bytes1 discriminator = 33;
-        bytes instructionData = abi.encode(discriminator, args);
-
-        metadataProgramId.call{accounts: metas}(instructionData);
-    }
-}

+ 0 - 387
tokens/transfer-tokens/solang/solidity/spl_token.sol

@@ -1,387 +0,0 @@
-import 'solana';
-import 'system_instruction.sol';
-
-library SplToken {
-	address constant tokenProgramId = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
-	address constant associatedTokenProgramId = address"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
-	address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-	enum TokenInstruction {
-		InitializeMint, // 0
-		InitializeAccount, // 1
-		InitializeMultisig, // 2
-		Transfer, // 3
-		Approve, // 4
-		Revoke, // 5
-		SetAuthority, // 6
-		MintTo, // 7
-		Burn, // 8
-		CloseAccount, // 9
-		FreezeAccount, // 10
-		ThawAccount, // 11
-		TransferChecked, // 12
-		ApproveChecked, // 13
-		MintToChecked, // 14
-		BurnChecked, // 15
-		InitializeAccount2, // 16
-		SyncNative, // 17
-		InitializeAccount3, // 18
-		InitializeMultisig2, // 19
-		InitializeMint2, // 20
-		GetAccountDataSize, // 21
-		InitializeImmutableOwner, // 22
-		AmountToUiAmount, // 23
-		UiAmountToAmount, // 24
-		InitializeMintCloseAuthority, // 25
-		TransferFeeExtension, // 26
-		ConfidentialTransferExtension, // 27
-		DefaultAccountStateExtension, // 28
-		Reallocate, // 29
-		MemoTransferExtension, // 30
-		CreateNativeMint // 31
-	}
-
-	/// Initialize a new token account.
-	///
-	/// @param tokenAccount the public key of the token account to initialize
-	/// @param mint the public key of the mint account for this new token account
-	/// @param owner the public key of the owner of this new token account
-	function initialize_account(address tokenAccount, address mint, address owner) internal view{
-		bytes instr = new bytes(1);
-
-		instr[0] = uint8(TokenInstruction.InitializeAccount);
-		AccountMeta[4] metas = [
-			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Initialize a new associated token account.
-	///
-	/// @param payer the public key of the payer to create the associated token account
-	/// @param tokenAccount the public key of the token account to initialize
-	/// @param mint the public key of the mint account for this new token account
-	/// @param owner the public key of the owner of this new token account
-    function create_associated_token_account(address payer, address tokenAccount, address mint, address owner) internal view {
-        AccountMeta[6] metas = [
-			AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
-			AccountMeta({pubkey: tokenAccount, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: SystemInstruction.systemAddress, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: SplToken.tokenProgramId, is_writable: false, is_signer: false})
-		];
-
-        bytes instructionData = abi.encode((0));
-		associatedTokenProgramId.call{accounts: metas}(instructionData);
-    }
-
-	// Initialize mint instruction data
-	struct InitializeMintInstruction {
-        uint8 instruction;
-        uint8 decimals;
-        address mintAuthority;
-        uint8 freezeAuthorityOption;
-        address freezeAuthority;
-    }
-
-	/// Initialize a new mint account.
-	///
-	/// @param mint the public key of the mint account to initialize
-	/// @param mintAuthority the public key of the mint authority
-	/// @param freezeAuthority the public key of the freeze authority
-	/// @param decimals the decimals of the mint
-	function initialize_mint(address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
-    	InitializeMintInstruction instr = InitializeMintInstruction({
-            instruction: 20,
-            decimals: decimals,
-            mintAuthority: mintAuthority,
-            freezeAuthorityOption: 1,
-            freezeAuthority: freezeAuthority
-        });
-
-		AccountMeta[1] metas = [
-			AccountMeta({pubkey: mint, is_writable: true, is_signer: false})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Create and initialize a new mint account in one instruction
-	///
-	/// @param payer the public key of the account paying to create the mint account
-	/// @param mint the public key of the mint account to initialize
-	/// @param mintAuthority the public key of the mint authority
-	/// @param freezeAuthority the public key of the freeze authority
-	/// @param decimals the decimals of the mint
-	function create_mint(address payer, address mint, address mintAuthority, address freezeAuthority, uint8 decimals) internal view {
-		// Invoke System Program to create a new account for the mint account
-        // Program owner is set to the Token program
-        SystemInstruction.create_account(
-            payer,   // lamports sent from this account (payer)
-            mint,    // lamports sent to this account (account to be created)
-            1461600, // lamport amount (minimum lamports for mint account)
-            82,      // space required for the account (mint account)
-            SplToken.tokenProgramId // new program owner
-        );
-
-		InitializeMintInstruction instr = InitializeMintInstruction({
-            instruction: 20,
-            decimals: decimals,
-            mintAuthority: mintAuthority,
-            freezeAuthorityOption: 1,
-            freezeAuthority: freezeAuthority
-        });
-
-		AccountMeta[1] metas = [
-			AccountMeta({pubkey: mint, is_writable: true, is_signer: false})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Mint new tokens. The transaction should be signed by the mint authority keypair
-	///
-	/// @param mint the account of the mint
-	/// @param account the token account where the minted tokens should go
-	/// @param authority the public key of the mint authority
-	/// @param amount the amount of tokens to mint
-	function mint_to(address mint, address account, address authority, uint64 amount) internal view {
-		bytes instr = new bytes(9);
-
-		instr[0] = uint8(TokenInstruction.MintTo);
-		instr.writeUint64LE(amount, 1);
-
-		AccountMeta[3] metas = [
-			AccountMeta({pubkey: mint, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: authority, is_writable: true, is_signer: true})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Transfer @amount token from @from to @to. The transaction should be signed by the owner
-	/// keypair of the from account.
-	///
-	/// @param from the account to transfer tokens from
-	/// @param to the account to transfer tokens to
-	/// @param owner the publickey of the from account owner keypair
-	/// @param amount the amount to transfer
-	function transfer(address from, address to, address owner, uint64 amount) internal view {
-		bytes instr = new bytes(9);
-
-		instr[0] = uint8(TokenInstruction.Transfer);
-		instr.writeUint64LE(amount, 1);
-
-		AccountMeta[3] metas = [
-			AccountMeta({pubkey: from, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: to, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: true, is_signer: true})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Burn @amount tokens in account. This transaction should be signed by the owner.
-	///
-	/// @param account the acount for which tokens should be burned
-	/// @param mint the mint for this token
-	/// @param owner the publickey of the account owner keypair
-	/// @param amount the amount to transfer
-	function burn(address account, address mint, address owner, uint64 amount) internal view {
-		bytes instr = new bytes(9);
-
-		instr[0] = uint8(TokenInstruction.Burn);
-		instr.writeUint64LE(amount, 1);
-
-		AccountMeta[3] metas = [
-			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: mint, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: true, is_signer: true})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Approve an amount to a delegate. This transaction should be signed by the owner
-	///
-	/// @param account the account for which a delegate should be approved
-	/// @param delegate the delegate publickey
-	/// @param owner the publickey of the account owner keypair
-	/// @param amount the amount to approve
-	function approve(address account, address delegate, address owner, uint64 amount) internal view {
-		bytes instr = new bytes(9);
-
-		instr[0] = uint8(TokenInstruction.Approve);
-		instr.writeUint64LE(amount, 1);
-
-		AccountMeta[3] metas = [
-			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: delegate, is_writable: false, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: false, is_signer: true})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Revoke a previously approved delegate. This transaction should be signed by the owner. After
-	/// this transaction, no delgate is approved for any amount.
-	///
-	/// @param account the account for which a delegate should be approved
-	/// @param owner the publickey of the account owner keypair
-	function revoke(address account, address owner) internal view {
-		bytes instr = new bytes(1);
-
-		instr[0] = uint8(TokenInstruction.Revoke);
-
-		AccountMeta[2] metas = [
-			AccountMeta({pubkey: account, is_writable: true, is_signer: false}),
-			AccountMeta({pubkey: owner, is_writable: false, is_signer: true})
-		];
-
-		tokenProgramId.call{accounts: metas}(instr);
-	}
-
-	/// Get the total supply for the mint, i.e. the total amount in circulation
-	/// @param mint the mint for this token
-	function total_supply(address mint) internal view returns (uint64) {
-		AccountInfo account = get_account_info(mint);
-
-		return account.data.readUint64LE(36);
-	}
-
-	/// Get the balance for an account.
-	///
-	/// @param account the account for which we want to know a balance
-	function get_balance(address account) internal view returns (uint64) {
-		AccountInfo ai = get_account_info(account);
-
-		return ai.data.readUint64LE(64);
-	}
-
-	/// Get the account info for an account. This walks the transaction account infos
-	/// and find the account info, or the transaction fails.
-	///
-	/// @param account the account for which we want to have the acount info.
-	function get_account_info(address account) internal view returns (AccountInfo) {
-		for (uint64 i = 0; i < tx.accounts.length; i++) {
-			AccountInfo ai = tx.accounts[i];
-			if (ai.key == account) {
-				return ai;
-			}
-		}
-
-		revert("account missing");
-	}
-
-	/// This enum represents the state of a token account
-	enum AccountState {
-		Uninitialized,
-		Initialized,
-		Frozen
-	}
-
-	/// This struct is the return of 'get_token_account_data'
-	struct TokenAccountData {
-		address mintAccount;
-		address owner;
-		uint64 balance;
-		bool delegate_present;
-		address delegate;
-		AccountState state;
-		bool is_native_present;
-		uint64 is_native;
-		uint64 delegated_amount;
-		bool close_authority_present;
-		address close_authority;
-	}
-
-	/// Fetch the owner, mint account and balance for an associated token account.
-	///
-	/// @param tokenAccount The token account
-	/// @return struct TokenAccountData
-	function get_token_account_data(address tokenAccount) public view returns (TokenAccountData) {
-		AccountInfo ai = get_account_info(tokenAccount);
-
-		TokenAccountData data = TokenAccountData(
-			{
-				mintAccount: ai.data.readAddress(0),
-				owner: ai.data.readAddress(32),
-			 	balance: ai.data.readUint64LE(64),
-				delegate_present: ai.data.readUint32LE(72) > 0,
-				delegate: ai.data.readAddress(76),
-				state: AccountState(ai.data[108]),
-				is_native_present: ai.data.readUint32LE(109) > 0,
-				is_native: ai.data.readUint64LE(113),
-				delegated_amount: ai.data.readUint64LE(121),
-				close_authority_present: ai.data.readUint32LE(129) > 10,
-				close_authority: ai.data.readAddress(133)
-			}
-		);
-
-		return data;
-	}
-
-	// This struct is the return of 'get_mint_account_data'
-	struct MintAccountData {
-		bool authority_present;
-		address mint_authority;
-		uint64 supply;
-		uint8 decimals;
-		bool is_initialized;
-		bool freeze_authority_present;
-		address freeze_authority;
-	}
-
-	/// Retrieve the information saved in a mint account
-	///
-	/// @param mintAccount the account whose information we want to retrive
-	/// @return the MintAccountData struct
-	function get_mint_account_data(address mintAccount) public view returns (MintAccountData) {
-		AccountInfo ai = get_account_info(mintAccount);
-
-		uint32 authority_present = ai.data.readUint32LE(0);
-		uint32 freeze_authority_present = ai.data.readUint32LE(46);
-		MintAccountData data = MintAccountData( {
-			authority_present: authority_present > 0,
-			mint_authority: ai.data.readAddress(4),
-			supply: ai.data.readUint64LE(36),
-			decimals: uint8(ai.data[44]),
-			is_initialized: ai.data[45] > 0,
-			freeze_authority_present: freeze_authority_present > 0,
-			freeze_authority: ai.data.readAddress(50)
-		});
-
-		return data;
-	}
-
-	// A mint account has an authority, whose type is one of the members of this struct.
-	enum AuthorityType {
-		MintTokens,
-		FreezeAccount,
-		AccountOwner,
-		CloseAccount
-	}
-
-	/// Remove the mint authority from a mint account
-	///
-	/// @param mintAccount the public key for the mint account
-	/// @param mintAuthority the public for the mint authority
-	function remove_mint_authority(address mintAccount, address mintAuthority) public view {
-		AccountMeta[2] metas = [
-			AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}),
-			AccountMeta({pubkey: mintAuthority, is_signer: true, is_writable: false})
-		];
-
-		bytes data = new bytes(9);
-		data[0] = uint8(TokenInstruction.SetAuthority);
-		data[1] = uint8(AuthorityType.MintTokens);
-		data[3] = 0;
-
-		tokenProgramId.call{accounts: metas}(data);
-	}
-}

+ 0 - 300
tokens/transfer-tokens/solang/solidity/system_instruction.sol

@@ -1,300 +0,0 @@
-// SPDX-License-Identifier: Apache-2.0
-
-// Disclaimer: This library provides a bridge for Solidity to interact with Solana's system instructions. Although it is production ready,
-// it has not been audited for security, so use it at your own risk.
-
-import 'solana';
-
-library SystemInstruction {
-    address constant systemAddress = address"11111111111111111111111111111111";
-    address constant recentBlockHashes = address"SysvarRecentB1ockHashes11111111111111111111";
-    address constant rentAddress = address"SysvarRent111111111111111111111111111111111";
-    uint64 constant state_size = 80;
-
-    enum Instruction {
-        CreateAccount,
-        Assign,
-        Transfer,
-        CreateAccountWithSeed,
-        AdvanceNounceAccount,
-        WithdrawNonceAccount,
-        InitializeNonceAccount,
-        AuthorizeNonceAccount,
-        Allocate,
-        AllocateWithSeed,
-        AssignWithSeed,
-        TransferWithSeed,
-        UpgradeNonceAccount // This is not available on Solana v1.9.15
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to public key for the account to be created
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account(address from, address to, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.CreateAccount), lamports, space, owner);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param to the public key for the account to be created. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'to' address using the seed
-    /// @param seed the string utilized to created the 'to' public key
-    /// @param lamports amount of lamports to be transfered to the new account
-    /// @param space the size in bytes that is going to be made available for the account
-    /// @param owner public key for the program that will own the account being created
-    function create_account_with_seed(address from, address to, address base, string seed, uint64 lamports, uint64 space, address owner) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        uint32 buffer_size = 92 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.CreateAccountWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = seed.length + 44;
-        bincode.writeUint64LE(lamports, offset);
-        offset += 8;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Assign account to a program (owner)
-    ///
-    /// @param pubkey the public key for the account whose owner is going to be reassigned
-    /// @param owner the public key for the new account owner
-    function assign(address pubkey, address owner) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pubkey, is_signer: true, is_writable: true})
-        ];
-        bytes bincode = abi.encode(uint32(Instruction.Assign), owner);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Assign account to a program (owner) based on a seed
-    ///
-    /// @param addr the public key for the account whose owner is going to be reassigned. The public key must match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to created the 'addr' public key
-    /// @param owner the public key for the new program owner
-    function assign_with_seed(address addr, address base, string seed, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-
-        uint32 buffer_size = 76 + seed.length;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.AssignWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(uint64(seed.length), 36);
-        bincode.writeString(seed, 44);
-        bincode.writeAddress(owner, 44 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports between accounts
-    ///
-    /// @param from public key for the funding account
-    /// @param to public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer(address from, address to, uint64 lamports) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: from, is_signer: true, is_writable: true}),
-            AccountMeta({pubkey: to, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Transfer), lamports);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Transfer lamports from a derived address
-    ///
-    /// @param from_pubkey The funding account public key. It should match create_with_seed(from_base, seed, from_owner)
-    /// @param from_base the base address that derived the 'from_pubkey' key using the seed
-    /// @param seed the string utilized to create the 'from_pubkey' public key
-    /// @param from_owner owner to use to derive the funding account address
-    /// @param to_pubkey the public key for the recipient account
-    /// @param lamports amount of lamports to transfer
-    function transfer_with_seed(address from_pubkey, address from_base, string seed, address from_owner, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: from_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: from_base, is_signer: true, is_writable: false}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true})
-        ];
-
-        uint32 buffer_size = seed.length + 52;
-        bytes bincode = new bytes(buffer_size);
-        bincode.writeUint32LE(uint32(Instruction.TransferWithSeed), 0);
-        bincode.writeUint64LE(lamports, 4);
-        bincode.writeUint64LE(seed.length, 12);
-        bincode.writeString(seed, 20);
-        bincode.writeAddress(from_owner, 20 + seed.length);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Allocate space in a (possibly new) account without funding
-    ///
-    /// @param pub_key account for which to allocate space
-    /// @param space number of bytes of memory to allocate
-    function allocate(address pub_key, uint64 space) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: pub_key, is_signer: true, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.Allocate), space);
-
-        systemAddress.call{accounts: meta}(bincode);
-    }
-
-    /// Allocate space for an assign an account at an address derived from a base public key and a seed
-    ///
-    /// @param addr account for which to allocate space. It should match create_with_seed(base, seed, owner)
-    /// @param base the base address that derived the 'addr' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param space number of bytes of memory to allocate
-    /// @param owner owner to use to derive the 'addr' account address
-    function allocate_with_seed(address addr, address base, string seed, uint64 space, address owner) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: addr, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: base, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = new bytes(seed.length + 84);
-        bincode.writeUint32LE(uint32(Instruction.AllocateWithSeed), 0);
-        bincode.writeAddress(base, 4);
-        bincode.writeUint64LE(seed.length, 36);
-        bincode.writeString(seed, 44);
-        uint32 offset = 44 + seed.length;
-        bincode.writeUint64LE(space, offset);
-        offset += 8;
-        bincode.writeAddress(owner, offset);
-
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new nonce account on Solana using a public key derived from a seed
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the account to be created. The public key must match create_with_seed(base, seed, systemAddress)
-    /// @param base the base address that derived the 'nonce' key using the seed
-    /// @param seed the string utilized to create the 'addr' public key
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account_with_seed(address from, address nonce, address base, string seed, address authority, uint64 lamports) internal view {
-        create_account_with_seed(from, nonce, base, seed, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Create a new account on Solana
-    ///
-    /// @param from public key for the account from which to transfer lamports to the new account
-    /// @param nonce the public key for the nonce account to be created
-    /// @param authority The entity authorized to execute nonce instructions on the account
-    /// @param lamports amount of lamports to be transfered to the new account
-    function create_nonce_account(address from, address nonce, address authority, uint64 lamports) internal view {
-        create_account(from, nonce, lamports, state_size, systemAddress);
-
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.InitializeNonceAccount), authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Consumes a stored nonce, replacing it with a successor
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the publick key for the entity authorized to execute instructins on the account
-    function advance_nonce_account(address nonce_pubkey, address authorized_pubkey) internal view {
-        AccountMeta[3] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AdvanceNounceAccount));
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Withdraw funds from a nonce account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param to_pubkey the recipient account
-    /// @param lamports the number of lamports to withdraw
-    function withdraw_nonce_account(address nonce_pubkey, address authorized_pubkey, address to_pubkey, uint64 lamports) internal view {
-        AccountMeta[5] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: to_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: recentBlockHashes, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: rentAddress, is_signer: false, is_writable: false}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.WithdrawNonceAccount), lamports);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// Change the entity authorized to execute nonce instructions on the account
-    ///
-    /// @param nonce_pubkey the public key for the nonce account
-    /// @param authorized_pubkey the public key for the entity authorized to execute instructins on the account
-    /// @param new_authority
-    function authorize_nonce_account(address nonce_pubkey, address authorized_pubkey, address new_authority) internal view {
-        AccountMeta[2] metas = [
-            AccountMeta({pubkey: nonce_pubkey, is_signer: false, is_writable: true}),
-            AccountMeta({pubkey: authorized_pubkey, is_signer: true, is_writable: false})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.AuthorizeNonceAccount), new_authority);
-        systemAddress.call{accounts: metas}(bincode);
-    }
-
-    /// One-time idempotent upgrade of legacy nonce version in order to bump them out of chain domain.
-    ///
-    /// @param nonce the public key for the nonce account
-    // This is not available on Solana v1.9.15
-    function upgrade_nonce_account(address nonce) internal view {
-        AccountMeta[1] meta = [
-            AccountMeta({pubkey: nonce, is_signer: false, is_writable: true})
-        ];
-
-        bytes bincode = abi.encode(uint32(Instruction.UpgradeNonceAccount));
-        systemAddress.call{accounts: meta}(bincode);
-    }
-}

+ 6 - 6
tokens/transfer-tokens/solang/solidity/transfer-tokens.sol

@@ -1,12 +1,12 @@
 
-import "./spl_token.sol";
-import "./mpl_metadata.sol";
+import "../libraries/spl_token.sol";
+import "../libraries/mpl_metadata.sol";
 
 @program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC")
 contract transfer_tokens {
 
     @payer(payer)
-    constructor(address payer) {}
+    constructor() {}
 
     function createTokenMint(
         address payer, // payer account
@@ -18,7 +18,7 @@ contract transfer_tokens {
         string name, // name for the metadata account
         string symbol, // symbol for the metadata account
         string uri // uri for the metadata account
-    ) public view {
+    ) public {
         // Invoke System Program to create a new account for the mint account and,
         // Invoke Token Program to initialize the mint account
         // Set mint authority, freeze authority, and decimals for the mint account
@@ -49,7 +49,7 @@ contract transfer_tokens {
         address mint, // mint account
         address owner, // token account owner
         uint64 amount // amount to mint
-    ) public view {
+    ) public {
         // Mint token to the token account
         SplToken.mint_to(
             mint, // mint account
@@ -64,7 +64,7 @@ contract transfer_tokens {
         address from, // token account to transfer from
         address to, // token account to transfer to
         uint64 amount // amount to transfer
-    ) public view {
+    ) public {
         SplToken.TokenAccountData from_data = SplToken.get_token_account_data(from);
         SplToken.transfer(from, to, from_data.owner, amount);
     }

+ 36 - 36
tokens/transfer-tokens/solang/tests/transfer-tokens.ts

@@ -1,48 +1,48 @@
-import * as anchor from "@coral-xyz/anchor"
-import { Program } from "@coral-xyz/anchor"
-import { TransferTokens } from "../target/types/transfer_tokens"
-import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js"
-import { Metaplex } from "@metaplex-foundation/js"
+import * as anchor from "@coral-xyz/anchor";
+import { Program } from "@coral-xyz/anchor";
+import { TransferTokens } from "../target/types/transfer_tokens";
+import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from "@solana/web3.js";
+import { Metaplex } from "@metaplex-foundation/js";
 import {
   ASSOCIATED_TOKEN_PROGRAM_ID,
   getAssociatedTokenAddressSync,
   getOrCreateAssociatedTokenAccount,
   TOKEN_PROGRAM_ID,
-} from "@solana/spl-token"
+} from "@solana/spl-token";
 
 describe("Transfer Tokens", () => {
   // Configure the client to use the local cluster.
-  const provider = anchor.AnchorProvider.env()
-  anchor.setProvider(provider)
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
-  const dataAccount = anchor.web3.Keypair.generate()
-  const mintKeypair = anchor.web3.Keypair.generate()
-  const wallet = provider.wallet as anchor.Wallet
-  const connection = provider.connection
+  const dataAccount = anchor.web3.Keypair.generate();
+  const mintKeypair = anchor.web3.Keypair.generate();
+  const wallet = provider.wallet as anchor.Wallet;
+  const connection = provider.connection;
 
-  const program = anchor.workspace.TransferTokens as Program<TransferTokens>
+  const program = anchor.workspace.TransferTokens as Program<TransferTokens>;
 
-  const nftTitle = "Homer NFT"
-  const nftSymbol = "HOMR"
+  const nftTitle = "Homer NFT";
+  const nftSymbol = "HOMR";
   const nftUri =
-    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json"
+    "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/nft.json";
 
   it("Is initialized!", async () => {
     // Add your test here.
     const tx = await program.methods
-      .new(wallet.publicKey)
+      .new()
       .accounts({ dataAccount: dataAccount.publicKey })
       .signers([dataAccount])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
 
   it("Create an SPL Token!", async () => {
-    const metaplex = Metaplex.make(connection)
+    const metaplex = Metaplex.make(connection);
     const metadataAddress = await metaplex
       .nfts()
       .pdas()
-      .metadata({ mint: mintKeypair.publicKey })
+      .metadata({ mint: mintKeypair.publicKey });
 
     // Add your test here.
     const tx = await program.methods
@@ -75,9 +75,9 @@ describe("Transfer Tokens", () => {
         { pubkey: SYSVAR_RENT_PUBKEY, isWritable: false, isSigner: false },
       ])
       .signers([mintKeypair])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Mint some tokens to your wallet!", async () => {
     // Wallet's associated token account address for mint
@@ -86,7 +86,7 @@ describe("Transfer Tokens", () => {
       wallet.payer, // payer
       mintKeypair.publicKey, // mint
       wallet.publicKey // owner
-    )
+    );
 
     const tx = await program.methods
       .mintTo(
@@ -117,9 +117,9 @@ describe("Transfer Tokens", () => {
           isSigner: false,
         },
       ])
-      .rpc({ skipPreflight: true })
-    console.log("Your transaction signature", tx)
-  })
+      .rpc({ skipPreflight: true });
+    console.log("Your transaction signature", tx);
+  });
 
   it("Transfer some tokens to another wallet!", async () => {
     // Wallet's associated token account address for mint
@@ -128,15 +128,15 @@ describe("Transfer Tokens", () => {
       wallet.payer, // payer
       mintKeypair.publicKey, // mint
       wallet.publicKey // owner
-    )
+    );
 
-    const receipient = anchor.web3.Keypair.generate()
+    const receipient = anchor.web3.Keypair.generate();
     const receipientTokenAccount = await getOrCreateAssociatedTokenAccount(
       connection,
       wallet.payer, // payer
       mintKeypair.publicKey, // mint account
       receipient.publicKey // owner account
-    )
+    );
 
     const tx = await program.methods
       .transferTokens(
@@ -167,7 +167,7 @@ describe("Transfer Tokens", () => {
           isSigner: false,
         },
       ])
-      .rpc()
-    console.log("Your transaction signature", tx)
-  })
-})
+      .rpc();
+    console.log("Your transaction signature", tx);
+  });
+});

+ 9 - 9
tokens/transfer-tokens/solang/tsconfig.json

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