Skip to content

Commit a18b140

Browse files
committed
Small updates to WizardConnect utils
1 parent 2c0b9ad commit a18b140

3 files changed

Lines changed: 91 additions & 83 deletions

File tree

packages/cashscript/src/TransactionBuilder.ts

Lines changed: 62 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import {
1818
isStandardUnlockableUtxo,
1919
StandardUnlockableUtxo,
2020
VmResourceUsage,
21-
isContractUnlocker,
22-
BchChangeOutputOptions,
23-
TokenChangeOutputOptions,
24-
isPlaceholderUnlocker,
25-
} from './interfaces.js';
21+
isContractUnlocker,
22+
BchChangeOutputOptions,
23+
TokenChangeOutputOptions,
24+
isPlaceholderUnlocker,
25+
} from './interfaces.js';
2626
import { NetworkProvider } from './network/index.js';
2727
import {
2828
calculateDust,
@@ -37,15 +37,15 @@ import {
3737
import { FailedTransactionError } from './Errors.js';
3838
import { DebugResults } from './debugging.js';
3939
import { debugLibauthTemplate, getLibauthTemplate, getBitauthUri } from './libauth-template/LibauthTemplate.js';
40-
import {
41-
getWcContractInfo,
42-
WcSourceOutput,
43-
WcTransactionOptions,
44-
WizardConnectInputPath,
45-
WizardConnectTransactionObject,
46-
} from './walletconnect-utils.js';
40+
import {
41+
getWcContractInfo,
42+
WalletConnectSourceOutput,
43+
WalletConnectTransactionOptions,
44+
WizardConnectInputPath,
45+
WizardConnectTransactionObject,
46+
} from './walletconnect-utils.js';
4747
import semver from 'semver';
48-
import { WcTransactionObject } from './walletconnect-utils.js';
48+
import { WalletConnectTransactionObject } from './walletconnect-utils.js';
4949

5050
/**
5151
* Options accepted by the `TransactionBuilder` constructor.
@@ -558,6 +558,13 @@ export class TransactionBuilder {
558558
throw new Error('Could not retrieve transaction details for over 10 minutes');
559559
}
560560

561+
/**
562+
* @deprecated Use `generateWalletConnectTransactionObject` instead.
563+
*/
564+
generateWcTransactionObject(options?: WalletConnectTransactionOptions): WalletConnectTransactionObject {
565+
return this.generateWalletConnectTransactionObject(options);
566+
}
567+
561568
/**
562569
* Build the transaction and format it as a BCH WalletConnect transaction object suitable for
563570
* signing and broadcasting via a BCH WalletConnect-compatible Bitcoin Cash wallet.
@@ -568,52 +575,52 @@ export class TransactionBuilder {
568575
* @returns A WalletConnect transaction object ready to be sent to a WalletConnect wallet.
569576
* @throws If the transaction cannot be built (fee exceeds limit or fungible tokens burned).
570577
*/
571-
generateWcTransactionObject(options?: WcTransactionOptions): WcTransactionObject {
572-
const encodedTransaction = this.build();
573-
const transaction = decodeTransactionUnsafe(hexToBin(encodedTransaction));
578+
generateWalletConnectTransactionObject(options?: WalletConnectTransactionOptions): WalletConnectTransactionObject {
579+
const encodedTransaction = this.build();
580+
const transaction = decodeTransactionUnsafe(hexToBin(encodedTransaction));
574581

575582
const libauthSourceOutputs = generateLibauthSourceOutputs(this.inputs);
576-
const sourceOutputs: WcSourceOutput[] = libauthSourceOutputs.map((sourceOutput, index) => {
583+
const sourceOutputs: WalletConnectSourceOutput[] = libauthSourceOutputs.map((sourceOutput, index) => {
577584
return {
578585
...sourceOutput,
579586
...transaction.inputs[index],
580587
...getWcContractInfo(this.inputs[index]),
581588
};
582-
});
583-
return { ...options, transaction, sourceOutputs };
584-
}
585-
586-
/**
587-
* Build the transaction and format it as a WizardConnect transaction request.
588-
*
589-
* WizardConnect uses the standard BCH WalletConnect transaction object plus HD path metadata for
590-
* each placeholder P2PKH input that the wallet must sign.
591-
*
592-
* @param options - Optional WalletConnect options such as `broadcast` and `userPrompt`.
593-
* @returns A WizardConnect transaction object ready to be sent to a WizardConnect wallet.
594-
* @throws If the transaction cannot be built, or if a placeholder input is missing HD path metadata.
595-
*/
596-
generateWizardConnectTransactionObject(options?: WcTransactionOptions): WizardConnectTransactionObject {
597-
const transaction = this.generateWcTransactionObject(options);
598-
const inputPaths = this.generateWizardConnectInputPaths();
599-
600-
return { transaction, inputPaths };
601-
}
602-
603-
private generateWizardConnectInputPaths(): WizardConnectInputPath[] {
604-
const inputPaths: WizardConnectInputPath[] = [];
605-
606-
this.inputs.forEach((input, inputIndex) => {
607-
if (!isPlaceholderUnlocker(input.unlocker)) return;
608-
609-
const hdPath = input.unlocker.hdPath;
610-
if (!hdPath) {
611-
throw new Error(`Placeholder P2PKH input ${inputIndex} is missing WizardConnect HD path metadata`);
612-
}
613-
614-
inputPaths.push([inputIndex, hdPath.name, hdPath.addressIndex]);
615-
});
616-
617-
return inputPaths;
618-
}
619-
}
589+
});
590+
return { ...options, transaction, sourceOutputs };
591+
}
592+
593+
/**
594+
* Build the transaction and format it as a WizardConnect transaction request.
595+
*
596+
* WizardConnect uses the standard BCH WalletConnect transaction object plus HD path metadata for
597+
* each placeholder P2PKH input that the wallet must sign.
598+
*
599+
* @param options - Optional WalletConnect options such as `broadcast` and `userPrompt`.
600+
* @returns A WizardConnect transaction object ready to be sent to a WizardConnect wallet.
601+
* @throws If the transaction cannot be built, or if a placeholder input is missing HD path metadata.
602+
*/
603+
generateWizardConnectTransactionObject(options?: WalletConnectTransactionOptions): WizardConnectTransactionObject {
604+
const transaction = this.generateWalletConnectTransactionObject(options);
605+
const inputPaths = this.generateWizardConnectInputPaths();
606+
607+
return { transaction, inputPaths };
608+
}
609+
610+
private generateWizardConnectInputPaths(): WizardConnectInputPath[] {
611+
const inputPaths: WizardConnectInputPath[] = [];
612+
613+
this.inputs.forEach((input, inputIndex) => {
614+
if (!isPlaceholderUnlocker(input.unlocker)) return;
615+
616+
const hdPath = input.unlocker.hdPath;
617+
if (!hdPath) {
618+
throw new Error(`Placeholder P2PKH input ${inputIndex} is missing WizardConnect HD path metadata`);
619+
}
620+
621+
inputPaths.push([inputIndex, hdPath.name, hdPath.addressIndex]);
622+
});
623+
624+
return inputPaths;
625+
}
626+
}

