@btc-vision/transaction 1.0.101 → 1.0.102
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/.vscode/settings.json +10 -0
- package/LICENSE +21 -0
- package/browser/generators/Features.d.ts +4 -1
- package/browser/generators/builders/CalldataGenerator.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/keypair/EcKeyPair.d.ts +2 -2
- package/browser/metadata/contracts/wBTC.d.ts +2 -2
- package/browser/transaction/TransactionFactory.d.ts +4 -5
- package/browser/transaction/browser/extensions/UnisatSigner.d.ts +2 -2
- package/browser/transaction/browser/types/Unisat.d.ts +1 -2
- package/browser/transaction/builders/DeploymentTransaction.d.ts +1 -1
- package/browser/transaction/builders/FundingTransaction.d.ts +1 -1
- package/browser/transaction/processor/PsbtTransaction.d.ts +2 -2
- package/browser/utils/BitcoinUtils.d.ts +1 -1
- package/browser/utxo/OPNetLimitedProvider.d.ts +3 -3
- package/build/generators/Features.d.ts +4 -1
- package/build/generators/Features.js +4 -1
- package/build/generators/builders/CalldataGenerator.d.ts +1 -1
- package/build/generators/builders/CalldataGenerator.js +5 -3
- package/build/generators/builders/MultiSignGenerator.js +2 -2
- package/build/keypair/EcKeyPair.d.ts +2 -2
- package/build/keypair/EcKeyPair.js +8 -5
- package/build/metadata/contracts/wBTC.d.ts +2 -2
- package/build/metadata/contracts/wBTC.js +2 -2
- package/build/metadata/tokens.js +2 -2
- package/build/signer/TweakedSigner.js +1 -1
- package/build/transaction/TransactionFactory.d.ts +4 -5
- package/build/transaction/TransactionFactory.js +6 -7
- package/build/transaction/browser/extensions/UnisatSigner.d.ts +2 -2
- package/build/transaction/browser/extensions/UnisatSigner.js +3 -3
- package/build/transaction/browser/types/Unisat.d.ts +1 -2
- package/build/transaction/builders/CustomScriptTransaction.js +2 -2
- package/build/transaction/builders/DeploymentTransaction.d.ts +1 -1
- package/build/transaction/builders/DeploymentTransaction.js +2 -2
- package/build/transaction/builders/FundingTransaction.d.ts +1 -1
- package/build/transaction/builders/FundingTransaction.js +2 -2
- package/build/transaction/builders/MultiSignTransaction.js +7 -7
- package/build/transaction/builders/SharedInteractionTransaction.js +3 -3
- package/build/transaction/builders/TransactionBuilder.js +6 -6
- package/build/transaction/builders/UnwrapTransaction.js +4 -4
- package/build/transaction/builders/WrapTransaction.js +1 -1
- package/build/transaction/processor/PsbtTransaction.d.ts +2 -2
- package/build/transaction/processor/PsbtTransaction.js +2 -2
- package/build/transaction/shared/TweakedTransaction.js +4 -4
- package/build/utils/BitcoinUtils.d.ts +1 -1
- package/build/utils/BitcoinUtils.js +1 -1
- package/build/utxo/OPNetLimitedProvider.d.ts +3 -3
- package/build/utxo/OPNetLimitedProvider.js +7 -7
- package/eslint.config.js +10 -2
- package/gulpfile.js +19 -45
- package/package.json +7 -2
- package/src/generators/Features.ts +5 -1
- package/src/generators/builders/CalldataGenerator.ts +6 -4
- package/src/generators/builders/MultiSignGenerator.ts +6 -4
- package/src/keypair/EcKeyPair.ts +10 -8
- package/src/metadata/contracts/wBTC.ts +3 -3
- package/src/metadata/tokens.ts +2 -2
- package/src/signer/TweakedSigner.ts +4 -4
- package/src/transaction/TransactionFactory.ts +18 -20
- package/src/transaction/browser/extensions/UnisatSigner.ts +6 -6
- package/src/transaction/browser/types/Unisat.ts +1 -3
- package/src/transaction/builders/CustomScriptTransaction.ts +2 -2
- package/src/transaction/builders/DeploymentTransaction.ts +5 -5
- package/src/transaction/builders/FundingTransaction.ts +2 -2
- package/src/transaction/builders/MultiSignTransaction.ts +8 -7
- package/src/transaction/builders/SharedInteractionTransaction.ts +3 -3
- package/src/transaction/builders/TransactionBuilder.ts +6 -6
- package/src/transaction/builders/UnwrapTransaction.ts +4 -4
- package/src/transaction/builders/WrapTransaction.ts +1 -1
- package/src/transaction/processor/PsbtTransaction.ts +4 -4
- package/src/transaction/shared/TweakedTransaction.ts +19 -11
- package/src/utils/BitcoinUtils.ts +3 -3
- package/src/utxo/OPNetLimitedProvider.ts +19 -10
- package/webpack.config.js +1 -0
- package/LICENSE.md +0 -62
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
1
2
|
import { BIP32Interface } from 'bip32';
|
|
2
3
|
import { Network } from 'bitcoinjs-lib';
|
|
3
4
|
import { ECPairInterface } from 'ecpair';
|
|
4
|
-
import { Address } from '@btc-vision/bsi-binary';
|
|
5
5
|
import { IWallet } from './interfaces/IWallet.js';
|
|
6
6
|
export declare class EcKeyPair {
|
|
7
|
-
static BIP32:
|
|
7
|
+
static BIP32: import("bip32").BIP32API;
|
|
8
8
|
static ECPair: import("ecpair").ECPairAPI;
|
|
9
9
|
static fromWIF(wif: string, network?: Network): ECPairInterface;
|
|
10
10
|
static fromPrivateKey(privateKey: Buffer, network?: Network): ECPairInterface;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Network } from 'bitcoinjs-lib';
|
|
2
|
-
import { ContractBaseMetadata } from '../ContractBaseMetadata.js';
|
|
3
1
|
import { Address } from '@btc-vision/bsi-binary';
|
|
2
|
+
import { Network } from 'bitcoinjs-lib';
|
|
4
3
|
import { ChainId } from '../../network/ChainId.js';
|
|
4
|
+
import { ContractBaseMetadata } from '../ContractBaseMetadata.js';
|
|
5
5
|
export declare class wBTC extends ContractBaseMetadata {
|
|
6
6
|
protected network: Network;
|
|
7
7
|
readonly tokenName: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
1
2
|
import { Transaction } from 'bitcoinjs-lib';
|
|
2
|
-
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
3
|
-
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
4
3
|
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
5
|
-
import {
|
|
4
|
+
import { ICustomTransactionParameters } from './builders/CustomScriptTransaction.js';
|
|
5
|
+
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
6
6
|
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
7
7
|
import { TransactionType } from './enums/TransactionType.js';
|
|
8
|
-
import {
|
|
8
|
+
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
9
9
|
export interface DeploymentResult {
|
|
10
10
|
readonly transaction: [string, string];
|
|
11
11
|
readonly contractAddress: Address;
|
|
@@ -38,7 +38,6 @@ export interface UnwrapResult {
|
|
|
38
38
|
readonly utxos: UTXO[];
|
|
39
39
|
}
|
|
40
40
|
export declare class TransactionFactory {
|
|
41
|
-
constructor();
|
|
42
41
|
createCustomScriptTransaction(interactionParameters: ICustomTransactionParameters): Promise<[string, string, UTXO[]]>;
|
|
43
42
|
signInteraction(interactionParameters: IInteractionParameters): Promise<[string, string, UTXO[]]>;
|
|
44
43
|
signDeployment(deploymentParameters: IDeploymentParameters): Promise<DeploymentResult>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
2
2
|
import { Network, Psbt } from 'bitcoinjs-lib';
|
|
3
|
+
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
3
4
|
import { Unisat } from '../types/Unisat.js';
|
|
4
|
-
import { Address } from '@btc-vision/bsi-binary';
|
|
5
5
|
declare global {
|
|
6
6
|
interface Window {
|
|
7
7
|
unisat?: Unisat;
|
|
@@ -66,8 +66,7 @@ export interface Unisat {
|
|
|
66
66
|
signPsbts(psbtHex: string[], psbtOptions: PsbtSignatureOptions): Promise<string[]>;
|
|
67
67
|
pushPsbt(psbtHex: string): Promise<string>;
|
|
68
68
|
on(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
69
|
-
on(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
70
|
-
on(event: 'chainChanged', listener: (network: UnisatNetwork) => void): void;
|
|
69
|
+
on(event: 'chainChanged' | 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
71
70
|
removeListener(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
72
71
|
removeListener(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
73
72
|
}
|
|
@@ -5,8 +5,8 @@ import { TransactionBuilder } from './TransactionBuilder.js';
|
|
|
5
5
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
6
6
|
import { Address } from '@btc-vision/bsi-binary';
|
|
7
7
|
export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
8
|
-
type: TransactionType.DEPLOYMENT;
|
|
9
8
|
static readonly MAXIMUM_CONTRACT_SIZE: number;
|
|
9
|
+
type: TransactionType.DEPLOYMENT;
|
|
10
10
|
protected readonly _contractAddress: Address;
|
|
11
11
|
protected tapLeafScript: TapLeafScript | null;
|
|
12
12
|
private targetScriptRedeem;
|
|
@@ -8,6 +8,6 @@ export declare class FundingTransaction extends TransactionBuilder<TransactionTy
|
|
|
8
8
|
protected splitInputsInto: number;
|
|
9
9
|
constructor(parameters: IFundingTransactionParameters);
|
|
10
10
|
protected buildTransaction(): Promise<void>;
|
|
11
|
-
protected splitInputs(amountSpent: bigint):
|
|
11
|
+
protected splitInputs(amountSpent: bigint): void;
|
|
12
12
|
protected getSignerKey(): Signer;
|
|
13
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
1
2
|
import { Network, Psbt, Signer, Transaction } from 'bitcoinjs-lib';
|
|
2
|
-
import { ITweakedTransactionData, TweakedTransaction } from '../shared/TweakedTransaction.js';
|
|
3
3
|
import { PsbtInputExtended, PsbtOutputExtended } from '../interfaces/Tap.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ITweakedTransactionData, TweakedTransaction } from '../shared/TweakedTransaction.js';
|
|
5
5
|
export interface PsbtTransactionData extends ITweakedTransactionData {
|
|
6
6
|
readonly psbt: Psbt;
|
|
7
7
|
readonly signer: Signer;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VaultUTXOs } from '../transaction/processor/PsbtTransaction.js';
|
|
2
2
|
export declare class BitcoinUtils {
|
|
3
|
-
static btcToSatoshi(btc: number):
|
|
3
|
+
static btcToSatoshi(btc: number): bigint;
|
|
4
4
|
static rndBytes(): Buffer;
|
|
5
5
|
static getUnsafeRandomValues(length: number): Buffer;
|
|
6
6
|
static opnetHash(data: Buffer): string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { FetchUTXOParams, FetchUTXOParamsMultiAddress, UTXO } from './interfaces/IUTXO.js';
|
|
2
|
-
import { WrappedGeneration } from '../wbtc/WrappedGenerationParameters.js';
|
|
3
|
-
import { BroadcastResponse } from './interfaces/BroadcastResponse.js';
|
|
4
1
|
import { Address } from '@btc-vision/bsi-binary';
|
|
5
2
|
import { UnwrapGeneration } from '../wbtc/UnwrapGeneration.js';
|
|
3
|
+
import { WrappedGeneration } from '../wbtc/WrappedGenerationParameters.js';
|
|
4
|
+
import { BroadcastResponse } from './interfaces/BroadcastResponse.js';
|
|
5
|
+
import { FetchUTXOParams, FetchUTXOParamsMultiAddress, UTXO } from './interfaces/IUTXO.js';
|
|
6
6
|
export declare class OPNetLimitedProvider {
|
|
7
7
|
private readonly opnetAPIUrl;
|
|
8
8
|
private readonly utxoPath;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { opcodes } from 'bitcoinjs-lib';
|
|
2
2
|
export var Features;
|
|
3
3
|
(function (Features) {
|
|
4
|
-
Features[Features["UNWRAP"] =
|
|
4
|
+
Features[Features["UNWRAP"] = 0] = "UNWRAP";
|
|
5
5
|
})(Features || (Features = {}));
|
|
6
|
+
export const FeatureOpCodes = {
|
|
7
|
+
[Features.UNWRAP]: opcodes.OP_16,
|
|
8
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Network } from 'bitcoinjs-lib';
|
|
2
|
-
import { Generator } from '../Generator.js';
|
|
3
2
|
import { Features } from '../Features.js';
|
|
3
|
+
import { Generator } from '../Generator.js';
|
|
4
4
|
export declare class CalldataGenerator extends Generator {
|
|
5
5
|
constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
|
|
6
6
|
static getPubKeyAsBuffer(witnessKeys: Buffer[], network: Network): Buffer;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { crypto, networks, opcodes, script } from 'bitcoinjs-lib';
|
|
2
2
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
3
|
-
import { Generator } from '../Generator.js';
|
|
4
3
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
4
|
+
import { FeatureOpCodes } from '../Features.js';
|
|
5
|
+
import { Generator } from '../Generator.js';
|
|
5
6
|
export class CalldataGenerator extends Generator {
|
|
6
7
|
constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
|
|
7
8
|
super(senderPubKey, contractSaltPubKey, network);
|
|
8
9
|
}
|
|
9
10
|
static getPubKeyAsBuffer(witnessKeys, network) {
|
|
10
11
|
let finalBuffer = Buffer.alloc(0);
|
|
11
|
-
for (
|
|
12
|
+
for (const pubKey of witnessKeys) {
|
|
12
13
|
const key = EcKeyPair.fromPublicKey(pubKey, network);
|
|
13
14
|
if (!key.compressed) {
|
|
14
15
|
throw new Error('Public key must be compressed');
|
|
@@ -69,7 +70,8 @@ export class CalldataGenerator extends Generator {
|
|
|
69
70
|
throw new Error('Minimum signatures must be provided');
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
const featureOpcodes = features.map((feature) => FeatureOpCodes[feature]);
|
|
74
|
+
compiledData = compiledData.concat(...featureOpcodes, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
|
|
73
75
|
const asm = compiledData.flat();
|
|
74
76
|
const compiled = script.compile(asm);
|
|
75
77
|
const decompiled = script.decompile(compiled);
|
|
@@ -13,11 +13,11 @@ export class MultiSignGenerator {
|
|
|
13
13
|
}
|
|
14
14
|
const minimumRequired = Buffer.alloc(1);
|
|
15
15
|
minimumRequired.writeUInt8(minimumSignatures);
|
|
16
|
-
vaultPublicKeys = vaultPublicKeys.filter((buf, index, self) => index === self.findIndex(otherBuf => buf.equals(otherBuf)));
|
|
16
|
+
vaultPublicKeys = vaultPublicKeys.filter((buf, index, self) => index === self.findIndex((otherBuf) => buf.equals(otherBuf)));
|
|
17
17
|
vaultPublicKeys = vaultPublicKeys.sort((a, b) => a.compare(b));
|
|
18
18
|
let included = false;
|
|
19
19
|
const data = vaultPublicKeys.map((key) => {
|
|
20
|
-
|
|
20
|
+
const newKey = toXOnly(key);
|
|
21
21
|
if (internal && !included)
|
|
22
22
|
included = internal.equals(newKey);
|
|
23
23
|
return newKey;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
1
2
|
import { BIP32Interface } from 'bip32';
|
|
2
3
|
import { Network } from 'bitcoinjs-lib';
|
|
3
4
|
import { ECPairInterface } from 'ecpair';
|
|
4
|
-
import { Address } from '@btc-vision/bsi-binary';
|
|
5
5
|
import { IWallet } from './interfaces/IWallet.js';
|
|
6
6
|
export declare class EcKeyPair {
|
|
7
|
-
static BIP32:
|
|
7
|
+
static BIP32: import("bip32").BIP32API;
|
|
8
8
|
static ECPair: import("ecpair").ECPairAPI;
|
|
9
9
|
static fromWIF(wif: string, network?: Network): ECPairInterface;
|
|
10
10
|
static fromPrivateKey(privateKey: Buffer, network?: Network): ECPairInterface;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import bip32 from 'bip32';
|
|
2
|
-
import { address, initEccLib, networks, payments } from 'bitcoinjs-lib';
|
|
3
|
-
import { ECPairFactory } from 'ecpair';
|
|
4
1
|
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
2
|
+
import bip32, { BIP32Factory } from 'bip32';
|
|
3
|
+
import { address, initEccLib, networks, payments } from 'bitcoinjs-lib';
|
|
5
4
|
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
|
|
5
|
+
import { ECPairFactory } from 'ecpair';
|
|
6
6
|
initEccLib(ecc);
|
|
7
|
-
const
|
|
7
|
+
const BIP32factory = typeof bip32 === 'function' ? bip32 : BIP32Factory;
|
|
8
|
+
if (!BIP32factory) {
|
|
9
|
+
throw new Error('Failed to load BIP32 library');
|
|
10
|
+
}
|
|
8
11
|
export class EcKeyPair {
|
|
9
12
|
static fromWIF(wif, network = networks.bitcoin) {
|
|
10
13
|
return this.ECPair.fromWIF(wif, network);
|
|
@@ -107,5 +110,5 @@ export class EcKeyPair {
|
|
|
107
110
|
return this.ECPair.fromPrivateKey(privKey, { network });
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
|
-
EcKeyPair.BIP32 =
|
|
113
|
+
EcKeyPair.BIP32 = BIP32factory(ecc);
|
|
111
114
|
EcKeyPair.ECPair = ECPairFactory(ecc);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Network } from 'bitcoinjs-lib';
|
|
2
|
-
import { ContractBaseMetadata } from '../ContractBaseMetadata.js';
|
|
3
1
|
import { Address } from '@btc-vision/bsi-binary';
|
|
2
|
+
import { Network } from 'bitcoinjs-lib';
|
|
4
3
|
import { ChainId } from '../../network/ChainId.js';
|
|
4
|
+
import { ContractBaseMetadata } from '../ContractBaseMetadata.js';
|
|
5
5
|
export declare class wBTC extends ContractBaseMetadata {
|
|
6
6
|
protected network: Network;
|
|
7
7
|
readonly tokenName: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { networks } from 'bitcoinjs-lib';
|
|
2
|
+
import { ChainId } from '../../network/ChainId.js';
|
|
2
3
|
import { ContractBaseMetadata } from '../ContractBaseMetadata.js';
|
|
3
4
|
import { WBTC_ADDRESS_FRACTAL, WBTC_ADDRESS_REGTEST, WBTC_ADDRESS_TESTNET } from '../tokens.js';
|
|
4
|
-
import { ChainId } from '../../network/ChainId.js';
|
|
5
5
|
export class wBTC extends ContractBaseMetadata {
|
|
6
6
|
constructor(network = networks.bitcoin, chainId = ChainId.Bitcoin) {
|
|
7
7
|
super(network);
|
|
@@ -20,7 +20,7 @@ export class wBTC extends ContractBaseMetadata {
|
|
|
20
20
|
case networks.testnet.bech32:
|
|
21
21
|
return WBTC_ADDRESS_TESTNET;
|
|
22
22
|
default:
|
|
23
|
-
throw new Error(`Invalid network: ${network}`);
|
|
23
|
+
throw new Error(`Invalid network: ${network.bech32}`);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
static getWBTCAddressForChain(chainId) {
|
package/build/metadata/tokens.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ChainId } from '../network/ChainId.js';
|
|
2
2
|
export const FACTORY_ADDRESS_REGTEST = 'bcrt1q9pf9fnpch9z2qrp5e3dgr2avzu3mypq3km2k40';
|
|
3
3
|
export const POOL_ADDRESS_REGTEST = 'bcrt1qg87nx9v9ln3qyadcn0llekzjn0hx8js46ztwky';
|
|
4
|
-
export const WBTC_ADDRESS_REGTEST = '
|
|
5
|
-
export const MOTO_ADDRESS_REGTEST = '
|
|
4
|
+
export const WBTC_ADDRESS_REGTEST = 'bcrt1qamv2ejattjgsc6k3yf3zqrp0wpuyedqgjmwx0v';
|
|
5
|
+
export const MOTO_ADDRESS_REGTEST = 'bcrt1qw8w4ejas2k22y54avv7hgrslg3cd0hme58h28r';
|
|
6
6
|
export const ROUTER_ADDRESS_REGTEST = 'bcrt1q9yd6mk324k0q4krmlxjky0pk65ul6hkf4u35e6';
|
|
7
7
|
export const FACTORY_ADDRESS_TESTNET = 'tb1qgev5kldhp5zvg6j8t9vl6x4phkrwn8nk9felxh';
|
|
8
8
|
export const POOL_ADDRESS_TESTNET = 'tb1q6a7yw353hjmresphupytw5vczpqxtg4yrupayk';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
1
2
|
import { initEccLib } from 'bitcoinjs-lib';
|
|
2
3
|
import { tapTweakHash } from 'bitcoinjs-lib/src/payments/bip341.js';
|
|
3
4
|
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
|
|
4
|
-
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
5
5
|
import { EcKeyPair } from '../keypair/EcKeyPair.js';
|
|
6
6
|
initEccLib(ecc);
|
|
7
7
|
export class TweakedSigner {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
1
2
|
import { Transaction } from 'bitcoinjs-lib';
|
|
2
|
-
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
3
|
-
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
4
3
|
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
5
|
-
import {
|
|
4
|
+
import { ICustomTransactionParameters } from './builders/CustomScriptTransaction.js';
|
|
5
|
+
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
6
6
|
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
7
7
|
import { TransactionType } from './enums/TransactionType.js';
|
|
8
|
-
import {
|
|
8
|
+
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
9
9
|
export interface DeploymentResult {
|
|
10
10
|
readonly transaction: [string, string];
|
|
11
11
|
readonly contractAddress: Address;
|
|
@@ -38,7 +38,6 @@ export interface UnwrapResult {
|
|
|
38
38
|
readonly utxos: UTXO[];
|
|
39
39
|
}
|
|
40
40
|
export declare class TransactionFactory {
|
|
41
|
-
constructor();
|
|
42
41
|
createCustomScriptTransaction(interactionParameters: ICustomTransactionParameters): Promise<[string, string, UTXO[]]>;
|
|
43
42
|
signInteraction(interactionParameters: IInteractionParameters): Promise<[string, string, UTXO[]]>;
|
|
44
43
|
signDeployment(deploymentParameters: IDeploymentParameters): Promise<DeploymentResult>;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
+
import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
|
|
2
|
+
import { wBTC } from '../metadata/contracts/wBTC.js';
|
|
3
|
+
import { CustomScriptTransaction, } from './builders/CustomScriptTransaction.js';
|
|
4
|
+
import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
|
|
1
5
|
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
2
6
|
import { InteractionTransaction } from './builders/InteractionTransaction.js';
|
|
3
|
-
import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
|
|
4
|
-
import { wBTC } from '../metadata/contracts/wBTC.js';
|
|
5
|
-
import { WrapTransaction } from './builders/WrapTransaction.js';
|
|
6
|
-
import { PSBTTypes } from './psbt/PSBTTypes.js';
|
|
7
7
|
import { UnwrapSegwitTransaction } from './builders/UnwrapSegwitTransaction.js';
|
|
8
8
|
import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { WrapTransaction } from './builders/WrapTransaction.js';
|
|
10
|
+
import { PSBTTypes } from './psbt/PSBTTypes.js';
|
|
11
11
|
export class TransactionFactory {
|
|
12
|
-
constructor() { }
|
|
13
12
|
async createCustomScriptTransaction(interactionParameters) {
|
|
14
13
|
if (!interactionParameters.to) {
|
|
15
14
|
throw new Error('Field "to" not provided.');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
2
2
|
import { Network, Psbt } from 'bitcoinjs-lib';
|
|
3
|
+
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
3
4
|
import { Unisat } from '../types/Unisat.js';
|
|
4
|
-
import { Address } from '@btc-vision/bsi-binary';
|
|
5
5
|
declare global {
|
|
6
6
|
interface Window {
|
|
7
7
|
unisat?: Unisat;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
2
1
|
import { networks, Psbt } from 'bitcoinjs-lib';
|
|
3
|
-
import { UnisatNetwork } from '../types/Unisat.js';
|
|
4
2
|
import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
|
|
3
|
+
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
4
|
+
import { UnisatNetwork } from '../types/Unisat.js';
|
|
5
5
|
export class UnisatSigner extends CustomKeypair {
|
|
6
6
|
constructor() {
|
|
7
7
|
super();
|
|
@@ -87,7 +87,7 @@ export class UnisatSigner extends CustomKeypair {
|
|
|
87
87
|
throw new Error('Not implemented: verify');
|
|
88
88
|
}
|
|
89
89
|
async signTaprootInput(transaction, i, sighashTypes) {
|
|
90
|
-
|
|
90
|
+
const firstSignature = await this.signTweaked(transaction, i, sighashTypes, false);
|
|
91
91
|
this.combine(transaction, firstSignature, i);
|
|
92
92
|
}
|
|
93
93
|
async signInput(transaction, i, sighashTypes) {
|
|
@@ -66,8 +66,7 @@ export interface Unisat {
|
|
|
66
66
|
signPsbts(psbtHex: string[], psbtOptions: PsbtSignatureOptions): Promise<string[]>;
|
|
67
67
|
pushPsbt(psbtHex: string): Promise<string>;
|
|
68
68
|
on(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
69
|
-
on(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
70
|
-
on(event: 'chainChanged', listener: (network: UnisatNetwork) => void): void;
|
|
69
|
+
on(event: 'chainChanged' | 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
71
70
|
removeListener(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
72
71
|
removeListener(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
73
72
|
}
|
|
@@ -58,7 +58,7 @@ export class CustomScriptTransaction extends TransactionBuilder {
|
|
|
58
58
|
if (!this.to) {
|
|
59
59
|
this.to = this.getScriptAddress();
|
|
60
60
|
}
|
|
61
|
-
const selectedRedeem =
|
|
61
|
+
const selectedRedeem = this.contractSigner
|
|
62
62
|
? this.targetScriptRedeem
|
|
63
63
|
: this.leftOverFundsScriptRedeem;
|
|
64
64
|
if (!selectedRedeem) {
|
|
@@ -108,7 +108,7 @@ export class CustomScriptTransaction extends TransactionBuilder {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
generateTapData() {
|
|
111
|
-
const selectedRedeem =
|
|
111
|
+
const selectedRedeem = this.contractSigner
|
|
112
112
|
? this.targetScriptRedeem
|
|
113
113
|
: this.leftOverFundsScriptRedeem;
|
|
114
114
|
if (!selectedRedeem) {
|
|
@@ -5,8 +5,8 @@ import { TransactionBuilder } from './TransactionBuilder.js';
|
|
|
5
5
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
6
6
|
import { Address } from '@btc-vision/bsi-binary';
|
|
7
7
|
export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
8
|
-
type: TransactionType.DEPLOYMENT;
|
|
9
8
|
static readonly MAXIMUM_CONTRACT_SIZE: number;
|
|
9
|
+
type: TransactionType.DEPLOYMENT;
|
|
10
10
|
protected readonly _contractAddress: Address;
|
|
11
11
|
protected tapLeafScript: TapLeafScript | null;
|
|
12
12
|
private targetScriptRedeem;
|
|
@@ -64,7 +64,7 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
64
64
|
if (!this.to) {
|
|
65
65
|
this.to = this.getScriptAddress();
|
|
66
66
|
}
|
|
67
|
-
const selectedRedeem =
|
|
67
|
+
const selectedRedeem = this.contractSigner
|
|
68
68
|
? this.targetScriptRedeem
|
|
69
69
|
: this.leftOverFundsScriptRedeem;
|
|
70
70
|
if (!selectedRedeem) {
|
|
@@ -114,7 +114,7 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
generateTapData() {
|
|
117
|
-
const selectedRedeem =
|
|
117
|
+
const selectedRedeem = this.contractSigner
|
|
118
118
|
? this.targetScriptRedeem
|
|
119
119
|
: this.leftOverFundsScriptRedeem;
|
|
120
120
|
if (!selectedRedeem) {
|
|
@@ -8,6 +8,6 @@ export declare class FundingTransaction extends TransactionBuilder<TransactionTy
|
|
|
8
8
|
protected splitInputsInto: number;
|
|
9
9
|
constructor(parameters: IFundingTransactionParameters);
|
|
10
10
|
protected buildTransaction(): Promise<void>;
|
|
11
|
-
protected splitInputs(amountSpent: bigint):
|
|
11
|
+
protected splitInputs(amountSpent: bigint): void;
|
|
12
12
|
protected getSignerKey(): Signer;
|
|
13
13
|
}
|
|
@@ -23,7 +23,7 @@ export class FundingTransaction extends TransactionBuilder {
|
|
|
23
23
|
amountSpent += this.getTransactionOPNetFee();
|
|
24
24
|
}
|
|
25
25
|
if (this.splitInputsInto > 1) {
|
|
26
|
-
|
|
26
|
+
this.splitInputs(amountSpent);
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
29
29
|
this.addOutput({
|
|
@@ -33,7 +33,7 @@ export class FundingTransaction extends TransactionBuilder {
|
|
|
33
33
|
}
|
|
34
34
|
await this.addRefundOutput(amountSpent);
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
splitInputs(amountSpent) {
|
|
37
37
|
if (!this.to) {
|
|
38
38
|
throw new Error('Recipient address is required');
|
|
39
39
|
}
|
|
@@ -64,7 +64,7 @@ export class MultiSignTransaction extends TransactionBuilder {
|
|
|
64
64
|
static verifyIfSigned(psbt, signerPubKey) {
|
|
65
65
|
let alreadySigned = false;
|
|
66
66
|
for (let i = 1; i < psbt.data.inputs.length; i++) {
|
|
67
|
-
|
|
67
|
+
const input = psbt.data.inputs[i];
|
|
68
68
|
if (!input.finalScriptWitness) {
|
|
69
69
|
continue;
|
|
70
70
|
}
|
|
@@ -86,11 +86,11 @@ export class MultiSignTransaction extends TransactionBuilder {
|
|
|
86
86
|
let signed = false;
|
|
87
87
|
let final = true;
|
|
88
88
|
for (let i = originalInputCount; i < psbt.data.inputs.length; i++) {
|
|
89
|
-
|
|
89
|
+
const input = psbt.data.inputs[i];
|
|
90
90
|
if (!input.tapInternalKey) {
|
|
91
91
|
input.tapInternalKey = toXOnly(MultiSignTransaction.numsPoint);
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
const partialSignatures = [];
|
|
94
94
|
if (input.finalScriptWitness) {
|
|
95
95
|
const decoded = TransactionBuilder.readScriptWitnessToWitnessStack(input.finalScriptWitness);
|
|
96
96
|
input.tapLeafScript = [
|
|
@@ -149,11 +149,11 @@ export class MultiSignTransaction extends TransactionBuilder {
|
|
|
149
149
|
let finalizedInputs = 0;
|
|
150
150
|
for (let i = startIndex; i < psbt.data.inputs.length; i++) {
|
|
151
151
|
try {
|
|
152
|
-
|
|
152
|
+
const input = psbt.data.inputs[i];
|
|
153
153
|
if (!input.tapInternalKey) {
|
|
154
154
|
input.tapInternalKey = toXOnly(MultiSignTransaction.numsPoint);
|
|
155
155
|
}
|
|
156
|
-
|
|
156
|
+
const partialSignatures = [];
|
|
157
157
|
if (input.finalScriptWitness) {
|
|
158
158
|
const decoded = TransactionBuilder.readScriptWitnessToWitnessStack(input.finalScriptWitness);
|
|
159
159
|
for (let j = 0; j < decoded.length - 2; j += 3) {
|
|
@@ -341,9 +341,9 @@ MultiSignTransaction.partialFinalizer = (inputIndex, input, partialSignatures, o
|
|
|
341
341
|
.flat();
|
|
342
342
|
}
|
|
343
343
|
else {
|
|
344
|
-
for (
|
|
344
|
+
for (const pubKey of orderedPubKeys) {
|
|
345
345
|
let found = false;
|
|
346
|
-
for (
|
|
346
|
+
for (const sig of input.tapScriptSig) {
|
|
347
347
|
if (sig.pubkey.equals(toXOnly(pubKey))) {
|
|
348
348
|
scriptSolution.push(sig.signature);
|
|
349
349
|
found = true;
|
|
@@ -57,7 +57,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
57
57
|
async buildTransaction() {
|
|
58
58
|
if (!this.to)
|
|
59
59
|
throw new Error('To address is required');
|
|
60
|
-
const selectedRedeem =
|
|
60
|
+
const selectedRedeem = this.scriptSigner
|
|
61
61
|
? this.targetScriptRedeem
|
|
62
62
|
: this.leftOverFundsScriptRedeem;
|
|
63
63
|
if (!selectedRedeem) {
|
|
@@ -92,7 +92,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
94
|
for (let i = 0; i < transaction.data.inputs.length; i++) {
|
|
95
|
-
|
|
95
|
+
const input = transaction.data.inputs[i];
|
|
96
96
|
let finalized = false;
|
|
97
97
|
let signed = false;
|
|
98
98
|
try {
|
|
@@ -133,7 +133,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
|
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
135
|
generateTapData() {
|
|
136
|
-
const selectedRedeem =
|
|
136
|
+
const selectedRedeem = this.scriptSigner
|
|
137
137
|
? this.targetScriptRedeem
|
|
138
138
|
: this.leftOverFundsScriptRedeem;
|
|
139
139
|
if (!selectedRedeem) {
|
|
@@ -203,7 +203,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
203
203
|
if (value < TransactionBuilder.MINIMUM_DUST) {
|
|
204
204
|
throw new Error(`Value to send is less than the minimum dust ${value} < ${TransactionBuilder.MINIMUM_DUST}`);
|
|
205
205
|
}
|
|
206
|
-
for (
|
|
206
|
+
for (const output of this.outputs) {
|
|
207
207
|
if ('address' in output && output.address === this.to) {
|
|
208
208
|
output.value += Number(value);
|
|
209
209
|
return;
|
|
@@ -219,14 +219,14 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
219
219
|
}
|
|
220
220
|
calculateTotalUTXOAmount() {
|
|
221
221
|
let total = 0n;
|
|
222
|
-
for (
|
|
222
|
+
for (const utxo of this.utxos) {
|
|
223
223
|
total += utxo.value;
|
|
224
224
|
}
|
|
225
225
|
return total;
|
|
226
226
|
}
|
|
227
227
|
calculateTotalVOutAmount() {
|
|
228
228
|
let total = 0n;
|
|
229
|
-
for (
|
|
229
|
+
for (const utxo of this.utxos) {
|
|
230
230
|
total += utxo.value;
|
|
231
231
|
}
|
|
232
232
|
return total;
|
|
@@ -266,7 +266,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
266
266
|
return this.tapData.output;
|
|
267
267
|
}
|
|
268
268
|
verifyUTXOValidity() {
|
|
269
|
-
for (
|
|
269
|
+
for (const utxo of this.utxos) {
|
|
270
270
|
if (!utxo.scriptPubKey) {
|
|
271
271
|
throw new Error('Address is required');
|
|
272
272
|
}
|
|
@@ -274,7 +274,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
274
274
|
}
|
|
275
275
|
async setFeeOutput(output) {
|
|
276
276
|
const initialValue = output.value;
|
|
277
|
-
|
|
277
|
+
const fee = await this.estimateTransactionFees();
|
|
278
278
|
output.value = initialValue - Number(fee);
|
|
279
279
|
if (output.value < TransactionBuilder.MINIMUM_DUST) {
|
|
280
280
|
this.feeOutput = null;
|
|
@@ -284,7 +284,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
284
284
|
}
|
|
285
285
|
else {
|
|
286
286
|
this.feeOutput = output;
|
|
287
|
-
|
|
287
|
+
const fee = await this.estimateTransactionFees();
|
|
288
288
|
if (fee > BigInt(initialValue)) {
|
|
289
289
|
throw new Error(`estimateTransactionFees: Insufficient funds to pay the fees. Fee: ${fee} > Value: ${initialValue}. Total input: ${this.totalInputAmount} sat`);
|
|
290
290
|
}
|
|
@@ -64,7 +64,7 @@ export class UnwrapTransaction extends SharedInteractionTransaction {
|
|
|
64
64
|
}
|
|
65
65
|
getRefund() {
|
|
66
66
|
let losses = -currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT;
|
|
67
|
-
for (
|
|
67
|
+
for (const vault of this.vaultUTXOs) {
|
|
68
68
|
for (let i = 0; i < vault.utxos.length; i++) {
|
|
69
69
|
losses += currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT;
|
|
70
70
|
}
|
|
@@ -72,13 +72,13 @@ export class UnwrapTransaction extends SharedInteractionTransaction {
|
|
|
72
72
|
return losses;
|
|
73
73
|
}
|
|
74
74
|
getFeeLossOrRefund() {
|
|
75
|
-
|
|
75
|
+
const refund = this.getRefund();
|
|
76
76
|
return refund - this.estimatedFeeLoss;
|
|
77
77
|
}
|
|
78
78
|
mergeVaults() {
|
|
79
79
|
const totalInputAmount = this.getVaultTotalOutputAmount(this.vaultUTXOs);
|
|
80
80
|
let refund = this.getRefund();
|
|
81
|
-
|
|
81
|
+
const outputLeftAmount = totalInputAmount - refund - this.amount;
|
|
82
82
|
if (outputLeftAmount === currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT) {
|
|
83
83
|
refund += currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT;
|
|
84
84
|
}
|
|
@@ -90,7 +90,7 @@ export class UnwrapTransaction extends SharedInteractionTransaction {
|
|
|
90
90
|
if (!bestVault) {
|
|
91
91
|
throw new Error('No vaults provided');
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
const hasConsolidation = outputLeftAmount > currentConsensusConfig.VAULT_MINIMUM_AMOUNT &&
|
|
94
94
|
outputLeftAmount - currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT !== 0n;
|
|
95
95
|
if (hasConsolidation) {
|
|
96
96
|
this.success(`Consolidating output with ${outputLeftAmount} sat.`);
|
|
@@ -76,7 +76,7 @@ export class WrapTransaction extends SharedInteractionTransaction {
|
|
|
76
76
|
async buildTransaction() {
|
|
77
77
|
if (!this.to)
|
|
78
78
|
throw new Error('To address is required');
|
|
79
|
-
const selectedRedeem =
|
|
79
|
+
const selectedRedeem = this.scriptSigner
|
|
80
80
|
? this.targetScriptRedeem
|
|
81
81
|
: this.leftOverFundsScriptRedeem;
|
|
82
82
|
if (!selectedRedeem) {
|