@cogcoin/client 1.1.8 → 1.1.9

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.
Files changed (266) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/commands/mining-read.js +1 -1
  3. package/dist/cli/commands/wallet-mutation/anchor.d.ts +2 -0
  4. package/dist/cli/commands/wallet-mutation/anchor.js +33 -0
  5. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.d.ts +2 -0
  6. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.js +32 -0
  7. package/dist/cli/commands/wallet-mutation/cog.d.ts +2 -0
  8. package/dist/cli/commands/wallet-mutation/cog.js +131 -0
  9. package/dist/cli/commands/wallet-mutation/context.d.ts +3 -0
  10. package/dist/cli/commands/wallet-mutation/context.js +18 -0
  11. package/dist/cli/commands/wallet-mutation/domain-admin.d.ts +2 -0
  12. package/dist/cli/commands/wallet-mutation/domain-admin.js +173 -0
  13. package/dist/cli/commands/wallet-mutation/domain-market.d.ts +2 -0
  14. package/dist/cli/commands/wallet-mutation/domain-market.js +107 -0
  15. package/dist/cli/commands/wallet-mutation/field.d.ts +2 -0
  16. package/dist/cli/commands/wallet-mutation/field.js +125 -0
  17. package/dist/cli/commands/wallet-mutation/register.d.ts +2 -0
  18. package/dist/cli/commands/wallet-mutation/register.js +38 -0
  19. package/dist/cli/commands/wallet-mutation/registry.d.ts +3 -0
  20. package/dist/cli/commands/wallet-mutation/registry.js +39 -0
  21. package/dist/cli/commands/wallet-mutation/reputation.d.ts +2 -0
  22. package/dist/cli/commands/wallet-mutation/reputation.js +57 -0
  23. package/dist/cli/commands/wallet-mutation/types.d.ts +32 -0
  24. package/dist/cli/commands/wallet-mutation/types.js +1 -0
  25. package/dist/cli/commands/wallet-mutation.js +13 -765
  26. package/dist/cli/commands/wallet-read.js +4 -4
  27. package/dist/cli/mutation-success.d.ts +0 -2
  28. package/dist/cli/output/classify.d.ts +7 -0
  29. package/dist/cli/output/classify.js +94 -0
  30. package/dist/cli/output/render.d.ts +2 -0
  31. package/dist/cli/output/render.js +13 -0
  32. package/dist/cli/output/rules/cli-surface.d.ts +2 -0
  33. package/dist/cli/output/rules/cli-surface.js +110 -0
  34. package/dist/cli/output/rules/generic.d.ts +2 -0
  35. package/dist/cli/output/rules/generic.js +13 -0
  36. package/dist/cli/output/rules/index.d.ts +2 -0
  37. package/dist/cli/output/rules/index.js +24 -0
  38. package/dist/cli/output/rules/mining-update.d.ts +2 -0
  39. package/dist/cli/output/rules/mining-update.js +68 -0
  40. package/dist/cli/output/rules/services.d.ts +2 -0
  41. package/dist/cli/output/rules/services.js +110 -0
  42. package/dist/cli/output/rules/wallet-admin.d.ts +2 -0
  43. package/dist/cli/output/rules/wallet-admin.js +224 -0
  44. package/dist/cli/output/rules/wallet-mutations.d.ts +2 -0
  45. package/dist/cli/output/rules/wallet-mutations.js +274 -0
  46. package/dist/cli/output/types.d.ts +16 -0
  47. package/dist/cli/output/types.js +1 -0
  48. package/dist/cli/output.d.ts +2 -168
  49. package/dist/cli/output.js +6 -989
  50. package/dist/cli/pagination.d.ts +15 -0
  51. package/dist/cli/pagination.js +16 -0
  52. package/dist/cli/recommendations.d.ts +4 -0
  53. package/dist/cli/recommendations.js +108 -0
  54. package/dist/cli/wallet-format/availability.d.ts +5 -0
  55. package/dist/cli/wallet-format/availability.js +96 -0
  56. package/dist/cli/wallet-format/balance.d.ts +2 -0
  57. package/dist/cli/wallet-format/balance.js +162 -0
  58. package/dist/cli/wallet-format/domains.d.ts +8 -0
  59. package/dist/cli/wallet-format/domains.js +84 -0
  60. package/dist/cli/wallet-format/fields.d.ts +6 -0
  61. package/dist/cli/wallet-format/fields.js +61 -0
  62. package/dist/cli/wallet-format/identity.d.ts +5 -0
  63. package/dist/cli/wallet-format/identity.js +19 -0
  64. package/dist/cli/wallet-format/locks.d.ts +7 -0
  65. package/dist/cli/wallet-format/locks.js +52 -0
  66. package/dist/cli/wallet-format/overview.d.ts +2 -0
  67. package/dist/cli/wallet-format/overview.js +122 -0
  68. package/dist/cli/wallet-format/pending.d.ts +13 -0
  69. package/dist/cli/wallet-format/pending.js +101 -0
  70. package/dist/cli/wallet-format/shared.d.ts +7 -0
  71. package/dist/cli/wallet-format/shared.js +31 -0
  72. package/dist/cli/wallet-format/status.d.ts +3 -0
  73. package/dist/cli/wallet-format/status.js +27 -0
  74. package/dist/cli/wallet-format.d.ts +8 -30
  75. package/dist/cli/wallet-format.js +8 -830
  76. package/dist/cli/wallet-read-helpers.d.ts +6 -0
  77. package/dist/cli/wallet-read-helpers.js +17 -0
  78. package/dist/wallet/mining/candidate.d.ts +1 -1
  79. package/dist/wallet/mining/candidate.js +3 -3
  80. package/dist/wallet/mining/constants.d.ts +2 -2
  81. package/dist/wallet/mining/constants.js +2 -2
  82. package/dist/wallet/mining/sentence-protocol.d.ts +2 -2
  83. package/dist/wallet/mining/sentences.js +8 -8
  84. package/dist/wallet/tx/anchor/confirm.d.ts +15 -0
  85. package/dist/wallet/tx/anchor/confirm.js +60 -0
  86. package/dist/wallet/tx/anchor/draft.d.ts +39 -0
  87. package/dist/wallet/tx/anchor/draft.js +167 -0
  88. package/dist/wallet/tx/anchor/index.d.ts +5 -0
  89. package/dist/wallet/tx/anchor/index.js +148 -0
  90. package/dist/wallet/tx/anchor/intent.d.ts +61 -0
  91. package/dist/wallet/tx/anchor/intent.js +101 -0
  92. package/dist/wallet/tx/anchor/plan.d.ts +3 -0
  93. package/dist/wallet/tx/anchor/plan.js +18 -0
  94. package/dist/wallet/tx/anchor/result.d.ts +25 -0
  95. package/dist/wallet/tx/anchor/result.js +20 -0
  96. package/dist/wallet/tx/anchor.d.ts +1 -39
  97. package/dist/wallet/tx/anchor.js +1 -494
  98. package/dist/wallet/tx/bitcoin-transfer/confirm.d.ts +7 -0
  99. package/dist/wallet/tx/bitcoin-transfer/confirm.js +11 -0
  100. package/dist/wallet/tx/bitcoin-transfer/index.d.ts +5 -0
  101. package/dist/wallet/tx/bitcoin-transfer/index.js +112 -0
  102. package/dist/wallet/tx/bitcoin-transfer/intent.d.ts +52 -0
  103. package/dist/wallet/tx/bitcoin-transfer/intent.js +74 -0
  104. package/dist/wallet/tx/bitcoin-transfer/plan.d.ts +5 -0
  105. package/dist/wallet/tx/bitcoin-transfer/plan.js +21 -0
  106. package/dist/wallet/tx/bitcoin-transfer/result.d.ts +19 -0
  107. package/dist/wallet/tx/bitcoin-transfer/result.js +16 -0
  108. package/dist/wallet/tx/bitcoin-transfer.d.ts +1 -35
  109. package/dist/wallet/tx/bitcoin-transfer.js +1 -200
  110. package/dist/wallet/tx/cog/confirm.d.ts +13 -0
  111. package/dist/wallet/tx/cog/confirm.js +59 -0
  112. package/dist/wallet/tx/cog/draft.d.ts +20 -0
  113. package/dist/wallet/tx/cog/draft.js +114 -0
  114. package/dist/wallet/tx/cog/index.d.ts +6 -0
  115. package/dist/wallet/tx/cog/index.js +117 -0
  116. package/dist/wallet/tx/cog/intent.d.ts +30 -0
  117. package/dist/wallet/tx/cog/intent.js +169 -0
  118. package/dist/wallet/tx/cog/plan.d.ts +19 -0
  119. package/dist/wallet/tx/cog/plan.js +65 -0
  120. package/dist/wallet/tx/cog/result.d.ts +27 -0
  121. package/dist/wallet/tx/cog/result.js +28 -0
  122. package/dist/wallet/tx/cog/types.d.ts +186 -0
  123. package/dist/wallet/tx/cog/types.js +2 -0
  124. package/dist/wallet/tx/cog/variants/claim.d.ts +3 -0
  125. package/dist/wallet/tx/cog/variants/claim.js +92 -0
  126. package/dist/wallet/tx/cog/variants/lock.d.ts +2 -0
  127. package/dist/wallet/tx/cog/variants/lock.js +102 -0
  128. package/dist/wallet/tx/cog/variants/send.d.ts +2 -0
  129. package/dist/wallet/tx/cog/variants/send.js +77 -0
  130. package/dist/wallet/tx/cog.d.ts +1 -96
  131. package/dist/wallet/tx/cog.js +1 -824
  132. package/dist/wallet/tx/common.d.ts +14 -199
  133. package/dist/wallet/tx/common.js +10 -493
  134. package/dist/wallet/tx/domain-admin/confirm.d.ts +17 -0
  135. package/dist/wallet/tx/domain-admin/confirm.js +58 -0
  136. package/dist/wallet/tx/domain-admin/draft.d.ts +20 -0
  137. package/dist/wallet/tx/domain-admin/draft.js +161 -0
  138. package/dist/wallet/tx/domain-admin/index.d.ts +9 -0
  139. package/dist/wallet/tx/domain-admin/index.js +150 -0
  140. package/dist/wallet/tx/domain-admin/intent.d.ts +12 -0
  141. package/dist/wallet/tx/domain-admin/intent.js +61 -0
  142. package/dist/wallet/tx/domain-admin/plan.d.ts +19 -0
  143. package/dist/wallet/tx/domain-admin/plan.js +64 -0
  144. package/dist/wallet/tx/domain-admin/result.d.ts +19 -0
  145. package/dist/wallet/tx/domain-admin/result.js +33 -0
  146. package/dist/wallet/tx/domain-admin/types.d.ts +162 -0
  147. package/dist/wallet/tx/domain-admin/types.js +1 -0
  148. package/dist/wallet/tx/domain-admin/variants/canonical.d.ts +2 -0
  149. package/dist/wallet/tx/domain-admin/variants/canonical.js +22 -0
  150. package/dist/wallet/tx/domain-admin/variants/delegate.d.ts +3 -0
  151. package/dist/wallet/tx/domain-admin/variants/delegate.js +60 -0
  152. package/dist/wallet/tx/domain-admin/variants/endpoint.d.ts +3 -0
  153. package/dist/wallet/tx/domain-admin/variants/endpoint.js +102 -0
  154. package/dist/wallet/tx/domain-admin/variants/miner.d.ts +3 -0
  155. package/dist/wallet/tx/domain-admin/variants/miner.js +59 -0
  156. package/dist/wallet/tx/domain-admin.d.ts +1 -107
  157. package/dist/wallet/tx/domain-admin.js +1 -729
  158. package/dist/wallet/tx/domain-market/confirm.d.ts +6 -0
  159. package/dist/wallet/tx/domain-market/confirm.js +52 -0
  160. package/dist/wallet/tx/domain-market/draft.d.ts +43 -0
  161. package/dist/wallet/tx/domain-market/draft.js +286 -0
  162. package/dist/wallet/tx/domain-market/index.d.ts +6 -0
  163. package/dist/wallet/tx/domain-market/index.js +145 -0
  164. package/dist/wallet/tx/domain-market/intent.d.ts +15 -0
  165. package/dist/wallet/tx/domain-market/intent.js +131 -0
  166. package/dist/wallet/tx/domain-market/plan.d.ts +31 -0
  167. package/dist/wallet/tx/domain-market/plan.js +98 -0
  168. package/dist/wallet/tx/domain-market/result.d.ts +45 -0
  169. package/dist/wallet/tx/domain-market/result.js +88 -0
  170. package/dist/wallet/tx/domain-market/types.d.ts +221 -0
  171. package/dist/wallet/tx/domain-market/types.js +1 -0
  172. package/dist/wallet/tx/domain-market/variants/buy.d.ts +2 -0
  173. package/dist/wallet/tx/domain-market/variants/buy.js +103 -0
  174. package/dist/wallet/tx/domain-market/variants/sell.d.ts +2 -0
  175. package/dist/wallet/tx/domain-market/variants/sell.js +91 -0
  176. package/dist/wallet/tx/domain-market/variants/transfer.d.ts +2 -0
  177. package/dist/wallet/tx/domain-market/variants/transfer.js +105 -0
  178. package/dist/wallet/tx/domain-market.d.ts +1 -116
  179. package/dist/wallet/tx/domain-market.js +1 -1078
  180. package/dist/wallet/tx/draft-build.d.ts +60 -0
  181. package/dist/wallet/tx/draft-build.js +127 -0
  182. package/dist/wallet/tx/executor.d.ts +6 -40
  183. package/dist/wallet/tx/executor.js +6 -100
  184. package/dist/wallet/tx/fee.d.ts +30 -0
  185. package/dist/wallet/tx/fee.js +98 -0
  186. package/dist/wallet/tx/field/confirm.d.ts +11 -0
  187. package/dist/wallet/tx/field/confirm.js +19 -0
  188. package/dist/wallet/tx/field/draft.d.ts +23 -0
  189. package/dist/wallet/tx/field/draft.js +202 -0
  190. package/dist/wallet/tx/field/index.d.ts +5 -0
  191. package/dist/wallet/tx/field/index.js +140 -0
  192. package/dist/wallet/tx/field/intent.d.ts +5 -0
  193. package/dist/wallet/tx/field/intent.js +50 -0
  194. package/dist/wallet/tx/field/plan.d.ts +20 -0
  195. package/dist/wallet/tx/field/plan.js +65 -0
  196. package/dist/wallet/tx/field/result.d.ts +29 -0
  197. package/dist/wallet/tx/field/result.js +103 -0
  198. package/dist/wallet/tx/field/types.d.ts +163 -0
  199. package/dist/wallet/tx/field/types.js +1 -0
  200. package/dist/wallet/tx/field/variants/clear.d.ts +2 -0
  201. package/dist/wallet/tx/field/variants/clear.js +60 -0
  202. package/dist/wallet/tx/field/variants/create.d.ts +2 -0
  203. package/dist/wallet/tx/field/variants/create.js +67 -0
  204. package/dist/wallet/tx/field/variants/set.d.ts +2 -0
  205. package/dist/wallet/tx/field/variants/set.js +195 -0
  206. package/dist/wallet/tx/field.d.ts +1 -95
  207. package/dist/wallet/tx/field.js +1 -920
  208. package/dist/wallet/tx/mining-preemption.d.ts +6 -0
  209. package/dist/wallet/tx/mining-preemption.js +7 -0
  210. package/dist/wallet/tx/primitives.d.ts +13 -0
  211. package/dist/wallet/tx/primitives.js +42 -0
  212. package/dist/wallet/tx/psbt-assert.d.ts +14 -0
  213. package/dist/wallet/tx/psbt-assert.js +39 -0
  214. package/dist/wallet/tx/publish.d.ts +37 -0
  215. package/dist/wallet/tx/publish.js +88 -0
  216. package/dist/wallet/tx/readiness.d.ts +7 -0
  217. package/dist/wallet/tx/readiness.js +61 -0
  218. package/dist/wallet/tx/reconcile.d.ts +24 -0
  219. package/dist/wallet/tx/reconcile.js +72 -0
  220. package/dist/wallet/tx/register/confirm.d.ts +6 -0
  221. package/dist/wallet/tx/register/confirm.js +66 -0
  222. package/dist/wallet/tx/register/draft.d.ts +42 -0
  223. package/dist/wallet/tx/register/draft.js +181 -0
  224. package/dist/wallet/tx/register/index.d.ts +6 -0
  225. package/dist/wallet/tx/register/index.js +158 -0
  226. package/dist/wallet/tx/register/intent.d.ts +74 -0
  227. package/dist/wallet/tx/register/intent.js +119 -0
  228. package/dist/wallet/tx/register/plan.d.ts +43 -0
  229. package/dist/wallet/tx/register/plan.js +168 -0
  230. package/dist/wallet/tx/register/result.d.ts +78 -0
  231. package/dist/wallet/tx/register/result.js +41 -0
  232. package/dist/wallet/tx/register.d.ts +1 -70
  233. package/dist/wallet/tx/register.js +1 -681
  234. package/dist/wallet/tx/reputation/confirm.d.ts +11 -0
  235. package/dist/wallet/tx/reputation/confirm.js +51 -0
  236. package/dist/wallet/tx/reputation/draft.d.ts +20 -0
  237. package/dist/wallet/tx/reputation/draft.js +130 -0
  238. package/dist/wallet/tx/reputation/index.d.ts +4 -0
  239. package/dist/wallet/tx/reputation/index.js +162 -0
  240. package/dist/wallet/tx/reputation/intent.d.ts +36 -0
  241. package/dist/wallet/tx/reputation/intent.js +157 -0
  242. package/dist/wallet/tx/reputation/plan.d.ts +19 -0
  243. package/dist/wallet/tx/reputation/plan.js +64 -0
  244. package/dist/wallet/tx/reputation/result.d.ts +21 -0
  245. package/dist/wallet/tx/reputation/result.js +31 -0
  246. package/dist/wallet/tx/reputation/types.d.ts +130 -0
  247. package/dist/wallet/tx/reputation/types.js +1 -0
  248. package/dist/wallet/tx/reputation.d.ts +1 -74
  249. package/dist/wallet/tx/reputation.js +1 -556
  250. package/dist/wallet/tx/signing.d.ts +18 -0
  251. package/dist/wallet/tx/signing.js +31 -0
  252. package/dist/wallet/tx/state-persist.d.ts +27 -0
  253. package/dist/wallet/tx/state-persist.js +54 -0
  254. package/dist/wallet/tx/types.d.ts +44 -0
  255. package/dist/wallet/tx/types.js +1 -0
  256. package/package.json +1 -1
  257. package/dist/cli/mining-json.d.ts +0 -20
  258. package/dist/cli/mining-json.js +0 -46
  259. package/dist/cli/mutation-json.d.ts +0 -325
  260. package/dist/cli/mutation-json.js +0 -269
  261. package/dist/cli/mutation-resolved-json.d.ts +0 -117
  262. package/dist/cli/mutation-resolved-json.js +0 -123
  263. package/dist/cli/preview-json.d.ts +0 -319
  264. package/dist/cli/preview-json.js +0 -254
  265. package/dist/cli/read-json.d.ts +0 -190
  266. package/dist/cli/read-json.js +0 -627
