@atomicfinance/bitcoin-dlc-provider 2.4.0 → 2.5.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/dist/BitcoinDlcProvider.d.ts +3 -1
- package/dist/BitcoinDlcProvider.js +788 -692
- package/dist/BitcoinDlcProvider.js.map +1 -1
- package/dist/index.js +57 -21
- package/dist/utils/Utils.js +54 -50
- package/lib/BitcoinDlcProvider.ts +203 -19
- package/package.json +10 -10
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
DualFundingTxFinalizer,
|
|
53
53
|
groupByIgnoringDigits,
|
|
54
54
|
HyperbolaPayoutCurve,
|
|
55
|
+
PolynomialPayoutCurve,
|
|
55
56
|
roundPayout,
|
|
56
57
|
} from '@node-dlc/core';
|
|
57
58
|
import {
|
|
@@ -83,6 +84,7 @@ import {
|
|
|
83
84
|
OracleEventV0,
|
|
84
85
|
OracleInfoV0,
|
|
85
86
|
PayoutFunctionV0,
|
|
87
|
+
PolynomialPayoutCurvePiece,
|
|
86
88
|
ScriptWitnessV0,
|
|
87
89
|
} from '@node-dlc/messaging';
|
|
88
90
|
import { Script, Sequence, Tx } from '@node-lightning/bitcoin';
|
|
@@ -131,7 +133,15 @@ export default class BitcoinDlcProvider
|
|
|
131
133
|
|
|
132
134
|
for (let i = 0; i < inputs.length; i++) {
|
|
133
135
|
const input = inputs[i];
|
|
134
|
-
|
|
136
|
+
let derivationPath = input.derivationPath;
|
|
137
|
+
|
|
138
|
+
if (!derivationPath) {
|
|
139
|
+
derivationPath = (
|
|
140
|
+
await this.getMethod('getWalletAddress')(input.address)
|
|
141
|
+
).derivationPath;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const keyPair = await this.getMethod('keyPair')(derivationPath);
|
|
135
145
|
const privKey = Buffer.from(keyPair.__D).toString('hex');
|
|
136
146
|
privKeys.push(privKey);
|
|
137
147
|
}
|
|
@@ -308,6 +318,66 @@ export default class BitcoinDlcProvider
|
|
|
308
318
|
return { payouts, payoutGroups, messagesList };
|
|
309
319
|
}
|
|
310
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
|
+
|
|
311
381
|
private GetPayouts(_dlcOffer: DlcOffer): GetPayoutsResponse[] {
|
|
312
382
|
const { dlcOffer } = checkTypes({ _dlcOffer });
|
|
313
383
|
|
|
@@ -363,18 +433,45 @@ export default class BitcoinDlcProvider
|
|
|
363
433
|
totalCollateral: bigint,
|
|
364
434
|
) {
|
|
365
435
|
switch (contractDescriptor.type) {
|
|
366
|
-
case MessageType.ContractDescriptorV0:
|
|
436
|
+
case MessageType.ContractDescriptorV0: {
|
|
367
437
|
throw Error('ContractDescriptorV0 not yet supported');
|
|
438
|
+
}
|
|
368
439
|
case MessageType.ContractDescriptorV1:
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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: {
|
|
377
473
|
throw Error('ContractDescriptor must be V0 or V1');
|
|
474
|
+
}
|
|
378
475
|
}
|
|
379
476
|
}
|
|
380
477
|
|
|
@@ -550,9 +647,9 @@ export default class BitcoinDlcProvider
|
|
|
550
647
|
network,
|
|
551
648
|
);
|
|
552
649
|
|
|
553
|
-
const {
|
|
554
|
-
|
|
555
|
-
]);
|
|
650
|
+
const {
|
|
651
|
+
derivationPath,
|
|
652
|
+
} = await this.client.financewallet.quickFindAddress([fundingAddress]);
|
|
556
653
|
|
|
557
654
|
const fundPrivateKeyPair = await this.getMethod('keyPair')(derivationPath);
|
|
558
655
|
const fundPrivateKey = Buffer.from(fundPrivateKeyPair.__D).toString('hex');
|
|
@@ -914,6 +1011,84 @@ export default class BitcoinDlcProvider
|
|
|
914
1011
|
return fundTx;
|
|
915
1012
|
}
|
|
916
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
|
+
|
|
917
1092
|
async FindOutcomeIndexFromHyperbolaPayoutCurvePiece(
|
|
918
1093
|
_dlcOffer: DlcOffer,
|
|
919
1094
|
contractDescriptor: ContractDescriptorV1,
|
|
@@ -1044,14 +1219,21 @@ Payout Group not found',
|
|
|
1044
1219
|
.reduce((acc, val, i) => acc + Number(val) * base ** i, 0);
|
|
1045
1220
|
|
|
1046
1221
|
const piecesSorted = payoutFunction.pieces.sort(
|
|
1047
|
-
(a, b) => Number(
|
|
1222
|
+
(a, b) => Number(a.endpoint) - Number(b.endpoint),
|
|
1048
1223
|
);
|
|
1049
1224
|
|
|
1050
1225
|
const piece = piecesSorted.find((piece) => outcome < piece.endpoint);
|
|
1051
1226
|
|
|
1052
1227
|
switch (piece.payoutCurvePiece.type) {
|
|
1053
1228
|
case MessageType.PolynomialPayoutCurvePiece:
|
|
1054
|
-
|
|
1229
|
+
return this.FindOutcomeIndexFromPolynomialPayoutCurvePiece(
|
|
1230
|
+
dlcOffer,
|
|
1231
|
+
contractDescriptor,
|
|
1232
|
+
contractOraclePairIndex,
|
|
1233
|
+
piece.payoutCurvePiece as PolynomialPayoutCurvePiece,
|
|
1234
|
+
oracleAttestation,
|
|
1235
|
+
BigInt(outcome),
|
|
1236
|
+
);
|
|
1055
1237
|
case MessageType.HyperbolaPayoutCurvePiece:
|
|
1056
1238
|
return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(
|
|
1057
1239
|
dlcOffer,
|
|
@@ -1555,11 +1737,13 @@ Payout Group not found',
|
|
|
1555
1737
|
network,
|
|
1556
1738
|
);
|
|
1557
1739
|
|
|
1558
|
-
let walletAddress: Address = await this.
|
|
1559
|
-
offerFundingAddress,
|
|
1560
|
-
|
|
1740
|
+
let walletAddress: Address = await this.client.financewallet.quickFindAddress(
|
|
1741
|
+
[offerFundingAddress],
|
|
1742
|
+
);
|
|
1561
1743
|
if (walletAddress) return true;
|
|
1562
|
-
walletAddress = await this.
|
|
1744
|
+
walletAddress = await this.client.financewallet.quickFindAddress([
|
|
1745
|
+
acceptFundingAddress,
|
|
1746
|
+
]);
|
|
1563
1747
|
if (walletAddress) return false;
|
|
1564
1748
|
|
|
1565
1749
|
throw Error('Wallet Address not found for DlcOffer or DlcAccept');
|
package/package.json
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atomicfinance/bitcoin-dlc-provider",
|
|
3
3
|
"umdName": "BitcoinDlcProvider",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.5.0",
|
|
5
5
|
"description": "CAL Finance Bitcoin Dlc Provider",
|
|
6
6
|
"author": "Atomic Finance <info@atomic.finance>",
|
|
7
7
|
"homepage": "",
|
|
8
8
|
"license": "ISC",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "../../node_modules/.bin/
|
|
11
|
+
"build": "../../node_modules/.bin/swc lib --out-dir=dist --config-file=../../.swcrc",
|
|
12
12
|
"prepublishOnly": "yarn run build",
|
|
13
13
|
"test": "yarn run build",
|
|
14
14
|
"lint": "../../node_modules/.bin/eslint --ignore-path ../../.eslintignore -c ../../.eslintrc.js .",
|
|
15
15
|
"lint:fix": "../../node_modules/.bin/eslint --fix --ignore-path ../../.eslintignore -c ../../.eslintrc.js ."
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@atomicfinance/bitcoin-networks": "^2.
|
|
19
|
-
"@atomicfinance/provider": "^2.
|
|
20
|
-
"@atomicfinance/types": "^2.
|
|
18
|
+
"@atomicfinance/bitcoin-networks": "^2.5.0",
|
|
19
|
+
"@atomicfinance/provider": "^2.5.0",
|
|
20
|
+
"@atomicfinance/types": "^2.5.0",
|
|
21
21
|
"@liquality/bitcoin-utils": "1.1.5",
|
|
22
22
|
"@liquality/provider": "1.1.5",
|
|
23
23
|
"@liquality/types": "1.1.5",
|
|
24
24
|
"@liquality/utils": "1.1.5",
|
|
25
|
-
"@node-dlc/core": "0.
|
|
26
|
-
"@node-dlc/messaging": "0.
|
|
25
|
+
"@node-dlc/core": "0.18.3",
|
|
26
|
+
"@node-dlc/messaging": "0.18.3",
|
|
27
27
|
"@node-lightning/bitcoin": "0.26.1",
|
|
28
28
|
"@node-lightning/bufio": "0.26.1",
|
|
29
29
|
"@node-lightning/crypto": "0.26.1",
|
|
30
|
-
"bignumber.js": "9.0.1",
|
|
30
|
+
"bignumber.js": "^9.0.1",
|
|
31
31
|
"bip-schnorr": "0.6.2",
|
|
32
32
|
"bitcoinjs-lib": "5.2.0",
|
|
33
33
|
"lodash": "^4.17.20",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/lodash": "^4.14.160",
|
|
39
|
-
"@types/node": "
|
|
39
|
+
"@types/node": "16.10.3"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"access": "public"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "021537d74a46eb5bd578a7c4b122555e6b0a310f"
|
|
45
45
|
}
|