@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.
@@ -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 { BitcoinNetwork } from '@liquality/bitcoin-networks';
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
- // eslint-disable-next-line no-case-declarations
378
- return this.GetPayoutsFromPayoutFunction(
379
- dlcOffer,
380
- contractDescriptor as ContractDescriptorV1,
381
- oracleInfo,
382
- totalCollateral,
383
- );
384
- default:
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.getMethod('findAddress')([
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(b.endpoint) - Number(a.endpoint),
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
- throw Error('Polynomial Curve Piece not yet supported');
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.getMethod('findAddress')([
1740
+ let walletAddress: Address = await this.client.wallet.findAddress([
1567
1741
  offerFundingAddress,
1568
1742
  ]);
1569
1743
  if (walletAddress) return true;
1570
- walletAddress = await this.getMethod('findAddress')([acceptFundingAddress]);
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.financewallet.quickFindAddress(
2778
- [_address],
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": "2.4.2",
5
- "description": "CAL Finance Bitcoin Dlc Provider",
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-networks": "^2.4.2",
19
- "@atomicfinance/provider": "^2.4.2",
20
- "@atomicfinance/types": "^2.4.2",
21
- "@liquality/bitcoin-utils": "1.1.5",
22
- "@liquality/provider": "1.1.5",
23
- "@liquality/types": "1.1.5",
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": "^16.10.2"
37
+ "@types/node": "16.10.3"
40
38
  },
41
39
  "publishConfig": {
42
40
  "access": "public"
43
- },
44
- "gitHead": "ae5d1bf9db5c664032f0be604116a83dbf6b5db3"
41
+ }
45
42
  }