@btc-vision/transaction 1.0.88 → 1.0.89
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/index.js +1 -1
- package/browser/transaction/TransactionFactory.d.ts +18 -5
- package/browser/transaction/builders/FundingTransaction.d.ts +1 -1
- package/browser/transaction/builders/TransactionBuilder.d.ts +2 -2
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/transaction/TransactionFactory.d.ts +18 -5
- package/build/transaction/TransactionFactory.js +22 -2
- package/build/transaction/builders/FundingTransaction.d.ts +1 -1
- package/build/transaction/builders/FundingTransaction.js +11 -3
- package/build/transaction/builders/TransactionBuilder.d.ts +2 -2
- package/build/transaction/builders/TransactionBuilder.js +12 -9
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/metadata/tokens.ts +135 -135
- package/src/transaction/TransactionFactory.ts +56 -12
- package/src/transaction/builders/FundingTransaction.ts +11 -5
- package/src/transaction/builders/TransactionBuilder.ts +26 -21
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { Transaction } from 'bitcoinjs-lib';
|
|
1
2
|
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
3
|
+
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
2
4
|
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
3
5
|
import { Address } from '@btc-vision/bsi-binary';
|
|
6
|
+
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
7
|
+
import { TransactionType } from './enums/TransactionType.js';
|
|
4
8
|
export interface DeploymentResult {
|
|
5
9
|
readonly transaction: [string, string];
|
|
6
10
|
readonly contractAddress: Address;
|
|
@@ -14,6 +18,18 @@ export interface WrapResult {
|
|
|
14
18
|
readonly receiverAddress: Address;
|
|
15
19
|
readonly utxos: UTXO[];
|
|
16
20
|
}
|
|
21
|
+
export interface FundingTransactionResponse {
|
|
22
|
+
readonly tx: Transaction;
|
|
23
|
+
readonly original: FundingTransaction;
|
|
24
|
+
readonly estimatedFees: bigint;
|
|
25
|
+
readonly nextUTXOs: UTXO[];
|
|
26
|
+
}
|
|
27
|
+
export interface BitcoinTransferResponse {
|
|
28
|
+
readonly tx: string;
|
|
29
|
+
readonly original: FundingTransaction;
|
|
30
|
+
readonly estimatedFees: bigint;
|
|
31
|
+
readonly nextUTXOs: UTXO[];
|
|
32
|
+
}
|
|
17
33
|
export interface UnwrapResult {
|
|
18
34
|
readonly fundingTransaction: string;
|
|
19
35
|
readonly psbt: string;
|
|
@@ -27,11 +43,8 @@ export declare class TransactionFactory {
|
|
|
27
43
|
wrap(warpParameters: Omit<IWrapParameters, 'calldata'>): Promise<WrapResult>;
|
|
28
44
|
unwrapSegwit(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult>;
|
|
29
45
|
unwrap(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult>;
|
|
30
|
-
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<
|
|
31
|
-
|
|
32
|
-
tx: string;
|
|
33
|
-
nextUTXOs: UTXO[];
|
|
34
|
-
}>;
|
|
46
|
+
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<BitcoinTransferResponse>;
|
|
47
|
+
getAllNewUTXOs(original: TransactionBuilder<TransactionType>, tx: Transaction, to: Address): UTXO[];
|
|
35
48
|
private createFundTransaction;
|
|
36
49
|
private calculateNumSignatures;
|
|
37
50
|
private calculateNumInputs;
|
|
@@ -4,7 +4,7 @@ import { Signer } from 'bitcoinjs-lib';
|
|
|
4
4
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
5
|
export declare class FundingTransaction extends TransactionBuilder<TransactionType.FUNDING> {
|
|
6
6
|
readonly type: TransactionType.FUNDING;
|
|
7
|
-
protected
|
|
7
|
+
protected amount: bigint;
|
|
8
8
|
protected splitInputsInto: number;
|
|
9
9
|
constructor(parameters: IFundingTransactionParameters);
|
|
10
10
|
protected buildTransaction(): Promise<void>;
|
|
@@ -44,6 +44,8 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
44
44
|
estimateTransactionFees(): Promise<bigint>;
|
|
45
45
|
rebuildFromBase64(base64: string): Promise<Psbt>;
|
|
46
46
|
setPSBT(psbt: Psbt): void;
|
|
47
|
+
getInputs(): PsbtInputExtended[];
|
|
48
|
+
getOutputs(): PsbtOutputExtended[];
|
|
47
49
|
protected addRefundOutput(amountSpent: bigint): Promise<void>;
|
|
48
50
|
protected addValueToToOutput(value: number | bigint): void;
|
|
49
51
|
protected getTransactionOPNetFee(): bigint;
|
|
@@ -55,8 +57,6 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
55
57
|
protected updateInput(input: UpdateInput): void;
|
|
56
58
|
protected getWitness(): Buffer;
|
|
57
59
|
protected getTapOutput(): Buffer;
|
|
58
|
-
protected getInputs(): PsbtInputExtended[];
|
|
59
|
-
protected getOutputs(): PsbtOutputExtended[];
|
|
60
60
|
protected verifyUTXOValidity(): void;
|
|
61
61
|
protected setFeeOutput(output: PsbtOutputExtended): Promise<void>;
|
|
62
62
|
protected internalBuildTransaction(transaction: Psbt): Promise<boolean>;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.89";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
1
|
+
export const version = '1.0.89';
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { Transaction } from 'bitcoinjs-lib';
|
|
1
2
|
import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters, IUnwrapParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
|
|
3
|
+
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
2
4
|
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
3
5
|
import { Address } from '@btc-vision/bsi-binary';
|
|
6
|
+
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
7
|
+
import { TransactionType } from './enums/TransactionType.js';
|
|
4
8
|
export interface DeploymentResult {
|
|
5
9
|
readonly transaction: [string, string];
|
|
6
10
|
readonly contractAddress: Address;
|
|
@@ -14,6 +18,18 @@ export interface WrapResult {
|
|
|
14
18
|
readonly receiverAddress: Address;
|
|
15
19
|
readonly utxos: UTXO[];
|
|
16
20
|
}
|
|
21
|
+
export interface FundingTransactionResponse {
|
|
22
|
+
readonly tx: Transaction;
|
|
23
|
+
readonly original: FundingTransaction;
|
|
24
|
+
readonly estimatedFees: bigint;
|
|
25
|
+
readonly nextUTXOs: UTXO[];
|
|
26
|
+
}
|
|
27
|
+
export interface BitcoinTransferResponse {
|
|
28
|
+
readonly tx: string;
|
|
29
|
+
readonly original: FundingTransaction;
|
|
30
|
+
readonly estimatedFees: bigint;
|
|
31
|
+
readonly nextUTXOs: UTXO[];
|
|
32
|
+
}
|
|
17
33
|
export interface UnwrapResult {
|
|
18
34
|
readonly fundingTransaction: string;
|
|
19
35
|
readonly psbt: string;
|
|
@@ -27,11 +43,8 @@ export declare class TransactionFactory {
|
|
|
27
43
|
wrap(warpParameters: Omit<IWrapParameters, 'calldata'>): Promise<WrapResult>;
|
|
28
44
|
unwrapSegwit(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult>;
|
|
29
45
|
unwrap(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult>;
|
|
30
|
-
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<
|
|
31
|
-
|
|
32
|
-
tx: string;
|
|
33
|
-
nextUTXOs: UTXO[];
|
|
34
|
-
}>;
|
|
46
|
+
createBTCTransfer(parameters: IFundingTransactionParameters): Promise<BitcoinTransferResponse>;
|
|
47
|
+
getAllNewUTXOs(original: TransactionBuilder<TransactionType>, tx: Transaction, to: Address): UTXO[];
|
|
35
48
|
private createFundTransaction;
|
|
36
49
|
private calculateNumSignatures;
|
|
37
50
|
private calculateNumInputs;
|
|
@@ -230,11 +230,30 @@ export class TransactionFactory {
|
|
|
230
230
|
const resp = await this.createFundTransaction(parameters);
|
|
231
231
|
return {
|
|
232
232
|
estimatedFees: resp.estimatedFees,
|
|
233
|
+
original: resp.original,
|
|
233
234
|
tx: resp.tx.toHex(),
|
|
234
|
-
nextUTXOs: this.
|
|
235
|
+
nextUTXOs: this.getAllNewUTXOs(resp.original, resp.tx, parameters.from),
|
|
235
236
|
};
|
|
236
237
|
}
|
|
238
|
+
getAllNewUTXOs(original, tx, to) {
|
|
239
|
+
const outputs = original.getOutputs();
|
|
240
|
+
const utxos = [];
|
|
241
|
+
for (let i = 0; i < tx.outs.length; i++) {
|
|
242
|
+
const output = outputs[i];
|
|
243
|
+
if ('address' in output) {
|
|
244
|
+
if (output.address !== to)
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
utxos.push(...this.getUTXOAsTransaction(tx, to, i));
|
|
251
|
+
}
|
|
252
|
+
return utxos;
|
|
253
|
+
}
|
|
237
254
|
async createFundTransaction(parameters) {
|
|
255
|
+
if (!parameters.to)
|
|
256
|
+
throw new Error('Field "to" not provided.');
|
|
238
257
|
const fundingTransaction = new FundingTransaction(parameters);
|
|
239
258
|
const signedTransaction = await fundingTransaction.signTransaction();
|
|
240
259
|
if (!signedTransaction) {
|
|
@@ -243,7 +262,8 @@ export class TransactionFactory {
|
|
|
243
262
|
return {
|
|
244
263
|
tx: signedTransaction,
|
|
245
264
|
original: fundingTransaction,
|
|
246
|
-
estimatedFees:
|
|
265
|
+
estimatedFees: fundingTransaction.estimatedFees,
|
|
266
|
+
nextUTXOs: this.getUTXOAsTransaction(signedTransaction, parameters.to, 0),
|
|
247
267
|
};
|
|
248
268
|
}
|
|
249
269
|
calculateNumSignatures(vault) {
|
|
@@ -4,7 +4,7 @@ import { Signer } from 'bitcoinjs-lib';
|
|
|
4
4
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
5
|
export declare class FundingTransaction extends TransactionBuilder<TransactionType.FUNDING> {
|
|
6
6
|
readonly type: TransactionType.FUNDING;
|
|
7
|
-
protected
|
|
7
|
+
protected amount: bigint;
|
|
8
8
|
protected splitInputsInto: number;
|
|
9
9
|
constructor(parameters: IFundingTransactionParameters);
|
|
10
10
|
protected buildTransaction(): Promise<void>;
|
|
@@ -2,11 +2,11 @@ import { TransactionType } from '../enums/TransactionType.js';
|
|
|
2
2
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
3
3
|
export class FundingTransaction extends TransactionBuilder {
|
|
4
4
|
type = TransactionType.FUNDING;
|
|
5
|
-
|
|
5
|
+
amount;
|
|
6
6
|
splitInputsInto;
|
|
7
7
|
constructor(parameters) {
|
|
8
8
|
super(parameters);
|
|
9
|
-
this.
|
|
9
|
+
this.amount = parameters.amount;
|
|
10
10
|
this.splitInputsInto = parameters.splitInputsInto ?? 1;
|
|
11
11
|
this.internalInit();
|
|
12
12
|
}
|
|
@@ -15,7 +15,15 @@ export class FundingTransaction extends TransactionBuilder {
|
|
|
15
15
|
throw new Error('Recipient address is required');
|
|
16
16
|
}
|
|
17
17
|
this.addInputsFromUTXO();
|
|
18
|
-
|
|
18
|
+
let amountSpent = this.amount;
|
|
19
|
+
if (this.getTransactionOPNetFee() === TransactionBuilder.MINIMUM_DUST) {
|
|
20
|
+
if (amountSpent < TransactionBuilder.MINIMUM_DUST) {
|
|
21
|
+
amountSpent += TransactionBuilder.MINIMUM_DUST;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
amountSpent += this.getTransactionOPNetFee();
|
|
26
|
+
}
|
|
19
27
|
if (this.splitInputsInto > 1) {
|
|
20
28
|
await this.splitInputs(amountSpent);
|
|
21
29
|
}
|
|
@@ -44,6 +44,8 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
44
44
|
estimateTransactionFees(): Promise<bigint>;
|
|
45
45
|
rebuildFromBase64(base64: string): Promise<Psbt>;
|
|
46
46
|
setPSBT(psbt: Psbt): void;
|
|
47
|
+
getInputs(): PsbtInputExtended[];
|
|
48
|
+
getOutputs(): PsbtOutputExtended[];
|
|
47
49
|
protected addRefundOutput(amountSpent: bigint): Promise<void>;
|
|
48
50
|
protected addValueToToOutput(value: number | bigint): void;
|
|
49
51
|
protected getTransactionOPNetFee(): bigint;
|
|
@@ -55,8 +57,6 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
|
|
|
55
57
|
protected updateInput(input: UpdateInput): void;
|
|
56
58
|
protected getWitness(): Buffer;
|
|
57
59
|
protected getTapOutput(): Buffer;
|
|
58
|
-
protected getInputs(): PsbtInputExtended[];
|
|
59
|
-
protected getOutputs(): PsbtOutputExtended[];
|
|
60
60
|
protected verifyUTXOValidity(): void;
|
|
61
61
|
protected setFeeOutput(output: PsbtOutputExtended): Promise<void>;
|
|
62
62
|
protected internalBuildTransaction(transaction: Psbt): Promise<boolean>;
|
|
@@ -38,6 +38,9 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
38
38
|
this.priorityFee = parameters.priorityFee ?? 0n;
|
|
39
39
|
this.utxos = parameters.utxos;
|
|
40
40
|
this.to = parameters.to || undefined;
|
|
41
|
+
if (!this.utxos.length) {
|
|
42
|
+
throw new Error('No UTXOs specified');
|
|
43
|
+
}
|
|
41
44
|
this.from = TransactionBuilder.getFrom(parameters.from, this.signer, this.network);
|
|
42
45
|
this.totalInputAmount = this.calculateTotalUTXOAmount();
|
|
43
46
|
const totalVOut = this.calculateTotalVOutAmount();
|
|
@@ -177,6 +180,15 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
177
180
|
setPSBT(psbt) {
|
|
178
181
|
this.transaction = psbt;
|
|
179
182
|
}
|
|
183
|
+
getInputs() {
|
|
184
|
+
return this.inputs;
|
|
185
|
+
}
|
|
186
|
+
getOutputs() {
|
|
187
|
+
const outputs = [...this.outputs];
|
|
188
|
+
if (this.feeOutput)
|
|
189
|
+
outputs.push(this.feeOutput);
|
|
190
|
+
return outputs;
|
|
191
|
+
}
|
|
180
192
|
async addRefundOutput(amountSpent) {
|
|
181
193
|
const sendBackAmount = this.totalInputAmount - amountSpent;
|
|
182
194
|
if (sendBackAmount >= TransactionBuilder.MINIMUM_DUST) {
|
|
@@ -263,15 +275,6 @@ export class TransactionBuilder extends TweakedTransaction {
|
|
|
263
275
|
}
|
|
264
276
|
return this.tapData.output;
|
|
265
277
|
}
|
|
266
|
-
getInputs() {
|
|
267
|
-
return this.inputs;
|
|
268
|
-
}
|
|
269
|
-
getOutputs() {
|
|
270
|
-
const outputs = [...this.outputs];
|
|
271
|
-
if (this.feeOutput)
|
|
272
|
-
outputs.push(this.feeOutput);
|
|
273
|
-
return outputs;
|
|
274
|
-
}
|
|
275
278
|
verifyUTXOValidity() {
|
|
276
279
|
for (let utxo of this.utxos) {
|
|
277
280
|
if (!utxo.scriptPubKey) {
|
package/package.json
CHANGED
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
1
|
+
export const version = '1.0.89';
|
package/src/metadata/tokens.ts
CHANGED
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
import { Address } from '@btc-vision/bsi-binary';
|
|
2
|
-
import { ChainId } from '../network/ChainId.js';
|
|
3
|
-
|
|
4
|
-
// Addresses Regtest
|
|
5
|
-
export const FACTORY_ADDRESS_REGTEST: Address = 'bcrt1qxtpreq8zg7pp9wm550kjrhaa2r5kj6lhph9he5';
|
|
6
|
-
export const POOL_ADDRESS_REGTEST: Address = 'bcrt1qqg2a8076rwuruzetdyquj8fh5jxtc22pmh9vep';
|
|
7
|
-
export const WBTC_ADDRESS_REGTEST: Address = 'bcrt1qdr7sjgtnudda8zrfklw8l5cnrxum5hns7e46hf';
|
|
8
|
-
export const MOTO_ADDRESS_REGTEST: Address = 'bcrt1q8reuxx9naek4mqesrfsgdpjv3q7a5g2llkh6ua';
|
|
9
|
-
export const ROUTER_ADDRESS_REGTEST: Address = 'bcrt1qplnz54sca73t8a03nh494jatr9ffjg6ecarrj8';
|
|
10
|
-
|
|
11
|
-
// Addresses Testnet
|
|
12
|
-
export const FACTORY_ADDRESS_TESTNET: Address = 'tb1qgev5kldhp5zvg6j8t9vl6x4phkrwn8nk9felxh';
|
|
13
|
-
export const POOL_ADDRESS_TESTNET: Address = 'tb1q6a7yw353hjmresphupytw5vczpqxtg4yrupayk';
|
|
14
|
-
export const WBTC_ADDRESS_TESTNET: Address = 'tb1qp28xna6pv47x6wflcplhu0a9hkld5shtvjx6xv';
|
|
15
|
-
export const MOTO_ADDRESS_TESTNET: Address = 'tb1q4tyhf8hpu04qjj3qaag20knun0spctultxzakw';
|
|
16
|
-
export const ROUTER_ADDRESS_TESTNET: Address = 'tb1qnh9mj95nnej25dwhjvvsppwmdm0myhxv7tllgt';
|
|
17
|
-
|
|
18
|
-
// Addresses Fractal
|
|
19
|
-
export const FACTORY_ADDRESS_FRACTAL: Address = 'bc1qr4g85824m58wu0zffjtnf56n425fp0e8azhc7q';
|
|
20
|
-
export const POOL_ADDRESS_FRACTAL: Address = 'bc1qv55cht4zzlt29ea7vdgwsedsn63a2sxtkgpv6h';
|
|
21
|
-
export const WBTC_ADDRESS_FRACTAL: Address = '
|
|
22
|
-
export const MOTO_ADDRESS_FRACTAL: Address = 'bc1qfzq6w5uvgg5489egv0lj4shlqx4dagqt0ewdnu';
|
|
23
|
-
export const ROUTER_ADDRESS_FRACTAL: Address = 'bc1q9w2zvmkzlezt2fu34u57y9vuw6rll5sp2090kn';
|
|
24
|
-
|
|
25
|
-
export enum OPNetNetwork {
|
|
26
|
-
Mainnet = 'mainnet',
|
|
27
|
-
Testnet = 'testnet',
|
|
28
|
-
Regtest = 'regtest',
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface OPNetTokenMetadata {
|
|
32
|
-
readonly factory: Address;
|
|
33
|
-
readonly pool: Address;
|
|
34
|
-
readonly wbtc: Address;
|
|
35
|
-
readonly moto: Address;
|
|
36
|
-
readonly router: Address;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export class OPNetTokenAddressManager {
|
|
40
|
-
private readonly metadata: {
|
|
41
|
-
[key in ChainId]: { [key in OPNetNetwork]?: OPNetTokenMetadata };
|
|
42
|
-
} = {
|
|
43
|
-
[ChainId.Bitcoin]: {
|
|
44
|
-
[OPNetNetwork.Testnet]: {
|
|
45
|
-
factory: FACTORY_ADDRESS_TESTNET,
|
|
46
|
-
pool: POOL_ADDRESS_TESTNET,
|
|
47
|
-
wbtc: WBTC_ADDRESS_TESTNET,
|
|
48
|
-
moto: MOTO_ADDRESS_TESTNET,
|
|
49
|
-
router: ROUTER_ADDRESS_TESTNET,
|
|
50
|
-
},
|
|
51
|
-
[OPNetNetwork.Regtest]: {
|
|
52
|
-
factory: FACTORY_ADDRESS_REGTEST,
|
|
53
|
-
pool: POOL_ADDRESS_REGTEST,
|
|
54
|
-
wbtc: WBTC_ADDRESS_REGTEST,
|
|
55
|
-
moto: MOTO_ADDRESS_REGTEST,
|
|
56
|
-
router: ROUTER_ADDRESS_REGTEST,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
[ChainId.Fractal]: {
|
|
60
|
-
[OPNetNetwork.Mainnet]: {
|
|
61
|
-
factory: FACTORY_ADDRESS_FRACTAL,
|
|
62
|
-
pool: POOL_ADDRESS_FRACTAL,
|
|
63
|
-
wbtc: WBTC_ADDRESS_FRACTAL,
|
|
64
|
-
moto: MOTO_ADDRESS_FRACTAL,
|
|
65
|
-
router: ROUTER_ADDRESS_FRACTAL,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
public getFactoryAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
71
|
-
const address = this.metadata[chainId][network]?.factory;
|
|
72
|
-
|
|
73
|
-
if (!address) {
|
|
74
|
-
throw new Error(
|
|
75
|
-
`Factory address not found for network ${network} and chainId ${chainId}`,
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return address;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public getPoolAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
83
|
-
const address = this.metadata[chainId][network]?.pool;
|
|
84
|
-
|
|
85
|
-
if (!address) {
|
|
86
|
-
throw new Error(`Pool address not found for network ${network} and chainId ${chainId}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return address;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
public getWBTCAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
93
|
-
const address = this.metadata[chainId][network]?.wbtc;
|
|
94
|
-
|
|
95
|
-
if (!address) {
|
|
96
|
-
throw new Error(`WBTC address not found for network ${network} and chainId ${chainId}`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return address;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
public getMOTOAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
103
|
-
const address = this.metadata[chainId][network]?.moto;
|
|
104
|
-
|
|
105
|
-
if (!address) {
|
|
106
|
-
throw new Error(`MOTO address not found for network ${network} and chainId ${chainId}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return address;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
public getRouterAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
113
|
-
const address = this.metadata[chainId][network]?.router;
|
|
114
|
-
|
|
115
|
-
if (!address) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
`Router address not found for network ${network} and chainId ${chainId}`,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return address;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
public getAddresses(network: OPNetNetwork, chainId: ChainId): OPNetTokenMetadata {
|
|
125
|
-
const metadata = this.metadata[chainId][network];
|
|
126
|
-
|
|
127
|
-
if (!metadata) {
|
|
128
|
-
throw new Error(`Metadata not found for network ${network} and chainId ${chainId}`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return metadata;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export const OPNetMetadata: OPNetTokenAddressManager = new OPNetTokenAddressManager();
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
2
|
+
import { ChainId } from '../network/ChainId.js';
|
|
3
|
+
|
|
4
|
+
// Addresses Regtest
|
|
5
|
+
export const FACTORY_ADDRESS_REGTEST: Address = 'bcrt1qxtpreq8zg7pp9wm550kjrhaa2r5kj6lhph9he5';
|
|
6
|
+
export const POOL_ADDRESS_REGTEST: Address = 'bcrt1qqg2a8076rwuruzetdyquj8fh5jxtc22pmh9vep';
|
|
7
|
+
export const WBTC_ADDRESS_REGTEST: Address = 'bcrt1qdr7sjgtnudda8zrfklw8l5cnrxum5hns7e46hf';
|
|
8
|
+
export const MOTO_ADDRESS_REGTEST: Address = 'bcrt1q8reuxx9naek4mqesrfsgdpjv3q7a5g2llkh6ua';
|
|
9
|
+
export const ROUTER_ADDRESS_REGTEST: Address = 'bcrt1qplnz54sca73t8a03nh494jatr9ffjg6ecarrj8';
|
|
10
|
+
|
|
11
|
+
// Addresses Testnet
|
|
12
|
+
export const FACTORY_ADDRESS_TESTNET: Address = 'tb1qgev5kldhp5zvg6j8t9vl6x4phkrwn8nk9felxh';
|
|
13
|
+
export const POOL_ADDRESS_TESTNET: Address = 'tb1q6a7yw353hjmresphupytw5vczpqxtg4yrupayk';
|
|
14
|
+
export const WBTC_ADDRESS_TESTNET: Address = 'tb1qp28xna6pv47x6wflcplhu0a9hkld5shtvjx6xv';
|
|
15
|
+
export const MOTO_ADDRESS_TESTNET: Address = 'tb1q4tyhf8hpu04qjj3qaag20knun0spctultxzakw';
|
|
16
|
+
export const ROUTER_ADDRESS_TESTNET: Address = 'tb1qnh9mj95nnej25dwhjvvsppwmdm0myhxv7tllgt';
|
|
17
|
+
|
|
18
|
+
// Addresses Fractal
|
|
19
|
+
export const FACTORY_ADDRESS_FRACTAL: Address = 'bc1qr4g85824m58wu0zffjtnf56n425fp0e8azhc7q';
|
|
20
|
+
export const POOL_ADDRESS_FRACTAL: Address = 'bc1qv55cht4zzlt29ea7vdgwsedsn63a2sxtkgpv6h';
|
|
21
|
+
export const WBTC_ADDRESS_FRACTAL: Address = 'bc1qdtzlucslvrvu4useyh9r69supqrw3w4xn9t4yv';
|
|
22
|
+
export const MOTO_ADDRESS_FRACTAL: Address = 'bc1qfzq6w5uvgg5489egv0lj4shlqx4dagqt0ewdnu';
|
|
23
|
+
export const ROUTER_ADDRESS_FRACTAL: Address = 'bc1q9w2zvmkzlezt2fu34u57y9vuw6rll5sp2090kn';
|
|
24
|
+
|
|
25
|
+
export enum OPNetNetwork {
|
|
26
|
+
Mainnet = 'mainnet',
|
|
27
|
+
Testnet = 'testnet',
|
|
28
|
+
Regtest = 'regtest',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface OPNetTokenMetadata {
|
|
32
|
+
readonly factory: Address;
|
|
33
|
+
readonly pool: Address;
|
|
34
|
+
readonly wbtc: Address;
|
|
35
|
+
readonly moto: Address;
|
|
36
|
+
readonly router: Address;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class OPNetTokenAddressManager {
|
|
40
|
+
private readonly metadata: {
|
|
41
|
+
[key in ChainId]: { [key in OPNetNetwork]?: OPNetTokenMetadata };
|
|
42
|
+
} = {
|
|
43
|
+
[ChainId.Bitcoin]: {
|
|
44
|
+
[OPNetNetwork.Testnet]: {
|
|
45
|
+
factory: FACTORY_ADDRESS_TESTNET,
|
|
46
|
+
pool: POOL_ADDRESS_TESTNET,
|
|
47
|
+
wbtc: WBTC_ADDRESS_TESTNET,
|
|
48
|
+
moto: MOTO_ADDRESS_TESTNET,
|
|
49
|
+
router: ROUTER_ADDRESS_TESTNET,
|
|
50
|
+
},
|
|
51
|
+
[OPNetNetwork.Regtest]: {
|
|
52
|
+
factory: FACTORY_ADDRESS_REGTEST,
|
|
53
|
+
pool: POOL_ADDRESS_REGTEST,
|
|
54
|
+
wbtc: WBTC_ADDRESS_REGTEST,
|
|
55
|
+
moto: MOTO_ADDRESS_REGTEST,
|
|
56
|
+
router: ROUTER_ADDRESS_REGTEST,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
[ChainId.Fractal]: {
|
|
60
|
+
[OPNetNetwork.Mainnet]: {
|
|
61
|
+
factory: FACTORY_ADDRESS_FRACTAL,
|
|
62
|
+
pool: POOL_ADDRESS_FRACTAL,
|
|
63
|
+
wbtc: WBTC_ADDRESS_FRACTAL,
|
|
64
|
+
moto: MOTO_ADDRESS_FRACTAL,
|
|
65
|
+
router: ROUTER_ADDRESS_FRACTAL,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
public getFactoryAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
71
|
+
const address = this.metadata[chainId][network]?.factory;
|
|
72
|
+
|
|
73
|
+
if (!address) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Factory address not found for network ${network} and chainId ${chainId}`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return address;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public getPoolAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
83
|
+
const address = this.metadata[chainId][network]?.pool;
|
|
84
|
+
|
|
85
|
+
if (!address) {
|
|
86
|
+
throw new Error(`Pool address not found for network ${network} and chainId ${chainId}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return address;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public getWBTCAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
93
|
+
const address = this.metadata[chainId][network]?.wbtc;
|
|
94
|
+
|
|
95
|
+
if (!address) {
|
|
96
|
+
throw new Error(`WBTC address not found for network ${network} and chainId ${chainId}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return address;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public getMOTOAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
103
|
+
const address = this.metadata[chainId][network]?.moto;
|
|
104
|
+
|
|
105
|
+
if (!address) {
|
|
106
|
+
throw new Error(`MOTO address not found for network ${network} and chainId ${chainId}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return address;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public getRouterAddress(network: OPNetNetwork, chainId: ChainId): Address {
|
|
113
|
+
const address = this.metadata[chainId][network]?.router;
|
|
114
|
+
|
|
115
|
+
if (!address) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Router address not found for network ${network} and chainId ${chainId}`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return address;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public getAddresses(network: OPNetNetwork, chainId: ChainId): OPNetTokenMetadata {
|
|
125
|
+
const metadata = this.metadata[chainId][network];
|
|
126
|
+
|
|
127
|
+
if (!metadata) {
|
|
128
|
+
throw new Error(`Metadata not found for network ${network} and chainId ${chainId}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return metadata;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export const OPNetMetadata: OPNetTokenAddressManager = new OPNetTokenAddressManager();
|
|
@@ -19,6 +19,8 @@ import { VaultUTXOs } from './processor/PsbtTransaction.js';
|
|
|
19
19
|
import { UnwrapSegwitTransaction } from './builders/UnwrapSegwitTransaction.js';
|
|
20
20
|
import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
|
|
21
21
|
import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
|
|
22
|
+
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
23
|
+
import { TransactionType } from './enums/TransactionType.js';
|
|
22
24
|
|
|
23
25
|
export interface DeploymentResult {
|
|
24
26
|
readonly transaction: [string, string];
|
|
@@ -37,6 +39,20 @@ export interface WrapResult {
|
|
|
37
39
|
readonly utxos: UTXO[];
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
export interface FundingTransactionResponse {
|
|
43
|
+
readonly tx: Transaction;
|
|
44
|
+
readonly original: FundingTransaction;
|
|
45
|
+
readonly estimatedFees: bigint;
|
|
46
|
+
readonly nextUTXOs: UTXO[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface BitcoinTransferResponse {
|
|
50
|
+
readonly tx: string;
|
|
51
|
+
readonly original: FundingTransaction;
|
|
52
|
+
readonly estimatedFees: bigint;
|
|
53
|
+
readonly nextUTXOs: UTXO[];
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
export interface UnwrapResult {
|
|
41
57
|
readonly fundingTransaction: string;
|
|
42
58
|
readonly psbt: string;
|
|
@@ -403,11 +419,9 @@ export class TransactionFactory {
|
|
|
403
419
|
* @param {IFundingTransactionParameters} parameters - The funding transaction parameters
|
|
404
420
|
* @returns {Promise<{ estimatedFees: bigint; tx: string }>} - The signed transaction
|
|
405
421
|
*/
|
|
406
|
-
public async createBTCTransfer(
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
nextUTXOs: UTXO[];
|
|
410
|
-
}> {
|
|
422
|
+
public async createBTCTransfer(
|
|
423
|
+
parameters: IFundingTransactionParameters,
|
|
424
|
+
): Promise<BitcoinTransferResponse> {
|
|
411
425
|
if (!parameters.from) {
|
|
412
426
|
throw new Error('Field "from" not provided.');
|
|
413
427
|
}
|
|
@@ -416,16 +430,45 @@ export class TransactionFactory {
|
|
|
416
430
|
|
|
417
431
|
return {
|
|
418
432
|
estimatedFees: resp.estimatedFees,
|
|
433
|
+
original: resp.original,
|
|
419
434
|
tx: resp.tx.toHex(),
|
|
420
|
-
nextUTXOs: this.
|
|
435
|
+
nextUTXOs: this.getAllNewUTXOs(resp.original, resp.tx, parameters.from),
|
|
421
436
|
};
|
|
422
437
|
}
|
|
423
438
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Get all new UTXOs of a generated transaction.
|
|
441
|
+
* @param {TransactionBuilder<TransactionType>} original - The original transaction
|
|
442
|
+
* @param {Transaction} tx - The transaction
|
|
443
|
+
* @param {Address} to - The address to filter
|
|
444
|
+
*/
|
|
445
|
+
public getAllNewUTXOs(
|
|
446
|
+
original: TransactionBuilder<TransactionType>,
|
|
447
|
+
tx: Transaction,
|
|
448
|
+
to: Address,
|
|
449
|
+
): UTXO[] {
|
|
450
|
+
const outputs = original.getOutputs();
|
|
451
|
+
|
|
452
|
+
const utxos: UTXO[] = [];
|
|
453
|
+
for (let i = 0; i < tx.outs.length; i++) {
|
|
454
|
+
const output = outputs[i];
|
|
455
|
+
if ('address' in output) {
|
|
456
|
+
if (output.address !== to) continue;
|
|
457
|
+
} else {
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
utxos.push(...this.getUTXOAsTransaction(tx, to, i));
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return utxos;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private async createFundTransaction(
|
|
468
|
+
parameters: IFundingTransactionParameters,
|
|
469
|
+
): Promise<FundingTransactionResponse> {
|
|
470
|
+
if (!parameters.to) throw new Error('Field "to" not provided.');
|
|
471
|
+
|
|
429
472
|
const fundingTransaction: FundingTransaction = new FundingTransaction(parameters);
|
|
430
473
|
const signedTransaction: Transaction = await fundingTransaction.signTransaction();
|
|
431
474
|
if (!signedTransaction) {
|
|
@@ -435,7 +478,8 @@ export class TransactionFactory {
|
|
|
435
478
|
return {
|
|
436
479
|
tx: signedTransaction,
|
|
437
480
|
original: fundingTransaction,
|
|
438
|
-
estimatedFees:
|
|
481
|
+
estimatedFees: fundingTransaction.estimatedFees,
|
|
482
|
+
nextUTXOs: this.getUTXOAsTransaction(signedTransaction, parameters.to, 0),
|
|
439
483
|
};
|
|
440
484
|
}
|
|
441
485
|
|