diff --git a/src/api/routes/faucets.ts b/src/api/routes/faucets.ts index c9b2b04e8..5d7b55016 100644 --- a/src/api/routes/faucets.ts +++ b/src/api/routes/faucets.ts @@ -74,27 +74,41 @@ export const FaucetRoutes: FastifyPluginAsync< preHandler: missingBtcConfigMiddleware, schema: { operationId: 'run_faucet_btc', - summary: 'Add testnet BTC tokens to address', - description: `Add 1 BTC token to the specified testnet BTC address. + summary: 'Add regtest BTC tokens to address', + description: `Add 0.01 BTC token to the specified regtest BTC address. - The endpoint returns the transaction ID, which you can use to view the transaction in a testnet Bitcoin block + The endpoint returns the transaction ID, which you can use to view the transaction in a regtest Bitcoin block explorer. The tokens are delivered once the transaction has been included in a block. - **Note:** This is a testnet only endpoint. This endpoint will not work on the mainnet.`, + **Note:** This is a Bitcoin regtest-only endpoint. This endpoint will not work on the Bitcoin mainnet.`, tags: ['Faucets'], querystring: Type.Object({ address: Type.Optional( Type.String({ - description: 'A valid testnet BTC address', + description: 'A valid regtest BTC address', examples: ['2N4M94S1ZPt8HfxydXzL2P7qyzgVq7MHWts'], }) ), + large: Type.Optional( + Type.Boolean({ + description: + 'Request a large amount of regtest BTC than the default', + default: false, + }) + ), + xlarge: Type.Optional( + Type.Boolean({ + description: + 'Request an extra large amount of regtest BTC than the default', + default: false, + }) + ), }), body: OptionalNullable( Type.Object({ address: Type.Optional( Type.String({ - description: 'A valid testnet BTC address', + description: 'A valid regtest BTC address', examples: ['2N4M94S1ZPt8HfxydXzL2P7qyzgVq7MHWts'], }) ), @@ -112,7 +126,7 @@ export const FaucetRoutes: FastifyPluginAsync< { title: 'RunFaucetResponse', description: - 'POST request that initiates a transfer of tokens to a specified testnet address', + 'POST request that initiates a transfer of tokens to a specified Bitcoin regtest address', } ), '4xx': Type.Object({ @@ -125,6 +139,21 @@ export const FaucetRoutes: FastifyPluginAsync< async (req, reply) => { await btcFaucetRequestQueue.add(async () => { const address = req.query.address || req.body?.address; + let btcAmount = 0.0001; + + if (req.query.large && req.query.xlarge) { + return await reply.status(400).send({ + error: 'cannot simultaneously request a large and xlarge amount', + success: false, + }); + } + + if (req.query.large) { + btcAmount = 0.01; + } else if (req.query.xlarge) { + btcAmount = 0.5; + } + if (!address) { return await reply.status(400).send({ error: 'address required', @@ -156,7 +185,7 @@ export const FaucetRoutes: FastifyPluginAsync< }); } - const tx = await makeBtcFaucetPayment(btc.networks.regtest, address, 0.5); + const tx = await makeBtcFaucetPayment(btc.networks.regtest, address, btcAmount); await fastify.writeDb?.insertFaucetRequest({ ip: `${ip}`, address: address, @@ -183,7 +212,7 @@ export const FaucetRoutes: FastifyPluginAsync< tags: ['Faucets'], params: Type.Object({ address: Type.String({ - description: 'A valid testnet BTC address', + description: 'A valid regtest BTC address', examples: ['2N4M94S1ZPt8HfxydXzL2P7qyzgVq7MHWts'], }), }), diff --git a/tests/btc-faucet/faucet-btc.test.ts b/tests/btc-faucet/faucet-btc.test.ts index 5d2ae10d0..60e000255 100644 --- a/tests/btc-faucet/faucet-btc.test.ts +++ b/tests/btc-faucet/faucet-btc.test.ts @@ -156,6 +156,40 @@ describe('btc faucet', () => { `/extended/v1/faucets/btc/${addr}` ); expect(balanceResponse.status).toBe(200); + expect(JSON.parse(balanceResponse.text)).toEqual({ balance: 0.0001 }); + }); + + test('faucet http balance endpoint large', async () => { + const addr = getKeyAddress(ECPair.makeRandom({ network: regtest })); + const response = await supertest(apiServer.server).post( + `/extended/v1/faucets/btc?address=${addr}&large=true` + ); + expect(response.status).toBe(200); + await getRpcClient().generatetoaddress({ + address: getKeyAddress(ECPair.makeRandom({ network: regtest })), + nblocks: 1, + }); + const balanceResponse = await supertest(apiServer.server).get( + `/extended/v1/faucets/btc/${addr}` + ); + expect(balanceResponse.status).toBe(200); + expect(JSON.parse(balanceResponse.text)).toEqual({ balance: 0.01 }); + }); + + test('faucet http balance endpoint xlarge', async () => { + const addr = getKeyAddress(ECPair.makeRandom({ network: regtest })); + const response = await supertest(apiServer.server).post( + `/extended/v1/faucets/btc?address=${addr}&xlarge=true` + ); + expect(response.status).toBe(200); + await getRpcClient().generatetoaddress({ + address: getKeyAddress(ECPair.makeRandom({ network: regtest })), + nblocks: 1, + }); + const balanceResponse = await supertest(apiServer.server).get( + `/extended/v1/faucets/btc/${addr}` + ); + expect(balanceResponse.status).toBe(200); expect(JSON.parse(balanceResponse.text)).toEqual({ balance: 0.5 }); });