{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-products/wallet/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["admonition"]},"type":"markdown"},"seo":{"title":"Raw signing","description":"User guides, API reference, and support resources.","siteUrl":"https://docs.ripple.com/products/custody","lang":"en-US","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"raw-signing","__idx":0},"children":["Raw signing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Raw signing with Wallet-as-a-Service (Palisade) offers the ability to sign any transaction type available to a blockchain. It can be used on any transaction type if enabled."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is an important feature of the Wallet-as-a-Service (Palisade) platform as it means customers can benefit from all natively supported transaction types of a blockchain as soon as they become available, regardless of whether that blockchain or transaction type is currently supported by Wallet-as-a-Service (Palisade)."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Raw signing can be enabled and disabled for a wallet from wallet settings."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Disabled by default"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Raw signing is a powerful and insecure signing method. It is therefore disabled by default. Please only enable raw signing for individual wallets if you fully understand this feature."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"API documentation"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["See our ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/products/wallet/api-docs/palisade-api/palisade-api"},"children":["Wallet-as-a-Service (Palisade) API reference"]}," for information on how to submit raw transactions via the API."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"transaction-encoding-formats","__idx":1},"children":["Transaction Encoding Formats"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When using the Raw Transaction API, the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodedTransaction"]}," field must be encoded in a blockchain-specific format. This section details the exact encoding requirements for each supported blockchain."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"evm-chains-ethereum-base-polygon-avalanche-arbitrum-bnb-chain","__idx":2},"children":["EVM Chains (Ethereum, Base, Polygon, Avalanche, Arbitrum, BNB Chain)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodedTransaction"]}," field must match the output of go-ethereum's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["rlp.EncodeToBytes(types.Transaction)"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Format:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"RLP(type_byte || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gas, to, value, data, accessList, v, r, s]))\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key requirements:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Include v, r, s signature fields"]}," — Set to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}," for unsigned transactions"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Apply outer RLP wrapper"]}," — The typed transaction must be wrapped as an RLP byte string"]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Common error"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you receive ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"typed transaction too short\""]},", you're likely using the standard unsigned format (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0x02 || RLP([9 fields])"]},") which is missing the v/r/s placeholders and outer RLP wrapper."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"from eth_account.typed_transactions import DynamicFeeTransaction\nimport rlp\n\n# Use the signed transaction serializer (includes v, r, s fields)\nserializer = DynamicFeeTransaction._signed_transaction_serializer\n\ntx = serializer(\n    chainId=84532,  # Base Sepolia\n    nonce=nonce,\n    maxPriorityFeePerGas=max_priority,\n    maxFeePerGas=max_fee,\n    gas=gas_limit,\n    to=bytes.fromhex(to_address[2:]),\n    value=0,\n    data=calldata_bytes,\n    accessList=(),\n    v=0,  # Placeholder for unsigned\n    r=0,  # Placeholder for unsigned\n    s=0,  # Placeholder for unsigned\n)\n\n# RLP encode the fields\ntx_rlp = rlp.encode(tx)\n\n# Add EIP-1559 type prefix (0x02)\ntyped_tx = bytes([2]) + tx_rlp\n\n# Wrap in RLP string (matches go-ethereum's rlp.EncodeToBytes)\nencoded_transaction = rlp.encode(typed_tx).hex()\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Go example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import (\n    \"github.com/ethereum/go-ethereum/core/types\"\n    \"github.com/ethereum/go-ethereum/rlp\"\n)\n\ntx := types.NewTx(&types.DynamicFeeTx{\n    ChainID:   big.NewInt(84532),\n    Nonce:     nonce,\n    GasTipCap: maxPriorityFeePerGas,\n    GasFeeCap: maxFeePerGas,\n    Gas:       gasLimit,\n    To:        &toAddress,\n    Value:     big.NewInt(0),\n    Data:      calldata,\n})\n\nencodedBytes, _ := rlp.EncodeToBytes(tx)\nencodedTransaction := hex.EncodeToString(encodedBytes)\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"xrp-ledger","__idx":3},"children":["XRP Ledger"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodedTransaction"]}," field must use the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["XRP Binary Codec"]}," format with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodeForSigning"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Format:"]}," Hex-encoded binary codec output of the transaction JSON"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key requirements:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SigningPubKey"]}," field with the wallet's public key"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodeForSigning"]}," (not ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encode"]},") for unsigned transactions"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JavaScript example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const { encodeForSigning } = require('ripple-binary-codec');\n\nconst tx = {\n    Account: \"rSourceAddress...\",\n    Destination: \"rDestAddress...\",\n    Amount: \"1000000\",  // In drops\n    Fee: \"10\",\n    Sequence: 12345,\n    SigningPubKey: \"02ECE63017B0FEFC...\",  // Required\n    TransactionType: \"Payment\"\n};\n\nconst encodedTransaction = encodeForSigning(tx);\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"from xrpl.core.binarycodec import encode_for_signing\n\ntx = {\n    \"Account\": \"rSourceAddress...\",\n    \"Destination\": \"rDestAddress...\",\n    \"Amount\": \"1000000\",\n    \"Fee\": \"10\",\n    \"Sequence\": 12345,\n    \"SigningPubKey\": \"02ECE63017B0FEFC...\",\n    \"TransactionType\": \"Payment\"\n}\n\nencoded_transaction = encode_for_signing(tx)\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"solana","__idx":4},"children":["Solana"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodedTransaction"]}," field must be a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["base64-encoded"]}," serialized Solana transaction."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Format:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["base64(transaction.MarshalBinary())"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key requirements:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Transaction must include a valid recent blockhash"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Account keys must be properly ordered (fee payer first)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use standard base64 encoding (not base58)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"from solders.transaction import Transaction\nfrom solders.message import Message\nimport base64\n\n# Build your transaction message\nmessage = Message.new_with_blockhash(\n    instructions,\n    payer,\n    blockhash\n)\n\n# Create unsigned transaction\ntx = Transaction.new_unsigned(message)\n\n# Serialize and base64 encode\ntx_bytes = bytes(tx)\nencoded_transaction = base64.b64encode(tx_bytes).decode('utf-8')\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JavaScript example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const { Transaction } = require('@solana/web3.js');\n\nconst tx = new Transaction();\ntx.recentBlockhash = blockhash;\ntx.feePayer = payerPublicKey;\ntx.add(instruction);\n\n// Serialize (without signing)\nconst serialized = tx.serialize({ requireAllSignatures: false });\nconst encodedTransaction = serialized.toString('base64');\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"tron","__idx":5},"children":["TRON"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["encodedTransaction"]}," field must be a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["hex-encoded"]}," TRON Transaction protobuf."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Format:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hex(proto.Marshal(Transaction))"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Key requirements:"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Transaction must include valid ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ref_block_bytes"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ref_block_hash"]}," from a recent block"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Expiration timestamp must be in the future (typically current time + 60 seconds, in milliseconds)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Fee limit must be set for TRC-20 transfers (recommended: 15,000,000 SUN = 15 TRX)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The signing hash is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SHA256(raw_data)"]}," — Wallet-as-a-Service (Palisade) computes this automatically"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Supported contract types:"]}]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Contract Type"},"children":["Contract Type"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TransferContract"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Native TRX transfers"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TriggerSmartContract"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["TRC-20 token transfers and smart contract calls"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python example (using tronpy):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"python","header":{"controls":{"copy":{}}},"source":"from tronpy import Tron\n\nclient = Tron(network='shasta')  # or 'mainnet'\n\n# Build a TRX transfer transaction\ntxn = (\n    client.trx.transfer(\n        from_=\"TSourceAddress...\",\n        to=\"TDestAddress...\",\n        amount=1_000_000  # 1 TRX in SUN\n    )\n    .fee_limit(1_000_000)  # 1 TRX fee limit\n    .build()\n)\n\n# Get the raw transaction bytes (protobuf serialized)\nraw_bytes = txn._raw_data.SerializeToString()\n\n# Hex encode for Wallet-as-a-Service (Palisade)\nencoded_transaction = raw_bytes.hex()\n\n# For TRC-20 transfers, use trigger_smart_contract instead\n","lang":"python"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JavaScript example (using TronWeb):"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"javascript","header":{"controls":{"copy":{}}},"source":"const TronWeb = require('tronweb');\n\nconst tronWeb = new TronWeb({\n    fullHost: 'https://api.shasta.trongrid.io',  // or mainnet\n});\n\n// Build a TRX transfer transaction\nconst tx = await tronWeb.transactionBuilder.sendTrx(\n    'TDestAddress...',      // to\n    1000000,                // amount in SUN (1 TRX)\n    'TSourceAddress...'     // from\n);\n\n// The transaction object contains raw_data_hex\nconst encodedTransaction = tx.raw_data_hex;\n","lang":"javascript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Go example:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import (\n    \"encoding/hex\"\n    \"time\"\n    \n    \"github.com/fbsobreira/gotron-sdk/pkg/proto/core\"\n    \"google.golang.org/protobuf/proto\"\n    \"google.golang.org/protobuf/types/known/anypb\"\n)\n\n// Build a TRX transfer\ntransfer := &core.TransferContract{\n    OwnerAddress: ownerAddrBytes,  // 21-byte TRON address\n    ToAddress:    toAddrBytes,\n    Amount:       1000000,         // 1 TRX in SUN\n}\n\nanyValue, _ := anypb.New(transfer)\n\ntx := &core.Transaction{\n    RawData: &core.TransactionRaw{\n        Contract: []*core.Transaction_Contract{{\n            Type:      core.Transaction_Contract_TransferContract,\n            Parameter: anyValue,\n        }},\n        RefBlockBytes: refBlockBytes,  // From recent block\n        RefBlockHash:  refBlockHash,\n        Expiration:    time.Now().Add(60*time.Second).UnixMilli(),\n        Timestamp:     time.Now().UnixMilli(),\n    },\n}\n\ntxBytes, _ := proto.Marshal(tx)\nencodedTransaction := hex.EncodeToString(txBytes)\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"TRON address format"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["TRON addresses can be in base58 format (starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["T"]},") or hex format (starts with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["41"]},"). The API accepts base58 addresses, but internally they are converted to 21-byte hex addresses in the protobuf."]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"warning","name":"Reference block requirements"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["TRON transactions require ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ref_block_bytes"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ref_block_hash"]}," from a recent block (within ~18 hours). If you're building transactions manually, fetch the latest block and extract bytes 6-8 of the block number and bytes 8-16 of the block hash."]}]}]},"headings":[{"value":"Raw signing","id":"raw-signing","depth":1},{"value":"Transaction Encoding Formats","id":"transaction-encoding-formats","depth":2},{"value":"EVM Chains (Ethereum, Base, Polygon, Avalanche, Arbitrum, BNB Chain)","id":"evm-chains-ethereum-base-polygon-avalanche-arbitrum-bnb-chain","depth":3},{"value":"XRP Ledger","id":"xrp-ledger","depth":3},{"value":"Solana","id":"solana","depth":3},{"value":"TRON","id":"tron","depth":3}],"frontmatter":{"title":"Raw signing","seo":{"title":"Raw signing"}},"lastModified":"2026-02-12T10:38:18.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/products/wallet/user-interface/transactions/raw-signing","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}