diff --git a/modules/ecash-agora/tests/partial.slp.test.ts b/modules/ecash-agora/tests/partial.slp.test.ts
new file mode 100644
--- /dev/null
+++ b/modules/ecash-agora/tests/partial.slp.test.ts
@@ -0,0 +1,45 @@
+// Copyright (c) 2024 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+import { expect, use } from 'chai';
+import chaiAsPromised from 'chai-as-promised';
+import { ChronikClient } from 'chronik-client';
+import { Ecc, initWasm, OP_RETURN, Script } from 'ecash-lib';
+import { TestRunner } from 'ecash-lib/dist/test/testRunner.js';
+
+use(chaiAsPromised);
+
+// This test needs a lot of sats
+const NUM_COINS = 500;
+const COIN_VALUE = 1100000000;
+
+describe('AgoraPartial SLP', () => {
+    let runner: TestRunner;
+    let chronik: ChronikClient;
+    let ecc: Ecc;
+
+    before(async () => {
+        await initWasm();
+        runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
+        chronik = runner.chronik;
+        ecc = runner.ecc;
+        await runner.setupCoins(NUM_COINS, COIN_VALUE);
+    });
+
+    after(() => {
+        runner.stop();
+    });
+
+    it('Can get a big UTXO', async () => {
+        // TODO: this will be filled in by actual tests later
+        const txid = await runner.sendToScript(
+            [10000, 1010000000],
+            Script.fromAddress(
+                'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07',
+            ),
+        );
+        const tx = await chronik.tx(txid);
+        expect(tx.outputs[1].value).to.equal(1010000000);
+    });
+});
diff --git a/modules/ecash-lib/src/test/testRunner.ts b/modules/ecash-lib/src/test/testRunner.ts
--- a/modules/ecash-lib/src/test/testRunner.ts
+++ b/modules/ecash-lib/src/test/testRunner.ts
@@ -12,6 +12,7 @@
 import { OP_1, OP_RETURN } from '../opcode.js';
 import { Script } from '../script.js';
 import { OutPoint, Tx } from '../tx.js';
+import { TxBuilder } from '../txBuilder.js';
 
 const OP_TRUE_SCRIPT = Script.fromOps([OP_1]);
 const OP_TRUE_SCRIPT_SIG = Script.fromOps([
@@ -26,6 +27,7 @@
     public runner: ChildProcess;
     public chronik: ChronikClient;
     private coinsTxid: string | undefined;
+    private coinValue: number | undefined;
     private lastUsedOutIdx: number;
 
     private constructor(
@@ -129,20 +131,19 @@
         coinValue: number,
     ): Promise<void> {
         const opTrueScriptHash = shaRmd160(OP_TRUE_SCRIPT.bytecode);
-        const utxo = (
+        const utxos = (
             await this.chronik.script('p2sh', toHex(opTrueScriptHash)).utxos()
-        ).utxos[0];
+        ).utxos;
         const anyoneScriptHash = shaRmd160(ANYONE_SCRIPT.bytecode);
         const anyoneP2sh = Script.p2sh(anyoneScriptHash);
         const tx = new Tx({
-            inputs: [
-                {
-                    prevOut: utxo.outpoint,
-                    script: OP_TRUE_SCRIPT_SIG,
-                    sequence: 0xffffffff,
-                },
-            ],
+            inputs: utxos.map(utxo => ({
+                prevOut: utxo.outpoint,
+                script: OP_TRUE_SCRIPT_SIG,
+                sequence: 0xffffffff,
+            })),
         });
+        const utxosValue = utxos.reduce((a, b) => a + b.value, 0);
         for (let i = 0; i < numCoins; ++i) {
             tx.outputs.push({
                 value: coinValue,
@@ -154,9 +155,10 @@
             script: Script.fromOps([OP_RETURN]),
         });
         tx.outputs[tx.outputs.length - 1].value =
-            utxo.value - numCoins * coinValue - tx.serSize();
+            utxosValue - numCoins * coinValue - tx.serSize();
 
         this.coinsTxid = (await this.chronik.broadcastTx(tx.ser())).txid;
+        this.coinValue = coinValue;
     }
 
     public getOutpoint(): OutPoint {
@@ -169,17 +171,31 @@
         };
     }
 
-    public async sendToScript(value: number, script: Script): Promise<string> {
-        const setupTx = new Tx({
+    public async sendToScript(
+        value: number | number[],
+        script: Script,
+    ): Promise<string> {
+        const coinValue = this.coinValue!;
+        const values = Array.isArray(value) ? value : [value];
+        const setupTxBuilder = new TxBuilder({
             inputs: [
                 {
-                    prevOut: this.getOutpoint(),
-                    script: ANYONE_SCRIPT_SIG,
-                    sequence: 0xffffffff,
+                    input: {
+                        prevOut: this.getOutpoint(),
+                        script: ANYONE_SCRIPT_SIG,
+                        sequence: 0xffffffff,
+                        signData: {
+                            value: coinValue,
+                        },
+                    },
                 },
             ],
-            outputs: [{ value, script }],
+            outputs: [
+                ...values.map(value => ({ value, script })),
+                Script.fromOps([OP_RETURN]), // burn leftover
+            ],
         });
+        const setupTx = setupTxBuilder.sign(this.ecc, 1000, 546);
         return (await this.chronik.broadcastTx(setupTx.ser())).txid;
     }
 
diff --git a/test/functional/setup_scripts/ecash-agora_base.py b/test/functional/setup_scripts/ecash-agora_base.py
--- a/test/functional/setup_scripts/ecash-agora_base.py
+++ b/test/functional/setup_scripts/ecash-agora_base.py
@@ -26,7 +26,7 @@
     def run_test(self):
         node = self.nodes[0]
 
-        self.generatetoaddress(node, 1, ADDRESS_ECREG_P2SH_OP_TRUE)[0]
+        self.generatetoaddress(node, 149, ADDRESS_ECREG_P2SH_OP_TRUE)[0]
         self.generatetoaddress(node, COINBASE_MATURITY, ADDRESS_ECREG_UNSPENDABLE)
 
         plugins_toml = os.path.join(node.datadir, "plugins.toml")