{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["amendment-disclaimer","tabs","tab","code-snippet","admonition"]},"redocly_category":"Documentation","type":"markdown"},"seo":{"title":"Sponsor a Transaction with a Pre-funded Pool","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":"Create a sponsorship pool that lets a sponsee submit sponsored transactions without the sponsor co-signing each one."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"sponsor-a-transaction-with-a-pre-funded-pool","__idx":0},"children":["Sponsor a Transaction with a Pre-funded Pool"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial shows how to use the pre-funded ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/accounts/sponsored-fees-and-reserves#how-sponsorship-works"},"children":["sponsorship"]}," flow, where a sponsor allocates XRP upfront that a sponsee draws on for fees and reserves. In this example, a sponsor onboards a new user who holds no XRP, then sets up a pool the user can spend without further approval."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the default pre-funded flow when sponsees must be able to transact without waiting on the sponsor. If the sponsor needs to review each transaction without setting up a pool, use ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/tutorials/best-practices/account-management/sponsor-a-transaction-by-co-signing"},"children":["co-signing"]}," 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 a pre-funded sponsorship pool for a sponsee."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Submit a sponsored transaction that draws on the pool."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Confirm what the pool spent on fees and reserves."]}]},{"$$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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"import {\n  Client,\n  PaymentFlags,\n  SponsorFlags,\n  Wallet,\n  addPreFundedSponsor,\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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"import json\nimport sys\n\nfrom xrpl.clients import JsonRpcClient\nfrom xrpl.models import (\n    DepositPreauth,\n    Payment,\n    PaymentFlag,\n    SponsorFlag,\n    SponsorshipSet,\n)\nfrom xrpl.transaction import 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. Only the sponsor needs XRP, because it covers every cost in this example."]},{"$$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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Create the sponsor and sponsee wallets ----------------------\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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Create the sponsor and sponsee wallets ----------------------\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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Prepare Payment transaction to create the sponsee's account ----------------------\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}\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})\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}\nconsole.log('Sponsee account created successfully!')\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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Prepare Payment transaction to create the sponsee's account ----------------------\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\nprint(\"Sponsee account created successfully!\")\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-sponsorshipset-transaction","__idx":9},"children":["5. Prepare the SponsorshipSet transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To create the pre-funded pool (",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/ledger-data/ledger-entry-types/sponsorship"},"children":["Sponsorship entry"]},"), prepare a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/sponsorshipset"},"children":["SponsorshipSet transaction"]},"."]},{"$$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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Prepare SponsorshipSet transaction ----------------------\nconsole.log(`\\n=== Preparing SponsorshipSet transaction... ===`)\nconst sponsorshipSetTx = {\n  TransactionType: 'SponsorshipSet',\n  Account: sponsor.address,\n  Sponsee: sponsee.address,\n  FeeAmountDelta: '1000000',\n  MaxFee: '1000',\n  RemainingOwnerCountDelta: 5\n}\nvalidate(sponsorshipSetTx)\nconsole.log(JSON.stringify(sponsorshipSetTx, 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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Prepare SponsorshipSet transaction ----------------------\nprint(\"\\n=== Preparing SponsorshipSet transaction... ===\")\nsponsorship_set_tx = SponsorshipSet(\n    account=sponsor.address,\n    sponsee=sponsee.address,\n    fee_amount_delta=\"1000000\",\n    max_fee=\"1000\",\n    remaining_owner_count_delta=5,\n)\nprint(json.dumps(sponsorship_set_tx.to_xrpl(), indent=2))"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"success","name":"Tip"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MaxFee"]}," with enough headroom for changes in the network's required ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/concepts/transactions/transaction-cost"},"children":["transaction cost"]},". A cap near the current minimum can block the sponsee's transactions when the cost rises. Monitor the pool's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FeeAmount"]}," so it can be topped up before it runs out."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FeeAmountDelta"]}," field represents the drops available for fees, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MaxFee"]}," caps what the pool pays for any single transaction, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RemainingOwnerCountDelta"]}," is the number of owner reserves the sponsor covers."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The two delta fields are amounts to add to the pool's current values (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FeeAmount"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RemainingOwnerCount"]},"), not replacements. For this example, the pool is new so each delta becomes its starting value. Both fields also accept a ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["negative"]}," value:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A negative ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FeeAmountDelta"]}," returns the unspent XRP to the sponsor."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A negative ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RemainingOwnerCountDelta"]}," lowers how many owner reserves the pool covers."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A negative delta is a subtraction, so neither field goes below zero. If you subtract more than a field has left, that field drops to zero instead, as long as the other one stays positive. A subtraction that would leave both at zero fails with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tecNO_PERMISSION"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"6-submit-the-sponsorshipset-transaction","__idx":10},"children":["6. Submit the SponsorshipSet transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Sign and submit the SponsorshipSet transaction."]},{"$$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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Submit the SponsorshipSet transaction ----------------------\nconsole.log(`\\n=== Submitting SponsorshipSet transaction... ===`)\nconst sponsorshipResponse = await client.submitAndWait(sponsorshipSetTx, {\n  wallet: sponsor,\n  autofill: true\n})\n\nif (sponsorshipResponse.result.meta.TransactionResult !== 'tesSUCCESS') {\n  const resultCode = sponsorshipResponse.result.meta.TransactionResult\n  console.error('Error: Unable to create the sponsorship:', resultCode)\n  await client.disconnect()\n  process.exit(1)\n}\n\n// Extract the Sponsorship entry from the transaction result ----------------------\nconst sponsorshipNode = sponsorshipResponse.result.meta.AffectedNodes.find(\n  node => node.CreatedNode?.LedgerEntryType === 'Sponsorship'\n)\nconsole.log('Sponsorship created successfully!')\nconsole.log(`Sponsorship ID: ${sponsorshipNode.CreatedNode.LedgerIndex}`)\nconsole.log(`Transaction URL: https://devnet.xrpl.org/transactions/${sponsorshipResponse.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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Submit the SponsorshipSet transaction ----------------------\nprint(\"\\n=== Submitting SponsorshipSet transaction... ===\")\nsponsorship_response = submit_and_wait(sponsorship_set_tx, client, sponsor)\n\nif sponsorship_response.result[\"meta\"][\"TransactionResult\"] != \"tesSUCCESS\":\n    result_code = sponsorship_response.result[\"meta\"][\"TransactionResult\"]\n    print(f\"Error: Unable to create the sponsorship: {result_code}\")\n    sys.exit(1)\n\n# Extract the Sponsorship entry from the transaction result ----------------------\nsponsorship_node = next(\n    node for node in sponsorship_response.result[\"meta\"][\"AffectedNodes\"]\n    if node.get(\"CreatedNode\", {}).get(\"LedgerEntryType\") == \"Sponsorship\"\n)\nprint(\"Sponsorship created successfully!\")\nprint(f\"Sponsorship ID: {sponsorship_node['CreatedNode']['LedgerIndex']}\")\nprint(f\"Transaction URL: https://devnet.xrpl.org/transactions/{sponsorship_response.result['hash']}\")"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The sponsor pays the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FeeAmountDelta"]}," up front and must also meet the reserve requirement for the new Sponsorship entry. If it can't cover those costs, the transaction fails with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tecUNFUNDED"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each pool is a single Sponsorship entry that serves one sponsee. To fund several sponsees, the sponsor must create a pool for each one and hold an owner reserve for every pool."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info","name":"Note"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By default, the sponsee can spend from the pool without further sponsor approval. A sponsor can also require a signature on each use by enabling the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tfSponsorshipSetRequireSignForFee"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tfSponsorshipSetRequireSignForReserve"]}," flags. In that variation, transactions still draw from the pre-funded pool, but each sponsored transaction must also include the sponsor's signature."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"7-sponsor-a-transaction","__idx":11},"children":["7. Sponsor a transaction"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Submit the sponsored 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":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["addPreFundedSponsor"]}," helper adds the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Sponsor"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SponsorFlags"]}," fields for a transaction that draws from an existing pre-funded Sponsorship entry."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"file":"/_code-samples/sponsored-fees-and-reserves/js/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Prepare the sponsored DepositPreauth transaction ----------------------\nconsole.log(`\\n=== Preparing sponsored DepositPreauth transaction... ===`)\nconst depositPreauthTx = addPreFundedSponsor(\n  {\n    TransactionType: 'DepositPreauth',\n    Account: sponsee.address,\n    Authorize: sponsor.address\n  },\n  sponsor.address,\n  SponsorFlags.spfSponsorFee | SponsorFlags.spfSponsorReserve\n)\nvalidate(depositPreauthTx)\nconsole.log(JSON.stringify(depositPreauthTx, null, 2))\n\n// Submit the sponsored DepositPreauth transaction ----------------------\nconsole.log(`\\n=== Submitting sponsored DepositPreauth transaction... ===`)\nconst submitResponse = await client.submitAndWait(depositPreauthTx, {\n  wallet: sponsee,\n  autofill: true\n})\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}\n\n// The transaction carries no SponsorSignature, which is what distinguishes the\n// pre-funded flow from the co-signed flow.\nif (submitResponse.result.tx_json.SponsorSignature !== undefined) {\n  console.error('Error: A pre-funded sponsorship should not need a SponsorSignature')\n  await client.disconnect()\n  process.exit(1)\n}\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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Prepare the sponsored DepositPreauth transaction ----------------------\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)\nprint(json.dumps(deposit_preauth_tx.to_xrpl(), indent=2))\n\n# Submit the sponsored DepositPreauth transaction ----------------------\nprint(\"\\n=== Submitting sponsored DepositPreauth transaction... ===\")\nsubmit_response = submit_and_wait(deposit_preauth_tx, client, sponsee)\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\n# The transaction carries no SponsorSignature, which is what distinguishes the\n# pre-funded flow from the co-signed flow.\nif \"SponsorSignature\" in submit_response.result[\"tx_json\"]:\n    print(\"Error: A pre-funded sponsorship should not need a SponsorSignature\")\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":["In this example, the sponsee submits a ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/transactions/types/depositpreauth"},"children":["DepositPreauth transaction"]}," without a signature from the sponsor. The transaction draws its transaction fee and the new ledger entry's reserve from the pool. 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":"Heading","attributes":{"level":3,"id":"8-validate-the-sponsorship","__idx":12},"children":["8. Validate the sponsorship"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Inspect the affected nodes to verify the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Sponsor"]}," field is on the new ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/references/protocol/ledger-data/ledger-entry-types/depositpreauth"},"children":["DepositPreauth entry"]},", and compare the Sponsorship entry's fields before and after to see what the pool spent."]},{"$$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/sponsorWithPreFundedPool.js","language":"js","header":{"controls":{"copy":{}}},"lang":"js","source":"// Extract sponsorship information from the transaction result ----------------------\nconsole.log(`\\n=== Sponsorship Pool 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 Sponsorship entry shows the fee drops and owner reserves the pool spent.\nconst sponsorshipPool = submitResponse.result.meta.AffectedNodes.find(\n  node => node.ModifiedNode?.LedgerEntryType === 'Sponsorship'\n)\nconst fields = sponsorshipPool.ModifiedNode.FinalFields\nconst previous = sponsorshipPool.ModifiedNode.PreviousFields\nconst feePaid = BigInt(previous.FeeAmount) - BigInt(fields.FeeAmount)\n\nconsole.log(`\\nFee spent from the pool: ${feePaid} drops`)\nconsole.log(`Fee remaining in the pool: ${fields.FeeAmount} drops`)\nconsole.log(`Owner reserves spent: ${previous.RemainingOwnerCount - fields.RemainingOwnerCount}`)\nconsole.log(`Owner reserves remaining: ${fields.RemainingOwnerCount}`)\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_with_pre_funded_pool.py","language":"py","header":{"controls":{"copy":{}}},"lang":"py","source":"# Extract sponsorship information from the transaction result ----------------------\nprint(\"\\n=== Sponsorship Pool 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 Sponsorship entry shows the fee drops and owner reserves the pool spent.\nsponsorship_pool = next(\n    node for node in submit_response.result[\"meta\"][\"AffectedNodes\"]\n    if node.get(\"ModifiedNode\", {}).get(\"LedgerEntryType\") == \"Sponsorship\"\n)\nfields = sponsorship_pool[\"ModifiedNode\"][\"FinalFields\"]\nprevious = sponsorship_pool[\"ModifiedNode\"][\"PreviousFields\"]\nfee_paid = int(previous[\"FeeAmount\"]) - int(fields[\"FeeAmount\"])\nowner_reserves_spent = int(previous[\"RemainingOwnerCount\"]) - int(fields[\"RemainingOwnerCount\"])\n\nprint(f\"\\nFee spent from the pool: {fee_paid} drops\")\nprint(f\"Fee remaining in the pool: {fields['FeeAmount']} drops\")\nprint(f\"Owner reserves spent: {owner_reserves_spent}\")\nprint(f\"Owner reserves remaining: {fields['RemainingOwnerCount']}\")\n"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"see-also","__idx":13},"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-by-co-signing"},"children":["Sponsor a Transaction by Co-Signing"]}]},{"$$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/sponsorshipset"},"children":["SponsorshipSet 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/ledger-data/ledger-entry-types/sponsorship"},"children":["Sponsorship ledger entry"]}]},{"$$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 with a Pre-funded Pool","id":"sponsor-a-transaction-with-a-pre-funded-pool","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 SponsorshipSet transaction","id":"5-prepare-the-sponsorshipset-transaction","depth":3},{"value":"6. Submit the SponsorshipSet transaction","id":"6-submit-the-sponsorshipset-transaction","depth":3},{"value":"7. Sponsor a transaction","id":"7-sponsor-a-transaction","depth":3},{"value":"8. Validate the sponsorship","id":"8-validate-the-sponsorship","depth":3},{"value":"See Also","id":"see-also","depth":2}],"frontmatter":{"seo":{"description":"Create a sponsorship pool that lets a sponsee submit sponsored transactions without the sponsor co-signing each one.","title":"Sponsor a Transaction with a Pre-funded Pool"},"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-with-a-pre-funded-pool.md"},"lastModified":"2026-08-26T10:28:02.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/tutorials/best-practices/account-management/sponsor-a-transaction-with-a-pre-funded-pool","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}