@cogcoin/client 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/commands/mining-read.js +1 -1
  3. package/dist/cli/commands/wallet-mutation/anchor.d.ts +2 -0
  4. package/dist/cli/commands/wallet-mutation/anchor.js +33 -0
  5. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.d.ts +2 -0
  6. package/dist/cli/commands/wallet-mutation/bitcoin-transfer.js +32 -0
  7. package/dist/cli/commands/wallet-mutation/cog.d.ts +2 -0
  8. package/dist/cli/commands/wallet-mutation/cog.js +131 -0
  9. package/dist/cli/commands/wallet-mutation/context.d.ts +3 -0
  10. package/dist/cli/commands/wallet-mutation/context.js +18 -0
  11. package/dist/cli/commands/wallet-mutation/domain-admin.d.ts +2 -0
  12. package/dist/cli/commands/wallet-mutation/domain-admin.js +173 -0
  13. package/dist/cli/commands/wallet-mutation/domain-market.d.ts +2 -0
  14. package/dist/cli/commands/wallet-mutation/domain-market.js +107 -0
  15. package/dist/cli/commands/wallet-mutation/field.d.ts +2 -0
  16. package/dist/cli/commands/wallet-mutation/field.js +125 -0
  17. package/dist/cli/commands/wallet-mutation/register.d.ts +2 -0
  18. package/dist/cli/commands/wallet-mutation/register.js +38 -0
  19. package/dist/cli/commands/wallet-mutation/registry.d.ts +3 -0
  20. package/dist/cli/commands/wallet-mutation/registry.js +39 -0
  21. package/dist/cli/commands/wallet-mutation/reputation.d.ts +2 -0
  22. package/dist/cli/commands/wallet-mutation/reputation.js +57 -0
  23. package/dist/cli/commands/wallet-mutation/types.d.ts +32 -0
  24. package/dist/cli/commands/wallet-mutation/types.js +1 -0
  25. package/dist/cli/commands/wallet-mutation.js +13 -765
  26. package/dist/cli/commands/wallet-read.js +4 -4
  27. package/dist/cli/mutation-success.d.ts +0 -2
  28. package/dist/cli/output/classify.d.ts +7 -0
  29. package/dist/cli/output/classify.js +94 -0
  30. package/dist/cli/output/render.d.ts +2 -0
  31. package/dist/cli/output/render.js +13 -0
  32. package/dist/cli/output/rules/cli-surface.d.ts +2 -0
  33. package/dist/cli/output/rules/cli-surface.js +110 -0
  34. package/dist/cli/output/rules/generic.d.ts +2 -0
  35. package/dist/cli/output/rules/generic.js +13 -0
  36. package/dist/cli/output/rules/index.d.ts +2 -0
  37. package/dist/cli/output/rules/index.js +24 -0
  38. package/dist/cli/output/rules/mining-update.d.ts +2 -0
  39. package/dist/cli/output/rules/mining-update.js +68 -0
  40. package/dist/cli/output/rules/services.d.ts +2 -0
  41. package/dist/cli/output/rules/services.js +110 -0
  42. package/dist/cli/output/rules/wallet-admin.d.ts +2 -0
  43. package/dist/cli/output/rules/wallet-admin.js +224 -0
  44. package/dist/cli/output/rules/wallet-mutations.d.ts +2 -0
  45. package/dist/cli/output/rules/wallet-mutations.js +274 -0
  46. package/dist/cli/output/types.d.ts +16 -0
  47. package/dist/cli/output/types.js +1 -0
  48. package/dist/cli/output.d.ts +2 -168
  49. package/dist/cli/output.js +6 -989
  50. package/dist/cli/pagination.d.ts +15 -0
  51. package/dist/cli/pagination.js +16 -0
  52. package/dist/cli/recommendations.d.ts +4 -0
  53. package/dist/cli/recommendations.js +108 -0
  54. package/dist/cli/wallet-format/availability.d.ts +5 -0
  55. package/dist/cli/wallet-format/availability.js +96 -0
  56. package/dist/cli/wallet-format/balance.d.ts +2 -0
  57. package/dist/cli/wallet-format/balance.js +162 -0
  58. package/dist/cli/wallet-format/domains.d.ts +8 -0
  59. package/dist/cli/wallet-format/domains.js +84 -0
  60. package/dist/cli/wallet-format/fields.d.ts +6 -0
  61. package/dist/cli/wallet-format/fields.js +61 -0
  62. package/dist/cli/wallet-format/identity.d.ts +5 -0
  63. package/dist/cli/wallet-format/identity.js +19 -0
  64. package/dist/cli/wallet-format/locks.d.ts +7 -0
  65. package/dist/cli/wallet-format/locks.js +52 -0
  66. package/dist/cli/wallet-format/overview.d.ts +2 -0
  67. package/dist/cli/wallet-format/overview.js +122 -0
  68. package/dist/cli/wallet-format/pending.d.ts +13 -0
  69. package/dist/cli/wallet-format/pending.js +101 -0
  70. package/dist/cli/wallet-format/shared.d.ts +7 -0
  71. package/dist/cli/wallet-format/shared.js +31 -0
  72. package/dist/cli/wallet-format/status.d.ts +3 -0
  73. package/dist/cli/wallet-format/status.js +27 -0
  74. package/dist/cli/wallet-format.d.ts +8 -30
  75. package/dist/cli/wallet-format.js +8 -830
  76. package/dist/cli/wallet-read-helpers.d.ts +6 -0
  77. package/dist/cli/wallet-read-helpers.js +17 -0
  78. package/dist/wallet/mining/candidate.d.ts +1 -1
  79. package/dist/wallet/mining/candidate.js +3 -3
  80. package/dist/wallet/mining/constants.d.ts +2 -2
  81. package/dist/wallet/mining/constants.js +2 -2
  82. package/dist/wallet/mining/sentence-protocol.d.ts +2 -2
  83. package/dist/wallet/mining/sentences.js +8 -8
  84. package/dist/wallet/tx/anchor/confirm.d.ts +15 -0
  85. package/dist/wallet/tx/anchor/confirm.js +60 -0
  86. package/dist/wallet/tx/anchor/draft.d.ts +39 -0
  87. package/dist/wallet/tx/anchor/draft.js +167 -0
  88. package/dist/wallet/tx/anchor/index.d.ts +5 -0
  89. package/dist/wallet/tx/anchor/index.js +148 -0
  90. package/dist/wallet/tx/anchor/intent.d.ts +61 -0
  91. package/dist/wallet/tx/anchor/intent.js +101 -0
  92. package/dist/wallet/tx/anchor/plan.d.ts +3 -0
  93. package/dist/wallet/tx/anchor/plan.js +18 -0
  94. package/dist/wallet/tx/anchor/result.d.ts +25 -0
  95. package/dist/wallet/tx/anchor/result.js +20 -0
  96. package/dist/wallet/tx/anchor.d.ts +1 -39
  97. package/dist/wallet/tx/anchor.js +1 -494
  98. package/dist/wallet/tx/bitcoin-transfer/confirm.d.ts +7 -0
  99. package/dist/wallet/tx/bitcoin-transfer/confirm.js +11 -0
  100. package/dist/wallet/tx/bitcoin-transfer/index.d.ts +5 -0
  101. package/dist/wallet/tx/bitcoin-transfer/index.js +112 -0
  102. package/dist/wallet/tx/bitcoin-transfer/intent.d.ts +52 -0
  103. package/dist/wallet/tx/bitcoin-transfer/intent.js +74 -0
  104. package/dist/wallet/tx/bitcoin-transfer/plan.d.ts +5 -0
  105. package/dist/wallet/tx/bitcoin-transfer/plan.js +21 -0
  106. package/dist/wallet/tx/bitcoin-transfer/result.d.ts +19 -0
  107. package/dist/wallet/tx/bitcoin-transfer/result.js +16 -0
  108. package/dist/wallet/tx/bitcoin-transfer.d.ts +1 -35
  109. package/dist/wallet/tx/bitcoin-transfer.js +1 -200
  110. package/dist/wallet/tx/cog/confirm.d.ts +13 -0
  111. package/dist/wallet/tx/cog/confirm.js +59 -0
  112. package/dist/wallet/tx/cog/draft.d.ts +20 -0
  113. package/dist/wallet/tx/cog/draft.js +114 -0
  114. package/dist/wallet/tx/cog/index.d.ts +6 -0
  115. package/dist/wallet/tx/cog/index.js +117 -0
  116. package/dist/wallet/tx/cog/intent.d.ts +30 -0
  117. package/dist/wallet/tx/cog/intent.js +169 -0
  118. package/dist/wallet/tx/cog/plan.d.ts +19 -0
  119. package/dist/wallet/tx/cog/plan.js +65 -0
  120. package/dist/wallet/tx/cog/result.d.ts +27 -0
  121. package/dist/wallet/tx/cog/result.js +28 -0
  122. package/dist/wallet/tx/cog/types.d.ts +186 -0
  123. package/dist/wallet/tx/cog/types.js +2 -0
  124. package/dist/wallet/tx/cog/variants/claim.d.ts +3 -0
  125. package/dist/wallet/tx/cog/variants/claim.js +92 -0
  126. package/dist/wallet/tx/cog/variants/lock.d.ts +2 -0
  127. package/dist/wallet/tx/cog/variants/lock.js +102 -0
  128. package/dist/wallet/tx/cog/variants/send.d.ts +2 -0
  129. package/dist/wallet/tx/cog/variants/send.js +77 -0
  130. package/dist/wallet/tx/cog.d.ts +1 -96
  131. package/dist/wallet/tx/cog.js +1 -824
  132. package/dist/wallet/tx/common.d.ts +14 -199
  133. package/dist/wallet/tx/common.js +10 -493
  134. package/dist/wallet/tx/domain-admin/confirm.d.ts +17 -0
  135. package/dist/wallet/tx/domain-admin/confirm.js +58 -0
  136. package/dist/wallet/tx/domain-admin/draft.d.ts +20 -0
  137. package/dist/wallet/tx/domain-admin/draft.js +161 -0
  138. package/dist/wallet/tx/domain-admin/index.d.ts +9 -0
  139. package/dist/wallet/tx/domain-admin/index.js +150 -0
  140. package/dist/wallet/tx/domain-admin/intent.d.ts +12 -0
  141. package/dist/wallet/tx/domain-admin/intent.js +61 -0
  142. package/dist/wallet/tx/domain-admin/plan.d.ts +19 -0
  143. package/dist/wallet/tx/domain-admin/plan.js +64 -0
  144. package/dist/wallet/tx/domain-admin/result.d.ts +19 -0
  145. package/dist/wallet/tx/domain-admin/result.js +33 -0
  146. package/dist/wallet/tx/domain-admin/types.d.ts +162 -0
  147. package/dist/wallet/tx/domain-admin/types.js +1 -0
  148. package/dist/wallet/tx/domain-admin/variants/canonical.d.ts +2 -0
  149. package/dist/wallet/tx/domain-admin/variants/canonical.js +22 -0
  150. package/dist/wallet/tx/domain-admin/variants/delegate.d.ts +3 -0
  151. package/dist/wallet/tx/domain-admin/variants/delegate.js +60 -0
  152. package/dist/wallet/tx/domain-admin/variants/endpoint.d.ts +3 -0
  153. package/dist/wallet/tx/domain-admin/variants/endpoint.js +102 -0
  154. package/dist/wallet/tx/domain-admin/variants/miner.d.ts +3 -0
  155. package/dist/wallet/tx/domain-admin/variants/miner.js +59 -0
  156. package/dist/wallet/tx/domain-admin.d.ts +1 -107
  157. package/dist/wallet/tx/domain-admin.js +1 -729
  158. package/dist/wallet/tx/domain-market/confirm.d.ts +6 -0
  159. package/dist/wallet/tx/domain-market/confirm.js +52 -0
  160. package/dist/wallet/tx/domain-market/draft.d.ts +43 -0
  161. package/dist/wallet/tx/domain-market/draft.js +286 -0
  162. package/dist/wallet/tx/domain-market/index.d.ts +6 -0
  163. package/dist/wallet/tx/domain-market/index.js +145 -0
  164. package/dist/wallet/tx/domain-market/intent.d.ts +15 -0
  165. package/dist/wallet/tx/domain-market/intent.js +131 -0
  166. package/dist/wallet/tx/domain-market/plan.d.ts +31 -0
  167. package/dist/wallet/tx/domain-market/plan.js +98 -0
  168. package/dist/wallet/tx/domain-market/result.d.ts +45 -0
  169. package/dist/wallet/tx/domain-market/result.js +88 -0
  170. package/dist/wallet/tx/domain-market/types.d.ts +221 -0
  171. package/dist/wallet/tx/domain-market/types.js +1 -0
  172. package/dist/wallet/tx/domain-market/variants/buy.d.ts +2 -0
  173. package/dist/wallet/tx/domain-market/variants/buy.js +103 -0
  174. package/dist/wallet/tx/domain-market/variants/sell.d.ts +2 -0
  175. package/dist/wallet/tx/domain-market/variants/sell.js +91 -0
  176. package/dist/wallet/tx/domain-market/variants/transfer.d.ts +2 -0
  177. package/dist/wallet/tx/domain-market/variants/transfer.js +105 -0
  178. package/dist/wallet/tx/domain-market.d.ts +1 -116
  179. package/dist/wallet/tx/domain-market.js +1 -1078
  180. package/dist/wallet/tx/draft-build.d.ts +60 -0
  181. package/dist/wallet/tx/draft-build.js +127 -0
  182. package/dist/wallet/tx/executor.d.ts +6 -40
  183. package/dist/wallet/tx/executor.js +6 -100
  184. package/dist/wallet/tx/fee.d.ts +30 -0
  185. package/dist/wallet/tx/fee.js +98 -0
  186. package/dist/wallet/tx/field/confirm.d.ts +11 -0
  187. package/dist/wallet/tx/field/confirm.js +19 -0
  188. package/dist/wallet/tx/field/draft.d.ts +23 -0
  189. package/dist/wallet/tx/field/draft.js +202 -0
  190. package/dist/wallet/tx/field/index.d.ts +5 -0
  191. package/dist/wallet/tx/field/index.js +140 -0
  192. package/dist/wallet/tx/field/intent.d.ts +5 -0
  193. package/dist/wallet/tx/field/intent.js +50 -0
  194. package/dist/wallet/tx/field/plan.d.ts +20 -0
  195. package/dist/wallet/tx/field/plan.js +65 -0
  196. package/dist/wallet/tx/field/result.d.ts +29 -0
  197. package/dist/wallet/tx/field/result.js +103 -0
  198. package/dist/wallet/tx/field/types.d.ts +163 -0
  199. package/dist/wallet/tx/field/types.js +1 -0
  200. package/dist/wallet/tx/field/variants/clear.d.ts +2 -0
  201. package/dist/wallet/tx/field/variants/clear.js +60 -0
  202. package/dist/wallet/tx/field/variants/create.d.ts +2 -0
  203. package/dist/wallet/tx/field/variants/create.js +67 -0
  204. package/dist/wallet/tx/field/variants/set.d.ts +2 -0
  205. package/dist/wallet/tx/field/variants/set.js +195 -0
  206. package/dist/wallet/tx/field.d.ts +1 -95
  207. package/dist/wallet/tx/field.js +1 -920
  208. package/dist/wallet/tx/mining-preemption.d.ts +6 -0
  209. package/dist/wallet/tx/mining-preemption.js +7 -0
  210. package/dist/wallet/tx/primitives.d.ts +13 -0
  211. package/dist/wallet/tx/primitives.js +42 -0
  212. package/dist/wallet/tx/psbt-assert.d.ts +14 -0
  213. package/dist/wallet/tx/psbt-assert.js +39 -0
  214. package/dist/wallet/tx/publish.d.ts +37 -0
  215. package/dist/wallet/tx/publish.js +88 -0
  216. package/dist/wallet/tx/readiness.d.ts +7 -0
  217. package/dist/wallet/tx/readiness.js +61 -0
  218. package/dist/wallet/tx/reconcile.d.ts +24 -0
  219. package/dist/wallet/tx/reconcile.js +72 -0
  220. package/dist/wallet/tx/register/confirm.d.ts +6 -0
  221. package/dist/wallet/tx/register/confirm.js +66 -0
  222. package/dist/wallet/tx/register/draft.d.ts +42 -0
  223. package/dist/wallet/tx/register/draft.js +181 -0
  224. package/dist/wallet/tx/register/index.d.ts +6 -0
  225. package/dist/wallet/tx/register/index.js +158 -0
  226. package/dist/wallet/tx/register/intent.d.ts +74 -0
  227. package/dist/wallet/tx/register/intent.js +119 -0
  228. package/dist/wallet/tx/register/plan.d.ts +43 -0
  229. package/dist/wallet/tx/register/plan.js +168 -0
  230. package/dist/wallet/tx/register/result.d.ts +78 -0
  231. package/dist/wallet/tx/register/result.js +41 -0
  232. package/dist/wallet/tx/register.d.ts +1 -70
  233. package/dist/wallet/tx/register.js +1 -681
  234. package/dist/wallet/tx/reputation/confirm.d.ts +11 -0
  235. package/dist/wallet/tx/reputation/confirm.js +51 -0
  236. package/dist/wallet/tx/reputation/draft.d.ts +20 -0
  237. package/dist/wallet/tx/reputation/draft.js +130 -0
  238. package/dist/wallet/tx/reputation/index.d.ts +4 -0
  239. package/dist/wallet/tx/reputation/index.js +162 -0
  240. package/dist/wallet/tx/reputation/intent.d.ts +36 -0
  241. package/dist/wallet/tx/reputation/intent.js +157 -0
  242. package/dist/wallet/tx/reputation/plan.d.ts +19 -0
  243. package/dist/wallet/tx/reputation/plan.js +64 -0
  244. package/dist/wallet/tx/reputation/result.d.ts +21 -0
  245. package/dist/wallet/tx/reputation/result.js +31 -0
  246. package/dist/wallet/tx/reputation/types.d.ts +130 -0
  247. package/dist/wallet/tx/reputation/types.js +1 -0
  248. package/dist/wallet/tx/reputation.d.ts +1 -74
  249. package/dist/wallet/tx/reputation.js +1 -556
  250. package/dist/wallet/tx/signing.d.ts +18 -0
  251. package/dist/wallet/tx/signing.js +31 -0
  252. package/dist/wallet/tx/state-persist.d.ts +27 -0
  253. package/dist/wallet/tx/state-persist.js +54 -0
  254. package/dist/wallet/tx/types.d.ts +44 -0
  255. package/dist/wallet/tx/types.js +1 -0
  256. package/package.json +1 -1
  257. package/dist/cli/mining-json.d.ts +0 -20
  258. package/dist/cli/mining-json.js +0 -46
  259. package/dist/cli/mutation-json.d.ts +0 -325
  260. package/dist/cli/mutation-json.js +0 -269
  261. package/dist/cli/mutation-resolved-json.d.ts +0 -117
  262. package/dist/cli/mutation-resolved-json.js +0 -123
  263. package/dist/cli/preview-json.d.ts +0 -319
  264. package/dist/cli/preview-json.js +0 -254
  265. package/dist/cli/read-json.d.ts +0 -190
  266. package/dist/cli/read-json.js +0 -627
@@ -1,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";