{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["amendment-disclaimer","tabs","tab","code-snippet"]},"redocly_category":"Documentation","type":"markdown"},"seo":{"title":"Sponsor a Transaction by Co-Signing","siteUrl":"https://xrpl.org/","llmstxt":{"hide":false,"title":"XRPL Developer Portal & Documentation","description":"Explore XRP Ledger documentation, blogs, and other blockchain developer resources needed to start building and integrating with the ledger.","details":{"content":"XRP Ledger concepts, use cases, tutorials, references, and other blockchain developer resources. Also, stay up to date with release announcements and more through the XRPL Blog."},"sections":[{"title":"Introduction","description":"A high-level introduction to the XRP Ledger.","includeFiles":["docs/introduction/**/*.*","about/faq.md"],"excludeFiles":["docs/introduction/index.md"]},{"title":"Use Cases","description":"Real-world applications and business scenarios for the XRP Ledger.","includeFiles":["docs/use-cases/**/*.*"],"excludeFiles":["docs/use-cases/index.md","docs/use-cases/defi/index.md"]},{"title":"Agentic Transactions","description":"XRPL AI Starter Kit to help autonomous agents discover, set up, and execute agentic transactions on the XRP Ledger.","includeFiles":["docs/agents/**/*.*"],"excludeFiles":[]},{"title":"Concepts","description":"Core concepts including accounts, tokens, transactions, consensus, and more.","includeFiles":["docs/concepts/**/*.*"],"excludeFiles":["docs/concepts/index.md","docs/concepts/decentralized-storage/index.md","docs/concepts/payment-types/index.md"]},{"title":"Tutorials","description":"Step-by-step guides for building on the XRP Ledger in JavaScript, Python, Go, and more.","includeFiles":["docs/tutorials/**/*.*"],"excludeFiles":[]},{"title":"References","description":"Protocol specification, transaction types, ledger entries, and API methods.","includeFiles":["docs/references/**/*.*"],"excludeFiles":["docs/references/xrp-api.md","docs/references/data-api.md","docs/references/protocol/index.md","docs/references/protocol/ledger-data/ledger-entry-types/index.md","docs/references/protocol/transactions/index.md","docs/references/protocol/transactions/types/index.md","docs/references/http-websocket-apis/api-conventions/index.md","docs/references/http-websocket-apis/public-api-methods/*/index.md","docs/references/http-websocket-apis/admin-api-methods/*/index.md"]},{"title":"Infrastructure","description":"Install, configure, and troubleshoot xrpld and Clio servers.","includeFiles":["docs/infrastructure/**/*.*"],"excludeFiles":["docs/infrastructure/index.md","docs/infrastructure/*/index.md","docs/infrastructure/installation/build-run-xrpld-in-reporting-mode.md","docs/infrastructure/configuration/data-retention/index.md","docs/infrastructure/configuration/server-modes/index.md"]},{"title":"Blog (2023+)","description":"Recent XRPL Blog posts (showing 2023 and newer).","includeFiles":["blog/2023/**/*.*","blog/2024/**/*.*","blog/2025/**/*.*","blog/2026/**/*.*"],"excludeFiles":[]},{"title":"Resources","description":"Developer resources and contribution guidelines.","includeFiles":["resources/**/*.*"],"excludeFiles":["resources/index.md"]}],"excludeFiles":[]},"description":"Cover another account's transaction fee and reserve requirement by co-signing a single transaction."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"sponsor-a-transaction-by-co-signing","__idx":0},"children":["Sponsor a Transaction by Co-Signing"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial shows you how to use the co-signed ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/accounts/sponsored-fees-and-reserves#how-sponsorship-works"},"children":["sponsorship"]}," flow, where the sponsor approves a single transaction by adding a signature to it. In this example, a sponsor creates an account for a new user who holds no XRP, then covers the fee and the owner reserve for a transaction that user sends."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this flow when the sponsor needs to review each sponsored transaction before it is submitted. If the sponsee needs to be able to transact without waiting on the sponsor, use a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/best-practices/account-management/sponsor-a-transaction-with-a-pre-funded-pool"},"children":["pre-funded pool"]}," instead."]},{"$$mdtype":"Tag","name":"AmendmentDisclaimer","attributes":{"name":"Sponsor","compact":false,"statusOnly":false,"mode":""},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"goals","__idx":1},"children":["Goals"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By the end of this tutorial, you should be able to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create an account for a sponsee and pay its account reserve as the sponsor."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Co-sign a transaction so the sponsor pays the fee and the new ledger entry's reserve."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Confirm that the sponsor paid the fee and reserve."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":2},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To complete this tutorial, you should:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Have a basic understanding of the XRP Ledger and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/accounts/sponsored-fees-and-reserves"},"children":["Sponsored Fees and Reserves"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Have an XRP Ledger client library set up in your development environment. This page provides examples for the following:",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["JavaScript"]}," with the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://github.com/XRPLF/xrpl.js"},"children":["xrpl.js library"]},". See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/get-started/get-started-javascript"},"children":["Get Started Using JavaScript"]}," for setup steps."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Python"]}," with the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://github.com/XRPLF/xrpl-py"},"children":["xrpl-py library"]},". See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/get-started/get-started-python"},"children":["Get Started Using Python"]}," for setup steps."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"source-code","__idx":3},"children":["Source Code"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can find the complete source code for this tutorial's example in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/sponsored-fees-and-reserves"},"children":["code samples section of this website's repository"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"steps","__idx":4},"children":["Steps"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-install-dependencies","__idx":5},"children":["1. Install dependencies"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From the code sample folder, use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["npm"]}," to install dependencies:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"npm install\n","lang":"bash"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["From the code sample folder, set up a virtual environment and use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["pip"]}," to install dependencies:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"python3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n","lang":"bash"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-set-up-the-client","__idx":6},"children":["2. Set up the client"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Import the necessary libraries and instantiate a client to connect to the XRPL. This example imports:"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["xrpl"]},": Used for XRPL client connection, transaction submission, and wallet handling."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"import {\n  Client,\n  PaymentFlags,\n  SponsorFlags,\n  Wallet,\n  signAsSponsor,\n  validate\n} from 'xrpl'\n\n// Connect to the network ----------------------\nconst client = new Client('wss://s.devnet.rippletest.net:51233')\nawait client.connect()"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["xrpl"]},": Used for XRPL client connection, transaction submission, and wallet handling."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json"]},": Used for formatting JSON data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sys"]},": Used to exit on transaction failures."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"import json\nimport sys\n\nfrom xrpl.clients import JsonRpcClient\nfrom xrpl.models import DepositPreauth, Payment, PaymentFlag, SponsorFlag\nfrom xrpl.transaction import autofill, sign, sign_as_sponsor, submit_and_wait\nfrom xrpl.wallet import Wallet, generate_faucet_wallet\n\n# Set up client ----------------------\nclient = JsonRpcClient(\"https://s.devnet.rippletest.net:51234\")"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-create-the-wallets","__idx":7},"children":["3. Create the wallets"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Fund the sponsor and generate a key pair for the sponsee. The sponsee has no account on the ledger yet, and no XRP to pay for one."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Create the sponsor and sponsee wallets ----------------------\n// Only the sponsor is funded. The sponsee has no account on the ledger yet, and no\n// XRP to pay for one.\nconsole.log(`\\n=== Creating the sponsor and sponsee wallets... ===`)\nconst { wallet: sponsor } = await client.fundWallet()\nconst sponsee = Wallet.generate()\n\nconsole.log(`Sponsor address: ${sponsor.address}`)\nconsole.log(`Sponsee address: ${sponsee.address}`)"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Create the sponsor and sponsee wallets ----------------------\n# Only the sponsor is funded. The sponsee has no account on the ledger yet, and no\n# XRP to pay for one.\nprint(\"\\n=== Creating the sponsor and sponsee wallets... ===\")\nsponsor = generate_faucet_wallet(client)\nsponsee = Wallet.create()\n\nprint(f\"Sponsor address: {sponsor.address}\")\nprint(f\"Sponsee address: {sponsee.address}\")"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-create-the-sponsees-account","__idx":8},"children":["4. Create the sponsee's account"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/payment"},"children":["Payment transaction"]}," with the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tfSponsorCreatedAccount"]}," flag enabled to create the sponsee's account. The flag makes the sponsor responsible for the new account's reserve, so the payment only needs to deliver the smallest possible XRP amount."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Prepare Payment transaction to create the sponsee's account ----------------------\n// The tfSponsorCreatedAccount flag makes the sponsor pay the new account's reserve,\n// so the payment itself only needs to deliver 1 drop.\nconsole.log(`\\n=== Preparing Payment transaction to create the sponsee's account... ===`)\nconst createAccountTx = {\n  TransactionType: 'Payment',\n  Account: sponsor.address,\n  Destination: sponsee.address,\n  Amount: '1',\n  Flags: PaymentFlags.tfSponsorCreatedAccount\n}\n\nvalidate(createAccountTx)\nconsole.log(JSON.stringify(createAccountTx, null, 2))\n\n// Submit the Payment transaction ----------------------\nconsole.log(`\\n=== Submitting Payment transaction... ===`)\nconst createAccountResponse = await client.submitAndWait(createAccountTx, {\n  wallet: sponsor,\n  autofill: true\n})\nif (createAccountResponse.result.meta.TransactionResult !== 'tesSUCCESS') {\n  const resultCode = createAccountResponse.result.meta.TransactionResult\n  console.error(`Error: Unable to create the sponsee's account:`, resultCode)\n  await client.disconnect()\n  process.exit(1)\n}\n\n// Confirm the new AccountRoot entry records the sponsor\nconst accountNode = createAccountResponse.result.meta.AffectedNodes.find(\n  node => node.CreatedNode?.LedgerEntryType === 'AccountRoot'\n)\nconsole.log('Sponsee account created successfully!')\nconsole.log(`Account reserve sponsored by: ${accountNode.CreatedNode.NewFields.Sponsor}`)\nconsole.log(`Transaction URL: https://devnet.xrpl.org/transactions/${createAccountResponse.result.hash}`)"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Prepare Payment transaction to create the sponsee's account ----------------------\n# The tfSponsorCreatedAccount flag makes the sponsor pay the new account's reserve,\n# so the payment itself only needs to deliver 1 drop.\nprint(\"\\n=== Preparing Payment transaction to create the sponsee's account... ===\")\ncreate_account_tx = Payment(\n    account=sponsor.address,\n    destination=sponsee.address,\n    amount=\"1\",\n    flags=PaymentFlag.TF_SPONSOR_CREATED_ACCOUNT,\n)\n\nprint(json.dumps(create_account_tx.to_xrpl(), indent=2))\n\n# Submit the Payment transaction ----------------------\nprint(\"\\n=== Submitting Payment transaction... ===\")\ncreate_account_response = submit_and_wait(create_account_tx, client, sponsor)\n\nif create_account_response.result[\"meta\"][\"TransactionResult\"] != \"tesSUCCESS\":\n    result_code = create_account_response.result[\"meta\"][\"TransactionResult\"]\n    print(f\"Error: Unable to create the sponsee's account: {result_code}\")\n    sys.exit(1)\n\n# Confirm the new AccountRoot entry records the sponsor\naccount_node = next(\n    node for node in create_account_response.result[\"meta\"][\"AffectedNodes\"]\n    if node.get(\"CreatedNode\", {}).get(\"LedgerEntryType\") == \"AccountRoot\"\n)\nprint(\"Sponsee account created successfully!\")\nprint(f\"Account reserve sponsored by: {account_node['CreatedNode']['NewFields']['Sponsor']}\")\nprint(f\"Transaction URL: https://devnet.xrpl.org/transactions/{create_account_response.result['hash']}\")"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"5-prepare-the-sponsored-transaction","__idx":9},"children":["5. Prepare the sponsored transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In this example, the sponsee submits a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/depositpreauth"},"children":["DepositPreauth transaction"]},", but many other transaction types can also be sponsored; see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/common-fields#sponsorflags-field"},"children":["SponsorFlags field"]}," to learn more."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Prepare the sponsored DepositPreauth transaction ----------------------\n// The sponsee is the sending account. The Sponsor and SponsorFlags fields ask the\n// sponsor to cover both the fee and the reserve for the new DepositPreauth entry.\nconsole.log(`\\n=== Preparing sponsored DepositPreauth transaction... ===`)\nconst depositPreauthTx = {\n  TransactionType: 'DepositPreauth',\n  Account: sponsee.address,\n  Authorize: sponsor.address,\n  Sponsor: sponsor.address,\n  SponsorFlags: SponsorFlags.spfSponsorFee | SponsorFlags.spfSponsorReserve\n}\nvalidate(depositPreauthTx)\n\nconst preparedTx = await client.autofill(depositPreauthTx)\nconsole.log(JSON.stringify(preparedTx, null, 2))"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Prepare the sponsored DepositPreauth transaction ----------------------\n# The sponsee is the sending account. The Sponsor and SponsorFlags fields ask the\n# sponsor to cover both the fee and the reserve for the new DepositPreauth entry.\nprint(\"\\n=== Preparing sponsored DepositPreauth transaction... ===\")\ndeposit_preauth_tx = DepositPreauth(\n    account=sponsee.address,\n    authorize=sponsor.address,\n    sponsor=sponsor.address,\n    sponsor_flags=SponsorFlag.SPF_SPONSOR_FEE | SponsorFlag.SPF_SPONSOR_RESERVE,\n)\n\ndeposit_preauth_tx = autofill(deposit_preauth_tx, client)\nprint(json.dumps(deposit_preauth_tx.to_xrpl(), indent=2))"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Sponsor"]}," field names the account that pays, and the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SponsorFlags"]}," field states what it pays for:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["spfSponsorFee"]}," for the transaction fee."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["spfSponsorReserve"]}," for the reserve of the new ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["DepositPreauth"]}," entry."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sponsor must sign the transaction with the exact ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Fee"]}," amount it agrees to pay. Autofill the transaction before signing so the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Fee"]}," field is set; if the fee is added or changed after signing, the signature no longer matches the transaction."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"6-co-sign-the-transaction","__idx":10},"children":["6. Co-sign the transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A sponsored transaction needs a signature from both parties, and each one has its own place in the transaction."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sponsee's signature fills the usual ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SigningPubKey"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TxnSignature"]}," fields. The sponsor's goes into a separate ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SponsorSignature"]}," field, which carries its own ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SigningPubKey"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TxnSignature"]},"."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Sign as the sponsee ----------------------\nconst sponseeSignedTx = sponsee.sign(preparedTx)\n\n// Co-sign as the sponsor ----------------------\nconst coSignedTx = signAsSponsor(sponsor, sponseeSignedTx.tx_blob)"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Sign as the sponsee ----------------------\nsponsee_signed_tx = sign(deposit_preauth_tx, sponsee)\n\n# Co-sign as the sponsor ----------------------\nco_signed_tx = sign_as_sponsor(sponsor, sponsee_signed_tx)"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"7-submit-the-transaction-and-confirm-the-sponsorship","__idx":11},"children":["7. Submit the transaction and confirm the sponsorship"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Submit the fully signed transaction and wait for validation."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Submit the fully signed transaction and wait for validation ----------------------\nconsole.log(`\\n=== Submitting sponsored DepositPreauth transaction... ===`)\nconsole.log(JSON.stringify(coSignedTx.tx, null, 2))\nconst submitResponse = await client.submitAndWait(coSignedTx.tx_blob)\n\nif (submitResponse.result.meta.TransactionResult !== 'tesSUCCESS') {\n  const resultCode = submitResponse.result.meta.TransactionResult\n  console.error('Error: Unable to create the preauthorization:', resultCode)\n  await client.disconnect()\n  process.exit(1)\n}\nconsole.log('Transaction sponsored successfully!')\nconsole.log(`Transaction URL: https://devnet.xrpl.org/transactions/${submitResponse.result.hash}`)"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Submit the fully signed transaction and wait for validation ----------------------\nprint(\"\\n=== Submitting sponsored DepositPreauth transaction... ===\")\nprint(json.dumps(co_signed_tx.tx.to_xrpl(), indent=2))\nsubmit_response = submit_and_wait(co_signed_tx.tx, client)\n\nif submit_response.result[\"meta\"][\"TransactionResult\"] != \"tesSUCCESS\":\n    result_code = submit_response.result[\"meta\"][\"TransactionResult\"]\n    print(f\"Error: Unable to create the preauthorization: {result_code}\")\n    sys.exit(1)\n\nprint(\"Transaction sponsored successfully!\")\nprint(f\"Transaction URL: https://devnet.xrpl.org/transactions/{submit_response.result['hash']}\")"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Finally, inspect the affected nodes to confirm the sponsor paid the fee and reserve."]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"JavaScript","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorATransaction.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Extract sponsorship information from the transaction result ----------------------\nconsole.log(`\\n=== Sponsorship Information ===`)\nconst preauthNode = submitResponse.result.meta.AffectedNodes.find(\n  node => node.CreatedNode?.LedgerEntryType === 'DepositPreauth'\n)\nconsole.log(`DepositPreauth ID: ${preauthNode.CreatedNode.LedgerIndex}`)\nconsole.log(`DepositPreauth reserve sponsored by: ${preauthNode.CreatedNode.NewFields.Sponsor}`)\n\n// The sponsor's AccountRoot shows the fee it paid and the reserves it now covers.\n// The sponsee's balance is untouched.\nfor (const node of submitResponse.result.meta.AffectedNodes) {\n  const modified = node.ModifiedNode\n  if (modified?.LedgerEntryType !== 'AccountRoot') {\n    continue\n  }\n\n  const fields = modified.FinalFields\n  const previousBalance = modified.PreviousFields?.Balance ?? fields.Balance\n  const feePaid = Number(previousBalance) - Number(fields.Balance)\n\n  if (fields.Account === sponsor.address) {\n    console.log(`\\nSponsor fee paid: ${feePaid} drops`)\n    console.log(`Sponsor balance:  ${fields.Balance} drops`)\n    console.log(`Reserves sponsored (SponsoringOwnerCount): ${fields.SponsoringOwnerCount ?? 0}`)\n  } else if (fields.Account === sponsee.address) {\n    console.log(`\\nSponsee fee paid: ${feePaid} drops`)\n    console.log(`Sponsee balance:  ${fields.Balance} drops`)\n    console.log(`Sponsee owner count: ${fields.OwnerCount ?? 0}`)\n  }\n}\n\nawait client.disconnect()\n"},"children":[]}]},{"$$mdtype":"Tag","name":"TabItemFragment","attributes":{"label":"Python","disable":false},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/py/sponsor_a_transaction.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Extract sponsorship information from the transaction result ----------------------\nprint(\"\\n=== Sponsorship Information ===\")\npreauth_node = next(\n    node for node in submit_response.result[\"meta\"][\"AffectedNodes\"]\n    if node.get(\"CreatedNode\", {}).get(\"LedgerEntryType\") == \"DepositPreauth\"\n)\nprint(f\"DepositPreauth ID: {preauth_node['CreatedNode']['LedgerIndex']}\")\nprint(f\"DepositPreauth reserve sponsored by: {preauth_node['CreatedNode']['NewFields']['Sponsor']}\")\n\n# The sponsor's AccountRoot shows the fee it paid and the reserves it now covers.\n# The sponsee's balance is untouched.\nfor node in submit_response.result[\"meta\"][\"AffectedNodes\"]:\n    modified = node.get(\"ModifiedNode\", {})\n    if modified.get(\"LedgerEntryType\") != \"AccountRoot\":\n        continue\n\n    fields = modified[\"FinalFields\"]\n    previous = modified.get(\"PreviousFields\", {})\n    fee_paid = int(previous.get(\"Balance\", fields[\"Balance\"])) - int(fields[\"Balance\"])\n\n    if fields[\"Account\"] == sponsor.address:\n        print(f\"\\nSponsor fee paid: {fee_paid} drops\")\n        print(f\"Sponsor balance:  {fields['Balance']} drops\")\n        print(f\"Reserves sponsored (SponsoringOwnerCount): {fields.get('SponsoringOwnerCount', 0)}\")\n    elif fields[\"Account\"] == sponsee.address:\n        print(f\"\\nSponsee fee paid: {fee_paid} drops\")\n        print(f\"Sponsee balance:  {fields['Balance']} drops\")\n        print(f\"Sponsee owner count: {fields.get('OwnerCount', 0)}\")\n"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"see-also","__idx":12},"children":["See Also"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Concepts:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/accounts/sponsored-fees-and-reserves"},"children":["Sponsored Fees and Reserves"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/accounts/reserves"},"children":["Reserves"]}]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Tutorials:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/best-practices/account-management/sponsor-a-transaction-with-a-pre-funded-pool"},"children":["Sponsor a Transaction with a Pre-funded Pool"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/best-practices/account-management/manage-a-sponsorship-pool"},"children":["Manage a Sponsorship Pool"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/best-practices/account-management/transfer-a-reserve-sponsorship"},"children":["Transfer a Reserve Sponsorship"]}]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["References:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/payment"},"children":["Payment transaction"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/depositpreauth"},"children":["DepositPreauth transaction"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/common-fields#sponsorflags-field"},"children":["Common Fields"]}]}]}]}]}]},"headings":[{"value":"Sponsor a Transaction by Co-Signing","id":"sponsor-a-transaction-by-co-signing","depth":1},{"value":"Goals","id":"goals","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Source Code","id":"source-code","depth":2},{"value":"Steps","id":"steps","depth":2},{"value":"1. Install dependencies","id":"1-install-dependencies","depth":3},{"value":"2. Set up the client","id":"2-set-up-the-client","depth":3},{"value":"3. Create the wallets","id":"3-create-the-wallets","depth":3},{"value":"4. Create the sponsee's account","id":"4-create-the-sponsees-account","depth":3},{"value":"5. Prepare the sponsored transaction","id":"5-prepare-the-sponsored-transaction","depth":3},{"value":"6. Co-sign the transaction","id":"6-co-sign-the-transaction","depth":3},{"value":"7. Submit the transaction and confirm the sponsorship","id":"7-submit-the-transaction-and-confirm-the-sponsorship","depth":3},{"value":"See Also","id":"see-also","depth":2}],"frontmatter":{"seo":{"description":"Cover another account's transaction fee and reserve requirement by co-signing a single transaction.","title":"Sponsor a Transaction by Co-Signing"},"labels":["Accounts","Fees","Sponsorship"],"status":"not_enabled"},"editPage":{"to":"https://github.com/XRPLF/xrpl-dev-portal/tree/master/docs/tutorials/best-practices/account-management/sponsor-a-transaction-by-co-signing.md"},"lastModified":"2026-08-26T10:28:02.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/tutorials/best-practices/account-management/sponsor-a-transaction-by-co-signing","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}