How to make non-transferable token on solana - solana

I'm trying to deploy non-transferable token on solana. As explained in the document, I used token-program-2022 example with non-transferable extension.
import {
clusterApiUrl,
sendAndConfirmTransaction,
Connection,
Keypair,
SystemProgram,
Transaction,
LAMPORTS_PER_SOL,
} from '#solana/web3.js';
import {
createInitializeNonTransferableMintInstruction,
createInitializeMintInstruction,
getMintLen,
ExtensionType,
TOKEN_2022_PROGRAM_ID,
} from '#solana/spl-token';
(async () => {
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
const payer = Keypair.generate();
const airdropSignature = await connection.requestAirdrop(payer.publicKey, 2 * LAMPORTS_PER_SOL);
await connection.confirmTransaction({ signature: airdropSignature, ...(await connection.getLatestBlockhash()) });
const mintAuthority = Keypair.generate();
const decimals = 9;
const mintKeypair = Keypair.generate();
const mint = mintKeypair.publicKey;
const mintLen = getMintLen([ExtensionType.NonTransferable]);
const lamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const transaction = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mint,
space: mintLen,
lamports,
programId: TOKEN_2022_PROGRAM_ID,
}),
createInitializeNonTransferableMintInstruction(mint, TOKEN_2022_PROGRAM_ID),
createInitializeMintInstruction(mint, decimals, mintAuthority.publicKey, null, TOKEN_2022_PROGRAM_ID)
);
await sendAndConfirmTransaction(connection, transaction, [payer, mintKeypair], undefined);
})();
But my transaction failed with this logs.
SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 1: custom program error: 0xc
at Connection.sendEncodedTransaction (/Users/user/Desktop/workspace/solana-nft-js-test/node_modules/#solana/web3.js/src/connection.ts:4825:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (/Users/user/Desktop/workspace/solana-nft-js-test/node_modules/#solana/web3.js/src/connection.ts:4784:20)
at async Connection.sendTransaction (/Users/user/Desktop/workspace/solana-nft-js-test/node_modules/#solana/web3.js/src/connection.ts:4772:12)
at async sendAndConfirmTransaction (/Users/user/Desktop/workspace/solana-nft-js-test/node_modules/#solana/web3.js/src/utils/send-and-confirm-transaction.ts:31:21)
at async /Users/user/Desktop/workspace/solana-nft-js-test/src/example.ts:87:3 {
logs: [
'Program 11111111111111111111111111111111 invoke [1]',
'Program 11111111111111111111111111111111 success',
'Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb invoke [1]',
'Program log: Error: Invalid instruction',
'Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb consumed 725 of 600000 compute units',
'Program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb failed: custom program error: 0xc'
]
}
I can't find the reason why the transaction failed. Is token-program-2022 deployed on the 'devnet' different from the program in spl git repository?

Related

mint_to from token.sol example from solang throw new Error(unknown signer: ${signature.publicKey.toString()});

I tried to mint token with solang example contract:
https://github.com/hyperledger-labs/solang/blob/main/integration/solana/token.sol
and at contract.functions.mint_to it throw error unknown signer: ${signature.publicKey.toString()
Where is the error in code?
My js code reworked from
https://github.com/hyperledger-labs/solang/blob/main/integration/solana/token.spec.ts
here:
const web3 = require('#solana/web3.js');
const { PublicKey, clusterApiUrl, Connection, LAMPORTS_PER_SOL, Keypair } = require('#solana/web3.js');
const { Contract, Program, publicKeyToHex } = require('#solana/solidity');
const { readFileSync } = require('fs');
const { getOrCreateAssociatedTokenAccount, createMint, TOKEN_PROGRAM_ID, mintTo , splToken} = require('#solana/spl-token');
const SPL_TOKEN_ABI = JSON.parse(readFileSync('./Token.abi', 'utf8'));
const PROGRAM_SO = readFileSync('./bundle.so');
(async function () {
console.log('Connecting to your local Solana node ...');
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
const payer = Keypair.generate();
const freezeAuthority = Keypair.generate();
const mintAuthority = Keypair.generate();
const program = Keypair.generate();
const storage = Keypair.generate();
console.log('address payer: ' + payer.publicKey.toBase58());
console.log('Airdropping SOL to a new wallet payer.publicKey ...');
const signature = await connection.requestAirdrop(payer.publicKey, 1.5 * LAMPORTS_PER_SOL);
await connection.confirmTransaction(signature, 'confirmed');
console.log('new Contract ...');
const contract = new Contract(connection, program.publicKey, storage.publicKey, SPL_TOKEN_ABI, payer);
console.log('address program.publicKey: ' + program.publicKey.toBase58());
console.log('address storage.publicKey: ' + storage.publicKey.toBase58());
await contract.load(program, PROGRAM_SO);
await contract.deploy('Token', [], program, storage, 3096 *8);
console.log('contract deployed ...');
console.log('createMint ...');
const mint = await createMint(
connection,
payer,
mintAuthority.publicKey,
freezeAuthority.publicKey,
3
);
console.log('set_mint ...');
await contract.functions.set_mint(publicKeyToHex(mint));
console.log('getOrCreateAssociatedTokenAccount ...');
const tokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
payer,
mint,
payer.publicKey
)
console.log('address mint: ' + mint.toBase58());
console.log('address tokenAccount.address: ' + tokenAccount.address.toBase58());
console.log('address mintAuthority.publicKey: ' + mintAuthority.publicKey.toBase58());
console.log('address payer.publicKey: ' + payer.publicKey.toBase58());
console.log('mint_to ...');
await contract.functions.mint_to(
publicKeyToHex(tokenAccount.address),
publicKeyToHex(mintAuthority.publicKey),
100000,
{
accounts: [TOKEN_PROGRAM_ID],
writableAccounts: [mint, tokenAccount.address],
signers: [mintAuthority]
},
);
})();
Error logs after calling script:
/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:2690
throw new Error(`unknown signer: ${signature.publicKey.toString()}`);
^
Error: unknown signer: CKq7xZwFqbaJtcFCChWuYFzgZMEoYRMZPftxAi7JTQi7
at Transaction.compileMessage (/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:2690:15)
at Transaction._compile (/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:2753:26)
at Transaction.sign (/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:2858:26)
at Connection.sendTransaction (/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:7382:21)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async sendAndConfirmTransaction (/home/alex/node_modules/#solana/web3.js/lib/index.cjs.js:3133:21)
How can I mint token with https://github.com/hyperledger-labs/solang/blob/main/integration/solana/token.sol smart contract?
Thank you for any help.
![Whole log is here: ] (https://i.stack.imgur.com/NGzM1.png)

Why is this contract call failing (rust-counter increment)?

I am attempting to call the increment in the counter contract here, which is deployed to my account on testnet, using the following script:
const nearAPI = require("near-api-js");
require("dotenv").config();
const {parseSeedPhrase} = require("near-seed-phrase");
async function call() {
const mneumonic = process.env.nearmneumonic0?.trim() || "";
const ACCOUNT_ID = process.env.nearacct0?.trim() || "";
const keyStores = nearAPI.keyStores;
const keyPair = nearAPI.KeyPair;
const connect = nearAPI.connect;
const keyStore = new keyStores.InMemoryKeyStore();
const PRIVATE_KEY = parseSeedPhrase(mneumonic);
const keyPair_ = keyPair.fromString(PRIVATE_KEY.secretKey);
await keyStore.setKey("testnet", ACCOUNT_ID, keyPair_);
const config = {
keyStore,
networkId: "testnet",
nodeUrl: "https://rpc.testnet.near.org",
};
const near = await connect(config);
const account = await near.account(ACCOUNT_ID);
const contract = new nearAPI.Contract(
account,
ACCOUNT_ID,
{
changeMethods: ["increment", "decrement", "reset"],
viewMethods: ["get_num"],
sender: account,
}
);
let response = await contract.increment(
{
args: {
//arg_name: "value"
},
gas: 300000000000000
}
);
console.log(response);
}
call();
However, the response thrown is al followed:
Failure [acct.testnet]: Error: Contract method is not found
...
ServerTransactionError: Contract method is not found
I have looked through some of the docs, which mention to add changeMethod/viewMethod, however it seems there is still errors thrown.
Any help much appreciated!

How do I "unwrap SOL" using the web3 sdk?

I need to unwrap some SOL using the web3 sdk. I'm wondering, Is it just a simple transfer from the wrapped account into SOL account or is it more complicated than that? Below Is just some sample code I've setup.
const emptyWSolAccount = async (amount:any) => {
const wsolAddress = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
new PublicKey("So11111111111111111111111111111111111111112"),
wallet.publicKey
);
const wsolAccount = await connection.getAccountInfo(wsolAddress);
if (wsolAccount) {
const transaction = new Transaction({
feePayer: wallet.publicKey,
});
const instructions = [];
const lamports = amount * LAMPORTS_PER_SOL;
instructions.push(
SystemProgram.transfer({
fromPubkey: wsolAddress,
toPubkey: wallet.publicKey,
lamports: lamports, // 1 sol
})
);
transaction.add(...instructions);
transaction.recentBlockhash = await (
await connection.getRecentBlockhash()
).blockhash;
transaction.partialSign(wallet.payer);
const result = await connection.sendTransaction(transaction, [
wallet.payer,
]);
console.log({ result });
return { result };
}
return ;
};
This is not really explained anywhere, but unwrapping SOL actually means closing the wrapped SOL account.
So instead of using a SystemProgram.transfer instruction, you'll do:
instructions.push(
splToken.instructions.createCloseAccountInstruction(
wsolAddress,
wallet.publicKey,
wallet.publicKey,
)
);
This closes wsolAddress and sends the contents to wallet, assuming that wallet is the owner.
You can see the CLI implementation at https://github.com/solana-labs/solana-program-library/blob/3db53e278b543a040d3c970797b6be6f9ea5aef9/token/cli/src/main.rs#L1139-L1194

Retrying failed custom token transaction with '#solana/web3.js'

I want to send my deployed token other than sol using solana web3.js. My code works most of the time but sometimes the transaction fails.
I put a while loop so that when the transaction fails the client retries it with the sendRawTransaction function. The problem is that when it fails the first time it always fails after it.
const provider = await this.getProvider();
const publicKey = new web3.PublicKey(this.wallet);
const toPublicKey = new web3.PublicKey(
"the public key to send"
);
const mint = new web3.PublicKey(
"my token adress"
);
const connection = await new Connection(clusterApiUrl("mainnet-beta"));
const { signTransaction } = useWallet();
const fromTokenAccount = await this.getOrCreateAssociatedTokenAccount(
connection,
publicKey,
mint,
publicKey,
signTransaction
)
});
const toTokenAccount = await this.getOrCreateAssociatedTokenAccount(
connection,
publicKey,
mint,
toPublicKey,
signTransaction
);
const transferInstruction = await this.createTransferInstruction(
fromTokenAccount.address, // source
toTokenAccount.address, // dest
publicKey,
amount,
[],
TOKEN_PROGRAM_ID
);
const transaction = new Transaction().add(transferInstruction);
var blockHash = await connection.getLatestBlockhash('finalized');
transaction.feePayer = await publicKey;
console.log(blockHash.blockhash)
transaction.recentBlockhash = blockHash.blockhash;
// const provider = await this.getProvider();
const signed = await provider.signTransaction(transaction);
window.createEvent('openPopup', {
text: 'Your transaction is being validated by the Solana blockchain.',
loading: 30,
show: true
})
var nbRetry = 0;
while(true){
const signature = await connection.sendRawTransaction(signed.serialize())
this.post(`verifyTransaction`, {
signature,
})
.then(() => {
window.location.assign('/transaction_success')
})
.catch(async (error) => {
if (error.response.status === 403) {
if (nbRetry > 5){
window.createEvent('openPopup', {
show: true,
image: 'error.png',
text: 'The transaction failed.',
reload: true
})} else nbRetry++;
}}
})

Signature verification failed When transferring spl-token to user connected phantom wallet

bs58.decode(
"2YQDdnfxiHPKu9GypLX1yXaQTQojvDSPgFkDxrU********************************************"
)
const mintPubkey =
"A8SJfwzKJAaMrY6Lb*************************";
const getProvider = async () => {
// opens wallet to connect to
await window.solana.connect();
const provider = window.solana;
}
const network = "https://api.devnet.solana.com";
const connection = new Connection(network);
var provider = await getProvider()
console.log(provider.publicKey.toString())
const userWalletPublicKey = provider.publicKey;
var myMint = new PublicKey(mintPubkey);
var myToken = new Token(
connection,
myMint,
TOKEN_PROGRAM_ID,
alice
);
const fromTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
alice.publicKey,
);
const toTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
userWalletPublicKey,
);
// Add token transfer instructions to transaction
const transaction = new Transaction().add(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
fromTokenAccount.address,
toTokenAccount.address,
alice.publicKey,
[],
1,
),
);
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
transaction.feePayer = userWalletPublicKey;
const signedTransaction = await window.solana.signTransaction(transaction);
const signature = await connection.sendRawTransaction(signedTransaction.serialize());
when I try to approve the transection it gives me signature verification failed
I am using SPL-TOKEN Library and Solana web3 js
did I implement the spl-transfer token with phantom correctly?
Your help on this will be much appreciated
basically i am trying to make when a user click on buy it transfer the nft present in my wallet to the guy's wallet who connected and clicked on buy

Resources