@btc-vision/transaction 1.3.4 → 1.3.6
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 +9 -4
- package/browser/generators/Generator.d.ts +5 -2
- package/browser/generators/builders/CalldataGenerator.d.ts +2 -2
- package/browser/generators/builders/LegacyCalldataGenerator.d.ts +2 -2
- package/browser/index.js +1 -1
- package/browser/opnet.d.ts +7 -0
- package/browser/transaction/TransactionFactory.d.ts +2 -0
- package/browser/transaction/browser/extensions/UnisatSigner.d.ts +3 -5
- package/browser/transaction/builders/InteractionTransaction.d.ts +1 -0
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +4 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/generators/Features.d.ts +9 -4
- package/build/generators/Features.js +1 -5
- package/build/generators/Generator.d.ts +5 -2
- package/build/generators/Generator.js +40 -5
- package/build/generators/builders/CalldataGenerator.d.ts +2 -2
- package/build/generators/builders/CalldataGenerator.js +10 -4
- package/build/generators/builders/DeploymentGenerator.js +13 -2
- package/build/generators/builders/LegacyCalldataGenerator.d.ts +2 -2
- package/build/generators/builders/LegacyCalldataGenerator.js +10 -4
- package/build/opnet.d.ts +7 -0
- package/build/transaction/TransactionFactory.d.ts +2 -0
- package/build/transaction/TransactionFactory.js +65 -18
- package/build/transaction/browser/extensions/UnisatSigner.d.ts +3 -5
- package/build/transaction/builders/DeploymentTransaction.js +12 -2
- package/build/transaction/builders/InteractionTransaction.d.ts +1 -0
- package/build/transaction/builders/InteractionTransaction.js +12 -1
- package/build/transaction/interfaces/ITransactionParameters.d.ts +4 -0
- package/build/transaction/shared/TweakedTransaction.js +3 -3
- package/eslint.config.js +1 -0
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/generators/Features.ts +10 -5
- package/src/generators/Generator.ts +54 -5
- package/src/generators/builders/CalldataGenerator.ts +16 -9
- package/src/generators/builders/DeploymentGenerator.ts +17 -1
- package/src/generators/builders/LegacyCalldataGenerator.ts +14 -6
- package/src/opnet.ts +9 -0
- package/src/transaction/TransactionFactory.ts +95 -31
- package/src/transaction/browser/extensions/UnisatSigner.ts +4 -6
- package/src/transaction/builders/DeploymentTransaction.ts +12 -3
- package/src/transaction/builders/InteractionTransaction.ts +15 -0
- package/src/transaction/interfaces/ITransactionParameters.ts +7 -1
- package/src/transaction/shared/TweakedTransaction.ts +3 -4
package/browser/opnet.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Unisat } from './transaction/browser/types/Unisat.js';
|
|
1
2
|
export { version } from './_version.js';
|
|
2
3
|
export * from './bytecode/Compressor.js';
|
|
3
4
|
export * from './generators/builders/CalldataGenerator.js';
|
|
@@ -63,3 +64,9 @@ export * from './metadata/tokens.js';
|
|
|
63
64
|
export * from './transaction/browser/Web3Provider.js';
|
|
64
65
|
export * from './keypair/Secp256k1PointDeriver.js';
|
|
65
66
|
export * from './transaction/ContractAddress.js';
|
|
67
|
+
declare global {
|
|
68
|
+
interface Window {
|
|
69
|
+
unisat?: Unisat;
|
|
70
|
+
opnet?: Unisat;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -52,7 +52,9 @@ export declare class TransactionFactory {
|
|
|
52
52
|
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<BitcoinTransferResponse>;
|
|
53
53
|
createChallengeSolution(parameters: IChallengeSolutionTransactionParameters): Promise<ChallengeSolution>;
|
|
54
54
|
getAllNewUTXOs(original: TransactionBuilder<TransactionType>, tx: Transaction, to: string): UTXO[];
|
|
55
|
+
private parseOptionalInputs;
|
|
55
56
|
private detectInteractionOPWallet;
|
|
57
|
+
private detectDeploymentOPWallet;
|
|
56
58
|
private _createChallengeSolution;
|
|
57
59
|
private createFundTransaction;
|
|
58
60
|
private writePSBTHeader;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Network, Psbt } from '@btc-vision/bitcoin';
|
|
2
2
|
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
3
3
|
import { SignatureType, Unisat } from '../types/Unisat.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
opnet?: Unisat;
|
|
8
|
-
}
|
|
4
|
+
export interface WindowWithWallets {
|
|
5
|
+
unisat?: Unisat;
|
|
6
|
+
opnet?: Unisat;
|
|
9
7
|
}
|
|
10
8
|
export declare class UnisatSigner extends CustomKeypair {
|
|
11
9
|
private isInitialized;
|
|
@@ -2,6 +2,9 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
|
|
|
2
2
|
import { ITweakedTransactionData } from '../shared/TweakedTransaction.js';
|
|
3
3
|
import { ChainId } from '../../network/ChainId.js';
|
|
4
4
|
import { PsbtOutputExtended } from '@btc-vision/bitcoin';
|
|
5
|
+
export interface LoadedStorage {
|
|
6
|
+
[key: string]: string[];
|
|
7
|
+
}
|
|
5
8
|
export interface ITransactionParameters extends ITweakedTransactionData {
|
|
6
9
|
readonly from?: string;
|
|
7
10
|
readonly to?: string;
|
|
@@ -28,6 +31,7 @@ export interface SharedInteractionParameters extends ITransactionParameters {
|
|
|
28
31
|
disableAutoRefund?: boolean;
|
|
29
32
|
readonly preimage: Buffer;
|
|
30
33
|
readonly randomBytes?: Buffer;
|
|
34
|
+
readonly loadedStorage?: LoadedStorage;
|
|
31
35
|
}
|
|
32
36
|
export interface IInteractionParameters extends SharedInteractionParameters {
|
|
33
37
|
readonly calldata: Buffer;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.3.
|
|
1
|
+
export declare const version = "1.3.6";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.3.
|
|
1
|
+
export const version = '1.3.6';
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { LoadedStorage } from '../transaction/interfaces/ITransactionParameters.js';
|
|
1
2
|
export declare enum Features {
|
|
2
|
-
|
|
3
|
+
ACCESS_LIST = 1
|
|
4
|
+
}
|
|
5
|
+
export interface Feature<T extends Features> {
|
|
6
|
+
opcode: T;
|
|
7
|
+
data: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
|
|
10
|
+
data: LoadedStorage;
|
|
3
11
|
}
|
|
4
|
-
export declare const FeatureOpCodes: {
|
|
5
|
-
[key: number]: number;
|
|
6
|
-
};
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import { opcodes } from '@btc-vision/bitcoin';
|
|
2
1
|
export var Features;
|
|
3
2
|
(function (Features) {
|
|
4
|
-
Features[Features["
|
|
3
|
+
Features[Features["ACCESS_LIST"] = 1] = "ACCESS_LIST";
|
|
5
4
|
})(Features || (Features = {}));
|
|
6
|
-
export const FeatureOpCodes = {
|
|
7
|
-
[Features.UNWRAP]: opcodes.OP_16,
|
|
8
|
-
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
+
import { Feature, Features } from './Features.js';
|
|
2
3
|
export declare abstract class Generator {
|
|
3
4
|
static readonly DATA_CHUNK_SIZE: number;
|
|
4
5
|
static readonly MAGIC: Buffer;
|
|
@@ -7,8 +8,10 @@ export declare abstract class Generator {
|
|
|
7
8
|
protected readonly contractSaltPubKey?: Buffer;
|
|
8
9
|
protected readonly network: Network;
|
|
9
10
|
protected constructor(senderPubKey: Buffer, contractSaltPubKey?: Buffer, network?: Network);
|
|
10
|
-
|
|
11
|
-
getHeader(maxPriority: bigint): Buffer;
|
|
11
|
+
buildHeader(features: Features[]): Buffer;
|
|
12
|
+
getHeader(maxPriority: bigint, features?: Features[]): Buffer;
|
|
12
13
|
abstract compile(...args: unknown[]): Buffer;
|
|
13
14
|
protected splitBufferIntoChunks(buffer: Buffer, chunkSize?: number): Array<Buffer[]>;
|
|
15
|
+
protected encodeFeature(feature: Feature<Features>): Buffer[][];
|
|
16
|
+
private encodeAccessListFeature;
|
|
14
17
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { networks, toXOnly } from '@btc-vision/bitcoin';
|
|
2
2
|
import { BinaryWriter } from '../buffer/BinaryWriter.js';
|
|
3
|
+
import { Features } from './Features.js';
|
|
4
|
+
import { Address } from '../keypair/Address.js';
|
|
5
|
+
import { Compressor } from '../bytecode/Compressor.js';
|
|
3
6
|
export class Generator {
|
|
4
7
|
constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
|
|
5
8
|
this.network = networks.bitcoin;
|
|
@@ -8,12 +11,18 @@ export class Generator {
|
|
|
8
11
|
this.network = network;
|
|
9
12
|
this.xSenderPubKey = toXOnly(senderPubKey);
|
|
10
13
|
}
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
buildHeader(features) {
|
|
15
|
+
let flags = 0;
|
|
16
|
+
for (const feature of features) {
|
|
17
|
+
flags |= feature;
|
|
18
|
+
}
|
|
19
|
+
const bytesU24 = Buffer.alloc(3);
|
|
20
|
+
bytesU24.writeUIntBE(flags, 0, 3);
|
|
21
|
+
return Buffer.from([this.senderPubKey[0], ...bytesU24]);
|
|
13
22
|
}
|
|
14
|
-
getHeader(maxPriority) {
|
|
15
|
-
const writer = new BinaryWriter(
|
|
16
|
-
writer.writeBytes(this.
|
|
23
|
+
getHeader(maxPriority, features = []) {
|
|
24
|
+
const writer = new BinaryWriter(12);
|
|
25
|
+
writer.writeBytes(this.buildHeader(features));
|
|
17
26
|
writer.writeU64(maxPriority);
|
|
18
27
|
return Buffer.from(writer.getBuffer());
|
|
19
28
|
}
|
|
@@ -29,6 +38,32 @@ export class Generator {
|
|
|
29
38
|
}
|
|
30
39
|
return chunks;
|
|
31
40
|
}
|
|
41
|
+
encodeFeature(feature) {
|
|
42
|
+
switch (feature.opcode) {
|
|
43
|
+
case Features.ACCESS_LIST:
|
|
44
|
+
return this.splitBufferIntoChunks(this.encodeAccessListFeature(feature));
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`Unknown feature type: ${feature.opcode}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
encodeAccessListFeature(feature) {
|
|
50
|
+
const writer = new BinaryWriter();
|
|
51
|
+
writer.writeU16(Object.keys(feature.data).length);
|
|
52
|
+
for (const contract in feature.data) {
|
|
53
|
+
const parsedContract = Address.fromString(contract);
|
|
54
|
+
const data = feature.data[contract];
|
|
55
|
+
writer.writeAddress(parsedContract);
|
|
56
|
+
writer.writeU32(data.length);
|
|
57
|
+
for (const pointer of data) {
|
|
58
|
+
const pointerBuffer = Buffer.from(pointer, 'base64');
|
|
59
|
+
if (pointerBuffer.length !== 32) {
|
|
60
|
+
throw new Error(`Invalid pointer length: ${pointerBuffer.length}`);
|
|
61
|
+
}
|
|
62
|
+
writer.writeBytes(pointerBuffer);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return Compressor.compress(Buffer.from(writer.getBuffer()));
|
|
66
|
+
}
|
|
32
67
|
}
|
|
33
68
|
Generator.DATA_CHUNK_SIZE = 512;
|
|
34
69
|
Generator.MAGIC = Buffer.from('op', 'utf-8');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
-
import { Features } from '../Features.js';
|
|
2
|
+
import { Feature, Features } from '../Features.js';
|
|
3
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;
|
|
7
|
-
compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, maxPriority: bigint, features?: Features[]): Buffer;
|
|
7
|
+
compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, maxPriority: bigint, features?: Feature<Features>[]): Buffer;
|
|
8
8
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { crypto, networks, opcodes, script } from '@btc-vision/bitcoin';
|
|
2
2
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
3
3
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
4
|
-
import { FeatureOpCodes } from '../Features.js';
|
|
5
4
|
import { Generator } from '../Generator.js';
|
|
6
5
|
export class CalldataGenerator extends Generator {
|
|
7
6
|
constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
|
|
@@ -31,8 +30,16 @@ export class CalldataGenerator extends Generator {
|
|
|
31
30
|
const dataChunks = this.splitBufferIntoChunks(calldata);
|
|
32
31
|
if (!dataChunks.length)
|
|
33
32
|
throw new Error('No data chunks found');
|
|
33
|
+
const featuresList = [];
|
|
34
|
+
const featureData = [];
|
|
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
|
+
}
|
|
34
41
|
let compiledData = [
|
|
35
|
-
this.getHeader(maxPriority),
|
|
42
|
+
this.getHeader(maxPriority, featuresList),
|
|
36
43
|
opcodes.OP_TOALTSTACK,
|
|
37
44
|
preimage,
|
|
38
45
|
opcodes.OP_TOALTSTACK,
|
|
@@ -53,8 +60,7 @@ export class CalldataGenerator extends Generator {
|
|
|
53
60
|
opcodes.OP_IF,
|
|
54
61
|
Generator.MAGIC,
|
|
55
62
|
];
|
|
56
|
-
|
|
57
|
-
compiledData = compiledData.concat(...featureOpcodes, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
|
|
63
|
+
compiledData = compiledData.concat(...featureData, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
|
|
58
64
|
const asm = compiledData.flat();
|
|
59
65
|
const compiled = script.compile(asm);
|
|
60
66
|
const decompiled = script.decompile(compiled);
|
|
@@ -13,13 +13,23 @@ export class DeploymentGenerator extends Generator {
|
|
|
13
13
|
}
|
|
14
14
|
return compiled;
|
|
15
15
|
}
|
|
16
|
-
getAsm(contractBytecode, contractSalt, preimage, maxPriority, calldata) {
|
|
16
|
+
getAsm(contractBytecode, contractSalt, preimage, maxPriority, calldata, features) {
|
|
17
17
|
if (!this.contractSaltPubKey)
|
|
18
18
|
throw new Error('Contract salt public key not set');
|
|
19
19
|
const dataChunks = this.splitBufferIntoChunks(contractBytecode);
|
|
20
20
|
const calldataChunks = calldata ? this.splitBufferIntoChunks(calldata) : [];
|
|
21
|
+
const featuresList = [];
|
|
22
|
+
const featureData = [];
|
|
23
|
+
if (features) {
|
|
24
|
+
for (let i = 0; i < features.length; i++) {
|
|
25
|
+
const feature = features[i];
|
|
26
|
+
featuresList.push(feature.opcode);
|
|
27
|
+
const data = this.encodeFeature(feature);
|
|
28
|
+
featureData.push(...data);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
21
31
|
const compiledData = [
|
|
22
|
-
this.getHeader(maxPriority),
|
|
32
|
+
this.getHeader(maxPriority, featuresList),
|
|
23
33
|
opcodes.OP_TOALTSTACK,
|
|
24
34
|
preimage,
|
|
25
35
|
opcodes.OP_TOALTSTACK,
|
|
@@ -39,6 +49,7 @@ export class DeploymentGenerator extends Generator {
|
|
|
39
49
|
opcodes.OP_NUMEQUAL,
|
|
40
50
|
opcodes.OP_IF,
|
|
41
51
|
Generator.MAGIC,
|
|
52
|
+
...featureData,
|
|
42
53
|
opcodes.OP_0,
|
|
43
54
|
...calldataChunks,
|
|
44
55
|
opcodes.OP_1NEGATE,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
-
import { Features } from '../Features.js';
|
|
3
2
|
import { Generator } from '../Generator.js';
|
|
3
|
+
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, preimage: Buffer, maxPriority: bigint, features?: Features[]): Buffer;
|
|
7
|
+
compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, maxPriority: bigint, features?: Feature<Features>[]): Buffer;
|
|
8
8
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { crypto, networks, opcodes, script } from '@btc-vision/bitcoin';
|
|
2
2
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
3
3
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
4
|
-
import { FeatureOpCodes } from '../Features.js';
|
|
5
4
|
import { Generator } from '../Generator.js';
|
|
6
5
|
export class LegacyCalldataGenerator extends Generator {
|
|
7
6
|
constructor(senderPubKey, network = networks.bitcoin) {
|
|
@@ -29,8 +28,16 @@ export class LegacyCalldataGenerator extends Generator {
|
|
|
29
28
|
const dataChunks = this.splitBufferIntoChunks(calldata);
|
|
30
29
|
if (!dataChunks.length)
|
|
31
30
|
throw new Error('No data chunks found');
|
|
31
|
+
const featuresList = [];
|
|
32
|
+
const featureData = [];
|
|
33
|
+
for (let i = 0; i < features.length; i++) {
|
|
34
|
+
const feature = features[i];
|
|
35
|
+
featuresList.push(feature.opcode);
|
|
36
|
+
const data = this.encodeFeature(feature);
|
|
37
|
+
featureData.push(...data);
|
|
38
|
+
}
|
|
32
39
|
let compiledData = [
|
|
33
|
-
this.getHeader(maxPriority),
|
|
40
|
+
this.getHeader(maxPriority, featuresList),
|
|
34
41
|
opcodes.OP_TOALTSTACK,
|
|
35
42
|
preimage,
|
|
36
43
|
opcodes.OP_TOALTSTACK,
|
|
@@ -48,8 +55,7 @@ export class LegacyCalldataGenerator extends Generator {
|
|
|
48
55
|
opcodes.OP_IF,
|
|
49
56
|
Generator.MAGIC,
|
|
50
57
|
];
|
|
51
|
-
|
|
52
|
-
compiledData = compiledData.concat(...featureOpcodes, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
|
|
58
|
+
compiledData = compiledData.concat(...featureData, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
|
|
53
59
|
const asm = compiledData.flat();
|
|
54
60
|
const compiled = script.compile(asm);
|
|
55
61
|
const decompiled = script.decompile(compiled);
|
package/build/opnet.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Unisat } from './transaction/browser/types/Unisat.js';
|
|
1
2
|
export { version } from './_version.js';
|
|
2
3
|
export * from './bytecode/Compressor.js';
|
|
3
4
|
export * from './generators/builders/CalldataGenerator.js';
|
|
@@ -63,3 +64,9 @@ export * from './metadata/tokens.js';
|
|
|
63
64
|
export * from './transaction/browser/Web3Provider.js';
|
|
64
65
|
export * from './keypair/Secp256k1PointDeriver.js';
|
|
65
66
|
export * from './transaction/ContractAddress.js';
|
|
67
|
+
declare global {
|
|
68
|
+
interface Window {
|
|
69
|
+
unisat?: Unisat;
|
|
70
|
+
opnet?: Unisat;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -52,7 +52,9 @@ export declare class TransactionFactory {
|
|
|
52
52
|
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<BitcoinTransferResponse>;
|
|
53
53
|
createChallengeSolution(parameters: IChallengeSolutionTransactionParameters): Promise<ChallengeSolution>;
|
|
54
54
|
getAllNewUTXOs(original: TransactionBuilder<TransactionType>, tx: Transaction, to: string): UTXO[];
|
|
55
|
+
private parseOptionalInputs;
|
|
55
56
|
private detectInteractionOPWallet;
|
|
57
|
+
private detectDeploymentOPWallet;
|
|
56
58
|
private _createChallengeSolution;
|
|
57
59
|
private createFundTransaction;
|
|
58
60
|
private writePSBTHeader;
|
|
@@ -70,18 +70,7 @@ export class TransactionFactory {
|
|
|
70
70
|
if (!('signer' in interactionParameters)) {
|
|
71
71
|
throw new Error('Field "signer" not provided, OP_WALLET not detected.');
|
|
72
72
|
}
|
|
73
|
-
const inputs = (interactionParameters.optionalInputs
|
|
74
|
-
let nonWitness = input.nonWitnessUtxo;
|
|
75
|
-
if (nonWitness &&
|
|
76
|
-
!(nonWitness instanceof Uint8Array) &&
|
|
77
|
-
typeof nonWitness === 'object') {
|
|
78
|
-
nonWitness = Buffer.from(Uint8Array.from(Object.values(input.nonWitnessUtxo)));
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
...input,
|
|
82
|
-
nonWitnessUtxo: nonWitness,
|
|
83
|
-
};
|
|
84
|
-
});
|
|
73
|
+
const inputs = this.parseOptionalInputs(interactionParameters.optionalInputs);
|
|
85
74
|
const preTransaction = new InteractionTransaction({
|
|
86
75
|
...interactionParameters,
|
|
87
76
|
utxos: [interactionParameters.utxos[0]],
|
|
@@ -134,13 +123,35 @@ export class TransactionFactory {
|
|
|
134
123
|
};
|
|
135
124
|
}
|
|
136
125
|
async signDeployment(deploymentParameters) {
|
|
137
|
-
const
|
|
138
|
-
|
|
126
|
+
const opWalletDeployment = await this.detectDeploymentOPWallet(deploymentParameters);
|
|
127
|
+
if (opWalletDeployment) {
|
|
128
|
+
return opWalletDeployment;
|
|
129
|
+
}
|
|
130
|
+
if (!('signer' in deploymentParameters)) {
|
|
131
|
+
throw new Error('Field "signer" not provided, OP_WALLET not detected.');
|
|
132
|
+
}
|
|
133
|
+
const inputs = this.parseOptionalInputs(deploymentParameters.optionalInputs);
|
|
134
|
+
const preTransaction = new DeploymentTransaction({
|
|
135
|
+
...deploymentParameters,
|
|
136
|
+
utxos: [deploymentParameters.utxos[0]],
|
|
137
|
+
optionalInputs: inputs,
|
|
138
|
+
});
|
|
139
|
+
await preTransaction.generateTransactionMinimalSignatures();
|
|
139
140
|
const parameters = await preTransaction.getFundingTransactionParameters();
|
|
141
|
+
parameters.utxos = deploymentParameters.utxos;
|
|
140
142
|
parameters.amount =
|
|
141
143
|
(await preTransaction.estimateTransactionFees()) +
|
|
142
144
|
this.getPriorityFee(deploymentParameters) +
|
|
143
145
|
preTransaction.getOptionalOutputValue();
|
|
146
|
+
const feeEstimationFundingTransaction = await this.createFundTransaction({
|
|
147
|
+
...parameters,
|
|
148
|
+
optionalOutputs: [],
|
|
149
|
+
optionalInputs: [],
|
|
150
|
+
});
|
|
151
|
+
if (!feeEstimationFundingTransaction) {
|
|
152
|
+
throw new Error('Could not sign funding transaction.');
|
|
153
|
+
}
|
|
154
|
+
parameters.estimatedFees = feeEstimationFundingTransaction.estimatedFees;
|
|
144
155
|
const fundingTransaction = new FundingTransaction({
|
|
145
156
|
...parameters,
|
|
146
157
|
optionalInputs: [],
|
|
@@ -166,8 +177,8 @@ export class TransactionFactory {
|
|
|
166
177
|
randomBytes: preTransaction.getRndBytes(),
|
|
167
178
|
preimage: preTransaction.getPreimage(),
|
|
168
179
|
nonWitnessUtxo: signedTransaction.toBuffer(),
|
|
169
|
-
|
|
170
|
-
optionalInputs:
|
|
180
|
+
estimatedFees: preTransaction.estimatedFees,
|
|
181
|
+
optionalInputs: inputs,
|
|
171
182
|
};
|
|
172
183
|
const finalTransaction = new DeploymentTransaction(newParams);
|
|
173
184
|
const outTx = await finalTransaction.signTransaction();
|
|
@@ -230,11 +241,29 @@ export class TransactionFactory {
|
|
|
230
241
|
}
|
|
231
242
|
return utxos;
|
|
232
243
|
}
|
|
244
|
+
parseOptionalInputs(optionalInputs) {
|
|
245
|
+
return (optionalInputs || []).map((input) => {
|
|
246
|
+
let nonWitness = input.nonWitnessUtxo;
|
|
247
|
+
if (nonWitness &&
|
|
248
|
+
!(nonWitness instanceof Uint8Array) &&
|
|
249
|
+
typeof nonWitness === 'object') {
|
|
250
|
+
nonWitness = Buffer.from(Uint8Array.from(Object.values(input.nonWitnessUtxo)));
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
...input,
|
|
254
|
+
nonWitnessUtxo: nonWitness,
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
}
|
|
233
258
|
async detectInteractionOPWallet(interactionParameters) {
|
|
234
|
-
if (typeof window === 'undefined'
|
|
259
|
+
if (typeof window === 'undefined') {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
const _window = window;
|
|
263
|
+
if (!_window || !_window.opnet || !_window.opnet.web3) {
|
|
235
264
|
return null;
|
|
236
265
|
}
|
|
237
|
-
const opnet =
|
|
266
|
+
const opnet = _window.opnet.web3;
|
|
238
267
|
const interaction = await opnet.signInteraction({
|
|
239
268
|
...interactionParameters,
|
|
240
269
|
signer: undefined,
|
|
@@ -244,6 +273,24 @@ export class TransactionFactory {
|
|
|
244
273
|
}
|
|
245
274
|
return interaction;
|
|
246
275
|
}
|
|
276
|
+
async detectDeploymentOPWallet(deploymentParameters) {
|
|
277
|
+
if (typeof window === 'undefined') {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
const _window = window;
|
|
281
|
+
if (!_window || !_window.opnet || !_window.opnet.web3) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const opnet = _window.opnet.web3;
|
|
285
|
+
const deployment = await opnet.deployContract({
|
|
286
|
+
...deploymentParameters,
|
|
287
|
+
signer: undefined,
|
|
288
|
+
});
|
|
289
|
+
if (!deployment) {
|
|
290
|
+
throw new Error('Could not sign interaction transaction.');
|
|
291
|
+
}
|
|
292
|
+
return deployment;
|
|
293
|
+
}
|
|
247
294
|
async _createChallengeSolution(parameters) {
|
|
248
295
|
if (!parameters.to)
|
|
249
296
|
throw new Error('Field "to" not provided.');
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { Network, Psbt } from '@btc-vision/bitcoin';
|
|
2
2
|
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
3
3
|
import { SignatureType, Unisat } from '../types/Unisat.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
opnet?: Unisat;
|
|
8
|
-
}
|
|
4
|
+
export interface WindowWithWallets {
|
|
5
|
+
unisat?: Unisat;
|
|
6
|
+
opnet?: Unisat;
|
|
9
7
|
}
|
|
10
8
|
export declare class UnisatSigner extends CustomKeypair {
|
|
11
9
|
private isInitialized;
|
|
@@ -125,7 +125,12 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
125
125
|
transaction.finalizeInput(i, this.customFinalizer);
|
|
126
126
|
}
|
|
127
127
|
else {
|
|
128
|
-
|
|
128
|
+
try {
|
|
129
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
transaction.finalizeInput(i);
|
|
133
|
+
}
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
}
|
|
@@ -146,7 +151,12 @@ export class DeploymentTransaction extends TransactionBuilder {
|
|
|
146
151
|
}
|
|
147
152
|
else {
|
|
148
153
|
transaction.signInput(i, this.getSignerKey());
|
|
149
|
-
|
|
154
|
+
try {
|
|
155
|
+
transaction.finalizeInput(i, this.customFinalizerP2SH);
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
transaction.finalizeInput(i);
|
|
159
|
+
}
|
|
150
160
|
}
|
|
151
161
|
}
|
|
152
162
|
}
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
2
2
|
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
3
|
+
import { Features } from '../../generators/Features.js';
|
|
3
4
|
export class InteractionTransaction extends SharedInteractionTransaction {
|
|
4
5
|
constructor(parameters) {
|
|
5
6
|
super(parameters);
|
|
6
7
|
this.type = TransactionType.INTERACTION;
|
|
7
8
|
this.tapLeafScript = null;
|
|
8
9
|
this.contractSecret = this.generateSecret();
|
|
9
|
-
this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage, this.priorityFee);
|
|
10
|
+
this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage, this.priorityFee, this.generateFeatures(parameters));
|
|
10
11
|
this.scriptTree = this.getScriptTree();
|
|
11
12
|
this.internalInit();
|
|
12
13
|
}
|
|
14
|
+
generateFeatures(parameters) {
|
|
15
|
+
const features = [];
|
|
16
|
+
if (parameters.loadedStorage) {
|
|
17
|
+
features.push({
|
|
18
|
+
opcode: Features.ACCESS_LIST,
|
|
19
|
+
data: parameters.loadedStorage,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return features;
|
|
23
|
+
}
|
|
13
24
|
}
|
|
@@ -2,6 +2,9 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
|
|
|
2
2
|
import { ITweakedTransactionData } from '../shared/TweakedTransaction.js';
|
|
3
3
|
import { ChainId } from '../../network/ChainId.js';
|
|
4
4
|
import { PsbtOutputExtended } from '@btc-vision/bitcoin';
|
|
5
|
+
export interface LoadedStorage {
|
|
6
|
+
[key: string]: string[];
|
|
7
|
+
}
|
|
5
8
|
export interface ITransactionParameters extends ITweakedTransactionData {
|
|
6
9
|
readonly from?: string;
|
|
7
10
|
readonly to?: string;
|
|
@@ -28,6 +31,7 @@ export interface SharedInteractionParameters extends ITransactionParameters {
|
|
|
28
31
|
disableAutoRefund?: boolean;
|
|
29
32
|
readonly preimage: Buffer;
|
|
30
33
|
readonly randomBytes?: Buffer;
|
|
34
|
+
readonly loadedStorage?: LoadedStorage;
|
|
31
35
|
}
|
|
32
36
|
export interface IInteractionParameters extends SharedInteractionParameters {
|
|
33
37
|
readonly calldata: Buffer;
|
|
@@ -428,9 +428,9 @@ export class TweakedTransaction extends Logger {
|
|
|
428
428
|
if (this.tapLeafScript) {
|
|
429
429
|
input.tapLeafScript = [this.tapLeafScript];
|
|
430
430
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
if (this.nonWitnessUtxo) {
|
|
432
|
+
input.nonWitnessUtxo = this.nonWitnessUtxo;
|
|
433
|
+
}
|
|
434
434
|
}
|
|
435
435
|
return input;
|
|
436
436
|
}
|
package/eslint.config.js
CHANGED
package/package.json
CHANGED
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.3.
|
|
1
|
+
export const version = '1.3.6';
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LoadedStorage } from '../transaction/interfaces/ITransactionParameters.js';
|
|
2
2
|
|
|
3
3
|
export enum Features {
|
|
4
|
-
|
|
4
|
+
ACCESS_LIST = 1,
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export interface Feature<T extends Features> {
|
|
8
|
+
opcode: T;
|
|
9
|
+
data: unknown;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
|
|
13
|
+
data: LoadedStorage;
|
|
14
|
+
}
|