@cogcoin/client 1.1.7 → 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 (284) hide show
  1. package/README.md +1 -1
  2. package/dist/bitcoind/service.js +1 -1
  3. package/dist/cli/commands/mining-read.js +1 -1
  4. package/dist/cli/commands/wallet-mutation/anchor.d.ts +2 -0
  5. package/dist/cli/commands/wallet-mutation/anchor.js +33 -0
  6. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.d.ts +2 -0
  7. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.js +32 -0
  8. package/dist/cli/commands/wallet-mutation/cog.d.ts +2 -0
  9. package/dist/cli/commands/wallet-mutation/cog.js +131 -0
  10. package/dist/cli/commands/wallet-mutation/context.d.ts +3 -0
  11. package/dist/cli/commands/wallet-mutation/context.js +18 -0
  12. package/dist/cli/commands/wallet-mutation/domain-admin.d.ts +2 -0
  13. package/dist/cli/commands/wallet-mutation/domain-admin.js +173 -0
  14. package/dist/cli/commands/wallet-mutation/domain-market.d.ts +2 -0
  15. package/dist/cli/commands/wallet-mutation/domain-market.js +107 -0
  16. package/dist/cli/commands/wallet-mutation/field.d.ts +2 -0
  17. package/dist/cli/commands/wallet-mutation/field.js +125 -0
  18. package/dist/cli/commands/wallet-mutation/register.d.ts +2 -0
  19. package/dist/cli/commands/wallet-mutation/register.js +38 -0
  20. package/dist/cli/commands/wallet-mutation/registry.d.ts +3 -0
  21. package/dist/cli/commands/wallet-mutation/registry.js +39 -0
  22. package/dist/cli/commands/wallet-mutation/reputation.d.ts +2 -0
  23. package/dist/cli/commands/wallet-mutation/reputation.js +57 -0
  24. package/dist/cli/commands/wallet-mutation/types.d.ts +32 -0
  25. package/dist/cli/commands/wallet-mutation/types.js +1 -0
  26. package/dist/cli/commands/wallet-mutation.js +13 -765
  27. package/dist/cli/commands/wallet-read.js +4 -4
  28. package/dist/cli/mutation-success.d.ts +0 -2
  29. package/dist/cli/output/classify.d.ts +7 -0
  30. package/dist/cli/output/classify.js +94 -0
  31. package/dist/cli/output/render.d.ts +2 -0
  32. package/dist/cli/output/render.js +13 -0
  33. package/dist/cli/output/rules/cli-surface.d.ts +2 -0
  34. package/dist/cli/output/rules/cli-surface.js +110 -0
  35. package/dist/cli/output/rules/generic.d.ts +2 -0
  36. package/dist/cli/output/rules/generic.js +13 -0
  37. package/dist/cli/output/rules/index.d.ts +2 -0
  38. package/dist/cli/output/rules/index.js +24 -0
  39. package/dist/cli/output/rules/mining-update.d.ts +2 -0
  40. package/dist/cli/output/rules/mining-update.js +68 -0
  41. package/dist/cli/output/rules/services.d.ts +2 -0
  42. package/dist/cli/output/rules/services.js +110 -0
  43. package/dist/cli/output/rules/wallet-admin.d.ts +2 -0
  44. package/dist/cli/output/rules/wallet-admin.js +224 -0
  45. package/dist/cli/output/rules/wallet-mutations.d.ts +2 -0
  46. package/dist/cli/output/rules/wallet-mutations.js +274 -0
  47. package/dist/cli/output/types.d.ts +16 -0
  48. package/dist/cli/output/types.js +1 -0
  49. package/dist/cli/output.d.ts +2 -168
  50. package/dist/cli/output.js +6 -989
  51. package/dist/cli/pagination.d.ts +15 -0
  52. package/dist/cli/pagination.js +16 -0
  53. package/dist/cli/recommendations.d.ts +4 -0
  54. package/dist/cli/recommendations.js +108 -0
  55. package/dist/cli/wallet-format/availability.d.ts +5 -0
  56. package/dist/cli/wallet-format/availability.js +96 -0
  57. package/dist/cli/wallet-format/balance.d.ts +2 -0
  58. package/dist/cli/wallet-format/balance.js +162 -0
  59. package/dist/cli/wallet-format/domains.d.ts +8 -0
  60. package/dist/cli/wallet-format/domains.js +84 -0
  61. package/dist/cli/wallet-format/fields.d.ts +6 -0
  62. package/dist/cli/wallet-format/fields.js +61 -0
  63. package/dist/cli/wallet-format/identity.d.ts +5 -0
  64. package/dist/cli/wallet-format/identity.js +19 -0
  65. package/dist/cli/wallet-format/locks.d.ts +7 -0
  66. package/dist/cli/wallet-format/locks.js +52 -0
  67. package/dist/cli/wallet-format/overview.d.ts +2 -0
  68. package/dist/cli/wallet-format/overview.js +122 -0
  69. package/dist/cli/wallet-format/pending.d.ts +13 -0
  70. package/dist/cli/wallet-format/pending.js +101 -0
  71. package/dist/cli/wallet-format/shared.d.ts +7 -0
  72. package/dist/cli/wallet-format/shared.js +31 -0
  73. package/dist/cli/wallet-format/status.d.ts +3 -0
  74. package/dist/cli/wallet-format/status.js +27 -0
  75. package/dist/cli/wallet-format.d.ts +8 -30
  76. package/dist/cli/wallet-format.js +8 -830
  77. package/dist/cli/wallet-read-helpers.d.ts +6 -0
  78. package/dist/cli/wallet-read-helpers.js +17 -0
  79. package/dist/wallet/mining/candidate.d.ts +1 -1
  80. package/dist/wallet/mining/candidate.js +3 -3
  81. package/dist/wallet/mining/constants.d.ts +2 -2
  82. package/dist/wallet/mining/constants.js +2 -2
  83. package/dist/wallet/mining/engine-state.js +10 -0
  84. package/dist/wallet/mining/sentence-protocol.d.ts +2 -2
  85. package/dist/wallet/mining/sentences.js +8 -8
  86. package/dist/wallet/mining/visualizer-sync.js +79 -15
  87. package/dist/wallet/read/context.js +1 -1
  88. package/dist/wallet/reset/artifacts.d.ts +16 -0
  89. package/dist/wallet/reset/artifacts.js +141 -0
  90. package/dist/wallet/reset/execution.d.ts +38 -0
  91. package/dist/wallet/reset/execution.js +458 -0
  92. package/dist/wallet/reset/preflight.d.ts +7 -0
  93. package/dist/wallet/reset/preflight.js +116 -0
  94. package/dist/wallet/reset/preview.d.ts +2 -0
  95. package/dist/wallet/reset/preview.js +50 -0
  96. package/dist/wallet/reset/process-cleanup.d.ts +12 -0
  97. package/dist/wallet/reset/process-cleanup.js +179 -0
  98. package/dist/wallet/reset/types.d.ts +189 -0
  99. package/dist/wallet/reset/types.js +1 -0
  100. package/dist/wallet/reset.d.ts +4 -119
  101. package/dist/wallet/reset.js +4 -882
  102. package/dist/wallet/tx/anchor/confirm.d.ts +15 -0
  103. package/dist/wallet/tx/anchor/confirm.js +60 -0
  104. package/dist/wallet/tx/anchor/draft.d.ts +39 -0
  105. package/dist/wallet/tx/anchor/draft.js +167 -0
  106. package/dist/wallet/tx/anchor/index.d.ts +5 -0
  107. package/dist/wallet/tx/anchor/index.js +148 -0
  108. package/dist/wallet/tx/anchor/intent.d.ts +61 -0
  109. package/dist/wallet/tx/anchor/intent.js +101 -0
  110. package/dist/wallet/tx/anchor/plan.d.ts +3 -0
  111. package/dist/wallet/tx/anchor/plan.js +18 -0
  112. package/dist/wallet/tx/anchor/result.d.ts +25 -0
  113. package/dist/wallet/tx/anchor/result.js +20 -0
  114. package/dist/wallet/tx/anchor.d.ts +1 -39
  115. package/dist/wallet/tx/anchor.js +1 -494
  116. package/dist/wallet/tx/bitcoin-transfer/confirm.d.ts +7 -0
  117. package/dist/wallet/tx/bitcoin-transfer/confirm.js +11 -0
  118. package/dist/wallet/tx/bitcoin-transfer/index.d.ts +5 -0
  119. package/dist/wallet/tx/bitcoin-transfer/index.js +112 -0
  120. package/dist/wallet/tx/bitcoin-transfer/intent.d.ts +52 -0
  121. package/dist/wallet/tx/bitcoin-transfer/intent.js +74 -0
  122. package/dist/wallet/tx/bitcoin-transfer/plan.d.ts +5 -0
  123. package/dist/wallet/tx/bitcoin-transfer/plan.js +21 -0
  124. package/dist/wallet/tx/bitcoin-transfer/result.d.ts +19 -0
  125. package/dist/wallet/tx/bitcoin-transfer/result.js +16 -0
  126. package/dist/wallet/tx/bitcoin-transfer.d.ts +1 -35
  127. package/dist/wallet/tx/bitcoin-transfer.js +1 -200
  128. package/dist/wallet/tx/cog/confirm.d.ts +13 -0
  129. package/dist/wallet/tx/cog/confirm.js +59 -0
  130. package/dist/wallet/tx/cog/draft.d.ts +20 -0
  131. package/dist/wallet/tx/cog/draft.js +114 -0
  132. package/dist/wallet/tx/cog/index.d.ts +6 -0
  133. package/dist/wallet/tx/cog/index.js +117 -0
  134. package/dist/wallet/tx/cog/intent.d.ts +30 -0
  135. package/dist/wallet/tx/cog/intent.js +169 -0
  136. package/dist/wallet/tx/cog/plan.d.ts +19 -0
  137. package/dist/wallet/tx/cog/plan.js +65 -0
  138. package/dist/wallet/tx/cog/result.d.ts +27 -0
  139. package/dist/wallet/tx/cog/result.js +28 -0
  140. package/dist/wallet/tx/cog/types.d.ts +186 -0
  141. package/dist/wallet/tx/cog/types.js +2 -0
  142. package/dist/wallet/tx/cog/variants/claim.d.ts +3 -0
  143. package/dist/wallet/tx/cog/variants/claim.js +92 -0
  144. package/dist/wallet/tx/cog/variants/lock.d.ts +2 -0
  145. package/dist/wallet/tx/cog/variants/lock.js +102 -0
  146. package/dist/wallet/tx/cog/variants/send.d.ts +2 -0
  147. package/dist/wallet/tx/cog/variants/send.js +77 -0
  148. package/dist/wallet/tx/cog.d.ts +1 -96
  149. package/dist/wallet/tx/cog.js +1 -824
  150. package/dist/wallet/tx/common.d.ts +14 -199
  151. package/dist/wallet/tx/common.js +10 -493
  152. package/dist/wallet/tx/domain-admin/confirm.d.ts +17 -0
  153. package/dist/wallet/tx/domain-admin/confirm.js +58 -0
  154. package/dist/wallet/tx/domain-admin/draft.d.ts +20 -0
  155. package/dist/wallet/tx/domain-admin/draft.js +161 -0
  156. package/dist/wallet/tx/domain-admin/index.d.ts +9 -0
  157. package/dist/wallet/tx/domain-admin/index.js +150 -0
  158. package/dist/wallet/tx/domain-admin/intent.d.ts +12 -0
  159. package/dist/wallet/tx/domain-admin/intent.js +61 -0
  160. package/dist/wallet/tx/domain-admin/plan.d.ts +19 -0
  161. package/dist/wallet/tx/domain-admin/plan.js +64 -0
  162. package/dist/wallet/tx/domain-admin/result.d.ts +19 -0
  163. package/dist/wallet/tx/domain-admin/result.js +33 -0
  164. package/dist/wallet/tx/domain-admin/types.d.ts +162 -0
  165. package/dist/wallet/tx/domain-admin/types.js +1 -0
  166. package/dist/wallet/tx/domain-admin/variants/canonical.d.ts +2 -0
  167. package/dist/wallet/tx/domain-admin/variants/canonical.js +22 -0
  168. package/dist/wallet/tx/domain-admin/variants/delegate.d.ts +3 -0
  169. package/dist/wallet/tx/domain-admin/variants/delegate.js +60 -0
  170. package/dist/wallet/tx/domain-admin/variants/endpoint.d.ts +3 -0
  171. package/dist/wallet/tx/domain-admin/variants/endpoint.js +102 -0
  172. package/dist/wallet/tx/domain-admin/variants/miner.d.ts +3 -0
  173. package/dist/wallet/tx/domain-admin/variants/miner.js +59 -0
  174. package/dist/wallet/tx/domain-admin.d.ts +1 -107
  175. package/dist/wallet/tx/domain-admin.js +1 -729
  176. package/dist/wallet/tx/domain-market/confirm.d.ts +6 -0
  177. package/dist/wallet/tx/domain-market/confirm.js +52 -0
  178. package/dist/wallet/tx/domain-market/draft.d.ts +43 -0
  179. package/dist/wallet/tx/domain-market/draft.js +286 -0
  180. package/dist/wallet/tx/domain-market/index.d.ts +6 -0
  181. package/dist/wallet/tx/domain-market/index.js +145 -0
  182. package/dist/wallet/tx/domain-market/intent.d.ts +15 -0
  183. package/dist/wallet/tx/domain-market/intent.js +131 -0
  184. package/dist/wallet/tx/domain-market/plan.d.ts +31 -0
  185. package/dist/wallet/tx/domain-market/plan.js +98 -0
  186. package/dist/wallet/tx/domain-market/result.d.ts +45 -0
  187. package/dist/wallet/tx/domain-market/result.js +88 -0
  188. package/dist/wallet/tx/domain-market/types.d.ts +221 -0
  189. package/dist/wallet/tx/domain-market/types.js +1 -0
  190. package/dist/wallet/tx/domain-market/variants/buy.d.ts +2 -0
  191. package/dist/wallet/tx/domain-market/variants/buy.js +103 -0
  192. package/dist/wallet/tx/domain-market/variants/sell.d.ts +2 -0
  193. package/dist/wallet/tx/domain-market/variants/sell.js +91 -0
  194. package/dist/wallet/tx/domain-market/variants/transfer.d.ts +2 -0
  195. package/dist/wallet/tx/domain-market/variants/transfer.js +105 -0
  196. package/dist/wallet/tx/domain-market.d.ts +1 -116
  197. package/dist/wallet/tx/domain-market.js +1 -1078
  198. package/dist/wallet/tx/draft-build.d.ts +60 -0
  199. package/dist/wallet/tx/draft-build.js +127 -0
  200. package/dist/wallet/tx/executor.d.ts +6 -40
  201. package/dist/wallet/tx/executor.js +6 -100
  202. package/dist/wallet/tx/fee.d.ts +30 -0
  203. package/dist/wallet/tx/fee.js +98 -0
  204. package/dist/wallet/tx/field/confirm.d.ts +11 -0
  205. package/dist/wallet/tx/field/confirm.js +19 -0
  206. package/dist/wallet/tx/field/draft.d.ts +23 -0
  207. package/dist/wallet/tx/field/draft.js +202 -0
  208. package/dist/wallet/tx/field/index.d.ts +5 -0
  209. package/dist/wallet/tx/field/index.js +140 -0
  210. package/dist/wallet/tx/field/intent.d.ts +5 -0
  211. package/dist/wallet/tx/field/intent.js +50 -0
  212. package/dist/wallet/tx/field/plan.d.ts +20 -0
  213. package/dist/wallet/tx/field/plan.js +65 -0
  214. package/dist/wallet/tx/field/result.d.ts +29 -0
  215. package/dist/wallet/tx/field/result.js +103 -0
  216. package/dist/wallet/tx/field/types.d.ts +163 -0
  217. package/dist/wallet/tx/field/types.js +1 -0
  218. package/dist/wallet/tx/field/variants/clear.d.ts +2 -0
  219. package/dist/wallet/tx/field/variants/clear.js +60 -0
  220. package/dist/wallet/tx/field/variants/create.d.ts +2 -0
  221. package/dist/wallet/tx/field/variants/create.js +67 -0
  222. package/dist/wallet/tx/field/variants/set.d.ts +2 -0
  223. package/dist/wallet/tx/field/variants/set.js +195 -0
  224. package/dist/wallet/tx/field.d.ts +1 -95
  225. package/dist/wallet/tx/field.js +1 -920
  226. package/dist/wallet/tx/mining-preemption.d.ts +6 -0
  227. package/dist/wallet/tx/mining-preemption.js +7 -0
  228. package/dist/wallet/tx/primitives.d.ts +13 -0
  229. package/dist/wallet/tx/primitives.js +42 -0
  230. package/dist/wallet/tx/psbt-assert.d.ts +14 -0
  231. package/dist/wallet/tx/psbt-assert.js +39 -0
  232. package/dist/wallet/tx/publish.d.ts +37 -0
  233. package/dist/wallet/tx/publish.js +88 -0
  234. package/dist/wallet/tx/readiness.d.ts +7 -0
  235. package/dist/wallet/tx/readiness.js +61 -0
  236. package/dist/wallet/tx/reconcile.d.ts +24 -0
  237. package/dist/wallet/tx/reconcile.js +72 -0
  238. package/dist/wallet/tx/register/confirm.d.ts +6 -0
  239. package/dist/wallet/tx/register/confirm.js +66 -0
  240. package/dist/wallet/tx/register/draft.d.ts +42 -0
  241. package/dist/wallet/tx/register/draft.js +181 -0
  242. package/dist/wallet/tx/register/index.d.ts +6 -0
  243. package/dist/wallet/tx/register/index.js +158 -0
  244. package/dist/wallet/tx/register/intent.d.ts +74 -0
  245. package/dist/wallet/tx/register/intent.js +119 -0
  246. package/dist/wallet/tx/register/plan.d.ts +43 -0
  247. package/dist/wallet/tx/register/plan.js +168 -0
  248. package/dist/wallet/tx/register/result.d.ts +78 -0
  249. package/dist/wallet/tx/register/result.js +41 -0
  250. package/dist/wallet/tx/register.d.ts +1 -70
  251. package/dist/wallet/tx/register.js +1 -681
  252. package/dist/wallet/tx/reputation/confirm.d.ts +11 -0
  253. package/dist/wallet/tx/reputation/confirm.js +51 -0
  254. package/dist/wallet/tx/reputation/draft.d.ts +20 -0
  255. package/dist/wallet/tx/reputation/draft.js +130 -0
  256. package/dist/wallet/tx/reputation/index.d.ts +4 -0
  257. package/dist/wallet/tx/reputation/index.js +162 -0
  258. package/dist/wallet/tx/reputation/intent.d.ts +36 -0
  259. package/dist/wallet/tx/reputation/intent.js +157 -0
  260. package/dist/wallet/tx/reputation/plan.d.ts +19 -0
  261. package/dist/wallet/tx/reputation/plan.js +64 -0
  262. package/dist/wallet/tx/reputation/result.d.ts +21 -0
  263. package/dist/wallet/tx/reputation/result.js +31 -0
  264. package/dist/wallet/tx/reputation/types.d.ts +130 -0
  265. package/dist/wallet/tx/reputation/types.js +1 -0
  266. package/dist/wallet/tx/reputation.d.ts +1 -74
  267. package/dist/wallet/tx/reputation.js +1 -556
  268. package/dist/wallet/tx/signing.d.ts +18 -0
  269. package/dist/wallet/tx/signing.js +31 -0
  270. package/dist/wallet/tx/state-persist.d.ts +27 -0
  271. package/dist/wallet/tx/state-persist.js +54 -0
  272. package/dist/wallet/tx/types.d.ts +44 -0
  273. package/dist/wallet/tx/types.js +1 -0
  274. package/package.json +1 -1
  275. package/dist/cli/mining-json.d.ts +0 -20
  276. package/dist/cli/mining-json.js +0 -46
  277. package/dist/cli/mutation-json.d.ts +0 -325
  278. package/dist/cli/mutation-json.js +0 -269
  279. package/dist/cli/mutation-resolved-json.d.ts +0 -117
  280. package/dist/cli/mutation-resolved-json.js +0 -123
  281. package/dist/cli/preview-json.d.ts +0 -319
  282. package/dist/cli/preview-json.js +0 -254
  283. package/dist/cli/read-json.d.ts +0 -190
  284. package/dist/cli/read-json.js +0 -627