packages/cashscript/src/interfaces.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ export interface PlaceholderP2PKHUnlockerOptions {
6565
hdPath?: PlaceholderHdPath;
6666
}
6767

68-
export interface PlaceholderP2PKHUnlockerConfig extends PlaceholderP2PKHUnlockerOptions {
69-
address: string;
70-
}
71-
7268
export interface PlaceholderP2PKHUnlocker extends Unlocker {
7369
placeholder: true;
7470
address: string;
Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
type LibauthOutput,
33
isContractUnlocker,
4-
type PlaceholderP2PKHUnlockerConfig,
54
type PlaceholderP2PKHUnlocker,
65
type PlaceholderP2PKHUnlockerOptions,
76
type UnlockableUtxo,
@@ -12,52 +11,68 @@ import { cashAddressToLockingBytecode, hexToBin, type Input, type TransactionCom
1211
// Wallet Connect interfaces according to the spec
1312
// see https://github.com/mainnet-pat/wc2-bch-bcr
1413

15-
export interface WcTransactionOptions {
14+
export interface WalletConnectTransactionOptions {
1615
broadcast?: boolean;
1716
userPrompt?: string;
1817
}
1918

20-
export interface WcTransactionObject {
19+
/** @deprecated Use `WalletConnectTransactionOptions` instead. */
20+
export type WcTransactionOptions = WalletConnectTransactionOptions;
21+
22+
export interface WalletConnectTransactionObject {
2123
transaction: TransactionCommon; // spec also allows for a tx hex string but we use the libauth transaction object
22-
sourceOutputs: WcSourceOutput[];
24+
sourceOutputs: WalletConnectSourceOutput[];
2325
broadcast?: boolean;
2426
userPrompt?: string;
2527
}
2628

29+
/** @deprecated Use `WalletConnectTransactionObject` instead. */
30+
export type WcTransactionObject = WalletConnectTransactionObject;
31+
2732
export type WizardConnectInputPath = [inputIndex: number, pathName: string, addressIndex: number];
2833

2934
export interface WizardConnectTransactionObject {
30-
transaction: WcTransactionObject;
35+
transaction: WalletConnectTransactionObject;
3136
inputPaths: WizardConnectInputPath[];
3237
}
3338

34-
export type WcSourceOutput = Input & LibauthOutput & WcContractInfo;
39+
export type WalletConnectSourceOutput = Input & LibauthOutput & WalletConnectContractInfo;
40+
41+
/** @deprecated Use `WalletConnectSourceOutput` instead. */
42+
export type WcSourceOutput = WalletConnectSourceOutput;
3543

36-
export interface WcContractInfo {
44+
export interface WalletConnectContractInfo {
3745
contract?: {
3846
abiFunction: AbiFunction;
3947
redeemScript: Uint8Array;
4048
artifact: Partial<Artifact>;
4149
}
4250
}
4351

44-
export function getWcContractInfo(input: UnlockableUtxo): WcContractInfo | {} {
52+
/** @deprecated Use `WalletConnectContractInfo` instead. */
53+
export type WcContractInfo = WalletConnectContractInfo;
54+
55+
export function getWcContractInfo(input: UnlockableUtxo): WalletConnectContractInfo | {} {
4556
// If the input does not have a contract unlocker, return an empty object
4657
if (!(isContractUnlocker(input.unlocker))) return {};
58+
4759
const contract = input.unlocker.contract;
4860
const abiFunctionName = input.unlocker.abiFunction?.name;
4961
const abiFunction = contract.artifact.abi.find(abi => abi.name === abiFunctionName);
62+
5063
if (!abiFunction) {
5164
throw new Error(`ABI function ${abiFunctionName} not found in contract artifact`);
5265
}
53-
const wcContractObj: WcContractInfo = {
66+
67+
const walletConnectContractObject: WalletConnectContractInfo = {
5468
contract: {
5569
abiFunction: abiFunction,
5670
redeemScript: hexToBin(contract.bytecode),
5771
artifact: contract.artifact,
5872
},
5973
};
60-
return wcContractObj;
74+
75+
return walletConnectContractObject;
6176
}
6277

6378
/**
@@ -80,28 +95,18 @@ export const placeholderPublicKey = (): Uint8Array => Uint8Array.from(Array(33))
8095
/**
8196
* Create a placeholder P2PKH `Unlocker` for the provided user address. The returned unlocker
8297
* generates an empty unlocking bytecode and is flagged as `placeholder: true`, which is useful
83-
* when building a transaction object for WalletConnect signing where the final signing is
84-
* performed by the connected wallet.
98+
* when building a transaction object for WalletConnect / WizardConnect signing where the final
99+
* signing is performed by the connected wallet.
85100
*
86-
* @param userAddress - The user's CashAddress that will eventually sign the input, or an object
87-
* containing the address and signing metadata.
101+
* @param userAddress - The user's CashAddress that will eventually sign the input
88102
* @param options - Optional signing metadata, such as HD path information for WizardConnect.
89103
* @returns A placeholder unlocker that can be passed to `TransactionBuilder.addInput`.
90104
* @throws If `userAddress` is not a valid CashAddress.
91105
*/
92106
export function placeholderP2PKHUnlocker(
93107
userAddress: string,
94-
options?: PlaceholderP2PKHUnlockerOptions,
95-
): PlaceholderP2PKHUnlocker;
96-
export function placeholderP2PKHUnlocker(options: PlaceholderP2PKHUnlockerConfig): PlaceholderP2PKHUnlocker;
97-
export function placeholderP2PKHUnlocker(
98-
userAddressOrOptions: string | PlaceholderP2PKHUnlockerConfig,
99108
options: PlaceholderP2PKHUnlockerOptions = {},
100109
): PlaceholderP2PKHUnlocker {
101-
const userAddress = typeof userAddressOrOptions === 'string'
102-
? userAddressOrOptions
103-
: userAddressOrOptions.address;
104-
const unlockerOptions = typeof userAddressOrOptions === 'string' ? options : userAddressOrOptions;
105110
const decodeAddressResult = cashAddressToLockingBytecode(userAddress);
106111

107112
if (typeof decodeAddressResult === 'string') {
@@ -114,6 +119,6 @@ export function placeholderP2PKHUnlocker(
114119
generateUnlockingBytecode: () => Uint8Array.from(Array(0)),
115120
placeholder: true,
116121
address: userAddress,
117-
...unlockerOptions,
122+
...options,
118123
};
119124
}

0 commit comments

Comments
 (0)