@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
@@ -1,1078 +1 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
- import { getBalance, getListing, lookupDomain } from "@cogcoin/indexer/queries";
3
- import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
4
- import { createRpcClient } from "../../bitcoind/node.js";
5
- import {} from "../runtime.js";
6
- import { reconcilePersistentPolicyLocks as reconcileWalletCoinControlLocks } from "../coin-control.js";
7
- import {} from "../state/provider.js";
8
- import { serializeDomainBuy, serializeDomainSell, serializeDomainTransfer, validateDomainName, } from "../cogop/index.js";
9
- import { openWalletReadContext } from "../read/index.js";
10
- import { assertFixedInputPrefixMatches, assertFundingInputsAfterFixedPrefix, assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback, createFundingMutationSender, createWalletMutationFeeMetadata, getDecodedInputScriptPubKeyHex, isLocalWalletScript, mergeFixedWalletInputs, outpointKey, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "./common.js";
11
- import { confirmTypedAcknowledgement, confirmYesNo } from "./confirm.js";
12
- import { executeWalletMutationOperation, publishWalletMutation, resolveExistingWalletMutation, } from "./executor.js";
13
- import { getCanonicalIdentitySelector, resolveIdentityBySelector, } from "./identity-selector.js";
14
- import { upsertPendingMutation } from "./journal.js";
15
- import { normalizeBtcTarget } from "./targets.js";
16
- async function prepareDomainMarketBuildState(options) {
17
- if (!options.preflightCoinControl) {
18
- return {
19
- state: options.state,
20
- allUtxos: (await options.rpc.listUnspent(options.walletName, 1)).slice(),
21
- };
22
- }
23
- const reconciled = await reconcileWalletCoinControlLocks({
24
- rpc: options.rpc,
25
- walletName: options.walletName,
26
- state: options.state,
27
- });
28
- const nextState = reconciled.changed
29
- ? {
30
- ...reconciled.state,
31
- stateRevision: reconciled.state.stateRevision + 1,
32
- lastWrittenAtUnixMs: options.nowUnixMs,
33
- }
34
- : reconciled.state;
35
- if (reconciled.changed) {
36
- await saveWalletStatePreservingUnlock({
37
- state: nextState,
38
- provider: options.provider,
39
- nowUnixMs: options.nowUnixMs,
40
- paths: options.paths,
41
- });
42
- }
43
- return {
44
- state: nextState,
45
- allUtxos: (await options.rpc.listUnspent(options.walletName, 1)).slice(),
46
- };
47
- }
48
- function normalizeDomainName(domainName) {
49
- const normalized = domainName.trim().toLowerCase();
50
- if (normalized.length === 0) {
51
- throw new Error("wallet_domain_missing_domain");
52
- }
53
- validateDomainName(normalized);
54
- return normalized;
55
- }
56
- export function parseCogAmountToCogtoshi(raw) {
57
- const match = /^(-?)(\d+)(?:\.(\d{0,8}))?$/.exec(raw.trim());
58
- if (match == null) {
59
- throw new Error(`wallet_sell_invalid_amount_${raw}`);
60
- }
61
- const sign = match[1] === "-" ? -1n : 1n;
62
- const whole = BigInt(match[2] ?? "0");
63
- const fraction = BigInt((match[3] ?? "").padEnd(8, "0"));
64
- return sign * ((whole * 100000000n) + fraction);
65
- }
66
- function satsToBtcNumber(value) {
67
- return Number(value) / 100_000_000;
68
- }
69
- function valueToSats(value) {
70
- const text = typeof value === "number" ? value.toFixed(8) : value;
71
- const match = /^(-?)(\d+)(?:\.(\d{0,8}))?$/.exec(text.trim());
72
- if (match == null) {
73
- throw new Error(`wallet_domain_invalid_amount_${text}`);
74
- }
75
- const sign = match[1] === "-" ? -1n : 1n;
76
- const whole = BigInt(match[2] ?? "0");
77
- const fraction = BigInt((match[3] ?? "").padEnd(8, "0"));
78
- return sign * ((whole * 100000000n) + fraction);
79
- }
80
- function encodeOpReturnScript(payload) {
81
- if (payload.length <= 75) {
82
- return Buffer.concat([
83
- Buffer.from([0x6a, payload.length]),
84
- Buffer.from(payload),
85
- ]).toString("hex");
86
- }
87
- return Buffer.concat([
88
- Buffer.from([0x6a, 0x4c, payload.length]),
89
- Buffer.from(payload),
90
- ]).toString("hex");
91
- }
92
- function createIntentFingerprint(parts) {
93
- return createHash("sha256")
94
- .update(parts.join("\n"))
95
- .digest("hex");
96
- }
97
- function reserveTransferredDomainRecord(options) {
98
- const existing = options.state.domains.find((domain) => domain.name === options.domainName) ?? null;
99
- const domains = options.state.domains.some((domain) => domain.name === options.domainName)
100
- ? options.state.domains.map((domain) => {
101
- if (domain.name !== options.domainName) {
102
- return domain;
103
- }
104
- return {
105
- ...domain,
106
- domainId: options.domainId ?? domain.domainId,
107
- currentOwnerScriptPubKeyHex: options.currentOwnerScriptPubKeyHex,
108
- canonicalChainStatus: "registered-unanchored",
109
- birthTime: domain.birthTime ?? Math.floor(options.nowUnixMs / 1000),
110
- };
111
- })
112
- : [
113
- ...options.state.domains,
114
- {
115
- name: options.domainName,
116
- domainId: options.domainId,
117
- currentOwnerScriptPubKeyHex: options.currentOwnerScriptPubKeyHex,
118
- canonicalChainStatus: "registered-unanchored",
119
- foundingMessageText: existing?.foundingMessageText ?? null,
120
- birthTime: Math.floor(options.nowUnixMs / 1000),
121
- },
122
- ];
123
- return {
124
- ...options.state,
125
- domains,
126
- };
127
- }
128
- function createResolvedDomainMarketSenderSummary(sender, selector) {
129
- return {
130
- selector,
131
- localIndex: sender.localIndex,
132
- scriptPubKeyHex: sender.scriptPubKeyHex,
133
- address: sender.address,
134
- };
135
- }
136
- function createResolvedDomainMarketRecipientSummary(recipient) {
137
- return {
138
- scriptPubKeyHex: recipient.scriptPubKeyHex,
139
- address: recipient.address,
140
- opaque: recipient.opaque,
141
- };
142
- }
143
- function createTransferEconomicEffectSummary(clearsListing) {
144
- return {
145
- kind: "ownership-transfer",
146
- clearsListing,
147
- };
148
- }
149
- function createSellEconomicEffectSummary(listedPriceCogtoshi) {
150
- if (listedPriceCogtoshi === 0n) {
151
- return {
152
- kind: "listing-clear",
153
- listedPriceCogtoshi: "0",
154
- };
155
- }
156
- return {
157
- kind: "listing-set",
158
- listedPriceCogtoshi: listedPriceCogtoshi.toString(),
159
- };
160
- }
161
- function resolveOwnedDomainOperation(context, domainName, errorPrefix) {
162
- assertWalletMutationContextReady(context, errorPrefix);
163
- const chainDomain = lookupDomain(context.snapshot.state, domainName);
164
- if (chainDomain === null) {
165
- throw new Error(`${errorPrefix}_domain_not_found`);
166
- }
167
- if (chainDomain.anchored) {
168
- throw new Error(`${errorPrefix}_domain_anchored`);
169
- }
170
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
171
- if (ownerHex !== context.localState.state.funding.scriptPubKeyHex || context.model.walletAddress == null) {
172
- throw new Error(`${errorPrefix}_owner_not_locally_controlled`);
173
- }
174
- return {
175
- readContext: context,
176
- state: context.localState.state,
177
- sender: createFundingMutationSender(context.localState.state),
178
- senderSelector: context.model.walletAddress,
179
- chainDomain,
180
- };
181
- }
182
- function resolveBuyOperation(context, domainName, fromIdentity = null) {
183
- assertWalletMutationContextReady(context, "wallet_buy");
184
- const chainDomain = lookupDomain(context.snapshot.state, domainName);
185
- if (chainDomain === null) {
186
- throw new Error("wallet_buy_domain_not_found");
187
- }
188
- if (chainDomain.anchored) {
189
- throw new Error("wallet_buy_domain_anchored");
190
- }
191
- const listing = getListing(context.snapshot.state, chainDomain.domainId);
192
- if (listing === null) {
193
- throw new Error("wallet_buy_domain_not_listed");
194
- }
195
- if (context.model.walletAddress === null) {
196
- throw new Error("wallet_buy_funding_identity_unavailable");
197
- }
198
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
199
- if (ownerHex === context.localState.state.funding.scriptPubKeyHex) {
200
- throw new Error("wallet_buy_already_owner");
201
- }
202
- if (getBalance(context.snapshot.state, context.localState.state.funding.scriptPubKeyHex) < listing.priceCogtoshi) {
203
- throw new Error("wallet_buy_insufficient_cog_balance");
204
- }
205
- return {
206
- readContext: context,
207
- state: context.localState.state,
208
- sender: createFundingMutationSender(context.localState.state),
209
- senderSelector: context.model.walletAddress,
210
- chainDomain,
211
- listingPriceCogtoshi: listing.priceCogtoshi,
212
- buyerSelector: context.model.walletAddress,
213
- };
214
- }
215
- function buildPlanForDomainOperation(options) {
216
- const fundingUtxos = options.allUtxos.filter((entry) => entry.scriptPubKey === options.state.funding.scriptPubKeyHex
217
- && entry.confirmations >= 1
218
- && entry.spendable !== false
219
- && entry.safe !== false);
220
- return {
221
- sender: options.sender,
222
- changeAddress: options.state.funding.address,
223
- fixedInputs: [],
224
- outputs: [{ data: Buffer.from(options.opReturnData).toString("hex") }],
225
- changePosition: 1,
226
- expectedOpReturnScriptHex: encodeOpReturnScript(options.opReturnData),
227
- allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
228
- eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout }))),
229
- errorPrefix: options.errorPrefix,
230
- };
231
- }
232
- function validateFundedDraft(decoded, funded, plan) {
233
- const inputs = decoded.tx.vin;
234
- const outputs = decoded.tx.vout;
235
- if (inputs.length === 0) {
236
- throw new Error(`${plan.errorPrefix}_missing_sender_input`);
237
- }
238
- if (outputs[0]?.scriptPubKey?.hex !== plan.expectedOpReturnScriptHex) {
239
- throw new Error(`${plan.errorPrefix}_opreturn_mismatch`);
240
- }
241
- const expectedWithoutChange = 1;
242
- if (funded.changepos === -1) {
243
- if (outputs.length !== expectedWithoutChange) {
244
- throw new Error(`${plan.errorPrefix}_unexpected_output_count`);
245
- }
246
- return;
247
- }
248
- if (funded.changepos !== plan.changePosition || outputs.length !== expectedWithoutChange + 1) {
249
- throw new Error(`${plan.errorPrefix}_change_position_mismatch`);
250
- }
251
- if (outputs[funded.changepos]?.scriptPubKey?.hex !== plan.allowedFundingScriptPubKeyHex) {
252
- throw new Error(`${plan.errorPrefix}_change_output_mismatch`);
253
- }
254
- }
255
- async function buildTransaction(options) {
256
- return buildWalletMutationTransactionWithReserveFallback({
257
- rpc: options.rpc,
258
- walletName: options.walletName,
259
- state: options.state,
260
- plan: options.plan,
261
- validateFundedDraft,
262
- finalizeErrorCode: `${options.plan.errorPrefix}_finalize_failed`,
263
- mempoolRejectPrefix: `${options.plan.errorPrefix}_mempool_rejected`,
264
- feeRate: options.feeRateSatVb,
265
- });
266
- }
267
- function createDraftMutation(options) {
268
- if (options.existing !== null && options.existing !== undefined) {
269
- return {
270
- ...options.existing,
271
- kind: options.kind,
272
- parentDomainName: options.parentDomainName ?? null,
273
- senderScriptPubKeyHex: options.sender.scriptPubKeyHex,
274
- senderLocalIndex: options.sender.localIndex,
275
- recipientScriptPubKeyHex: options.recipientScriptPubKeyHex ?? null,
276
- priceCogtoshi: options.priceCogtoshi ?? null,
277
- status: "draft",
278
- lastUpdatedAtUnixMs: options.nowUnixMs,
279
- attemptedTxid: null,
280
- attemptedWtxid: null,
281
- ...createWalletMutationFeeMetadata(options.feeSelection),
282
- temporaryBuilderLockedOutpoints: [],
283
- };
284
- }
285
- return {
286
- mutationId: randomBytes(12).toString("hex"),
287
- kind: options.kind,
288
- domainName: options.domainName,
289
- parentDomainName: options.parentDomainName ?? null,
290
- senderScriptPubKeyHex: options.sender.scriptPubKeyHex,
291
- senderLocalIndex: options.sender.localIndex,
292
- recipientScriptPubKeyHex: options.recipientScriptPubKeyHex ?? null,
293
- priceCogtoshi: options.priceCogtoshi ?? null,
294
- intentFingerprintHex: options.intentFingerprintHex,
295
- status: "draft",
296
- createdAtUnixMs: options.nowUnixMs,
297
- lastUpdatedAtUnixMs: options.nowUnixMs,
298
- attemptedTxid: null,
299
- attemptedWtxid: null,
300
- ...createWalletMutationFeeMetadata(options.feeSelection),
301
- temporaryBuilderLockedOutpoints: [],
302
- };
303
- }
304
- function getTransferStatusAfterAcceptance(options) {
305
- const chainDomain = options.snapshot === null ? null : lookupDomain(options.snapshot.state, options.domainName);
306
- if (chainDomain === null) {
307
- return "live";
308
- }
309
- return Buffer.from(chainDomain.ownerScriptPubKey).toString("hex") === options.recipientScriptPubKeyHex
310
- ? "confirmed"
311
- : "live";
312
- }
313
- function getSellStatusAfterAcceptance(options) {
314
- const chainDomain = options.snapshot === null ? null : lookupDomain(options.snapshot.state, options.domainName);
315
- if (chainDomain === null) {
316
- return "live";
317
- }
318
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
319
- const listing = getListing(options.snapshot.state, chainDomain.domainId);
320
- if (options.listedPriceCogtoshi === 0n) {
321
- return ownerHex === options.senderScriptPubKeyHex && listing === null ? "confirmed" : "live";
322
- }
323
- return ownerHex === options.senderScriptPubKeyHex && listing?.priceCogtoshi === options.listedPriceCogtoshi
324
- ? "confirmed"
325
- : "live";
326
- }
327
- function getBuyStatusAfterAcceptance(options) {
328
- const chainDomain = options.snapshot === null ? null : lookupDomain(options.snapshot.state, options.domainName);
329
- if (chainDomain === null) {
330
- return "live";
331
- }
332
- return Buffer.from(chainDomain.ownerScriptPubKey).toString("hex") === options.buyerScriptPubKeyHex
333
- ? "confirmed"
334
- : "live";
335
- }
336
- async function reconcilePendingMutation(options) {
337
- if (options.mutation.status === "repair-required") {
338
- return {
339
- state: options.state,
340
- mutation: options.mutation,
341
- resolution: "repair-required",
342
- };
343
- }
344
- const chainDomain = options.context.snapshot === null
345
- ? null
346
- : lookupDomain(options.context.snapshot.state, options.mutation.domainName);
347
- if (chainDomain !== null) {
348
- const ownerHex = Buffer.from(chainDomain.ownerScriptPubKey).toString("hex");
349
- const listing = getListing(options.context.snapshot.state, chainDomain.domainId);
350
- if (options.mutation.kind === "transfer") {
351
- if (ownerHex === options.mutation.recipientScriptPubKeyHex) {
352
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
353
- const confirmed = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
354
- temporaryBuilderLockedOutpoints: [],
355
- });
356
- const nextState = reserveTransferredDomainRecord({
357
- state: upsertPendingMutation(options.state, confirmed),
358
- domainName: options.mutation.domainName,
359
- domainId: chainDomain.domainId,
360
- currentOwnerScriptPubKeyHex: ownerHex,
361
- nowUnixMs: options.nowUnixMs,
362
- });
363
- await saveWalletStatePreservingUnlock({
364
- state: nextState,
365
- provider: options.provider,
366
- nowUnixMs: options.nowUnixMs,
367
- paths: options.paths,
368
- });
369
- return { state: nextState, mutation: confirmed, resolution: "confirmed" };
370
- }
371
- if (ownerHex !== options.mutation.senderScriptPubKeyHex) {
372
- const repair = updateMutationRecord(options.mutation, "repair-required", options.nowUnixMs, {
373
- temporaryBuilderLockedOutpoints: [],
374
- });
375
- const nextState = upsertPendingMutation(options.state, repair);
376
- await saveWalletStatePreservingUnlock({
377
- state: nextState,
378
- provider: options.provider,
379
- nowUnixMs: options.nowUnixMs,
380
- paths: options.paths,
381
- });
382
- return { state: nextState, mutation: repair, resolution: "repair-required" };
383
- }
384
- }
385
- if (options.mutation.kind === "sell") {
386
- const targetPrice = options.mutation.priceCogtoshi ?? 0n;
387
- if (ownerHex === options.mutation.senderScriptPubKeyHex) {
388
- if (targetPrice === 0n && listing === null) {
389
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
390
- const confirmed = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
391
- temporaryBuilderLockedOutpoints: [],
392
- });
393
- const nextState = upsertPendingMutation(options.state, confirmed);
394
- await saveWalletStatePreservingUnlock({
395
- state: nextState,
396
- provider: options.provider,
397
- nowUnixMs: options.nowUnixMs,
398
- paths: options.paths,
399
- });
400
- return { state: nextState, mutation: confirmed, resolution: "confirmed" };
401
- }
402
- if (targetPrice > 0n && listing?.priceCogtoshi === targetPrice) {
403
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
404
- const confirmed = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
405
- temporaryBuilderLockedOutpoints: [],
406
- });
407
- const nextState = upsertPendingMutation(options.state, confirmed);
408
- await saveWalletStatePreservingUnlock({
409
- state: nextState,
410
- provider: options.provider,
411
- nowUnixMs: options.nowUnixMs,
412
- paths: options.paths,
413
- });
414
- return { state: nextState, mutation: confirmed, resolution: "confirmed" };
415
- }
416
- }
417
- else {
418
- const repair = updateMutationRecord(options.mutation, "repair-required", options.nowUnixMs, {
419
- temporaryBuilderLockedOutpoints: [],
420
- });
421
- const nextState = upsertPendingMutation(options.state, repair);
422
- await saveWalletStatePreservingUnlock({
423
- state: nextState,
424
- provider: options.provider,
425
- nowUnixMs: options.nowUnixMs,
426
- paths: options.paths,
427
- });
428
- return { state: nextState, mutation: repair, resolution: "repair-required" };
429
- }
430
- }
431
- if (options.mutation.kind === "buy") {
432
- if (ownerHex === options.mutation.senderScriptPubKeyHex) {
433
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
434
- const confirmed = updateMutationRecord(options.mutation, "confirmed", options.nowUnixMs, {
435
- temporaryBuilderLockedOutpoints: [],
436
- });
437
- const nextState = reserveTransferredDomainRecord({
438
- state: upsertPendingMutation(options.state, confirmed),
439
- domainName: options.mutation.domainName,
440
- domainId: chainDomain.domainId,
441
- currentOwnerScriptPubKeyHex: ownerHex,
442
- nowUnixMs: options.nowUnixMs,
443
- });
444
- await saveWalletStatePreservingUnlock({
445
- state: nextState,
446
- provider: options.provider,
447
- nowUnixMs: options.nowUnixMs,
448
- paths: options.paths,
449
- });
450
- return { state: nextState, mutation: confirmed, resolution: "confirmed" };
451
- }
452
- if (listing === null) {
453
- const repair = updateMutationRecord(options.mutation, "repair-required", options.nowUnixMs, {
454
- temporaryBuilderLockedOutpoints: [],
455
- });
456
- const nextState = upsertPendingMutation(options.state, repair);
457
- await saveWalletStatePreservingUnlock({
458
- state: nextState,
459
- provider: options.provider,
460
- nowUnixMs: options.nowUnixMs,
461
- paths: options.paths,
462
- });
463
- return { state: nextState, mutation: repair, resolution: "repair-required" };
464
- }
465
- }
466
- }
467
- if (options.mutation.attemptedTxid !== null) {
468
- const mempool = await options.rpc.getRawMempool().catch(() => []);
469
- if (mempool.includes(options.mutation.attemptedTxid)) {
470
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
471
- const live = updateMutationRecord(options.mutation, "live", options.nowUnixMs, {
472
- temporaryBuilderLockedOutpoints: [],
473
- });
474
- let nextState = upsertPendingMutation(options.state, live);
475
- if (live.kind === "transfer" || live.kind === "buy") {
476
- nextState = reserveTransferredDomainRecord({
477
- state: nextState,
478
- domainName: live.domainName,
479
- domainId: chainDomain?.domainId ?? null,
480
- currentOwnerScriptPubKeyHex: live.kind === "transfer"
481
- ? (live.recipientScriptPubKeyHex ?? live.senderScriptPubKeyHex)
482
- : live.senderScriptPubKeyHex,
483
- nowUnixMs: options.nowUnixMs,
484
- });
485
- }
486
- await saveWalletStatePreservingUnlock({
487
- state: nextState,
488
- provider: options.provider,
489
- nowUnixMs: options.nowUnixMs,
490
- paths: options.paths,
491
- });
492
- return { state: nextState, mutation: live, resolution: "live" };
493
- }
494
- }
495
- if (options.mutation.status === "broadcast-unknown"
496
- || options.mutation.status === "live"
497
- || options.mutation.status === "draft"
498
- || options.mutation.status === "broadcasting") {
499
- await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.mutation.temporaryBuilderLockedOutpoints);
500
- const canceled = updateMutationRecord(options.mutation, "canceled", options.nowUnixMs, {
501
- temporaryBuilderLockedOutpoints: [],
502
- });
503
- const nextState = upsertPendingMutation(options.state, canceled);
504
- await saveWalletStatePreservingUnlock({
505
- state: nextState,
506
- provider: options.provider,
507
- nowUnixMs: options.nowUnixMs,
508
- paths: options.paths,
509
- });
510
- return { state: nextState, mutation: canceled, resolution: "not-seen" };
511
- }
512
- return {
513
- state: options.state,
514
- mutation: options.mutation,
515
- resolution: "continue",
516
- };
517
- }
518
- async function confirmTransfer(prompter, domainName, sender, recipient, economicEffect, assumeYes = false) {
519
- prompter.writeLine(`You are transferring "${domainName}".`);
520
- prompter.writeLine(`Resolved sender: ${sender.selector} (${sender.address})`);
521
- prompter.writeLine(`Resolved recipient: ${recipient.address ?? `spk:${recipient.scriptPubKeyHex}`}`);
522
- prompter.writeLine(`Economic effect: ${economicEffect.kind === "ownership-transfer" && economicEffect.clearsListing
523
- ? "transfer domain ownership and clear any active listing."
524
- : "transfer domain ownership."}`);
525
- if (recipient.opaque) {
526
- prompter.writeLine(`Target script length: ${recipient.scriptPubKeyHex.length / 2} bytes`);
527
- prompter.writeLine("Cogcoin identity is exact raw-script equality. Different script templates are different identities.");
528
- const acknowledgement = `RAW-SCRIPT:${recipient.scriptPubKeyHex.slice(0, 16)}`;
529
- await confirmTypedAcknowledgement(prompter, {
530
- assumeYes,
531
- expected: acknowledgement,
532
- prompt: `Type ${acknowledgement} to continue: `,
533
- errorCode: "wallet_transfer_confirmation_rejected",
534
- requiresTtyErrorCode: "wallet_transfer_requires_tty",
535
- typedAckRequiredErrorCode: "wallet_transfer_typed_ack_required",
536
- });
537
- return;
538
- }
539
- await confirmYesNo(prompter, "This publishes a standalone DOMAIN_TRANSFER.", {
540
- assumeYes,
541
- errorCode: "wallet_transfer_confirmation_rejected",
542
- requiresTtyErrorCode: "wallet_transfer_requires_tty",
543
- });
544
- }
545
- async function confirmSell(prompter, domainName, sender, listedPriceCogtoshi, assumeYes = false) {
546
- prompter.writeLine(`You are listing "${domainName}".`);
547
- prompter.writeLine(`Resolved sender: ${sender.selector} (${sender.address})`);
548
- prompter.writeLine(`Exact listing price: ${listedPriceCogtoshi.toString()} cogtoshi.`);
549
- prompter.writeLine(`Economic effect: set the listing price to ${listedPriceCogtoshi.toString()} cogtoshi in COG state.`);
550
- prompter.writeLine("Settlement: entirely in COG state. No BTC payment output will be added.");
551
- await confirmYesNo(prompter, "This publishes a standalone DOMAIN_SELL mutation.", {
552
- assumeYes,
553
- errorCode: "wallet_sell_confirmation_rejected",
554
- requiresTtyErrorCode: "wallet_sell_requires_tty",
555
- });
556
- }
557
- async function confirmBuy(prompter, domainName, buyerSelector, buyer, sellerScriptPubKeyHex, sellerAddress, listedPriceCogtoshi, assumeYes = false) {
558
- prompter.writeLine(`You are buying "${domainName}".`);
559
- prompter.writeLine(`Exact listing price: ${listedPriceCogtoshi.toString()} cogtoshi.`);
560
- prompter.writeLine(`Resolved buyer: ${buyerSelector} (${buyer.address})`);
561
- prompter.writeLine(`Resolved seller: ${sellerAddress ?? `spk:${sellerScriptPubKeyHex}`}`);
562
- prompter.writeLine("Settlement: entirely in COG state. No BTC payment output will be added.");
563
- await confirmYesNo(prompter, "This publishes a standalone DOMAIN_BUY mutation.", {
564
- assumeYes,
565
- errorCode: "wallet_buy_confirmation_rejected",
566
- requiresTtyErrorCode: "wallet_buy_requires_tty",
567
- });
568
- }
569
- export async function transferDomain(options) {
570
- const normalizedDomainName = normalizeDomainName(options.domainName);
571
- const recipient = normalizeBtcTarget(options.target);
572
- const execution = await executeWalletMutationOperation({
573
- ...options,
574
- controlLockPurpose: "wallet-transfer",
575
- preemptionReason: "wallet-transfer",
576
- resolveOperation(readContext) {
577
- const operation = resolveOwnedDomainOperation(readContext, normalizedDomainName, "wallet_transfer");
578
- const resolvedSender = createResolvedDomainMarketSenderSummary(operation.sender, operation.senderSelector);
579
- const resolvedRecipient = createResolvedDomainMarketRecipientSummary(recipient);
580
- const resolvedEconomicEffect = createTransferEconomicEffectSummary(getListing(readContext.snapshot.state, operation.chainDomain.domainId) !== null);
581
- if (operation.sender.scriptPubKeyHex === recipient.scriptPubKeyHex) {
582
- throw new Error("wallet_transfer_self_transfer");
583
- }
584
- return {
585
- ...operation,
586
- normalizedDomainName,
587
- recipient,
588
- resolvedSender,
589
- resolvedRecipient,
590
- resolvedEconomicEffect,
591
- };
592
- },
593
- createIntentFingerprint(operation) {
594
- return createIntentFingerprint([
595
- "transfer",
596
- operation.state.walletRootId,
597
- operation.normalizedDomainName,
598
- operation.sender.scriptPubKeyHex,
599
- operation.recipient.scriptPubKeyHex,
600
- ]);
601
- },
602
- async resolveExistingMutation({ operation, existingMutation, execution }) {
603
- if (existingMutation === null) {
604
- return { state: operation.state, replacementFixedInputs: null, result: null };
605
- }
606
- return resolveExistingWalletMutation({
607
- existingMutation,
608
- execution,
609
- repairRequiredErrorCode: "wallet_transfer_repair_required",
610
- reconcileExistingMutation: (mutation) => reconcilePendingMutation({
611
- state: operation.state,
612
- mutation,
613
- provider: execution.provider,
614
- nowUnixMs: execution.nowUnixMs,
615
- paths: execution.paths,
616
- rpc: execution.rpc,
617
- walletName: execution.walletName,
618
- context: execution.readContext,
619
- }),
620
- createReuseResult: ({ mutation, resolution, fees }) => ({
621
- kind: "transfer",
622
- domainName: operation.normalizedDomainName,
623
- txid: mutation.attemptedTxid ?? "unknown",
624
- status: resolution,
625
- reusedExisting: true,
626
- recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
627
- resolved: {
628
- sender: operation.resolvedSender,
629
- recipient: operation.resolvedRecipient,
630
- economicEffect: operation.resolvedEconomicEffect,
631
- },
632
- fees,
633
- }),
634
- });
635
- },
636
- confirm({ operation }) {
637
- return confirmTransfer(options.prompter, operation.normalizedDomainName, operation.resolvedSender, operation.resolvedRecipient, operation.resolvedEconomicEffect, options.assumeYes);
638
- },
639
- createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
640
- return {
641
- mutation: createDraftMutation({
642
- kind: "transfer",
643
- domainName: operation.normalizedDomainName,
644
- sender: operation.sender,
645
- recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
646
- intentFingerprintHex,
647
- nowUnixMs: execution.nowUnixMs,
648
- feeSelection: execution.feeSelection,
649
- existing: existingMutation,
650
- }),
651
- prepared: null,
652
- };
653
- },
654
- async prepareBuildState({ state, execution }) {
655
- return (await prepareDomainMarketBuildState({
656
- rpc: execution.rpc,
657
- walletName: execution.walletName,
658
- state,
659
- provider: execution.provider,
660
- nowUnixMs: execution.nowUnixMs,
661
- paths: execution.paths,
662
- preflightCoinControl: false,
663
- })).state;
664
- },
665
- async build({ operation, state, execution, replacementFixedInputs }) {
666
- const transferPlan = buildPlanForDomainOperation({
667
- state,
668
- allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
669
- sender: operation.sender,
670
- opReturnData: serializeDomainTransfer(operation.chainDomain.domainId, Buffer.from(operation.recipient.scriptPubKeyHex, "hex")).opReturnData,
671
- errorPrefix: "wallet_transfer",
672
- });
673
- return buildTransaction({
674
- rpc: execution.rpc,
675
- walletName: execution.walletName,
676
- state,
677
- plan: {
678
- ...transferPlan,
679
- fixedInputs: mergeFixedWalletInputs(transferPlan.fixedInputs, replacementFixedInputs),
680
- },
681
- feeRateSatVb: execution.feeSelection.feeRateSatVb,
682
- });
683
- },
684
- publish({ operation, state, execution, built, mutation }) {
685
- return publishWalletMutation({
686
- rpc: execution.rpc,
687
- walletName: execution.walletName,
688
- snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
689
- built,
690
- mutation,
691
- state,
692
- provider: execution.provider,
693
- nowUnixMs: execution.nowUnixMs,
694
- paths: execution.paths,
695
- errorPrefix: "wallet_transfer",
696
- async afterAccepted({ state: acceptedState, broadcastingMutation, built, nowUnixMs }) {
697
- const finalStatus = getTransferStatusAfterAcceptance({
698
- snapshot: execution.readContext.snapshot,
699
- domainName: operation.normalizedDomainName,
700
- recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
701
- });
702
- const finalMutation = updateMutationRecord(broadcastingMutation, finalStatus, nowUnixMs, {
703
- attemptedTxid: built.txid,
704
- attemptedWtxid: built.wtxid,
705
- temporaryBuilderLockedOutpoints: [],
706
- });
707
- return {
708
- state: reserveTransferredDomainRecord({
709
- state: upsertPendingMutation(acceptedState, finalMutation),
710
- domainName: operation.normalizedDomainName,
711
- domainId: operation.chainDomain.domainId,
712
- currentOwnerScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
713
- nowUnixMs,
714
- }),
715
- mutation: finalMutation,
716
- status: finalStatus,
717
- };
718
- },
719
- });
720
- },
721
- createResult({ operation, mutation, built, status, reusedExisting, fees }) {
722
- return {
723
- kind: "transfer",
724
- domainName: operation.normalizedDomainName,
725
- txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
726
- status: status,
727
- reusedExisting,
728
- recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
729
- resolved: {
730
- sender: operation.resolvedSender,
731
- recipient: operation.resolvedRecipient,
732
- economicEffect: operation.resolvedEconomicEffect,
733
- },
734
- fees,
735
- };
736
- },
737
- });
738
- return execution.result;
739
- }
740
- async function runSellMutation(options) {
741
- const normalizedDomainName = normalizeDomainName(options.domainName);
742
- const execution = await executeWalletMutationOperation({
743
- ...options,
744
- controlLockPurpose: "wallet-sell",
745
- preemptionReason: "wallet-sell",
746
- resolveOperation(readContext) {
747
- const operation = resolveOwnedDomainOperation(readContext, normalizedDomainName, "wallet_sell");
748
- return {
749
- ...operation,
750
- normalizedDomainName,
751
- listedPriceCogtoshi: options.listedPriceCogtoshi,
752
- resolvedSender: createResolvedDomainMarketSenderSummary(operation.sender, operation.senderSelector),
753
- resolvedEconomicEffect: createSellEconomicEffectSummary(options.listedPriceCogtoshi),
754
- };
755
- },
756
- createIntentFingerprint(operation) {
757
- return createIntentFingerprint([
758
- "sell",
759
- operation.state.walletRootId,
760
- operation.normalizedDomainName,
761
- operation.sender.scriptPubKeyHex,
762
- operation.listedPriceCogtoshi.toString(),
763
- ]);
764
- },
765
- async resolveExistingMutation({ operation, existingMutation, execution }) {
766
- if (existingMutation === null) {
767
- return { state: operation.state, replacementFixedInputs: null, result: null };
768
- }
769
- return resolveExistingWalletMutation({
770
- existingMutation,
771
- execution,
772
- repairRequiredErrorCode: "wallet_sell_repair_required",
773
- reconcileExistingMutation: (mutation) => reconcilePendingMutation({
774
- state: operation.state,
775
- mutation,
776
- provider: execution.provider,
777
- nowUnixMs: execution.nowUnixMs,
778
- paths: execution.paths,
779
- rpc: execution.rpc,
780
- walletName: execution.walletName,
781
- context: execution.readContext,
782
- }),
783
- createReuseResult: ({ mutation, resolution, fees }) => ({
784
- kind: "sell",
785
- domainName: operation.normalizedDomainName,
786
- txid: mutation.attemptedTxid ?? "unknown",
787
- status: resolution,
788
- reusedExisting: true,
789
- listedPriceCogtoshi: operation.listedPriceCogtoshi,
790
- resolved: {
791
- sender: operation.resolvedSender,
792
- economicEffect: operation.resolvedEconomicEffect,
793
- },
794
- fees,
795
- }),
796
- });
797
- },
798
- async confirm({ operation }) {
799
- if (operation.listedPriceCogtoshi > 0n) {
800
- await confirmSell(options.prompter, operation.normalizedDomainName, operation.resolvedSender, operation.listedPriceCogtoshi, options.assumeYes);
801
- }
802
- },
803
- createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
804
- return {
805
- mutation: createDraftMutation({
806
- kind: "sell",
807
- domainName: operation.normalizedDomainName,
808
- sender: operation.sender,
809
- priceCogtoshi: operation.listedPriceCogtoshi,
810
- intentFingerprintHex,
811
- nowUnixMs: execution.nowUnixMs,
812
- feeSelection: execution.feeSelection,
813
- existing: existingMutation,
814
- }),
815
- prepared: null,
816
- };
817
- },
818
- async prepareBuildState({ state, execution }) {
819
- return (await prepareDomainMarketBuildState({
820
- rpc: execution.rpc,
821
- walletName: execution.walletName,
822
- state,
823
- provider: execution.provider,
824
- nowUnixMs: execution.nowUnixMs,
825
- paths: execution.paths,
826
- preflightCoinControl: false,
827
- })).state;
828
- },
829
- async build({ operation, state, execution, replacementFixedInputs }) {
830
- const sellPlan = buildPlanForDomainOperation({
831
- state,
832
- allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
833
- sender: operation.sender,
834
- opReturnData: serializeDomainSell(operation.chainDomain.domainId, operation.listedPriceCogtoshi).opReturnData,
835
- errorPrefix: "wallet_sell",
836
- });
837
- return buildTransaction({
838
- rpc: execution.rpc,
839
- walletName: execution.walletName,
840
- state,
841
- plan: {
842
- ...sellPlan,
843
- fixedInputs: mergeFixedWalletInputs(sellPlan.fixedInputs, replacementFixedInputs),
844
- },
845
- feeRateSatVb: execution.feeSelection.feeRateSatVb,
846
- });
847
- },
848
- publish({ operation, state, execution, built, mutation }) {
849
- return publishWalletMutation({
850
- rpc: execution.rpc,
851
- walletName: execution.walletName,
852
- snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
853
- built,
854
- mutation,
855
- state,
856
- provider: execution.provider,
857
- nowUnixMs: execution.nowUnixMs,
858
- paths: execution.paths,
859
- errorPrefix: "wallet_sell",
860
- async afterAccepted({ state: acceptedState, broadcastingMutation, built, nowUnixMs }) {
861
- const finalStatus = getSellStatusAfterAcceptance({
862
- snapshot: execution.readContext.snapshot,
863
- domainName: operation.normalizedDomainName,
864
- senderScriptPubKeyHex: operation.sender.scriptPubKeyHex,
865
- listedPriceCogtoshi: operation.listedPriceCogtoshi,
866
- });
867
- const finalMutation = updateMutationRecord(broadcastingMutation, finalStatus, nowUnixMs, {
868
- attemptedTxid: built.txid,
869
- attemptedWtxid: built.wtxid,
870
- temporaryBuilderLockedOutpoints: [],
871
- });
872
- return {
873
- state: upsertPendingMutation(acceptedState, finalMutation),
874
- mutation: finalMutation,
875
- status: finalStatus,
876
- };
877
- },
878
- });
879
- },
880
- createResult({ operation, mutation, built, status, reusedExisting, fees }) {
881
- return {
882
- kind: "sell",
883
- domainName: operation.normalizedDomainName,
884
- txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
885
- status: status,
886
- reusedExisting,
887
- listedPriceCogtoshi: operation.listedPriceCogtoshi,
888
- resolved: {
889
- sender: operation.resolvedSender,
890
- economicEffect: operation.resolvedEconomicEffect,
891
- },
892
- fees,
893
- };
894
- },
895
- });
896
- return execution.result;
897
- }
898
- export async function sellDomain(options) {
899
- if (options.listedPriceCogtoshi < 0n) {
900
- throw new Error("wallet_sell_invalid_amount");
901
- }
902
- return runSellMutation(options);
903
- }
904
- export async function buyDomain(options) {
905
- const normalizedDomainName = normalizeDomainName(options.domainName);
906
- const execution = await executeWalletMutationOperation({
907
- ...options,
908
- controlLockPurpose: "wallet-buy",
909
- preemptionReason: "wallet-buy",
910
- resolveOperation(readContext) {
911
- const operation = resolveBuyOperation(readContext, normalizedDomainName, options.fromIdentity ?? null);
912
- const model = readContext.model;
913
- const sellerScriptPubKeyHex = Buffer.from(operation.chainDomain.ownerScriptPubKey).toString("hex");
914
- const sellerAddress = sellerScriptPubKeyHex === model.walletScriptPubKeyHex ? model.walletAddress : null;
915
- return {
916
- ...operation,
917
- normalizedDomainName,
918
- sellerScriptPubKeyHex,
919
- resolvedBuyer: {
920
- selector: operation.buyerSelector,
921
- localIndex: operation.sender.localIndex,
922
- scriptPubKeyHex: operation.sender.scriptPubKeyHex,
923
- address: operation.sender.address,
924
- },
925
- resolvedSeller: {
926
- scriptPubKeyHex: sellerScriptPubKeyHex,
927
- address: sellerAddress,
928
- },
929
- };
930
- },
931
- createIntentFingerprint(operation) {
932
- return createIntentFingerprint([
933
- "buy",
934
- operation.state.walletRootId,
935
- operation.normalizedDomainName,
936
- operation.sender.scriptPubKeyHex,
937
- operation.listingPriceCogtoshi.toString(),
938
- ]);
939
- },
940
- async resolveExistingMutation({ operation, existingMutation, execution }) {
941
- if (existingMutation === null) {
942
- return { state: operation.state, replacementFixedInputs: null, result: null };
943
- }
944
- return resolveExistingWalletMutation({
945
- existingMutation,
946
- execution,
947
- repairRequiredErrorCode: "wallet_buy_repair_required",
948
- reconcileExistingMutation: (mutation) => reconcilePendingMutation({
949
- state: operation.state,
950
- mutation,
951
- provider: execution.provider,
952
- nowUnixMs: execution.nowUnixMs,
953
- paths: execution.paths,
954
- rpc: execution.rpc,
955
- walletName: execution.walletName,
956
- context: execution.readContext,
957
- }),
958
- createReuseResult: ({ mutation, resolution, fees }) => ({
959
- kind: "buy",
960
- domainName: operation.normalizedDomainName,
961
- txid: mutation.attemptedTxid ?? "unknown",
962
- status: resolution,
963
- reusedExisting: true,
964
- listedPriceCogtoshi: operation.listingPriceCogtoshi,
965
- resolvedBuyer: operation.resolvedBuyer,
966
- resolvedSeller: operation.resolvedSeller,
967
- fees,
968
- }),
969
- });
970
- },
971
- confirm({ operation }) {
972
- return confirmBuy(options.prompter, operation.normalizedDomainName, operation.buyerSelector, operation.sender, operation.sellerScriptPubKeyHex, operation.resolvedSeller.address, operation.listingPriceCogtoshi, options.assumeYes);
973
- },
974
- createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
975
- return {
976
- mutation: createDraftMutation({
977
- kind: "buy",
978
- domainName: operation.normalizedDomainName,
979
- sender: operation.sender,
980
- priceCogtoshi: operation.listingPriceCogtoshi,
981
- intentFingerprintHex,
982
- nowUnixMs: execution.nowUnixMs,
983
- feeSelection: execution.feeSelection,
984
- existing: existingMutation,
985
- }),
986
- prepared: null,
987
- };
988
- },
989
- async prepareBuildState({ state, execution }) {
990
- return (await prepareDomainMarketBuildState({
991
- rpc: execution.rpc,
992
- walletName: execution.walletName,
993
- state,
994
- provider: execution.provider,
995
- nowUnixMs: execution.nowUnixMs,
996
- paths: execution.paths,
997
- preflightCoinControl: false,
998
- })).state;
999
- },
1000
- async build({ operation, state, execution, replacementFixedInputs }) {
1001
- const buyPlan = buildPlanForDomainOperation({
1002
- state,
1003
- allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
1004
- sender: operation.sender,
1005
- opReturnData: serializeDomainBuy(operation.chainDomain.domainId, operation.listingPriceCogtoshi).opReturnData,
1006
- errorPrefix: "wallet_buy",
1007
- });
1008
- return buildTransaction({
1009
- rpc: execution.rpc,
1010
- walletName: execution.walletName,
1011
- state,
1012
- plan: {
1013
- ...buyPlan,
1014
- fixedInputs: mergeFixedWalletInputs(buyPlan.fixedInputs, replacementFixedInputs),
1015
- },
1016
- feeRateSatVb: execution.feeSelection.feeRateSatVb,
1017
- });
1018
- },
1019
- beforePublish({ operation }) {
1020
- const currentSellerHex = Buffer.from(operation.chainDomain.ownerScriptPubKey).toString("hex");
1021
- if (currentSellerHex !== operation.sellerScriptPubKeyHex) {
1022
- throw new Error("wallet_buy_stale_listing_owner");
1023
- }
1024
- return Promise.resolve();
1025
- },
1026
- publish({ operation, state, execution, built, mutation }) {
1027
- return publishWalletMutation({
1028
- rpc: execution.rpc,
1029
- walletName: execution.walletName,
1030
- snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
1031
- built,
1032
- mutation,
1033
- state,
1034
- provider: execution.provider,
1035
- nowUnixMs: execution.nowUnixMs,
1036
- paths: execution.paths,
1037
- errorPrefix: "wallet_buy",
1038
- async afterAccepted({ state: acceptedState, broadcastingMutation, built, nowUnixMs }) {
1039
- const finalStatus = getBuyStatusAfterAcceptance({
1040
- snapshot: execution.readContext.snapshot,
1041
- domainName: operation.normalizedDomainName,
1042
- buyerScriptPubKeyHex: operation.sender.scriptPubKeyHex,
1043
- });
1044
- const finalMutation = updateMutationRecord(broadcastingMutation, finalStatus, nowUnixMs, {
1045
- attemptedTxid: built.txid,
1046
- attemptedWtxid: built.wtxid,
1047
- temporaryBuilderLockedOutpoints: [],
1048
- });
1049
- return {
1050
- state: reserveTransferredDomainRecord({
1051
- state: upsertPendingMutation(acceptedState, finalMutation),
1052
- domainName: operation.normalizedDomainName,
1053
- domainId: operation.chainDomain.domainId,
1054
- currentOwnerScriptPubKeyHex: operation.sender.scriptPubKeyHex,
1055
- nowUnixMs,
1056
- }),
1057
- mutation: finalMutation,
1058
- status: finalStatus,
1059
- };
1060
- },
1061
- });
1062
- },
1063
- createResult({ operation, mutation, built, status, reusedExisting, fees }) {
1064
- return {
1065
- kind: "buy",
1066
- domainName: operation.normalizedDomainName,
1067
- txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
1068
- status: status,
1069
- reusedExisting,
1070
- listedPriceCogtoshi: operation.listingPriceCogtoshi,
1071
- resolvedBuyer: operation.resolvedBuyer,
1072
- resolvedSeller: operation.resolvedSeller,
1073
- fees,
1074
- };
1075
- },
1076
- });
1077
- return execution.result;
1078
- }
1
+ export * from "./domain-market/index.js";