Skip to content

Commit

Permalink
add additional swaps service tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbosworth committed Oct 20, 2020
1 parent 285f2a9 commit 6e4b735
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 48 deletions.
60 changes: 13 additions & 47 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
"bn.js": "5.1.3",
"cbor": "5.1.0",
"grpc": "1.24.3",
"ln-service": "49.14.0",
"ln-service": "49.14.2",
"macaroon": "3.0.4",
"node-fetch": "2.6.1",
"pushdata-bitcoin": "1.0.1",
"varuint-bitcoin": "1.1.2"
},
"description": "Tools for working with hash timelock contract swaps",
"devDependencies": {
"body-parser": "1.19.0",
"express": "4.17.1",
"tap": "14.10.8"
},
Expand Down
40 changes: 40 additions & 0 deletions service/generic_swap_server.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
const bodyParser = require('body-parser')
const express = require('express');

const defaultSwapInBaseFee = 5000;
const defaultSwapInFeeRate = 1500;
const defaultSwapInCltv = 1000;
const defaultMaxSwapInTokens = 30e6;
const defaultMinSwapInTokens = 250e3;
const defaultMaxSwapOutCltv = 400;
const defaultMaxSwapOutTokens = 30e6;
const defaultMinSwapOutCltv = 100;
const defaultMinSwapOutTokens = 250e3;
const feeRateDenominator = BigInt(1e6);
const methodSwapInQuote = 'loopInQuote';
const methodSwapInTerms = 'loopInTerms';
const methodSwapOutPushPreimage = 'loopOutPushPreimage';
const methodSwapOutQuote = 'loopOutQuote';
const methodSwapOutTerms = 'loopOutTerms';
const path = method => `/v0/${method}`;

