Closed rahulanand20 closed 2 years ago
How to sign a transaction without a private key of the buyer?
a tx = signatures + a message
the main idea is that you compose the message and send to user for signing. when you compose the message, you don't need user's private key. you only need the pubkey.
Thanks @yihau for the reply .
sir in this above line Signer is of type.Account and we will not be able to use feepayer.publickey in the as it belongs to the common
if i try to remove Signer I'm getting this error "2022/07/13 13:40:52 failed to send tx, err: rpc response error: {"code":-32003,"message":"Transaction signature verification failure"}"
Also if i try to use different Singer failed to new a tx, err: add not necessary signatures, 7s6Ro1mBBmmKmP2QDT2zzuCMqS6AVCgBQi1mRnsjX4QG is not a signer as it is not a correct singer
This is my code can you help me modifying this to make it work with only public key
package main
import ( "context" "fmt" "log"
"github.com/mr-tron/base58"
"github.com/portto/solana-go-sdk/client"
"github.com/portto/solana-go-sdk/common"
"github.com/portto/solana-go-sdk/pkg/pointer"
"github.com/portto/solana-go-sdk/program/assotokenprog"
"github.com/portto/solana-go-sdk/program/metaplex/tokenmeta"
"github.com/portto/solana-go-sdk/program/sysprog"
"github.com/portto/solana-go-sdk/program/tokenprog"
"github.com/portto/solana-go-sdk/rpc"
"github.com/portto/solana-go-sdk/types"
)
func main() { //
func main() {
//var feePayer, _ = types.AccountFromBase58("")
var feePayer1 = common.PublicKeyFromString("43xqaQkf8N95Af64ZqafbcQsPWdKqy5BRWxH7FFYomqX")
c := client.NewClient(rpc.DevnetRPCEndpoint)
mint := types.NewAccount()
fmt.Printf("NFT: %v\n", mint.PublicKey.ToBase58())
assTokAdrr, _, _ := common.FindAssociatedTokenAddress(**feePayer1**, mint.PublicKey)
fmt.Println("assTokAdrr", assTokAdrr.ToBase58())
collection := types.NewAccount()
fmt.Println(base58.Encode(collection.PrivateKey))
fmt.Printf("collection: %v\n", collection.PublicKey.ToBase58())
ata, _, err := common.FindAssociatedTokenAddress(feePayer1, mint.PublicKey)
if err != nil {
log.Fatalf("failed to find a valid ata, err: %v", err)
}
fmt.Println("ata", ata)
tokenMetadataPubkey, err := tokenmeta.GetTokenMetaPubkey(mint.PublicKey)
fmt.Println("tokenMetadataPubkey", tokenMetadataPubkey.ToBase58())
if err != nil {
log.Fatalf("failed to find a valid token metadata, err: %v", err)
}
tokenMasterEditionPubkey, err := tokenmeta.GetMasterEdition(mint.PublicKey)
fmt.Println("tokenMasterEditionPubkey", tokenMasterEditionPubkey.ToBase58())
if err != nil {
log.Fatalf("failed to find a valid master edition, err: %v", err)
}
mintAccountRent, err := c.GetMinimumBalanceForRentExemption(context.Background(), tokenprog.MintAccountSize)
if err != nil {
log.Fatalf("failed to get mint account rent, err: %v", err)
}
recentBlockhashResponse, err := c.GetRecentBlockhash(context.Background())
if err != nil {
log.Fatalf("failed to get recent blockhash, err: %v", err)
}
fmt.Println("Signers--------------------->", []types.Account{mint})
tx, err := types.NewTransaction(types.NewTransactionParam{
//Signers: []types.Account{mint, feePayer1},
Message: types.NewMessage(types.NewMessageParam{
FeePayer: feePayer1,
RecentBlockhash: recentBlockhashResponse.Blockhash,
Instructions: []types.Instruction{
sysprog.CreateAccount(sysprog.CreateAccountParam{
From: feePayer1,
New: mint.PublicKey,
Owner: common.TokenProgramID,
Lamports: mintAccountRent,
Space: tokenprog.MintAccountSize,
}),
tokenprog.InitializeMint(tokenprog.InitializeMintParam{
Decimals: 0,
Mint: mint.PublicKey,
MintAuth: feePayer1,
}),
tokenmeta.CreateMetadataAccountV2(tokenmeta.CreateMetadataAccountV2Param{
Metadata: tokenMetadataPubkey,
Mint: mint.PublicKey,
MintAuthority: feePayer1,
Payer: feePayer1,
UpdateAuthority: feePayer1,
UpdateAuthorityIsSigner: true,
IsMutable: true,
Data: tokenmeta.DataV2{
Name: "test",
Symbol: "tset",
Uri: "https://ipfs.infura.io/ipfs/QmVyceJtRJVY8E8kCmXUPK3vs2XdwzTtrtWrGpwjWVWhMX",
SellerFeeBasisPoints: 100,
Creators: &[]tokenmeta.Creator{
{
Address: feePayer1,
Verified: true,
Share: 100,
},
},
Collection: &tokenmeta.Collection{
Verified: false,
Key: collection.PublicKey,
},
Uses: &tokenmeta.Uses{
UseMethod: tokenmeta.Burn,
Remaining: 10,
Total: 10,
},
},
}),
assotokenprog.CreateAssociatedTokenAccount(assotokenprog.CreateAssociatedTokenAccountParam{
Funder: feePayer1,
Owner: feePayer1,
Mint: mint.PublicKey,
AssociatedTokenAccount: ata,
}),
tokenprog.MintTo(tokenprog.MintToParam{
Mint: mint.PublicKey,
To: ata,
Auth: feePayer1,
Amount: 1,
}),
tokenmeta.CreateMasterEditionV3(tokenmeta.CreateMasterEditionParam{
Edition: tokenMasterEditionPubkey,
Mint: mint.PublicKey,
UpdateAuthority: feePayer1,
MintAuthority: feePayer1,
Metadata: tokenMetadataPubkey,
Payer: feePayer1,
MaxSupply: pointer.Uint64(0),
}),
},
}),
})
if err != nil {
log.Fatalf("failed to new a tx, err: %v", err)
}
sig, err := c.SendTransaction(context.Background(), tx)
if err != nil {
log.Fatalf("failed to send tx, err: %v", err)
}
fmt.Println(sig)
}
Can you please help with the above query
any suggestion on the above issue?
I think the steps are more like
so it seems private key is mandatory to sign a transaction?
depends on which account you're using. if you are using a PDA, the account's signature doesn't be generated by a private key.
feel free to open another issue to ask something about this sdk.
https://github.com/portto/solana-go-sdk/blob/3379219af14a083038c96118c7d1d7daa7e21232/docs/_examples/nft/mint-a-nft-with-master-edition-v2/main.go#L21
Sir, I'm actually thinking of moving to production with mainnet config. But if I do so when the buyer(aka feePayer) has to mint then he has to provide is private key as per the code.. But no buyer will wish to provide/expose the private key .
My question is how can I mint an NFT without taking/using the private key of feePayer.
But usage of public key is fine