Skip to content

Commit

Permalink
Refactor Descriptor Types (use DescriptorInstance to express the type…
Browse files Browse the repository at this point in the history
… of an instance of the Descriptor class instead of Descriptor, which would lead to confussion) and Improve Documentation
  • Loading branch information
landabaso committed Sep 8, 2023
1 parent 6508de2 commit 5945e78
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 83 deletions.
10 changes: 5 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- **Configuration**:
- Adopted sharable configs from `@bitcoinerlab/configs` to improve the maintainability of the library.
- Adopted sharable configurations from `@bitcoinerlab/configs` to enhance library maintainability.

- **Exported Types**:
- Changed the exported type for descriptors:
- **Before**: The library exported `DescriptorInterfaceConstructor` which was primarily used for typing the methods of a descriptor instance but not its constructor.
- **Now**: The library exports `Descriptor`, a more comprehensive type derived using `InstanceType<ReturnType<typeof DescriptorsFactory>['Descriptor']>;`. This type represents an instance of the descriptor class returned by the factory, including its methods.
- Revised the exported types for descriptors:
- **Before**: The library previously exported both `DescriptorInterface` and `DescriptorInterfaceConstructor`.
- **Now**: The library now exports `DescriptorInstance`, a more comprehensive type derived using `InstanceType<ReturnType<typeof DescriptorsFactory>['Descriptor']>;`. This type embodies an instance of the descriptor class returned by the factory, inclusive of its methods. Furthermore, the library now exports `DescriptorConstructor` in place of `DescriptorInterfaceConstructor`.

If you had previously relied on `DescriptorInterface` for typing instances of the descriptor class, please update your implementations to use the new `Descriptor` type. The new type offers more accurate typings and includes methods as well as properties of descriptor instances.
If you previously used `DescriptorInterface` for type annotations with instances of the descriptor class, it's recommended to transition to the newly introduced `DescriptorInstance` type. For example: `const descriptor: DescriptorInterface = new Descriptor();` should now be `const descriptor: DescriptorInstance = new Descriptor();`. This new type not only offers more precise typings but also has a more appropriate name.

## [1.0.1] - 2023-07-14

Expand Down
20 changes: 9 additions & 11 deletions src/descriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,17 +836,15 @@ export function DescriptorsFactory(ecc: TinySecp256k1Interface) {
return { Descriptor, parseKeyExpression, expand, ECPair, BIP32 };
}
/**
* The {@link DescriptorsFactory | `DescriptorsFactory`} function internally creates and returns an instance of the {@link _Internal_.Descriptor | `Descriptor`} class.
* This instance is specialized for the provided `TinySecp256k1Interface`.
* The {@link DescriptorsFactory | `DescriptorsFactory`} function internally creates and returns the {@link _Internal_.Descriptor | `Descriptor`} class.
* This class is specialized for the provided `TinySecp256k1Interface`.
* Use `DescriptorInstance` to declare instances for this class: `const: DescriptorInstance = new Descriptor();`
*
* See the {@link _Internal_.Descriptor | documentation for the internal Descriptor class} for a complete list of available methods.
*/
type Descriptor = InstanceType<
ReturnType<typeof DescriptorsFactory>['Descriptor']
>;
//type Expand = ReturnType<typeof DescriptorsFactory>['expand'];
//type ParseKeyExpression = ReturnType<
// typeof DescriptorsFactory
//>['parseKeyExpression'];

export { Descriptor };
type DescriptorConstructor = ReturnType<
typeof DescriptorsFactory
>['Descriptor'];
type DescriptorInstance = InstanceType<DescriptorConstructor>;

export { DescriptorInstance, DescriptorConstructor };
12 changes: 8 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// Copyright (c) 2023 Jose-Luis Landabaso - https://bitcoinerlab.com
// Distributed under the MIT software license

export type { Expand, ParseKeyExpression } from './types';
export type { KeyInfo, Expansion } from './types';
import type { Psbt } from 'bitcoinjs-lib';
import type { Descriptor } from './descriptors';
export { DescriptorsFactory, Descriptor } from './descriptors';
import type { DescriptorInstance } from './descriptors';
export {
DescriptorsFactory,
DescriptorInstance,
DescriptorConstructor
} from './descriptors';
export { DescriptorChecksum as checksum } from './checksum';

