|
9 | 9 | #include <pubkey.h> |
10 | 10 | #include <script/miniscript.h> |
11 | 11 | #include <script/parsing.h> |
| 12 | +#include <script/policy.h> |
12 | 13 | #include <script/script.h> |
13 | 14 | #include <script/signingprovider.h> |
14 | 15 | #include <script/solver.h> |
@@ -1941,6 +1942,55 @@ std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index |
1941 | 1942 | error = "Can only have addr() at top level"; |
1942 | 1943 | return {}; |
1943 | 1944 | } |
| 1945 | + if (ctx == ParseScriptContext::TOP && Func("compile_tr", expr)) { |
| 1946 | + auto arg = Expr(expr); |
| 1947 | + auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error); |
| 1948 | + if (internal_keys.empty()) { |
| 1949 | + error = strprintf("compile_tr(): %s", error); |
| 1950 | + return {}; |
| 1951 | + } |
| 1952 | + ++key_exp_index; |
| 1953 | + if (!Const(",", expr)) { |
| 1954 | + error = "compile_tr(): expected ',' after internal key"; |
| 1955 | + return {}; |
| 1956 | + } |
| 1957 | + |
| 1958 | + KeyParser parser(/*out = */&out, /* in = */nullptr, /* ctx = */miniscript::MiniscriptContext::TAPSCRIPT, key_exp_index); |
| 1959 | + auto pol = policy::ParsePolicy<uint32_t>(expr, parser); |
| 1960 | + if (!pol) { |
| 1961 | + error = "compile_tr(): invalid policy expression"; |
| 1962 | + if (!parser.m_key_parsing_error.empty()) error = strprintf("compile_tr(): %s", parser.m_key_parsing_error); |
| 1963 | + return {}; |
| 1964 | + } |
| 1965 | + |
| 1966 | + auto result = policy::CompileTrNative<uint32_t>(*pol); |
| 1967 | + if (!result) { |
| 1968 | + error = "compile_tr(): policy compilation failed (too many leaves or unsupported policy)"; |
| 1969 | + return {}; |
| 1970 | + } |
| 1971 | + |
| 1972 | + auto& [scripts, depths] = *result; |
| 1973 | + |
| 1974 | + // Each compiled leaf's Node<uint32_t> uses key indices from parser.m_keys. |
| 1975 | + // Give each MiniscriptDescriptor a clone of all keys so indices resolve correctly. |
| 1976 | + std::vector<std::unique_ptr<DescriptorImpl>> descs; |
| 1977 | + for (size_t i = 0; i < scripts.size(); ++i) { |
| 1978 | + std::vector<std::unique_ptr<PubkeyProvider>> leaf_keys; |
| 1979 | + for (const auto& key_vec : parser.m_keys) { |
| 1980 | + leaf_keys.push_back(key_vec.at(0)->Clone()); |
| 1981 | + } |
| 1982 | + descs.push_back(std::make_unique<MiniscriptDescriptor>( |
| 1983 | + std::move(leaf_keys), std::move(scripts[i]))); |
| 1984 | + } |
| 1985 | + |
| 1986 | + key_exp_index += parser.m_keys.size(); |
| 1987 | + ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(0)), std::move(descs), depths)); |
| 1988 | + return ret; |
| 1989 | + |
| 1990 | + } else if (Func("compile_tr", expr)) { |
| 1991 | + error = "Can only have compile_tr at top level"; |
| 1992 | + return {}; |
| 1993 | + } |
1944 | 1994 | if (ctx == ParseScriptContext::TOP && Func("tr", expr)) { |
1945 | 1995 | auto arg = Expr(expr); |
1946 | 1996 | auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error); |
|
0 commit comments