@atomicfinance/bitcoin-dlc-provider 2.4.2 → 3.0.0
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/.turbo/turbo-build.log +1 -0
- package/.turbo/turbo-lint.log +1 -0
- package/.turbo/turbo-lint:fix.log +20 -0
- package/.turbo/turbo-test.log +1 -0
- package/CHANGELOG.md +25 -0
- package/dist/BitcoinDlcProvider.d.ts +4 -2
- package/dist/BitcoinDlcProvider.js +99 -12
- package/dist/BitcoinDlcProvider.js.map +1 -1
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -0
- package/dist/index.js.map +0 -0
- package/dist/utils/Utils.d.ts +0 -0
- package/dist/utils/Utils.js +0 -0
- package/dist/utils/Utils.js.map +0 -0
- package/lib/BitcoinDlcProvider.ts +198 -21
- package/package.json +12 -15
- package/LICENSE +0 -674
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { chainHashFromNetwork } from '@atomicfinance/bitcoin-networks';
|
|
2
1
|
import Provider from '@atomicfinance/provider';
|
|
3
2
|
import {
|
|
4
3
|
AdaptorPair,
|
|
4
|
+
Address,
|
|
5
5
|
AddSignaturesToRefundTxRequest,
|
|
6
6
|
AddSignaturesToRefundTxResponse,
|
|
7
7
|
AddSignatureToFundTransactionRequest,
|
|
8
8
|
AddSignatureToFundTransactionResponse,
|
|
9
|
+
bitcoin,
|
|
9
10
|
CalculateEcSignatureRequest,
|
|
10
11
|
CreateCetAdaptorSignatureRequest,
|
|
11
12
|
CreateCetAdaptorSignatureResponse,
|
|
@@ -44,14 +45,13 @@ import {
|
|
|
44
45
|
VerifyRefundTxSignatureResponse,
|
|
45
46
|
VerifySignatureRequest,
|
|
46
47
|
} from '@atomicfinance/types';
|
|
47
|
-
import {
|
|
48
|
-
import { Address, bitcoin } from '@liquality/types';
|
|
49
|
-
import { sleep } from '@liquality/utils';
|
|
48
|
+
import { sleep } from '@atomicfinance/utils';
|
|
50
49
|
import {
|
|
51
50
|
DualClosingTxFinalizer,
|
|
52
51
|
DualFundingTxFinalizer,
|
|
53
52
|
groupByIgnoringDigits,
|
|
54
53
|
HyperbolaPayoutCurve,
|
|
54
|
+
PolynomialPayoutCurve,
|
|
55
55
|
roundPayout,
|
|
56
56
|
} from '@node-dlc/core';
|
|
57
57
|
import {
|
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
OracleEventV0,
|
|
84
84
|
OracleInfoV0,
|
|
85
85
|
PayoutFunctionV0,
|
|
86
|
+
PolynomialPayoutCurvePiece,
|
|
86
87
|
ScriptWitnessV0,
|
|
87
88
|
} from '@node-dlc/messaging';
|
|
88
89
|
import { Script, Sequence, Tx } from '@node-lightning/bitcoin';
|
|
@@ -90,6 +91,7 @@ import { StreamReader } from '@node-lightning/bufio';
|
|
|
90
91
|
import { hash160, sha256, xor } from '@node-lightning/crypto';
|
|
91
92
|
import assert from 'assert';
|
|
92
93
|
import BigNumber from 'bignumber.js';
|
|
94
|
+
import { BitcoinNetwork, chainHashFromNetwork } from 'bitcoin-networks';
|
|
93
95
|
import {
|
|
94
96
|
address,
|
|
95
97
|
ECPairInterface,
|
|
@@ -316,6 +318,66 @@ export default class BitcoinDlcProvider
|
|
|
316
318
|
return { payouts, payoutGroups, messagesList };
|
|
317
319
|
}
|
|
318
320
|
|
|
321
|
+
private GetPayoutsFromPolynomialPayoutFunction(
|
|
322
|
+
_dlcOffer: DlcOffer,
|
|
323
|
+
contractDescriptor: ContractDescriptorV1,
|
|
324
|
+
oracleInfo: OracleInfoV0,
|
|
325
|
+
totalCollateral: bigint,
|
|
326
|
+
): GetPayoutsResponse {
|
|
327
|
+
if (_dlcOffer.type !== MessageType.DlcOfferV0)
|
|
328
|
+
throw Error('DlcOffer must be V0');
|
|
329
|
+
const dlcOffer = _dlcOffer as DlcOfferV0;
|
|
330
|
+
if (contractDescriptor.payoutFunction.type !== MessageType.PayoutFunctionV0)
|
|
331
|
+
throw Error('PayoutFunction must be V0');
|
|
332
|
+
const payoutFunction = contractDescriptor.payoutFunction as PayoutFunctionV0;
|
|
333
|
+
if (payoutFunction.pieces.length === 0)
|
|
334
|
+
throw Error('PayoutFunction must have at least once PayoutCurvePiece');
|
|
335
|
+
for (const piece of payoutFunction.pieces) {
|
|
336
|
+
if (
|
|
337
|
+
piece.payoutCurvePiece.type !== MessageType.PolynomialPayoutCurvePiece
|
|
338
|
+
)
|
|
339
|
+
throw Error('Must be PolynomialPayoutCurvePiece');
|
|
340
|
+
}
|
|
341
|
+
const eventDescriptor = oracleInfo.announcement.oracleEvent
|
|
342
|
+
.eventDescriptor as DigitDecompositionEventDescriptorV0;
|
|
343
|
+
if (
|
|
344
|
+
eventDescriptor.type !== MessageType.DigitDecompositionEventDescriptorV0
|
|
345
|
+
)
|
|
346
|
+
throw Error('Only DigitDecomposition Oracle Events supported');
|
|
347
|
+
|
|
348
|
+
const roundingIntervals = contractDescriptor.roundingIntervals;
|
|
349
|
+
const cetPayouts = PolynomialPayoutCurve.computePayouts(
|
|
350
|
+
payoutFunction,
|
|
351
|
+
totalCollateral,
|
|
352
|
+
roundingIntervals,
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
const payoutGroups: PayoutGroup[] = [];
|
|
356
|
+
cetPayouts.forEach((p) => {
|
|
357
|
+
payoutGroups.push({
|
|
358
|
+
payout: p.payout,
|
|
359
|
+
groups: groupByIgnoringDigits(
|
|
360
|
+
p.indexFrom,
|
|
361
|
+
p.indexTo,
|
|
362
|
+
eventDescriptor.base,
|
|
363
|
+
contractDescriptor.numDigits,
|
|
364
|
+
),
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
const rValuesMessagesList = this.GenerateMessages(oracleInfo);
|
|
369
|
+
|
|
370
|
+
const { payouts, messagesList } = outputsToPayouts(
|
|
371
|
+
payoutGroups,
|
|
372
|
+
rValuesMessagesList,
|
|
373
|
+
dlcOffer.offerCollateralSatoshis,
|
|
374
|
+
dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis,
|
|
375
|
+
true,
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
return { payouts, payoutGroups, messagesList };
|
|
379
|
+
}
|
|
380
|
+
|
|
319
381
|
private GetPayouts(_dlcOffer: DlcOffer): GetPayoutsResponse[] {
|
|
320
382
|
const { dlcOffer } = checkTypes({ _dlcOffer });
|
|
321
383
|
|
|
@@ -371,18 +433,45 @@ export default class BitcoinDlcProvider
|
|
|
371
433
|
totalCollateral: bigint,
|
|
372
434
|
) {
|
|
373
435
|
switch (contractDescriptor.type) {
|
|
374
|
-
case MessageType.ContractDescriptorV0:
|
|
436
|
+
case MessageType.ContractDescriptorV0: {
|
|
375
437
|
throw Error('ContractDescriptorV0 not yet supported');
|
|
438
|
+
}
|
|
376
439
|
case MessageType.ContractDescriptorV1:
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
440
|
+
{
|
|
441
|
+
const contractDescriptorV1 = contractDescriptor as ContractDescriptorV1;
|
|
442
|
+
const payoutFunction = contractDescriptorV1.payoutFunction as PayoutFunctionV0;
|
|
443
|
+
|
|
444
|
+
// TODO: add a better check for this
|
|
445
|
+
const payoutCurvePiece = payoutFunction.pieces[0].payoutCurvePiece;
|
|
446
|
+
|
|
447
|
+
switch (payoutCurvePiece.type) {
|
|
448
|
+
case MessageType.HyperbolaPayoutCurvePiece:
|
|
449
|
+
return this.GetPayoutsFromPayoutFunction(
|
|
450
|
+
dlcOffer,
|
|
451
|
+
contractDescriptor as ContractDescriptorV1,
|
|
452
|
+
oracleInfo,
|
|
453
|
+
totalCollateral,
|
|
454
|
+
);
|
|
455
|
+
case MessageType.OldHyperbolaPayoutCurvePiece:
|
|
456
|
+
return this.GetPayoutsFromPayoutFunction(
|
|
457
|
+
dlcOffer,
|
|
458
|
+
contractDescriptor as ContractDescriptorV1,
|
|
459
|
+
oracleInfo,
|
|
460
|
+
totalCollateral,
|
|
461
|
+
);
|
|
462
|
+
case MessageType.PolynomialPayoutCurvePiece:
|
|
463
|
+
return this.GetPayoutsFromPolynomialPayoutFunction(
|
|
464
|
+
dlcOffer,
|
|
465
|
+
contractDescriptor as ContractDescriptorV1,
|
|
466
|
+
oracleInfo,
|
|
467
|
+
totalCollateral,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
break;
|
|
472
|
+
default: {
|
|
385
473
|
throw Error('ContractDescriptor must be V0 or V1');
|
|
474
|
+
}
|
|
386
475
|
}
|
|
387
476
|
}
|
|
388
477
|
|
|
@@ -558,7 +647,7 @@ export default class BitcoinDlcProvider
|
|
|
558
647
|
network,
|
|
559
648
|
);
|
|
560
649
|
|
|
561
|
-
const { derivationPath } = await this.
|
|
650
|
+
const { derivationPath } = await this.client.wallet.findAddress([
|
|
562
651
|
fundingAddress,
|
|
563
652
|
]);
|
|
564
653
|
|
|
@@ -922,6 +1011,84 @@ export default class BitcoinDlcProvider
|
|
|
922
1011
|
return fundTx;
|
|
923
1012
|
}
|
|
924
1013
|
|
|
1014
|
+
async FindOutcomeIndexFromPolynomialPayoutCurvePiece(
|
|
1015
|
+
_dlcOffer: DlcOffer,
|
|
1016
|
+
contractDescriptor: ContractDescriptorV1,
|
|
1017
|
+
contractOraclePairIndex: number,
|
|
1018
|
+
polynomialPayoutCurvePiece: PolynomialPayoutCurvePiece,
|
|
1019
|
+
oracleAttestation: OracleAttestationV0,
|
|
1020
|
+
outcome: bigint,
|
|
1021
|
+
): Promise<FindOutcomeResponse> {
|
|
1022
|
+
const { dlcOffer } = checkTypes({ _dlcOffer });
|
|
1023
|
+
|
|
1024
|
+
const polynomialCurve = PolynomialPayoutCurve.fromPayoutCurvePiece(
|
|
1025
|
+
polynomialPayoutCurvePiece,
|
|
1026
|
+
);
|
|
1027
|
+
|
|
1028
|
+
const clampBN = (val: BigNumber) =>
|
|
1029
|
+
BigNumber.max(
|
|
1030
|
+
0,
|
|
1031
|
+
BigNumber.min(val, dlcOffer.contractInfo.totalCollateral.toString()),
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
const payout = clampBN(polynomialCurve.getPayout(outcome));
|
|
1035
|
+
|
|
1036
|
+
const payoutResponses = this.GetPayouts(dlcOffer);
|
|
1037
|
+
const payoutIndexOffset = this.GetIndicesFromPayouts(payoutResponses)[
|
|
1038
|
+
contractOraclePairIndex
|
|
1039
|
+
].startingMessagesIndex;
|
|
1040
|
+
|
|
1041
|
+
const { payoutGroups } = payoutResponses[contractOraclePairIndex];
|
|
1042
|
+
|
|
1043
|
+
const intervalsSorted = [
|
|
1044
|
+
...contractDescriptor.roundingIntervals.intervals,
|
|
1045
|
+
].sort((a, b) => Number(b.beginInterval) - Number(a.beginInterval));
|
|
1046
|
+
|
|
1047
|
+
const interval = intervalsSorted.find(
|
|
1048
|
+
(interval) => Number(outcome) >= Number(interval.beginInterval),
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
const roundedPayout = BigInt(
|
|
1052
|
+
clampBN(
|
|
1053
|
+
new BigNumber(roundPayout(payout, interval.roundingMod).toString()),
|
|
1054
|
+
).toString(),
|
|
1055
|
+
);
|
|
1056
|
+
|
|
1057
|
+
const outcomesFormatted = oracleAttestation.outcomes.map((outcome) =>
|
|
1058
|
+
parseInt(outcome),
|
|
1059
|
+
);
|
|
1060
|
+
|
|
1061
|
+
let index = 0;
|
|
1062
|
+
let groupIndex = -1;
|
|
1063
|
+
let groupLength = 0;
|
|
1064
|
+
|
|
1065
|
+
for (const payoutGroup of payoutGroups) {
|
|
1066
|
+
if (payoutGroup.payout === roundedPayout) {
|
|
1067
|
+
groupIndex = payoutGroup.groups.findIndex((group) => {
|
|
1068
|
+
return group.every((msg, i) => msg === outcomesFormatted[i]);
|
|
1069
|
+
});
|
|
1070
|
+
if (groupIndex === -1)
|
|
1071
|
+
throw Error(
|
|
1072
|
+
'Failed to Find OutcomeIndex From PolynomialPayoutCurvePiece. \
|
|
1073
|
+
Payout Group found but incorrect group index',
|
|
1074
|
+
);
|
|
1075
|
+
index += groupIndex;
|
|
1076
|
+
groupLength = payoutGroup.groups[groupIndex].length;
|
|
1077
|
+
break;
|
|
1078
|
+
} else {
|
|
1079
|
+
index += payoutGroup.groups.length;
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
if (groupIndex === -1)
|
|
1084
|
+
throw Error(
|
|
1085
|
+
'Failed to Find OutcomeIndex From PolynomialPayoutCurvePiece. \
|
|
1086
|
+
Payout Group not found',
|
|
1087
|
+
);
|
|
1088
|
+
|
|
1089
|
+
return { index: payoutIndexOffset + index, groupLength };
|
|
1090
|
+
}
|
|
1091
|
+
|
|
925
1092
|
async FindOutcomeIndexFromHyperbolaPayoutCurvePiece(
|
|
926
1093
|
_dlcOffer: DlcOffer,
|
|
927
1094
|
contractDescriptor: ContractDescriptorV1,
|
|
@@ -1052,14 +1219,21 @@ Payout Group not found',
|
|
|
1052
1219
|
.reduce((acc, val, i) => acc + Number(val) * base ** i, 0);
|
|
1053
1220
|
|
|
1054
1221
|
const piecesSorted = payoutFunction.pieces.sort(
|
|
1055
|
-
(a, b) => Number(
|
|
1222
|
+
(a, b) => Number(a.endpoint) - Number(b.endpoint),
|
|
1056
1223
|
);
|
|
1057
1224
|
|
|
1058
1225
|
const piece = piecesSorted.find((piece) => outcome < piece.endpoint);
|
|
1059
1226
|
|
|
1060
1227
|
switch (piece.payoutCurvePiece.type) {
|
|
1061
1228
|
case MessageType.PolynomialPayoutCurvePiece:
|
|
1062
|
-
|
|
1229
|
+
return this.FindOutcomeIndexFromPolynomialPayoutCurvePiece(
|
|
1230
|
+
dlcOffer,
|
|
1231
|
+
contractDescriptor,
|
|
1232
|
+
contractOraclePairIndex,
|
|
1233
|
+
piece.payoutCurvePiece as PolynomialPayoutCurvePiece,
|
|
1234
|
+
oracleAttestation,
|
|
1235
|
+
BigInt(outcome),
|
|
1236
|
+
);
|
|
1063
1237
|
case MessageType.HyperbolaPayoutCurvePiece:
|
|
1064
1238
|
return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(
|
|
1065
1239
|
dlcOffer,
|
|
@@ -1563,11 +1737,13 @@ Payout Group not found',
|
|
|
1563
1737
|
network,
|
|
1564
1738
|
);
|
|
1565
1739
|
|
|
1566
|
-
let walletAddress: Address = await this.
|
|
1740
|
+
let walletAddress: Address = await this.client.wallet.findAddress([
|
|
1567
1741
|
offerFundingAddress,
|
|
1568
1742
|
]);
|
|
1569
1743
|
if (walletAddress) return true;
|
|
1570
|
-
walletAddress = await this.
|
|
1744
|
+
walletAddress = await this.client.wallet.findAddress([
|
|
1745
|
+
acceptFundingAddress,
|
|
1746
|
+
]);
|
|
1571
1747
|
if (walletAddress) return false;
|
|
1572
1748
|
|
|
1573
1749
|
throw Error('Wallet Address not found for DlcOffer or DlcAccept');
|
|
@@ -2774,9 +2950,9 @@ Payout Group not found',
|
|
|
2774
2950
|
let derivationPath: string;
|
|
2775
2951
|
|
|
2776
2952
|
if (findDerivationPath) {
|
|
2777
|
-
const inputAddress: Address = await this.client.
|
|
2778
|
-
|
|
2779
|
-
);
|
|
2953
|
+
const inputAddress: Address = await this.client.wallet.findAddress([
|
|
2954
|
+
_address,
|
|
2955
|
+
]);
|
|
2780
2956
|
if (inputAddress) {
|
|
2781
2957
|
derivationPath = inputAddress.derivationPath;
|
|
2782
2958
|
}
|
|
@@ -2816,6 +2992,7 @@ Payout Group not found',
|
|
|
2816
2992
|
);
|
|
2817
2993
|
}
|
|
2818
2994
|
}
|
|
2995
|
+
|
|
2819
2996
|
const tx = Tx.decode(StreamReader.fromHex(txRaw));
|
|
2820
2997
|
|
|
2821
2998
|
fundingInput.prevTx = tx;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomicfinance/bitcoin-dlc-provider",
|
|
3
3
|
"umdName": "BitcoinDlcProvider",
|
|
4
|
-
"version": "
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "3.0.0",
|
|
5
|
+
"description": "Bitcoin Abstraction Layer Dlc Provider",
|
|
6
6
|
"author": "Atomic Finance <info@atomic.finance>",
|
|
7
7
|
"homepage": "",
|
|
8
8
|
"license": "ISC",
|
|
@@ -15,20 +15,18 @@
|
|
|
15
15
|
"lint:fix": "../../node_modules/.bin/eslint --fix --ignore-path ../../.eslintignore -c ../../.eslintrc.js ."
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@atomicfinance/bitcoin-
|
|
19
|
-
"@atomicfinance/provider": "^
|
|
20
|
-
"@atomicfinance/types": "^
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
24
|
-
"@liquality/utils": "1.1.5",
|
|
25
|
-
"@node-dlc/core": "0.12.1",
|
|
26
|
-
"@node-dlc/messaging": "0.12.1",
|
|
18
|
+
"@atomicfinance/bitcoin-utils": "3.0.0",
|
|
19
|
+
"@atomicfinance/provider": "^3.0.0",
|
|
20
|
+
"@atomicfinance/types": "^3.0.0",
|
|
21
|
+
"@atomicfinance/utils": "^3.0.0",
|
|
22
|
+
"@node-dlc/core": "0.19.1",
|
|
23
|
+
"@node-dlc/messaging": "0.19.1",
|
|
27
24
|
"@node-lightning/bitcoin": "0.26.1",
|
|
28
25
|
"@node-lightning/bufio": "0.26.1",
|
|
29
26
|
"@node-lightning/crypto": "0.26.1",
|
|
30
|
-
"bignumber.js": "9.0.1",
|
|
27
|
+
"bignumber.js": "^9.0.1",
|
|
31
28
|
"bip-schnorr": "0.6.2",
|
|
29
|
+
"bitcoin-networks": "^1.0.0",
|
|
32
30
|
"bitcoinjs-lib": "5.2.0",
|
|
33
31
|
"lodash": "^4.17.20",
|
|
34
32
|
"randombytes": "2.1.0",
|
|
@@ -36,10 +34,9 @@
|
|
|
36
34
|
},
|
|
37
35
|
"devDependencies": {
|
|
38
36
|
"@types/lodash": "^4.14.160",
|
|
39
|
-
"@types/node": "
|
|
37
|
+
"@types/node": "16.10.3"
|
|
40
38
|
},
|
|
41
39
|
"publishConfig": {
|
|
42
40
|
"access": "public"
|
|
43
|
-
}
|
|
44
|
-
"gitHead": "ae5d1bf9db5c664032f0be604116a83dbf6b5db3"
|
|
41
|
+
}
|
|
45
42
|
}
|