@cogcoin/client 0.5.15 → 1.0.1

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 (174) hide show
  1. package/README.md +80 -25
  2. package/dist/app-paths.d.ts +5 -6
  3. package/dist/app-paths.js +8 -16
  4. package/dist/art/balance.txt +10 -0
  5. package/dist/art/welcome.txt +16 -0
  6. package/dist/bitcoind/bootstrap/controller.d.ts +1 -0
  7. package/dist/bitcoind/bootstrap/controller.js +53 -1
  8. package/dist/bitcoind/client/follow-block-times.d.ts +1 -0
  9. package/dist/bitcoind/client/follow-block-times.js +1 -1
  10. package/dist/bitcoind/client/internal-types.d.ts +7 -3
  11. package/dist/bitcoind/client/managed-client.d.ts +4 -2
  12. package/dist/bitcoind/client/managed-client.js +14 -0
  13. package/dist/bitcoind/client/sync-engine.js +72 -11
  14. package/dist/bitcoind/hash-order.d.ts +4 -0
  15. package/dist/bitcoind/hash-order.js +13 -0
  16. package/dist/bitcoind/indexer-daemon-main.js +11 -3
  17. package/dist/bitcoind/normalize.js +3 -2
  18. package/dist/bitcoind/processing-start-height.d.ts +5 -0
  19. package/dist/bitcoind/processing-start-height.js +7 -0
  20. package/dist/bitcoind/progress/constants.d.ts +4 -0
  21. package/dist/bitcoind/progress/constants.js +4 -0
  22. package/dist/bitcoind/progress/controller.d.ts +2 -1
  23. package/dist/bitcoind/progress/controller.js +3 -3
  24. package/dist/bitcoind/progress/follow-scene.d.ts +6 -2
  25. package/dist/bitcoind/progress/follow-scene.js +29 -6
  26. package/dist/bitcoind/progress/formatting.d.ts +1 -0
  27. package/dist/bitcoind/progress/formatting.js +6 -0
  28. package/dist/bitcoind/progress/train-scene.js +37 -18
  29. package/dist/bitcoind/progress/tty-renderer.d.ts +6 -1
  30. package/dist/bitcoind/progress/tty-renderer.js +8 -4
  31. package/dist/bitcoind/rpc.d.ts +2 -1
  32. package/dist/bitcoind/rpc.js +3 -0
  33. package/dist/bitcoind/types.d.ts +6 -0
  34. package/dist/bytes.d.ts +1 -0
  35. package/dist/bytes.js +3 -0
  36. package/dist/cli/art.d.ts +2 -0
  37. package/dist/cli/art.js +37 -0
  38. package/dist/cli/commands/client-admin.d.ts +2 -0
  39. package/dist/cli/commands/client-admin.js +91 -0
  40. package/dist/cli/commands/follow.js +0 -2
  41. package/dist/cli/commands/mining-admin.js +6 -47
  42. package/dist/cli/commands/mining-read.js +11 -50
  43. package/dist/cli/commands/mining-runtime.js +142 -5
  44. package/dist/cli/commands/service-runtime.js +0 -2
  45. package/dist/cli/commands/status.js +8 -2
  46. package/dist/cli/commands/sync.js +49 -92
  47. package/dist/cli/commands/wallet-admin.js +142 -136
  48. package/dist/cli/commands/wallet-mutation.js +91 -79
  49. package/dist/cli/commands/wallet-read.js +15 -18
  50. package/dist/cli/context.js +5 -14
  51. package/dist/cli/mining-format.d.ts +0 -1
  52. package/dist/cli/mining-format.js +5 -37
  53. package/dist/cli/mining-json.d.ts +0 -18
  54. package/dist/cli/mining-json.js +0 -35
  55. package/dist/cli/mutation-command-groups.d.ts +1 -2
  56. package/dist/cli/mutation-command-groups.js +0 -5
  57. package/dist/cli/mutation-json.d.ts +24 -145
  58. package/dist/cli/mutation-json.js +30 -136
  59. package/dist/cli/mutation-resolved-json.d.ts +0 -7
  60. package/dist/cli/mutation-resolved-json.js +4 -10
  61. package/dist/cli/mutation-success.d.ts +2 -0
  62. package/dist/cli/mutation-success.js +11 -1
  63. package/dist/cli/mutation-text-format.js +1 -3
  64. package/dist/cli/output.d.ts +1 -1
  65. package/dist/cli/output.js +254 -231
  66. package/dist/cli/parse.d.ts +1 -1
  67. package/dist/cli/parse.js +93 -122
  68. package/dist/cli/preview-json.d.ts +17 -120
  69. package/dist/cli/preview-json.js +14 -97
  70. package/dist/cli/prompt.js +8 -13
  71. package/dist/cli/read-json.d.ts +15 -37
  72. package/dist/cli/read-json.js +44 -140
  73. package/dist/cli/runner.js +10 -13
  74. package/dist/cli/sync-progress.d.ts +6 -0
  75. package/dist/cli/sync-progress.js +91 -0
  76. package/dist/cli/types.d.ts +9 -17
  77. package/dist/cli/types.js +0 -2
  78. package/dist/cli/wallet-format.d.ts +1 -0
  79. package/dist/cli/wallet-format.js +208 -144
  80. package/dist/cli/workflow-hints.d.ts +3 -3
  81. package/dist/cli/workflow-hints.js +11 -8
  82. package/dist/client/default-client.d.ts +3 -1
  83. package/dist/client/default-client.js +45 -2
  84. package/dist/client/factory.js +1 -1
  85. package/dist/client/initialization.js +23 -0
  86. package/dist/client/persistence.js +5 -5
  87. package/dist/client/store-adapter.js +1 -0
  88. package/dist/sqlite/checkpoints.d.ts +1 -0
  89. package/dist/sqlite/checkpoints.js +7 -0
  90. package/dist/sqlite/store.js +14 -1
  91. package/dist/types.d.ts +1 -0
  92. package/dist/wallet/coin-control.d.ts +41 -12
  93. package/dist/wallet/coin-control.js +100 -428
  94. package/dist/wallet/descriptor-normalization.d.ts +1 -3
  95. package/dist/wallet/descriptor-normalization.js +0 -16
  96. package/dist/wallet/lifecycle.d.ts +7 -99
  97. package/dist/wallet/lifecycle.js +513 -968
  98. package/dist/wallet/managed-core-wallet.d.ts +13 -0
  99. package/dist/wallet/managed-core-wallet.js +20 -0
  100. package/dist/wallet/mining/constants.d.ts +5 -12
  101. package/dist/wallet/mining/constants.js +5 -12
  102. package/dist/wallet/mining/control.d.ts +1 -13
  103. package/dist/wallet/mining/control.js +45 -349
  104. package/dist/wallet/mining/index.d.ts +4 -5
  105. package/dist/wallet/mining/index.js +2 -3
  106. package/dist/wallet/mining/runner.d.ts +123 -13
  107. package/dist/wallet/mining/runner.js +899 -511
  108. package/dist/wallet/mining/runtime-artifacts.js +23 -3
  109. package/dist/wallet/mining/sentence-protocol.d.ts +44 -0
  110. package/dist/wallet/mining/sentence-protocol.js +123 -0
  111. package/dist/wallet/mining/sentences.d.ts +4 -8
  112. package/dist/wallet/mining/sentences.js +3 -52
  113. package/dist/wallet/mining/state.d.ts +11 -6
  114. package/dist/wallet/mining/state.js +7 -6
  115. package/dist/wallet/mining/types.d.ts +2 -30
  116. package/dist/wallet/mining/visualizer.d.ts +31 -3
  117. package/dist/wallet/mining/visualizer.js +135 -13
  118. package/dist/wallet/read/context.d.ts +0 -2
  119. package/dist/wallet/read/context.js +119 -140
  120. package/dist/wallet/read/filter.js +2 -11
  121. package/dist/wallet/read/index.d.ts +1 -1
  122. package/dist/wallet/read/project.js +24 -77
  123. package/dist/wallet/read/types.d.ts +10 -25
  124. package/dist/wallet/reset.d.ts +0 -1
  125. package/dist/wallet/reset.js +60 -138
  126. package/dist/wallet/root-resolution.d.ts +1 -5
  127. package/dist/wallet/root-resolution.js +0 -18
  128. package/dist/wallet/runtime.d.ts +0 -6
  129. package/dist/wallet/runtime.js +0 -8
  130. package/dist/wallet/state/client-password-agent.js +208 -0
  131. package/dist/wallet/state/client-password.d.ts +65 -0
  132. package/dist/wallet/state/client-password.js +952 -0
  133. package/dist/wallet/state/crypto.d.ts +1 -20
  134. package/dist/wallet/state/crypto.js +0 -63
  135. package/dist/wallet/state/provider.d.ts +23 -11
  136. package/dist/wallet/state/provider.js +248 -290
  137. package/dist/wallet/state/storage.d.ts +2 -2
  138. package/dist/wallet/state/storage.js +48 -16
  139. package/dist/wallet/tx/anchor.d.ts +3 -28
  140. package/dist/wallet/tx/anchor.js +349 -1250
  141. package/dist/wallet/tx/bitcoin-transfer.d.ts +35 -0
  142. package/dist/wallet/tx/bitcoin-transfer.js +200 -0
  143. package/dist/wallet/tx/cog.d.ts +5 -1
  144. package/dist/wallet/tx/cog.js +149 -185
  145. package/dist/wallet/tx/common.d.ts +61 -8
  146. package/dist/wallet/tx/common.js +266 -146
  147. package/dist/wallet/tx/domain-admin.d.ts +3 -1
  148. package/dist/wallet/tx/domain-admin.js +61 -99
  149. package/dist/wallet/tx/domain-market.d.ts +5 -1
  150. package/dist/wallet/tx/domain-market.js +221 -228
  151. package/dist/wallet/tx/field.d.ts +4 -10
  152. package/dist/wallet/tx/field.js +83 -924
  153. package/dist/wallet/tx/identity-selector.d.ts +9 -3
  154. package/dist/wallet/tx/identity-selector.js +17 -35
  155. package/dist/wallet/tx/index.d.ts +3 -1
  156. package/dist/wallet/tx/index.js +2 -1
  157. package/dist/wallet/tx/register.d.ts +3 -1
  158. package/dist/wallet/tx/register.js +62 -220
  159. package/dist/wallet/tx/reputation.d.ts +3 -1
  160. package/dist/wallet/tx/reputation.js +58 -95
  161. package/dist/wallet/types.d.ts +8 -122
  162. package/package.json +5 -5
  163. package/dist/wallet/archive.d.ts +0 -4
  164. package/dist/wallet/archive.js +0 -41
  165. package/dist/wallet/mining/hook-protocol.d.ts +0 -47
  166. package/dist/wallet/mining/hook-protocol.js +0 -161
  167. package/dist/wallet/mining/hook-runner.js +0 -52
  168. package/dist/wallet/mining/hooks.d.ts +0 -38
  169. package/dist/wallet/mining/hooks.js +0 -520
  170. package/dist/wallet/state/explicit-lock.d.ts +0 -4
  171. package/dist/wallet/state/explicit-lock.js +0 -19
  172. package/dist/wallet/state/session.d.ts +0 -12
  173. package/dist/wallet/state/session.js +0 -23
  174. /package/dist/wallet/{mining/hook-runner.d.ts → state/client-password-agent.d.ts} +0 -0
