this is more of a question than an actual issue
I want to use the contract
https://github.com/ironaddicteddog/anchor-escrow
to exchange tokens.
My plan is as follows, however I'm unsuccessful initializing the contract.
logs: [
'Program 11111111111111111111111111111111 invoke [1]',
'Create Account: account Address { address: 2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ, base: None } already in use',
'Program 11111111111111111111111111111111 failed: custom program error: 0x0'
]
Note: 2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ is the contract address in the lib.rs
Deploy program ✅ 2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ
Create Token A DhS6x9pTrfCeY8iwkRdGstxUuphbeHqddT2vZSWRw3d2 and Token B HpdLmjjxD8YZav2S1aastqyLsKDUb1ToLDfq4hPsLBoc ✅
Create token accounts Token A account Cj6cMp4xfAaCFegMg9G7GQaZWqYbQqgmu7Vjd4BbGYHh, Token B account HpdLmjjxD8YZav2S1aastqyLsKDUb1ToLDfq4hPsLBoc✅
Initialize contract ❌.
Exchange tokens
I've written following script to initialize the contract.
import * as anchor from '#project-serum/anchor';
import { PublicKey, SystemProgram, Transaction, Connection, Commitment } from '#solana/web3.js';
import { TOKEN_PROGRAM_ID, Token } from "#solana/spl-token";
import {
escrowAccount,
initializerMainAccount,
initializerTokenAccountA,
initializerTokenAccountB,
mintAPublicKey,
mintBPublicKey } from './accounts'
import NodeWallet from '#project-serum/anchor/dist/cjs/nodewallet';
const takerAmount = 1000;
const initializerAmount = 500;
const commitment: Commitment = 'processed';
const connection = new Connection('https://api.devnet.solana.com', { commitment, wsEndpoint: 'wss://api.devnet.solana.com/' });
// const connection = new Connection('http://127.0.0.1:8899', { commitment, wsEndpoint: 'wss://127.0.0.1:8899/' });
const options = anchor.Provider.defaultOptions();
const wallet = new NodeWallet(initializerMainAccount);
const provider = new anchor.Provider(connection, wallet, options);
anchor.setProvider(provider);
// Read the generated IDL.
const idl = JSON.parse(
require("fs").readFileSync("./tests/keypair/anchor_escrow.json", "utf8")
);
// Address of the deployed program.
const programId = new anchor.web3.PublicKey("2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ");
// Generate the program client from IDL.
const program = new anchor.Program(idl, programId);
const initEscrow = async () => {
const [_vault_account_pda, _vault_account_bump] = await PublicKey.findProgramAddress(
[Buffer.from(anchor.utils.bytes.utf8.encode("token-seed"))],
program.programId,
);
const vault_account_pda = _vault_account_pda;
const vault_account_bump = _vault_account_bump;
const [_vault_authority_pda, _vault_authority_bump] = await PublicKey.findProgramAddress(
[Buffer.from(anchor.utils.bytes.utf8.encode("escrow"))],
program.programId,
);
// DEBUG BEGIN
// console.info(`initializerMainAccount: ` + JSON.stringify(initializerMainAccount, null, 2));
// console.info(`Escrow account: ` + JSON.stringify(escrowAccount));
console.info(`Mint A: ` + mintAPublicKey.toBase58());
console.info(`Mint B: ` + mintBPublicKey.toBase58());
console.info(`TOKEN_PROGRAM_ID: ` + TOKEN_PROGRAM_ID);
console.info(`SYSVAR_RENT_PUBKEY: ` + anchor.web3.SYSVAR_RENT_PUBKEY);
// DEBUG CONSOLE END
await program.rpc.initialize(
vault_account_bump,
new anchor.BN(initializerAmount),
new anchor.BN(takerAmount),
{
accounts: {
initializer: initializerMainAccount.publicKey,
mint: mintAPublicKey,
vaultAccount: vault_account_pda,
initializerDepositTokenAccount: initializerTokenAccountA,
initializerReceiveTokenAccount: initializerTokenAccountB,
escrowAccount: escrowAccount.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
tokenProgram: TOKEN_PROGRAM_ID,
},
instructions: [
await program.account.escrowAccount.createInstruction(escrowAccount),
],
signers: [escrowAccount, initializerMainAccount],
}
);
}
initEscrow();
Long version of the error output is
➜ anchor-escrow git:(master) ✗ ts-node tests/init2.ts
Mint A: DhS6x9pTrfCeY8iwkRdGstxUuphbeHqddT2vZSWRw3d2
Mint B: HpdLmjjxD8YZav2S1aastqyLsKDUb1ToLDfq4hPsLBoc
TOKEN_PROGRAM_ID: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
SYSVAR_RENT_PUBKEY: SysvarRent111111111111111111111111111111111
Transaction simulation failed: Error processing Instruction 0: custom program error: 0x0
Program 11111111111111111111111111111111 invoke [1]
Create Account: account Address { address: 2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ, base: None } already in use
Program 11111111111111111111111111111111 failed: custom program error: 0x0
/Users/tuncatunc/git/anchor-escrow/node_modules/#solana/web3.js/src/connection.ts:3961
throw new SendTransactionError(
^
SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x0
at Connection.sendEncodedTransaction (/Users/tuncatunc/git/anchor-escrow/node_modules/#solana/web3.js/src/connection.ts:3961:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (/Users/tuncatunc/git/anchor-escrow/node_modules/#solana/web3.js/src/connection.ts:3918:20)
at async sendAndConfirmRawTransaction (/Users/tuncatunc/git/anchor-escrow/node_modules/#solana/web3.js/src/util/send-and-confirm-raw-transaction.ts:27:21)
at async Provider.send (/Users/tuncatunc/git/anchor-escrow/node_modules/#project-serum/anchor/src/provider.ts:118:18)
at async Object.rpc [as initialize] (/Users/tuncatunc/git/anchor-escrow/node_modules/#project-serum/anchor/src/program/namespace/rpc.ts:25:23) {
logs: [
'Program 11111111111111111111111111111111 invoke [1]',
'Create Account: account Address { address: 2yTRYBq58ZMgudQcEp18UnsCBPTUx9a12ZnzZ7N7v9hQ, base: None } already in use',
'Program 11111111111111111111111111111111 failed: custom program error: 0x0'
]
}
This is a long post
Thx a lot in advance for writing this contract to guide solana contract devs.
BR
I'll answer my own question here,
I figured out that the escrow program is already initialized.
The error log says that, it cannot use the same escrow account to re-initialize.
Related
I'm trying to find a way to run Next.js (v13.0.6) with OG image generation logic (using #vercel/og) in AWS Lambda
Everything works fine locally (in dev and prod mode) but when I try execute lambda handler getting "statusCode": 500,
It only fails for apis that involve ImageResponse (and runtime: 'experimental-edge' as a requirement for #vercel/og)
I'm pretty sure the problem is caused by Edge Runtime is not being configured correctly
There is my handler code
next build with next.config.js output: 'standalone' creates folder .next/standalone
insde standalone handler.js
const { parse } = require('url');
const NextServer = require('next/dist/server/next-server').default
const serverless = require('serverless-http');
const path = require('path');
process.env.NODE_ENV = 'production'
process.chdir(__dirname)
const currentPort = parseInt(process.env.PORT, 10) || 3000
const nextServer = new NextServer({
hostname: 'localhost',
port: currentPort,
dir: path.join(__dirname),
dev: false,
customServer: false,
conf: {...} // copied from `server.js` in there same folder
});
const requestHandler = nextServer.getRequestHandler();
// this is a AWS lambda handler that converts lambda event
// to http request that next server can process
const handler = serverless(async (req, res) => {
// const parsedUrl = parse(req.url, true);
try {
await requestHandler(req, res);
}catch(err){
console.error(err);
res.statusCode = 500
res.end('internal server error')
}
});
module.exports = {
handler
}
testing it locally with local-lambda, but getting similar results when test against AWS deployed lambda
what is confusing is that server.js (in .next/standalone) has a similar setup, it only involves http server on top of of it
update:
aws lambda logs show
ERROR [Error [CompileError]: WebAssembly.compile(): Compiling function #64 failed: invalid value type 'Simd128', enable with --experimental-wasm-simd #+3457 ]
update 2:
the first error was fixed by selecting Node 16 for AWS lambda, now getting this error
{
"errorType": "Error",
"errorMessage": "write after end",
"trace": [
"Error [ERR_STREAM_WRITE_AFTER_END]: write after end",
" at new NodeError (node:internal/errors:372:5)",
" at ServerlessResponse.end (node:_http_outgoing:846:15)",
" at ServerlessResponse.end (/var/task/node_modules/next/dist/compiled/compression/index.js:22:783)",
" at NodeNextResponse.send (/var/task/node_modules/next/dist/server/base-http/node.js:93:19)",
" at NextNodeServer.handleRequest (/var/task/node_modules/next/dist/server/base-server.js:332:47)",
" at processTicksAndRejections (node:internal/process/task_queues:96:5)",
" at async /var/task/index.js:34:5"
]
}
At the moment of writing Vercel's runtime: 'experimental-edge' seems to be unstable (run into multiple issues with it)
I ended up recreating #vercel/og lib without wasm and next.js dependencies, can be found here
and simply use it in AWS lambda. It depends on #resvg/resvg-js instead of wasm version, which uses binaries, so there should not be much perf loss comparing to wasm
I'mn trying to update a list of nfts to have a new secondary creator (the one with the 100% share). I don't think it's possible to update the first creator because I think the first creator is signed by the candy machine that created the nft? Anyway here's my code:
import { keypairIdentity, Metadata, Metaplex } from '#metaplex-foundation/js'
import { Connection, Keypair, PublicKey } from '#solana/web3.js'
import { program } from 'commander'
import { readFileSync, writeFileSync } from 'fs'
program
.command('update_creators')
.description('Updates the creator of all nfts')
.requiredOption(
'-i, --input-file <string>',
'Json file, list of NFT mint details'
)
.requiredOption(
'-o, --output-file <string>',
'Output file for NFT addresses that failed to update'
)
.requiredOption(
'-k, --keypair-file <path>',
`JSON file containing private key of token owner`,
'.cache/creator-keypair.json'
)
.option('-r, --rpc <string>', 'JSON rpc api url', defaultRpc)
.action(async ({ inputFile, outputFile, keypairFile, rpc }) => {
const connection = new Connection(rpc)
const metaplex = Metaplex.make(connection)
const keypairFileContents = readFileSync(keypairFile, 'utf-8')
const keypair = Keypair.fromSecretKey(
Buffer.from(JSON.parse(keypairFileContents))
)
metaplex.use(keypairIdentity(keypair))
const nftMintAddresses = JSON.parse(
readFileSync(inputFile, 'utf-8')
) as string[]
let nfts = (await metaplex
.nfts()
.findAllByMintList({
mints: nftMintAddresses.map(mint => new PublicKey(mint)),
})
.run()) as Metadata[]
const newCreator = new PublicKey(
'CUAwUE5N3TdHHHyPTHb3E5mpnpQFiRF6BcY8kEvJakfS'
)
const failedNfts: any[] = []
for (const nft of nfts) {
try {
console.dir(nft, { depth: null })
const newNft = await metaplex
.nfts()
.update({
nftOrSft: nft,
creators: [
nft.creators[0],
{
address: newCreator,
share: 100,
authority: keypair,
},
],
})
.run()
console.dir(newNft, { depth: null })
} catch (e) {
console.error(e)
failedNfts.push(nft)
process.exit()
}
}
writeFileSync(outputFile, JSON.stringify(failedNfts))
})
Note, the metaplex.use() keypair I'm using is the same wallet used to create the candy machine and has authority to update the nfts, but I keep getting the following error:
ParsedProgramError [MetaplexError]: TokenMetadataProgram > Incorrect account owner
>> Source: Program > TokenMetadataProgram [metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s]
>> Problem: The program [TokenMetadataProgram] at address [metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s] raised an error of code [57] that translates to "Incorrect account owner".
>> Solution: Check the error message provided by the program.
Caused By: IncorrectOwner: Incorrect account owner
at RpcClient.parseProgramError (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:302:9)
at RpcClient.sendTransaction (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:87:18)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RpcClient.sendAndConfirmTransaction (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:117:23)
at async TransactionBuilder.sendAndConfirm (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\TransactionBuilder.ts:189:22)
at async C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\Task.ts:82:23
at async Disposable.run (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\Disposable.ts:34:14)
at async Command.<anonymous> (C:\xampp\htdocs\sol-tools\src\cli.ts:263:24) {
key: 'metaplex.errors.program.parsed_program_error',
title: 'TokenMetadataProgram > Incorrect account owner',
problem: 'The program [TokenMetadataProgram] at address [metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s] raised an error of code [57] that translates to "Incorrect account owner".',
solution: 'Check the error message provided by the program.',
source: 'program',
sourceDetails: 'TokenMetadataProgram [metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s]',
cause: IncorrectOwner: Incorrect account owner
at Object.errorResolver (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\nftModule\plugin.ts:70:16)
at RpcClient.parseProgramError (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:299:35)
at RpcClient.sendTransaction (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:87:18)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async RpcClient.sendAndConfirmTransaction (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\plugins\rpcModule\RpcClient.ts:117:23)
at async TransactionBuilder.sendAndConfirm (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\TransactionBuilder.ts:189:22)
at async C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\Task.ts:82:23
at async Disposable.run (C:\xampp\htdocs\sol-tools\node_modules\#metaplex-foundation\js\src\utils\Disposable.ts:34:14)
at async Command.<anonymous> (C:\xampp\htdocs\sol-tools\src\cli.ts:263:24) {
code: 57
},
logs: undefined,
program: {
name: 'TokenMetadataProgram',
address: PublicKey {
_bn: <BN: b7065b1e3d17c45389d527f6b04c3cd58b86c731aa0fdb549b6d1bc03f82946>
},
errorResolver: [Function: errorResolver],
gpaResolver: [Function: gpaResolver]
}
}
And here's one of the NFTs I'm trying to update:
https://solscan.io/token/3woKb11Ajs9VkzHhMNkiyX5za1bV3STBmSaDHoQgmBKp#metadata
Any help would be appreciated. Thanks!
I'm trying to use auctioneer sale function from the auctioneer sdk. But i get this Error
'Program neer8g6yJq2mQM6KbnViEDAD4gr3gRZyMMf4F2p3MEh invoke [1]', 'Program log: Instruction: Sell', "4xd58eAU6pZQCwSigE5bXMspTKus1fBFm1TpDU4m4AWc's signer privilege escalated", 'Program neer8g6yJq2mQM6KbnViEDAD4gr3gRZyMMf4F2p3MEh consumed 15605 of 200000 compute units', 'Program neer8g6yJq2mQM6KbnViEDAD4gr3gRZyMMf4F2p3MEh failed: Cross-program invocation with unauthorized signer or writable account'
The Address 4xd58eAU6pZQCwSigE5bXMspTKus1fBFm1TpDU4m4AWc is the address of the listing config address.
I'm Finding auctioneer with this
const listingConfig = await PublicKey.createProgramAddress(
[ Buffer.from("listing_config"),
publicKey.toBuffer(),
aH.toBuffer(),
associatedAddress.toBuffer(),
WRAPPED_SOL_MINT.toBuffer(),
mint.toBuffer(),
new BN(1)
],
AUCTIONEER
)
which is the same as defined in this
pub fn find_listing_config_address(
wallet: &Pubkey,
auction_house: &Pubkey,
token_account: &Pubkey,
treasury_mint: &Pubkey,
token_mint: &Pubkey,
token_size: u64,
) -> (Pubkey, u8) {
Pubkey::find_program_address(
&[
LISTING_CONFIG.as_bytes(),
wallet.as_ref(),
auction_house.as_ref(),
token_account.as_ref(),
treasury_mint.as_ref(),
token_mint.as_ref(),
&token_size.to_le_bytes(),
],
&id(),
)
}
could it be possible that the error is coming from somewhere else?
In the listing Config we have to pass token size to a buffer like
const listingConfig = await PublicKey.createProgramAddress(
[ Buffer.from("listing_config"),
publicKey.toBuffer(),
aH.toBuffer(),
associatedAddress.toBuffer(),
WRAPPED_SOL_MINT.toBuffer(),
mint.toBuffer(),
new BN (1).toBuffer('le',8)
],
AUCTIONEER
)
I am trying to build a simple coin flip game in solana.
Full code here
I get this error:
Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x0
I followed some tutorials on how to use PDA's but couldn't find a report/workaround to an error as such.
Tests are running on localhost
I did some research and it might be that the account was already initialized ( maybe, no idea)
the part that is giving the error:
try {
await program.rpc.initialize(bump,
{
accounts: {
treasury: treasuryPda, // publickey for our new account
user: provider.wallet.publicKey,
systemProgram: SystemProgram.programId // just for Anchor reference
},
});
} catch (error) {
console.log("Transaction error: ", error);
console.log("blabla:", error.toString());
}
I'm actually stuck at the first step on connecting to phantom wallet. I'm trying to perform the following step.
Connect to Phantom wallet
Get a Public key
Get Balance of all tokens
Perform Buy/Sell
I'm able to connect to a phantom wallet with the below code. I'm not sure if the next step in the process is to get a public key so that I can find the balance of all tokens as part of the account.
const balance = connection.getBalance(publicKey);
The above method is what I found from the documentation, but I'm not sure how can I get the publicKey of the end user who connected their wallet to the webiste.
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl("mainnet-beta")) console.log(connection);
assume you have react app for integrating with solana wallets, first of all install these packages:
yarn add #solana/wallet-adapter-base \
#solana/wallet-adapter-react \
#solana/wallet-adapter-react-ui \
#solana/wallet-adapter-wallets \
#solana/web3.js \
react
you can use next, vue, angular, svelte and material ui as well
next we have this setup:
import React, { FC, useMemo } from 'react';
import { ConnectionProvider, WalletProvider } from '#solana/wallet-adapter-react';
import { WalletAdapterNetwork } from '#solana/wallet-adapter-base';
import {
//LedgerWalletAdapter,
PhantomWalletAdapter,
SolflareWalletAdapter,
//SlopeWalletAdapter,
//SolletExtensionWalletAdapter,
//SolletWalletAdapter,
//TorusWalletAdapter,
} from '#solana/wallet-adapter-wallets';
import {
WalletModalProvider,
WalletDisconnectButton,
WalletMultiButton
} from '#solana/wallet-adapter-react-ui';
import { clusterApiUrl } from '#solana/web3.js';
// Default styles that can be overridden by your app
require('#solana/wallet-adapter-react-ui/styles.css');
export const Wallet: FC = () => {
// The network can be set to 'devnet', 'testnet', or 'mainnet-beta'.
const network = WalletAdapterNetwork.Devnet;
// You can also provide a custom RPC endpoint.
const endpoint = useMemo(() => clusterApiUrl(network), [network]);
// #solana/wallet-adapter-wallets includes all the adapters but supports tree shaking and lazy loading --
// Only the wallets you configure here will be compiled into your application, and only the dependencies
// of wallets that your users connect to will be loaded.
const wallets = useMemo(
() => [
new PhantomWalletAdapter(),
new SlopeWalletAdapter(),
new SolflareWalletAdapter(),
new TorusWalletAdapter(),
new LedgerWalletAdapter(),
new SolletWalletAdapter({ network }),
new SolletExtensionWalletAdapter({ network }),
],
[network]
);
return (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>
<WalletMultiButton />
<WalletDisconnectButton />
{ /* Your app's components go here, nested within the context providers. */ }
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
};
after import modules, I commented some wallet adapters except phantom and solfare
also this code block is so important:
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>
<WalletMultiButton />
<WalletDisconnectButton />
{ /* Your app's components go here, nested within the context
providers. */ }
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
modals with functional buttons surrounded by
ConnectionProvider: prepare endpoint for wallets to connecting to and query wallet tokens
WalletProvider: prepare which wallets should be load in modals and ready to connect
and finally usage:
import { WalletNotConnectedError } from '#solana/wallet-adapter-base';
import { useConnection, useWallet } from '#solana/wallet-adapter-react';
import { Keypair, SystemProgram, Transaction } from '#solana/web3.js';
import React, { FC, useCallback } from 'react';
export const SendOneLamportToRandomAddress: FC = () => {
const { connection } = useConnection();
const { publicKey, sendTransaction } = useWallet();
const onClick = useCallback(async () => {
if (!publicKey) throw new WalletNotConnectedError();
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: publicKey,
toPubkey: Keypair.generate().publicKey,
lamports: 1,
})
);
const signature = await sendTransaction(transaction, connection);
await connection.confirmTransaction(signature, 'processed');
}, [publicKey, sendTransaction, connection]);
return (
<button onClick={onClick} disabled={!publicKey}>
Send 1 lamport to a random address!
</button>
);
};
so as you can see above this part
const { connection } = useConnection();
const { publicKey, sendTransaction } = useWallet();
was prepared for making a connection and give you connected wallet public key and also make use of sendTransaction function of connected wallet, sounds good!
other parts of code are obvous i think.
so, how many functions we have with wallet adapters like phantom? and what functions?
we can get public key, connecting(boolean), connected(boolean), readyState.
also we have some other main functions like:
connect
disconnect
sendTransaction
signTransaction
signAllTransactions
signMessage
you can see all of them in this github repo link
another point is if you use Anchor framework you should know that Anchor uses its own "Wallet" object to interact with the connected wallet and sign transactions on its behalf.
so In order to get an object compatible with Anchor's definition of a wallet, we can use yet another composable called useAnchorWallet. This will return a wallet object that can sign transactions.
const wallet = useAnchorWallet()
have fun