Sign and transfer using managed address

2 credits per API call, additional credits are charged for each gas covered operation.


Sign transaction and transfer assets from a custodial managed address.
Supported chains:

  • Solana

Logic for Solana
In Solana, it's possible to cover the fees connected to any arbitrary transaction by a third party. Tatum can cover these fees for any transaction on the Solana blockchain - transfer of SOL, SPL tokens, minting or transferring NFTs or invoking programs. In order to do this, Tatum fee address must be used as a feePayer address during transaction creation:
Mainnet addressDevnet address
AddressDSpHmb7hLnetoybammcJBJiyqMVR3pDhCuW6hqVg9eBFDSpHmb7hLnetoybammcJBJiyqMVR3pDhCuW6hqVg9eBF
Once transaction is constructed using Solana SDK, it can be serialized to HEX data string, which is then passed to the API and signed.
Transaction could require multiple private keys for signing - fee payer, sender of the SOL assets, minting key during NFT mint operation etc. Some of the keys are used in Tatum - fee payer, or, in case of managed wallet holding SOL assets, the key of that managed wallet - those must be referenced in a list of walletIds to be used. For external keys, which are not managed by Tatum, those could either sign the transaction before it's serialization, or could be passed to the API in it's raw form - this is OK only for keys, which could be exposed and there is no harm of loosing assets on them.
How to partially sign the transaction could be found here.
Fee payer key is used by default, doesn't have to be mentioned in the list of wallets used for signing.

Examples of different transaction payloads.

1. Send SOL from account HrJtQTy2RW9c6y41RvN8x3bEiD6Co74AuhER2MGCpa58 to FZAS4mtPvswgVxbpc117SqfNgCDLTCtk5CoeAtt58FWU
import { LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, Connection } from '@solana/web3.js'

const connection = new Connection('https://api.tatum.io/v3/blockchain/node/SOL')
const from = 'HrJtQTy2RW9c6y41RvN8x3bEiD6Co74AuhER2MGCpa58'
const to = 'FZAS4mtPvswgVxbpc117SqfNgCDLTCtk5CoeAtt58FWU'
const amount = '0.000001'
const devnet_fee_payer = '5zPr5331CtBjgVeLedhmJPEpFaUsorLCnb3aCQPsUc9w'
const fromPubkey = new PublicKey(from)
const transaction = new Transaction({ feePayer: new PublicKey(devnet_fee_payer) })
transaction.add(
SystemProgram.transfer({
fromPubkey: fromPubkey,
toPubkey: new PublicKey(to),
lamports: new BigNumber(amount).multipliedBy(LAMPORTS_PER_SOL).toNumber(),
}),
)
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('finalized')
transaction.recentBlockhash = blockhash
transaction.lastValidBlockHeight = lastValidBlockHeight
transaction.partialSign(...signers)
return transaction.serialize({ requireAllSignatures: false }).toString('hex')

For the above example, developer have 2 options how to sign transaction - if the sender address HrJtQTy2RW9c6y41RvN8x3bEiD6Co74AuhER2MGCpa58 is managed using a Tatum managed wallet with id 0b1eae3d-2520-4903-8bbf-5dec3ad2a5d4, the final payload to the custodial/transaction endpoint should look like this:
{
  "chain": "SOL",
  "txData": "020001044a22af97a838a504e6f7c0b18d779afcea612da50794cc1dac641861fc1ab14afa5cacaf91c298694e64bb5496916c3c68a32affb92d4bcd2736fbb00169d57bd840de2a454960308f688cd3ee308c1fa01ecfa0b03770aaaf3b52d71d46c31d000000000000000000000000000000000000000000000000000000000000000060d38e0da20dc5900b7e902c918eae6a95e2d90af154b53a422f4ab26b050f4f01030201020c02000000e803000000000000",
  "walletIds": [
    {
      "key": "0b1eae3d-2520-4903-8bbf-5dec3ad2a5d4",
      "type": "MANAGED"
    }
  ]
}
If the sender address is not managed, the transaction could be signed with the private key of that address before the serialization and the payload will look like this:
{
  "chain": "SOL",
  "txData": "020001044a22af97a838a504e6f7c0b18d779afcea612da50794cc1dac641861fc1ab14afa5cacaf91c298694e64bb5496916c3c68a32affb92d4bcd2736fbb00169d57bd840de2a454960308f688cd3ee308c1fa01ecfa0b03770aaaf3b52d71d46c31d000000000000000000000000000000000000000000000000000000000000000060d38e0da20dc5900b7e902c918eae6a95e2d90af154b53a422f4ab26b050f4f01030201020c02000000e803000000000000",
  "walletIds": []
}

Language
Authorization
Header
Click Try It! to start a request and see the response here!