@@ -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;
@@ -0,0 +1,74 @@
1
+ import { attachOrStartManagedBitcoindService } from "../../../bitcoind/service.js";
2
+ import { createRpcClient } from "../../../bitcoind/node.js";
3
+ import { openWalletReadContext } from "../../read/index.js";
4
+ import { normalizeBtcTarget } from "../targets.js";
5
+ function parsePositiveSats(value) {
6
+ const trimmed = value.trim();
7
+ if (!/^[1-9]\d*$/.test(trimmed)) {
8
+ throw new Error("wallet_bitcoin_transfer_invalid_amount");
9
+ }
10
+ return BigInt(trimmed);
11
+ }
12
+ function normalizeRecipientAddress(target) {
13
+ const trimmed = target.trim();
14
+ try {
15
+ const normalized = normalizeBtcTarget(trimmed);
16
+ if (trimmed.startsWith("spk:") || normalized.opaque || normalized.address === null) {
17
+ throw new Error("wallet_bitcoin_transfer_address_required");
18
+ }
19
+ return {
20
+ address: normalized.address,
21
+ scriptPubKeyHex: normalized.scriptPubKeyHex,
22
+ };
23
+ }
24
+ catch (error) {
25
+ if (error instanceof Error && error.message === "wallet_bitcoin_transfer_address_required") {
26
+ throw error;
27
+ }
28
+ if (trimmed.startsWith("spk:")) {
29
+ throw new Error("wallet_bitcoin_transfer_address_required", { cause: error });
30
+ }
31
+ if (error instanceof Error
32
+ && (error.message === "wallet_target_missing"
33
+ || error.message === "wallet_target_invalid_address"
34
+ || error.message === "wallet_target_invalid_script")) {
35
+ throw new Error("wallet_bitcoin_transfer_invalid_address", { cause: error });
36
+ }
37
+ throw error;
38
+ }
39
+ }
40
+ function satsToBtcNumber(value) {
41
+ return Number(value) / 100_000_000;
42
+ }
43
+ function isSpendableFundingUtxo(entry, fundingScriptPubKeyHex) {
44
+ return entry.scriptPubKey === fundingScriptPubKeyHex
45
+ && entry.confirmations >= 1
46
+ && entry.spendable !== false
47
+ && entry.safe !== false;
48
+ }
49
+ export function resolveBitcoinTransferIntent(options) {
50
+ const amountSats = parsePositiveSats(options.amountSatsText);
51
+ const recipient = normalizeRecipientAddress(options.target);
52
+ return {
53
+ amountSats,
54
+ recipientAddress: recipient.address,
55
+ recipientScriptPubKeyHex: recipient.scriptPubKeyHex,
56
+ };
57
+ }
58
+ export function buildPlanForBitcoinTransfer(options) {
59
+ const fundingUtxos = options.allUtxos.filter((entry) => isSpendableFundingUtxo(entry, options.state.funding.scriptPubKeyHex));
60
+ return {
61
+ fixedInputs: [],
62
+ outputs: [
63
+ {
64
+ [options.recipientAddress]: satsToBtcNumber(options.amountSats),
65
+ },
66
+ ],
67
+ changeAddress: options.state.funding.address,
68
+ changePosition: null,
69
+ allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
70
+ eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => options.outpointKey({ txid: entry.txid, vout: entry.vout }))),
71
+ recipientScriptPubKeyHex: options.recipientScriptPubKeyHex,
72
+ amountSats: options.amountSats,
73
+ };
74
+ }
@@ -0,0 +1,5 @@
1
+ import type { RpcDecodedPsbt } from "../../../bitcoind/types.js";
2
+ import type { BitcoinTransferPlan } from "./intent.js";
3
+ export declare function validateFundedBitcoinTransfer(decoded: RpcDecodedPsbt, _funded: {
4
+ fee: number;
5
+ }, plan: BitcoinTransferPlan): void;
@@ -0,0 +1,21 @@
1
+ function btcValueToSats(value) {
2
+ const numeric = typeof value === "string" ? Number(value) : value;
3
+ return BigInt(Math.round(numeric * 100_000_000));
4
+ }
5
+ export function validateFundedBitcoinTransfer(decoded, _funded, plan) {
6
+ if (decoded.tx.vin.length === 0) {
7
+ throw new Error("wallet_bitcoin_transfer_missing_sender_input");
8
+ }
9
+ const recipientOutputs = decoded.tx.vout.filter((output) => output.scriptPubKey?.hex === plan.recipientScriptPubKeyHex);
10
+ if (recipientOutputs.length !== 1) {
11
+ throw new Error("wallet_bitcoin_transfer_missing_recipient_output");
12
+ }
13
+ if (btcValueToSats(recipientOutputs[0].value) !== plan.amountSats) {
14
+ throw new Error("wallet_bitcoin_transfer_recipient_amount_mismatch");
15
+ }
16
+ const hasUnexpectedOutput = decoded.tx.vout.some((output) => output.scriptPubKey?.hex !== plan.recipientScriptPubKeyHex
17
+ && output.scriptPubKey?.hex !== plan.allowedFundingScriptPubKeyHex);
18
+ if (hasUnexpectedOutput) {
19
+ throw new Error("wallet_bitcoin_transfer_unexpected_output");
20
+ }
21
+ }
@@ -0,0 +1,19 @@
1
+ import type { WalletStateV1 } from "../../types.js";
2
+ import type { BuiltWalletMutationTransaction } from "../common.js";
3
+ export interface BitcoinTransferResult {
4
+ amountSats: bigint;
5
+ feeSats: bigint;
6
+ senderAddress: string;
7
+ recipientAddress: string;
8
+ recipientScriptPubKeyHex: string;
9
+ changeAddress: string;
10
+ txid: string;
11
+ wtxid: string | null;
12
+ }
13
+ export declare function createBitcoinTransferResult(options: {
14
+ state: WalletStateV1;
15
+ built: BuiltWalletMutationTransaction;
16
+ amountSats: bigint;
17
+ recipientAddress: string;
18
+ recipientScriptPubKeyHex: string;
19
+ }): BitcoinTransferResult;
@@ -0,0 +1,16 @@
1
+ function btcValueToSats(value) {
2
+ const numeric = typeof value === "string" ? Number(value) : value;
3
+ return BigInt(Math.round(numeric * 100_000_000));
4
+ }
5
+ export function createBitcoinTransferResult(options) {
6
+ return {
7
+ amountSats: options.amountSats,
8
+ feeSats: btcValueToSats(options.built.funded.fee),
9
+ senderAddress: options.state.funding.address,
10
+ recipientAddress: options.recipientAddress,
11
+ recipientScriptPubKeyHex: options.recipientScriptPubKeyHex,
12
+ changeAddress: options.state.funding.address,
13
+ txid: options.built.txid,
14
+ wtxid: options.built.wtxid,
15
+ };
16
+ }
@@ -1,35 +1 @@
1
- import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
2
- import { createRpcClient } from "../../bitcoind/node.js";
3
- import type { WalletPrompter } from "../lifecycle.js";
4
- import { openWalletReadContext } from "../read/index.js";
5
- import { type WalletRuntimePaths } from "../runtime.js";
6
- import { type WalletSecretProvider } from "../state/provider.js";
7
- import { type WalletMutationRpcClient } from "./common.js";
8
- interface WalletBitcoinTransferRpcClient extends WalletMutationRpcClient {
9
- sendRawTransaction(hex: string): Promise<string>;
10
- }
11
- export interface BitcoinTransferResult {
12
- amountSats: bigint;
13
- feeSats: bigint;
14
- senderAddress: string;
15
- recipientAddress: string;
16
- recipientScriptPubKeyHex: string;
17
- changeAddress: string;
18
- txid: string;
19
- wtxid: string | null;
20
- }
21
- export interface TransferBitcoinOptions {
22
- amountSatsText: string;
23
- target: string;
24
- dataDir: string;
25
- databasePath: string;
26
- provider?: WalletSecretProvider;
27
- prompter: WalletPrompter;
28
- assumeYes?: boolean;
29
- paths?: WalletRuntimePaths;
30
- openReadContext?: typeof openWalletReadContext;
31
- attachService?: typeof attachOrStartManagedBitcoindService;
32
- rpcFactory?: (config: Parameters<typeof createRpcClient>[0]) => WalletBitcoinTransferRpcClient;
33
- }
34
- export declare function transferBitcoin(options: TransferBitcoinOptions): Promise<BitcoinTransferResult>;
35
- export {};
1
+ export * from "./bitcoin-transfer/index.js";
@@ -1,200 +1 @@
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 { confirmYesNo } from "./confirm.js";
8
- import { assertWalletBitcoinTransferContextReady, buildWalletMutationTransaction, isAlreadyAcceptedError, isBroadcastUnknownError, isInsufficientFundsError, outpointKey, pauseMiningForWalletMutation, unlockTemporaryBuilderLocks, } from "./common.js";
9
- import { normalizeBtcTarget } from "./targets.js";
10
- function parsePositiveSats(value) {
11
- const trimmed = value.trim();
12
- if (!/^[1-9]\d*$/.test(trimmed)) {
13
- throw new Error("wallet_bitcoin_transfer_invalid_amount");
14
- }
15
- return BigInt(trimmed);
16
- }
17
- function satsToBtcNumber(value) {
18
- return Number(value) / 100_000_000;
19
- }
20
- function btcValueToSats(value) {
21
- const numeric = typeof value === "string" ? Number(value) : value;
22
- return BigInt(Math.round(numeric * 100_000_000));
23
- }
24
- function normalizeRecipientAddress(target) {
25
- const trimmed = target.trim();
26
- try {
27
- const normalized = normalizeBtcTarget(trimmed);
28
- if (trimmed.startsWith("spk:") || normalized.opaque || normalized.address === null) {
29
- throw new Error("wallet_bitcoin_transfer_address_required");
30
- }
31
- return {
32
- address: normalized.address,
33
- scriptPubKeyHex: normalized.scriptPubKeyHex,
34
- };
35
- }
36
- catch (error) {
37
- if (error instanceof Error && error.message === "wallet_bitcoin_transfer_address_required") {
38
- throw error;
39
- }
40
- if (trimmed.startsWith("spk:")) {
41
- throw new Error("wallet_bitcoin_transfer_address_required", { cause: error });
42
- }
43
- if (error instanceof Error
44
- && (error.message === "wallet_target_missing"
45
- || error.message === "wallet_target_invalid_address"
46
- || error.message === "wallet_target_invalid_script")) {
47
- throw new Error("wallet_bitcoin_transfer_invalid_address", { cause: error });
48
- }
49
- throw error;
50
- }
51
- }
52
- function isSpendableFundingUtxo(entry, fundingScriptPubKeyHex) {
53
- return entry.scriptPubKey === fundingScriptPubKeyHex
54
- && entry.confirmations >= 1
55
- && entry.spendable !== false
56
- && entry.safe !== false;
57
- }
58
- function buildPlanForBitcoinTransfer(options) {
59
- const fundingUtxos = options.allUtxos.filter((entry) => isSpendableFundingUtxo(entry, options.state.funding.scriptPubKeyHex));
60
- return {
61
- fixedInputs: [],
62
- outputs: [
63
- {
64
- [options.recipientAddress]: satsToBtcNumber(options.amountSats),
65
- },
66
- ],
67
- changeAddress: options.state.funding.address,
68
- changePosition: null,
69
- allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
70
- eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout }))),
71
- recipientScriptPubKeyHex: options.recipientScriptPubKeyHex,
72
- amountSats: options.amountSats,
73
- };
74
- }
75
- function validateFundedBitcoinTransfer(decoded, _funded, plan) {
76
- if (decoded.tx.vin.length === 0) {
77
- throw new Error("wallet_bitcoin_transfer_missing_sender_input");
78
- }
79
- const recipientOutputs = decoded.tx.vout.filter((output) => output.scriptPubKey?.hex === plan.recipientScriptPubKeyHex);
80
- if (recipientOutputs.length !== 1) {
81
- throw new Error("wallet_bitcoin_transfer_missing_recipient_output");
82
- }
83
- if (btcValueToSats(recipientOutputs[0].value) !== plan.amountSats) {
84
- throw new Error("wallet_bitcoin_transfer_recipient_amount_mismatch");
85
- }
86
- const hasUnexpectedOutput = decoded.tx.vout.some((output) => output.scriptPubKey?.hex !== plan.recipientScriptPubKeyHex
87
- && output.scriptPubKey?.hex !== plan.allowedFundingScriptPubKeyHex);
88
- if (hasUnexpectedOutput) {
89
- throw new Error("wallet_bitcoin_transfer_unexpected_output");
90
- }
91
- }
92
- async function confirmBitcoinTransfer(prompter, senderAddress, recipientAddress, amountSats, assumeYes = false) {
93
- prompter.writeLine(`You are sending ${amountSats.toString()} sats.`);
94
- prompter.writeLine(`Wallet address: ${senderAddress}`);
95
- prompter.writeLine(`Recipient: ${recipientAddress}`);
96
- await confirmYesNo(prompter, "This will publish a standard Bitcoin payment from the wallet address.", {
97
- assumeYes,
98
- errorCode: "wallet_bitcoin_transfer_confirmation_rejected",
99
- requiresTtyErrorCode: "wallet_bitcoin_transfer_requires_tty",
100
- });
101
- }
102
- export async function transferBitcoin(options) {
103
- const amountSats = parsePositiveSats(options.amountSatsText);
104
- const recipient = normalizeRecipientAddress(options.target);
105
- const provider = options.provider ?? createDefaultWalletSecretProvider();
106
- const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
107
- const controlLock = await acquireFileLock(paths.walletControlLockPath, {
108
- purpose: "wallet-bitcoin-transfer",
109
- walletRootId: null,
110
- });
111
- try {
112
- const miningPreemption = await pauseMiningForWalletMutation({
113
- paths,
114
- reason: "wallet-bitcoin-transfer",
115
- });
116
- const readContext = await (options.openReadContext ?? openWalletReadContext)({
117
- dataDir: options.dataDir,
118
- databasePath: options.databasePath,
119
- secretProvider: provider,
120
- walletControlLockHeld: true,
121
- paths,
122
- });
123
- try {
124
- assertWalletBitcoinTransferContextReady(readContext, "wallet_bitcoin_transfer");
125
- const state = readContext.localState.state;
126
- if (state.funding.scriptPubKeyHex === recipient.scriptPubKeyHex) {
127
- throw new Error("wallet_bitcoin_transfer_self_transfer");
128
- }
129
- await confirmBitcoinTransfer(options.prompter, state.funding.address, recipient.address, amountSats, options.assumeYes);
130
- const node = await (options.attachService ?? attachOrStartManagedBitcoindService)({
131
- dataDir: options.dataDir,
132
- chain: "main",
133
- startHeight: 0,
134
- walletRootId: state.walletRootId,
135
- });
136
- const rpc = (options.rpcFactory ?? createRpcClient)(node.rpc);
137
- const walletName = state.managedCoreWallet.walletName;
138
- const allUtxos = await rpc.listUnspent(walletName, 1);
139
- const plan = buildPlanForBitcoinTransfer({
140
- state,
141
- allUtxos,
142
- recipientAddress: recipient.address,
143
- recipientScriptPubKeyHex: recipient.scriptPubKeyHex,
144
- amountSats,
145
- });
146
- let built;
147
- try {
148
- built = await buildWalletMutationTransaction({
149
- rpc,
150
- walletName,
151
- state,
152
- plan,
153
- validateFundedDraft: validateFundedBitcoinTransfer,
154
- finalizeErrorCode: "wallet_bitcoin_transfer_finalize_failed",
155
- mempoolRejectPrefix: "wallet_bitcoin_transfer_mempool_reject",
156
- });
157
- }
158
- catch (error) {
159
- if (isInsufficientFundsError(error)) {
160
- throw new Error("wallet_bitcoin_transfer_insufficient_funds", { cause: error });
161
- }
162
- throw error;
163
- }
164
- try {
165
- await rpc.sendRawTransaction(built.rawHex);
166
- }
167
- catch (error) {
168
- if (!isAlreadyAcceptedError(error)) {
169
- if (isInsufficientFundsError(error)) {
170
- throw new Error("wallet_bitcoin_transfer_insufficient_funds", { cause: error });
171
- }
172
- if (isBroadcastUnknownError(error)) {
173
- throw new Error("wallet_bitcoin_transfer_broadcast_unknown", { cause: error });
174
- }
175
- throw error;
176
- }
177
- }
178
- finally {
179
- await unlockTemporaryBuilderLocks(rpc, walletName, built.temporaryBuilderLockedOutpoints);
180
- }
181
- return {
182
- amountSats,
183
- feeSats: btcValueToSats(built.funded.fee),
184
- senderAddress: state.funding.address,
185
- recipientAddress: recipient.address,
186
- recipientScriptPubKeyHex: recipient.scriptPubKeyHex,
187
- changeAddress: state.funding.address,
188
- txid: built.txid,
189
- wtxid: built.wtxid,
190
- };
191
- }
192
- finally {
193
- await readContext.close();
194
- await miningPreemption.release();
195
- }
196
- }
197
- finally {
198
- await controlLock.release();
199
- }
200
- }
1
+ export * from "./bitcoin-transfer/index.js";
@@ -0,0 +1,13 @@
1
+ import type { WalletPrompter } from "../../lifecycle.js";
2
+ import type { CogResolvedSummary } from "./types.js";
3
+ import { normalizeBtcTarget } from "../targets.js";
4
+ export declare function confirmSend(prompter: WalletPrompter, resolved: CogResolvedSummary, target: string, normalizedRecipient: ReturnType<typeof normalizeBtcTarget>, amountCogtoshi: bigint, assumeYes?: boolean): Promise<void>;
5
+ export declare function confirmLock(prompter: WalletPrompter, resolved: CogResolvedSummary, amountCogtoshi: bigint, recipientDomainName: string, timeoutHeight: number, assumeYes?: boolean): Promise<void>;
6
+ export declare function confirmClaim(prompter: WalletPrompter, options: {
7
+ kind: "claim" | "reclaim";
8
+ lockId: number;
9
+ recipientDomainName: string | null;
10
+ amountCogtoshi: bigint;
11
+ resolved: CogResolvedSummary;
12
+ assumeYes?: boolean;
13
+ }): Promise<void>;
@@ -0,0 +1,59 @@
1
+ import { formatCogAmount } from "../common.js";
2
+ import { confirmTypedAcknowledgement, confirmYesNo, } from "../confirm.js";
3
+ import { normalizeBtcTarget } from "../targets.js";
4
+ export async function confirmSend(prompter, resolved, target, normalizedRecipient, amountCogtoshi, assumeYes = false) {
5
+ prompter.writeLine(`You are sending ${formatCogAmount(amountCogtoshi)}.`);
6
+ prompter.writeLine(`Resolved sender: ${resolved.sender.selector} (${resolved.sender.address})`);
7
+ prompter.writeLine(`Recipient: ${normalizedRecipient.address ?? `spk:${normalizedRecipient.scriptPubKeyHex}`}`);
8
+ if (normalizedRecipient.opaque) {
9
+ await confirmTypedAcknowledgement(prompter, {
10
+ assumeYes,
11
+ expected: target.trim(),
12
+ prompt: "Type the exact target to continue: ",
13
+ errorCode: "wallet_send_confirmation_rejected",
14
+ requiresTtyErrorCode: "wallet_send_requires_tty",
15
+ typedAckRequiredErrorCode: "wallet_send_typed_ack_required",
16
+ });
17
+ return;
18
+ }
19
+ await confirmYesNo(prompter, "This will publish an on-chain COG transfer.", {
20
+ assumeYes,
21
+ errorCode: "wallet_send_confirmation_rejected",
22
+ requiresTtyErrorCode: "wallet_send_requires_tty",
23
+ });
24
+ }
25
+ export async function confirmLock(prompter, resolved, amountCogtoshi, recipientDomainName, timeoutHeight, assumeYes = false) {
26
+ prompter.writeLine(`You are locking ${formatCogAmount(amountCogtoshi)}.`);
27
+ prompter.writeLine(`Resolved sender: ${resolved.sender.selector} (${resolved.sender.address})`);
28
+ prompter.writeLine(`Recipient domain: ${recipientDomainName}`);
29
+ prompter.writeLine(`Resolved timeout height: ${timeoutHeight}`);
30
+ await confirmYesNo(prompter, "This creates an escrowed COG lock and the funds cannot be spent until claimed or reclaimed.", {
31
+ assumeYes,
32
+ errorCode: "wallet_mutation_confirmation_rejected",
33
+ requiresTtyErrorCode: "wallet_lock_requires_tty",
34
+ });
35
+ }
36
+ export async function confirmClaim(prompter, options) {
37
+ prompter.writeLine(`${options.kind === "claim" ? "Claiming" : "Reclaiming"} lock:${options.lockId} for ${formatCogAmount(options.amountCogtoshi)}.`);
38
+ prompter.writeLine(`Resolved sender: ${options.resolved.sender.selector} (${options.resolved.sender.address})`);
39
+ if (options.resolved.claimPath !== null) {
40
+ prompter.writeLine(`Resolved path: ${options.resolved.claimPath}.`);
41
+ }
42
+ if (options.recipientDomainName !== null) {
43
+ prompter.writeLine(`Recipient domain: ${options.recipientDomainName}`);
44
+ }
45
+ if (options.kind === "claim") {
46
+ prompter.writeLine("Warning: the claim preimage becomes public in the mempool and on-chain.");
47
+ }
48
+ await confirmYesNo(prompter, options.kind === "claim"
49
+ ? "This spends the lock via the recipient claim path."
50
+ : "This spends the lock via the timeout reclaim path.", {
51
+ assumeYes: options.assumeYes,
52
+ errorCode: options.kind === "claim"
53
+ ? "wallet_claim_confirmation_rejected"
54
+ : "wallet_reclaim_confirmation_rejected",
55
+ requiresTtyErrorCode: options.kind === "claim"
56
+ ? "wallet_claim_requires_tty"
57
+ : "wallet_reclaim_requires_tty",
58
+ });
59
+ }
@@ -0,0 +1,20 @@
1
+ import type { WalletRuntimePaths } from "../../runtime.js";
2
+ import type { WalletSecretProvider } from "../../state/provider.js";
3
+ import type { PendingMutationRecord, WalletStateV1 } from "../../types.js";
4
+ import type { WalletReadContext } from "../../read/index.js";
5
+ import type { CogDraftMutationOptions, WalletCogRpcClient } from "./types.js";
6
+ export declare function createCogDraftMutation(options: CogDraftMutationOptions): PendingMutationRecord;
7
+ export declare function reconcilePendingCogMutation(options: {
8
+ state: WalletStateV1;
9
+ mutation: PendingMutationRecord;
10
+ provider: WalletSecretProvider;
11
+ nowUnixMs: number;
12
+ paths: WalletRuntimePaths;
13
+ rpc: WalletCogRpcClient;
14
+ walletName: string;
15
+ context: WalletReadContext;
16
+ }): Promise<{
17
+ state: WalletStateV1;
18
+ mutation: PendingMutationRecord;
19
+ resolution: "confirmed" | "live" | "repair-required" | "continue";
20
+ }>;
@@ -0,0 +1,114 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { getLock } from "@cogcoin/indexer/queries";
3
+ import { createWalletMutationFeeMetadata, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "../common.js";
4
+ import { upsertPendingMutation } from "../journal.js";
5
+ import { ZERO_PREIMAGE_HEX } from "./types.js";
6
+ export function createCogDraftMutation(options) {
7
+ if (options.existing !== null && options.existing !== undefined) {
8
+ return {
9
+ ...options.existing,
10
+ kind: options.kind,
11
+ domainName: options.domainName ?? "",
12
+ senderScriptPubKeyHex: options.sender.scriptPubKeyHex,
13
+ senderLocalIndex: options.sender.localIndex,
14
+ recipientScriptPubKeyHex: options.recipientScriptPubKeyHex ?? null,
15
+ recipientDomainName: options.recipientDomainName ?? null,
16
+ amountCogtoshi: options.amountCogtoshi ?? null,
17
+ timeoutHeight: options.timeoutHeight ?? null,
18
+ conditionHex: options.conditionHex ?? null,
19
+ lockId: options.lockId ?? null,
20
+ preimageHex: options.preimageHex ?? null,
21
+ status: "draft",
22
+ lastUpdatedAtUnixMs: options.nowUnixMs,
23
+ attemptedTxid: null,
24
+ attemptedWtxid: null,
25
+ ...createWalletMutationFeeMetadata(options.feeSelection),
26
+ temporaryBuilderLockedOutpoints: [],
27
+ };
28
+ }
29
+ return {
30
+ mutationId: randomBytes(12).toString("hex"),
31
+ kind: options.kind,
32
+ domainName: options.domainName ?? "",
33
+ parentDomainName: null,
34
+ senderScriptPubKeyHex: options.sender.scriptPubKeyHex,
35
+ senderLocalIndex: options.sender.localIndex,
36
+ recipientScriptPubKeyHex: options.recipientScriptPubKeyHex ?? null,
37
+ recipientDomainName: options.recipientDomainName ?? null,
38
+ amountCogtoshi: options.amountCogtoshi ?? null,
39
+ timeoutHeight: options.timeoutHeight ?? null,
40
+ conditionHex: options.conditionHex ?? null,
41
+ lockId: options.lockId ?? null,
42
+ preimageHex: options.preimageHex ?? null,
43
+ intentFingerprintHex: options.intentFingerprintHex,
44
+ status: "draft",
45
+ createdAtUnixMs: options.nowUnixMs,
46
+ lastUpdatedAtUnixMs: options.nowUnixMs,
47
+ attemptedTxid: null,
48
+ attemptedWtxid: null,
49
+ ...createWalletMutationFeeMetadata(options.feeSelection),
50
+ temporaryBuilderLockedOutpoints: [],
51
+ };
52
+ }
53
+ export async function reconcilePendingCogMutation(options) {
54
+ if (options.mutation.status === "confirmed" || options.mutation.status === "live") {
55
+ return {
56
+ state: options.state,
57
+ mutation: options.mutation,
58
+ resolution: options.mutation.status,
59
+ };
60
+ }
61
+ if (options.mutation.status === "repair-required") {
62
+ return {
63
+ state: options.state,
64
+ mutation: options.mutation,
65
+ resolution: "repair-required",
66
+ };
67
+ }
68
+ if (options.mutation.kind === "claim" && options.context.snapshot !== null && options.mutation.lockId != null) {
69
+ const lock = getLock(options.context.snapshot.state, options.mutation.lockId);
70
+ const expectedStatus = options.mutation.preimageHex === ZERO_PREIMAGE_HEX ? "reclaimed" : "claimed";
71
+ if (lock !== null
72
+ && lock.status === expectedStatus
73
+ && Buffer.from(lock.resolverScriptPubKey ?? new Uint8Array()).toString("hex") === options.mutation.senderScriptPubKeyHex) {
74
+ await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
75
+ const confirmed = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
76
+ temporaryBuilderLockedOutpoints: [],
77
+ });
78
+ const nextState = {
79
+ ...upsertPendingMutation(options.state, confirmed),
80
+ stateRevision: options.state.stateRevision + 1,
81
+ lastWrittenAtUnixMs: options.nowUnixMs,
82
+ };
83
+ await saveWalletStatePreservingUnlock({
84
+ state: nextState,
85
+ provider: options.provider,
86
+ nowUnixMs: options.nowUnixMs,
87
+ paths: options.paths,
88
+ });
89
+ return { state: nextState, mutation: confirmed, resolution: "confirmed" };
90
+ }
91
+ }
92
+ const known = options.mutation.attemptedTxid === null
93
+ ? false
94
+ : await options.rpc.getRawTransaction(options.mutation.attemptedTxid, true).then(() => true).catch(() => false);
95
+ if (known) {
96
+ await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
97
+ const live = updateMutationRecord(options.mutation, "live", options.nowUnixMs, {
98
+ temporaryBuilderLockedOutpoints: [],
99
+ });
100
+ const nextState = {
101
+ ...upsertPendingMutation(options.state, live),
102
+ stateRevision: options.state.stateRevision + 1,
103
+ lastWrittenAtUnixMs: options.nowUnixMs,
104
+ };
105
+ await saveWalletStatePreservingUnlock({
106
+ state: nextState,
107
+ provider: options.provider,
108
+ nowUnixMs: options.nowUnixMs,
109
+ paths: options.paths,
110
+ });
111
+ return { state: nextState, mutation: live, resolution: "live" };
112
+ }
113
+ return { state: options.state, mutation: options.mutation, resolution: "continue" };
114
+ }
@@ -0,0 +1,6 @@
1
+ import type { ClaimCogLockOptions, CogMutationResult, LockCogToDomainOptions, ReclaimCogLockOptions, SendCogOptions } from "./types.js";
2
+ export type { ClaimCogLockOptions, CogMutationResult, CogResolvedClaimPath, CogResolvedSenderSummary, CogResolvedSummary, LockCogToDomainOptions, ReclaimCogLockOptions, SendCogOptions, } from "./types.js";
3
+ export declare function sendCog(options: SendCogOptions): Promise<CogMutationResult>;
4
+ export declare function lockCogToDomain(options: LockCogToDomainOptions): Promise<CogMutationResult>;
5
+ export declare function claimCogLock(options: ClaimCogLockOptions): Promise<CogMutationResult>;
6
+ export declare function reclaimCogLock(options: ReclaimCogLockOptions): Promise<CogMutationResult>;