@@ -1,494 +1 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
- import { encodeSentence } from "@cogcoin/scoring";
3
- import { lookupDomain } from "@cogcoin/indexer/queries";
4
- import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
5
- import { createRpcClient } from "../../bitcoind/node.js";
6
- import {} from "../runtime.js";
7
- import {} from "../state/provider.js";
8
- import { serializeDomainAnchor, validateDomainName, } from "../cogop/index.js";
9
- import { openWalletReadContext } from "../read/index.js";
10
- import { assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback, createWalletMutationFeeMetadata, mergeFixedWalletInputs, outpointKey, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "./common.js";
11
- import { executeWalletMutationOperation, persistWalletMutationState, publishWalletMutation, resolveExistingWalletMutation, } from "./executor.js";
12
- import { upsertPendingMutation } from "./journal.js";
13
- function normalizeDomainName(domainName) {
14
- const normalized = domainName.trim().toLowerCase();
15
- if (normalized.length === 0) {
16
- throw new Error("wallet_anchor_missing_domain");
17
- }
18
- validateDomainName(normalized);
19
- return normalized;
20
- }
21
- function encodeOpReturnScript(payload) {
22
- if (payload.length <= 75) {
23
- return Buffer.concat([
24
- Buffer.from([0x6a, payload.length]),
25
- Buffer.from(payload),
26
- ]).toString("hex");
27
- }
28
- return Buffer.concat([
29
- Buffer.from([0x6a, 0x4c, payload.length]),
30
- Buffer.from(payload),
31
- ]).toString("hex");
32
- }
33
- function satsToBtcNumber(value) {
34
- return Number(value) / 100_000_000;
35
- }
36
- function valueToSats(value) {
37
- const text = typeof value === "number" ? value.toFixed(8) : value;
38
- const match = /^(-?)(\d+)(?:\.(\d{0,8}))?$/.exec(text.trim());
39
- if (match == null) {
40
- throw new Error(`wallet_anchor_invalid_amount_${text}`);
41
- }
42
- const sign = match[1] === "-" ? -1n : 1n;
43
- const whole = BigInt(match[2] ?? "0");
44
- const fraction = BigInt((match[3] ?? "").padEnd(8, "0"));
45
- return sign * ((whole * 100000000n) + fraction);
46
- }
47
- function createIntentFingerprint(parts) {
48
- return createHash("sha256")
49
- .update(parts.map((part) => String(part)).join("\n"))
50
- .digest("hex");
51
- }
52
- function sortUtxos(entries) {
53
- return entries
54
- .slice()
55
- .sort((left, right) => right.amount - left.amount
56
- || left.txid.localeCompare(right.txid)
57
- || left.vout - right.vout);
58
- }
59
- function isSpendableFundingUtxo(entry, fundingScriptPubKeyHex) {
60
- return entry.scriptPubKey === fundingScriptPubKeyHex
61
- && entry.confirmations >= 1
62
- && entry.spendable !== false
63
- && entry.safe !== false;
64
- }
65
- function encodeFoundingMessage(foundingMessageText) {
66
- const trimmed = foundingMessageText?.trim() ?? "";
67
- if (trimmed === "") {
68
- return Promise.resolve({
69
- text: null,
70
- payloadHex: null,
71
- });
72
- }
73
- return encodeSentence(trimmed)
74
- .then((payload) => ({
75
- text: trimmed,
76
- payloadHex: Buffer.from(payload).toString("hex"),
77
- }))
78
- .catch((error) => {
79
- throw new Error(error instanceof Error ? `wallet_anchor_invalid_message_${error.message}` : "wallet_anchor_invalid_message");
80
- });
81
- }
82
- function extractAnchorInvalidMessageReason(error) {
83
- const message = error instanceof Error ? error.message : String(error);
84
- if (message === "wallet_anchor_invalid_message") {
85
- return null;
86
- }
87
- if (!message.startsWith("wallet_anchor_invalid_message_")) {
88
- return null;
89
- }
90
- const reason = message.slice("wallet_anchor_invalid_message_".length).trim();
91
- return reason === "" ? null : reason;
92
- }
93
- async function resolveFoundingMessage(options) {
94
- if (!options.promptForFoundingMessageWhenMissing || options.foundingMessageText != null) {
95
- return encodeFoundingMessage(options.foundingMessageText ?? null);
96
- }
97
- for (;;) {
98
- const answer = await options.prompter.prompt("Founding message (optional, press Enter to skip): ");
99
- try {
100
- return await encodeFoundingMessage(answer);
101
- }
102
- catch (error) {
103
- const reason = extractAnchorInvalidMessageReason(error);
104
- options.prompter.writeLine("Founding message cannot be encoded in canonical Coglex.");
105
- if (reason !== null) {
106
- options.prompter.writeLine(`Reason: ${reason}`);
107
- }
108
- }
109
- }
110
- }
111
- async function confirmDirectAnchor(prompter, options) {
112
- prompter.writeLine(`You are anchoring "${options.domainName}".`);
113
- prompter.writeLine(`Wallet address: ${options.walletAddress}`);
114
- prompter.writeLine("Anchoring publishes a standalone DOMAIN_ANCHOR from the local wallet address.");
115
- if (options.foundingMessageText !== null) {
116
- prompter.writeLine("The founding message bytes will be public in mempool and on-chain.");
117
- prompter.writeLine(`Founding message: ${options.foundingMessageText}`);
118
- }
119
- const answer = (await prompter.prompt("Type the domain name to continue: ")).trim();
120
- if (answer !== options.domainName) {
121
- throw new Error("wallet_anchor_confirmation_rejected");
122
- }
123
- }
124
- function buildDirectAnchorPlan(options) {
125
- const fundingUtxos = sortUtxos(options.allUtxos.filter((entry) => isSpendableFundingUtxo(entry, options.state.funding.scriptPubKeyHex)));
126
- const foundingPayload = options.foundingMessagePayloadHex === null
127
- ? undefined
128
- : Buffer.from(options.foundingMessagePayloadHex, "hex");
129
- const opReturnData = serializeDomainAnchor(options.domainId, foundingPayload).opReturnData;
130
- return {
131
- fixedInputs: [],
132
- outputs: [{ data: Buffer.from(opReturnData).toString("hex") }],
133
- changeAddress: options.state.funding.address,
134
- changePosition: 1,
135
- expectedOpReturnScriptHex: encodeOpReturnScript(opReturnData),
136
- allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
137
- eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout }))),
138
- };
139
- }
140
- function validateDirectAnchorDraft(decoded, funded, plan) {
141
- const outputs = decoded.tx.vout;
142
- if (outputs[0]?.scriptPubKey?.hex !== plan.expectedOpReturnScriptHex) {
143
- throw new Error("wallet_anchor_opreturn_mismatch");
144
- }
145
- if (funded.changepos === -1) {
146
- if (outputs.length !== 1) {
147
- throw new Error("wallet_anchor_unexpected_output_count");
148
- }
149
- return;
150
- }
151
- if (funded.changepos !== plan.changePosition || outputs.length !== 2) {
152
- throw new Error("wallet_anchor_change_position_mismatch");
153
- }
154
- if (outputs[funded.changepos]?.scriptPubKey?.hex !== plan.allowedFundingScriptPubKeyHex) {
155
- throw new Error("wallet_anchor_change_output_mismatch");
156
- }
157
- }
158
- function createDraftAnchorMutation(options) {
159
- const existing = options.existing ?? null;
160
- if (existing !== null) {
161
- return {
162
- ...existing,
163
- kind: "anchor",
164
- domainName: options.domainName,
165
- parentDomainName: null,
166
- senderScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
167
- senderLocalIndex: 0,
168
- intentFingerprintHex: options.intentFingerprintHex,
169
- status: "draft",
170
- lastUpdatedAtUnixMs: options.nowUnixMs,
171
- attemptedTxid: null,
172
- attemptedWtxid: null,
173
- ...createWalletMutationFeeMetadata(options.feeSelection),
174
- temporaryBuilderLockedOutpoints: [],
175
- };
176
- }
177
- return {
178
- mutationId: randomBytes(12).toString("hex"),
179
- kind: "anchor",
180
- domainName: options.domainName,
181
- parentDomainName: null,
182
- senderScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
183
- senderLocalIndex: 0,
184
- intentFingerprintHex: options.intentFingerprintHex,
185
- status: "draft",
186
- createdAtUnixMs: options.nowUnixMs,
187
- lastUpdatedAtUnixMs: options.nowUnixMs,
188
- attemptedTxid: null,
189
- attemptedWtxid: null,
190
- ...createWalletMutationFeeMetadata(options.feeSelection),
191
- temporaryBuilderLockedOutpoints: [],
192
- };
193
- }
194
- function upsertAnchoredDomainRecord(options) {
195
- const domains = options.state.domains.slice();
196
- const existingIndex = domains.findIndex((entry) => entry.name === options.domainName);
197
- const current = existingIndex >= 0 ? domains[existingIndex] : null;
198
- const nextRecord = {
199
- name: options.domainName,
200
- domainId: options.domainId,
201
- currentOwnerScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
202
- canonicalChainStatus: "anchored",
203
- foundingMessageText: options.foundingMessageText ?? current?.foundingMessageText ?? null,
204
- birthTime: current?.birthTime ?? options.state.lastWrittenAtUnixMs,
205
- };
206
- if (existingIndex >= 0) {
207
- domains[existingIndex] = nextRecord;
208
- }
209
- else {
210
- domains.push(nextRecord);
211
- }
212
- return {
213
- ...options.state,
214
- domains,
215
- };
216
- }
217
- function anchorConfirmedOnSnapshot(options) {
218
- const chainDomain = lookupDomain(options.snapshot.state, options.domainName);
219
- if (chainDomain === null || !chainDomain.anchored) {
220
- return false;
221
- }
222
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
223
- return ownerHex === options.state.funding.scriptPubKeyHex
224
- || (options.state.localScriptPubKeyHexes ?? []).includes(ownerHex);
225
- }
226
- async function saveState(options) {
227
- return persistWalletMutationState(options);
228
- }
229
- async function reconcilePendingAnchorMutation(options) {
230
- if (options.mutation.status === "repair-required") {
231
- return {
232
- state: options.state,
233
- mutation: options.mutation,
234
- resolution: "repair-required",
235
- };
236
- }
237
- if (options.context.snapshot !== null && anchorConfirmedOnSnapshot({
238
- snapshot: options.context.snapshot,
239
- state: options.state,
240
- domainName: options.mutation.domainName,
241
- })) {
242
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
243
- const confirmedMutation = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
244
- temporaryBuilderLockedOutpoints: [],
245
- });
246
- const chainDomain = lookupDomain(options.context.snapshot.state, options.mutation.domainName);
247
- const nextState = upsertAnchoredDomainRecord({
248
- state: upsertPendingMutation(options.state, confirmedMutation),
249
- domainName: options.mutation.domainName,
250
- domainId: chainDomain?.domainId ?? 0,
251
- foundingMessageText: options.foundingMessageText,
252
- });
253
- return {
254
- state: await saveState({
255
- state: nextState,
256
- provider: options.provider,
257
- nowUnixMs: options.nowUnixMs,
258
- paths: options.paths,
259
- }),
260
- mutation: confirmedMutation,
261
- resolution: "confirmed",
262
- };
263
- }
264
- if (options.mutation.attemptedTxid !== null) {
265
- const mempool = await options.rpc.getRawMempool().catch(() => []);
266
- if (mempool.includes(options.mutation.attemptedTxid)) {
267
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
268
- const liveMutation = updateMutationRecord(options.mutation, "live", options.nowUnixMs, {
269
- temporaryBuilderLockedOutpoints: [],
270
- });
271
- const domainId = (options.context.snapshot === null
272
- ? null
273
- : lookupDomain(options.context.snapshot.state, options.mutation.domainName)?.domainId)
274
- ?? options.state.domains.find((domain) => domain.name === options.mutation.domainName)?.domainId
275
- ?? 0;
276
- const nextState = upsertAnchoredDomainRecord({
277
- state: upsertPendingMutation(options.state, liveMutation),
278
- domainName: options.mutation.domainName,
279
- domainId,
280
- foundingMessageText: options.foundingMessageText,
281
- });
282
- return {
283
- state: await saveState({
284
- state: nextState,
285
- provider: options.provider,
286
- nowUnixMs: options.nowUnixMs,
287
- paths: options.paths,
288
- }),
289
- mutation: liveMutation,
290
- resolution: "live",
291
- };
292
- }
293
- }
294
- if (options.mutation.status === "broadcast-unknown"
295
- || options.mutation.status === "live"
296
- || options.mutation.status === "draft"
297
- || options.mutation.status === "broadcasting") {
298
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
299
- const canceledMutation = updateMutationRecord(options.mutation, "canceled", options.nowUnixMs, {
300
- temporaryBuilderLockedOutpoints: [],
301
- });
302
- const nextState = upsertPendingMutation(options.state, canceledMutation);
303
- return {
304
- state: await saveState({
305
- state: nextState,
306
- provider: options.provider,
307
- nowUnixMs: options.nowUnixMs,
308
- paths: options.paths,
309
- }),
310
- mutation: canceledMutation,
311
- resolution: "not-seen",
312
- };
313
- }
314
- return {
315
- state: options.state,
316
- mutation: options.mutation,
317
- resolution: "continue",
318
- };
319
- }
320
- function ensureSameTipHeight(context, bestHeight, errorCode) {
321
- if (context.snapshot?.tip?.height !== bestHeight) {
322
- throw new Error(errorCode);
323
- }
324
- }
325
- export async function anchorDomain(options) {
326
- if (!options.prompter.isInteractive) {
327
- throw new Error("wallet_anchor_requires_tty");
328
- }
329
- const normalizedDomainName = normalizeDomainName(options.domainName);
330
- const execution = await executeWalletMutationOperation({
331
- ...options,
332
- controlLockPurpose: "wallet-anchor",
333
- preemptionReason: "wallet-anchor",
334
- async resolveOperation(readContext) {
335
- assertWalletMutationContextReady(readContext, "wallet_anchor");
336
- const message = await resolveFoundingMessage({
337
- foundingMessageText: options.foundingMessageText,
338
- promptForFoundingMessageWhenMissing: options.promptForFoundingMessageWhenMissing,
339
- prompter: options.prompter,
340
- });
341
- const state = readContext.localState.state;
342
- const chainDomain = lookupDomain(readContext.snapshot.state, normalizedDomainName);
343
- if (chainDomain === null) {
344
- throw new Error("wallet_anchor_domain_not_found");
345
- }
346
- if (chainDomain.anchored) {
347
- throw new Error("wallet_anchor_domain_already_anchored");
348
- }
349
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
350
- const localScriptHexes = new Set([
351
- state.funding.scriptPubKeyHex,
352
- ...(state.localScriptPubKeyHexes ?? []),
353
- ]);
354
- if (!localScriptHexes.has(ownerHex)) {
355
- throw new Error("wallet_anchor_owner_not_locally_controlled");
356
- }
357
- if (state.funding.address.trim() === "") {
358
- throw new Error("wallet_anchor_owner_identity_not_supported");
359
- }
360
- return {
361
- state,
362
- normalizedDomainName,
363
- chainDomain,
364
- message,
365
- };
366
- },
367
- createIntentFingerprint(operation) {
368
- return createIntentFingerprint([
369
- "anchor",
370
- operation.state.walletRootId,
371
- operation.normalizedDomainName,
372
- operation.state.funding.scriptPubKeyHex,
373
- operation.message.payloadHex ?? "",
374
- ]);
375
- },
376
- async resolveExistingMutation({ operation, existingMutation, execution }) {
377
- if (existingMutation === null) {
378
- return { state: operation.state, replacementFixedInputs: null, result: null };
379
- }
380
- return resolveExistingWalletMutation({
381
- existingMutation,
382
- execution,
383
- repairRequiredErrorCode: "wallet_anchor_repair_required",
384
- reconcileExistingMutation: (mutation) => reconcilePendingAnchorMutation({
385
- state: operation.state,
386
- mutation,
387
- provider: execution.provider,
388
- nowUnixMs: execution.nowUnixMs,
389
- paths: execution.paths,
390
- rpc: execution.rpc,
391
- walletName: execution.walletName,
392
- context: execution.readContext,
393
- foundingMessageText: operation.message.text,
394
- }),
395
- createReuseResult: ({ mutation, resolution, fees }) => ({
396
- domainName: operation.normalizedDomainName,
397
- txid: mutation.attemptedTxid ?? "unknown",
398
- status: resolution,
399
- reusedExisting: true,
400
- foundingMessageText: operation.message.text,
401
- fees,
402
- }),
403
- });
404
- },
405
- confirm({ operation }) {
406
- return confirmDirectAnchor(options.prompter, {
407
- domainName: operation.normalizedDomainName,
408
- walletAddress: operation.state.funding.address,
409
- foundingMessageText: operation.message.text,
410
- });
411
- },
412
- createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
413
- return {
414
- mutation: createDraftAnchorMutation({
415
- state: operation.state,
416
- domainName: operation.normalizedDomainName,
417
- intentFingerprintHex,
418
- nowUnixMs: execution.nowUnixMs,
419
- feeSelection: execution.feeSelection,
420
- existing: existingMutation ?? null,
421
- }),
422
- prepared: null,
423
- };
424
- },
425
- async build({ operation, state, execution, replacementFixedInputs }) {
426
- const directAnchorPlan = buildDirectAnchorPlan({
427
- state,
428
- allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
429
- domainId: operation.chainDomain.domainId,
430
- foundingMessagePayloadHex: operation.message.payloadHex,
431
- });
432
- return buildWalletMutationTransactionWithReserveFallback({
433
- rpc: execution.rpc,
434
- walletName: execution.walletName,
435
- state,
436
- plan: {
437
- ...directAnchorPlan,
438
- fixedInputs: mergeFixedWalletInputs(directAnchorPlan.fixedInputs, replacementFixedInputs),
439
- },
440
- validateFundedDraft: validateDirectAnchorDraft,
441
- finalizeErrorCode: "wallet_anchor_finalize_failed",
442
- mempoolRejectPrefix: "wallet_anchor_mempool_rejected",
443
- feeRate: execution.feeSelection.feeRateSatVb,
444
- });
445
- },
446
- publish({ operation, state, execution, built, mutation }) {
447
- return publishWalletMutation({
448
- rpc: execution.rpc,
449
- walletName: execution.walletName,
450
- snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
451
- built,
452
- mutation,
453
- state,
454
- provider: execution.provider,
455
- nowUnixMs: execution.nowUnixMs,
456
- paths: execution.paths,
457
- errorPrefix: "wallet_anchor",
458
- async afterAccepted({ state: acceptedState, broadcastingMutation, built, nowUnixMs }) {
459
- const finalStatus = anchorConfirmedOnSnapshot({
460
- snapshot: execution.readContext.snapshot,
461
- state: acceptedState,
462
- domainName: operation.normalizedDomainName,
463
- }) ? "confirmed" : "live";
464
- const finalMutation = updateMutationRecord(broadcastingMutation, finalStatus, nowUnixMs, {
465
- attemptedTxid: built.txid,
466
- attemptedWtxid: built.wtxid,
467
- temporaryBuilderLockedOutpoints: [],
468
- });
469
- return {
470
- state: upsertAnchoredDomainRecord({
471
- state: upsertPendingMutation(acceptedState, finalMutation),
472
- domainName: operation.normalizedDomainName,
473
- domainId: operation.chainDomain.domainId,
474
- foundingMessageText: operation.message.text,
475
- }),
476
- mutation: finalMutation,
477
- status: finalStatus,
478
- };
479
- },
480
- });
481
- },
482
- createResult({ operation, mutation, built, status, reusedExisting, fees }) {
483
- return {
484
- domainName: operation.normalizedDomainName,
485
- txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
486
- status: status,
487
- reusedExisting,
488
- foundingMessageText: operation.message.text,
489
- fees,
490
- };
491
- },
492
- });
493
- return execution.result;
494
- }
1
+ export * from "./anchor/index.js";
@@ -0,0 +1,7 @@
1
+ import type { WalletPrompter } from "../../lifecycle.js";
2
+ export declare function confirmBitcoinTransfer(prompter: WalletPrompter, options: {
3
+ senderAddress: string;
4
+ recipientAddress: string;
5
+ amountSats: bigint;
6
+ assumeYes?: boolean;
7
+ }): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { confirmYesNo } from "../confirm.js";
2
+ export async function confirmBitcoinTransfer(prompter, options) {
3
+ prompter.writeLine(`You are sending ${options.amountSats.toString()} sats.`);
4
+ prompter.writeLine(`Wallet address: ${options.senderAddress}`);
5
+ prompter.writeLine(`Recipient: ${options.recipientAddress}`);
6
+ await confirmYesNo(prompter, "This will publish a standard Bitcoin payment from the wallet address.", {
7
+ assumeYes: options.assumeYes,
8
+ errorCode: "wallet_bitcoin_transfer_confirmation_rejected",
9
+ requiresTtyErrorCode: "wallet_bitcoin_transfer_requires_tty",
10
+ });
11
+ }
@@ -0,0 +1,5 @@
1
+ import { type TransferBitcoinOptions } from "./intent.js";
2
+ import { type BitcoinTransferResult } from "./result.js";
3
+ export type { TransferBitcoinOptions } from "./intent.js";
4
+ export type { BitcoinTransferResult } from "./result.js";
5
+ export declare function transferBitcoin(options: TransferBitcoinOptions): Promise<BitcoinTransferResult>;
@@ -0,0 +1,112 @@
1
+ import { attachOrStartManagedBitcoindService } from "../../../bitcoind/service.js";
2
+ import { createRpcClient } from "../../../bitcoind/node.js";
3
+ import { acquireFileLock } from "../../fs/lock.js";
4
+ import { openWalletReadContext } from "../../read/index.js";
5
+ import { resolveWalletRuntimePathsForTesting } from "../../runtime.js";
6
+ import { createDefaultWalletSecretProvider, } from "../../state/provider.js";
7
+ import { assertWalletBitcoinTransferContextReady, buildWalletMutationTransaction, isAlreadyAcceptedError, isBroadcastUnknownError, isInsufficientFundsError, outpointKey, pauseMiningForWalletMutation, unlockTemporaryBuilderLocks, } from "../common.js";
8
+ import { confirmBitcoinTransfer } from "./confirm.js";
9
+ import { buildPlanForBitcoinTransfer, resolveBitcoinTransferIntent, } from "./intent.js";
10
+ import { validateFundedBitcoinTransfer } from "./plan.js";
11
+ import { createBitcoinTransferResult } from "./result.js";
12
+ export async function transferBitcoin(options) {
13
+ const intent = resolveBitcoinTransferIntent(options);
14
+ const provider = options.provider ?? createDefaultWalletSecretProvider();
15
+ const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
16
+ const controlLock = await acquireFileLock(paths.walletControlLockPath, {
17
+ purpose: "wallet-bitcoin-transfer",
18
+ walletRootId: null,
19
+ });
20
+ try {
21
+ const miningPreemption = await pauseMiningForWalletMutation({
22
+ paths,
23
+ reason: "wallet-bitcoin-transfer",
24
+ });
25
+ const readContext = await (options.openReadContext ?? openWalletReadContext)({
26
+ dataDir: options.dataDir,
27
+ databasePath: options.databasePath,
28
+ secretProvider: provider,
29
+ walletControlLockHeld: true,
30
+ paths,
31
+ });
32
+ try {
33
+ assertWalletBitcoinTransferContextReady(readContext, "wallet_bitcoin_transfer");
34
+ const state = readContext.localState.state;
35
+ if (state.funding.scriptPubKeyHex === intent.recipientScriptPubKeyHex) {
36
+ throw new Error("wallet_bitcoin_transfer_self_transfer");
37
+ }
38
+ await confirmBitcoinTransfer(options.prompter, {
39
+ senderAddress: state.funding.address,
40
+ recipientAddress: intent.recipientAddress,
41
+ amountSats: intent.amountSats,
42
+ assumeYes: options.assumeYes,
43
+ });
44
+ const node = await (options.attachService ?? attachOrStartManagedBitcoindService)({
45
+ dataDir: options.dataDir,
46
+ chain: "main",
47
+ startHeight: 0,
48
+ walletRootId: state.walletRootId,
49
+ });
50
+ const rpc = (options.rpcFactory ?? createRpcClient)(node.rpc);
51
+ const walletName = state.managedCoreWallet.walletName;
52
+ const allUtxos = await rpc.listUnspent(walletName, 1);
53
+ const plan = buildPlanForBitcoinTransfer({
54
+ state,
55
+ allUtxos,
56
+ recipientAddress: intent.recipientAddress,
57
+ recipientScriptPubKeyHex: intent.recipientScriptPubKeyHex,
58
+ amountSats: intent.amountSats,
59
+ outpointKey,
60
+ });
61
+ let built;
62
+ try {
63
+ built = await buildWalletMutationTransaction({
64
+ rpc,
65
+ walletName,
66
+ state,
67
+ plan,
68
+ validateFundedDraft: validateFundedBitcoinTransfer,
69
+ finalizeErrorCode: "wallet_bitcoin_transfer_finalize_failed",
70
+ mempoolRejectPrefix: "wallet_bitcoin_transfer_mempool_reject",
71
+ });
72
+ }
73
+ catch (error) {
74
+ if (isInsufficientFundsError(error)) {
75
+ throw new Error("wallet_bitcoin_transfer_insufficient_funds", { cause: error });
76
+ }
77
+ throw error;
78
+ }
79
+ try {
80
+ await rpc.sendRawTransaction(built.rawHex);
81
+ }
82
+ catch (error) {
83
+ if (!isAlreadyAcceptedError(error)) {
84
+ if (isInsufficientFundsError(error)) {
85
+ throw new Error("wallet_bitcoin_transfer_insufficient_funds", { cause: error });
86
+ }
87
+ if (isBroadcastUnknownError(error)) {
88
+ throw new Error("wallet_bitcoin_transfer_broadcast_unknown", { cause: error });
89
+ }
90
+ throw error;
91
+ }
92
+ }
93
+ finally {
94
+ await unlockTemporaryBuilderLocks(rpc, walletName, built.temporaryBuilderLockedOutpoints);
95
+ }
96
+ return createBitcoinTransferResult({
97
+ state,
98
+ built,
99
+ amountSats: intent.amountSats,
100
+ recipientAddress: intent.recipientAddress,
101
+ recipientScriptPubKeyHex: intent.recipientScriptPubKeyHex,
102
+ });
103
+ }
104
+ finally {
105
+ await readContext.close();
106
+ await miningPreemption.release();
107
+ }
108
+ }
109
+ finally {
110
+ await controlLock.release();
111
+ }
112
+ }
@@ -0,0 +1,52 @@
1
+ import type { RpcListUnspentEntry } from "../../../bitcoind/types.js";
2
+ import { attachOrStartManagedBitcoindService } from "../../../bitcoind/service.js";
3
+ import { createRpcClient } from "../../../bitcoind/node.js";
4
+ import type { WalletPrompter } from "../../lifecycle.js";
5
+ import { openWalletReadContext } from "../../read/index.js";
6
+ import type { WalletRuntimePaths } from "../../runtime.js";
7
+ import type { WalletSecretProvider } from "../../state/provider.js";
8
+ import type { WalletStateV1 } from "../../types.js";
9
+ import type { FixedWalletInput, WalletMutationRpcClient } from "../common.js";
10
+ export interface WalletBitcoinTransferRpcClient extends WalletMutationRpcClient {
11
+ sendRawTransaction(hex: string): Promise<string>;
12
+ }
13
+ export interface TransferBitcoinOptions {
14
+ amountSatsText: string;
15
+ target: string;
16
+ dataDir: string;
17
+ databasePath: string;
18
+ provider?: WalletSecretProvider;
19
+ prompter: WalletPrompter;
20
+ assumeYes?: boolean;
21
+ paths?: WalletRuntimePaths;
22
+ openReadContext?: typeof openWalletReadContext;
23
+ attachService?: typeof attachOrStartManagedBitcoindService;
24
+ rpcFactory?: (config: Parameters<typeof createRpcClient>[0]) => WalletBitcoinTransferRpcClient;
25
+ }
26
+ export interface BitcoinTransferIntent {
27
+ amountSats: bigint;
28
+ recipientAddress: string;
29
+ recipientScriptPubKeyHex: string;
30
+ }
31
+ export interface BitcoinTransferPlan {
32
+ fixedInputs: FixedWalletInput[];
33
+ outputs: unknown[];
34
+ changeAddress: string;
35
+ changePosition: number | null;
36
+ allowedFundingScriptPubKeyHex: string;
37
+ eligibleFundingOutpointKeys: Set<string>;
38
+ recipientScriptPubKeyHex: string;
39
+ amountSats: bigint;
40
+ }
41
+ export declare function resolveBitcoinTransferIntent(options: TransferBitcoinOptions): BitcoinTransferIntent;
42
+ export declare function buildPlanForBitcoinTransfer(options: {
43
+ state: WalletStateV1;
44
+ allUtxos: RpcListUnspentEntry[];
45
+ recipientAddress: string;
46
+ recipientScriptPubKeyHex: string;
47
+ amountSats: bigint;
48
+ outpointKey(outpoint: {
49
+ txid: string;
50
+ vout: number;
51
+ }): string;
52
+ }): BitcoinTransferPlan;