package/README.md CHANGED
@@ -1,39 +1,95 @@
1
1
  # `@cogcoin/client`
2
2
 
3
- `@cogcoin/client@0.5.15` is the store-backed Cogcoin client package for applications that want a local wallet, durable SQLite-backed state, and a managed Bitcoin Core integration around `@cogcoin/indexer`. It publishes the reusable client APIs, the SQLite adapter, the managed `bitcoind` integration, and the first-party `cogcoin` CLI in one package.
3
+ `@cogcoin/client@1.0.0` is the reference Cogcoin client package for applications that want a local wallet, durable SQLite-backed state, and a managed Bitcoin Core integration around `@cogcoin/indexer`. It publishes the reusable client APIs, the SQLite adapter, the managed `bitcoind` integration, and the first-party `cogcoin` CLI in one package.
4
4
 
5
5
  Use Node 22 or newer.
6
6
 
7
- ## Links
8
-
9
- - Website: [cogcoin.org](https://cogcoin.org)
10
- - Whitepaper: [cogcoin.org/whitepaper.md](https://cogcoin.org/whitepaper.md)
11
- - Source: [github.com/cogcoin/client](https://github.com/cogcoin/client)
12
- - Bitcoin package: [npmjs.com/package/@cogcoin/bitcoin](https://www.npmjs.com/package/@cogcoin/bitcoin)
13
- - Genesis package: [npmjs.com/package/@cogcoin/genesis](https://www.npmjs.com/package/@cogcoin/genesis)
14
- - Indexer package: [npmjs.com/package/@cogcoin/indexer](https://www.npmjs.com/package/@cogcoin/indexer)
15
- - Scoring package: [npmjs.com/package/@cogcoin/scoring](https://www.npmjs.com/package/@cogcoin/scoring)
16
-
17
7
  ## Quick Start
18
8
 
19
9
  Install the package:
20
10
 
21
11
  ```bash
22
- npm install @cogcoin/client
12
+ npm install -g @cogcoin/client
13
+ cogcoin init
14
+ cogcoin address # Send 0.0015 BTC to address
15
+ cogcoin register <domainname> # 6+ character domain for 0.001 BTC
16
+ cogcoin anchor <domainname> # You can leave a founding message permanently on Bitcoin!
17
+ cogcoin mine setup
18
+ cogcoin mine # Use remaining ~0.0005 BTC for mining tx, ~1000 sats per entry (0.00001 BTC)
19
+ ```
20
+
21
+ ## Preview
22
+
23
+ ```bash
24
+
25
+ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
26
+ ▄▀ ▀▄
27
+ █ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄ █ Welcome to...
28
+ █ █ █ █
29
+ █ █ █ █ █ █ █ █████ █████ █████ █████ █████ ██ ███ ██
30
+ █ █ █ █ █ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
31
+ █ █ ▄█ █ █ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██
32
+ █ █ ▄ ▄ █ █ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
33
+ █ █ ▀▀▀▀ █ █ █████ █████ █████ █████ █████ ██ ██ ████
34
+ █ ▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀ █
35
+ █ █ ┏┳┓╻┏┓╻┏━╸ ╻ ╻╻╺┳╸╻ ╻ ╻ ╻┏━┓┏━┓╺┳┓┏━┓
36
+ █ █ ┃┃┃┃┃┗┫┣╸ ┃╻┃┃ ┃ ┣━┫ ┃╻┃┃ ┃┣┳┛ ┃┃┗━┓
37
+ █ ▄▄ ▄▄▄▄▄▄ █ ╹ ╹╹╹ ╹┗━╸ ┗┻┛╹ ╹ ╹ ╹ ┗┻┛┗━┛╹┗╸╺┻┛┗━┛
38
+ █ █
39
+ ▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀ We are so happy to have you here!
40
+ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
41
+
42
+
23
43
  ```
24
44
 
25
- Then, from your project root, run:
45
+ ```bash
46
+ ⛭ Behold, your Cogcoin wallet. ⛭
47
+ ▐▀▀▀▀▀▀▀▀▚ ╔──────────────────────────────────────────────────────────────────╗
48
+ ▛▞▀▀▀▀▀▀▀▀▚ │ │
49
+ ▌▝▀▀▀▀▀▀▀▀▀▌│ Funding address: bc1qsamplewallet0000000000000000000000000 │
50
+ ▌ ▗▙▙ ▌│ │
51
+ ▌ ▐ ▌ ▌│ Bitcoin Balance: 0.00150000 BTC │
52
+ ▌ ▐▀▀▚ ▌│ Cogcoin Balance: 12.50000000 COG │
53
+ ▌ ▐▄▄▞ ▌│ │
54
+ ▌ ▘▘ ▌│ mempool.space/address/bc1qsamplewallet0000000000000000000000000 |
55
+ ▝▀▀▀▀▀▀▀▀▀▀▘╚──────────────────────────────────────────────────────────────────╝
56
+
57
+ Anchored Domains
58
+ ⌂ cogdemo
59
+
60
+ Unanchored Domains
61
+ --- No unanchored domains ---
62
+ ```
26
63
 
27
64
  ```bash
28
- node node_modules/@cogcoin/genesis/verify.mjs
29
- npx cogcoin init
30
- npx cogcoin sync
65
+ _____ _____
66
+ ( ___ ) 12.500 COG ⛭ C O G C O I N ⛭ 150000 SAT ( ___ )
67
+ | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| |
68
+ | | | |
69
+ | | | |
70
+ | | 945516 945515 945514 945513 945512| |
71
+ | |_|"""""| _|"""""|_|"""""|_|"""""|_|"""""|_|"""""| |
72
+ | |"`-0-0-' "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-| |
73
+ | | ~10 min | |
74
+ | | | |
75
+ | | | |
76
+ |___|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|___|
77
+ (_____) Waiting for indexer (_____)
78
+
79
+ [░░░░░░░░░░░░░░░░████] Mining is waiting for Bitcoin Core and the indexer to align.
80
+ Required words: OWNER, OLYMPIC, ERODE, DESK, DIFFER
81
+ @cogdemo: By the desk, the owner observed that Olympic lettering could erode over time, though experts differ.
31
82
  ```
32
83
 
33
- Verify the installed genesis artifacts before using the client in a production implementation.
34
- The installed package provides the `cogcoin` command for local wallet setup, sync, reads, writes, and mining workflows.
35
- Provider-backed local wallets unlock on demand by default; `cogcoin wallet lock` suppresses that behavior until `cogcoin unlock` is run again.
36
- Passphrase-wrapped wallet-state flows still require explicit passphrase-based access.
84
+ ## Links
85
+
86
+ - Website: [cogcoin.org](https://cogcoin.org)
87
+ - Whitepaper: [cogcoin.org/whitepaper.md](https://cogcoin.org/whitepaper.md)
88
+ - Source: [github.com/cogcoin/client](https://github.com/cogcoin/client)
89
+ - Bitcoin package: [npmjs.com/package/@cogcoin/bitcoin](https://www.npmjs.com/package/@cogcoin/bitcoin)
90
+ - Genesis package: [npmjs.com/package/@cogcoin/genesis](https://www.npmjs.com/package/@cogcoin/genesis)
91
+ - Indexer package: [npmjs.com/package/@cogcoin/indexer](https://www.npmjs.com/package/@cogcoin/indexer)
92
+ - Scoring package: [npmjs.com/package/@cogcoin/scoring](https://www.npmjs.com/package/@cogcoin/scoring)
37
93
 
38
94
  ## Dependency Surface
39
95
 
@@ -41,7 +97,7 @@ The published package depends on:
41
97
 
42
98
  - `@cogcoin/bitcoin@30.2.0`
43
99
  - `@cogcoin/genesis@1.0.0`
44
- - `@cogcoin/indexer@1.0.0`
100
+ - `@cogcoin/indexer@1.0.1`
45
101
  - `@cogcoin/scoring@1.0.0`
46
102
  - `@scure/base@^2.0.0`
47
103
  - `@scure/bip32@^2.0.1`
@@ -74,21 +130,20 @@ Managed node subpath:
74
130
 
75
131
  The installed `cogcoin` command covers the first-party local wallet and node workflow:
76
132
 
77
- - wallet lifecycle commands such as `init`, `restore`, `unlock`, `lock`, `repair`, `export`, and `import`
133
+ - wallet lifecycle commands such as `init`, `restore`, `wallet delete`, `wallet show-mnemonic`, and `repair`
78
134
  - sync and service commands such as `status`, `sync`, `follow`, `bitcoin start`, `bitcoin stop`, `bitcoin status`, `indexer start`, `indexer stop`, and `indexer status`
79
135
  - domain and field commands such as `register`, `anchor`, `show`, `domains`, `fields`, `buy`, `sell`, and `transfer`
80
136
  - COG and reputation commands such as `send`, `cog lock`, `claim`, `reclaim`, `rep give`, and `rep revoke`
81
- - mining and hook commands such as `mine`, `mine start`, `mine stop`, `mine status`, `mine log`, `mine setup`, and `hooks status`
137
+ - mining commands such as `mine`, `mine start`, `mine stop`, `mine status`, `mine log`, and `mine setup`
82
138
 
83
139
  The CLI also supports stable `--output json` and `--output preview-json` envelopes on the commands that advertise machine-readable output.
84
140
  Interactive text invocations periodically check the npm registry for newer `@cogcoin/client` releases and print `npm install -g @cogcoin/client` when a newer version is available.
85
141
  Set `COGCOIN_DISABLE_UPDATE_CHECK=1` to disable the CLI update notice entirely.
86
142
  Ordinary `sync`, `follow`, and wallet-aware read/status flows detach from the managed Bitcoin and indexer services on exit instead of stopping them.
87
143
  Use the explicit `bitcoin ...` and `indexer ...` commands when you want direct service inspection or start/stop control.
88
- For provider-backed local wallets, normal reads, mutations, export, and mining setup flows auto-materialize a local unlock session when the wallet is not explicitly locked.
144
+ For provider-backed local wallets, normal reads, mutations, and mining setup flows load local wallet state on demand whenever the local secret provider is available.
89
145
  `cogcoin restore` and `cogcoin wallet restore` rebuild a fresh local wallet from a 24-word English BIP39 mnemonic and recreate the managed Core wallet replica.
90
146
  Run `cogcoin sync` afterward to bootstrap the managed Bitcoin/indexer state.
91
- `cogcoin wallet import <path>` remains the richer encrypted-archive restore path that preserves more local continuity metadata than mnemonic-only restore.
92
147
 
93
148
  ## SQLite Store
94
149
 
@@ -8,7 +8,6 @@ export interface CogcoinResolvedPaths {
8
8
  configRoot: string;
9
9
  stateRoot: string;
10
10
  runtimeRoot: string;
11
- hooksRoot: string;
12
11
  bitcoinDataDir: string;
13
12
  clientDataDir: string;
14
13
  clientDatabasePath: string;
@@ -19,21 +18,21 @@ export interface CogcoinResolvedPaths {
19
18
  walletStateBackupPath: string;
20
19
  walletInitPendingPath: string;
21
20
  walletInitPendingBackupPath: string;
22
- walletUnlockSessionPath: string;
23
- walletExplicitLockPath: string;
24
21
  walletControlLockPath: string;
25
22
  bitcoindLockPath: string;
26
23
  bitcoindStatusPath: string;
27
24
  indexerDaemonLockPath: string;
28
25
  indexerStatusPath: string;
29
- hooksMiningDir: string;
30
- hooksMiningEntrypointPath: string;
31
- hooksMiningPackageJsonPath: string;
32
26
  miningRoot: string;
33
27
  miningStatusPath: string;
34
28
  miningEventsPath: string;
35
29
  miningControlLockPath: string;
36
30
  }
31
+ export declare function resolveLegacyHooksRootPath(options: {
32
+ dataRoot: string;
33
+ clientConfigPath: string;
34
+ platform?: NodeJS.Platform;
35
+ }): string;
37
36
  export declare function resolveCogcoinPathsForTesting(resolution?: CogcoinPathResolution): CogcoinResolvedPaths;
38
37
  export declare function resolveCogcoinAppRootForTesting(resolution?: CogcoinPathResolution): string;
39
38
  export declare function resolveDefaultBitcoindDataDirForTesting(resolution?: CogcoinPathResolution): string;
package/dist/app-paths.js CHANGED
@@ -21,9 +21,16 @@ function resolveLinuxRoots(env, homeDirectory) {
21
21
  configRoot,
22
22
  stateRoot,
23
23
  runtimeRoot,
24
- hooksRoot: join(configRoot, "hooks"),
25
24
  };
26
25
  }
26
+ export function resolveLegacyHooksRootPath(options) {
27
+ const platform = options.platform ?? process.platform;
28
+ if (platform === "darwin" || platform === "win32") {
29
+ return joinForPlatform(platform, options.dataRoot, "hooks");
30
+ }
31
+ const configDirectory = dirname(options.clientConfigPath);
32
+ return joinForPlatform(platform, configDirectory, "hooks");
33
+ }
27
34
  export function resolveCogcoinPathsForTesting(resolution = {}) {
28
35
  const platform = resolution.platform ?? process.platform;
29
36
  const env = resolution.env ?? process.env;
@@ -32,20 +39,17 @@ export function resolveCogcoinPathsForTesting(resolution = {}) {
32
39
  let configRoot;
33
40
  let stateRoot;
34
41
  let runtimeRoot;
35
- let hooksRoot;
36
42
  if (platform === "darwin") {
37
43
  dataRoot = join(homeDirectory, "Library", "Application Support", "Cogcoin");
38
44
  configRoot = join(dataRoot, "config");
39
45
  stateRoot = join(dataRoot, "state");
40
46
  runtimeRoot = join(dataRoot, "runtime");
41
- hooksRoot = join(dataRoot, "hooks");
42
47
  }
43
48
  else if (platform === "win32") {
44
49
  dataRoot = win32Path.join(resolveLocalAppDataWindows(env, homeDirectory), "Cogcoin");
45
50
  configRoot = win32Path.join(dataRoot, "config");
46
51
  stateRoot = win32Path.join(dataRoot, "state");
47
52
  runtimeRoot = win32Path.join(dataRoot, "runtime");
48
- hooksRoot = win32Path.join(dataRoot, "hooks");
49
53
  }
50
54
  else {
51
55
  const linuxRoots = resolveLinuxRoots(env, homeDirectory);
@@ -53,7 +57,6 @@ export function resolveCogcoinPathsForTesting(resolution = {}) {
53
57
  configRoot = linuxRoots.configRoot;
54
58
  stateRoot = linuxRoots.stateRoot;
55
59
  runtimeRoot = linuxRoots.runtimeRoot;
56
- hooksRoot = linuxRoots.hooksRoot;
57
60
  }
58
61
  const bitcoinDataDir = joinForPlatform(platform, dataRoot, "bitcoin");
59
62
  const clientDataDir = joinForPlatform(platform, dataRoot, "client");
@@ -65,16 +68,11 @@ export function resolveCogcoinPathsForTesting(resolution = {}) {
65
68
  const walletStateBackupPath = joinForPlatform(platform, walletStateDirectory, "wallet-state.enc.bak");
66
69
  const walletInitPendingPath = joinForPlatform(platform, walletStateDirectory, "wallet-init-pending.enc");
67
70
  const walletInitPendingBackupPath = joinForPlatform(platform, walletStateDirectory, "wallet-init-pending.enc.bak");
68
- const walletUnlockSessionPath = joinForPlatform(platform, runtimeRoot, "wallet-unlock-session.enc");
69
- const walletExplicitLockPath = joinForPlatform(platform, runtimeRoot, "wallet-explicit-lock.json");
70
71
  const walletControlLockPath = joinForPlatform(platform, runtimeRoot, "wallet-control.lock");
71
72
  const bitcoindLockPath = joinForPlatform(platform, runtimeRoot, "bitcoind.lock");
72
73
  const bitcoindStatusPath = joinForPlatform(platform, runtimeRoot, "bitcoind-status.json");
73
74
  const indexerDaemonLockPath = joinForPlatform(platform, runtimeRoot, "indexer-daemon.lock");
74
75
  const indexerStatusPath = joinForPlatform(platform, indexerRoot, "status.json");
75
- const hooksMiningDir = joinForPlatform(platform, hooksRoot, "mining");
76
- const hooksMiningEntrypointPath = joinForPlatform(platform, hooksMiningDir, "generate-sentences.js");
77
- const hooksMiningPackageJsonPath = joinForPlatform(platform, hooksMiningDir, "package.json");
78
76
  const miningRoot = joinForPlatform(platform, runtimeRoot, "mining");
79
77
  const miningStatusPath = joinForPlatform(platform, miningRoot, "status.json");
80
78
  const miningEventsPath = joinForPlatform(platform, miningRoot, "events.jsonl");
@@ -84,7 +82,6 @@ export function resolveCogcoinPathsForTesting(resolution = {}) {
84
82
  configRoot,
85
83
  stateRoot,
86
84
  runtimeRoot,
87
- hooksRoot,
88
85
  bitcoinDataDir,
89
86
  clientDataDir,
90
87
  clientDatabasePath,
@@ -95,16 +92,11 @@ export function resolveCogcoinPathsForTesting(resolution = {}) {
95
92
  walletStateBackupPath,
96
93
  walletInitPendingPath,
97
94
  walletInitPendingBackupPath,
98
- walletUnlockSessionPath,
99
- walletExplicitLockPath,
100
95
  walletControlLockPath,
101
96
  bitcoindLockPath,
102
97
  bitcoindStatusPath,
103
98
  indexerDaemonLockPath,
104
99
  indexerStatusPath,
105
- hooksMiningDir,
106
- hooksMiningEntrypointPath,
107
- hooksMiningPackageJsonPath,
108
100
  miningRoot,
109
101
  miningStatusPath,
110
102
  miningEventsPath,
@@ -0,0 +1,10 @@
1
+ ⛭ Behold, your Cogcoin wallet. ⛭
2
+ ▐▀▀▀▀▀▀▀▀▚ ╔──────────────────────────────────────────────────────────────────╗
3
+ ▛▞▀▀▀▀▀▀▀▀▚ │ │
4
+ ▌▝▀▀▀▀▀▀▀▀▀▌│ Funding address: │
5
+ ▌ ▗▙▙ ▌│ │
6
+ ▌ ▐ ▌ ▌│ Bitcoin Balance: │
7
+ ▌ ▐▀▀▚ ▌│ Cogcoin Balance: │
8
+ ▌ ▐▄▄▞ ▌│ │
9
+ ▌ ▘▘ ▌│ mempool.space/address/ |
10
+ ▝▀▀▀▀▀▀▀▀▀▀▘╚──────────────────────────────────────────────────────────────────╝
@@ -0,0 +1,16 @@
1
+ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
2
+ ▄▀ ▀▄
3
+ █ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄ █ Welcome to...
4
+ █ █ █ █
5
+ █ █ █ █ █ █ █ █████ █████ █████ █████ █████ ██ ███ ██
6
+ █ █ █ █ █ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
7
+ █ █ ▄█ █ █ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██
8
+ █ █ ▄ ▄ █ █ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
9
+ █ █ ▀▀▀▀ █ █ █████ █████ █████ █████ █████ ██ ██ ████
10
+ █ ▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀ █
11
+ █ █ ┏┳┓╻┏┓╻┏━╸ ╻ ╻╻╺┳╸╻ ╻ ╻ ╻┏━┓┏━┓╺┳┓┏━┓
12
+ █ █ ┃┃┃┃┃┗┫┣╸ ┃╻┃┃ ┃ ┣━┫ ┃╻┃┃ ┃┣┳┛ ┃┃┗━┓
13
+ █ ▄▄ ▄▄▄▄▄▄ █ ╹ ╹╹╹ ╹┗━╸ ┗┻┛╹ ╹ ╹ ╹ ┗┻┛┗━┛╹┗╸╺┻┛┗━┛
14
+ █ █
15
+ ▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▀ We are so happy to have you here!
16
+ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
@@ -36,5 +36,6 @@ export declare class AssumeUtxoBootstrapController {
36
36
  lastError: string | null;
37
37
  updatedAt: number;
38
38
  }>;
39
+ cleanupObsoleteSnapshotFilesIfNeeded(): Promise<boolean>;
39
40
  }
40
41
  export {};
@@ -5,6 +5,7 @@ import { DEFAULT_SNAPSHOT_METADATA } from "./constants.js";
5
5
  import { downloadSnapshotFileForTesting } from "./download.js";
6
6
  import { waitForHeaders } from "./headers.js";
7
7
  import { resolveBootstrapPaths } from "./paths.js";
8
+ import { resetSnapshotFiles } from "./snapshot-file.js";
8
9
  import { loadBootstrapStateRecord, saveBootstrapState } from "./state.js";
9
10
  import { findLoadedSnapshotChainState, isSnapshotAlreadyLoaded } from "./chainstate.js";
10
11
  import { describeManagedRpcRetryError, isRetryableManagedRpcError, } from "../retryable-rpc.js";
@@ -54,7 +55,8 @@ export class AssumeUtxoBootstrapController {
54
55
  return;
55
56
  }
56
57
  const { state, snapshotIdentity } = await this.#loadStateRecord();
57
- if (state.loadTxOutSetComplete && await isSnapshotAlreadyLoaded(this.#rpc, this.#snapshot, state)) {
58
+ const lifecycle = await this.#probeSnapshotLifecycle(state);
59
+ if (lifecycle.lifecycle === "snapshot-active") {
58
60
  if (state.lastError !== null) {
59
61
  state.lastError = null;
60
62
  await saveBootstrapState(this.#paths, state);
@@ -69,6 +71,25 @@ export class AssumeUtxoBootstrapController {
69
71
  });
70
72
  return;
71
73
  }
74
+ if (lifecycle.lifecycle === "snapshot-obsolete") {
75
+ await this.#deleteSnapshotArtifactsBestEffort();
76
+ if (state.lastError !== null || state.phase !== "bitcoin_sync") {
77
+ state.phase = "bitcoin_sync";
78
+ state.lastError = null;
79
+ await saveBootstrapState(this.#paths, state);
80
+ }
81
+ const info = await this.#rpc.getBlockchainInfo();
82
+ await this.#progress.setPhase("bitcoin_sync", {
83
+ blocks: info.blocks,
84
+ headers: info.headers,
85
+ targetHeight: info.headers,
86
+ baseHeight: state.baseHeight,
87
+ tipHashHex: state.tipHashHex,
88
+ message: "Bitcoin Core is syncing blocks after assumeutxo bootstrap.",
89
+ lastError: null,
90
+ });
91
+ return;
92
+ }
72
93
  await downloadSnapshotFileForTesting({
73
94
  fetchImpl: this.#fetchImpl,
74
95
  manifest: this.#manifest,
@@ -137,6 +158,20 @@ export class AssumeUtxoBootstrapController {
137
158
  async getStateForTesting() {
138
159
  return { ...(await this.#loadState()) };
139
160
  }
161
+ async cleanupObsoleteSnapshotFilesIfNeeded() {
162
+ try {
163
+ const { state } = await this.#loadStateRecord();
164
+ const lifecycle = await this.#probeSnapshotLifecycle(state);
165
+ if (lifecycle.lifecycle !== "snapshot-obsolete") {
166
+ return false;
167
+ }
168
+ await this.#deleteSnapshotArtifactsBestEffort();
169
+ return true;
170
+ }
171
+ catch {
172
+ return false;
173
+ }
174
+ }
140
175
  async #loadState() {
141
176
  return (await this.#loadStateRecord()).state;
142
177
  }
@@ -144,4 +179,21 @@ export class AssumeUtxoBootstrapController {
144
179
  this.#stateRecordPromise ??= loadBootstrapStateRecord(this.#paths, this.#snapshot);
145
180
  return this.#stateRecordPromise;
146
181
  }
182
+ async #probeSnapshotLifecycle(state) {
183
+ if (!state.loadTxOutSetComplete) {
184
+ return {
185
+ state,
186
+ lifecycle: "bootstrap-pending",
187
+ };
188
+ }
189
+ return {
190
+ state,
191
+ lifecycle: await isSnapshotAlreadyLoaded(this.#rpc, this.#snapshot, state)
192
+ ? "snapshot-active"
193
+ : "snapshot-obsolete",
194
+ };
195
+ }
196
+ async #deleteSnapshotArtifactsBestEffort() {
197
+ await resetSnapshotFiles(this.#paths).catch(() => undefined);
198
+ }
147
199
  }
@@ -1,5 +1,6 @@
1
1
  import type { Client, ClientStoreAdapter } from "../../types.js";
2
2
  import type { BitcoinRpcClient } from "../rpc.js";
3
+ export declare const FOLLOW_VISIBLE_PRIOR_BLOCKS = 4;
3
4
  export declare function loadVisibleFollowBlockTimes(options: {
4
5
  tip: Awaited<ReturnType<Client["getTip"]>>;
5
6
  startHeight: number;
@@ -1,4 +1,4 @@
1
- const FOLLOW_VISIBLE_PRIOR_BLOCKS = 4;
1
+ export const FOLLOW_VISIBLE_PRIOR_BLOCKS = 4;
2
2
  export async function loadVisibleFollowBlockTimes(options) {
3
3
  const { tip, startHeight, store, rpc } = options;
4
4
  if (tip === null) {
@@ -1,4 +1,4 @@
1
- import type { Client, ClientStoreAdapter } from "../../types.js";
1
+ import type { Client, ClientCheckpoint, ClientStoreAdapter, ClientTip } from "../../types.js";
2
2
  import type { AssumeUtxoBootstrapController } from "../bootstrap.js";
3
3
  import type { ManagedProgressController } from "../progress.js";
4
4
  import type { BitcoinRpcClient } from "../rpc.js";
@@ -8,13 +8,17 @@ export interface SyncPassResult {
8
8
  rewoundBlocks: number;
9
9
  commonAncestorHeight: number | null;
10
10
  }
11
+ export interface SyncRecoveryClient extends Client {
12
+ restoreCheckpoint(checkpoint: ClientCheckpoint): Promise<ClientTip>;
13
+ resetToInitialState(): Promise<null>;
14
+ }
11
15
  export interface BlockRateTracker {
12
16
  lastHeight: number | null;
13
17
  lastUpdatedAt: number | null;
14
18
  blocksPerSecond: number | null;
15
19
  }
16
20
  export interface SyncEngineDependencies {
17
- client: Client;
21
+ client: SyncRecoveryClient;
18
22
  store: ClientStoreAdapter;
19
23
  node: ManagedBitcoindNodeHandle;
20
24
  rpc: BitcoinRpcClient;
@@ -26,7 +30,7 @@ export interface SyncEngineDependencies {
26
30
  cogcoinRateTracker: BlockRateTracker;
27
31
  abortSignal?: AbortSignal;
28
32
  isFollowing(): boolean;
29
- loadVisibleFollowBlockTimes(tip: Awaited<ReturnType<Client["getTip"]>>): Promise<Record<number, number>>;
33
+ loadVisibleFollowBlockTimes(tip: Awaited<ReturnType<SyncRecoveryClient["getTip"]>>): Promise<Record<number, number>>;
30
34
  }
31
35
  export interface FollowLoopSubscriber extends AsyncIterable<unknown> {
32
36
  close(): void;
@@ -1,13 +1,14 @@
1
1
  import type { BitcoinBlock } from "@cogcoin/indexer/types";
2
- import type { Client, ClientStoreAdapter } from "../../types.js";
2
+ import type { ClientStoreAdapter } from "../../types.js";
3
3
  import { AssumeUtxoBootstrapController } from "../bootstrap.js";
4
4
  import type { IndexerDaemonClient } from "../indexer-daemon.js";
5
5
  import type { ManagedProgressController } from "../progress.js";
6
6
  import type { BitcoinRpcClient } from "../rpc.js";
7
7
  import type { ManagedBitcoindClient, ManagedBitcoindNodeHandle, ManagedBitcoindStatus, SyncResult } from "../types.js";
8
+ import { type SyncRecoveryClient } from "./internal-types.js";
8
9
  export declare class DefaultManagedBitcoindClient implements ManagedBitcoindClient {
9
10
  #private;
10
- constructor(client: Client, store: ClientStoreAdapter, node: ManagedBitcoindNodeHandle, rpc: BitcoinRpcClient, progress: ManagedProgressController, bootstrap: AssumeUtxoBootstrapController, indexerDaemon: IndexerDaemonClient | null, reattachIndexerDaemon: (() => Promise<IndexerDaemonClient | null>) | null, startHeight: number, syncDebounceMs: number, dataDir: string, walletRootId: string, startupTimeoutMs: number | undefined, shutdownTimeoutMs: number | undefined, fetchImpl: typeof fetch | undefined);
11
+ constructor(client: SyncRecoveryClient, store: ClientStoreAdapter, node: ManagedBitcoindNodeHandle, rpc: BitcoinRpcClient, progress: ManagedProgressController, bootstrap: AssumeUtxoBootstrapController, indexerDaemon: IndexerDaemonClient | null, reattachIndexerDaemon: (() => Promise<IndexerDaemonClient | null>) | null, startHeight: number, syncDebounceMs: number, dataDir: string, walletRootId: string, startupTimeoutMs: number | undefined, shutdownTimeoutMs: number | undefined, fetchImpl: typeof fetch | undefined);
11
12
  getTip(): Promise<import("../../types.js").ClientTip | null>;
12
13
  getState(): Promise<import("@cogcoin/indexer/types").IndexerState>;
13
14
  applyBlock(block: BitcoinBlock): Promise<import("../../types.js").ApplyBlockResult>;
@@ -17,4 +18,5 @@ export declare class DefaultManagedBitcoindClient implements ManagedBitcoindClie
17
18
  getNodeStatus(): Promise<ManagedBitcoindStatus>;
18
19
  close(): Promise<void>;
19
20
  playSyncCompletionScene(): Promise<void>;
21
+ detachToBackgroundFollow(): Promise<void>;
20
22
  }
@@ -45,6 +45,7 @@ export class DefaultManagedBitcoindClient {
45
45
  #syncPromise = Promise.resolve(createInitialSyncResult());
46
46
  #debounceTimer = null;
47
47
  #syncAbortControllers = new Set();
48
+ #backgroundFollowResumed = false;
48
49
  constructor(client, store, node, rpc, progress, bootstrap, indexerDaemon, reattachIndexerDaemon, startHeight, syncDebounceMs, dataDir, walletRootId, startupTimeoutMs, shutdownTimeoutMs, fetchImpl) {
49
50
  this.#client = client;
50
51
  this.#store = store;
@@ -198,11 +199,18 @@ export class DefaultManagedBitcoindClient {
198
199
  await this.#client.close();
199
200
  await this.#resumeIndexerBackgroundFollow();
200
201
  await this.#indexerDaemon?.close();
202
+ this.#indexerDaemon = null;
201
203
  }
202
204
  async playSyncCompletionScene() {
203
205
  this.#assertOpen();
204
206
  await this.#progress.playCompletionScene();
205
207
  }
208
+ async detachToBackgroundFollow() {
209
+ this.#assertOpen();
210
+ await this.#resumeIndexerBackgroundFollow();
211
+ await this.#indexerDaemon?.close();
212
+ this.#indexerDaemon = null;
213
+ }
206
214
  async #setGetblockStatusMessage(currentHeight, message, targetHeight = currentHeight) {
207
215
  const safeTargetHeight = Math.max(currentHeight, targetHeight);
208
216
  await this.#progress.setPhase("bitcoin_sync", {
@@ -397,12 +405,17 @@ export class DefaultManagedBitcoindClient {
397
405
  }
398
406
  }
399
407
  async #resumeIndexerBackgroundFollow() {
408
+ if (this.#backgroundFollowResumed) {
409
+ return;
410
+ }
400
411
  if (this.#indexerDaemon === null && this.#reattachIndexerDaemon === null) {
412
+ this.#backgroundFollowResumed = true;
401
413
  return;
402
414
  }
403
415
  if (this.#indexerDaemon !== null) {
404
416
  try {
405
417
  await this.#indexerDaemon.resumeBackgroundFollow();
418
+ this.#backgroundFollowResumed = true;
406
419
  return;
407
420
  }
408
421
  catch (error) {
@@ -418,5 +431,6 @@ export class DefaultManagedBitcoindClient {
418
431
  const replacementDaemon = await reattachIndexerDaemon();
419
432
  this.#indexerDaemon = replacementDaemon;
420
433
  await replacementDaemon?.resumeBackgroundFollow();
434
+ this.#backgroundFollowResumed = true;
421
435
  }
422
436
  }