@btc-vision/transaction 1.0.110 → 1.0.112
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/browser/_version.d.ts +1 -1
- package/browser/generators/Generator.d.ts +2 -0
- package/browser/generators/builders/DeploymentGenerator.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/keypair/EcKeyPair.d.ts +2 -0
- package/browser/transaction/builders/DeploymentTransaction.d.ts +3 -0
- package/browser/transaction/builders/SharedInteractionTransaction.d.ts +1 -0
- package/browser/transaction/builders/TransactionBuilder.d.ts +1 -0
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/browser/verification/TapscriptVerificator.d.ts +2 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/generators/Generator.d.ts +2 -0
- package/build/generators/Generator.js +5 -0
- package/build/generators/builders/CalldataGenerator.js +4 -2
- package/build/generators/builders/DeploymentGenerator.d.ts +1 -1
- package/build/generators/builders/DeploymentGenerator.js +13 -7
- package/build/keypair/EcKeyPair.d.ts +2 -0
- package/build/keypair/EcKeyPair.js +17 -0
- package/build/transaction/builders/DeploymentTransaction.d.ts +3 -0
- package/build/transaction/builders/DeploymentTransaction.js +21 -6
- package/build/transaction/builders/FundingTransaction.js +18 -4
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +1 -0
- package/build/transaction/builders/SharedInteractionTransaction.js +2 -1
- package/build/transaction/builders/TransactionBuilder.d.ts +1 -0
- package/build/transaction/builders/TransactionBuilder.js +7 -2
- package/build/transaction/builders/UnwrapTransaction.js +1 -1
- package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/build/verification/TapscriptVerificator.d.ts +2 -1
- package/build/verification/TapscriptVerificator.js +3 -3
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/generators/Generator.ts +12 -0
- package/src/generators/builders/CalldataGenerator.ts +6 -3
- package/src/generators/builders/DeploymentGenerator.ts +21 -8
- package/src/keypair/EcKeyPair.ts +40 -1
- package/src/transaction/builders/DeploymentTransaction.ts +31 -4
- package/src/transaction/builders/FundingTransaction.ts +16 -4
- package/src/transaction/builders/SharedInteractionTransaction.ts +3 -1
- package/src/transaction/builders/TransactionBuilder.ts +18 -2
- package/src/transaction/builders/UnwrapTransaction.ts +1 -1
- package/src/transaction/interfaces/ITransactionParameters.ts +2 -0
- package/src/verification/TapscriptVerificator.ts +5 -3
package/src/keypair/EcKeyPair.ts
CHANGED
|
@@ -181,6 +181,28 @@ export class EcKeyPair {
|
|
|
181
181
|
return !!address.toOutputScript(contractAddress, network);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Get the legacy segwit address from a keypair
|
|
186
|
+
* @param {ECPairInterface} keyPair - The keypair to get the address for
|
|
187
|
+
* @param {Network} network - The network to use
|
|
188
|
+
* @returns {Address} - The legacy address
|
|
189
|
+
*/
|
|
190
|
+
public static getLegacySegwitAddress(
|
|
191
|
+
keyPair: ECPairInterface,
|
|
192
|
+
network: Network = networks.bitcoin,
|
|
193
|
+
): Address {
|
|
194
|
+
const wallet = payments.p2sh({
|
|
195
|
+
redeem: payments.p2wpkh({ pubkey: keyPair.publicKey, network: network }),
|
|
196
|
+
network: network,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
if (!wallet.address) {
|
|
200
|
+
throw new Error('Failed to generate wallet');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return wallet.address;
|
|
204
|
+
}
|
|
205
|
+
|
|
184
206
|
/**
|
|
185
207
|
* Get the legacy address from a keypair
|
|
186
208
|
* @param {ECPairInterface} keyPair - The keypair to get the address for
|
|
@@ -192,7 +214,6 @@ export class EcKeyPair {
|
|
|
192
214
|
network: Network = networks.bitcoin,
|
|
193
215
|
): Address {
|
|
194
216
|
const wallet = payments.p2pkh({ pubkey: keyPair.publicKey, network: network });
|
|
195
|
-
|
|
196
217
|
if (!wallet.address) {
|
|
197
218
|
throw new Error('Failed to generate wallet');
|
|
198
219
|
}
|
|
@@ -200,6 +221,24 @@ export class EcKeyPair {
|
|
|
200
221
|
return wallet.address;
|
|
201
222
|
}
|
|
202
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Get the legacy address from a keypair
|
|
226
|
+
* @param {ECPairInterface} keyPair - The keypair to get the address for
|
|
227
|
+
* @param {Network} network - The network to use
|
|
228
|
+
* @returns {Address} - The legacy address
|
|
229
|
+
*/
|
|
230
|
+
public static getP2PKAddress(
|
|
231
|
+
keyPair: ECPairInterface,
|
|
232
|
+
network: Network = networks.bitcoin,
|
|
233
|
+
): Address {
|
|
234
|
+
const wallet = payments.p2pk({ pubkey: keyPair.publicKey, network: network });
|
|
235
|
+
if (!wallet.output) {
|
|
236
|
+
throw new Error('Failed to generate wallet');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return '0x' + wallet.output.toString('hex');
|
|
240
|
+
}
|
|
241
|
+
|
|
203
242
|
/**
|
|
204
243
|
* Generate a random keypair
|
|
205
244
|
* @param {Network} network - The network to use
|
|
@@ -12,6 +12,7 @@ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
|
|
|
12
12
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
13
13
|
import { AddressGenerator } from '../../generators/AddressGenerator.js';
|
|
14
14
|
import { Address } from '@btc-vision/bsi-binary';
|
|
15
|
+
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
15
16
|
|
|
16
17
|
export class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
17
18
|
public static readonly MAXIMUM_CONTRACT_SIZE = 128 * 1024;
|
|
@@ -64,6 +65,12 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
64
65
|
*/
|
|
65
66
|
private readonly bytecode: Buffer;
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Constructor calldata
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
private readonly calldata?: Buffer;
|
|
73
|
+
|
|
67
74
|
/**
|
|
68
75
|
* The contract signer
|
|
69
76
|
* @private
|
|
@@ -80,10 +87,12 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
80
87
|
super(parameters);
|
|
81
88
|
|
|
82
89
|
this.bytecode = Compressor.compress(parameters.bytecode);
|
|
83
|
-
|
|
90
|
+
this.verifyBytecode();
|
|
84
91
|
|
|
85
|
-
if (
|
|
86
|
-
|
|
92
|
+
if (parameters.calldata) {
|
|
93
|
+
this.calldata = parameters.calldata;
|
|
94
|
+
this.verifyCalldata();
|
|
95
|
+
}
|
|
87
96
|
|
|
88
97
|
this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
|
|
89
98
|
|
|
@@ -91,7 +100,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
91
100
|
this.contractSigner = EcKeyPair.fromSeedKeyPair(this.contractSeed, this.network);
|
|
92
101
|
|
|
93
102
|
this.deploymentGenerator = new DeploymentGenerator(
|
|
94
|
-
this.
|
|
103
|
+
this.signer.publicKey,
|
|
95
104
|
this.contractSignerXOnlyPubKey(),
|
|
96
105
|
this.network,
|
|
97
106
|
);
|
|
@@ -99,6 +108,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
99
108
|
this.compiledTargetScript = this.deploymentGenerator.compile(
|
|
100
109
|
this.bytecode,
|
|
101
110
|
this.randomBytes,
|
|
111
|
+
this.calldata,
|
|
102
112
|
);
|
|
103
113
|
|
|
104
114
|
this.scriptTree = this.getScriptTree();
|
|
@@ -243,6 +253,23 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
243
253
|
};
|
|
244
254
|
}
|
|
245
255
|
|
|
256
|
+
private verifyCalldata(): void {
|
|
257
|
+
if (
|
|
258
|
+
this.calldata &&
|
|
259
|
+
this.calldata.length > SharedInteractionTransaction.MAXIMUM_CALLDATA_SIZE
|
|
260
|
+
) {
|
|
261
|
+
throw new Error('Calldata size overflow.');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private verifyBytecode(): void {
|
|
266
|
+
if (!this.bytecode) throw new Error('Bytecode is required');
|
|
267
|
+
|
|
268
|
+
if (this.bytecode.length > DeploymentTransaction.MAXIMUM_CONTRACT_SIZE) {
|
|
269
|
+
throw new Error('Contract size overflow.');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
246
273
|
/**
|
|
247
274
|
* Generate the contract seed for the deployment
|
|
248
275
|
* @private
|
|
@@ -27,6 +27,11 @@ export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDI
|
|
|
27
27
|
|
|
28
28
|
if (this.splitInputsInto > 1) {
|
|
29
29
|
this.splitInputs(this.amount);
|
|
30
|
+
} else if (this.isPubKeyDestination) {
|
|
31
|
+
this.addOutput({
|
|
32
|
+
value: Number(this.amount),
|
|
33
|
+
script: Buffer.from(this.to.slice(2), 'hex'),
|
|
34
|
+
});
|
|
30
35
|
} else {
|
|
31
36
|
this.addOutput({
|
|
32
37
|
value: Number(this.amount),
|
|
@@ -45,10 +50,17 @@ export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDI
|
|
|
45
50
|
const splitAmount = amountSpent / BigInt(this.splitInputsInto);
|
|
46
51
|
|
|
47
52
|
for (let i = 0; i < this.splitInputsInto; i++) {
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
if (this.isPubKeyDestination) {
|
|
54
|
+
this.addOutput({
|
|
55
|
+
value: Number(splitAmount),
|
|
56
|
+
script: Buffer.from(this.to.slice(2), 'hex'),
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
this.addOutput({
|
|
60
|
+
value: Number(splitAmount),
|
|
61
|
+
address: this.to,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
52
64
|
}
|
|
53
65
|
}
|
|
54
66
|
|
|
@@ -18,6 +18,8 @@ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
|
|
|
18
18
|
export abstract class SharedInteractionTransaction<
|
|
19
19
|
T extends TransactionType,
|
|
20
20
|
> extends TransactionBuilder<T> {
|
|
21
|
+
public static readonly MAXIMUM_CALLDATA_SIZE = 1024 * 1024; // 1MB
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* Random salt for the interaction
|
|
23
25
|
* @type {Buffer}
|
|
@@ -71,7 +73,7 @@ export abstract class SharedInteractionTransaction<
|
|
|
71
73
|
this.scriptSigner = this.generateKeyPairFromSeed();
|
|
72
74
|
|
|
73
75
|
this.calldataGenerator = new CalldataGenerator(
|
|
74
|
-
this.
|
|
76
|
+
this.signer.publicKey,
|
|
75
77
|
this.scriptSignerXOnlyPubKey(),
|
|
76
78
|
this.network,
|
|
77
79
|
);
|
|
@@ -107,6 +107,12 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
107
107
|
*/
|
|
108
108
|
protected _maximumFeeRate: number = 100000000;
|
|
109
109
|
|
|
110
|
+
/**
|
|
111
|
+
* @description Is the destionation P2PK
|
|
112
|
+
* @protected
|
|
113
|
+
*/
|
|
114
|
+
protected isPubKeyDestination: boolean;
|
|
115
|
+
|
|
110
116
|
protected constructor(parameters: ITransactionParameters) {
|
|
111
117
|
super(parameters);
|
|
112
118
|
|
|
@@ -121,6 +127,8 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
121
127
|
this.utxos = parameters.utxos;
|
|
122
128
|
this.to = parameters.to || undefined;
|
|
123
129
|
|
|
130
|
+
this.isPubKeyDestination = this.to ? this.to.startsWith('0x') : false;
|
|
131
|
+
|
|
124
132
|
this.optionalOutputs = parameters.optionalOutputs;
|
|
125
133
|
|
|
126
134
|
this.from = TransactionBuilder.getFrom(
|
|
@@ -231,7 +239,11 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
231
239
|
throw new Error('No UTXOs specified');
|
|
232
240
|
}
|
|
233
241
|
|
|
234
|
-
if (
|
|
242
|
+
if (
|
|
243
|
+
this.to &&
|
|
244
|
+
!this.isPubKeyDestination &&
|
|
245
|
+
!EcKeyPair.verifyContractAddress(this.to, this.network)
|
|
246
|
+
) {
|
|
235
247
|
throw new Error(
|
|
236
248
|
'Invalid contract address. The contract address must be a taproot address.',
|
|
237
249
|
);
|
|
@@ -261,7 +273,11 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
261
273
|
public async generateTransactionMinimalSignatures(
|
|
262
274
|
checkPartialSigs: boolean = false,
|
|
263
275
|
): Promise<void> {
|
|
264
|
-
if (
|
|
276
|
+
if (
|
|
277
|
+
this.to &&
|
|
278
|
+
!this.isPubKeyDestination &&
|
|
279
|
+
!EcKeyPair.verifyContractAddress(this.to, this.network)
|
|
280
|
+
) {
|
|
265
281
|
throw new Error(
|
|
266
282
|
'Invalid contract address. The contract address must be a taproot address.',
|
|
267
283
|
);
|
|
@@ -109,7 +109,7 @@ export class UnwrapTransaction extends SharedInteractionTransaction<TransactionT
|
|
|
109
109
|
this.contractSecret = this.generateSecret();
|
|
110
110
|
|
|
111
111
|
this.calldataGenerator = new CalldataGenerator(
|
|
112
|
-
|
|
112
|
+
this.signer.publicKey,
|
|
113
113
|
this.scriptSignerXOnlyPubKey(),
|
|
114
114
|
this.network,
|
|
115
115
|
);
|
|
@@ -5,6 +5,7 @@ import { ITweakedTransactionData } from '../shared/TweakedTransaction.js';
|
|
|
5
5
|
import { VaultUTXOs } from '../processor/PsbtTransaction.js';
|
|
6
6
|
import { ChainId } from '../../network/ChainId.js';
|
|
7
7
|
import { PsbtOutputExtended } from './Tap.js';
|
|
8
|
+
|
|
8
9
|
export interface ITransactionParameters extends ITweakedTransactionData {
|
|
9
10
|
readonly from?: Address;
|
|
10
11
|
readonly to?: Address;
|
|
@@ -58,6 +59,7 @@ export interface IUnwrapParameters extends Omit<SharedInteractionParameters, 'op
|
|
|
58
59
|
|
|
59
60
|
export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'> {
|
|
60
61
|
readonly bytecode: Buffer;
|
|
62
|
+
readonly calldata?: Buffer;
|
|
61
63
|
|
|
62
64
|
readonly randomBytes?: Buffer;
|
|
63
65
|
}
|
|
@@ -6,10 +6,11 @@ import { TransactionBuilder } from '../transaction/builders/TransactionBuilder.j
|
|
|
6
6
|
import { AddressGenerator } from '../generators/AddressGenerator.js';
|
|
7
7
|
|
|
8
8
|
export interface ContractAddressVerificationParams {
|
|
9
|
-
readonly
|
|
9
|
+
readonly deployerPubKey: Buffer;
|
|
10
10
|
readonly contractSaltPubKey: Buffer;
|
|
11
11
|
readonly originalSalt: Buffer;
|
|
12
12
|
readonly bytecode: Buffer;
|
|
13
|
+
readonly calldata?: Buffer;
|
|
13
14
|
readonly network?: Network;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -21,7 +22,7 @@ export class TapscriptVerificator {
|
|
|
21
22
|
): string | undefined {
|
|
22
23
|
const network = params.network || networks.bitcoin;
|
|
23
24
|
const scriptBuilder: DeploymentGenerator = new DeploymentGenerator(
|
|
24
|
-
params.
|
|
25
|
+
params.deployerPubKey,
|
|
25
26
|
toXOnly(params.contractSaltPubKey),
|
|
26
27
|
network,
|
|
27
28
|
);
|
|
@@ -29,6 +30,7 @@ export class TapscriptVerificator {
|
|
|
29
30
|
const compiledTargetScript: Buffer = scriptBuilder.compile(
|
|
30
31
|
params.bytecode,
|
|
31
32
|
params.originalSalt,
|
|
33
|
+
params.calldata,
|
|
32
34
|
);
|
|
33
35
|
|
|
34
36
|
const scriptTree: Taptree = [
|
|
@@ -78,7 +80,7 @@ export class TapscriptVerificator {
|
|
|
78
80
|
const network = params.network || networks.bitcoin;
|
|
79
81
|
|
|
80
82
|
const transactionData: Payment = {
|
|
81
|
-
internalPubkey: params.
|
|
83
|
+
internalPubkey: toXOnly(params.deployerPubKey),
|
|
82
84
|
network: network,
|
|
83
85
|
scriptTree: scriptTree,
|
|
84
86
|
};
|