Open mkocurek opened 2 years ago
I believe it's not yet fully integrated, but haven't tested it https://github.com/tighten/solana-php-sdk#transactions
Anymore info on this would be highly appreciated ❤️
Seems like it's being worked on https://github.com/tighten/solana-php-sdk/pull/28
@suchpro Were you able to figure this out
I can transfer tokens now, but the amount sent is not encoded properly I believe to the right decimal so it sends a wrong value
@impozzible haven't tested it yet
Figured it out, incase someone else runs into this issue
public function createTransferInstruction(
PublicKey $source,
PublicKey $destination,
PublicKey $owner,
int $amount
): TransactionInstruction {
$data = [
// uint32
...unpack("C*", pack("C", 3)),
// int64
...unpack("C*", pack("P", $amount)),
];
// dd($data);
$keys = [
new AccountMeta($source, false, true),
new AccountMeta($destination, false, true),
new AccountMeta($owner,true,true),
];
return new TransactionInstruction(
new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
$keys,
$data
);
}```
'Transfer' instruction is deprecated for now and token developers recommend to use 'TransferChecked' instruction, sample code:
public function createTransferCheckedInstruction(
string $source,
string $destination,
string $owner,
string $mint,
int $amount,
int $decimals
): TransactionInstruction
{
/**
* TokenInstructions :
* Transfer = 3,
* TransferChecked = 12,
*/
$data = [
// u8
...unpack("C*", pack("C", 12)), // token instruction index
// u64
...unpack("C*", pack("P", $amount)), // amount without decimals
// u8
...unpack("C*", pack("C", $decimals)), // token decimals
];
$keys = [
new AccountMeta(new PublicKey($source), false, true), // source account address
new AccountMeta(new PublicKey($mint), false, false), // mint token address
new AccountMeta(new PublicKey($destination), false, true), // destination account address, if not exist need call
new AccountMeta(new PublicKey($owner), true, true), // singer address, wallet who will be sing tx
];
return new TransactionInstruction(
new PublicKey(SplTokenProgram::SOLANA_TOKEN_PROGRAM_ID),
$keys,
$data
);
}
In case when you doesn't have token Account address you must to create it, for this action get associated token address with following function
public static function getAssociatedTokenAccount(string $mint, string $publicKeyAddress): PublicKey
{
$publicKeyAccount = new PublicKey($publicKeyAddress);
$publicKeyMint = new PublicKey($mint);
$programId = new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
$seed = [
$publicKeyAccount->toBuffer(),
$programId->toBuffer(),
$publicKeyMint->toBuffer()
];
return \Arr::first(PublicKey::findProgramAddress($seed, new PublicKey("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"))); // ATTENTION : It's function not working correctly in latest version of package, now latest is "^0.3.2", for solve it change package version to "dev-main
}
Then add instruction for create token address into your transaction, but if account already created not add this instruction to transaction object
public static function createAssociatedTokenAccountInstruction(
string $payer, // tx payer address. it address wallet whose using for sining transaction
string $associatedToken, // generated token address, for get call function "getAssociatedTokenAccount"
string $owner, // wallet address for which you want to create associated token wallet
string $mint, // Token mint address
string $programId = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
string $associatedTokenProgramId = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
): TransactionInstruction
{
$data = [];
$keys = [
new AccountMeta(new PublicKey($payer), true, true),
new AccountMeta(new PublicKey($associatedToken), false, true),
new AccountMeta(new PublicKey($owner), false, false),
new AccountMeta(new PublicKey($mint), false, false),
new AccountMeta(new PublicKey("11111111111111111111111111111111"), false, false),
new AccountMeta(new PublicKey($programId), false, false),
new AccountMeta(new PublicKey("SysvarRent111111111111111111111111111111111"), false, false),
];
return new TransactionInstruction(
new PublicKey($associatedTokenProgramId),
$keys,
$data
);
}
Does anyone have an example of full code on this working? I keep getting a
Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction
error
Figured it out, incase someone else runs into this issue
public function createTransferInstruction( PublicKey $source, PublicKey $destination, PublicKey $owner, int $amount ): TransactionInstruction { $data = [ // uint32 ...unpack("C*", pack("C", 3)), // int64 ...unpack("C*", pack("P", $amount)), ]; // dd($data); $keys = [ new AccountMeta($source, false, true), new AccountMeta($destination, false, true), new AccountMeta($owner,true,true), ]; return new TransactionInstruction( new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"), $keys, $data ); }```
Can you post your full code for sending a token please?
not an issue but a question or a feature request
is it possible to transfer tokens using this SDK like with the Solana CLI using a terminal?
Terminal Example: $spl-token transfer --allow-unfunded-recipient --fund-recipient [token address] [amount of tokens] [recipients wallet]