У меня есть этот код, который передает токен с помощью spl-token 0.2.x.
Как заставить тот же код работать в 0.1.8? Насколько я понимаю документы, между ними не было серьезных изменений, но в более старой версии используется класс Token, но я не уверен, как его вызывать для функций getOrCreateAssociatedTokenAccount
и transfer
.
async function transferToken(endpoint: string, fromWallet: Keypair, address_to: string, token_id: string)
{
const connection = new Connection(endpoint);
const toWalletPublicKey = new PublicKey(address_to);
const mint_key = new PublicKey(token_id);
// From
const from = [connection, fromWallet, mint_key, fromWallet.publicKey];
const fromTokenAccount = await getOrCreateAssociatedTokenAccount(...from);
// To
const to = [connection, fromWallet, mint_key, toWalletPublicKey];
const toTokenAccount = await getOrCreateAssociatedTokenAccount(...to);
// Transfer
const transferParams = [connection, fromWallet, fromTokenAccount.address, toTokenAccount.address, fromWallet.publicKey, 1, []];
return await transfer(...transferParams);
}
Вот как я передаю fromWallet
KeyPair
, загруженный из шестнадцатеричной строки.
const fromWallet = Keypair.fromSecretKey(Uint8Array.from(Buffer.from(private_key, 'hex')));
На самом деле в версии 2 есть изменения (отсюда и главный удар версии), в данном случае это удаление класса Token
в пользу тех функций, которые вы видите в примере.
Документы довольно ... плохие, но если вы посмотрите проект Github год назад, то вы увидите, как функция была перенесена понемногу.
getOrCreateAssociatedTokenAccount
и transfer
требуют использовать токен класса следующим образом:
const token = new Token(connection, toWalletPublicKey, mint_key, fromWallet.publicKey) // Not sure about the last argument as it is the Signer
/**
* Retrieve the associated account or create one if not found.
*
* This account may then be used as a `transfer()` or `approve()` destination
*
* @param owner User account that will own the new account
* @return The new associated account
*/
const fromTokenAccount = token.getOrCreateAssociatedAccountInfo(fromWallet.publicKey)
const toTokenAccount = token.getOrCreateAssociatedAccountInfo(toWalletPublicKey)
/**
* Transfer parameters
* @param source Source account
* @param destination Destination account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Number of tokens to transfer
*/
token.transfer(fromTokenAccount, toTokenAccount, fromWallet, [], 1)
Также на это частично ответили в здесь
Keypair.fromSecretKey(Uint8Array.from(Buffer.from(private_key, 'hex')))
поскольку у вас есть только одна подписывающая сторона, вы можете оставить подписывающую сторону в покое при передаче, она должна исходить от fromTokenAccount
, поскольку для инициализации токена подписывающая сторона — это просто KeyPar, на который вы указываете. Вы получаете какую-то конкретную ошибку?
.../node_modules/@solana/web3.js/src/transaction.ts:611 const key = signer.publicKey.toString(); ^ TypeError: Cannot read properties of undefined (reading 'toString')
вы отлаживаете, что подписывающая сторона, которую вы передаете, содержит как закрытый, так и открытый ключ?
Да, подписывающая сторона содержит как закрытый, так и открытый ключ, когда я выхожу из нее. Если я передаю fromWallet
вместо fromWallet.publicKey
, я получаю эту ошибку. `выбросить новую ошибку('Небазовый' + БАЗОВЫЙ + 'символ') ^ Ошибка: небазовый символ 58`
Я также добавил, как я создаю KeyPair из сохраненной шестнадцатеричной строки закрытого ключа. Мой пример кода 0.2.0 работает с этими значениями.
Кроме того, если я добавляю await
к token.getOrCreateAssociatedAccountInfo(fromWallet.publicKey)
, это дает мне эту ошибку. Error: Failed to find account
Хорошо! Я думаю, что я неправильно создаю подписывающую сторону. Как это сделать с закрытым ключом? Вот как я создаю KeyPair (fromWallet) из сохраненного закрытого ключа.