-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminiscript-types.ts
120 lines (100 loc) · 4.31 KB
/
miniscript-types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//Converted from https://github.com/bitcoin/bitcoin/blob/e69796c79c0aa202087a13ba62d9fbcc1c8754d4/src/script/miniscript.h#L157 with the help of chatgpt
let Types = {
BaseType: 1 << 0, // Corresponds to *p == 'B'
VerifyType: 1 << 1, // Corresponds to *p == 'V'
KeyType: 1 << 2, // Corresponds to *p == 'K'
WrappedType: 1 << 3, // Corresponds to *p == 'W'
ZeroArgProperty: 1 << 4, // Corresponds to *p == 'z'
OneArgProperty: 1 << 5, // Corresponds to *p == 'o'
NonzeroArgProperty: 1 << 6, // Corresponds to *p == 'n'
DissatisfiableProperty: 1 << 7, // Corresponds to *p == 'd'
UnitProperty: 1 << 8, // Corresponds to *p == 'u'
ExpressionProperty: 1 << 9, // Corresponds to *p == 'e'
ForcedProperty: 1 << 10, // Corresponds to *p == 'f'
SafeProperty: 1 << 11, // Corresponds to *p == 's'
NonmalleableProperty: 1 << 12, // Corresponds to *p == 'm'
ExpensiveVerify: 1 << 13, // Corresponds to *p == 'x'
ContainsRelativeTimeTimelock: 1 << 14, // Corresponds to *p == 'g'
ContainsRelativeHeightTimelock: 1 << 15, // Corresponds to *p == 'h'
ContainsTimeTimelock: 1 << 16, // Corresponds to *p == 'i'
ContainsHeightTimelock: 1 << 17, // Corresponds to *p == 'j'
NoCombinationHeightTimeLocks: 1 << 18, // Corresponds to *p == 'k'
};
let TypeDescriptions = {
BaseType:
"takes inputs from the top of the stack and pushes a nonzero value of up to 4 bytes on satisfaction, or an exact 0 on dissatisfaction.",
VerifyType: "leaves nothing on the stack.",
WrappedType:
"takes input from one below the top of the stack and pushes a non-zero on top (or one below the top) of the stack on satisfaction, or an exact 0 on dissatisfaction.",
};
function sanityCheck(type: number) {
let num_types =
(type & Types.KeyType ? 1 : 0) +
(type & Types.VerifyType ? 1 : 0) +
(type & Types.BaseType ? 1 : 0) +
(type & Types.WrappedType ? 1 : 0);
if (num_types === 0) {
throw new Error(
`Type must be one of Key, Verify, Base, or Wrapped type. Type value: ${type}`
);
}
if (num_types !== 1) {
throw new Error(
"Key, Verify, Base, and Wrapped types conflict with each other"
);
}
if (type & Types.ZeroArgProperty && type & Types.OneArgProperty) {
throw new Error("The ZeroArgProperty conflicts with the OneArgProperty");
}
if (type & Types.NonzeroArgProperty && type & Types.ZeroArgProperty) {
throw new Error(
"The NonzeroArgProperty conflicts with the ZeroArgProperty"
);
}
if (type & Types.NonzeroArgProperty && type & Types.WrappedType) {
throw new Error("The NonzeroArgProperty conflicts with the WrappedType");
}
if (type & Types.VerifyType && type & Types.DissatisfiableProperty) {
throw new Error("The VerifyType conflicts with the DissatisfiableProperty");
}
if (type & Types.KeyType && !(type & Types.UnitProperty)) {
throw new Error("The KeyType implies the UnitProperty");
}
if (type & Types.VerifyType && type & Types.UnitProperty) {
throw new Error("The VerifyType conflicts with the UnitProperty");
}
if (type & Types.ExpressionProperty && type & Types.ForcedProperty) {
throw new Error("The ExpressionProperty conflicts with the ForcedProperty");
}
if (
type & Types.ExpressionProperty &&
!(type & Types.DissatisfiableProperty)
) {
throw new Error(
"The ExpressionProperty implies the DissatisfiableProperty"
);
}
if (type & Types.VerifyType && type & Types.ExpressionProperty) {
throw new Error("The VerifyType conflicts with the ExpressionProperty");
}
if (type & Types.DissatisfiableProperty && type & Types.ForcedProperty) {
throw new Error(
"The DissatisfiableProperty conflicts with the ForcedProperty"
);
}
if (type & Types.VerifyType && !(type & Types.ForcedProperty)) {
throw new Error("The VerifyType implies the ForcedProperty");
}
if (type & Types.KeyType && !(type & Types.SafeProperty)) {
throw new Error("The KeyType implies the SafeProperty");
}
if (type & Types.ZeroArgProperty && !(type & Types.NonmalleableProperty)) {
throw new Error("The ZeroArgProperty implies the NonmalleableProperty");
}
return type;
}
function hasType(typeToCheck: number, types: number[]) {
let combinedTypes = types.reduce((acc, c) => acc | c, 0);
return (typeToCheck & combinedTypes) == combinedTypes;
}
export { Types, TypeDescriptions, sanityCheck, hasType };