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