@atomiqlabs/base 10.0.0-dev.2 → 10.0.0-dev.21
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/LICENSE +201 -201
- package/dist/btc/BitcoinNetwork.d.ts +6 -6
- package/dist/btc/BitcoinNetwork.js +10 -10
- package/dist/btc/rpc/BitcoinRpc.d.ts +68 -68
- package/dist/btc/rpc/BitcoinRpc.js +2 -2
- package/dist/btcrelay/BtcRelay.d.ts +61 -61
- package/dist/btcrelay/BtcRelay.js +2 -2
- package/dist/btcrelay/synchronizer/RelaySynchronizer.d.ts +18 -18
- package/dist/btcrelay/synchronizer/RelaySynchronizer.js +2 -2
- package/dist/btcrelay/types/BtcBlock.d.ts +13 -13
- package/dist/btcrelay/types/BtcBlock.js +2 -2
- package/dist/btcrelay/types/BtcHeader.d.ts +10 -10
- package/dist/btcrelay/types/BtcHeader.js +2 -2
- package/dist/btcrelay/types/BtcStoredHeader.d.ts +11 -11
- package/dist/btcrelay/types/BtcStoredHeader.js +2 -2
- package/dist/btcrelay/utils/StatePredictorUtils.d.ts +11 -11
- package/dist/btcrelay/utils/StatePredictorUtils.js +80 -80
- package/dist/chains/ChainData.d.ts +31 -31
- package/dist/chains/ChainData.js +2 -2
- package/dist/chains/ChainInterface.d.ts +133 -110
- package/dist/chains/ChainInterface.js +7 -2
- package/dist/chains/ChainType.d.ts +24 -23
- package/dist/chains/ChainType.js +2 -2
- package/dist/errors/CannotInitializeATAError.d.ts +3 -3
- package/dist/errors/CannotInitializeATAError.js +11 -11
- package/dist/errors/SignatureVerificationError.d.ts +3 -3
- package/dist/errors/SignatureVerificationError.js +11 -11
- package/dist/errors/SwapDataVerificationError.d.ts +3 -3
- package/dist/errors/SwapDataVerificationError.js +11 -11
- package/dist/errors/TransactionRevertedError.d.ts +3 -0
- package/dist/errors/TransactionRevertedError.js +11 -0
- package/dist/events/ChainEvents.d.ts +9 -9
- package/dist/events/ChainEvents.js +2 -2
- package/dist/events/types/ChainEvent.d.ts +7 -7
- package/dist/events/types/ChainEvent.js +6 -6
- package/dist/events/types/spv_vault/SpvVaultClaimEvent.d.ts +12 -12
- package/dist/events/types/spv_vault/SpvVaultClaimEvent.js +18 -18
- package/dist/events/types/spv_vault/SpvVaultCloseEvent.d.ts +7 -7
- package/dist/events/types/spv_vault/SpvVaultCloseEvent.js +13 -13
- package/dist/events/types/spv_vault/SpvVaultDepositEvent.d.ts +7 -7
- package/dist/events/types/spv_vault/SpvVaultDepositEvent.js +13 -13
- package/dist/events/types/spv_vault/SpvVaultEvent.d.ts +15 -15
- package/dist/events/types/spv_vault/SpvVaultEvent.js +20 -20
- package/dist/events/types/spv_vault/SpvVaultFrontEvent.d.ts +10 -10
- package/dist/events/types/spv_vault/SpvVaultFrontEvent.js +16 -16
- package/dist/events/types/spv_vault/SpvVaultOpenEvent.d.ts +7 -7
- package/dist/events/types/spv_vault/SpvVaultOpenEvent.js +13 -13
- package/dist/events/types/swap/ClaimEvent.d.ts +7 -7
- package/dist/events/types/swap/ClaimEvent.js +11 -11
- package/dist/events/types/swap/InitializeEvent.d.ts +9 -9
- package/dist/events/types/swap/InitializeEvent.js +12 -12
- package/dist/events/types/swap/RefundEvent.d.ts +5 -5
- package/dist/events/types/swap/RefundEvent.js +7 -7
- package/dist/events/types/swap/SwapEvent.d.ts +12 -12
- package/dist/events/types/swap/SwapEvent.js +17 -17
- package/dist/index.d.ts +42 -38
- package/dist/index.js +58 -54
- package/dist/lockable/Lockable.d.ts +6 -6
- package/dist/lockable/Lockable.js +28 -28
- package/dist/messaging/Messenger.d.ts +8 -0
- package/dist/messaging/Messenger.js +2 -0
- package/dist/messaging/messages/Message.d.ts +11 -0
- package/dist/messaging/messages/Message.js +22 -0
- package/dist/messaging/messages/SwapClaimWitnessMessage.d.ts +10 -0
- package/dist/messaging/messages/SwapClaimWitnessMessage.js +28 -0
- package/dist/spv_swap/SpvVaultContract.d.ts +258 -199
- package/dist/spv_swap/SpvVaultContract.js +2 -2
- package/dist/spv_swap/SpvVaultData.d.ts +35 -35
- package/dist/spv_swap/SpvVaultData.js +37 -37
- package/dist/spv_swap/SpvWithdrawalState.d.ts +31 -31
- package/dist/spv_swap/SpvWithdrawalState.js +10 -10
- package/dist/spv_swap/SpvWithdrawalTransactionData.d.ts +43 -43
- package/dist/spv_swap/SpvWithdrawalTransactionData.js +143 -143
- package/dist/storage/IStorageManager.d.ts +15 -15
- package/dist/storage/IStorageManager.js +2 -2
- package/dist/storage/StorageObject.d.ts +3 -3
- package/dist/storage/StorageObject.js +2 -2
- package/dist/swaps/ChainSwapType.d.ts +6 -6
- package/dist/swaps/ChainSwapType.js +10 -10
- package/dist/swaps/SwapCommitState.d.ts +39 -38
- package/dist/swaps/SwapCommitState.js +11 -11
- package/dist/swaps/SwapContract.d.ts +479 -467
- package/dist/swaps/SwapContract.js +2 -2
- package/dist/swaps/SwapData.d.ts +37 -36
- package/dist/swaps/SwapData.js +17 -14
- package/dist/utils/BigIntBufferUtils.d.ts +6 -6
- package/dist/utils/BigIntBufferUtils.js +31 -31
- package/package.json +31 -31
- package/src/btc/BitcoinNetwork.ts +6 -6
- package/src/btc/rpc/BitcoinRpc.ts +77 -77
- package/src/btcrelay/BtcRelay.ts +70 -70
- package/src/btcrelay/synchronizer/RelaySynchronizer.ts +17 -17
- package/src/btcrelay/types/BtcBlock.ts +15 -15
- package/src/btcrelay/types/BtcHeader.ts +11 -11
- package/src/btcrelay/types/BtcStoredHeader.ts +12 -12
- package/src/btcrelay/utils/StatePredictorUtils.ts +108 -108
- package/src/chains/ChainData.ts +40 -40
- package/src/chains/ChainInterface.ts +159 -132
- package/src/chains/ChainType.ts +40 -38
- package/src/errors/CannotInitializeATAError.ts +11 -11
- package/src/errors/SignatureVerificationError.ts +11 -11
- package/src/errors/SwapDataVerificationError.ts +11 -11
- package/src/errors/TransactionRevertedError.ts +11 -0
- package/src/events/ChainEvents.ts +13 -13
- package/src/events/types/ChainEvent.ts +10 -10
- package/src/events/types/spv_vault/SpvVaultClaimEvent.ts +31 -31
- package/src/events/types/spv_vault/SpvVaultCloseEvent.ts +17 -17
- package/src/events/types/spv_vault/SpvVaultDepositEvent.ts +17 -17
- package/src/events/types/spv_vault/SpvVaultEvent.ts +25 -25
- package/src/events/types/spv_vault/SpvVaultFrontEvent.ts +27 -27
- package/src/events/types/spv_vault/SpvVaultOpenEvent.ts +16 -16
- package/src/events/types/swap/ClaimEvent.ts +15 -15
- package/src/events/types/swap/InitializeEvent.ts +18 -18
- package/src/events/types/swap/RefundEvent.ts +6 -6
- package/src/events/types/swap/SwapEvent.ts +21 -21
- package/src/index.ts +51 -46
- package/src/lockable/Lockable.ts +30 -30
- package/src/messaging/Messenger.ts +11 -0
- package/src/messaging/messages/Message.ts +25 -0
- package/src/messaging/messages/SwapClaimWitnessMessage.ts +34 -0
- package/src/spv_swap/SpvVaultContract.ts +269 -230
- package/src/spv_swap/SpvVaultData.ts +70 -70
- package/src/spv_swap/SpvWithdrawalState.ts +40 -40
- package/src/spv_swap/SpvWithdrawalTransactionData.ts +169 -169
- package/src/storage/IStorageManager.ts +16 -16
- package/src/storage/StorageObject.ts +6 -6
- package/src/swaps/ChainSwapType.ts +6 -6
- package/src/swaps/SwapCommitState.ts +40 -39
- package/src/swaps/SwapContract.ts +564 -556
- package/src/swaps/SwapData.ts +69 -65
- package/src/utils/BigIntBufferUtils.ts +31 -31
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
export enum SpvWithdrawalStateType {
|
|
3
|
-
CLOSED = -1,
|
|
4
|
-
NOT_FOUND = 0,
|
|
5
|
-
CLAIMED = 1,
|
|
6
|
-
FRONTED = 2
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type SpvWithdrawalNotFoundState = {
|
|
10
|
-
type: SpvWithdrawalStateType.NOT_FOUND
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type SpvWithdrawalStateCommon = {
|
|
14
|
-
txId: string,
|
|
15
|
-
owner: string,
|
|
16
|
-
vaultId: bigint,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type SpvWithdrawalClaimedState = {
|
|
20
|
-
type: SpvWithdrawalStateType.CLAIMED,
|
|
21
|
-
recipient: string,
|
|
22
|
-
claimer: string,
|
|
23
|
-
fronter: string
|
|
24
|
-
} & SpvWithdrawalStateCommon;
|
|
25
|
-
|
|
26
|
-
export type SpvWithdrawalFrontedState = {
|
|
27
|
-
type: SpvWithdrawalStateType.FRONTED,
|
|
28
|
-
recipient: string,
|
|
29
|
-
fronter: string
|
|
30
|
-
} & SpvWithdrawalStateCommon;
|
|
31
|
-
|
|
32
|
-
export type SpvWithdrawalClosedState = {
|
|
33
|
-
type: SpvWithdrawalStateType.CLOSED,
|
|
34
|
-
error: string
|
|
35
|
-
} & SpvWithdrawalStateCommon;
|
|
36
|
-
|
|
37
|
-
export type SpvWithdrawalState = SpvWithdrawalNotFoundState |
|
|
38
|
-
SpvWithdrawalClaimedState |
|
|
39
|
-
SpvWithdrawalFrontedState |
|
|
40
|
-
SpvWithdrawalClosedState;
|
|
1
|
+
|
|
2
|
+
export enum SpvWithdrawalStateType {
|
|
3
|
+
CLOSED = -1,
|
|
4
|
+
NOT_FOUND = 0,
|
|
5
|
+
CLAIMED = 1,
|
|
6
|
+
FRONTED = 2
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type SpvWithdrawalNotFoundState = {
|
|
10
|
+
type: SpvWithdrawalStateType.NOT_FOUND
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type SpvWithdrawalStateCommon = {
|
|
14
|
+
txId: string,
|
|
15
|
+
owner: string,
|
|
16
|
+
vaultId: bigint,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type SpvWithdrawalClaimedState = {
|
|
20
|
+
type: SpvWithdrawalStateType.CLAIMED,
|
|
21
|
+
recipient: string,
|
|
22
|
+
claimer: string,
|
|
23
|
+
fronter: string
|
|
24
|
+
} & SpvWithdrawalStateCommon;
|
|
25
|
+
|
|
26
|
+
export type SpvWithdrawalFrontedState = {
|
|
27
|
+
type: SpvWithdrawalStateType.FRONTED,
|
|
28
|
+
recipient: string,
|
|
29
|
+
fronter: string
|
|
30
|
+
} & SpvWithdrawalStateCommon;
|
|
31
|
+
|
|
32
|
+
export type SpvWithdrawalClosedState = {
|
|
33
|
+
type: SpvWithdrawalStateType.CLOSED,
|
|
34
|
+
error: string
|
|
35
|
+
} & SpvWithdrawalStateCommon;
|
|
36
|
+
|
|
37
|
+
export type SpvWithdrawalState = SpvWithdrawalNotFoundState |
|
|
38
|
+
SpvWithdrawalClaimedState |
|
|
39
|
+
SpvWithdrawalFrontedState |
|
|
40
|
+
SpvWithdrawalClosedState;
|
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
import {BtcTx} from "../btc/rpc/BitcoinRpc";
|
|
2
|
-
import {Buffer} from "buffer";
|
|
3
|
-
import {StorageObject} from "../storage/StorageObject";
|
|
4
|
-
|
|
5
|
-
export type ExecutionData = {
|
|
6
|
-
executionHash: string,
|
|
7
|
-
executionExpiry: number
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export abstract class SpvWithdrawalTransactionData implements StorageObject {
|
|
11
|
-
|
|
12
|
-
static deserializers: {
|
|
13
|
-
[type: string]: new (serialized: any) => any,
|
|
14
|
-
} = {};
|
|
15
|
-
|
|
16
|
-
static deserialize<T extends SpvWithdrawalTransactionData>(data: any): T {
|
|
17
|
-
if (SpvWithdrawalTransactionData.deserializers[data.type] != null) {
|
|
18
|
-
return new SpvWithdrawalTransactionData.deserializers[data.type](data) as unknown as T;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
protected abstract fromOpReturnData(data: Buffer): {recipient: string, rawAmounts: bigint[], executionHash: string};
|
|
23
|
-
|
|
24
|
-
readonly recipient: string;
|
|
25
|
-
readonly rawAmounts: bigint[];
|
|
26
|
-
|
|
27
|
-
readonly callerFeeRate: bigint;
|
|
28
|
-
readonly executionFeeRate: bigint;
|
|
29
|
-
readonly frontingFeeRate: bigint;
|
|
30
|
-
|
|
31
|
-
readonly executionHash: string;
|
|
32
|
-
readonly executionExpiry: number;
|
|
33
|
-
|
|
34
|
-
readonly btcTx: BtcTx;
|
|
35
|
-
|
|
36
|
-
constructor(btcTx: BtcTx) {
|
|
37
|
-
if(btcTx.ins.length<2) throw new Error("Need at least 2 inputs");
|
|
38
|
-
if(btcTx.outs.length<2) throw new Error("Need at least 2 outputs");
|
|
39
|
-
|
|
40
|
-
const nSequence0 = BigInt(btcTx.ins[0].sequence);
|
|
41
|
-
const nSequence1 = BigInt(btcTx.ins[1].sequence);
|
|
42
|
-
|
|
43
|
-
if((nSequence0 & 0x80000000n) != 0x80000000n) throw new Error("nSequence0 high bit not set!");
|
|
44
|
-
if((nSequence1 & 0x80000000n) != 0x80000000n) throw new Error("nSequence0 high bit not set!");
|
|
45
|
-
const callerFeeRate: bigint = nSequence0 & 0xFFFFFn;
|
|
46
|
-
const executionFeeRate: bigint = nSequence1 & 0xFFFFFn;
|
|
47
|
-
const frontingFeeRate: bigint = ((nSequence0 >> 10n) & 0b1111_1111_1100_0000_0000n) | ((nSequence1 >> 20n) & 0b11_1111_1111n);
|
|
48
|
-
|
|
49
|
-
const executionExpiry = btcTx.locktime + 1_000_000_000;
|
|
50
|
-
if(executionExpiry >= Math.pow(2, 32)) throw new Error("Execution expiry overflow");
|
|
51
|
-
|
|
52
|
-
const opReturnOutput = btcTx.outs[1];
|
|
53
|
-
//Parse script
|
|
54
|
-
const opReturnData = Buffer.from(opReturnOutput.scriptPubKey.hex, "hex");
|
|
55
|
-
if(opReturnData.length===0) throw new Error("Output 1 empty script");
|
|
56
|
-
if(opReturnData.at(0)!==0x6a) throw new Error("Output 1 is not OP_RETURN");
|
|
57
|
-
if(opReturnData.at(1)===0) throw new Error("Output 1 OP_RETURN followed by OP_0");
|
|
58
|
-
let data: Buffer;
|
|
59
|
-
if(opReturnData.at(1) === 0x4c) { //OP_PUSHDATA1
|
|
60
|
-
const dataLength = opReturnData.at(2);
|
|
61
|
-
data = opReturnData.subarray(3, 3+dataLength);
|
|
62
|
-
if(data.length !== dataLength) throw new Error("Output 1 OP_RETURN data length mismatch!");
|
|
63
|
-
} else if(opReturnData.at(1) <= 0x4b) { //OP_PUSH<length>
|
|
64
|
-
const dataLength = opReturnData.at(1);
|
|
65
|
-
data = opReturnData.subarray(2, 2+dataLength);
|
|
66
|
-
if(data.length !== dataLength) throw new Error("Output 1 OP_RETURN data length mismatch!");
|
|
67
|
-
} else {
|
|
68
|
-
throw new Error("Output 1 invalid push opcode");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
//Parse OP_RETURN data
|
|
72
|
-
const res = this.fromOpReturnData(data);
|
|
73
|
-
|
|
74
|
-
this.recipient = res.recipient;
|
|
75
|
-
this.rawAmounts = res.rawAmounts;
|
|
76
|
-
|
|
77
|
-
this.callerFeeRate = callerFeeRate;
|
|
78
|
-
this.frontingFeeRate = frontingFeeRate;
|
|
79
|
-
this.executionFeeRate = executionFeeRate;
|
|
80
|
-
|
|
81
|
-
this.executionHash = res.executionHash;
|
|
82
|
-
this.executionExpiry = executionExpiry;
|
|
83
|
-
|
|
84
|
-
this.btcTx = btcTx;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
serialize(): any {
|
|
88
|
-
return this.btcTx;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
getRecipient(): string {
|
|
92
|
-
return this.recipient;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
abstract isRecipient(address: string): boolean;
|
|
96
|
-
|
|
97
|
-
abstract getFrontingId(): string;
|
|
98
|
-
|
|
99
|
-
getOutputWithoutFees(): bigint[] {
|
|
100
|
-
return this.rawAmounts;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
getCallerFee(): bigint[] {
|
|
104
|
-
return this.rawAmounts.map(val => val * this.callerFeeRate / 100_000n);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
getFrontingFee(): bigint[] {
|
|
108
|
-
return this.rawAmounts.map(val => val * this.frontingFeeRate / 100_000n);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
getExecutionFee(): bigint[] {
|
|
112
|
-
return [this.rawAmounts[0] * this.executionFeeRate / 100_000n];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
getTotalOutput(): bigint[] {
|
|
116
|
-
const amounts = [...this.getOutputWithoutFees()];
|
|
117
|
-
const callerFee = this.getCallerFee();
|
|
118
|
-
if(callerFee!=null) callerFee.forEach((fee, i) => {
|
|
119
|
-
if(fee==null || fee===0n) return;
|
|
120
|
-
if(amounts[i]==null) throw new Error("Caller fee token out of bounds");
|
|
121
|
-
amounts[i] += fee;
|
|
122
|
-
});
|
|
123
|
-
const frontingFee = this.getFrontingFee();
|
|
124
|
-
if(frontingFee!=null) frontingFee.forEach((fee, i) => {
|
|
125
|
-
if(fee==null || fee===0n) return;
|
|
126
|
-
if(amounts[i]==null) throw new Error("Fronting fee token out of bounds");
|
|
127
|
-
amounts[i] += fee;
|
|
128
|
-
});
|
|
129
|
-
const executionFee = this.getExecutionFee();
|
|
130
|
-
if(executionFee!=null) executionFee.forEach((fee, i) => {
|
|
131
|
-
if(fee==null || fee===0n) return;
|
|
132
|
-
if(amounts[i]==null) throw new Error("Execution fee token out of bounds");
|
|
133
|
-
amounts[i] += fee;
|
|
134
|
-
});
|
|
135
|
-
amounts.forEach((val, index) => {
|
|
136
|
-
if(val >= 2n**64n) throw new Error("Token "+index+" amount out of bounds");
|
|
137
|
-
})
|
|
138
|
-
return amounts;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
getExecutionData(): ExecutionData | null {
|
|
142
|
-
if(this.executionHash==null) return null;
|
|
143
|
-
return {
|
|
144
|
-
executionHash: this.executionHash,
|
|
145
|
-
executionExpiry: this.executionExpiry
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
getTxId(): string {
|
|
150
|
-
return this.btcTx.txid;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
getSpentVaultUtxo(): string {
|
|
154
|
-
const in0 = this.btcTx.ins[0];
|
|
155
|
-
return in0.txid+":"+in0.vout;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
getCreatedVaultUtxo(): string {
|
|
159
|
-
return this.getTxId()+":0";
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
getNewVaultScript(): Buffer {
|
|
163
|
-
return Buffer.from(this.btcTx.outs[0].scriptPubKey.hex, "hex");
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
getNewVaultBtcAmount(): number {
|
|
167
|
-
return this.btcTx.outs[0].value;
|
|
168
|
-
}
|
|
169
|
-
|
|
1
|
+
import {BtcTx} from "../btc/rpc/BitcoinRpc";
|
|
2
|
+
import {Buffer} from "buffer";
|
|
3
|
+
import {StorageObject} from "../storage/StorageObject";
|
|
4
|
+
|
|
5
|
+
export type ExecutionData = {
|
|
6
|
+
executionHash: string,
|
|
7
|
+
executionExpiry: number
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export abstract class SpvWithdrawalTransactionData implements StorageObject {
|
|
11
|
+
|
|
12
|
+
static deserializers: {
|
|
13
|
+
[type: string]: new (serialized: any) => any,
|
|
14
|
+
} = {};
|
|
15
|
+
|
|
16
|
+
static deserialize<T extends SpvWithdrawalTransactionData>(data: any): T {
|
|
17
|
+
if (SpvWithdrawalTransactionData.deserializers[data.type] != null) {
|
|
18
|
+
return new SpvWithdrawalTransactionData.deserializers[data.type](data) as unknown as T;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected abstract fromOpReturnData(data: Buffer): {recipient: string, rawAmounts: bigint[], executionHash: string};
|
|
23
|
+
|
|
24
|
+
readonly recipient: string;
|
|
25
|
+
readonly rawAmounts: bigint[];
|
|
26
|
+
|
|
27
|
+
readonly callerFeeRate: bigint;
|
|
28
|
+
readonly executionFeeRate: bigint;
|
|
29
|
+
readonly frontingFeeRate: bigint;
|
|
30
|
+
|
|
31
|
+
readonly executionHash: string;
|
|
32
|
+
readonly executionExpiry: number;
|
|
33
|
+
|
|
34
|
+
readonly btcTx: BtcTx;
|
|
35
|
+
|
|
36
|
+
constructor(btcTx: BtcTx) {
|
|
37
|
+
if(btcTx.ins.length<2) throw new Error("Need at least 2 inputs");
|
|
38
|
+
if(btcTx.outs.length<2) throw new Error("Need at least 2 outputs");
|
|
39
|
+
|
|
40
|
+
const nSequence0 = BigInt(btcTx.ins[0].sequence);
|
|
41
|
+
const nSequence1 = BigInt(btcTx.ins[1].sequence);
|
|
42
|
+
|
|
43
|
+
if((nSequence0 & 0x80000000n) != 0x80000000n) throw new Error("nSequence0 high bit not set!");
|
|
44
|
+
if((nSequence1 & 0x80000000n) != 0x80000000n) throw new Error("nSequence0 high bit not set!");
|
|
45
|
+
const callerFeeRate: bigint = nSequence0 & 0xFFFFFn;
|
|
46
|
+
const executionFeeRate: bigint = nSequence1 & 0xFFFFFn;
|
|
47
|
+
const frontingFeeRate: bigint = ((nSequence0 >> 10n) & 0b1111_1111_1100_0000_0000n) | ((nSequence1 >> 20n) & 0b11_1111_1111n);
|
|
48
|
+
|
|
49
|
+
const executionExpiry = btcTx.locktime + 1_000_000_000;
|
|
50
|
+
if(executionExpiry >= Math.pow(2, 32)) throw new Error("Execution expiry overflow");
|
|
51
|
+
|
|
52
|
+
const opReturnOutput = btcTx.outs[1];
|
|
53
|
+
//Parse script
|
|
54
|
+
const opReturnData = Buffer.from(opReturnOutput.scriptPubKey.hex, "hex");
|
|
55
|
+
if(opReturnData.length===0) throw new Error("Output 1 empty script");
|
|
56
|
+
if(opReturnData.at(0)!==0x6a) throw new Error("Output 1 is not OP_RETURN");
|
|
57
|
+
if(opReturnData.at(1)===0) throw new Error("Output 1 OP_RETURN followed by OP_0");
|
|
58
|
+
let data: Buffer;
|
|
59
|
+
if(opReturnData.at(1) === 0x4c) { //OP_PUSHDATA1
|
|
60
|
+
const dataLength = opReturnData.at(2);
|
|
61
|
+
data = opReturnData.subarray(3, 3+dataLength);
|
|
62
|
+
if(data.length !== dataLength) throw new Error("Output 1 OP_RETURN data length mismatch!");
|
|
63
|
+
} else if(opReturnData.at(1) <= 0x4b) { //OP_PUSH<length>
|
|
64
|
+
const dataLength = opReturnData.at(1);
|
|
65
|
+
data = opReturnData.subarray(2, 2+dataLength);
|
|
66
|
+
if(data.length !== dataLength) throw new Error("Output 1 OP_RETURN data length mismatch!");
|
|
67
|
+
} else {
|
|
68
|
+
throw new Error("Output 1 invalid push opcode");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//Parse OP_RETURN data
|
|
72
|
+
const res = this.fromOpReturnData(data);
|
|
73
|
+
|
|
74
|
+
this.recipient = res.recipient;
|
|
75
|
+
this.rawAmounts = res.rawAmounts;
|
|
76
|
+
|
|
77
|
+
this.callerFeeRate = callerFeeRate;
|
|
78
|
+
this.frontingFeeRate = frontingFeeRate;
|
|
79
|
+
this.executionFeeRate = executionFeeRate;
|
|
80
|
+
|
|
81
|
+
this.executionHash = res.executionHash;
|
|
82
|
+
this.executionExpiry = executionExpiry;
|
|
83
|
+
|
|
84
|
+
this.btcTx = btcTx;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
serialize(): any {
|
|
88
|
+
return this.btcTx;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
getRecipient(): string {
|
|
92
|
+
return this.recipient;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
abstract isRecipient(address: string): boolean;
|
|
96
|
+
|
|
97
|
+
abstract getFrontingId(): string;
|
|
98
|
+
|
|
99
|
+
getOutputWithoutFees(): bigint[] {
|
|
100
|
+
return this.rawAmounts;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getCallerFee(): bigint[] {
|
|
104
|
+
return this.rawAmounts.map(val => val * this.callerFeeRate / 100_000n);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
getFrontingFee(): bigint[] {
|
|
108
|
+
return this.rawAmounts.map(val => val * this.frontingFeeRate / 100_000n);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getExecutionFee(): bigint[] {
|
|
112
|
+
return [this.rawAmounts[0] * this.executionFeeRate / 100_000n];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
getTotalOutput(): bigint[] {
|
|
116
|
+
const amounts = [...this.getOutputWithoutFees()];
|
|
117
|
+
const callerFee = this.getCallerFee();
|
|
118
|
+
if(callerFee!=null) callerFee.forEach((fee, i) => {
|
|
119
|
+
if(fee==null || fee===0n) return;
|
|
120
|
+
if(amounts[i]==null) throw new Error("Caller fee token out of bounds");
|
|
121
|
+
amounts[i] += fee;
|
|
122
|
+
});
|
|
123
|
+
const frontingFee = this.getFrontingFee();
|
|
124
|
+
if(frontingFee!=null) frontingFee.forEach((fee, i) => {
|
|
125
|
+
if(fee==null || fee===0n) return;
|
|
126
|
+
if(amounts[i]==null) throw new Error("Fronting fee token out of bounds");
|
|
127
|
+
amounts[i] += fee;
|
|
128
|
+
});
|
|
129
|
+
const executionFee = this.getExecutionFee();
|
|
130
|
+
if(executionFee!=null) executionFee.forEach((fee, i) => {
|
|
131
|
+
if(fee==null || fee===0n) return;
|
|
132
|
+
if(amounts[i]==null) throw new Error("Execution fee token out of bounds");
|
|
133
|
+
amounts[i] += fee;
|
|
134
|
+
});
|
|
135
|
+
amounts.forEach((val, index) => {
|
|
136
|
+
if(val >= 2n**64n) throw new Error("Token "+index+" amount out of bounds");
|
|
137
|
+
})
|
|
138
|
+
return amounts;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
getExecutionData(): ExecutionData | null {
|
|
142
|
+
if(this.executionHash==null) return null;
|
|
143
|
+
return {
|
|
144
|
+
executionHash: this.executionHash,
|
|
145
|
+
executionExpiry: this.executionExpiry
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getTxId(): string {
|
|
150
|
+
return this.btcTx.txid;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
getSpentVaultUtxo(): string {
|
|
154
|
+
const in0 = this.btcTx.ins[0];
|
|
155
|
+
return in0.txid+":"+in0.vout;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
getCreatedVaultUtxo(): string {
|
|
159
|
+
return this.getTxId()+":0";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
getNewVaultScript(): Buffer {
|
|
163
|
+
return Buffer.from(this.btcTx.outs[0].scriptPubKey.hex, "hex");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
getNewVaultBtcAmount(): number {
|
|
167
|
+
return this.btcTx.outs[0].value;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
170
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {StorageObject} from "./StorageObject";
|
|
2
|
-
|
|
3
|
-
export interface IStorageManager<T extends StorageObject> {
|
|
4
|
-
|
|
5
|
-
data: {
|
|
6
|
-
[key: string]: T
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
init(): Promise<void>;
|
|
10
|
-
saveData(hash: string, object: T): Promise<void>;
|
|
11
|
-
removeData(hash: string): Promise<void>;
|
|
12
|
-
loadData(type: new(data: any) => T): Promise<T[]>;
|
|
13
|
-
|
|
14
|
-
removeDataArr?(keys: string[]): Promise<void>;
|
|
15
|
-
saveDataArr?(values: {id: string, object: T}[]): Promise<void>;
|
|
16
|
-
|
|
1
|
+
import {StorageObject} from "./StorageObject";
|
|
2
|
+
|
|
3
|
+
export interface IStorageManager<T extends StorageObject> {
|
|
4
|
+
|
|
5
|
+
data: {
|
|
6
|
+
[key: string]: T
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
saveData(hash: string, object: T): Promise<void>;
|
|
11
|
+
removeData(hash: string): Promise<void>;
|
|
12
|
+
loadData(type: new(data: any) => T): Promise<T[]>;
|
|
13
|
+
|
|
14
|
+
removeDataArr?(keys: string[]): Promise<void>;
|
|
15
|
+
saveDataArr?(values: {id: string, object: T}[]): Promise<void>;
|
|
16
|
+
|
|
17
17
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface StorageObject {
|
|
4
|
-
|
|
5
|
-
serialize(): any;
|
|
6
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export interface StorageObject {
|
|
4
|
+
|
|
5
|
+
serialize(): any;
|
|
6
|
+
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export enum ChainSwapType {
|
|
2
|
-
HTLC = 0,
|
|
3
|
-
CHAIN = 1,
|
|
4
|
-
CHAIN_NONCED = 2,
|
|
5
|
-
CHAIN_TXID = 3
|
|
6
|
-
}
|
|
1
|
+
export enum ChainSwapType {
|
|
2
|
+
HTLC = 0,
|
|
3
|
+
CHAIN = 1,
|
|
4
|
+
CHAIN_NONCED = 2,
|
|
5
|
+
CHAIN_TXID = 3
|
|
6
|
+
}
|
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
export enum SwapCommitStateType {
|
|
2
|
-
EXPIRED=0,
|
|
3
|
-
NOT_COMMITED=1,
|
|
4
|
-
COMMITED=2,
|
|
5
|
-
PAID=3,
|
|
6
|
-
REFUNDABLE=4
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type SwapNotCommitedState = {
|
|
10
|
-
type: SwapCommitStateType.NOT_COMMITED,
|
|
11
|
-
getRefundTxId?: () => Promise<string>,
|
|
12
|
-
getTxBlock?: () => Promise<{blockHeight: number, blockTime: number}>
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type SwapExpiredState = {
|
|
16
|
-
type: SwapCommitStateType.EXPIRED,
|
|
17
|
-
getRefundTxId?: () => Promise<string>,
|
|
18
|
-
getTxBlock?: () => Promise<{blockHeight: number, blockTime: number}>
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type SwapRefundableState = {
|
|
22
|
-
type: SwapCommitStateType.REFUNDABLE
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type SwapCommitedState = {
|
|
26
|
-
type: SwapCommitStateType.COMMITED
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type SwapPaidState = {
|
|
30
|
-
type: SwapCommitStateType.PAID,
|
|
31
|
-
getClaimTxId: () => Promise<string>,
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
1
|
+
export enum SwapCommitStateType {
|
|
2
|
+
EXPIRED=0,
|
|
3
|
+
NOT_COMMITED=1,
|
|
4
|
+
COMMITED=2,
|
|
5
|
+
PAID=3,
|
|
6
|
+
REFUNDABLE=4
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type SwapNotCommitedState = {
|
|
10
|
+
type: SwapCommitStateType.NOT_COMMITED,
|
|
11
|
+
getRefundTxId?: () => Promise<string>,
|
|
12
|
+
getTxBlock?: () => Promise<{blockHeight: number, blockTime: number}>
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type SwapExpiredState = {
|
|
16
|
+
type: SwapCommitStateType.EXPIRED,
|
|
17
|
+
getRefundTxId?: () => Promise<string>,
|
|
18
|
+
getTxBlock?: () => Promise<{blockHeight: number, blockTime: number}>
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type SwapRefundableState = {
|
|
22
|
+
type: SwapCommitStateType.REFUNDABLE
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type SwapCommitedState = {
|
|
26
|
+
type: SwapCommitStateType.COMMITED
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type SwapPaidState = {
|
|
30
|
+
type: SwapCommitStateType.PAID,
|
|
31
|
+
getClaimTxId: () => Promise<string>,
|
|
32
|
+
getClaimResult: () => Promise<string>,
|
|
33
|
+
getTxBlock: () => Promise<{blockHeight: number, blockTime: number}>
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type SwapCommitState = SwapNotCommitedState |
|
|
37
|
+
SwapExpiredState |
|
|
38
|
+
SwapRefundableState |
|
|
39
|
+
SwapCommitedState |
|
|
40
|
+
SwapPaidState;
|