@btc-vision/transaction 1.7.14 → 1.7.16
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/Features.d.ts +6 -0
- package/browser/generators/builders/CalldataGenerator.d.ts +1 -1
- package/browser/generators/builders/LegacyCalldataGenerator.d.ts +1 -1
- package/browser/generators/builders/P2WDAGenerator.d.ts +1 -1
- package/browser/index.js +1 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/epoch/ChallengeSolution.js +1 -1
- package/build/generators/Features.d.ts +6 -0
- package/build/generators/Features.js +6 -0
- package/build/generators/builders/CalldataGenerator.d.ts +1 -1
- package/build/generators/builders/CalldataGenerator.js +10 -6
- package/build/generators/builders/DeploymentGenerator.js +4 -2
- package/build/generators/builders/LegacyCalldataGenerator.d.ts +1 -1
- package/build/generators/builders/LegacyCalldataGenerator.js +10 -6
- package/build/generators/builders/P2WDAGenerator.d.ts +1 -1
- package/build/generators/builders/P2WDAGenerator.js +2 -1
- package/build/transaction/builders/DeploymentTransaction.js +2 -1
- package/build/transaction/builders/InteractionTransaction.js +3 -1
- package/build/transaction/builders/InteractionTransactionP2WDA.js +3 -1
- package/build/transaction/builders/TransactionBuilder.js +2 -1
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/epoch/ChallengeSolution.ts +5 -1
- package/src/generators/Features.ts +7 -0
- package/src/generators/builders/CalldataGenerator.ts +14 -7
- package/src/generators/builders/DeploymentGenerator.ts +9 -2
- package/src/generators/builders/LegacyCalldataGenerator.ts +14 -7
- package/src/generators/builders/P2WDAGenerator.ts +4 -2
- package/src/transaction/builders/DeploymentTransaction.ts +2 -1
- package/src/transaction/builders/InteractionTransaction.ts +3 -1
- package/src/transaction/builders/InteractionTransactionP2WDA.ts +3 -1
- package/src/transaction/builders/TransactionBuilder.ts +2 -1
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.7.
|
|
1
|
+
export declare const version = "1.7.16";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.7.
|
|
1
|
+
export const version = '1.7.16';
|
|
@@ -31,7 +31,7 @@ export class ChallengeSubmission {
|
|
|
31
31
|
signatureDataWriter.writeBytes(this.graffiti);
|
|
32
32
|
}
|
|
33
33
|
const buffer = signatureDataWriter.getBuffer();
|
|
34
|
-
return MessageSigner.verifySignature(this.publicKey, buffer, this.signature);
|
|
34
|
+
return MessageSigner.verifySignature(this.publicKey.tweakedPublicKeyToBuffer(), buffer, this.signature);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
export class ChallengeSolution {
|
|
@@ -6,9 +6,15 @@ export declare enum Features {
|
|
|
6
6
|
EPOCH_SUBMISSION = 2,
|
|
7
7
|
MLDSA_LINK_PUBKEY = 4
|
|
8
8
|
}
|
|
9
|
+
export declare enum FeaturePriority {
|
|
10
|
+
ACCESS_LIST = 1,
|
|
11
|
+
EPOCH_SUBMISSION = 2,
|
|
12
|
+
MLDSA_LINK_PUBKEY = 3
|
|
13
|
+
}
|
|
9
14
|
export interface Feature<T extends Features> {
|
|
10
15
|
opcode: T;
|
|
11
16
|
data: unknown;
|
|
17
|
+
priority: number;
|
|
12
18
|
}
|
|
13
19
|
export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
|
|
14
20
|
data: LoadedStorage;
|
|
@@ -4,3 +4,9 @@ export var Features;
|
|
|
4
4
|
Features[Features["EPOCH_SUBMISSION"] = 2] = "EPOCH_SUBMISSION";
|
|
5
5
|
Features[Features["MLDSA_LINK_PUBKEY"] = 4] = "MLDSA_LINK_PUBKEY";
|
|
6
6
|
})(Features || (Features = {}));
|
|
7
|
+
export var FeaturePriority;
|
|
8
|
+
(function (FeaturePriority) {
|
|
9
|
+
FeaturePriority[FeaturePriority["ACCESS_LIST"] = 1] = "ACCESS_LIST";
|
|
10
|
+
FeaturePriority[FeaturePriority["EPOCH_SUBMISSION"] = 2] = "EPOCH_SUBMISSION";
|
|
11
|
+
FeaturePriority[FeaturePriority["MLDSA_LINK_PUBKEY"] = 3] = "MLDSA_LINK_PUBKEY";
|
|
12
|
+
})(FeaturePriority || (FeaturePriority = {}));
|
|
@@ -5,5 +5,5 @@ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
|
|
|
5
5
|
export declare class CalldataGenerator extends Generator {
|
|
6
6
|
constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
|
|
7
7
|
static getPubKeyAsBuffer(witnessKeys: Buffer[], network: Network): Buffer;
|
|
8
|
-
compile(calldata: Buffer, contractSecret: Buffer, challenge: ChallengeSolution, maxPriority: bigint,
|
|
8
|
+
compile(calldata: Buffer, contractSecret: Buffer, challenge: ChallengeSolution, maxPriority: bigint, featuresRaw?: Feature<Features>[]): Buffer;
|
|
9
9
|
}
|
|
@@ -24,7 +24,7 @@ export class CalldataGenerator extends Generator {
|
|
|
24
24
|
}
|
|
25
25
|
return compressed;
|
|
26
26
|
}
|
|
27
|
-
compile(calldata, contractSecret, challenge, maxPriority,
|
|
27
|
+
compile(calldata, contractSecret, challenge, maxPriority, featuresRaw = []) {
|
|
28
28
|
if (!this.contractSaltPubKey)
|
|
29
29
|
throw new Error('Contract salt public key not set');
|
|
30
30
|
const dataChunks = this.splitBufferIntoChunks(calldata);
|
|
@@ -32,11 +32,15 @@ export class CalldataGenerator extends Generator {
|
|
|
32
32
|
throw new Error('No data chunks found');
|
|
33
33
|
const featuresList = [];
|
|
34
34
|
const featureData = [];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const features = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
36
|
+
if (features.length) {
|
|
37
|
+
for (let i = 0; i < features.length; i++) {
|
|
38
|
+
const feature = features[i];
|
|
39
|
+
featuresList.push(feature.opcode);
|
|
40
|
+
const data = this.encodeFeature(feature);
|
|
41
|
+
featureData.push(...data);
|
|
42
|
+
featureData.push(opcodes.OP_0);
|
|
43
|
+
}
|
|
40
44
|
}
|
|
41
45
|
let compiledData = [
|
|
42
46
|
this.getHeader(maxPriority, featuresList),
|
|
@@ -15,19 +15,21 @@ export class DeploymentGenerator extends Generator {
|
|
|
15
15
|
}
|
|
16
16
|
return compiled;
|
|
17
17
|
}
|
|
18
|
-
getAsm(contractBytecode, contractSalt, challenge, maxPriority, calldata,
|
|
18
|
+
getAsm(contractBytecode, contractSalt, challenge, maxPriority, calldata, featuresRaw) {
|
|
19
19
|
if (!this.contractSaltPubKey)
|
|
20
20
|
throw new Error('Contract salt public key not set');
|
|
21
21
|
const dataChunks = this.splitBufferIntoChunks(contractBytecode);
|
|
22
22
|
const calldataChunks = calldata ? this.splitBufferIntoChunks(calldata) : [];
|
|
23
23
|
const featuresList = [];
|
|
24
24
|
const featureData = [];
|
|
25
|
-
if (
|
|
25
|
+
if (featuresRaw) {
|
|
26
|
+
const features = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
26
27
|
for (let i = 0; i < features.length; i++) {
|
|
27
28
|
const feature = features[i];
|
|
28
29
|
featuresList.push(feature.opcode);
|
|
29
30
|
const data = this.encodeFeature(feature);
|
|
30
31
|
featureData.push(...data);
|
|
32
|
+
featureData.push(opcodes.OP_0);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
const compiledData = [
|
|
@@ -4,5 +4,5 @@ import { Feature, Features } from '../Features.js';
|
|
|
4
4
|
export declare class LegacyCalldataGenerator extends Generator {
|
|
5
5
|
constructor(senderPubKey: Buffer, network?: Network);
|
|
6
6
|
static getPubKeyAsBuffer(witnessKeys: Buffer[], network: Network): Buffer;
|
|
7
|
-
compile(calldata: Buffer, contractSecret: Buffer, challenge: Buffer, maxPriority: bigint,
|
|
7
|
+
compile(calldata: Buffer, contractSecret: Buffer, challenge: Buffer, maxPriority: bigint, featuresRaw?: Feature<Features>[]): Buffer;
|
|
8
8
|
}
|
|
@@ -24,17 +24,21 @@ export class LegacyCalldataGenerator extends Generator {
|
|
|
24
24
|
}
|
|
25
25
|
return compressed;
|
|
26
26
|
}
|
|
27
|
-
compile(calldata, contractSecret, challenge, maxPriority,
|
|
27
|
+
compile(calldata, contractSecret, challenge, maxPriority, featuresRaw = []) {
|
|
28
28
|
const dataChunks = this.splitBufferIntoChunks(calldata);
|
|
29
29
|
if (!dataChunks.length)
|
|
30
30
|
throw new Error('No data chunks found');
|
|
31
31
|
const featuresList = [];
|
|
32
32
|
const featureData = [];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
const features = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
34
|
+
if (features.length) {
|
|
35
|
+
for (let i = 0; i < features.length; i++) {
|
|
36
|
+
const feature = features[i];
|
|
37
|
+
featuresList.push(feature.opcode);
|
|
38
|
+
const data = this.encodeFeature(feature);
|
|
39
|
+
featureData.push(...data);
|
|
40
|
+
featureData.push(opcodes.OP_0);
|
|
41
|
+
}
|
|
38
42
|
}
|
|
39
43
|
let compiledData = [
|
|
40
44
|
this.getHeader(maxPriority, featuresList),
|
|
@@ -6,7 +6,7 @@ export declare class P2WDAGenerator extends Generator {
|
|
|
6
6
|
private static readonly P2WDA_VERSION;
|
|
7
7
|
constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
|
|
8
8
|
static validateWitnessSize(dataSize: number, maxWitnessFields?: number, maxBytesPerWitness?: number): boolean;
|
|
9
|
-
compile(calldata: Buffer, contractSecret: Buffer, challenge: ChallengeSolution, maxPriority: bigint,
|
|
9
|
+
compile(calldata: Buffer, contractSecret: Buffer, challenge: ChallengeSolution, maxPriority: bigint, featuresRaw?: Feature<Features>[]): Buffer;
|
|
10
10
|
getHeader(maxPriority: bigint, features?: Features[]): Buffer;
|
|
11
11
|
private writeFeatures;
|
|
12
12
|
private encodeFeatureData;
|
|
@@ -14,7 +14,7 @@ export class P2WDAGenerator extends Generator {
|
|
|
14
14
|
const requiredFields = Math.ceil(compressedSize / maxBytesPerWitness);
|
|
15
15
|
return requiredFields <= maxWitnessFields;
|
|
16
16
|
}
|
|
17
|
-
compile(calldata, contractSecret, challenge, maxPriority,
|
|
17
|
+
compile(calldata, contractSecret, challenge, maxPriority, featuresRaw = []) {
|
|
18
18
|
if (!this.contractSaltPubKey) {
|
|
19
19
|
throw new Error('Contract salt public key not set');
|
|
20
20
|
}
|
|
@@ -23,6 +23,7 @@ export class P2WDAGenerator extends Generator {
|
|
|
23
23
|
}
|
|
24
24
|
const writer = new BinaryWriter();
|
|
25
25
|
writer.writeU8(P2WDAGenerator.P2WDA_VERSION);
|
|
26
|
+
const features = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
26
27
|
writer.writeBytes(this.getHeader(maxPriority, features.map((f) => f.opcode)));
|
|
27
28
|
writer.writeBytes(contractSecret);
|
|
28
29
|
writer.writeBytes(challenge.publicKey.toBuffer());
|
|
@@ -8,7 +8,7 @@ import { Compressor } from '../../bytecode/Compressor.js';
|
|
|
8
8
|
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
9
9
|
import { Address } from '../../keypair/Address.js';
|
|
10
10
|
import { TimeLockGenerator } from '../mineable/TimelockGenerator.js';
|
|
11
|
-
import { Features } from '../../generators/Features.js';
|
|
11
|
+
import { FeaturePriority, Features } from '../../generators/Features.js';
|
|
12
12
|
export class DeploymentTransaction extends TransactionBuilder {
|
|
13
13
|
constructor(parameters) {
|
|
14
14
|
super(parameters);
|
|
@@ -202,6 +202,7 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
202
202
|
const submission = parameters.challenge.getSubmission();
|
|
203
203
|
if (submission) {
|
|
204
204
|
features.push({
|
|
205
|
+
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
205
206
|
opcode: Features.EPOCH_SUBMISSION,
|
|
206
207
|
data: submission,
|
|
207
208
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
2
2
|
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
3
|
-
import { Features } from '../../generators/Features.js';
|
|
3
|
+
import { FeaturePriority, Features } from '../../generators/Features.js';
|
|
4
4
|
export class InteractionTransaction extends SharedInteractionTransaction {
|
|
5
5
|
constructor(parameters) {
|
|
6
6
|
super(parameters);
|
|
@@ -34,6 +34,7 @@ export class InteractionTransaction extends SharedInteractionTransaction {
|
|
|
34
34
|
const features = [];
|
|
35
35
|
if (parameters.loadedStorage) {
|
|
36
36
|
features.push({
|
|
37
|
+
priority: FeaturePriority.ACCESS_LIST,
|
|
37
38
|
opcode: Features.ACCESS_LIST,
|
|
38
39
|
data: parameters.loadedStorage,
|
|
39
40
|
});
|
|
@@ -41,6 +42,7 @@ export class InteractionTransaction extends SharedInteractionTransaction {
|
|
|
41
42
|
const submission = parameters.challenge.getSubmission();
|
|
42
43
|
if (submission) {
|
|
43
44
|
features.push({
|
|
45
|
+
priority: FeaturePriority.EPOCH_SUBMISSION,
|
|
44
46
|
opcode: Features.EPOCH_SUBMISSION,
|
|
45
47
|
data: submission,
|
|
46
48
|
});
|
|
@@ -5,7 +5,7 @@ import { TransactionBuilder } from './TransactionBuilder.js';
|
|
|
5
5
|
import { MessageSigner } from '../../keypair/MessageSigner.js';
|
|
6
6
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
7
7
|
import { P2WDAGenerator } from '../../generators/builders/P2WDAGenerator.js';
|
|
8
|
-
import { Features } from '../../generators/Features.js';
|
|
8
|
+
import { FeaturePriority, Features } from '../../generators/Features.js';
|
|
9
9
|
import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
|
|
10
10
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
11
11
|
import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
|
|
@@ -106,6 +106,7 @@ export class InteractionTransactionP2WDA extends TransactionBuilder {
|
|
|
106
106
|
const features = [];
|
|
107
107
|
if (parameters.loadedStorage) {
|
|
108
108
|
features.push({
|
|
109
|
+
priority: FeaturePriority.ACCESS_LIST,
|
|
109
110
|
opcode: Features.ACCESS_LIST,
|
|
110
111
|
data: parameters.loadedStorage,
|
|
111
112
|
});
|
|
@@ -113,6 +114,7 @@ export class InteractionTransactionP2WDA extends TransactionBuilder {
|
|
|
113
114
|
const submission = parameters.challenge.getSubmission();
|
|
114
115
|
if (submission) {
|
|
115
116
|
features.push({
|
|
117
|
+
priority: FeaturePriority.EPOCH_SUBMISSION,
|
|
116
118
|
opcode: Features.EPOCH_SUBMISSION,
|
|
117
119
|
data: submission,
|
|
118
120
|
});
|
|
@@ -4,7 +4,7 @@ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
|
4
4
|
import { AddressVerificator } from '../../keypair/AddressVerificator.js';
|
|
5
5
|
import { TweakedTransaction } from '../shared/TweakedTransaction.js';
|
|
6
6
|
import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
|
|
7
|
-
import { Features } from '../../generators/Features.js';
|
|
7
|
+
import { FeaturePriority, Features } from '../../generators/Features.js';
|
|
8
8
|
import { BITCOIN_PROTOCOL_ID, getChainId } from '../../chain/ChainData.js';
|
|
9
9
|
import { BinaryWriter } from '../../buffer/BinaryWriter.js';
|
|
10
10
|
import { MLDSASecurityLevel } from '@btc-vision/bip32';
|
|
@@ -562,6 +562,7 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
562
562
|
mldsaSignature = this.generateMLDSASignature();
|
|
563
563
|
}
|
|
564
564
|
const mldsaRequest = {
|
|
565
|
+
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
565
566
|
opcode: Features.MLDSA_LINK_PUBKEY,
|
|
566
567
|
data: {
|
|
567
568
|
verifyRequest: !!parameters.revealMLDSAPublicKey,
|
package/package.json
CHANGED
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.7.
|
|
1
|
+
export const version = '1.7.16';
|
|
@@ -59,7 +59,11 @@ export class ChallengeSubmission implements IChallengeSubmission {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const buffer = signatureDataWriter.getBuffer();
|
|
62
|
-
return MessageSigner.verifySignature(
|
|
62
|
+
return MessageSigner.verifySignature(
|
|
63
|
+
this.publicKey.tweakedPublicKeyToBuffer(),
|
|
64
|
+
buffer,
|
|
65
|
+
this.signature,
|
|
66
|
+
);
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
|
|
@@ -8,9 +8,16 @@ export enum Features {
|
|
|
8
8
|
MLDSA_LINK_PUBKEY = 0b100,
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
export enum FeaturePriority {
|
|
12
|
+
ACCESS_LIST = 1,
|
|
13
|
+
EPOCH_SUBMISSION = 2,
|
|
14
|
+
MLDSA_LINK_PUBKEY = 3,
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
export interface Feature<T extends Features> {
|
|
12
18
|
opcode: T;
|
|
13
19
|
data: unknown;
|
|
20
|
+
priority: number;
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
|
|
@@ -59,7 +59,7 @@ export class CalldataGenerator extends Generator {
|
|
|
59
59
|
* @param {Buffer} contractSecret - The contract secret
|
|
60
60
|
* @param {ChallengeSolution} challenge
|
|
61
61
|
* @param maxPriority - Amount of satoshis to spend max on priority fee
|
|
62
|
-
* @param {Feature<Features>[]}
|
|
62
|
+
* @param {Feature<Features>[]} featuresRaw - The features to use
|
|
63
63
|
* @returns {Buffer} - The compiled script
|
|
64
64
|
* @throws {Error} - If something goes wrong
|
|
65
65
|
*/
|
|
@@ -68,7 +68,7 @@ export class CalldataGenerator extends Generator {
|
|
|
68
68
|
contractSecret: Buffer,
|
|
69
69
|
challenge: ChallengeSolution,
|
|
70
70
|
maxPriority: bigint,
|
|
71
|
-
|
|
71
|
+
featuresRaw: Feature<Features>[] = [],
|
|
72
72
|
): Buffer {
|
|
73
73
|
if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
|
|
74
74
|
|
|
@@ -77,12 +77,19 @@ export class CalldataGenerator extends Generator {
|
|
|
77
77
|
|
|
78
78
|
const featuresList: Features[] = [];
|
|
79
79
|
const featureData: (number | Buffer | Buffer[])[] = [];
|
|
80
|
-
for (let i = 0; i < features.length; i++) {
|
|
81
|
-
const feature = features[i];
|
|
82
|
-
featuresList.push(feature.opcode);
|
|
83
80
|
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
const features: Feature<Features>[] = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
82
|
+
if (features.length) {
|
|
83
|
+
for (let i = 0; i < features.length; i++) {
|
|
84
|
+
const feature = features[i];
|
|
85
|
+
featuresList.push(feature.opcode);
|
|
86
|
+
|
|
87
|
+
const data = this.encodeFeature(feature);
|
|
88
|
+
featureData.push(...data);
|
|
89
|
+
|
|
90
|
+
// Separator between features so decoder knows where each ends
|
|
91
|
+
featureData.push(opcodes.OP_0);
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
let compiledData: (number | Buffer | Buffer[])[] = [
|
|
@@ -61,7 +61,7 @@ export class DeploymentGenerator extends Generator {
|
|
|
61
61
|
challenge: ChallengeSolution,
|
|
62
62
|
maxPriority: bigint,
|
|
63
63
|
calldata?: Buffer,
|
|
64
|
-
|
|
64
|
+
featuresRaw?: Feature<Features>[],
|
|
65
65
|
): (number | Buffer)[] {
|
|
66
66
|
if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
|
|
67
67
|
|
|
@@ -71,13 +71,20 @@ export class DeploymentGenerator extends Generator {
|
|
|
71
71
|
const featuresList: Features[] = [];
|
|
72
72
|
const featureData: (number | Buffer | Buffer[])[] = [];
|
|
73
73
|
|
|
74
|
-
if (
|
|
74
|
+
if (featuresRaw) {
|
|
75
|
+
const features: Feature<Features>[] = featuresRaw.sort(
|
|
76
|
+
(a, b) => a.priority - b.priority,
|
|
77
|
+
);
|
|
78
|
+
|
|
75
79
|
for (let i = 0; i < features.length; i++) {
|
|
76
80
|
const feature = features[i];
|
|
77
81
|
featuresList.push(feature.opcode);
|
|
78
82
|
|
|
79
83
|
const data = this.encodeFeature(feature);
|
|
80
84
|
featureData.push(...data);
|
|
85
|
+
|
|
86
|
+
// Separator between features so decoder knows where each ends
|
|
87
|
+
featureData.push(opcodes.OP_0);
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
|
|
@@ -55,7 +55,7 @@ export class LegacyCalldataGenerator extends Generator {
|
|
|
55
55
|
* @param {Buffer} contractSecret - The contract secret
|
|
56
56
|
* @param {Buffer} challenge - The challenge to use
|
|
57
57
|
* @param {bigint} maxPriority - The maximum priority
|
|
58
|
-
* @param {number[]} [
|
|
58
|
+
* @param {number[]} [featuresRaw=[]] - The features to use (optional)
|
|
59
59
|
* @returns {Buffer} - The compiled script
|
|
60
60
|
* @throws {Error} - If something goes wrong
|
|
61
61
|
*/
|
|
@@ -64,19 +64,26 @@ export class LegacyCalldataGenerator extends Generator {
|
|
|
64
64
|
contractSecret: Buffer,
|
|
65
65
|
challenge: Buffer,
|
|
66
66
|
maxPriority: bigint,
|
|
67
|
-
|
|
67
|
+
featuresRaw: Feature<Features>[] = [],
|
|
68
68
|
): Buffer {
|
|
69
69
|
const dataChunks: Buffer[][] = this.splitBufferIntoChunks(calldata);
|
|
70
70
|
if (!dataChunks.length) throw new Error('No data chunks found');
|
|
71
71
|
|
|
72
72
|
const featuresList: Features[] = [];
|
|
73
73
|
const featureData: (number | Buffer | Buffer[])[] = [];
|
|
74
|
-
|
|
75
|
-
const feature = features[i];
|
|
76
|
-
featuresList.push(feature.opcode);
|
|
74
|
+
const features: Feature<Features>[] = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
if (features.length) {
|
|
77
|
+
for (let i = 0; i < features.length; i++) {
|
|
78
|
+
const feature = features[i];
|
|
79
|
+
featuresList.push(feature.opcode);
|
|
80
|
+
|
|
81
|
+
const data = this.encodeFeature(feature);
|
|
82
|
+
featureData.push(...data);
|
|
83
|
+
|
|
84
|
+
// Separator between features so decoder knows where each ends
|
|
85
|
+
featureData.push(opcodes.OP_0);
|
|
86
|
+
}
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
let compiledData = [
|
|
@@ -59,7 +59,7 @@ export class P2WDAGenerator extends Generator {
|
|
|
59
59
|
* @param contractSecret The 32-byte contract secret
|
|
60
60
|
* @param challenge The challenge solution for epoch rewards
|
|
61
61
|
* @param maxPriority Maximum priority fee in satoshis
|
|
62
|
-
* @param
|
|
62
|
+
* @param featuresRaw Optional features like access lists
|
|
63
63
|
* @returns Raw operation data ready for signing and compression
|
|
64
64
|
*/
|
|
65
65
|
public compile(
|
|
@@ -67,7 +67,7 @@ export class P2WDAGenerator extends Generator {
|
|
|
67
67
|
contractSecret: Buffer,
|
|
68
68
|
challenge: ChallengeSolution,
|
|
69
69
|
maxPriority: bigint,
|
|
70
|
-
|
|
70
|
+
featuresRaw: Feature<Features>[] = [],
|
|
71
71
|
): Buffer {
|
|
72
72
|
if (!this.contractSaltPubKey) {
|
|
73
73
|
throw new Error('Contract salt public key not set');
|
|
@@ -82,6 +82,8 @@ export class P2WDAGenerator extends Generator {
|
|
|
82
82
|
// Version byte
|
|
83
83
|
writer.writeU8(P2WDAGenerator.P2WDA_VERSION);
|
|
84
84
|
|
|
85
|
+
const features: Feature<Features>[] = featuresRaw.sort((a, b) => a.priority - b.priority);
|
|
86
|
+
|
|
85
87
|
// Header
|
|
86
88
|
writer.writeBytes(
|
|
87
89
|
this.getHeader(
|
|
@@ -25,7 +25,7 @@ import { Address } from '../../keypair/Address.js';
|
|
|
25
25
|
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
|
|
26
26
|
import { TimeLockGenerator } from '../mineable/TimelockGenerator.js';
|
|
27
27
|
import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
|
|
28
|
-
import { Feature, Features } from '../../generators/Features.js';
|
|
28
|
+
import { Feature, FeaturePriority, Features } from '../../generators/Features.js';
|
|
29
29
|
import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
|
|
30
30
|
|
|
31
31
|
export class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
@@ -379,6 +379,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
379
379
|
const submission = parameters.challenge.getSubmission();
|
|
380
380
|
if (submission) {
|
|
381
381
|
features.push({
|
|
382
|
+
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
382
383
|
opcode: Features.EPOCH_SUBMISSION,
|
|
383
384
|
data: submission,
|
|
384
385
|
});
|
|
@@ -3,7 +3,7 @@ import { TransactionType } from '../enums/TransactionType.js';
|
|
|
3
3
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
4
4
|
import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
|
|
5
5
|
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
6
|
-
import { Feature, Features } from '../../generators/Features.js';
|
|
6
|
+
import { Feature, FeaturePriority, Features } from '../../generators/Features.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Class for interaction transactions
|
|
@@ -63,6 +63,7 @@ export class InteractionTransaction extends SharedInteractionTransaction<Transac
|
|
|
63
63
|
|
|
64
64
|
if (parameters.loadedStorage) {
|
|
65
65
|
features.push({
|
|
66
|
+
priority: FeaturePriority.ACCESS_LIST,
|
|
66
67
|
opcode: Features.ACCESS_LIST,
|
|
67
68
|
data: parameters.loadedStorage,
|
|
68
69
|
});
|
|
@@ -71,6 +72,7 @@ export class InteractionTransaction extends SharedInteractionTransaction<Transac
|
|
|
71
72
|
const submission = parameters.challenge.getSubmission();
|
|
72
73
|
if (submission) {
|
|
73
74
|
features.push({
|
|
75
|
+
priority: FeaturePriority.EPOCH_SUBMISSION,
|
|
74
76
|
opcode: Features.EPOCH_SUBMISSION,
|
|
75
77
|
data: submission,
|
|
76
78
|
});
|
|
@@ -6,7 +6,7 @@ import { TransactionBuilder } from './TransactionBuilder.js';
|
|
|
6
6
|
import { MessageSigner } from '../../keypair/MessageSigner.js';
|
|
7
7
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
8
8
|
import { P2WDAGenerator } from '../../generators/builders/P2WDAGenerator.js';
|
|
9
|
-
import { Feature, Features } from '../../generators/Features.js';
|
|
9
|
+
import { Feature, FeaturePriority, Features } from '../../generators/Features.js';
|
|
10
10
|
import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
|
|
11
11
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
12
12
|
import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
|
|
@@ -200,6 +200,7 @@ export class InteractionTransactionP2WDA extends TransactionBuilder<TransactionT
|
|
|
200
200
|
|
|
201
201
|
if (parameters.loadedStorage) {
|
|
202
202
|
features.push({
|
|
203
|
+
priority: FeaturePriority.ACCESS_LIST,
|
|
203
204
|
opcode: Features.ACCESS_LIST,
|
|
204
205
|
data: parameters.loadedStorage,
|
|
205
206
|
});
|
|
@@ -208,6 +209,7 @@ export class InteractionTransactionP2WDA extends TransactionBuilder<TransactionT
|
|
|
208
209
|
const submission = parameters.challenge.getSubmission();
|
|
209
210
|
if (submission) {
|
|
210
211
|
features.push({
|
|
212
|
+
priority: FeaturePriority.EPOCH_SUBMISSION,
|
|
211
213
|
opcode: Features.EPOCH_SUBMISSION,
|
|
212
214
|
data: submission,
|
|
213
215
|
});
|
|
@@ -27,7 +27,7 @@ import { TweakedTransaction } from '../shared/TweakedTransaction.js';
|
|
|
27
27
|
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
|
|
28
28
|
import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
|
|
29
29
|
import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
|
|
30
|
-
import { Feature, Features, MLDSALinkRequest } from '../../generators/Features.js';
|
|
30
|
+
import { Feature, FeaturePriority, Features, MLDSALinkRequest } from '../../generators/Features.js';
|
|
31
31
|
import { BITCOIN_PROTOCOL_ID, getChainId } from '../../chain/ChainData.js';
|
|
32
32
|
import { BinaryWriter } from '../../buffer/BinaryWriter.js';
|
|
33
33
|
import { MLDSASecurityLevel } from '@btc-vision/bip32';
|
|
@@ -979,6 +979,7 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
979
979
|
}
|
|
980
980
|
|
|
981
981
|
const mldsaRequest: MLDSALinkRequest = {
|
|
982
|
+
priority: FeaturePriority.MLDSA_LINK_PUBKEY,
|
|
982
983
|
opcode: Features.MLDSA_LINK_PUBKEY,
|
|
983
984
|
data: {
|
|
984
985
|
verifyRequest: !!parameters.revealMLDSAPublicKey,
|