import * as signers from './signers';
Expand All @@ -16,7 +20,7 @@ export function finalizePsbt({
validate = true
}: {
psbt: Psbt;
descriptors: Descriptor[];
descriptors: DescriptorInstance[];
validate?: boolean | undefined;
}) {
descriptors.forEach((descriptor, inputIndex) =>
Expand Down
10 changes: 5 additions & 5 deletions src/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* All the conditions above are checked in function descriptorToLedgerFormat.
*/

import type { Descriptor } from './descriptors';
import type { DescriptorInstance } from './descriptors';
import { Network, networks } from 'bitcoinjs-lib';
import { reOriginPath } from './re';

Expand Down Expand Up @@ -237,7 +237,7 @@ export async function descriptorToLedgerFormat({
ledgerClient,
ledgerState
}: {
descriptor: Descriptor;
descriptor: DescriptorInstance;
ledgerClient: unknown;
ledgerState: LedgerState;
}): Promise<{ ledgerTemplate: string; keyRoots: string[] } | null> {
Expand Down Expand Up @@ -334,7 +334,7 @@ export async function registerLedgerWallet({
ledgerState,
policyName
}: {
descriptor: Descriptor;
descriptor: DescriptorInstance;
ledgerClient: unknown;
ledgerState: LedgerState;
policyName: string;
Expand Down Expand Up @@ -390,7 +390,7 @@ export async function ledgerPolicyFromStandard({
ledgerClient,
ledgerState
}: {
descriptor: Descriptor;
descriptor: DescriptorInstance;
ledgerClient: unknown;
ledgerState: LedgerState;
}): Promise<LedgerPolicy | null> {
Expand Down Expand Up @@ -439,7 +439,7 @@ export async function ledgerPolicyFromState({
ledgerClient,
ledgerState
}: {
descriptor: Descriptor;
descriptor: DescriptorInstance;
ledgerClient: unknown;
ledgerState: LedgerState;
}): Promise<LedgerPolicy | null> {
Expand Down
6 changes: 3 additions & 3 deletions src/signers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { Psbt } from 'bitcoinjs-lib';
import type { ECPairInterface } from 'ecpair';
import type { BIP32Interface } from 'bip32';
import type { Descriptor } from './descriptors';
import type { DescriptorInstance } from './descriptors';
import {
importAndValidateLedgerBitcoin,
comparePolicies,
Expand Down Expand Up @@ -86,7 +86,7 @@ export async function signInputLedger({
}: {
psbt: Psbt;
index: number;
descriptor: Descriptor;
descriptor: DescriptorInstance;
ledgerClient: unknown;
ledgerState: LedgerState;
}): Promise<void> {
Expand Down Expand Up @@ -158,7 +158,7 @@ export async function signLedger({
ledgerState
}: {
psbt: Psbt;
descriptors: Descriptor[];
descriptors: DescriptorInstance[];
ledgerClient: unknown;
ledgerState: LedgerState;
}): Promise<void> {
Expand Down
104 changes: 53 additions & 51 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,58 @@ export interface TinySecp256k1Interface {
privateNegate(d: Uint8Array): Uint8Array;
}

export type Expansion = {
/**
* The corresponding [bitcoinjs-lib Payment](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/payments/index.ts) for the provided expression, if applicable.
*/
payment?: Payment;

/**
* The expanded descriptor expression.
*/
expandedExpression?: string;

/**
* The extracted miniscript from the expression, if any.
*/
miniscript?: string;

/**
* A map of key expressions in the descriptor to their corresponding expanded keys.
*/
expansionMap?: ExpansionMap;

/**
* A boolean indicating whether the descriptor represents a SegWit script.
*/
isSegwit?: boolean;

/**
* The expanded miniscript, if any.
*/
expandedMiniscript?: string;

/**
* The redeem script for the descriptor, if applicable.
*/
redeemScript?: Buffer;

/**
* The witness script for the descriptor, if applicable.
*/
witnessScript?: Buffer;

/**
* Whether this expression represents a ranged-descriptor.
*/
isRanged: boolean;

/**
* This is the preferred or authoritative representation of the descriptor expression.
*/
canonicalExpression: string;
};

/**
* The {@link DescriptorsFactory | `DescriptorsFactory`} function creates and returns an implementation of the `Expand` interface.
* This returned implementation is tailored for the provided `TinySecp256k1Interface`.
Expand Down Expand Up @@ -110,57 +162,7 @@ export interface Expand {
* @defaultValue false
*/
allowMiniscriptInP2SH?: boolean;
}): {
/**
* The corresponding [bitcoinjs-lib Payment](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/payments/index.ts) for the provided expression, if applicable.
*/
payment?: Payment;

/**
* The expanded descriptor expression.
*/
expandedExpression?: string;

/**
* The extracted miniscript from the expression, if any.
*/
miniscript?: string;

/**
* A map of key expressions in the descriptor to their corresponding expanded keys.
*/
expansionMap?: ExpansionMap;

/**
* A boolean indicating whether the descriptor represents a SegWit script.
*/
isSegwit?: boolean;

/**
* The expanded miniscript, if any.
*/
expandedMiniscript?: string;

/**
* The redeem script for the descriptor, if applicable.
*/
redeemScript?: Buffer;

/**
* The witness script for the descriptor, if applicable.
*/
witnessScript?: Buffer;

/**
* Whether this expression represents a ranged-descriptor.
*/
isRanged: boolean;

/**
* This is the preferred or authoritative representation of the descriptor expression.
*/
canonicalExpression: string;
};
}): Expansion;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions test/integration/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import {
keyExpressionLedger,
scriptExpressions,
DescriptorsFactory,
Descriptor,
DescriptorInstance,
ledger,
LedgerState
} from '../../dist/';
Expand All @@ -105,7 +105,7 @@ let txId: string;
let vout: number;
let inputIndex: number;
//In this array, we will keep track of the descriptors of each input:
const psbtInputDescriptors: Descriptor[] = [];
const psbtInputDescriptors: DescriptorInstance[] = [];

(async () => {
let transport;
Expand Down
4 changes: 2 additions & 2 deletions test/integration/standardOutputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const SOFT_MNEMONIC =
import * as ecc from '@bitcoinerlab/secp256k1';
import {
DescriptorsFactory,
Descriptor,
DescriptorInstance,
scriptExpressions,
keyExpressionBIP32,
signers
Expand Down Expand Up @@ -60,7 +60,7 @@ const expressionsECPair = [

(async () => {
const psbtMultiInputs = new Psbt();
const multiInputsDescriptors: Descriptor[] = [];
const multiInputsDescriptors: DescriptorInstance[] = [];
for (const expression of expressionsBIP32) {
const descriptorBIP32 = new Descriptor({ expression, network: NETWORK });

Expand Down

0 comments on commit 5945e78

Please sign in to comment.