Transfer some SOL to fee payer and setup token for payment

Our fee payer on devnet works as long as it has SOL on HrqCCATHJsqaFCfQVjvhWXEpop81jcWZn5i4jSZYjS9g. Please top it up if you are extensively using Hosted Octane on Devnet.
const airdropSignature = await connection.requestAirdrop(
new PublicKey('HrqCCATHJsqaFCfQVjvhWXEpop81jcWZn5i4jSZYjS9g'), LAMPORTS_PER_SOL
await connection.confirmTransaction(airdropSignature);
Normally, only specific liquid tokens can be used to pay for the transaction. However, to make experimenting with Octane easier, we've made devnet endpoints to accept any token as fee payment.
So, you should create a new token to use it for the fees:
const tokenKeypair = Keypair.generate();
const airdropSignature = await connection.requestAirdrop(
tokenKeypair.publicKey, LAMPORTS_PER_SOL,
await connection.confirmTransaction(airdropSignature);
const mint = await createMint(connection, tokenKeypair, tokenKeypair.publicKey, null, 9, undefined, {commitment: 'confirmed'});
Now, we should create an account that Octane will use to receive payments. Again, normally, this account will be already created by node owner, but this approach simplifies testing on devnet.
const tokenAccount = await getOrCreateAssociatedTokenAccount(
{commitment: 'confirmed'}

Prepare transaction

First, let's create a hypothetical end user: someone, who doesn't have any SOL, but has some tokens. In our story, the user wants to transfer some tokens to a friend.
endUserKeypair = Keypair.generate();
endUserTokenAccount = await createAccount(connection, tokenKeypair, mint, endUserKeypair.publicKey, undefined, {commitment: 'confirmed'});
await mintTo(connection, tokenKeypair, mint, endUserTokenAccount, tokenKeypair.publicKey, 1e9, undefined, {commitment: 'confirmed'});
Now, let's create friend's keypair and token account.
const targetKeypair = Keypair.generate();
const targetAccount = await createAccount(connection, tokenKeypair, mint, targetKeypair.publicKey, undefined, {commitment: 'confirmed'}); // for now, we assume it's already created
We also will need Octane node configuration to know how many tokens we should transfer to pay for their transaction and which account will be the fee payer (it should specified in every transaction):
const response = (await axios.get('', {
headers: {'Accept': 'application/json'}
const feePayer = new PublicKey(response.feePayer);
const simpleTransactionFee = response.endpoints.transfer.tokens[0].fee;
We are almost good to go! The last thing we need is the actual transaction with two instructions:
  • First instruction sends token fee to Octane's account
  • Second instruction ("arbitrary" or "payload") executes the token transfer to the friend
We also should set feePayer and recentBlockhash, and then sign the transaction using the end user wallet.
const transaction = new Transaction();
transaction.add(createTransferInstruction(endUserTokenAccount, tokenAccount.address, endUserKeypair.publicKey, simpleTransactionFee));
transaction.add(createTransferInstruction(endUserTokenAccount, targetAccount, endUserKeypair.publicKey, 100));
transaction.feePayer = feePayer;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
transaction.partialSign(endUserKeypair); // in client code, you should use wallet adapter instead

Get signature from Octane instance

Now, we have the transaction with end user's signature. However, the transaction lacks signature of fee payer.
You need to call an HTTP endpoint to get this signature and attach it to the transaction:
const octaneResponse = (await'', {
transaction: base58.encode(transaction.serialize({requireAllSignatures: false})),
overrideAccount: tokenAccount.address.toBase58(),
overrideMint: mint.toBase58()
transaction.addSignature(feePayer, base58.decode(octaneResponse.signature));
Since it's a devnet endpoint, we are overriding account and mint parameters from the config.

Submit transaction to network

It's ready! You can send the transaction to the network now:
await sendAndConfirmRawTransaction(
connection, transaction.serialize(), { commitment: 'confirmed' }
console.log('Find on devnet explorer ///', octaneResponse.signature);
Last modified 6mo ago