forked from cashubtc/cashu-ts
-
Notifications
You must be signed in to change notification settings - Fork 1
/
integration.test.ts
216 lines (192 loc) · 8.65 KB
/
integration.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
import { CashuMint } from '../src/CashuMint.js';
import { CashuWallet } from '../src/CashuWallet.js';
import dns from 'node:dns';
import { deriveKeysetId, getEncodedToken } from '../src/utils.js';
import { secp256k1 } from '@noble/curves/secp256k1';
import { bytesToHex } from '@noble/curves/abstract/utils';
dns.setDefaultResultOrder('ipv4first');
const externalInvoice =
'lnbc20u1p3u27nppp5pm074ffk6m42lvae8c6847z7xuvhyknwgkk7pzdce47grf2ksqwsdpv2phhwetjv4jzqcneypqyc6t8dp6xu6twva2xjuzzda6qcqzpgxqyz5vqsp5sw6n7cztudpl5m5jv3z6dtqpt2zhd3q6dwgftey9qxv09w82rgjq9qyyssqhtfl8wv7scwp5flqvmgjjh20nf6utvv5daw5h43h69yqfwjch7wnra3cn94qkscgewa33wvfh7guz76rzsfg9pwlk8mqd27wavf2udsq3yeuju';
let request: Record<string, string> | undefined;
const mintUrl = 'http://localhost:3338';
const unit = 'sat';
describe('mint api', () => {
test('get keys', async () => {
const mint = new CashuMint(mintUrl);
const keys = await mint.getKeys();
expect(keys).toBeDefined();
});
test('get keysets', async () => {
const mint = new CashuMint(mintUrl);
const keysets = await mint.getKeySets();
expect(keysets).toBeDefined();
expect(keysets.keysets).toBeDefined();
expect(keysets.keysets.length).toBeGreaterThan(0);
});
test('get info', async () => {
const mint = new CashuMint(mintUrl);
const info = await mint.getInfo();
expect(info).toBeDefined();
});
test('request mint', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(100);
expect(request).toBeDefined();
const mintQuote = await wallet.checkMintQuote(request.quote);
expect(mintQuote).toBeDefined();
});
test('mint tokens', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(1337);
expect(request).toBeDefined();
expect(request.request).toContain('lnbc1337');
const tokens = await wallet.mintTokens(1337, request.quote);
expect(tokens).toBeDefined();
// expect that the sum of all tokens.proofs.amount is equal to the requested amount
expect(tokens.proofs.reduce((a, b) => a + b.amount, 0)).toBe(1337);
});
test('get fee for local invoice', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(100);
const fee = (await wallet.createMeltQuote(request.request)).fee_reserve;
expect(fee).toBeDefined();
// because local invoice, fee should be 0
expect(fee).toBe(0);
});
test('get fee for external invoice', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const fee = (await wallet.createMeltQuote(externalInvoice)).fee_reserve;
expect(fee).toBeDefined();
// because external invoice, fee should be > 0
expect(fee).toBeGreaterThan(0);
});
test('pay local invoice', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(100);
const tokens = await wallet.mintTokens(100, request.quote);
// expect no fee because local invoice
const mintQuote = await wallet.createMintQuote(10);
const quote = await wallet.createMeltQuote(mintQuote.request);
const fee = quote.fee_reserve;
expect(fee).toBe(0);
// get the quote from the mint
const quote_ = await wallet.checkMeltQuote(quote.quote);
expect(quote_).toBeDefined();
const sendResponse = await wallet.send(10, tokens.proofs);
const response = await wallet.payLnInvoice(mintQuote.request, sendResponse.send, quote);
expect(response).toBeDefined();
// expect that we have received the fee back, since it was internal
expect(response.change.reduce((a, b) => a + b.amount, 0)).toBe(fee);
// check states of spent and kept proofs after payment
const sentProofsSpent = await wallet.checkProofsSpent(sendResponse.send);
expect(sentProofsSpent).toBeDefined();
// expect that all proofs are spent, i.e. sendProofsSpent == sendResponse.send
expect(sentProofsSpent).toEqual(sendResponse.send);
// expect none of the sendResponse.returnChange to be spent
const returnChangeSpent = await wallet.checkProofsSpent(sendResponse.returnChange);
expect(returnChangeSpent).toBeDefined();
expect(returnChangeSpent).toEqual([]);
});
test('pay external invoice', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(3000);
const tokens = await wallet.mintTokens(3000, request.quote);
const meltQuote = await wallet.createMeltQuote(externalInvoice);
const fee = meltQuote.fee_reserve;
expect(fee).toBeGreaterThan(0);
// get the quote from the mint
const quote_ = await wallet.checkMeltQuote(meltQuote.quote);
expect(quote_).toBeDefined();
const sendResponse = await wallet.send(2000 + fee, tokens.proofs);
const response = await wallet.payLnInvoice(externalInvoice, sendResponse.send, meltQuote);
expect(response).toBeDefined();
// expect that we have not received the fee back, since it was external
expect(response.change.reduce((a, b) => a + b.amount, 0)).toBeLessThan(fee);
// check states of spent and kept proofs after payment
const sentProofsSpent = await wallet.checkProofsSpent(sendResponse.send);
expect(sentProofsSpent).toBeDefined();
// expect that all proofs are spent, i.e. sendProofsSpent == sendResponse.send
expect(sentProofsSpent).toEqual(sendResponse.send);
// expect none of the sendResponse.returnChange to be spent
const returnChangeSpent = await wallet.checkProofsSpent(sendResponse.returnChange);
expect(returnChangeSpent).toBeDefined();
expect(returnChangeSpent).toEqual([]);
});
test('test send tokens exact without previous split', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(64);
const tokens = await wallet.mintTokens(64, request.quote);
const sendResponse = await wallet.send(64, tokens.proofs);
expect(sendResponse).toBeDefined();
expect(sendResponse.send).toBeDefined();
expect(sendResponse.returnChange).toBeDefined();
expect(sendResponse.send.length).toBe(1);
expect(sendResponse.returnChange.length).toBe(0);
});
test('test send tokens with change', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(100);
const tokens = await wallet.mintTokens(100, request.quote);
const sendResponse = await wallet.send(10, tokens.proofs);
expect(sendResponse).toBeDefined();
expect(sendResponse.send).toBeDefined();
expect(sendResponse.returnChange).toBeDefined();
expect(sendResponse.send.length).toBe(2);
expect(sendResponse.returnChange.length).toBe(4);
});
test('receive tokens with previous split', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(100);
const tokens = await wallet.mintTokens(100, request.quote);
const sendResponse = await wallet.send(10, tokens.proofs);
const encoded = getEncodedToken({
token: [{ mint: mintUrl, proofs: sendResponse.send }]
});
const response = await wallet.receive(encoded);
expect(response).toBeDefined();
});
test('receive tokens with previous mint', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint, { unit });
const request = await wallet.createMintQuote(64);
const tokens = await wallet.mintTokens(64, request.quote);
const encoded = getEncodedToken({
token: [{ mint: mintUrl, proofs: tokens.proofs }]
});
const response = await wallet.receive(encoded);
expect(response).toBeDefined();
});
test('send and receive p2pk', async () => {
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint);
const privKeyAlice = secp256k1.utils.randomPrivateKey();
const pubKeyAlice = secp256k1.getPublicKey(privKeyAlice);
const privKeyBob = secp256k1.utils.randomPrivateKey();
const pubKeyBob = secp256k1.getPublicKey(privKeyBob);
const request = await wallet.createMintQuote(64);
const tokens = await wallet.mintTokens(64, request.quote);
const { send } = await wallet.send(64, tokens.proofs, { pubkey: bytesToHex(pubKeyBob) });
const encoded = getEncodedToken({
token: [{ mint: mintUrl, proofs: send }]
});
const result = await wallet
.receive(encoded, { privkey: bytesToHex(privKeyAlice) })
.catch((e) => e);
expect(result).toEqual(new Error('Error when receiving'));
const proofs = await wallet.receive(encoded, { privkey: bytesToHex(privKeyBob) });
expect(
proofs.reduce((curr, acc) => {
return curr + acc.amount;
}, 0)
).toBe(64);
});
});