/** Create generic swap server
{
[max_swap_in_tokens]: <Maximum Swap In Tokens Number>
[min_swap_in_tokens]: <Minimum Swap In Tokens Number>
[max_swap_out_cltv]: <Maximum Swap Out CLTV Delta Number>
[max_swap_out_tokens]: <Maximum Swap Out Tokens Number>
[min_swap_out_cltv]: <Minimum Swap Out CLTV Delta Number>
[min_swap_out_tokens]: <Minimum Swap Out Tokens Number>
[swap_in_base_fee]: <Swap In Base Fee Tokens Number>
[swap_in_fee_rate]: <Swap In Fee Rate Parts Per Million Number>
[swap_in_cltv]: <Swap In CLTV Delta Number>
}
@returns
Expand All @@ -24,6 +40,30 @@ const path = method => `/v0/${method}`;
module.exports = args => {
const app = express();

app.use(bodyParser.json());

app.post(path(methodSwapInQuote), (req, res) => {
const swapInBaseFee = args.swap_in_base_fee || defaultSwapInBaseFee;
const swapInFeeRate = args.swap_in_fee_rate || defaultSwapInFeeRate;
const tokens = Number(req.body.amt);

const rate = BigInt(tokens) * BigInt(swapInFeeRate) / feeRateDenominator;

return res.json({
cltv_delta: args.swap_in_cltv || defaultSwapInCltv,
swap_fee: swapInBaseFee + Number(rate),
});
});

app.post(path(methodSwapInTerms), (req, res) => {
return res.json({
max_swap_amount: args.max_swap_in_tokens || defaultMaxSwapInTokens,
min_swap_amount: args.min_swap_in_tokens || defaultMinSwapInTokens,
});
});

app.post(path(methodSwapOutPushPreimage), (req, res) => res.json({}));

app.post(path(methodSwapOutTerms), (req, res) => {
return res.json({
max_cltv_delta: args.max_swap_out_cltv || defaultMaxSwapOutCltv,
Expand Down
50 changes: 50 additions & 0 deletions test/service/test_get_swap_in_quote.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const fetch = require('node-fetch');
const {test} = require('tap');

const {genericSwapServer} = require('./../../service');
const {genericSwapService} = require('./../../');
const {getSwapInQuote} = require('./../../');

const port = 2349;

const socket = `http://localhost:${port}`;

const tests = [
{
args: {service: genericSwapService({fetch, socket}).service, tokens: 1e6},
description: 'Generic swap service can be used to get a swap in quote',
expected: {cltv_delta: 1000, fee: 6500},
},
];

const startSwapServer = ({app, port}) => new Promise((resolve, reject) => {
let server;

server = app.listen(port, () => resolve({server}));

return;
});

const stopSwapServer = ({server}) => new Promise((resolve, reject) => {
return server.close(() => resolve());
});

tests.forEach(({args, description, error, expected}) => {
return test(description, async ({deepIs, end, equal, throws, rejects}) => {
const {app} = genericSwapServer({});

const {server} = await startSwapServer({app, port});

if (!!error) {
await rejects(getSwapInQuote(args), error, 'Got ExpectedError');
} else {
const result = await getSwapInQuote(args);

deepIs(result, expected, 'Got expected result');
}

await stopSwapServer({server});

return end();
});
});
50 changes: 50 additions & 0 deletions test/service/test_get_swap_in_terms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const fetch = require('node-fetch');
const {test} = require('tap');

const {genericSwapServer} = require('./../../service');
const {genericSwapService} = require('./../../');
const {getSwapInTerms} = require('./../../');

const port = 2349;

const socket = `http://localhost:${port}`;

const tests = [
{
args: {service: genericSwapService({fetch, socket}).service},
description: 'Generic swap service can be used to get swap in terms',
expected: {max_tokens: 30e6, min_tokens: 250000},
},
];

const startSwapServer = ({app, port}) => new Promise((resolve, reject) => {
let server;

server = app.listen(port, () => resolve({server}));

return;
});

const stopSwapServer = ({server}) => new Promise((resolve, reject) => {
return server.close(() => resolve());
});

tests.forEach(({args, description, error, expected}) => {
return test(description, async ({deepIs, end, equal, throws, rejects}) => {
const {app} = genericSwapServer({});

const {server} = await startSwapServer({app, port});

if (!!error) {
await rejects(getSwapInTerms(args), error, 'Got ExpectedError');
} else {
const result = await getSwapInTerms(args);

deepIs(result, expected, 'Got expected result');
}

await stopSwapServer({server});

return end();
});
});
54 changes: 54 additions & 0 deletions test/service/test_release_swap_out_secret.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const fetch = require('node-fetch');
const {test} = require('tap');

const {genericSwapServer} = require('./../../service');
const {genericSwapService} = require('./../../');
const {releaseSwapOutSecret} = require('./../../');

const port = 2349;

const socket = `http://localhost:${port}`;

const tests = [
{
args: {
auth_macaroon: Buffer.alloc(1).toString('base64'),
auth_preimage: Buffer.alloc(32).toString('hex'),
secret: Buffer.alloc(32).toString('hex'),
service: genericSwapService({fetch, socket}).service,
},
description: 'Generic swap service can be used to release a swap secret',
},
];

const startSwapServer = ({app, port}) => new Promise((resolve, reject) => {
let server;

server = app.listen(port, () => resolve({server}));

return;
});

const stopSwapServer = ({server}) => new Promise((resolve, reject) => {
return server.close(() => resolve());
});

tests.forEach(({args, description, error, expected}) => {
return test(description, async ({deepIs, end, equal, throws, rejects}) => {
const {app} = genericSwapServer({});

const {server} = await startSwapServer({app, port});

if (!!error) {
await rejects(releaseSwapOutSecret(args), error, 'Got ExpectedError');
} else {
const result = await releaseSwapOutSecret(args);

deepIs(result, expected, 'Got expected result');
}

await stopSwapServer({server});

return end();
});
});

0 comments on commit 6e4b735

Please sign in to comment.