ecash-agora 0.1.1-rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +8 -0
- package/.nycrc +4 -0
- package/README.md +122 -0
- package/agora.py +771 -0
- package/dist/ad.d.ts +15 -0
- package/dist/ad.d.ts.map +1 -0
- package/dist/ad.js +111 -0
- package/dist/ad.js.map +1 -0
- package/dist/agora.d.ts +178 -0
- package/dist/agora.d.ts.map +1 -0
- package/dist/agora.js +432 -0
- package/dist/agora.js.map +1 -0
- package/dist/consts.d.ts +5 -0
- package/dist/consts.d.ts.map +1 -0
- package/dist/consts.js +9 -0
- package/dist/consts.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/oneshot.d.ts +34 -0
- package/dist/oneshot.d.ts.map +1 -0
- package/dist/oneshot.js +204 -0
- package/dist/oneshot.js.map +1 -0
- package/dist/partial.d.ts +256 -0
- package/dist/partial.d.ts.map +1 -0
- package/dist/partial.js +955 -0
- package/dist/partial.js.map +1 -0
- package/eslint.config.js +16 -0
- package/package.json +52 -0
- package/tests/oneshot.test.ts +569 -0
- package/tests/partial-helper-alp.ts +131 -0
- package/tests/partial-helper-slp.ts +154 -0
- package/tests/partial.alp.bigsats.test.ts +694 -0
- package/tests/partial.alp.test.ts +586 -0
- package/tests/partial.slp.bigsats.test.ts +681 -0
- package/tests/partial.slp.test.ts +630 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
// Copyright (c) 2024 The Bitcoin developers
|
|
2
|
+
// Distributed under the MIT software license, see the accompanying
|
|
3
|
+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
4
|
+
|
|
5
|
+
import { expect, use } from 'chai';
|
|
6
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
7
|
+
import { ChronikClient } from 'chronik-client';
|
|
8
|
+
import {
|
|
9
|
+
ALL_BIP143,
|
|
10
|
+
DEFAULT_DUST_LIMIT,
|
|
11
|
+
Ecc,
|
|
12
|
+
P2PKHSignatory,
|
|
13
|
+
SLP_FUNGIBLE,
|
|
14
|
+
SLP_LOKAD_ID,
|
|
15
|
+
Script,
|
|
16
|
+
TxBuilderInput,
|
|
17
|
+
fromHex,
|
|
18
|
+
initWasm,
|
|
19
|
+
shaRmd160,
|
|
20
|
+
slpSend,
|
|
21
|
+
strToBytes,
|
|
22
|
+
toHex,
|
|
23
|
+
} from 'ecash-lib';
|
|
24
|
+
import { TestRunner } from 'ecash-lib/dist/test/testRunner.js';
|
|
25
|
+
|
|
26
|
+
import { AgoraPartial } from '../src/partial.js';
|
|
27
|
+
import { makeSlpOffer, takeSlpOffer } from './partial-helper-slp.js';
|
|
28
|
+
|
|
29
|
+
use(chaiAsPromised);
|
|
30
|
+
|
|
31
|
+
const BASE_PARAMS_SLP = {
|
|
32
|
+
tokenId: '00'.repeat(32), // filled in later
|
|
33
|
+
tokenType: SLP_FUNGIBLE,
|
|
34
|
+
tokenProtocol: 'SLP' as const,
|
|
35
|
+
dustAmount: DEFAULT_DUST_LIMIT,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const BIGSATS = 149 * 5000000000 - 20000;
|
|
39
|
+
|
|
40
|
+
let makerSk: Uint8Array;
|
|
41
|
+
let makerPk: Uint8Array;
|
|
42
|
+
let makerPkh: Uint8Array;
|
|
43
|
+
let makerScript: Script;
|
|
44
|
+
let makerScriptHex: string;
|
|
45
|
+
let takerSk: Uint8Array;
|
|
46
|
+
let takerPk: Uint8Array;
|
|
47
|
+
let takerPkh: Uint8Array;
|
|
48
|
+
let takerScript: Script;
|
|
49
|
+
let takerScriptHex: string;
|
|
50
|
+
|
|
51
|
+
function initKeys(ecc: Ecc) {
|
|
52
|
+
makerSk = fromHex('33'.repeat(32));
|
|
53
|
+
makerPk = ecc.derivePubkey(makerSk);
|
|
54
|
+
makerPkh = shaRmd160(makerPk);
|
|
55
|
+
makerScript = Script.p2pkh(makerPkh);
|
|
56
|
+
makerScriptHex = toHex(makerScript.bytecode);
|
|
57
|
+
takerSk = fromHex('44'.repeat(32));
|
|
58
|
+
takerPk = ecc.derivePubkey(takerSk);
|
|
59
|
+
takerPkh = shaRmd160(takerPk);
|
|
60
|
+
takerScript = Script.p2pkh(takerPkh);
|
|
61
|
+
takerScriptHex = toHex(takerScript.bytecode);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function makeBuilderInputs(
|
|
65
|
+
runner: TestRunner,
|
|
66
|
+
values: number[],
|
|
67
|
+
): Promise<TxBuilderInput[]> {
|
|
68
|
+
const txid = await runner.sendToScript(values, makerScript);
|
|
69
|
+
return values.map((value, outIdx) => ({
|
|
70
|
+
input: {
|
|
71
|
+
prevOut: {
|
|
72
|
+
txid,
|
|
73
|
+
outIdx,
|
|
74
|
+
},
|
|
75
|
+
signData: {
|
|
76
|
+
value,
|
|
77
|
+
outputScript: makerScript,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
signatory: P2PKHSignatory(makerSk, makerPk, ALL_BIP143),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
describe('Agora Partial 7450M XEC vs 2p64-1 full accept', () => {
|
|
85
|
+
let runner: TestRunner;
|
|
86
|
+
let chronik: ChronikClient;
|
|
87
|
+
let ecc: Ecc;
|
|
88
|
+
|
|
89
|
+
before(async () => {
|
|
90
|
+
await initWasm();
|
|
91
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
92
|
+
chronik = runner.chronik;
|
|
93
|
+
ecc = runner.ecc;
|
|
94
|
+
initKeys(ecc);
|
|
95
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
after(() => {
|
|
99
|
+
runner.stop();
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('Agora Partial 7450M XEC vs 2p64-1 full accept', async () => {
|
|
103
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
104
|
+
10000,
|
|
105
|
+
BIGSATS,
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
109
|
+
offeredTokens: 0xffffffffffffffffn,
|
|
110
|
+
priceNanoSatsPerToken: 40n, // scaled to use the XEC
|
|
111
|
+
makerPk: makerPk,
|
|
112
|
+
minAcceptedTokens: 0xffffffffffffn,
|
|
113
|
+
...BASE_PARAMS_SLP,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(agoraPartial).to.deep.equal(
|
|
117
|
+
new AgoraPartial({
|
|
118
|
+
truncTokens: 0xffffffn,
|
|
119
|
+
numTokenTruncBytes: 5,
|
|
120
|
+
tokenScaleFactor: 127n,
|
|
121
|
+
scaledTruncTokensPerTruncSat: 189n,
|
|
122
|
+
numSatsTruncBytes: 2,
|
|
123
|
+
makerPk,
|
|
124
|
+
minAcceptedScaledTruncTokens: 32511n,
|
|
125
|
+
...BASE_PARAMS_SLP,
|
|
126
|
+
scriptLen: 216,
|
|
127
|
+
}),
|
|
128
|
+
);
|
|
129
|
+
expect(agoraPartial.offeredTokens()).to.equal(0xffffff0000000000n);
|
|
130
|
+
expect(agoraPartial.askedSats(0x10000000000n)).to.equal(65536n);
|
|
131
|
+
expect(agoraPartial.priceNanoSatsPerToken(0x10000000000n)).to.equal(
|
|
132
|
+
59n,
|
|
133
|
+
);
|
|
134
|
+
expect(agoraPartial.askedSats(0xffffff0000000000n)).to.equal(
|
|
135
|
+
738825273344n,
|
|
136
|
+
);
|
|
137
|
+
expect(
|
|
138
|
+
agoraPartial.priceNanoSatsPerToken(0xffffff0000000000n),
|
|
139
|
+
).to.equal(40n);
|
|
140
|
+
expect(agoraPartial.priceNanoSatsPerToken()).to.equal(40n);
|
|
141
|
+
|
|
142
|
+
const offer = await makeSlpOffer({
|
|
143
|
+
chronik,
|
|
144
|
+
ecc,
|
|
145
|
+
agoraPartial,
|
|
146
|
+
makerSk,
|
|
147
|
+
fuelInput,
|
|
148
|
+
});
|
|
149
|
+
const acceptTxid = await takeSlpOffer({
|
|
150
|
+
chronik,
|
|
151
|
+
ecc,
|
|
152
|
+
offer,
|
|
153
|
+
takerSk,
|
|
154
|
+
takerInput,
|
|
155
|
+
acceptedTokens: agoraPartial.offeredTokens(),
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
159
|
+
// 0th output is OP_RETURN SLP SEND
|
|
160
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
161
|
+
toHex(
|
|
162
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [
|
|
163
|
+
0,
|
|
164
|
+
agoraPartial.offeredTokens(),
|
|
165
|
+
]).bytecode,
|
|
166
|
+
),
|
|
167
|
+
);
|
|
168
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
169
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
170
|
+
// 1st output is sats to maker
|
|
171
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
172
|
+
expect(acceptTx.outputs[1].value).to.equal(738825273344);
|
|
173
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
174
|
+
// 2nd output is tokens to taker
|
|
175
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal(
|
|
176
|
+
0xffffff0000000000n.toString(),
|
|
177
|
+
);
|
|
178
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
179
|
+
expect(acceptTx.outputs[2].outputScript).to.equal(takerScriptHex);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('Agora Partial 7450M XEC vs 2p64-1 small accept', () => {
|
|
184
|
+
let runner: TestRunner;
|
|
185
|
+
let chronik: ChronikClient;
|
|
186
|
+
let ecc: Ecc;
|
|
187
|
+
|
|
188
|
+
before(async () => {
|
|
189
|
+
await initWasm();
|
|
190
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
191
|
+
chronik = runner.chronik;
|
|
192
|
+
ecc = runner.ecc;
|
|
193
|
+
initKeys(ecc);
|
|
194
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
after(() => {
|
|
198
|
+
runner.stop();
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('Agora Partial 7450M XEC vs 2p64-1 small accept', async () => {
|
|
202
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
203
|
+
10000,
|
|
204
|
+
BIGSATS,
|
|
205
|
+
]);
|
|
206
|
+
|
|
207
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
208
|
+
offeredTokens: 0xffffffffffffffffn,
|
|
209
|
+
priceNanoSatsPerToken: 500000000n, // scaled to use the XEC
|
|
210
|
+
makerPk,
|
|
211
|
+
minAcceptedTokens: 0xffffffffffn,
|
|
212
|
+
...BASE_PARAMS_SLP,
|
|
213
|
+
});
|
|
214
|
+
expect(agoraPartial).to.deep.equal(
|
|
215
|
+
new AgoraPartial({
|
|
216
|
+
truncTokens: 0xffffffn,
|
|
217
|
+
numTokenTruncBytes: 5,
|
|
218
|
+
tokenScaleFactor: 128n,
|
|
219
|
+
scaledTruncTokensPerTruncSat: 1n,
|
|
220
|
+
numSatsTruncBytes: 4,
|
|
221
|
+
makerPk,
|
|
222
|
+
minAcceptedScaledTruncTokens: 0x7fn,
|
|
223
|
+
...BASE_PARAMS_SLP,
|
|
224
|
+
scriptLen: 216,
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
expect(agoraPartial.offeredTokens()).to.equal(0xffffff0000000000n);
|
|
228
|
+
expect(agoraPartial.askedSats(0x10000000000n)).to.equal(549755813888n);
|
|
229
|
+
expect(agoraPartial.priceNanoSatsPerToken(0x10000000000n)).to.equal(
|
|
230
|
+
500000000n,
|
|
231
|
+
);
|
|
232
|
+
expect(agoraPartial.askedSats(0xffffff0000000000n)).to.equal(
|
|
233
|
+
9223371487098961920n,
|
|
234
|
+
);
|
|
235
|
+
expect(
|
|
236
|
+
agoraPartial.priceNanoSatsPerToken(0xffffff0000000000n),
|
|
237
|
+
).to.equal(500000000n);
|
|
238
|
+
expect(agoraPartial.priceNanoSatsPerToken()).to.equal(500000000n);
|
|
239
|
+
|
|
240
|
+
const offer = await makeSlpOffer({
|
|
241
|
+
chronik,
|
|
242
|
+
ecc,
|
|
243
|
+
agoraPartial,
|
|
244
|
+
makerSk,
|
|
245
|
+
fuelInput,
|
|
246
|
+
});
|
|
247
|
+
const acceptedTokens = 0x10000000000n;
|
|
248
|
+
const acceptTxid = await takeSlpOffer({
|
|
249
|
+
chronik,
|
|
250
|
+
ecc,
|
|
251
|
+
offer,
|
|
252
|
+
takerSk,
|
|
253
|
+
takerInput,
|
|
254
|
+
acceptedTokens,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
258
|
+
|
|
259
|
+
// 0th output is OP_RETURN SLP SEND
|
|
260
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
261
|
+
toHex(
|
|
262
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [
|
|
263
|
+
0,
|
|
264
|
+
agoraPartial.offeredTokens() - acceptedTokens,
|
|
265
|
+
acceptedTokens,
|
|
266
|
+
]).bytecode,
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
270
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
271
|
+
// 1st output is sats to maker
|
|
272
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
273
|
+
expect(acceptTx.outputs[1].value).to.equal(549755813888);
|
|
274
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
275
|
+
// 2nd output is back to the P2SH Script
|
|
276
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal(
|
|
277
|
+
(agoraPartial.offeredTokens() - acceptedTokens).toString(),
|
|
278
|
+
);
|
|
279
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
280
|
+
expect(acceptTx.outputs[2].outputScript.slice(0, 4)).to.equal('a914');
|
|
281
|
+
// 3rd output is tokens to taker
|
|
282
|
+
expect(acceptTx.outputs[3].token?.amount).to.equal(
|
|
283
|
+
acceptedTokens.toString(),
|
|
284
|
+
);
|
|
285
|
+
expect(acceptTx.outputs[3].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
286
|
+
expect(acceptTx.outputs[3].outputScript).to.equal(takerScriptHex);
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
describe('Agora Partial 7450M XEC vs 2p63-1 full accept', () => {
|
|
291
|
+
let runner: TestRunner;
|
|
292
|
+
let chronik: ChronikClient;
|
|
293
|
+
let ecc: Ecc;
|
|
294
|
+
|
|
295
|
+
before(async () => {
|
|
296
|
+
await initWasm();
|
|
297
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
298
|
+
chronik = runner.chronik;
|
|
299
|
+
ecc = runner.ecc;
|
|
300
|
+
initKeys(ecc);
|
|
301
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
after(() => {
|
|
305
|
+
runner.stop();
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('Agora Partial 7450M XEC vs 2p63-1 full accept', async () => {
|
|
309
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
310
|
+
10000,
|
|
311
|
+
BIGSATS,
|
|
312
|
+
]);
|
|
313
|
+
|
|
314
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
315
|
+
offeredTokens: 0x7fffffffffffffffn,
|
|
316
|
+
priceNanoSatsPerToken: 80n, // scaled to use the XEC
|
|
317
|
+
makerPk: makerPk,
|
|
318
|
+
minAcceptedTokens: 0xffffffffffffn,
|
|
319
|
+
...BASE_PARAMS_SLP,
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
expect(agoraPartial).to.deep.equal(
|
|
323
|
+
new AgoraPartial({
|
|
324
|
+
truncTokens: 0x7fffff42n,
|
|
325
|
+
numTokenTruncBytes: 4,
|
|
326
|
+
tokenScaleFactor: 1n,
|
|
327
|
+
scaledTruncTokensPerTruncSat: 190n,
|
|
328
|
+
numSatsTruncBytes: 2,
|
|
329
|
+
makerPk,
|
|
330
|
+
minAcceptedScaledTruncTokens: 0xffffn,
|
|
331
|
+
...BASE_PARAMS_SLP,
|
|
332
|
+
scriptLen: 206,
|
|
333
|
+
}),
|
|
334
|
+
);
|
|
335
|
+
expect(agoraPartial.offeredTokens()).to.equal(0x7fffff4200000000n);
|
|
336
|
+
expect(agoraPartial.askedSats(0x100000000n)).to.equal(65536n);
|
|
337
|
+
expect(agoraPartial.priceNanoSatsPerToken(0x100000000n)).to.equal(
|
|
338
|
+
15258n,
|
|
339
|
+
);
|
|
340
|
+
expect(agoraPartial.askedSats(0x7fffff4200000000n)).to.equal(
|
|
341
|
+
740723589120n,
|
|
342
|
+
);
|
|
343
|
+
expect(
|
|
344
|
+
agoraPartial.priceNanoSatsPerToken(0x7fffff4200000000n),
|
|
345
|
+
).to.equal(80n);
|
|
346
|
+
expect(agoraPartial.priceNanoSatsPerToken()).to.equal(80n);
|
|
347
|
+
|
|
348
|
+
const offer = await makeSlpOffer({
|
|
349
|
+
chronik,
|
|
350
|
+
ecc,
|
|
351
|
+
agoraPartial,
|
|
352
|
+
makerSk,
|
|
353
|
+
fuelInput,
|
|
354
|
+
});
|
|
355
|
+
const acceptedTokens = agoraPartial.offeredTokens();
|
|
356
|
+
const acceptTxid = await takeSlpOffer({
|
|
357
|
+
chronik,
|
|
358
|
+
ecc,
|
|
359
|
+
offer,
|
|
360
|
+
takerSk,
|
|
361
|
+
takerInput,
|
|
362
|
+
acceptedTokens,
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
366
|
+
|
|
367
|
+
// 0th output is OP_RETURN SLP SEND
|
|
368
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
369
|
+
toHex(
|
|
370
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [
|
|
371
|
+
0,
|
|
372
|
+
acceptedTokens,
|
|
373
|
+
]).bytecode,
|
|
374
|
+
),
|
|
375
|
+
);
|
|
376
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
377
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
378
|
+
// 1st output is sats to maker
|
|
379
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
380
|
+
expect(acceptTx.outputs[1].value).to.equal(740723589120);
|
|
381
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
382
|
+
// 2nd output is tokens to taker
|
|
383
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal(
|
|
384
|
+
acceptedTokens.toString(),
|
|
385
|
+
);
|
|
386
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
387
|
+
expect(acceptTx.outputs[2].outputScript).to.equal(takerScriptHex);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
describe('Agora Partial 7450M XEC vs 2p63-1 small accept', () => {
|
|
392
|
+
let runner: TestRunner;
|
|
393
|
+
let chronik: ChronikClient;
|
|
394
|
+
let ecc: Ecc;
|
|
395
|
+
|
|
396
|
+
before(async () => {
|
|
397
|
+
await initWasm();
|
|
398
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
399
|
+
chronik = runner.chronik;
|
|
400
|
+
ecc = runner.ecc;
|
|
401
|
+
initKeys(ecc);
|
|
402
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
after(() => {
|
|
406
|
+
runner.stop();
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('Agora Partial 7450M XEC vs 2p63-1 small accept', async () => {
|
|
410
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
411
|
+
10000,
|
|
412
|
+
BIGSATS,
|
|
413
|
+
]);
|
|
414
|
+
|
|
415
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
416
|
+
offeredTokens: 0x7fffffffffffffffn,
|
|
417
|
+
priceNanoSatsPerToken: 1000000000n,
|
|
418
|
+
makerPk,
|
|
419
|
+
minAcceptedTokens: 0x100000000n,
|
|
420
|
+
...BASE_PARAMS_SLP,
|
|
421
|
+
});
|
|
422
|
+
expect(agoraPartial).to.deep.equal(
|
|
423
|
+
new AgoraPartial({
|
|
424
|
+
truncTokens: 0x7fffffffn,
|
|
425
|
+
numTokenTruncBytes: 4,
|
|
426
|
+
tokenScaleFactor: 1n,
|
|
427
|
+
scaledTruncTokensPerTruncSat: 1n,
|
|
428
|
+
numSatsTruncBytes: 4,
|
|
429
|
+
makerPk,
|
|
430
|
+
minAcceptedScaledTruncTokens: 1n,
|
|
431
|
+
...BASE_PARAMS_SLP,
|
|
432
|
+
scriptLen: 201,
|
|
433
|
+
}),
|
|
434
|
+
);
|
|
435
|
+
expect(agoraPartial.offeredTokens()).to.equal(0x7fffffff00000000n);
|
|
436
|
+
expect(agoraPartial.askedSats(0x100000000n)).to.equal(4294967296n);
|
|
437
|
+
expect(agoraPartial.priceNanoSatsPerToken(0x100000000n)).to.equal(
|
|
438
|
+
1000000000n,
|
|
439
|
+
);
|
|
440
|
+
expect(agoraPartial.askedSats(0x7fffffff00000000n)).to.equal(
|
|
441
|
+
9223372032559808512n,
|
|
442
|
+
);
|
|
443
|
+
expect(
|
|
444
|
+
agoraPartial.priceNanoSatsPerToken(0x7fffffff00000000n),
|
|
445
|
+
).to.equal(1000000000n);
|
|
446
|
+
expect(agoraPartial.priceNanoSatsPerToken()).to.equal(1000000000n);
|
|
447
|
+
|
|
448
|
+
const offer = await makeSlpOffer({
|
|
449
|
+
chronik,
|
|
450
|
+
ecc,
|
|
451
|
+
agoraPartial,
|
|
452
|
+
makerSk,
|
|
453
|
+
fuelInput,
|
|
454
|
+
});
|
|
455
|
+
const acceptedTokens = 0x100000000n;
|
|
456
|
+
const acceptTxid = await takeSlpOffer({
|
|
457
|
+
chronik,
|
|
458
|
+
ecc,
|
|
459
|
+
offer,
|
|
460
|
+
takerSk,
|
|
461
|
+
takerInput,
|
|
462
|
+
acceptedTokens,
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
466
|
+
|
|
467
|
+
// 0th output is OP_RETURN SLP SEND
|
|
468
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
469
|
+
toHex(
|
|
470
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [
|
|
471
|
+
0,
|
|
472
|
+
agoraPartial.offeredTokens() - acceptedTokens,
|
|
473
|
+
acceptedTokens,
|
|
474
|
+
]).bytecode,
|
|
475
|
+
),
|
|
476
|
+
);
|
|
477
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
478
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
479
|
+
// 1st output is sats to maker
|
|
480
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
481
|
+
expect(acceptTx.outputs[1].value).to.equal(4294967296);
|
|
482
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
483
|
+
// 2nd output is back to the P2SH Script
|
|
484
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal(
|
|
485
|
+
(agoraPartial.offeredTokens() - acceptedTokens).toString(),
|
|
486
|
+
);
|
|
487
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
488
|
+
expect(acceptTx.outputs[2].outputScript.slice(0, 4)).to.equal('a914');
|
|
489
|
+
// 3rd output is tokens to taker
|
|
490
|
+
expect(acceptTx.outputs[3].token?.amount).to.equal(
|
|
491
|
+
acceptedTokens.toString(),
|
|
492
|
+
);
|
|
493
|
+
expect(acceptTx.outputs[3].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
494
|
+
expect(acceptTx.outputs[3].outputScript).to.equal(takerScriptHex);
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
describe('Agora Partial 7450M XEC vs 100 full accept', () => {
|
|
499
|
+
let runner: TestRunner;
|
|
500
|
+
let chronik: ChronikClient;
|
|
501
|
+
let ecc: Ecc;
|
|
502
|
+
|
|
503
|
+
before(async () => {
|
|
504
|
+
await initWasm();
|
|
505
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
506
|
+
chronik = runner.chronik;
|
|
507
|
+
ecc = runner.ecc;
|
|
508
|
+
initKeys(ecc);
|
|
509
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
after(() => {
|
|
513
|
+
runner.stop();
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it('Agora Partial 7450M XEC vs 100 full accept', async () => {
|
|
517
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
518
|
+
10000,
|
|
519
|
+
BIGSATS,
|
|
520
|
+
]);
|
|
521
|
+
|
|
522
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
523
|
+
offeredTokens: 100n,
|
|
524
|
+
priceNanoSatsPerToken: 7123456780n * 1000000000n, // scaled to use the XEC
|
|
525
|
+
makerPk: makerPk,
|
|
526
|
+
minAcceptedTokens: 1n,
|
|
527
|
+
...BASE_PARAMS_SLP,
|
|
528
|
+
});
|
|
529
|
+
expect(agoraPartial).to.deep.equal(
|
|
530
|
+
new AgoraPartial({
|
|
531
|
+
truncTokens: 100n,
|
|
532
|
+
numTokenTruncBytes: 0,
|
|
533
|
+
tokenScaleFactor: 0x7fff3a28n / 100n,
|
|
534
|
+
scaledTruncTokensPerTruncSat: 50576n,
|
|
535
|
+
numSatsTruncBytes: 3,
|
|
536
|
+
makerPk,
|
|
537
|
+
minAcceptedScaledTruncTokens: 0x7fff3a28n / 100n,
|
|
538
|
+
...BASE_PARAMS_SLP,
|
|
539
|
+
scriptLen: 214,
|
|
540
|
+
}),
|
|
541
|
+
);
|
|
542
|
+
expect(agoraPartial.offeredTokens()).to.equal(100n);
|
|
543
|
+
expect(agoraPartial.minAcceptedTokens()).to.equal(1n);
|
|
544
|
+
expect(agoraPartial.askedSats(1n)).to.equal(7130316800n);
|
|
545
|
+
expect(agoraPartial.askedSats(2n)).to.equal(7130316800n * 2n);
|
|
546
|
+
expect(agoraPartial.askedSats(3n)).to.equal(7124724394n * 3n + 2n);
|
|
547
|
+
expect(agoraPartial.askedSats(4n)).to.equal(7126122496n * 4n);
|
|
548
|
+
expect(agoraPartial.askedSats(5n)).to.equal(71236059136n / 2n);
|
|
549
|
+
expect(agoraPartial.askedSats(10n)).to.equal(71236059136n);
|
|
550
|
+
expect(agoraPartial.askedSats(100n)).to.equal(712360591360n);
|
|
551
|
+
|
|
552
|
+
const offer = await makeSlpOffer({
|
|
553
|
+
chronik,
|
|
554
|
+
ecc,
|
|
555
|
+
agoraPartial,
|
|
556
|
+
makerSk,
|
|
557
|
+
fuelInput,
|
|
558
|
+
});
|
|
559
|
+
const acceptTxid = await takeSlpOffer({
|
|
560
|
+
chronik,
|
|
561
|
+
ecc,
|
|
562
|
+
offer,
|
|
563
|
+
takerSk,
|
|
564
|
+
takerInput,
|
|
565
|
+
acceptedTokens: 100n,
|
|
566
|
+
});
|
|
567
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
568
|
+
|
|
569
|
+
// 0th output is OP_RETURN SLP SEND
|
|
570
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
571
|
+
toHex(
|
|
572
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [0, 100n])
|
|
573
|
+
.bytecode,
|
|
574
|
+
),
|
|
575
|
+
);
|
|
576
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
577
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
578
|
+
// 1st output is sats to maker
|
|
579
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
580
|
+
expect(acceptTx.outputs[1].value).to.equal(712360591360);
|
|
581
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
582
|
+
// 2nd output is tokens to taker
|
|
583
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal('100');
|
|
584
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
585
|
+
expect(acceptTx.outputs[2].outputScript).to.equal(takerScriptHex);
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
describe('Agora Partial 7450M XEC vs 100 small accept', () => {
|
|
590
|
+
let runner: TestRunner;
|
|
591
|
+
let chronik: ChronikClient;
|
|
592
|
+
let ecc: Ecc;
|
|
593
|
+
|
|
594
|
+
before(async () => {
|
|
595
|
+
await initWasm();
|
|
596
|
+
runner = await TestRunner.setup('setup_scripts/ecash-agora_base');
|
|
597
|
+
chronik = runner.chronik;
|
|
598
|
+
ecc = runner.ecc;
|
|
599
|
+
initKeys(ecc);
|
|
600
|
+
await runner.setupCoins(1, BIGSATS + 11000);
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
after(() => {
|
|
604
|
+
runner.stop();
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it('Agora Partial 7450M XEC vs 100 small accept', async () => {
|
|
608
|
+
const [fuelInput, takerInput] = await makeBuilderInputs(runner, [
|
|
609
|
+
10000,
|
|
610
|
+
BIGSATS,
|
|
611
|
+
]);
|
|
612
|
+
|
|
613
|
+
const agoraPartial = AgoraPartial.approximateParams({
|
|
614
|
+
offeredTokens: 100n,
|
|
615
|
+
priceNanoSatsPerToken: 712345678000n * 1000000000n, // scaled to use the XEC
|
|
616
|
+
makerPk: makerPk,
|
|
617
|
+
minAcceptedTokens: 1n,
|
|
618
|
+
...BASE_PARAMS_SLP,
|
|
619
|
+
});
|
|
620
|
+
expect(agoraPartial).to.deep.equal(
|
|
621
|
+
new AgoraPartial({
|
|
622
|
+
truncTokens: 100n,
|
|
623
|
+
numTokenTruncBytes: 0,
|
|
624
|
+
tokenScaleFactor: 0x7ffe05f4n / 100n,
|
|
625
|
+
scaledTruncTokensPerTruncSat: 129471n,
|
|
626
|
+
numSatsTruncBytes: 4,
|
|
627
|
+
makerPk,
|
|
628
|
+
minAcceptedScaledTruncTokens: 0x7ffe05f4n / 100n,
|
|
629
|
+
...BASE_PARAMS_SLP,
|
|
630
|
+
scriptLen: 215,
|
|
631
|
+
}),
|
|
632
|
+
);
|
|
633
|
+
expect(agoraPartial.offeredTokens()).to.equal(100n);
|
|
634
|
+
expect(agoraPartial.minAcceptedTokens()).to.equal(1n);
|
|
635
|
+
expect(agoraPartial.askedSats(1n)).to.equal(712964571136n);
|
|
636
|
+
expect(agoraPartial.askedSats(10n)).to.equal(7125350744064n);
|
|
637
|
+
expect(agoraPartial.askedSats(100n)).to.equal(71236327571456n);
|
|
638
|
+
|
|
639
|
+
const offer = await makeSlpOffer({
|
|
640
|
+
chronik,
|
|
641
|
+
ecc,
|
|
642
|
+
agoraPartial,
|
|
643
|
+
makerSk,
|
|
644
|
+
fuelInput,
|
|
645
|
+
});
|
|
646
|
+
const acceptTxid = await takeSlpOffer({
|
|
647
|
+
chronik,
|
|
648
|
+
ecc,
|
|
649
|
+
offer,
|
|
650
|
+
takerSk,
|
|
651
|
+
takerInput,
|
|
652
|
+
acceptedTokens: 1n,
|
|
653
|
+
});
|
|
654
|
+
const acceptTx = await chronik.tx(acceptTxid);
|
|
655
|
+
|
|
656
|
+
// 0th output is OP_RETURN SLP SEND
|
|
657
|
+
expect(acceptTx.outputs[0].outputScript).to.equal(
|
|
658
|
+
toHex(
|
|
659
|
+
slpSend(agoraPartial.tokenId, agoraPartial.tokenType, [
|
|
660
|
+
0,
|
|
661
|
+
99n,
|
|
662
|
+
1n,
|
|
663
|
+
]).bytecode,
|
|
664
|
+
),
|
|
665
|
+
);
|
|
666
|
+
expect(acceptTx.outputs[0].value).to.equal(0);
|
|
667
|
+
expect(acceptTx.outputs[0].token).to.equal(undefined);
|
|
668
|
+
// 1st output is sats to maker
|
|
669
|
+
expect(acceptTx.outputs[1].token).to.equal(undefined);
|
|
670
|
+
expect(acceptTx.outputs[1].value).to.equal(712964571136);
|
|
671
|
+
expect(acceptTx.outputs[1].outputScript).to.equal(makerScriptHex);
|
|
672
|
+
// 2nd output is back to the P2SH Script
|
|
673
|
+
expect(acceptTx.outputs[2].token?.amount).to.equal('99');
|
|
674
|
+
expect(acceptTx.outputs[2].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
675
|
+
expect(acceptTx.outputs[2].outputScript.slice(0, 4)).to.equal('a914');
|
|
676
|
+
// 3rd output is tokens to taker
|
|
677
|
+
expect(acceptTx.outputs[3].token?.amount).to.equal('1');
|
|
678
|
+
expect(acceptTx.outputs[3].value).to.equal(DEFAULT_DUST_LIMIT);
|
|
679
|
+
expect(acceptTx.outputs[3].outputScript).to.equal(takerScriptHex);
|
|
680
|
+
});
|
|
681
|
+
});
|