diff --git a/basics/account-data/solang/.gitignore b/basics/account-data/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/account-data/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/account-data/solang/Anchor.toml b/basics/account-data/solang/Anchor.toml deleted file mode 100644 index b4c03a37..00000000 --- a/basics/account-data/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -account_data = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/account-data/solang/package.json b/basics/account-data/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/account-data/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/account-data/solang/solidity/account-data.sol b/basics/account-data/solang/solidity/account-data.sol deleted file mode 100644 index 498ae5e8..00000000 --- a/basics/account-data/solang/solidity/account-data.sol +++ /dev/null @@ -1,42 +0,0 @@ - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract account_data { - // A private instance of the AddressInfo struct - // This is the data that is stored in the account - AddressInfo private addressInfo; - - // The AddressInfo struct definition - struct AddressInfo { - string name; - uint8 houseNumber; - string street; - string city; - } - - @payer(payer) // "payer" is the account that pays to create the dataAccount - 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); - } - - // A function to get the addressInfo data stored on the account - function get() public view returns (AddressInfo) { - return addressInfo; - } - - // A function to get the size in bytes of the stored AddressInfo - function getAddressInfoSize() public view returns(uint) { - uint size = 0; - size += bytes(addressInfo.name).length; - size += 1; // For houseNumber, which is uint8 and takes 1 byte - size += bytes(addressInfo.street).length; - size += bytes(addressInfo.city).length; - return size; - } -} diff --git a/basics/account-data/solang/tests/account-data.ts b/basics/account-data/solang/tests/account-data.ts deleted file mode 100644 index edf7c8af..00000000 --- a/basics/account-data/solang/tests/account-data.ts +++ /dev/null @@ -1,52 +0,0 @@ -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); - - // 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; - - // Create the new account - // Using 10240 bytes of space, because its unclear how to correctly calculate the minimum space needed for the account - // Space calculation is different from regular Native/Anchor Solana programs - it("Is initialized!", async () => { - const tx = await program.methods - .new( - 10240, // space (10240 bytes is the maximum space allowed when allocating space through a program) - "Joe C", // name - 136, // house number - "Mile High Dr.", // street - "Solana Beach" // city - ) - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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); - }); - - // Get the account data size - // Testing how much space is used to store the account data - // However, minimum space required is greater than this - it("Get AddressInfo Size", async () => { - const size = await program.methods - .getAddressInfoSize() - .accounts({ dataAccount: dataAccount.publicKey }) - .view(); - console.log("Size:", size.toNumber()); - }); -}); diff --git a/basics/account-data/solang/tsconfig.json b/basics/account-data/solang/tsconfig.json deleted file mode 100644 index 9abe3197..00000000 --- a/basics/account-data/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/checking-accounts/solang/.gitignore b/basics/checking-accounts/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/checking-accounts/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/checking-accounts/solang/Anchor.toml b/basics/checking-accounts/solang/Anchor.toml deleted file mode 100644 index 71dfc3e8..00000000 --- a/basics/checking-accounts/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -checking_accounts = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/checking-accounts/solang/package.json b/basics/checking-accounts/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/checking-accounts/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/checking-accounts/solang/solidity/checking-accounts.sol b/basics/checking-accounts/solang/solidity/checking-accounts.sol deleted file mode 100644 index 0fd84eef..00000000 --- a/basics/checking-accounts/solang/solidity/checking-accounts.sol +++ /dev/null @@ -1,42 +0,0 @@ - -import "solana"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -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() {} - - @account(accountToChange) - @mutableSigner(accountToCreate) - function checkAccounts(address accountToChange, address accountToCreate) external view { - print("Number of Accounts Provided: {:}".format(tx.accounts.length)); - - // Perform checks on the account - programOwnerCheck(tx.accounts.accountToChange); - notInitializedCheck(tx.accounts.accountToCreate); - signerCheck(tx.accounts.accountToCreate); - - // (Create account...) (unimplemented) - // (Change account...) (unimplemented) - } - - function programOwnerCheck(AccountInfo account) internal pure { - print("Progam Owner Check"); - // The owner of this account should be this program - require(account.owner == type(checking_accounts).program_id, "Account to change does not have the correct program id."); - } - - function notInitializedCheck(AccountInfo account) internal pure { - print("Check Account Not Initialized"); - // This account should not be initialized (has no lamports) - require(account.lamports == 0, "The program expected the account to create to not yet be initialized."); - } - - function signerCheck(AccountInfo account) internal pure { - print("Check Account Signed Transaction"); - // This account should be a signer on the transaction - require(account.is_signer, "Account required to be a signer"); - } -} diff --git a/basics/checking-accounts/solang/tests/checking-accounts.ts b/basics/checking-accounts/solang/tests/checking-accounts.ts deleted file mode 100644 index 21f49728..00000000 --- a/basics/checking-accounts/solang/tests/checking-accounts.ts +++ /dev/null @@ -1,66 +0,0 @@ -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"; - -describe("checking-accounts", () => { - // Configure the client to use the local cluster. - const provider = anchor.AnchorProvider.env(); - anchor.setProvider(provider); - - // Generate a new random keypair for the data account. - const dataAccount = anchor.web3.Keypair.generate(); - - // Generate a new keypair to represent the account we will change. - 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 program = anchor.workspace - .CheckingAccounts as Program; - - 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() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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 - let ix = SystemProgram.createAccount({ - fromPubkey: wallet.publicKey, - newAccountPubkey: accountToChange.publicKey, - 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" - const tx = await program.methods - .checkAccounts(accountToChange.publicKey, accountToCreate.publicKey) - .accounts({ - accountToCreate: accountToCreate.publicKey, - accountToChange: accountToChange.publicKey, - }) - .signers([accountToCreate]) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/basics/checking-accounts/solang/tsconfig.json b/basics/checking-accounts/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/checking-accounts/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/counter/solang/.gitignore b/basics/counter/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/counter/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/counter/solang/Anchor.toml b/basics/counter/solang/Anchor.toml deleted file mode 100644 index df009e86..00000000 --- a/basics/counter/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -counter = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/counter/solang/package.json b/basics/counter/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/counter/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/counter/solang/solidity/counter.sol b/basics/counter/solang/solidity/counter.sol deleted file mode 100644 index 2b4b1e98..00000000 --- a/basics/counter/solang/solidity/counter.sol +++ /dev/null @@ -1,23 +0,0 @@ - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract counter { - // The counter value that is stored in the account - uint64 private count; - - // The constructor is used to create a new counter account - @payer(payer) // The "payer" pays for the counter account creation - constructor() { - // Initialize the count to zero - count = 0; - } - - // Increments the count by one. - function increment() public { - count += 1; - } - - // Returns the count value - function get() public view returns (uint64) { - return count; - } -} diff --git a/basics/counter/solang/tests/counter.ts b/basics/counter/solang/tests/counter.ts deleted file mode 100644 index 67138911..00000000 --- a/basics/counter/solang/tests/counter.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as anchor from "@coral-xyz/anchor" -import { Program } from "@coral-xyz/anchor" -import { Counter } from "../target/types/counter" -import { assert } from "chai" - -describe("counter", () => { - // Configure the client to use the local cluster. - 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.Counter as Program - - it("Is initialized!", async () => { - // Initialize new Counter account - const tx = await program.methods - .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) - - // Fetch the counter value - const val = await program.methods - .get() - .accounts({ dataAccount: dataAccount.publicKey }) - .view() - - assert(Number(val) === 0) - console.log("Count:", Number(val)) - }) - - it("Increment", async () => { - // Increment the counter - const tx = await program.methods - .increment() - .accounts({ dataAccount: dataAccount.publicKey }) - .rpc() - console.log("Your transaction signature", tx) - - // Fetch the counter value - const val = await program.methods - .get() - .accounts({ dataAccount: dataAccount.publicKey }) - .view() - - assert(Number(val) === 1) - console.log("Count:", Number(val)) - }) -}) diff --git a/basics/counter/solang/tsconfig.json b/basics/counter/solang/tsconfig.json deleted file mode 100644 index 3c8dd81c..00000000 --- a/basics/counter/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } - } - \ No newline at end of file diff --git a/basics/cross-program-invocation/solang/.gitignore b/basics/cross-program-invocation/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/cross-program-invocation/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/cross-program-invocation/solang/Anchor.toml b/basics/cross-program-invocation/solang/Anchor.toml deleted file mode 100644 index 16b6ca45..00000000 --- a/basics/cross-program-invocation/solang/Anchor.toml +++ /dev/null @@ -1,16 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -hand = "9rN5nSQBX1gcbweshWAfRE4Ccv5puJfxUJhqKZ5BEdoP" -lever = "4wFN9As94uDgcBK9umEi6DNjRLi8gq7jaHwSw3829xq8" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/cross-program-invocation/solang/package.json b/basics/cross-program-invocation/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/cross-program-invocation/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/cross-program-invocation/solang/solidity/hand.sol b/basics/cross-program-invocation/solang/solidity/hand.sol deleted file mode 100644 index 40a4c655..00000000 --- a/basics/cross-program-invocation/solang/solidity/hand.sol +++ /dev/null @@ -1,33 +0,0 @@ - -import "solana"; - -// Interface to the lever program. -@program_id("4wFN9As94uDgcBK9umEi6DNjRLi8gq7jaHwSw3829xq8") -interface leverInterface { - function switchPower(string name) external; -} - -@program_id("9rN5nSQBX1gcbweshWAfRE4Ccv5puJfxUJhqKZ5BEdoP") -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() {} - - // "Pull the lever" by calling the switchPower instruction on the lever program via a Cross Program Invocation. - @mutableAccount(leverData) - function pullLever(string name) external { - // The account required by the switchPower instruction. - // This is the data account created by the lever program (not this program), which stores the state of the switch. - AccountMeta[1] metas = [ - AccountMeta({pubkey: tx.accounts.leverData.key, is_writable: true, is_signer: false}) - ]; - - // The data required by the switchPower instruction. - string instructionData = name; - - // Invoke the switchPower instruction on the lever program. - leverInterface.switchPower{accounts: metas}(instructionData); - } -} diff --git a/basics/cross-program-invocation/solang/solidity/lever.sol b/basics/cross-program-invocation/solang/solidity/lever.sol deleted file mode 100644 index e9b349e3..00000000 --- a/basics/cross-program-invocation/solang/solidity/lever.sol +++ /dev/null @@ -1,30 +0,0 @@ - -@program_id("4wFN9As94uDgcBK9umEi6DNjRLi8gq7jaHwSw3829xq8") -contract lever { - // Switch state - bool private isOn = true; - - @payer(payer) // payer for the data account - constructor() {} - - // Switch the power on or off - function switchPower(string name) public { - // Flip the switch - isOn = !isOn; - - // Print the name of the person who pulled the switch - print("{:} is pulling the power switch!".format(name)); - - // Print the current state of the switch - if (isOn){ - print("The power is now on."); - } else { - print("The power is now off!"); - } - } - - // Get the current state of the switch - function get() public view returns (bool) { - return isOn; - } -} diff --git a/basics/cross-program-invocation/solang/tests/test.ts b/basics/cross-program-invocation/solang/tests/test.ts deleted file mode 100644 index 83ae6cb6..00000000 --- a/basics/cross-program-invocation/solang/tests/test.ts +++ /dev/null @@ -1,87 +0,0 @@ -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); - - // 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; - - // The lever program and hand program - const leverProgram = anchor.workspace.Lever as Program; - const handProgram = anchor.workspace.Hand as Program; - - it("Initialize the lever!", async () => { - // Initialize data account for the lever program - const tx = await leverProgram.methods - .new() - .accounts({ dataAccount: dataAccountLever.publicKey }) - .signers([dataAccountLever]) - .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(); - - 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() - .accounts({ dataAccount: dataAccountHand.publicKey }) - .signers([dataAccountHand]) - .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 - .pullLever("Chris") - .accounts({ - leverData: dataAccountLever.publicKey, // The lever program's data account, which stores the state - leverInterface_programId: leverProgram.programId // The lever program's program ID - }) - .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(); - - console.log("State:", val); - }); - - it("Pull it again!", async () => { - // Call the pullLever instruction on the hand program, which invokes the lever program via CPI - const tx = await handProgram.methods - .pullLever("Ashley") - .accounts({ - leverData: dataAccountLever.publicKey, // The lever program's data account, which stores the state - leverInterface_programId: leverProgram.programId, // The lever program's program ID - }) - .rpc({ skipPreflight: true }); - - console.log("Your transaction signature", tx); - - // Fetch the state of the data account - const val = await leverProgram.methods - .get() - .accounts({ dataAccount: dataAccountLever.publicKey }) - .view(); - - console.log("State:", val); - }); -}); diff --git a/basics/cross-program-invocation/solang/tsconfig.json b/basics/cross-program-invocation/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/cross-program-invocation/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/hello-solana/solang/.gitignore b/basics/hello-solana/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/hello-solana/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/hello-solana/solang/Anchor.toml b/basics/hello-solana/solang/Anchor.toml deleted file mode 100644 index a1584295..00000000 --- a/basics/hello-solana/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -hello_solana = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/hello-solana/solang/package.json b/basics/hello-solana/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/hello-solana/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/hello-solana/solang/solidity/hello-solana.sol b/basics/hello-solana/solang/solidity/hello-solana.sol deleted file mode 100644 index 64db21f8..00000000 --- a/basics/hello-solana/solang/solidity/hello-solana.sol +++ /dev/null @@ -1,15 +0,0 @@ - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -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() { - // We get the program ID by calling 'this'; - address programId = address(this); - - // Print messages to the program logs - print("Hello, Solana!"); - print("Our program's Program ID: {:}".format(programId)); - } -} diff --git a/basics/hello-solana/solang/tests/hello-solana.ts b/basics/hello-solana/solang/tests/hello-solana.ts deleted file mode 100644 index 8c68c077..00000000 --- a/basics/hello-solana/solang/tests/hello-solana.ts +++ /dev/null @@ -1,25 +0,0 @@ -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); - - // Generate a new random keypair for the data account. - const dataAccount = anchor.web3.Keypair.generate(); - const wallet = provider.wallet; - - const program = anchor.workspace.HelloSolana as Program; - - it("Is initialized!", async () => { - // Initialize a new data account - const tx = await program.methods - .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); - }); -}); diff --git a/basics/hello-solana/solang/tsconfig.json b/basics/hello-solana/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/hello-solana/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/pda-rent-payer/solang/.gitignore b/basics/pda-rent-payer/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/pda-rent-payer/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/pda-rent-payer/solang/Anchor.toml b/basics/pda-rent-payer/solang/Anchor.toml deleted file mode 100644 index 92f3b296..00000000 --- a/basics/pda-rent-payer/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -pda_rent_payer = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/pda-rent-payer/solang/libraries/system_instruction.sol b/basics/pda-rent-payer/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/basics/pda-rent-payer/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/basics/pda-rent-payer/solang/package.json b/basics/pda-rent-payer/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/pda-rent-payer/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/pda-rent-payer/solang/solidity/pda-rent-payer.sol b/basics/pda-rent-payer/solang/solidity/pda-rent-payer.sol deleted file mode 100644 index 0863771c..00000000 --- a/basics/pda-rent-payer/solang/solidity/pda-rent-payer.sol +++ /dev/null @@ -1,37 +0,0 @@ - -import "../libraries/system_instruction.sol"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract pda_rent_payer { - - @payer(payer) // "payer" is the account that pays for creating the account - @seed("rent_vault") // hardcoded seed - 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"], address(this)); - - // 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) - require(bump == _bump, 'INVALID_BUMP'); - - // Fund the pda account with additional lamports - SystemInstruction.transfer( - tx.accounts.payer.key, // from - tx.accounts.dataAccount.key, // to (the address of the account being created) - fundLamports // amount of lamports to transfer - ); - } - - @mutableAccount(ownedByProgram) - @mutableAccount(intendedRecipient) - function createNewAccount(uint64 lamports) external { - AccountInfo from = tx.accounts.ownedByProgram; // an account owned by the program - AccountInfo to = tx.accounts.intendedRecipient; // second account must be the intended recipient - - print("From: {:}".format(from.key)); - print("To: {:}".format(to.key)); - - from.lamports -= lamports; - to.lamports += lamports; - } -} diff --git a/basics/pda-rent-payer/solang/tests/pda-rent-payer.ts b/basics/pda-rent-payer/solang/tests/pda-rent-payer.ts deleted file mode 100644 index 00e0dd6f..00000000 --- a/basics/pda-rent-payer/solang/tests/pda-rent-payer.ts +++ /dev/null @@ -1,57 +0,0 @@ -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 wallet = provider.wallet; - const connection = provider.connection; - - const program = anchor.workspace.PdaRentPayer as Program; - - // Amount of additional lamports to fund the dataAccount with. - 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([bump], new anchor.BN(fundLamports)) - .accounts({ dataAccount: dataAccountPDA }) - .rpc(); - console.log("Your transaction signature", tx); - - 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 - - // Get the minimum balance for the account to be rent exempt. - const lamports = await connection.getMinimumBalanceForRentExemption(space); - - // Invoke the createNewAccount instruction on our program - const tx = await program.methods - .createNewAccount(new anchor.BN(lamports)) - .accounts({ - ownedByProgram: dataAccountPDA, - intendedRecipient: newAccount.publicKey, // account to create by directly transferring lamports - }) - .rpc(); - console.log("Your transaction signature", tx); - - const accountInfo = await connection.getAccountInfo(newAccount.publicKey); - console.log("AccountInfo Lamports:", accountInfo.lamports); - }); -}); diff --git a/basics/pda-rent-payer/solang/tsconfig.json b/basics/pda-rent-payer/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/pda-rent-payer/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/processing-instructions/solang/.gitignore b/basics/processing-instructions/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/processing-instructions/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/processing-instructions/solang/.prettierignore b/basics/processing-instructions/solang/.prettierignore deleted file mode 100644 index c1a0b75f..00000000 --- a/basics/processing-instructions/solang/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -node_modules -dist -build -test-ledger diff --git a/basics/processing-instructions/solang/Anchor.toml b/basics/processing-instructions/solang/Anchor.toml deleted file mode 100644 index 6dbb482d..00000000 --- a/basics/processing-instructions/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -processing_instructions = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/processing-instructions/solang/package.json b/basics/processing-instructions/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/processing-instructions/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/processing-instructions/solang/solidity/processing-instructions.sol b/basics/processing-instructions/solang/solidity/processing-instructions.sol deleted file mode 100644 index 4e286a75..00000000 --- a/basics/processing-instructions/solang/solidity/processing-instructions.sol +++ /dev/null @@ -1,18 +0,0 @@ - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract processing_instructions { - - @payer(payer) // payer for the data account, required by Solang but not used in this example - constructor() {} - - function goToPark(string name, uint32 height) public pure { - // Print messages to the program logs - print("Welcome to the park, {:}".format(name)); - - if (height >5) { - print("You are tall enough to ride this ride. Congratulations."); - } else { - print("You are NOT tall enough to ride this ride. Sorry mate."); - } - } -} diff --git a/basics/processing-instructions/solang/tests/processing-instructions.ts b/basics/processing-instructions/solang/tests/processing-instructions.ts deleted file mode 100644 index bd9723f1..00000000 --- a/basics/processing-instructions/solang/tests/processing-instructions.ts +++ /dev/null @@ -1,40 +0,0 @@ -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); - - // Generate a new keypair for the data account for the program - const dataAccount = anchor.web3.Keypair.generate(); - const wallet = provider.wallet; - - const program = anchor.workspace - .ProcessingInstructions as Program; - - it("Is initialized!", async () => { - // Initialize data account for the program, which is required by Solang - const tx = await program.methods - .new() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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(); - - // Call the goToPark instruction on the program, providing the instruction data - await program.methods - .goToPark("Mary", 10) - .accounts({ dataAccount: dataAccount.publicKey }) - .rpc(); - }); -}); diff --git a/basics/processing-instructions/solang/tsconfig.json b/basics/processing-instructions/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/processing-instructions/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/program-derived-addresses/solang/.gitignore b/basics/program-derived-addresses/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/program-derived-addresses/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/program-derived-addresses/solang/Anchor.toml b/basics/program-derived-addresses/solang/Anchor.toml deleted file mode 100644 index 336fd107..00000000 --- a/basics/program-derived-addresses/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -program_derived_addresses = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/program-derived-addresses/solang/package.json b/basics/program-derived-addresses/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/program-derived-addresses/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/program-derived-addresses/solang/solidity/program-derived-addresses.sol b/basics/program-derived-addresses/solang/solidity/program-derived-addresses.sol deleted file mode 100644 index 57be6f30..00000000 --- a/basics/program-derived-addresses/solang/solidity/program-derived-addresses.sol +++ /dev/null @@ -1,44 +0,0 @@ - -import "solana"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract program_derived_addresses { - // A private instance of the PageVisits struct - // This is the data that is stored in the account - PageVisits private accountData; - - // The PageVisits struct definition - struct PageVisits { - uint32 pageVisits; - bytes1 bump; - } - - // The constructor is used to create a new account - // 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 - 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", 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) - require(bump == _bump, 'INVALID_BUMP'); - - // The PageVisits instance is initialized with pageVisits set to zero and bump set to the bump passed to the constructor - accountData = PageVisits(0, bump); - } - - // Increments the pageVisits by one. - function incrementPageVisits() public { - accountData.pageVisits += 1; - } - - // Returns the accountData (pageVisits and bump) stored on the account - function get() public view returns (PageVisits) { - return accountData; - } -} diff --git a/basics/program-derived-addresses/solang/tests/program-derived-addresses.ts b/basics/program-derived-addresses/solang/tests/program-derived-addresses.ts deleted file mode 100644 index 01f97c63..00000000 --- a/basics/program-derived-addresses/solang/tests/program-derived-addresses.ts +++ /dev/null @@ -1,60 +0,0 @@ -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 wallet = provider.wallet; - - const program = anchor.workspace - .ProgramDerivedAddresses as Program; - - // 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. - // The PDA doesn't have to be passed in explicity as a signer, the program can "sign" for it. - // 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.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); - - // Get the current state of the dataAccount. - const val = await program.methods - .get() - .accounts({ dataAccount: dataAccountPDA }) - .view(); - - 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); - - // Get the current state of the dataAccount. - const val = await program.methods - .get() - .accounts({ dataAccount: dataAccountPDA }) - .view(); - - console.log("State:", val); - }); -}); diff --git a/basics/program-derived-addresses/solang/tsconfig.json b/basics/program-derived-addresses/solang/tsconfig.json deleted file mode 100644 index cd5d2e3d..00000000 --- a/basics/program-derived-addresses/solang/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} diff --git a/basics/rent/solang/.gitignore b/basics/rent/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/rent/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/rent/solang/Anchor.toml b/basics/rent/solang/Anchor.toml deleted file mode 100644 index 595f325a..00000000 --- a/basics/rent/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -rent = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/rent/solang/libraries/minimum_balance.sol b/basics/rent/solang/libraries/minimum_balance.sol deleted file mode 100644 index 77ef3e88..00000000 --- a/basics/rent/solang/libraries/minimum_balance.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -// Disclaimer: This library provides functions for working with storage rent. Although it is production ready, -// it has not been audited for security, so use it at your own risk. - -// This is the Solidity version of the rust module rent: -// https://github.com/solana-labs/solana/blob/master/sdk/program/src/rent.rs -// As rent is currently not implemented on Solana, only the minimum balance is required. - -/// Default rental rate in lamports/byte-year. -/// -/// This calculation is based on: -/// - 10^9 lamports per SOL -/// - $1 per SOL -/// - $0.01 per megabyte day -/// - $3.65 per megabyte year -uint64 constant DEFAULT_LAMPORTS_PER_BYTE_YEAR = 1_000_000_000 / 100 * 365 / (1024 * 1024); - -/// Default amount of time (in years) the balance has to include rent for the -/// account to be rent exempt. -uint64 constant DEFAULT_EXEMPTION_THRESHOLD = 2; - -/// Account storage overhead for calculation of base rent. -/// -/// This is the number of bytes required to store an account with no data. It is -/// added to an accounts data length when calculating [`Rent::minimum_balance`]. -uint64 constant ACCOUNT_STORAGE_OVERHEAD = 128; - -/// Minimum balance due for rent-exemption of a given account data size. -function minimum_balance(uint64 data_len) pure returns (uint64) { - return ((ACCOUNT_STORAGE_OVERHEAD + data_len) * DEFAULT_LAMPORTS_PER_BYTE_YEAR) - * DEFAULT_EXEMPTION_THRESHOLD; -} \ No newline at end of file diff --git a/basics/rent/solang/libraries/system_instruction.sol b/basics/rent/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/basics/rent/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/basics/rent/solang/package.json b/basics/rent/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/rent/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/rent/solang/solidity/rent.sol b/basics/rent/solang/solidity/rent.sol deleted file mode 100644 index a2aa279a..00000000 --- a/basics/rent/solang/solidity/rent.sol +++ /dev/null @@ -1,26 +0,0 @@ - -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() {} - - @mutableSigner(payer) - @mutableSigner(newAccount) - function createSystemAccount(uint64 space) external { - // The minimum lamports required for the amount of space allocated to the account - uint64 lamports = minimum_balance(space); - - SystemInstruction.create_account( - tx.accounts.payer.key, // lamports sent from this account (payer) - tx.accounts.newAccount.key, // lamports sent to this account (account to be created) - lamports, // lamport amount (minimum lamports required) - space, // space required for the account - SystemInstruction.systemAddress // program owner (system program) - ); - } - -} diff --git a/basics/rent/solang/tests/rent.ts b/basics/rent/solang/tests/rent.ts deleted file mode 100644 index e790ecd4..00000000 --- a/basics/rent/solang/tests/rent.ts +++ /dev/null @@ -1,46 +0,0 @@ -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); - - // 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 program = anchor.workspace.Rent as Program; - - it("Is initialized!", async () => { - // Initialize data account for the program, which is required by Solang - const tx = await program.methods - .new() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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(); - // Number of bytes of space to allocate for the account - const space = 100; - - // Create a new account via a Cross Program Invocation to the system program - const tx = await program.methods - .createSystemAccount( - new anchor.BN(space) // space - ) - .accounts({ - payer: wallet.publicKey, - newAccount: newAccount.publicKey, - }) - .signers([newAccount]) // new account keypair required as signer - .rpc(); - console.log("Your transaction signature", tx); - }); -}); diff --git a/basics/rent/solang/tsconfig.json b/basics/rent/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/basics/rent/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/basics/transfer-sol/solang/.gitignore b/basics/transfer-sol/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/basics/transfer-sol/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/basics/transfer-sol/solang/.prettierignore b/basics/transfer-sol/solang/.prettierignore deleted file mode 100644 index c1a0b75f..00000000 --- a/basics/transfer-sol/solang/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -node_modules -dist -build -test-ledger diff --git a/basics/transfer-sol/solang/Anchor.toml b/basics/transfer-sol/solang/Anchor.toml deleted file mode 100644 index 69c86155..00000000 --- a/basics/transfer-sol/solang/Anchor.toml +++ /dev/null @@ -1,15 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -transfer_sol = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" diff --git a/basics/transfer-sol/solang/libraries/system_instruction.sol b/basics/transfer-sol/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/basics/transfer-sol/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/basics/transfer-sol/solang/package.json b/basics/transfer-sol/solang/package.json deleted file mode 100644 index eb9ad4fb..00000000 --- a/basics/transfer-sol/solang/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0" - }, - "devDependencies": { - "chai": "^4.3.4", - "mocha": "^9.0.3", - "ts-mocha": "^10.0.0", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "typescript": "^4.3.5", - "prettier": "^2.6.2" - } -} diff --git a/basics/transfer-sol/solang/solidity/transfer-sol.sol b/basics/transfer-sol/solang/solidity/transfer-sol.sol deleted file mode 100644 index 4e2549a6..00000000 --- a/basics/transfer-sol/solang/solidity/transfer-sol.sol +++ /dev/null @@ -1,34 +0,0 @@ - -import "../libraries/system_instruction.sol"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract transfer_sol { - - @payer(payer) // payer to create new data account - 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 - @mutableSigner(sender) - @mutableAccount(recipient) - function transferSolWithCpi(uint64 lamports) external { - // CPI to transfer SOL using "system_instruction" library - SystemInstruction.transfer(tx.accounts.sender.key, tx.accounts.recipient.key, lamports); - } - - // Transfer SOL from program owned account to another address by directly modifying the account data lamports - // This approach only works for accounts owned by the program itself (ex. the dataAccount created in the constructor) - @mutableAccount(sender) - @mutableAccount(recipient) - function transferSolWithProgram(uint64 lamports) external { - AccountInfo from = tx.accounts.sender; // first account must be an account owned by the program - AccountInfo to = tx.accounts.recipient; // second account must be the intended recipient - - print("From: {:}".format(from.key)); - print("To: {:}".format(to.key)); - - from.lamports -= lamports; - to.lamports += lamports; - } -} diff --git a/basics/transfer-sol/solang/tests/transfer-sol.ts b/basics/transfer-sol/solang/tests/transfer-sol.ts deleted file mode 100644 index 46a7082d..00000000 --- a/basics/transfer-sol/solang/tests/transfer-sol.ts +++ /dev/null @@ -1,103 +0,0 @@ -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); - - // Generate new keypair to use as data account - const dataAccount = anchor.web3.Keypair.generate(); - const wallet = provider.wallet; - const connection = provider.connection; - - const program = anchor.workspace.TransferSol as Program; - - // Amount to transfer in lamports - 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() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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 - - await getBalances(wallet.publicKey, recipient.publicKey, "Beginning"); - - const tx = await program.methods - .transferSolWithCpi( - new anchor.BN(transferAmount) // amount in lamports - ) - .accounts({ - sender: wallet.publicKey, - recipient: recipient.publicKey - }) - .rpc(); - - await getBalances(wallet.publicKey, recipient.publicKey, "Resulting"); - - console.log("Your transaction signature", tx); - }); - - it("Transfer SOL to program owned account", async () => { - await getBalances(wallet.publicKey, dataAccount.publicKey, "Beginning"); - - const tx = await program.methods - .transferSolWithCpi( - new anchor.BN(transferAmount) // amount in lamports - ) - .accounts({ - sender: wallet.publicKey, - recipient: dataAccount.publicKey, - }) - .rpc(); - - await getBalances(wallet.publicKey, dataAccount.publicKey, "Resulting"); - - console.log("Your transaction signature", tx); - }); - - it("Transfer SOL from program owned account", async () => { - await getBalances(dataAccount.publicKey, wallet.publicKey, "Beginning"); - - const tx = await program.methods - .transferSolWithProgram( - new anchor.BN(transferAmount) // amount in lamports - ) - .accounts({ - sender: dataAccount.publicKey, - recipient: wallet.publicKey, - }) - .rpc(); - - await getBalances(dataAccount.publicKey, wallet.publicKey, "Resulting"); - - console.log("Your transaction signature", tx); - }); - - // Helper function to get balances and log them to the console - async function getBalances( - payerPubkey: PublicKey, - 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 - console.log( - ` Recipient: ${recipientBalance / anchor.web3.LAMPORTS_PER_SOL}` // convert lamports to SOL - ); - } -}); diff --git a/basics/transfer-sol/solang/tsconfig.json b/basics/transfer-sol/solang/tsconfig.json deleted file mode 100644 index 558b83e5..00000000 --- a/basics/transfer-sol/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } - } - \ No newline at end of file diff --git a/compression/cnft-solang/.gitignore b/compression/cnft-solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/compression/cnft-solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/compression/cnft-solang/.prettierignore b/compression/cnft-solang/.prettierignore deleted file mode 100644 index c1a0b75f..00000000 --- a/compression/cnft-solang/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -node_modules -dist -build -test-ledger diff --git a/compression/cnft-solang/Anchor.toml b/compression/cnft-solang/Anchor.toml deleted file mode 100644 index 08608544..00000000 --- a/compression/cnft-solang/Anchor.toml +++ /dev/null @@ -1,30 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.devnet] -compressed_nft = "BvgEJTPXfriGPopjJr1nLc4vADXm7A7TqjLFVztpd19Q" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "devnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" - -[[test.validator.clone]] -address = "BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY" - -[[test.validator.clone]] -address = "noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV" - -[[test.validator.clone]] -address = "cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK" \ No newline at end of file diff --git a/compression/cnft-solang/app/.eslintrc.json b/compression/cnft-solang/app/.eslintrc.json deleted file mode 100644 index bffb357a..00000000 --- a/compression/cnft-solang/app/.eslintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "next/core-web-vitals" -} diff --git a/compression/cnft-solang/app/.gitignore b/compression/cnft-solang/app/.gitignore deleted file mode 100644 index eaaee160..00000000 --- a/compression/cnft-solang/app/.gitignore +++ /dev/null @@ -1,37 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -package-lock.json \ No newline at end of file diff --git a/compression/cnft-solang/app/README.md b/compression/cnft-solang/app/README.md deleted file mode 100644 index 965a1228..00000000 --- a/compression/cnft-solang/app/README.md +++ /dev/null @@ -1,38 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. - -[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. - -The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/compression/cnft-solang/app/components/Confirmed.tsx b/compression/cnft-solang/app/components/Confirmed.tsx deleted file mode 100644 index 4d4a2d74..00000000 --- a/compression/cnft-solang/app/components/Confirmed.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useState } from "react" -import { buildStyles, CircularProgressbar } from "react-circular-progressbar" -import "react-circular-progressbar/dist/styles.css" - -const Confirmed = () => { - const [percentage, setPercentage] = useState(0) - const [text, setText] = useState("😋") - - useEffect(() => { - const t1 = setTimeout(() => setPercentage(100), 100) - const t2 = setTimeout(() => setText("✅"), 600) - - return () => { - clearTimeout(t1) - clearTimeout(t2) - } - }, []) - - return ( - - ) -} - -export default Confirmed diff --git a/compression/cnft-solang/app/components/QrCodeCnftMint.tsx b/compression/cnft-solang/app/components/QrCodeCnftMint.tsx deleted file mode 100644 index dd24d976..00000000 --- a/compression/cnft-solang/app/components/QrCodeCnftMint.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { Button, Flex, VStack } from "@chakra-ui/react" -import { - createQR, - encodeURL, - findReference, - FindReferenceError, - TransactionRequestURLFields, - ValidateTransferError, -} from "@solana/pay" -import { clusterApiUrl, Connection, Keypair } from "@solana/web3.js" -import { useEffect, useRef, useState } from "react" -import Confirmed from "./Confirmed" - -interface Props { - onClose: () => void -} - -const QrModal = ({ onClose }: Props) => { - const [confirmed, setConfirmed] = useState(false) - const connection = new Connection(clusterApiUrl("devnet")) - const qrRef = useRef(null) - const [reference] = useState(Keypair.generate().publicKey) - - const [size, setSize] = useState(() => - typeof window === "undefined" ? 100 : Math.min(window.outerWidth - 10, 512) - ) - - useEffect(() => { - const listener = () => setSize(Math.min(window.outerWidth - 10, 512)) - window.addEventListener("resize", listener) - return () => window.removeEventListener("resize", listener) - }, []) - - useEffect(() => { - const { location } = window - const params = new URLSearchParams() - params.append("reference", reference.toString()) - - const apiUrl = `${location.protocol}//${ - location.host - }/api/mintCnft?${params.toString()}` - const urlParams: TransactionRequestURLFields = { - link: new URL(apiUrl), - label: "Label", - message: "Message", - } - const solanaUrl = encodeURL(urlParams) - console.log(solanaUrl) - const qr = createQR(solanaUrl, size, "white") - if (qrRef.current) { - qrRef.current.innerHTML = "" - qr.append(qrRef.current) - } - }, [window, size, reference]) - - useEffect(() => { - const interval = setInterval(async () => { - try { - const signatureInfo = await findReference(connection, reference, { - finality: "confirmed", - }) - setConfirmed(true) - } catch (e) { - if (e instanceof FindReferenceError) return - if (e instanceof ValidateTransferError) { - console.error("Transaction is invalid", e) - return - } - console.error("Unknown error", e) - } - }, 500) - return () => { - clearInterval(interval) - setConfirmed(false) - } - }, [reference.toString()]) - - return ( - - {confirmed ? ( -
- -
- ) : ( - - )} - -
- ) -} - -export default QrModal diff --git a/compression/cnft-solang/app/components/WalletMultiButton.tsx b/compression/cnft-solang/app/components/WalletMultiButton.tsx deleted file mode 100644 index 8f238001..00000000 --- a/compression/cnft-solang/app/components/WalletMultiButton.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import dynamic from "next/dynamic" - -export const WalletMultiButtonDynamic = dynamic( - async () => - (await import("@solana/wallet-adapter-react-ui")).WalletMultiButton, - { ssr: false } -) - -const WalletMultiButton = () => { - return -} - -export default WalletMultiButton diff --git a/compression/cnft-solang/app/contexts/WalletContextProvider.tsx b/compression/cnft-solang/app/contexts/WalletContextProvider.tsx deleted file mode 100644 index c77c209f..00000000 --- a/compression/cnft-solang/app/contexts/WalletContextProvider.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { FC, ReactNode, useMemo } from "react" -import { WalletAdapterNetwork } from "@solana/wallet-adapter-base" -import { - ConnectionProvider, - WalletProvider, -} from "@solana/wallet-adapter-react" -import { WalletModalProvider } from "@solana/wallet-adapter-react-ui" -import { - PhantomWalletAdapter, - SolflareWalletAdapter, -} from "@solana/wallet-adapter-wallets" -import { clusterApiUrl } from "@solana/web3.js" -require("@solana/wallet-adapter-react-ui/styles.css") - -const WalletContextProvider: FC<{ children: ReactNode }> = ({ children }) => { - const network = WalletAdapterNetwork.Devnet - const endpoint = useMemo(() => clusterApiUrl(network), [network]) - - const wallets = useMemo( - () => [ - new PhantomWalletAdapter(), - new SolflareWalletAdapter(), - ], - [network] - ) - - return ( - - - {children} - - - ) -} - -export default WalletContextProvider diff --git a/compression/cnft-solang/app/idl/compressed_nft.ts b/compression/cnft-solang/app/idl/compressed_nft.ts deleted file mode 100644 index 69aea996..00000000 --- a/compression/cnft-solang/app/idl/compressed_nft.ts +++ /dev/null @@ -1,229 +0,0 @@ -export type CompressedNft = { - "version": "0.0.1", - "name": "compressed_nft", - "instructions": [ - { - "name": "new", - "accounts": [ - { - "name": "dataAccount", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "payer", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "isOptional": false - } - ], - "args": [ - { - "name": "bump", - "type": { - "array": [ - "u8", - 1 - ] - } - } - ] - }, - { - "name": "mint", - "accounts": [ - { - "name": "tree_authority", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "leaf_owner", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "leaf_delegate", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "merkle_tree", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "payer", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "tree_delegate", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "noop_address", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "compression_pid", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "bubblegum_pid", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "isOptional": false - } - ], - "args": [ - { - "name": "uri", - "type": "string" - } - ] - } - ], - "metadata": { - "address": "BvgEJTPXfriGPopjJr1nLc4vADXm7A7TqjLFVztpd19Q" - } -}; - -export const IDL: CompressedNft = { - "version": "0.0.1", - "name": "compressed_nft", - "instructions": [ - { - "name": "new", - "accounts": [ - { - "name": "dataAccount", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "payer", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "isOptional": false - } - ], - "args": [ - { - "name": "bump", - "type": { - "array": [ - "u8", - 1 - ] - } - } - ] - }, - { - "name": "mint", - "accounts": [ - { - "name": "tree_authority", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "leaf_owner", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "leaf_delegate", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "merkle_tree", - "isMut": true, - "isSigner": false, - "isOptional": false - }, - { - "name": "payer", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "tree_delegate", - "isMut": true, - "isSigner": true, - "isOptional": false - }, - { - "name": "noop_address", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "compression_pid", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "bubblegum_pid", - "isMut": false, - "isSigner": false, - "isOptional": false - }, - { - "name": "systemProgram", - "isMut": false, - "isSigner": false, - "isOptional": false - } - ], - "args": [ - { - "name": "uri", - "type": "string" - } - ] - } - ], - "metadata": { - "address": "BvgEJTPXfriGPopjJr1nLc4vADXm7A7TqjLFVztpd19Q" - } -}; diff --git a/compression/cnft-solang/app/next.config.js b/compression/cnft-solang/app/next.config.js deleted file mode 100644 index a843cbee..00000000 --- a/compression/cnft-solang/app/next.config.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - reactStrictMode: true, -} - -module.exports = nextConfig diff --git a/compression/cnft-solang/app/package.json b/compression/cnft-solang/app/package.json deleted file mode 100644 index 9a2f8b52..00000000 --- a/compression/cnft-solang/app/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "wallet-adapter-chakraui-nextjs", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@chakra-ui/next-js": "^2.1.3", - "@chakra-ui/react": "^2.6.1", - "@coral-xyz/anchor": "^0.29.0", - "@emotion/react": "^11.11.0", - "@emotion/styled": "^11.11.0", - "@metaplex-foundation/mpl-bubblegum": "^0.7.0", - "@solana/pay": "^0.2.5", - "@solana/spl-account-compression": "^0.1.8", - "@solana/wallet-adapter-base": "^0.9.22", - "@solana/wallet-adapter-react": "^0.15.32", - "@solana/wallet-adapter-react-ui": "^0.9.31", - "@solana/wallet-adapter-wallets": "^0.19.16", - "@solana/web3.js": "^1.77.1", - "@types/node": "20.2.5", - "@types/react": "18.2.7", - "@types/react-dom": "18.2.4", - "eslint": "8.41.0", - "eslint-config-next": "13.4.4", - "framer-motion": "^10.12.16", - "next": "13.4.4", - "react": "18.2.0", - "react-circular-progressbar": "^2.1.0", - "react-dom": "18.2.0", - "typescript": "5.0.4" - } -} diff --git a/compression/cnft-solang/app/pages/_app.tsx b/compression/cnft-solang/app/pages/_app.tsx deleted file mode 100644 index 7ed4d84d..00000000 --- a/compression/cnft-solang/app/pages/_app.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { ChakraProvider } from "@chakra-ui/react" -import WalletContextProvider from "../contexts/WalletContextProvider" -import type { AppProps } from "next/app" - -export default function App({ Component, pageProps }: AppProps) { - return ( - - - - - - ) -} diff --git a/compression/cnft-solang/app/pages/_document.tsx b/compression/cnft-solang/app/pages/_document.tsx deleted file mode 100644 index 54e8bf3e..00000000 --- a/compression/cnft-solang/app/pages/_document.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Html, Head, Main, NextScript } from 'next/document' - -export default function Document() { - return ( - - - -
- - - - ) -} diff --git a/compression/cnft-solang/app/pages/api/mintCnft.ts b/compression/cnft-solang/app/pages/api/mintCnft.ts deleted file mode 100644 index 25493ca0..00000000 --- a/compression/cnft-solang/app/pages/api/mintCnft.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { NextApiRequest, NextApiResponse } from "next" -import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js" -import { - SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, - SPL_NOOP_PROGRAM_ID, -} from "@solana/spl-account-compression" -import { PROGRAM_ID as BUBBLEGUM_PROGRAM_ID } from "@metaplex-foundation/mpl-bubblegum" -import { program, connection, treeAddress } from "@/utils/setup" -import { uris } from "@/utils/uri" - -function get(res: NextApiResponse) { - res.status(200).json({ - label: "My Store", - icon: "https://solana.com/src/img/branding/solanaLogoMark.svg", - }) -} - -async function post(req: NextApiRequest, res: NextApiResponse) { - const { account } = req.body - const { reference } = req.query - - if (!account || !reference) { - res.status(400).json({ - error: "Required data missing. Account or reference not provided.", - }) - return - } - - try { - const transaction = await buildTransaction( - new PublicKey(account), - new PublicKey(reference) - ) - res.status(200).json({ - transaction, - message: "Please approve the transaction to mint your NFT!", - }) - } catch (error) { - console.error(error) - res.status(500).json({ error: "error creating transaction" }) - return - } -} - -async function buildTransaction(account: PublicKey, reference: PublicKey) { - // Required solang dataAccount, even though we're not using it. - const [dataAccount] = PublicKey.findProgramAddressSync( - [Buffer.from("seed")], - program.programId - ) - - // tree authority - const [treeAuthority] = PublicKey.findProgramAddressSync( - [treeAddress.toBuffer()], - BUBBLEGUM_PROGRAM_ID - ) - - // Randomly select a uri. - const randomUri = uris[Math.floor(Math.random() * uris.length)] - - // Initialize the dataAccount. - const instruction = await program.methods - .mint( - randomUri // uri - ) - .accounts({ - tree_authority: treeAuthority, // treeAuthority - leaf_owner: account, // leafOwner - leaf_delegate: account, // leafDelegate - merkle_tree: account, // merkleTree - payer: account, // payer - tree_delegate: account, // treeDelegate, public tree (no delegate check, just require signer) - noop_address: SPL_NOOP_PROGRAM_ID, - compression_pid: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, - bubblegum_pid: BUBBLEGUM_PROGRAM_ID, - }) - .instruction() - - // Add the reference account to the instruction - // Used in client to find the transaction once sent - instruction.keys.push({ - pubkey: reference, - isSigner: false, - isWritable: false, - }) - - const latestBlockhash = await connection.getLatestBlockhash() - - // create new Transaction and add instruction - const transaction = new Transaction({ - feePayer: account, - blockhash: latestBlockhash.blockhash, - lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, - }).add(instruction) - - return transaction - .serialize({ requireAllSignatures: false }) - .toString("base64") -} - -export default async function handler( - req: NextApiRequest, - res: NextApiResponse -) { - if (req.method === "GET") { - return get(res) - } else if (req.method === "POST") { - return await post(req, res) - } else { - return res.status(405).json({ error: "Method not allowed" }) - } -} diff --git a/compression/cnft-solang/app/pages/index.tsx b/compression/cnft-solang/app/pages/index.tsx deleted file mode 100644 index 6359d435..00000000 --- a/compression/cnft-solang/app/pages/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { - Box, - Button, - Flex, - Spacer, - VStack, - useDisclosure, -} from "@chakra-ui/react" -import WalletMultiButton from "@/components/WalletMultiButton" -import QrModal from "@/components/QrCodeCnftMint" -export default function Home() { - const { isOpen, onOpen, onClose } = useDisclosure() - return ( - - - - - - - - {isOpen && } - - - ) -} diff --git a/compression/cnft-solang/app/public/favicon.ico b/compression/cnft-solang/app/public/favicon.ico deleted file mode 100644 index 718d6fea..00000000 Binary files a/compression/cnft-solang/app/public/favicon.ico and /dev/null differ diff --git a/compression/cnft-solang/app/public/next.svg b/compression/cnft-solang/app/public/next.svg deleted file mode 100644 index 5174b28c..00000000 --- a/compression/cnft-solang/app/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/compression/cnft-solang/app/public/vercel.svg b/compression/cnft-solang/app/public/vercel.svg deleted file mode 100644 index d2f84222..00000000 --- a/compression/cnft-solang/app/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/compression/cnft-solang/app/styles/Home.module.css b/compression/cnft-solang/app/styles/Home.module.css deleted file mode 100644 index 9411a5e6..00000000 --- a/compression/cnft-solang/app/styles/Home.module.css +++ /dev/null @@ -1,229 +0,0 @@ -.main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - min-height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - width: var(--max-width); - max-width: 100%; -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - background: var(--primary-glow); - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ''; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/compression/cnft-solang/app/styles/globals.css b/compression/cnft-solang/app/styles/globals.css deleted file mode 100644 index d4f491e1..00000000 --- a/compression/cnft-solang/app/styles/globals.css +++ /dev/null @@ -1,107 +0,0 @@ -:root { - --max-width: 1100px; - --border-radius: 12px; - --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', - 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', - 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; - - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; - - --primary-glow: conic-gradient( - from 180deg at 50% 50%, - #16abff33 0deg, - #0885ff33 55deg, - #54d6ff33 120deg, - #0071ff33 160deg, - transparent 360deg - ); - --secondary-glow: radial-gradient( - rgba(255, 255, 255, 1), - rgba(255, 255, 255, 0) - ); - - --tile-start-rgb: 239, 245, 249; - --tile-end-rgb: 228, 232, 233; - --tile-border: conic-gradient( - #00000080, - #00000040, - #00000030, - #00000020, - #00000010, - #00000010, - #00000080 - ); - - --callout-rgb: 238, 240, 241; - --callout-border-rgb: 172, 175, 176; - --card-rgb: 180, 185, 188; - --card-border-rgb: 131, 134, 135; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - - --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); - --secondary-glow: linear-gradient( - to bottom right, - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0), - rgba(1, 65, 255, 0.3) - ); - - --tile-start-rgb: 2, 13, 46; - --tile-end-rgb: 2, 5, 19; - --tile-border: conic-gradient( - #ffffff80, - #ffffff40, - #ffffff30, - #ffffff20, - #ffffff10, - #ffffff10, - #ffffff80 - ); - - --callout-rgb: 20, 20, 20; - --callout-border-rgb: 108, 108, 108; - --card-rgb: 100, 100, 100; - --card-border-rgb: 200, 200, 200; - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -html, -body { - max-width: 100vw; - overflow-x: hidden; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); -} - -a { - color: inherit; - text-decoration: none; -} - -@media (prefers-color-scheme: dark) { - html { - color-scheme: dark; - } -} diff --git a/compression/cnft-solang/app/tsconfig.json b/compression/cnft-solang/app/tsconfig.json deleted file mode 100644 index 8b8e5811..00000000 --- a/compression/cnft-solang/app/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["dom", "dom.iterable", "esnext"], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "paths": { - "@/*": ["./*"] - } - }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] -} diff --git a/compression/cnft-solang/app/utils/setup.ts b/compression/cnft-solang/app/utils/setup.ts deleted file mode 100644 index 2d56cfcc..00000000 --- a/compression/cnft-solang/app/utils/setup.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Program, Idl } from "@coral-xyz/anchor"; -import { IDL, CompressedNft } from "../idl/compressed_nft"; -import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js"; - -export const connection = new Connection(clusterApiUrl("devnet"), "confirmed"); - -const programId = IDL.metadata.address; - -export const program = new Program(IDL as Idl, programId, { - connection, -}) as unknown as Program; - -export const treeAddress = new PublicKey( - "FYwZ4rMtexsHBTx2aCnQRVg51K5WXZJ1n3SYacXFvado" -); diff --git a/compression/cnft-solang/app/utils/uri.ts b/compression/cnft-solang/app/utils/uri.ts deleted file mode 100644 index 784a6484..00000000 --- a/compression/cnft-solang/app/utils/uri.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const uris = [ - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/40_183_132/40_183_132.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/12_217_47/12_217_47.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/255_68_196/255_68_196.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/156_61_27/156_61_27.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/32_150_152/32_150_152.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/78_96_197/78_96_197.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/38_47_11/38_47_11.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/190_85_238/190_85_238.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/69_46_192/69_46_192.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/142_17_9/142_17_9.json", -] diff --git a/compression/cnft-solang/migrations/deploy.ts b/compression/cnft-solang/migrations/deploy.ts deleted file mode 100644 index 82fb175f..00000000 --- a/compression/cnft-solang/migrations/deploy.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Migrations are an early feature. Currently, they're nothing more than this -// single deploy script that's invoked from the CLI, injecting a provider -// configured from the workspace's Anchor.toml. - -const anchor = require("@coral-xyz/anchor"); - -module.exports = async function (provider) { - // Configure client to use the provider. - anchor.setProvider(provider); - - // Add your deploy script here. -}; diff --git a/compression/cnft-solang/package.json b/compression/cnft-solang/package.json deleted file mode 100644 index aeb0fc69..00000000 --- a/compression/cnft-solang/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0", - "@metaplex-foundation/mpl-bubblegum": "^0.7.0", - "@solana/spl-account-compression": "^0.1.8" - }, - "devDependencies": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/compression/cnft-solang/solidity/compressed-nft.sol b/compression/cnft-solang/solidity/compressed-nft.sol deleted file mode 100644 index edb5116e..00000000 --- a/compression/cnft-solang/solidity/compressed-nft.sol +++ /dev/null @@ -1,147 +0,0 @@ - -import "solana"; - -@program_id("BvgEJTPXfriGPopjJr1nLc4vADXm7A7TqjLFVztpd19Q") -contract compressed_nft { - - @payer(payer) // payer address - @seed("seed") // hardcoded seed - constructor( - @bump bytes1 bump // bump seed for pda address - ) { - // Creating a dataAccount for the program, which is required by Solang - // However, this account is not used in the program - } - - // Mint a compressed NFT to an existing merkle tree, via a cross-program invocation to the Bubblegum program - // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/lib.rs#L922 - // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/lib.rs#L67 - @mutableAccount(tree_authority) // authority of the merkle tree - @account(leaf_owner) // owner of the new compressed NFT - @account(leaf_delegate) // delegate of the new compressed NFT (can be the same as leaf_owner) - @mutableAccount(merkle_tree) // address of the merkle tree - @mutableSigner(payer) // payer - @mutableSigner(tree_delegate) // delegate of the merkle tree - @account(noop_address) - @account(compression_pid) - @account(bubblegum_pid) - function mint( - string uri // uri of the new compressed NFT (metadata) - ) external { - print("Minting Compressed NFT"); - - // Create a creator array with a single creator - Creator[] memory creators = new Creator[](1); - // Set the creator to the payer - creators[0] = Creator({ - creatorAddress: tx.accounts.payer.key, - verified: false, - share: 100 - }); - - // Create the metadata args, representing the metadata of the new compressed NFT - // Solidity does not support optional arguments, - // So we have to explicitly declare if the optional arguments are present or not - // If not present, we comment them out, otherwise the transaction will fail with a invalid instruction data error - MetadataArgs memory args = MetadataArgs({ - name: "RGB", - symbol: "RGB", - uri: uri, - sellerFeeBasisPoints: 0, - primarySaleHappened: false, - isMutable: true, - editionNoncePresent: false, - // editionNonce: 0, - tokenStandardPresent: true, - tokenStandard: TokenStandard.NonFungible, - collectionPresent: false, - // collection: Collection({ - // verified: false, - // key: address(0) - // }), - usesPresent: false, - // uses: Uses({ - // useMethod: UseMethod.Burn, - // remaining: 0, - // total: 0 - // }), - tokenProgramVersion: TokenProgramVersion.Original, - creators: creators - }); - - AccountMeta[9] metas = [ - AccountMeta({pubkey: tx.accounts.tree_authority.key, is_writable: true, is_signer: false}), - AccountMeta({pubkey: tx.accounts.leaf_owner.key, is_writable: false, is_signer: false}), - AccountMeta({pubkey: tx.accounts.leaf_delegate.key, is_writable: false, is_signer: false}), - AccountMeta({pubkey: tx.accounts.merkle_tree.key, is_writable: true, is_signer: false}), - AccountMeta({pubkey: tx.accounts.payer.key, is_writable: true, is_signer: true}), - AccountMeta({pubkey: tx.accounts.tree_delegate.key, is_writable: true, is_signer: true}), - AccountMeta({pubkey: tx.accounts.noop_address.key, is_writable: false, is_signer: false}), - AccountMeta({pubkey: tx.accounts.compression_pid.key, is_writable: false, is_signer: false}), - AccountMeta({pubkey: address"11111111111111111111111111111111", is_writable: false, is_signer: false}) - ]; - - // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/js/src/generated/instructions/mintV1.ts#L64 - bytes8 discriminator = 0x9162c076b8937668; - bytes instructionData = abi.encode(discriminator, args); - - // Invoking the Bubblegum program - tx.accounts.bubblegum_pid.key.call{accounts: metas}(instructionData); - } - - // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L81 - struct MetadataArgs { - string name; - string symbol; - string uri; - uint16 sellerFeeBasisPoints; - bool primarySaleHappened; - bool isMutable; - bool editionNoncePresent; - // uint8 editionNonce; - bool tokenStandardPresent; - TokenStandard tokenStandard; - bool collectionPresent; - // Collection collection; - bool usesPresent; - // Uses uses; - TokenProgramVersion tokenProgramVersion; - Creator[] creators; - } - - enum TokenStandard { - NonFungible, - FungibleAsset, - Fungible, - NonFungibleEdition - } - - enum TokenProgramVersion { - Original, - Token2022 - } - - struct Creator { - address creatorAddress; - bool verified; - uint8 share; - } - - struct Collection { - bool verified; - address key; - } - - struct Uses { - UseMethod useMethod; - uint64 remaining; - uint64 total; - } - - enum UseMethod { - Burn, - Multiple, - Single - } - -} diff --git a/compression/cnft-solang/tests/compressed-nft.ts b/compression/cnft-solang/tests/compressed-nft.ts deleted file mode 100644 index fb6033e3..00000000 --- a/compression/cnft-solang/tests/compressed-nft.ts +++ /dev/null @@ -1,150 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program, Wallet } from "@coral-xyz/anchor"; -import { CompressedNft } from "../target/types/compressed_nft"; -import { - PublicKey, - SystemProgram, - Transaction, - Keypair, - sendAndConfirmTransaction, -} from "@solana/web3.js"; -import { - SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, - ValidDepthSizePair, - SPL_NOOP_PROGRAM_ID, - createAllocTreeIx, -} from "@solana/spl-account-compression"; -import { - PROGRAM_ID as BUBBLEGUM_PROGRAM_ID, - createCreateTreeInstruction, -} from "@metaplex-foundation/mpl-bubblegum"; -import { uris } from "../utils/uri"; - -describe("compressed-nft", () => { - const provider = anchor.AnchorProvider.env(); - anchor.setProvider(provider); - - const wallet = provider.wallet as Wallet; - const connection = provider.connection; - - const program = anchor.workspace.CompressedNft as Program; - - // Generate a new keypair for the merkle tree. - const treeKeypair = Keypair.generate(); - - // Derive the PDA that will be the tree authority. - // This is required by the bubblegum program. - const [treeAuthority] = PublicKey.findProgramAddressSync( - [treeKeypair.publicKey.toBuffer()], - BUBBLEGUM_PROGRAM_ID - ); - - // Derive the PDA that will be used to initialize the dataAccount. - // Required by Solang even though we're not using it. - const [dataAccount, bump] = PublicKey.findProgramAddressSync( - [Buffer.from("seed")], - program.programId - ); - - // Create a merkle tree account. - before(async () => { - // Maximum depth and buffer size for the merkle tree. - // 2^maxDepth determines the maximum number of leaves that can be stored in the tree. - // maxBufferSize determines maximum concurrent updates that can be made within one slot. - const maxDepthSizePair: ValidDepthSizePair = { - maxDepth: 14, - maxBufferSize: 64, - }; - - // Depth of the canopy (how much of the tree is stored on-chain) - const canopyDepth = 0; - - // Instruction to create an account with enough space to store the merkle tree. - const allocTreeIx = await createAllocTreeIx( - connection, - treeKeypair.publicKey, - wallet.publicKey, - maxDepthSizePair, - canopyDepth - ); - - // Instruction to initialize the merkle tree account with the bubblegum program. - const createTreeIx = createCreateTreeInstruction( - { - treeAuthority, - merkleTree: treeKeypair.publicKey, - payer: wallet.publicKey, - treeCreator: wallet.publicKey, - logWrapper: SPL_NOOP_PROGRAM_ID, - compressionProgram: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, - }, - { - maxBufferSize: maxDepthSizePair.maxBufferSize, - maxDepth: maxDepthSizePair.maxDepth, - public: true, // creating a "public" tree, so anyone can mint cnfts to it - }, - BUBBLEGUM_PROGRAM_ID - ); - - try { - const tx = new Transaction().add(allocTreeIx, createTreeIx); - tx.feePayer = wallet.publicKey; - - const txSignature = await sendAndConfirmTransaction( - connection, - tx, - [treeKeypair, wallet.payer], - { - commitment: "confirmed", - skipPreflight: true, - } - ); - - console.log( - `https://explorer.solana.com/tx/${txSignature}?cluster=devnet` - ); - - console.log("Tree Address:", treeKeypair.publicKey.toBase58()); - } catch (err: any) { - console.error("\nFailed to create merkle tree:", err); - throw err; - } - - console.log("\n"); - }); - - it("Is initialized!", async () => { - // Initialize the dataAccount. - const tx = await program.methods - .new([bump]) - .accounts({ dataAccount: dataAccount }) - .rpc(); - console.log("Your transaction signature", tx); - }); - - it("Mint Compressed NFT", async () => { - // Mint a compressed nft to random receiver. - const receiver = Keypair.generate().publicKey; - - // Use a random uri (off-chain metadata) from the list for the test. - const randomUri = uris[Math.floor(Math.random() * uris.length)]; - - const tx = await program.methods - .mint( - randomUri // uri - ) - .accounts({ - tree_authority: treeAuthority, - leaf_owner: receiver, - leaf_delegate: receiver, - merkle_tree: treeKeypair.publicKey, - payer: wallet.publicKey, - tree_delegate: wallet.publicKey, - noop_address: SPL_NOOP_PROGRAM_ID, - compression_pid: SPL_ACCOUNT_COMPRESSION_PROGRAM_ID, - bubblegum_pid: BUBBLEGUM_PROGRAM_ID, - }) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/compression/cnft-solang/tsconfig.json b/compression/cnft-solang/tsconfig.json deleted file mode 100644 index 558b83e5..00000000 --- a/compression/cnft-solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } - } - \ No newline at end of file diff --git a/compression/cnft-solang/utils/uri.ts b/compression/cnft-solang/utils/uri.ts deleted file mode 100644 index 784a6484..00000000 --- a/compression/cnft-solang/utils/uri.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const uris = [ - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/40_183_132/40_183_132.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/12_217_47/12_217_47.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/255_68_196/255_68_196.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/156_61_27/156_61_27.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/32_150_152/32_150_152.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/78_96_197/78_96_197.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/38_47_11/38_47_11.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/190_85_238/190_85_238.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/69_46_192/69_46_192.json", - "https://raw.githubusercontent.com/ZYJLiu/rgb-png-generator/master/assets/142_17_9/142_17_9.json", -] diff --git a/tokens/create-token/solang/.gitignore b/tokens/create-token/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/tokens/create-token/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/tokens/create-token/solang/Anchor.toml b/tokens/create-token/solang/Anchor.toml deleted file mode 100644 index 00be357b..00000000 --- a/tokens/create-token/solang/Anchor.toml +++ /dev/null @@ -1,21 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -create_token = "8eZPhSaXfHqbcrfskVThtCG68kq8MfVHqmtm6wYf4TLb" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" \ No newline at end of file diff --git a/tokens/create-token/solang/libraries/mpl_metadata.sol b/tokens/create-token/solang/libraries/mpl_metadata.sol deleted file mode 100644 index e8b4fe0b..00000000 --- a/tokens/create-token/solang/libraries/mpl_metadata.sol +++ /dev/null @@ -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 systemAddress = address"11111111111111111111111111111111"; - - // 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, - address metadataProgramId, - address rentAddress - ) 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); - } -} diff --git a/tokens/create-token/solang/libraries/spl_token.sol b/tokens/create-token/solang/libraries/spl_token.sol deleted file mode 100644 index 6532df43..00000000 --- a/tokens/create-token/solang/libraries/spl_token.sol +++ /dev/null @@ -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{ - 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); - } -} diff --git a/tokens/create-token/solang/libraries/system_instruction.sol b/tokens/create-token/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/tokens/create-token/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/tokens/create-token/solang/package.json b/tokens/create-token/solang/package.json deleted file mode 100644 index 6b59ef46..00000000 --- a/tokens/create-token/solang/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "dependencies": { - "@coral-xyz/anchor": "^0.28.0", - "@metaplex-foundation/js": "^0.19.4", - "@project-serum/anchor": "^0.26.0" - }, - "devDependencies": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/tokens/create-token/solang/solidity/create-token.sol b/tokens/create-token/solang/solidity/create-token.sol deleted file mode 100644 index df9a9ef2..00000000 --- a/tokens/create-token/solang/solidity/create-token.sol +++ /dev/null @@ -1,51 +0,0 @@ - -import "../libraries/spl_token.sol"; -import "../libraries/mpl_metadata.sol"; - -@program_id("8eZPhSaXfHqbcrfskVThtCG68kq8MfVHqmtm6wYf4TLb") -contract create_token { - - // Creating a dataAccount is required by Solang - // The account is unused in this example - @payer(payer) // payer account - constructor() {} - - @mutableSigner(payer) // payer account - @mutableSigner(mint) // mint account to be created - @mutableAccount(metadata) // metadata account to be created - @signer(mintAuthority) // mint authority for the mint account - @account(rentAddress) - @account(metadataProgramId) - function createTokenMint( - address freezeAuthority, // freeze authority for the mint account - uint8 decimals, // decimals for the mint account - string name, // name for the metadata account - string symbol, // symbol for the metadata account - string uri // uri for the metadata account - ) external { - // 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 - SplToken.create_mint( - tx.accounts.payer.key, // payer account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - freezeAuthority, // freeze authority - decimals // decimals - ); - - // Invoke Metadata Program to create a new account for the metadata account - MplMetadata.create_metadata_account( - tx.accounts.metadata.key, // metadata account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - tx.accounts.payer.key, // payer - tx.accounts.payer.key, // update authority (of the metadata account) - name, // name - symbol, // symbol - uri, // uri (off-chain metadata json) - tx.accounts.metadataProgramId.key, - tx.accounts.rentAddress.key - ); - } -} diff --git a/tokens/create-token/solang/tests/create-token.ts b/tokens/create-token/solang/tests/create-token.ts deleted file mode 100644 index 1be35970..00000000 --- a/tokens/create-token/solang/tests/create-token.ts +++ /dev/null @@ -1,96 +0,0 @@ -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; - - // Generate new keypair to use as data account - 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 tokenUri = - "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() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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(); - - // Get the metadata address for the mint - const metaplex = Metaplex.make(connection); - const metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - const tx = await program.methods - .createTokenMint( - wallet.publicKey, // freeze authority - 9, // decimals for the mint - tokenTitle, // token name - tokenSymbol, // token symbol - tokenUri // token uri (off-chain metadata) - ) - .accounts({ - payer: wallet.publicKey, //payer - mint: mintKeypair.publicKey, // mint - metadata: metadataAddress, // metadata address - mintAuthority: wallet.publicKey, // mint authority - rentAddress: SYSVAR_RENT_PUBKEY, - metadataProgramId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), - }) - .signers([mintKeypair]) - .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(); - - // Get the metadata address for the mint - const metaplex = Metaplex.make(connection); - const metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - const tx = await program.methods - .createTokenMint( - wallet.publicKey, - 0, // decimals for the mint, 0 for NFTs "non-fungible" - tokenTitle, - tokenSymbol, - tokenUri - ) - .accounts({ - payer: wallet.publicKey, //payer - mint: mintKeypair.publicKey, // mint - metadata: metadataAddress, // metadata address - mintAuthority: wallet.publicKey, // mint authority - rentAddress: SYSVAR_RENT_PUBKEY, - metadataProgramId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), - }) - .signers([mintKeypair]) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/tokens/create-token/solang/tsconfig.json b/tokens/create-token/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/tokens/create-token/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/tokens/freeze-tokens/README.md b/tokens/freeze-tokens/README.md deleted file mode 100644 index 8e2d8b51..00000000 --- a/tokens/freeze-tokens/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Freeze Tokens - -> Coming soon! \ No newline at end of file diff --git a/tokens/nft-minter/solang/.gitignore b/tokens/nft-minter/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/tokens/nft-minter/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/tokens/nft-minter/solang/Anchor.toml b/tokens/nft-minter/solang/Anchor.toml deleted file mode 100644 index e272fa99..00000000 --- a/tokens/nft-minter/solang/Anchor.toml +++ /dev/null @@ -1,21 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -nft_minter = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" \ No newline at end of file diff --git a/tokens/nft-minter/solang/libraries/mpl_metadata.sol b/tokens/nft-minter/solang/libraries/mpl_metadata.sol deleted file mode 100644 index cee36fb0..00000000 --- a/tokens/nft-minter/solang/libraries/mpl_metadata.sol +++ /dev/null @@ -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 systemAddress = address"11111111111111111111111111111111"; - - // 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, - address metadataProgramId, - address rentAddress - ) 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); - } -} diff --git a/tokens/nft-minter/solang/libraries/spl_token.sol b/tokens/nft-minter/solang/libraries/spl_token.sol deleted file mode 100644 index 6532df43..00000000 --- a/tokens/nft-minter/solang/libraries/spl_token.sol +++ /dev/null @@ -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{ - 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); - } -} diff --git a/tokens/nft-minter/solang/libraries/system_instruction.sol b/tokens/nft-minter/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/tokens/nft-minter/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/tokens/nft-minter/solang/package.json b/tokens/nft-minter/solang/package.json deleted file mode 100644 index 7fa094e4..00000000 --- a/tokens/nft-minter/solang/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "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": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/tokens/nft-minter/solang/solidity/nft-minter.sol b/tokens/nft-minter/solang/solidity/nft-minter.sol deleted file mode 100644 index 0458c9d8..00000000 --- a/tokens/nft-minter/solang/solidity/nft-minter.sol +++ /dev/null @@ -1,77 +0,0 @@ - -import "../libraries/spl_token.sol"; -import "../libraries/mpl_metadata.sol"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract nft_minter { - - @payer(payer) - constructor() {} - - @mutableSigner(payer) // payer account - @mutableSigner(mint) // mint account to be created - @mutableAccount(metadata) // metadata account to be created - @signer(mintAuthority) // mint authority for the mint account - @account(metadataProgramId) - @account(rentAddress) - function createTokenMint( - address freezeAuthority, // freeze authority for the mint account - uint8 decimals, // decimals for the mint account - string name, // name for the metadata account - string symbol, // symbol for the metadata account - string uri // uri for the metadata account - ) external { - // 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 - SplToken.create_mint( - tx.accounts.payer.key, // payer account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - freezeAuthority, // freeze authority - decimals // decimals - ); - - // Invoke Metadata Program to create a new account for the metadata account - MplMetadata.create_metadata_account( - tx.accounts.metadata.key, // metadata account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - tx.accounts.payer.key, // payer - tx.accounts.payer.key, // update authority (of the metadata account) - name, // name - symbol, // symbol - uri, // uri (off-chain metadata json) - tx.accounts.metadataProgramId.key, - tx.accounts.rentAddress.key - ); - } - - @mutableSigner(payer) - @mutableAccount(tokenAccount) - @account(owner) - @mutableAccount(mint) - function mintTo() external { - // Create an associated token account for the owner to receive the minted token - SplToken.create_associated_token_account( - tx.accounts.payer.key, // payer account - tx.accounts.tokenAccount.key, // associated token account address - tx.accounts.mint.key, // mint account - tx.accounts.owner.key // owner account - ); - - // Mint 1 token to the associated token account - SplToken.mint_to( - tx.accounts.mint.key, // mint account - tx.accounts.tokenAccount.key, // token account - tx.accounts.payer.key, // mint authority - 1 // amount - ); - - // Remove mint authority from mint account - SplToken.remove_mint_authority( - tx.accounts.mint.key, // mint - tx.accounts.payer.key // mint authority - ); - } -} diff --git a/tokens/nft-minter/solang/tests/nft-minter.ts b/tokens/nft-minter/solang/tests/nft-minter.ts deleted file mode 100644 index bc6cfd65..00000000 --- a/tokens/nft-minter/solang/tests/nft-minter.ts +++ /dev/null @@ -1,90 +0,0 @@ -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"; - -describe("nft-minter", () => { - // Configure the client to use the local cluster. - 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(); - - // Generate a mint keypair - const mintKeypair = anchor.web3.Keypair.generate(); - const wallet = provider.wallet; - const connection = provider.connection; - - const program = anchor.workspace.NftMinter as Program; - - // Metadata for the NFT - const nftTitle = "Homer NFT"; - const nftSymbol = "HOMR"; - const nftUri = - "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() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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 metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - const tx = await program.methods - .createTokenMint( - wallet.publicKey, // freeze authority - 0, // 0 decimals for NFT - nftTitle, // NFT name - nftSymbol, // NFT symbol - nftUri // NFT URI - ) - .accounts({ - payer: wallet.publicKey, - mint: mintKeypair.publicKey, - metadata: metadataAddress, - mintAuthority: wallet.publicKey, - metadataProgramId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), - rentAddress: SYSVAR_RENT_PUBKEY, - }) - .signers([mintKeypair]) - .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() - .accounts({ - payer: wallet.publicKey, // payer - tokenAccount: tokenAccount, // associated token account address - mint: mintKeypair.publicKey, // mint - owner: wallet.publicKey, // owner of token account - }) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/tokens/nft-minter/solang/tsconfig.json b/tokens/nft-minter/solang/tsconfig.json deleted file mode 100644 index 558b83e5..00000000 --- a/tokens/nft-minter/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } - } - \ No newline at end of file diff --git a/tokens/pda-mint-authority/solang/.gitignore b/tokens/pda-mint-authority/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/tokens/pda-mint-authority/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/tokens/pda-mint-authority/solang/Anchor.toml b/tokens/pda-mint-authority/solang/Anchor.toml deleted file mode 100644 index 828efd04..00000000 --- a/tokens/pda-mint-authority/solang/Anchor.toml +++ /dev/null @@ -1,21 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -pda_mint_authority = "J2eUKE878XKXJZaP7vXwxgWnWnNQMqHSkMPoRFQwa86b" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" \ No newline at end of file diff --git a/tokens/pda-mint-authority/solang/libraries/mpl_metadata.sol b/tokens/pda-mint-authority/solang/libraries/mpl_metadata.sol deleted file mode 100644 index 7b030a3a..00000000 --- a/tokens/pda-mint-authority/solang/libraries/mpl_metadata.sol +++ /dev/null @@ -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 { - // // 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); - } -} diff --git a/tokens/pda-mint-authority/solang/libraries/spl_token.sol b/tokens/pda-mint-authority/solang/libraries/spl_token.sol deleted file mode 100644 index 6532df43..00000000 --- a/tokens/pda-mint-authority/solang/libraries/spl_token.sol +++ /dev/null @@ -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{ - 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); - } -} diff --git a/tokens/pda-mint-authority/solang/libraries/system_instruction.sol b/tokens/pda-mint-authority/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/tokens/pda-mint-authority/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/tokens/pda-mint-authority/solang/package.json b/tokens/pda-mint-authority/solang/package.json deleted file mode 100644 index 7fa094e4..00000000 --- a/tokens/pda-mint-authority/solang/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "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": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/tokens/pda-mint-authority/solang/solidity/pda-mint-authority.sol b/tokens/pda-mint-authority/solang/solidity/pda-mint-authority.sol deleted file mode 100644 index b365bee1..00000000 --- a/tokens/pda-mint-authority/solang/solidity/pda-mint-authority.sol +++ /dev/null @@ -1,199 +0,0 @@ - -import "../libraries/spl_token.sol"; -import "solana"; - -@program_id("J2eUKE878XKXJZaP7vXwxgWnWnNQMqHSkMPoRFQwa86b") -contract pda_mint_authority { - bytes1 bump; // stores the bump for the pda address - - @payer(payer) - @seed("mint_authority") // hard-coded seed - 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); - - // 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) - require(pdaBump == _bump, 'INVALID_BUMP'); - - bump = _bump; - } - - - @mutableSigner(payer) // payer account - @mutableSigner(mint) // mint account to be created - @mutableAccount(metadata) // metadata account to be created - @account(mintAuthority) // mint authority for the mint account - @account(rentAddress) - @account(metaplexId) - function createTokenMint( - address freezeAuthority, // freeze authority for the mint account - uint8 decimals, // decimals for the mint account - string name, // name for the metadata account - string symbol, // symbol for the metadata account - string uri // uri for the metadata account - ) external { - // 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 - SplToken.create_mint( - tx.accounts.payer.key, // payer account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - freezeAuthority, // freeze authority - decimals // decimals - ); - - // Invoke Metadata Program to create a new account for the metadata account - _createMetadataAccount( - tx.accounts.metadata.key, // metadata account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - tx.accounts.payer.key, // payer - tx.accounts.payer.key, // update authority (of the metadata account) - name, // name - symbol, // symbol - uri, // uri (off-chain metadata json) - tx.accounts.rentAddress.key, - tx.accounts.metaplexId.key - ); - } - - // Create metadata account, must reimplement manually to sign with PDA, which is the mint authority - function _createMetadataAccount( - address metadata, // metadata account address - address mint, // mint account address - address mintAuthority, // mint authority - address payer, // payer - address updateAuthority, // update authority for the metadata account - string name, // token name - string symbol, // token symbol - string uri, // token uri - address rentAddress, - address metaplexId - ) 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(mintAuthority == pda, 'INVALID_PDA'); - - DataV2 data = DataV2({ - name: name, - symbol: symbol, - uri: uri, - sellerFeeBasisPoints: 0, - creatorsPresent: false, - collectionPresent: false, - usesPresent: false - }); - - CreateMetadataAccountArgsV3 args = CreateMetadataAccountArgsV3({ - data: data, - isMutable: true, - collectionDetailsPresent: false - }); - - 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: address"11111111111111111111111111111111", is_writable: false, is_signer: false}), - AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false}) - ]; - - bytes1 discriminator = 33; - bytes instructionData = abi.encode(discriminator, args); - - metaplexId.call{accounts: metas, seeds: [["mint_authority", abi.encode(_bump)]]}(instructionData); - } - - struct CreateMetadataAccountArgsV3 { - DataV2 data; - bool isMutable; - bool collectionDetailsPresent; // To handle Rust Option<> in Solidity - } - - struct DataV2 { - string name; - string symbol; - string uri; - uint16 sellerFeeBasisPoints; - bool creatorsPresent; // To handle Rust Option<> in Solidity - bool collectionPresent; // To handle Rust Option<> in Solidity - bool usesPresent; // To handle Rust Option<> in Solidity - } - - @mutableSigner(payer) - @mutableAccount(tokenAccount) - @account(owner) - @mutableAccount(mint) - @mutableAccount(pdaAccount) - function mintTo() external { - // Create an associated token account for the owner to receive the minted token - SplToken.create_associated_token_account( - tx.accounts.payer.key, // payer account - tx.accounts.tokenAccount.key, // associated token account address - tx.accounts.mint.key, // mint account - tx.accounts.owner.key // owner account - ); - - // Mint 1 token to the associated token account - _mintTo( - tx.accounts.mint.key, // mint account - tx.accounts.tokenAccount.key, // token account - 1, // amount - tx.accounts.pdaAccount.key - ); - - // // Remove mint authority from mint account - _removeMintAuthority( - tx.accounts.mint.key, // mint - tx.accounts.pdaAccount.key - ); - } - - // 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, address pdaAccount) 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(pdaAccount == pda, 'INVALID_PDA'); - - // Prepare instruction data - bytes instructionData = new bytes(9); - instructionData[0] = uint8(7); // MintTo instruction index - instructionData.writeUint64LE(amount, 1); // Amount to mint - - // Prepare accounts required by instruction - AccountMeta[3] metas = [ - AccountMeta({pubkey: mint, is_writable: true, is_signer: false}), - AccountMeta({pubkey: account, is_writable: true, is_signer: false}), - AccountMeta({pubkey: pda, is_writable: true, is_signer: true}) // mint authority - ]; - - // Invoke the token program with prepared accounts and instruction data - SplToken.tokenProgramId.call{accounts: metas, seeds: [["mint_authority", abi.encode(_bump)]]}(instructionData); - } - - function _removeMintAuthority(address mintAccount, address pdaAccount) 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(pdaAccount == pda, 'INVALID_PDA'); - - AccountMeta[2] metas = [ - AccountMeta({pubkey: mintAccount, is_signer: false, is_writable: true}), - AccountMeta({pubkey: pda, is_signer: true, is_writable: false}) // mint authority - ]; - - bytes instructionData = new bytes(9); - instructionData[0] = uint8(6); // SetAuthority instruction index - instructionData[1] = uint8(0); // AuthorityType::MintTokens - instructionData[3] = 0; - - // Invoke the token program with prepared accounts and instruction data - SplToken.tokenProgramId.call{accounts: metas, seeds: [["mint_authority", abi.encode(_bump)]]}(instructionData); - } -} diff --git a/tokens/pda-mint-authority/solang/tests/pda-mint-authority.ts b/tokens/pda-mint-authority/solang/tests/pda-mint-authority.ts deleted file mode 100644 index 7871694e..00000000 --- a/tokens/pda-mint-authority/solang/tests/pda-mint-authority.ts +++ /dev/null @@ -1,92 +0,0 @@ -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"; - -describe("pda-mint-authority", () => { - // Configure the client to use the local cluster. - const provider = anchor.AnchorProvider.env(); - anchor.setProvider(provider); - - const mintKeypair = anchor.web3.Keypair.generate(); - const wallet = provider.wallet; - const connection = provider.connection; - - const program = anchor.workspace - .PdaMintAuthority as Program; - - // 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 nftUri = - "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([bump]) - .accounts({ dataAccount: dataAccountPDA }) - .rpc(); - console.log("Your transaction signature", tx); - }); - - it("Create an NFT!", async () => { - const metaplex = Metaplex.make(connection); - const metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - // Add your test here. - const tx = await program.methods - .createTokenMint( - dataAccountPDA, // freeze authority - 0, // 0 decimals for NFT - nftTitle, // NFT name - nftSymbol, // NFT symbol - nftUri // NFT URI - ) - .accounts({ - payer: wallet.publicKey, - mint: mintKeypair.publicKey, - metadata: metadataAddress, - mintAuthority: dataAccountPDA, - rentAddress: SYSVAR_RENT_PUBKEY, - metaplexId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), - }) - .signers([mintKeypair]) - .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() - .accounts({ - pdaAccount: dataAccountPDA, - payer: wallet.publicKey, - tokenAccount: tokenAccount, - owner: wallet.publicKey, - mint: mintKeypair.publicKey - }) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/tokens/pda-mint-authority/solang/tsconfig.json b/tokens/pda-mint-authority/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/tokens/pda-mint-authority/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/tokens/spl-token-minter/solang/.gitignore b/tokens/spl-token-minter/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/tokens/spl-token-minter/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/tokens/spl-token-minter/solang/Anchor.toml b/tokens/spl-token-minter/solang/Anchor.toml deleted file mode 100644 index 1b75b685..00000000 --- a/tokens/spl-token-minter/solang/Anchor.toml +++ /dev/null @@ -1,21 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -spl_token_minter = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" \ No newline at end of file diff --git a/tokens/spl-token-minter/solang/libraries/mpl_metadata.sol b/tokens/spl-token-minter/solang/libraries/mpl_metadata.sol deleted file mode 100644 index 277dfdc1..00000000 --- a/tokens/spl-token-minter/solang/libraries/mpl_metadata.sol +++ /dev/null @@ -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 systemAddress = address"11111111111111111111111111111111"; - - // 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, - address rentAddress, - address metadataProgramId - ) 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); - } -} diff --git a/tokens/spl-token-minter/solang/libraries/spl_token.sol b/tokens/spl-token-minter/solang/libraries/spl_token.sol deleted file mode 100644 index 6532df43..00000000 --- a/tokens/spl-token-minter/solang/libraries/spl_token.sol +++ /dev/null @@ -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{ - 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); - } -} diff --git a/tokens/spl-token-minter/solang/libraries/system_instruction.sol b/tokens/spl-token-minter/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/tokens/spl-token-minter/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/tokens/spl-token-minter/solang/package.json b/tokens/spl-token-minter/solang/package.json deleted file mode 100644 index 7fa094e4..00000000 --- a/tokens/spl-token-minter/solang/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "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": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/tokens/spl-token-minter/solang/solidity/spl-token-minter.sol b/tokens/spl-token-minter/solang/solidity/spl-token-minter.sol deleted file mode 100644 index c198431a..00000000 --- a/tokens/spl-token-minter/solang/solidity/spl-token-minter.sol +++ /dev/null @@ -1,61 +0,0 @@ - -import "../libraries/spl_token.sol"; -import "../libraries/mpl_metadata.sol"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract spl_token_minter { - @payer(payer) - constructor() {} - - @mutableSigner(payer) // payer account - @mutableSigner(mint) // mint account to be created - @mutableAccount(metadata) // metadata account to be created - @signer(mintAuthority) // mint authority for the mint account - @account(rentAddress) - @account(metadataProgramId) - function createTokenMint( - address freezeAuthority, // freeze authority for the mint account - uint8 decimals, // decimals for the mint account - string name, // name for the metadata account - string symbol, // symbol for the metadata account - string uri // uri for the metadata account - ) external { - // 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 - SplToken.create_mint( - tx.accounts.payer.key, // payer account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - freezeAuthority, // freeze authority - decimals // decimals - ); - - // Invoke Metadata Program to create a new account for the metadata account - MplMetadata.create_metadata_account( - tx.accounts.metadata.key, // metadata account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - tx.accounts.payer.key, // payer - tx.accounts.payer.key, // update authority (of the metadata account) - name, // name - symbol, // symbol - uri, // uri (off-chain metadata json) - tx.accounts.rentAddress.key, - tx.accounts.metadataProgramId.key - ); - } - - @mutableAccount(mint) - @mutableAccount(tokenAccount) - @mutableSigner(mintAuthority) - function mintTo(uint64 amount) external { - // Mint tokens to the token account - SplToken.mint_to( - tx.accounts.mint.key, // mint account - tx.accounts.tokenAccount.key, // token account - tx.accounts.mintAuthority.key, // mint authority - amount // amount - ); - } -} diff --git a/tokens/spl-token-minter/solang/tests/spl-token-minter.ts b/tokens/spl-token-minter/solang/tests/spl-token-minter.ts deleted file mode 100644 index cfda90c4..00000000 --- a/tokens/spl-token-minter/solang/tests/spl-token-minter.ts +++ /dev/null @@ -1,93 +0,0 @@ -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"; - -describe("spl-token-minter", () => { - // Configure the client to use the local cluster. - 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(); - // Generate a mint keypair - const mintKeypair = anchor.web3.Keypair.generate(); - const wallet = provider.wallet as anchor.Wallet; - const connection = provider.connection; - - const program = anchor.workspace.SplTokenMinter as Program; - - // Metadata for the Token - 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"; - - it("Is initialized!", async () => { - // Initialize data account for the program, which is required by Solang - const tx = await program.methods - .new() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .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 metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - // Create the token mint - const tx = await program.methods - .createTokenMint( - wallet.publicKey, // freeze authority - 9, // decimals - tokenTitle, // token name - tokenSymbol, // token symbol - tokenUri // token uri - ) - .accounts({ - payer: wallet.publicKey, - mint: mintKeypair.publicKey, - metadata: metadataAddress, - mintAuthority: wallet.publicKey, - rentAddress: SYSVAR_RENT_PUBKEY, - metadataProgramId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s") - }) - .signers([mintKeypair]) - .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 - const tokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - wallet.payer, // payer - mintKeypair.publicKey, // mint - wallet.publicKey // owner - ); - - const tx = await program.methods - .mintTo( - new anchor.BN(150) // amount to mint - ) - .accounts({ - mintAuthority: wallet.publicKey, - tokenAccount: tokenAccount.address, - mint: mintKeypair.publicKey, - }) - .rpc({ skipPreflight: true }); - console.log("Your transaction signature", tx); - }); -}); diff --git a/tokens/spl-token-minter/solang/tsconfig.json b/tokens/spl-token-minter/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/tokens/spl-token-minter/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file diff --git a/tokens/transfer-tokens/solang/.gitignore b/tokens/transfer-tokens/solang/.gitignore deleted file mode 100644 index 8d401163..00000000 --- a/tokens/transfer-tokens/solang/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules -test-ledger -.yarn diff --git a/tokens/transfer-tokens/solang/.prettierignore b/tokens/transfer-tokens/solang/.prettierignore deleted file mode 100644 index c1a0b75f..00000000 --- a/tokens/transfer-tokens/solang/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ - -.anchor -.DS_Store -target -node_modules -dist -build -test-ledger diff --git a/tokens/transfer-tokens/solang/Anchor.toml b/tokens/transfer-tokens/solang/Anchor.toml deleted file mode 100644 index f3166308..00000000 --- a/tokens/transfer-tokens/solang/Anchor.toml +++ /dev/null @@ -1,21 +0,0 @@ -[features] -seeds = false -skip-lint = false -[programs.localnet] -transfer_tokens = "F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC" - -[registry] -url = "https://api.apr.dev" - -[provider] -cluster = "Localnet" -wallet = "~/.config/solana/id.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -[test.validator] -url = "https://api.mainnet-beta.solana.com" - -[[test.validator.clone]] -address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" \ No newline at end of file diff --git a/tokens/transfer-tokens/solang/libraries/mpl_metadata.sol b/tokens/transfer-tokens/solang/libraries/mpl_metadata.sol deleted file mode 100644 index 277dfdc1..00000000 --- a/tokens/transfer-tokens/solang/libraries/mpl_metadata.sol +++ /dev/null @@ -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 systemAddress = address"11111111111111111111111111111111"; - - // 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, - address rentAddress, - address metadataProgramId - ) 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); - } -} diff --git a/tokens/transfer-tokens/solang/libraries/spl_token.sol b/tokens/transfer-tokens/solang/libraries/spl_token.sol deleted file mode 100644 index 6532df43..00000000 --- a/tokens/transfer-tokens/solang/libraries/spl_token.sol +++ /dev/null @@ -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{ - 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); - } -} diff --git a/tokens/transfer-tokens/solang/libraries/system_instruction.sol b/tokens/transfer-tokens/solang/libraries/system_instruction.sol deleted file mode 100644 index 0ba370c8..00000000 --- a/tokens/transfer-tokens/solang/libraries/system_instruction.sol +++ /dev/null @@ -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 { - 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); - } -} diff --git a/tokens/transfer-tokens/solang/migrations/deploy.ts b/tokens/transfer-tokens/solang/migrations/deploy.ts deleted file mode 100644 index 82fb175f..00000000 --- a/tokens/transfer-tokens/solang/migrations/deploy.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Migrations are an early feature. Currently, they're nothing more than this -// single deploy script that's invoked from the CLI, injecting a provider -// configured from the workspace's Anchor.toml. - -const anchor = require("@coral-xyz/anchor"); - -module.exports = async function (provider) { - // Configure client to use the provider. - anchor.setProvider(provider); - - // Add your deploy script here. -}; diff --git a/tokens/transfer-tokens/solang/package.json b/tokens/transfer-tokens/solang/package.json deleted file mode 100644 index 7fa094e4..00000000 --- a/tokens/transfer-tokens/solang/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "scripts": { - "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" - }, - "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": { - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.3.0", - "@types/mocha": "^9.0.0", - "chai": "^4.3.4", - "mocha": "^9.0.3", - "prettier": "^2.6.2", - "ts-mocha": "^10.0.0", - "typescript": "^4.3.5" - } -} diff --git a/tokens/transfer-tokens/solang/solidity/transfer-tokens.sol b/tokens/transfer-tokens/solang/solidity/transfer-tokens.sol deleted file mode 100644 index fa10ccbc..00000000 --- a/tokens/transfer-tokens/solang/solidity/transfer-tokens.sol +++ /dev/null @@ -1,77 +0,0 @@ - -import "../libraries/spl_token.sol"; -import "../libraries/mpl_metadata.sol"; - -@program_id("F1ipperKF9EfD821ZbbYjS319LXYiBmjhzkkf5a26rC") -contract transfer_tokens { - - @payer(payer) - constructor() {} - - @mutableSigner(payer) // payer account - @mutableSigner(mint) // mint account to be created - @mutableAccount(metadata) // metadata account to be created - @signer(mintAuthority) // mint authority for the mint account - @account(rentAddress) - @account(metadataProgramId) - function createTokenMint( - address freezeAuthority, // freeze authority for the mint account - uint8 decimals, // decimals for the mint account - string name, // name for the metadata account - string symbol, // symbol for the metadata account - string uri // uri for the metadata account - ) external { - // 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 - SplToken.create_mint( - tx.accounts.payer.key, // payer account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - freezeAuthority, // freeze authority - decimals // decimals - ); - - // Invoke Metadata Program to create a new account for the metadata account - MplMetadata.create_metadata_account( - tx.accounts.metadata.key, // metadata account - tx.accounts.mint.key, // mint account - tx.accounts.mintAuthority.key, // mint authority - tx.accounts.payer.key, // payer - tx.accounts.payer.key, // update authority (of the metadata account) - name, // name - symbol, // symbol - uri, // uri (off-chain metadata json) - tx.accounts.rentAddress.key, - tx.accounts.metadataProgramId.key - ); - } - - @mutableAccount(mint) - @mutableAccount(tokenAccount) - @mutableSigner(mintAuthority) - function mintTo(uint64 amount) external { - // Mint tokens to the token account - SplToken.mint_to( - tx.accounts.mint.key, // mint account - tx.accounts.tokenAccount.key, // token account - tx.accounts.mintAuthority.key, // mint authority - amount // amount - ); - } - - // Transfer tokens from one token account to another via Cross Program Invocation to Token Program - @mutableAccount(from) // token account to transfer from - @mutableAccount(to) // token account to transfer to - @signer(owner) - function transferTokens( - uint64 amount // amount to transfer - ) external { - SplToken.transfer( - tx.accounts.from.key, - tx.accounts.to.key, - tx.accounts.owner.key, - amount - ); - } -} diff --git a/tokens/transfer-tokens/solang/tests/transfer-tokens.ts b/tokens/transfer-tokens/solang/tests/transfer-tokens.ts deleted file mode 100644 index ae713a7b..00000000 --- a/tokens/transfer-tokens/solang/tests/transfer-tokens.ts +++ /dev/null @@ -1,120 +0,0 @@ -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"; - -describe("Transfer Tokens", () => { - // Configure the client to use the local cluster. - 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 program = anchor.workspace.TransferTokens as Program; - - const nftTitle = "Homer NFT"; - const nftSymbol = "HOMR"; - const nftUri = - "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() - .accounts({ dataAccount: dataAccount.publicKey }) - .signers([dataAccount]) - .rpc(); - console.log("Your transaction signature", tx); - }); - - it("Create an SPL Token!", async () => { - const metaplex = Metaplex.make(connection); - const metadataAddress = await metaplex - .nfts() - .pdas() - .metadata({ mint: mintKeypair.publicKey }); - - // Add your test here. - const tx = await program.methods - .createTokenMint( - wallet.publicKey, // freeze authority - 9, // 0 decimals for NFT - nftTitle, // NFT name - nftSymbol, // NFT symbol - nftUri // NFT URI - ) - .accounts({ - payer: wallet.publicKey, - mint: mintKeypair.publicKey, - metadata: metadataAddress, - mintAuthority: wallet.publicKey, - rentAddress: SYSVAR_RENT_PUBKEY, - metadataProgramId: new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), - }) - .signers([mintKeypair]) - .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 - const tokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - wallet.payer, // payer - mintKeypair.publicKey, // mint - wallet.publicKey // owner - ); - - const tx = await program.methods - .mintTo( - new anchor.BN(150) // amount to mint - ) - .accounts({ - mintAuthority: wallet.publicKey, - tokenAccount: tokenAccount.address, - mint: mintKeypair.publicKey, - }) - .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 - const tokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - wallet.payer, // payer - mintKeypair.publicKey, // mint - wallet.publicKey // owner - ); - - 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( - new anchor.BN(150) - ) - .accounts({ - from: tokenAccount.address, - to: receipientTokenAccount.address, - owner: wallet.publicKey, - }) - .rpc(); - console.log("Your transaction signature", tx); - }); -}); diff --git a/tokens/transfer-tokens/solang/tsconfig.json b/tokens/transfer-tokens/solang/tsconfig.json deleted file mode 100644 index 5436e66f..00000000 --- a/tokens/transfer-tokens/solang/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "types": ["mocha", "chai"], - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } -} - \ No newline at end of file