@cogcoin/client 0.5.0
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.
- package/LICENSE +21 -0
- package/README.md +136 -0
- package/dist/app-paths.d.ts +38 -0
- package/dist/app-paths.js +121 -0
- package/dist/art/banner.txt +13 -0
- package/dist/art/scroll.txt +13 -0
- package/dist/art/train-car.txt +6 -0
- package/dist/art/train-smoke.txt +6 -0
- package/dist/art/train.txt +6 -0
- package/dist/bitcoind/bootstrap/chainstate.d.ts +4 -0
- package/dist/bitcoind/bootstrap/chainstate.js +13 -0
- package/dist/bitcoind/bootstrap/constants.d.ts +7 -0
- package/dist/bitcoind/bootstrap/constants.js +12 -0
- package/dist/bitcoind/bootstrap/controller.d.ts +29 -0
- package/dist/bitcoind/bootstrap/controller.js +101 -0
- package/dist/bitcoind/bootstrap/download.d.ts +2 -0
- package/dist/bitcoind/bootstrap/download.js +196 -0
- package/dist/bitcoind/bootstrap/headers.d.ts +13 -0
- package/dist/bitcoind/bootstrap/headers.js +61 -0
- package/dist/bitcoind/bootstrap/paths.d.ts +4 -0
- package/dist/bitcoind/bootstrap/paths.js +15 -0
- package/dist/bitcoind/bootstrap/snapshot-file.d.ts +7 -0
- package/dist/bitcoind/bootstrap/snapshot-file.js +42 -0
- package/dist/bitcoind/bootstrap/state.d.ts +40 -0
- package/dist/bitcoind/bootstrap/state.js +70 -0
- package/dist/bitcoind/bootstrap/types.d.ts +28 -0
- package/dist/bitcoind/bootstrap/types.js +1 -0
- package/dist/bitcoind/bootstrap.d.ts +8 -0
- package/dist/bitcoind/bootstrap.js +7 -0
- package/dist/bitcoind/client/factory.d.ts +3 -0
- package/dist/bitcoind/client/factory.js +57 -0
- package/dist/bitcoind/client/follow-block-times.d.ts +8 -0
- package/dist/bitcoind/client/follow-block-times.js +25 -0
- package/dist/bitcoind/client/follow-loop.d.ts +10 -0
- package/dist/bitcoind/client/follow-loop.js +57 -0
- package/dist/bitcoind/client/internal-types.d.ts +63 -0
- package/dist/bitcoind/client/internal-types.js +18 -0
- package/dist/bitcoind/client/managed-client.d.ts +20 -0
- package/dist/bitcoind/client/managed-client.js +197 -0
- package/dist/bitcoind/client/rate-tracker.d.ts +2 -0
- package/dist/bitcoind/client/rate-tracker.js +24 -0
- package/dist/bitcoind/client/sync-engine.d.ts +3 -0
- package/dist/bitcoind/client/sync-engine.js +143 -0
- package/dist/bitcoind/client.d.ts +1 -0
- package/dist/bitcoind/client.js +1 -0
- package/dist/bitcoind/errors.d.ts +1 -0
- package/dist/bitcoind/errors.js +49 -0
- package/dist/bitcoind/index.d.ts +2 -0
- package/dist/bitcoind/index.js +1 -0
- package/dist/bitcoind/indexer-daemon-main.d.ts +1 -0
- package/dist/bitcoind/indexer-daemon-main.js +472 -0
- package/dist/bitcoind/indexer-daemon.d.ts +107 -0
- package/dist/bitcoind/indexer-daemon.js +391 -0
- package/dist/bitcoind/node.d.ts +8 -0
- package/dist/bitcoind/node.js +219 -0
- package/dist/bitcoind/normalize.d.ts +3 -0
- package/dist/bitcoind/normalize.js +47 -0
- package/dist/bitcoind/progress/assets.d.ts +10 -0
- package/dist/bitcoind/progress/assets.js +90 -0
- package/dist/bitcoind/progress/constants.d.ts +48 -0
- package/dist/bitcoind/progress/constants.js +53 -0
- package/dist/bitcoind/progress/controller.d.ts +28 -0
- package/dist/bitcoind/progress/controller.js +188 -0
- package/dist/bitcoind/progress/follow-scene.d.ts +40 -0
- package/dist/bitcoind/progress/follow-scene.js +367 -0
- package/dist/bitcoind/progress/formatting.d.ts +23 -0
- package/dist/bitcoind/progress/formatting.js +227 -0
- package/dist/bitcoind/progress/quote-scene.d.ts +4 -0
- package/dist/bitcoind/progress/quote-scene.js +137 -0
- package/dist/bitcoind/progress/train-scene.d.ts +9 -0
- package/dist/bitcoind/progress/train-scene.js +92 -0
- package/dist/bitcoind/progress/tty-renderer.d.ts +18 -0
- package/dist/bitcoind/progress/tty-renderer.js +150 -0
- package/dist/bitcoind/progress.d.ts +7 -0
- package/dist/bitcoind/progress.js +7 -0
- package/dist/bitcoind/quotes.d.ts +24 -0
- package/dist/bitcoind/quotes.js +195 -0
- package/dist/bitcoind/rpc.d.ts +71 -0
- package/dist/bitcoind/rpc.js +322 -0
- package/dist/bitcoind/service-paths.d.ts +19 -0
- package/dist/bitcoind/service-paths.js +49 -0
- package/dist/bitcoind/service.d.ts +40 -0
- package/dist/bitcoind/service.js +735 -0
- package/dist/bitcoind/testing.d.ts +9 -0
- package/dist/bitcoind/testing.js +9 -0
- package/dist/bitcoind/types.d.ts +396 -0
- package/dist/bitcoind/types.js +3 -0
- package/dist/bytes.d.ts +9 -0
- package/dist/bytes.js +36 -0
- package/dist/cli/commands/follow.d.ts +2 -0
- package/dist/cli/commands/follow.js +43 -0
- package/dist/cli/commands/mining-admin.d.ts +2 -0
- package/dist/cli/commands/mining-admin.js +92 -0
- package/dist/cli/commands/mining-read.d.ts +2 -0
- package/dist/cli/commands/mining-read.js +173 -0
- package/dist/cli/commands/mining-runtime.d.ts +2 -0
- package/dist/cli/commands/mining-runtime.js +108 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.js +31 -0
- package/dist/cli/commands/sync.d.ts +2 -0
- package/dist/cli/commands/sync.js +52 -0
- package/dist/cli/commands/wallet-admin.d.ts +2 -0
- package/dist/cli/commands/wallet-admin.js +175 -0
- package/dist/cli/commands/wallet-mutation.d.ts +2 -0
- package/dist/cli/commands/wallet-mutation.js +681 -0
- package/dist/cli/commands/wallet-read.d.ts +2 -0
- package/dist/cli/commands/wallet-read.js +265 -0
- package/dist/cli/context.d.ts +3 -0
- package/dist/cli/context.js +75 -0
- package/dist/cli/io.d.ts +3 -0
- package/dist/cli/io.js +12 -0
- package/dist/cli/mining-format.d.ts +5 -0
- package/dist/cli/mining-format.js +156 -0
- package/dist/cli/mining-json.d.ts +49 -0
- package/dist/cli/mining-json.js +89 -0
- package/dist/cli/mutation-command-groups.d.ts +15 -0
- package/dist/cli/mutation-command-groups.js +71 -0
- package/dist/cli/mutation-json.d.ts +430 -0
- package/dist/cli/mutation-json.js +311 -0
- package/dist/cli/mutation-resolved-json.d.ts +124 -0
- package/dist/cli/mutation-resolved-json.js +129 -0
- package/dist/cli/mutation-success.d.ts +20 -0
- package/dist/cli/mutation-success.js +47 -0
- package/dist/cli/mutation-text-format.d.ts +22 -0
- package/dist/cli/mutation-text-format.js +171 -0
- package/dist/cli/mutation-text-write.d.ts +13 -0
- package/dist/cli/mutation-text-write.js +16 -0
- package/dist/cli/output.d.ts +185 -0
- package/dist/cli/output.js +1085 -0
- package/dist/cli/parse.d.ts +3 -0
- package/dist/cli/parse.js +971 -0
- package/dist/cli/preview-json.d.ts +416 -0
- package/dist/cli/preview-json.js +293 -0
- package/dist/cli/prompt.d.ts +3 -0
- package/dist/cli/prompt.js +33 -0
- package/dist/cli/read-json.d.ts +187 -0
- package/dist/cli/read-json.js +675 -0
- package/dist/cli/runner.d.ts +2 -0
- package/dist/cli/runner.js +129 -0
- package/dist/cli/signals.d.ts +3 -0
- package/dist/cli/signals.js +63 -0
- package/dist/cli/status-format.d.ts +2 -0
- package/dist/cli/status-format.js +48 -0
- package/dist/cli/types.d.ts +148 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/wallet-format.d.ts +29 -0
- package/dist/cli/wallet-format.js +637 -0
- package/dist/cli/workflow-hints.d.ts +13 -0
- package/dist/cli/workflow-hints.js +94 -0
- package/dist/cli-runner.d.ts +3 -0
- package/dist/cli-runner.js +3 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +6 -0
- package/dist/client/default-client.d.ts +11 -0
- package/dist/client/default-client.js +118 -0
- package/dist/client/factory.d.ts +2 -0
- package/dist/client/factory.js +15 -0
- package/dist/client/initialization.d.ts +6 -0
- package/dist/client/initialization.js +30 -0
- package/dist/client/persistence.d.ts +5 -0
- package/dist/client/persistence.js +28 -0
- package/dist/client/store-adapter.d.ts +3 -0
- package/dist/client/store-adapter.js +20 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/passive-status.d.ts +36 -0
- package/dist/passive-status.js +100 -0
- package/dist/sqlite/better-sqlite3.d.ts +26 -0
- package/dist/sqlite/better-sqlite3.js +4 -0
- package/dist/sqlite/checkpoints.d.ts +11 -0
- package/dist/sqlite/checkpoints.js +27 -0
- package/dist/sqlite/driver.d.ts +17 -0
- package/dist/sqlite/driver.js +98 -0
- package/dist/sqlite/index.d.ts +4 -0
- package/dist/sqlite/index.js +9 -0
- package/dist/sqlite/migrate.d.ts +2 -0
- package/dist/sqlite/migrate.js +37 -0
- package/dist/sqlite/store.d.ts +3 -0
- package/dist/sqlite/store.js +122 -0
- package/dist/sqlite/tip-meta.d.ts +26 -0
- package/dist/sqlite/tip-meta.js +97 -0
- package/dist/sqlite/types.d.ts +10 -0
- package/dist/sqlite/types.js +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.js +1 -0
- package/dist/wallet/archive.d.ts +4 -0
- package/dist/wallet/archive.js +39 -0
- package/dist/wallet/cogop/constants.d.ts +32 -0
- package/dist/wallet/cogop/constants.js +32 -0
- package/dist/wallet/cogop/index.d.ts +32 -0
- package/dist/wallet/cogop/index.js +213 -0
- package/dist/wallet/cogop/numeric.d.ts +3 -0
- package/dist/wallet/cogop/numeric.js +24 -0
- package/dist/wallet/cogop/scriptpubkey.d.ts +2 -0
- package/dist/wallet/cogop/scriptpubkey.js +13 -0
- package/dist/wallet/cogop/validate-name.d.ts +2 -0
- package/dist/wallet/cogop/validate-name.js +18 -0
- package/dist/wallet/fs/atomic.d.ts +6 -0
- package/dist/wallet/fs/atomic.js +46 -0
- package/dist/wallet/fs/lock.d.ts +19 -0
- package/dist/wallet/fs/lock.js +61 -0
- package/dist/wallet/fs/status-file.d.ts +1 -0
- package/dist/wallet/fs/status-file.js +4 -0
- package/dist/wallet/lifecycle.d.ts +193 -0
- package/dist/wallet/lifecycle.js +1475 -0
- package/dist/wallet/material.d.ts +45 -0
- package/dist/wallet/material.js +118 -0
- package/dist/wallet/mining/config.d.ts +18 -0
- package/dist/wallet/mining/config.js +44 -0
- package/dist/wallet/mining/constants.d.ts +24 -0
- package/dist/wallet/mining/constants.js +24 -0
- package/dist/wallet/mining/control.d.ts +53 -0
- package/dist/wallet/mining/control.js +758 -0
- package/dist/wallet/mining/coordination.d.ts +40 -0
- package/dist/wallet/mining/coordination.js +121 -0
- package/dist/wallet/mining/hook-protocol.d.ts +47 -0
- package/dist/wallet/mining/hook-protocol.js +161 -0
- package/dist/wallet/mining/hook-runner.d.ts +1 -0
- package/dist/wallet/mining/hook-runner.js +52 -0
- package/dist/wallet/mining/hooks.d.ts +38 -0
- package/dist/wallet/mining/hooks.js +520 -0
- package/dist/wallet/mining/index.d.ts +8 -0
- package/dist/wallet/mining/index.js +6 -0
- package/dist/wallet/mining/runner.d.ts +155 -0
- package/dist/wallet/mining/runner.js +2574 -0
- package/dist/wallet/mining/runtime-artifacts.d.ts +17 -0
- package/dist/wallet/mining/runtime-artifacts.js +166 -0
- package/dist/wallet/mining/sentences.d.ts +23 -0
- package/dist/wallet/mining/sentences.js +281 -0
- package/dist/wallet/mining/state.d.ts +9 -0
- package/dist/wallet/mining/state.js +75 -0
- package/dist/wallet/mining/types.d.ts +141 -0
- package/dist/wallet/mining/types.js +1 -0
- package/dist/wallet/mining/visualizer.d.ts +19 -0
- package/dist/wallet/mining/visualizer.js +134 -0
- package/dist/wallet/mining/worker-main.d.ts +1 -0
- package/dist/wallet/mining/worker-main.js +17 -0
- package/dist/wallet/read/context.d.ts +20 -0
- package/dist/wallet/read/context.js +532 -0
- package/dist/wallet/read/filter.d.ts +9 -0
- package/dist/wallet/read/filter.js +42 -0
- package/dist/wallet/read/index.d.ts +4 -0
- package/dist/wallet/read/index.js +3 -0
- package/dist/wallet/read/project.d.ts +11 -0
- package/dist/wallet/read/project.js +300 -0
- package/dist/wallet/read/types.d.ts +144 -0
- package/dist/wallet/read/types.js +1 -0
- package/dist/wallet/runtime.d.ts +26 -0
- package/dist/wallet/runtime.js +28 -0
- package/dist/wallet/state/crypto.d.ts +31 -0
- package/dist/wallet/state/crypto.js +127 -0
- package/dist/wallet/state/provider.d.ts +37 -0
- package/dist/wallet/state/provider.js +312 -0
- package/dist/wallet/state/session.d.ts +12 -0
- package/dist/wallet/state/session.js +23 -0
- package/dist/wallet/state/storage.d.ts +19 -0
- package/dist/wallet/state/storage.js +55 -0
- package/dist/wallet/tx/anchor.d.ts +40 -0
- package/dist/wallet/tx/anchor.js +1210 -0
- package/dist/wallet/tx/cog.d.ts +92 -0
- package/dist/wallet/tx/cog.js +1055 -0
- package/dist/wallet/tx/common.d.ts +89 -0
- package/dist/wallet/tx/common.js +156 -0
- package/dist/wallet/tx/confirm.d.ts +15 -0
- package/dist/wallet/tx/confirm.js +24 -0
- package/dist/wallet/tx/domain-admin.d.ts +105 -0
- package/dist/wallet/tx/domain-admin.js +869 -0
- package/dist/wallet/tx/domain-market.d.ts +112 -0
- package/dist/wallet/tx/domain-market.js +1365 -0
- package/dist/wallet/tx/field.d.ts +101 -0
- package/dist/wallet/tx/field.js +1853 -0
- package/dist/wallet/tx/identity-selector.d.ts +12 -0
- package/dist/wallet/tx/identity-selector.js +52 -0
- package/dist/wallet/tx/index.d.ts +7 -0
- package/dist/wallet/tx/index.js +7 -0
- package/dist/wallet/tx/journal.d.ts +5 -0
- package/dist/wallet/tx/journal.js +31 -0
- package/dist/wallet/tx/register.d.ts +68 -0
- package/dist/wallet/tx/register.js +952 -0
- package/dist/wallet/tx/reputation.d.ts +72 -0
- package/dist/wallet/tx/reputation.js +693 -0
- package/dist/wallet/tx/targets.d.ts +7 -0
- package/dist/wallet/tx/targets.js +122 -0
- package/dist/wallet/types.d.ts +249 -0
- package/dist/wallet/types.js +1 -0
- package/dist/writing_quotes.json +1654 -0
- package/package.json +78 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { RpcDecodedPsbt, RpcFinalizePsbtResult, RpcListUnspentEntry, RpcLockedUnspent, RpcTestMempoolAcceptResult, RpcTransaction, RpcWalletCreateFundedPsbtResult, RpcWalletProcessPsbtResult } from "../../bitcoind/types.js";
|
|
2
|
+
import { type WalletSecretProvider } from "../state/provider.js";
|
|
3
|
+
import type { OutpointRecord, PendingMutationRecord, PendingMutationStatus, WalletStateV1 } from "../types.js";
|
|
4
|
+
import type { WalletReadContext } from "../read/index.js";
|
|
5
|
+
import type { WalletRuntimePaths } from "../runtime.js";
|
|
6
|
+
import { type MiningPreemptionHandle } from "../mining/coordination.js";
|
|
7
|
+
export declare const DEFAULT_WALLET_MUTATION_FEE_RATE_SAT_VB = 10;
|
|
8
|
+
export interface MutationSender {
|
|
9
|
+
localIndex: number;
|
|
10
|
+
scriptPubKeyHex: string;
|
|
11
|
+
address: string;
|
|
12
|
+
}
|
|
13
|
+
export interface WalletMutationRpcClient {
|
|
14
|
+
listUnspent(walletName: string, minConf?: number): Promise<RpcListUnspentEntry[]>;
|
|
15
|
+
listLockUnspent(walletName: string): Promise<RpcLockedUnspent[]>;
|
|
16
|
+
lockUnspent(walletName: string, unlock: boolean, outputs: RpcLockedUnspent[]): Promise<boolean>;
|
|
17
|
+
walletCreateFundedPsbt(walletName: string, inputs: Array<{
|
|
18
|
+
txid: string;
|
|
19
|
+
vout: number;
|
|
20
|
+
}>, outputs: unknown[], locktime: number, options: Record<string, unknown>, bip32Derivs?: boolean): Promise<RpcWalletCreateFundedPsbtResult>;
|
|
21
|
+
decodePsbt(psbt: string): Promise<RpcDecodedPsbt>;
|
|
22
|
+
walletProcessPsbt(walletName: string, psbt: string, sign?: boolean, sighashType?: string): Promise<RpcWalletProcessPsbtResult>;
|
|
23
|
+
finalizePsbt(psbt: string, extract?: boolean): Promise<RpcFinalizePsbtResult>;
|
|
24
|
+
decodeRawTransaction(hex: string): Promise<RpcTransaction>;
|
|
25
|
+
testMempoolAccept(rawTransactions: string[]): Promise<RpcTestMempoolAcceptResult[]>;
|
|
26
|
+
}
|
|
27
|
+
export interface BuiltWalletMutationTransaction {
|
|
28
|
+
funded: RpcWalletCreateFundedPsbtResult;
|
|
29
|
+
decoded: RpcDecodedPsbt;
|
|
30
|
+
psbt: string;
|
|
31
|
+
rawHex: string;
|
|
32
|
+
txid: string;
|
|
33
|
+
wtxid: string | null;
|
|
34
|
+
temporaryBuilderLockedOutpoints: OutpointRecord[];
|
|
35
|
+
}
|
|
36
|
+
export declare function saveWalletStatePreservingUnlock(options: {
|
|
37
|
+
state: WalletStateV1;
|
|
38
|
+
provider: WalletSecretProvider;
|
|
39
|
+
unlockUntilUnixMs: number;
|
|
40
|
+
nowUnixMs: number;
|
|
41
|
+
paths: WalletRuntimePaths;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
export declare function formatCogAmount(value: bigint): string;
|
|
44
|
+
export declare function outpointKey(outpoint: OutpointRecord): string;
|
|
45
|
+
export declare function updateMutationRecord(mutation: PendingMutationRecord, status: PendingMutationStatus, nowUnixMs: number, options?: {
|
|
46
|
+
attemptedTxid?: string | null;
|
|
47
|
+
attemptedWtxid?: string | null;
|
|
48
|
+
temporaryBuilderLockedOutpoints?: OutpointRecord[];
|
|
49
|
+
}): PendingMutationRecord;
|
|
50
|
+
export declare function unlockTemporaryBuilderLocks(rpc: Pick<WalletMutationRpcClient, "lockUnspent">, walletName: string, outpoints: OutpointRecord[]): Promise<void>;
|
|
51
|
+
export declare function diffTemporaryLockedOutpoints(before: RpcLockedUnspent[], after: RpcLockedUnspent[]): OutpointRecord[];
|
|
52
|
+
export declare function isBroadcastUnknownError(error: unknown): boolean;
|
|
53
|
+
export declare function isAlreadyAcceptedError(error: unknown): boolean;
|
|
54
|
+
export declare function assertWalletMutationContextReady(context: WalletReadContext, errorPrefix: string): asserts context is WalletReadContext & {
|
|
55
|
+
localState: {
|
|
56
|
+
availability: "ready";
|
|
57
|
+
state: WalletStateV1;
|
|
58
|
+
unlockUntilUnixMs: number;
|
|
59
|
+
};
|
|
60
|
+
snapshot: NonNullable<WalletReadContext["snapshot"]>;
|
|
61
|
+
model: NonNullable<WalletReadContext["model"]>;
|
|
62
|
+
};
|
|
63
|
+
export declare function pauseMiningForWalletMutation(options: {
|
|
64
|
+
paths: WalletRuntimePaths;
|
|
65
|
+
reason: string;
|
|
66
|
+
}): Promise<MiningPreemptionHandle>;
|
|
67
|
+
export declare function buildWalletMutationTransaction<TPlan>(options: {
|
|
68
|
+
rpc: WalletMutationRpcClient;
|
|
69
|
+
walletName: string;
|
|
70
|
+
plan: TPlan & {
|
|
71
|
+
inputs: Array<{
|
|
72
|
+
txid: string;
|
|
73
|
+
vout: number;
|
|
74
|
+
}>;
|
|
75
|
+
outputs: unknown[];
|
|
76
|
+
changeAddress: string;
|
|
77
|
+
changePosition: number;
|
|
78
|
+
};
|
|
79
|
+
validateFundedDraft(decoded: RpcDecodedPsbt, funded: RpcWalletCreateFundedPsbtResult, plan: TPlan): void;
|
|
80
|
+
finalizeErrorCode: string;
|
|
81
|
+
mempoolRejectPrefix: string;
|
|
82
|
+
feeRate?: number;
|
|
83
|
+
builderOptions?: {
|
|
84
|
+
addInputs?: boolean;
|
|
85
|
+
includeUnsafe?: boolean;
|
|
86
|
+
minConf?: number;
|
|
87
|
+
lockUnspents?: boolean;
|
|
88
|
+
};
|
|
89
|
+
}): Promise<BuiltWalletMutationTransaction>;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { saveUnlockSession } from "../state/session.js";
|
|
3
|
+
import { saveWalletState } from "../state/storage.js";
|
|
4
|
+
import { createWalletSecretReference, } from "../state/provider.js";
|
|
5
|
+
import { requestMiningGenerationPreemption } from "../mining/coordination.js";
|
|
6
|
+
export const DEFAULT_WALLET_MUTATION_FEE_RATE_SAT_VB = 10;
|
|
7
|
+
function createUnlockSessionState(state, unlockUntilUnixMs, nowUnixMs) {
|
|
8
|
+
return {
|
|
9
|
+
schemaVersion: 1,
|
|
10
|
+
walletRootId: state.walletRootId,
|
|
11
|
+
sessionId: randomBytes(16).toString("hex"),
|
|
12
|
+
createdAtUnixMs: nowUnixMs,
|
|
13
|
+
unlockUntilUnixMs,
|
|
14
|
+
sourceStateRevision: state.stateRevision,
|
|
15
|
+
wrappedSessionKeyMaterial: createWalletSecretReference(state.walletRootId).keyId,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export async function saveWalletStatePreservingUnlock(options) {
|
|
19
|
+
const secretReference = createWalletSecretReference(options.state.walletRootId);
|
|
20
|
+
await saveWalletState({
|
|
21
|
+
primaryPath: options.paths.walletStatePath,
|
|
22
|
+
backupPath: options.paths.walletStateBackupPath,
|
|
23
|
+
}, options.state, {
|
|
24
|
+
provider: options.provider,
|
|
25
|
+
secretReference,
|
|
26
|
+
});
|
|
27
|
+
await saveUnlockSession(options.paths.walletUnlockSessionPath, createUnlockSessionState(options.state, options.unlockUntilUnixMs, options.nowUnixMs), {
|
|
28
|
+
provider: options.provider,
|
|
29
|
+
secretReference,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function formatCogAmount(value) {
|
|
33
|
+
const sign = value < 0n ? "-" : "";
|
|
34
|
+
const absolute = value < 0n ? -value : value;
|
|
35
|
+
const whole = absolute / 100000000n;
|
|
36
|
+
const fraction = absolute % 100000000n;
|
|
37
|
+
return `${sign}${whole.toString()}.${fraction.toString().padStart(8, "0")} COG`;
|
|
38
|
+
}
|
|
39
|
+
export function outpointKey(outpoint) {
|
|
40
|
+
return `${outpoint.txid}:${outpoint.vout}`;
|
|
41
|
+
}
|
|
42
|
+
export function updateMutationRecord(mutation, status, nowUnixMs, options = {}) {
|
|
43
|
+
return {
|
|
44
|
+
...mutation,
|
|
45
|
+
status,
|
|
46
|
+
lastUpdatedAtUnixMs: nowUnixMs,
|
|
47
|
+
attemptedTxid: options.attemptedTxid ?? mutation.attemptedTxid,
|
|
48
|
+
attemptedWtxid: options.attemptedWtxid ?? mutation.attemptedWtxid,
|
|
49
|
+
temporaryBuilderLockedOutpoints: options.temporaryBuilderLockedOutpoints ?? mutation.temporaryBuilderLockedOutpoints,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export async function unlockTemporaryBuilderLocks(rpc, walletName, outpoints) {
|
|
53
|
+
if (outpoints.length === 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await rpc.lockUnspent(walletName, true, outpoints).catch(() => undefined);
|
|
57
|
+
}
|
|
58
|
+
export function diffTemporaryLockedOutpoints(before, after) {
|
|
59
|
+
const beforeKeys = new Set(before.map((entry) => outpointKey(entry)));
|
|
60
|
+
return after
|
|
61
|
+
.filter((entry) => !beforeKeys.has(outpointKey(entry)))
|
|
62
|
+
.map((entry) => ({
|
|
63
|
+
txid: entry.txid,
|
|
64
|
+
vout: entry.vout,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
export function isBroadcastUnknownError(error) {
|
|
68
|
+
const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
69
|
+
return message.includes("timeout")
|
|
70
|
+
|| message.includes("timed out")
|
|
71
|
+
|| message.includes("socket hang up")
|
|
72
|
+
|| message.includes("econnreset")
|
|
73
|
+
|| message.includes("econnrefused")
|
|
74
|
+
|| message.includes("broken pipe")
|
|
75
|
+
|| message.includes("broadcast_unknown");
|
|
76
|
+
}
|
|
77
|
+
export function isAlreadyAcceptedError(error) {
|
|
78
|
+
const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
79
|
+
return message.includes("already in block chain")
|
|
80
|
+
|| message.includes("already in blockchain")
|
|
81
|
+
|| message.includes("txn-already-known");
|
|
82
|
+
}
|
|
83
|
+
export function assertWalletMutationContextReady(context, errorPrefix) {
|
|
84
|
+
if (context.localState.availability === "uninitialized") {
|
|
85
|
+
throw new Error("wallet_uninitialized");
|
|
86
|
+
}
|
|
87
|
+
if (context.localState.availability === "local-state-corrupt") {
|
|
88
|
+
throw new Error("local-state-corrupt");
|
|
89
|
+
}
|
|
90
|
+
if (context.localState.availability !== "ready" || context.localState.state === null || context.localState.unlockUntilUnixMs === null) {
|
|
91
|
+
throw new Error("wallet_locked");
|
|
92
|
+
}
|
|
93
|
+
if (context.bitcoind.health !== "ready") {
|
|
94
|
+
throw new Error(`${errorPrefix}_bitcoind_${context.bitcoind.health.replaceAll("-", "_")}`);
|
|
95
|
+
}
|
|
96
|
+
if (context.nodeHealth !== "synced") {
|
|
97
|
+
throw new Error(`${errorPrefix}_node_${context.nodeHealth.replaceAll("-", "_")}`);
|
|
98
|
+
}
|
|
99
|
+
if (context.indexer.health !== "synced" || context.snapshot === null || context.model === null) {
|
|
100
|
+
throw new Error(`${errorPrefix}_indexer_${context.indexer.health.replaceAll("-", "_")}`);
|
|
101
|
+
}
|
|
102
|
+
if (context.nodeStatus?.walletReplica?.proofStatus !== "ready") {
|
|
103
|
+
throw new Error(`${errorPrefix}_core_replica_not_ready`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export async function pauseMiningForWalletMutation(options) {
|
|
107
|
+
return requestMiningGenerationPreemption({
|
|
108
|
+
paths: options.paths,
|
|
109
|
+
reason: options.reason,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
export async function buildWalletMutationTransaction(options) {
|
|
113
|
+
const lockedBefore = await options.rpc.listLockUnspent(options.walletName);
|
|
114
|
+
let temporaryBuilderLockedOutpoints = [];
|
|
115
|
+
try {
|
|
116
|
+
const funded = await options.rpc.walletCreateFundedPsbt(options.walletName, options.plan.inputs, options.plan.outputs, 0, {
|
|
117
|
+
add_inputs: options.builderOptions?.addInputs ?? true,
|
|
118
|
+
include_unsafe: options.builderOptions?.includeUnsafe ?? false,
|
|
119
|
+
minconf: options.builderOptions?.minConf ?? 1,
|
|
120
|
+
changeAddress: options.plan.changeAddress,
|
|
121
|
+
changePosition: options.plan.changePosition,
|
|
122
|
+
lockUnspents: options.builderOptions?.lockUnspents ?? true,
|
|
123
|
+
fee_rate: options.feeRate ?? DEFAULT_WALLET_MUTATION_FEE_RATE_SAT_VB,
|
|
124
|
+
replaceable: true,
|
|
125
|
+
subtractFeeFromOutputs: [],
|
|
126
|
+
});
|
|
127
|
+
const lockedAfter = await options.rpc.listLockUnspent(options.walletName);
|
|
128
|
+
temporaryBuilderLockedOutpoints = diffTemporaryLockedOutpoints(lockedBefore, lockedAfter);
|
|
129
|
+
const decoded = await options.rpc.decodePsbt(funded.psbt);
|
|
130
|
+
options.validateFundedDraft(decoded, funded, options.plan);
|
|
131
|
+
const signed = await options.rpc.walletProcessPsbt(options.walletName, funded.psbt, true, "DEFAULT");
|
|
132
|
+
const finalized = await options.rpc.finalizePsbt(signed.psbt, true);
|
|
133
|
+
if (!finalized.complete || finalized.hex == null) {
|
|
134
|
+
throw new Error(options.finalizeErrorCode);
|
|
135
|
+
}
|
|
136
|
+
const decodedRaw = await options.rpc.decodeRawTransaction(finalized.hex);
|
|
137
|
+
const mempoolResult = await options.rpc.testMempoolAccept([finalized.hex]);
|
|
138
|
+
const accepted = mempoolResult[0];
|
|
139
|
+
if (accepted == null || !accepted.allowed) {
|
|
140
|
+
throw new Error(`${options.mempoolRejectPrefix}_${accepted?.["reject-reason"] ?? "unknown"}`);
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
funded,
|
|
144
|
+
decoded,
|
|
145
|
+
psbt: signed.psbt,
|
|
146
|
+
rawHex: finalized.hex,
|
|
147
|
+
txid: decodedRaw.txid,
|
|
148
|
+
wtxid: decodedRaw.hash ?? null,
|
|
149
|
+
temporaryBuilderLockedOutpoints,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
await unlockTemporaryBuilderLocks(options.rpc, options.walletName, temporaryBuilderLockedOutpoints);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { WalletPrompter } from "../lifecycle.js";
|
|
2
|
+
export declare function confirmYesNo(prompter: WalletPrompter, message: string, options: {
|
|
3
|
+
assumeYes?: boolean;
|
|
4
|
+
errorCode: string;
|
|
5
|
+
requiresTtyErrorCode: string;
|
|
6
|
+
prompt?: string;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function confirmTypedAcknowledgement(prompter: WalletPrompter, options: {
|
|
9
|
+
assumeYes?: boolean;
|
|
10
|
+
expected: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
errorCode: string;
|
|
13
|
+
requiresTtyErrorCode: string;
|
|
14
|
+
typedAckRequiredErrorCode: string;
|
|
15
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function confirmYesNo(prompter, message, options) {
|
|
2
|
+
prompter.writeLine(message);
|
|
3
|
+
if (options.assumeYes === true) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
if (!prompter.isInteractive) {
|
|
7
|
+
throw new Error(options.requiresTtyErrorCode);
|
|
8
|
+
}
|
|
9
|
+
const answer = (await prompter.prompt(options.prompt ?? "Continue? [y/N]: ")).trim().toLowerCase();
|
|
10
|
+
if (answer !== "y" && answer !== "yes") {
|
|
11
|
+
throw new Error(options.errorCode);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function confirmTypedAcknowledgement(prompter, options) {
|
|
15
|
+
if (!prompter.isInteractive) {
|
|
16
|
+
throw new Error(options.assumeYes === true
|
|
17
|
+
? options.typedAckRequiredErrorCode
|
|
18
|
+
: options.requiresTtyErrorCode);
|
|
19
|
+
}
|
|
20
|
+
const answer = (await prompter.prompt(options.prompt)).trim();
|
|
21
|
+
if (answer !== options.expected) {
|
|
22
|
+
throw new Error(options.errorCode);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
|
|
2
|
+
import { createRpcClient } from "../../bitcoind/node.js";
|
|
3
|
+
import type { RpcTransaction } from "../../bitcoind/types.js";
|
|
4
|
+
import type { WalletPrompter } from "../lifecycle.js";
|
|
5
|
+
import { type WalletRuntimePaths } from "../runtime.js";
|
|
6
|
+
import { type WalletSecretProvider } from "../state/provider.js";
|
|
7
|
+
import { openWalletReadContext } from "../read/index.js";
|
|
8
|
+
import { type WalletMutationRpcClient } from "./common.js";
|
|
9
|
+
type DomainAdminKind = "endpoint" | "delegate" | "miner" | "canonical";
|
|
10
|
+
interface DomainAdminRpcClient extends WalletMutationRpcClient {
|
|
11
|
+
getBlockchainInfo(): Promise<{
|
|
12
|
+
blocks: number;
|
|
13
|
+
}>;
|
|
14
|
+
sendRawTransaction(hex: string): Promise<string>;
|
|
15
|
+
getRawTransaction(txid: string, verbose?: boolean): Promise<RpcTransaction>;
|
|
16
|
+
}
|
|
17
|
+
export interface DomainAdminResolvedSenderSummary {
|
|
18
|
+
selector: string;
|
|
19
|
+
localIndex: number;
|
|
20
|
+
scriptPubKeyHex: string;
|
|
21
|
+
address: string;
|
|
22
|
+
}
|
|
23
|
+
export interface DomainAdminResolvedTargetSummary {
|
|
24
|
+
scriptPubKeyHex: string;
|
|
25
|
+
address: string | null;
|
|
26
|
+
opaque: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type DomainAdminResolvedEffect = {
|
|
29
|
+
kind: "endpoint-set";
|
|
30
|
+
byteLength: number;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "endpoint-clear";
|
|
33
|
+
} | {
|
|
34
|
+
kind: "delegate-set";
|
|
35
|
+
} | {
|
|
36
|
+
kind: "delegate-clear";
|
|
37
|
+
} | {
|
|
38
|
+
kind: "miner-set";
|
|
39
|
+
} | {
|
|
40
|
+
kind: "miner-clear";
|
|
41
|
+
} | {
|
|
42
|
+
kind: "canonicalize-owner";
|
|
43
|
+
};
|
|
44
|
+
export interface DomainAdminResolvedSummary {
|
|
45
|
+
sender: DomainAdminResolvedSenderSummary;
|
|
46
|
+
target: DomainAdminResolvedTargetSummary | null;
|
|
47
|
+
effect: DomainAdminResolvedEffect;
|
|
48
|
+
}
|
|
49
|
+
export interface DomainAdminMutationResult {
|
|
50
|
+
kind: DomainAdminKind;
|
|
51
|
+
domainName: string;
|
|
52
|
+
txid: string;
|
|
53
|
+
status: "live" | "confirmed";
|
|
54
|
+
reusedExisting: boolean;
|
|
55
|
+
recipientScriptPubKeyHex?: string | null;
|
|
56
|
+
endpointValueHex?: string | null;
|
|
57
|
+
resolved?: DomainAdminResolvedSummary | null;
|
|
58
|
+
}
|
|
59
|
+
interface DomainAdminBaseOptions {
|
|
60
|
+
domainName: string;
|
|
61
|
+
dataDir: string;
|
|
62
|
+
databasePath: string;
|
|
63
|
+
provider?: WalletSecretProvider;
|
|
64
|
+
prompter: WalletPrompter;
|
|
65
|
+
assumeYes?: boolean;
|
|
66
|
+
nowUnixMs?: number;
|
|
67
|
+
paths?: WalletRuntimePaths;
|
|
68
|
+
openReadContext?: typeof openWalletReadContext;
|
|
69
|
+
attachService?: typeof attachOrStartManagedBitcoindService;
|
|
70
|
+
rpcFactory?: (config: Parameters<typeof createRpcClient>[0]) => DomainAdminRpcClient;
|
|
71
|
+
}
|
|
72
|
+
export interface SetDomainEndpointOptions extends DomainAdminBaseOptions {
|
|
73
|
+
source: {
|
|
74
|
+
kind: "text";
|
|
75
|
+
value: string;
|
|
76
|
+
} | {
|
|
77
|
+
kind: "json";
|
|
78
|
+
value: string;
|
|
79
|
+
} | {
|
|
80
|
+
kind: "bytes";
|
|
81
|
+
value: string;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export interface ClearDomainEndpointOptions extends DomainAdminBaseOptions {
|
|
85
|
+
}
|
|
86
|
+
export interface SetDomainDelegateOptions extends DomainAdminBaseOptions {
|
|
87
|
+
target: string;
|
|
88
|
+
}
|
|
89
|
+
export interface ClearDomainDelegateOptions extends DomainAdminBaseOptions {
|
|
90
|
+
}
|
|
91
|
+
export interface SetDomainMinerOptions extends DomainAdminBaseOptions {
|
|
92
|
+
target: string;
|
|
93
|
+
}
|
|
94
|
+
export interface ClearDomainMinerOptions extends DomainAdminBaseOptions {
|
|
95
|
+
}
|
|
96
|
+
export interface SetDomainCanonicalOptions extends DomainAdminBaseOptions {
|
|
97
|
+
}
|
|
98
|
+
export declare function setDomainEndpoint(options: SetDomainEndpointOptions): Promise<DomainAdminMutationResult>;
|
|
99
|
+
export declare function clearDomainEndpoint(options: ClearDomainEndpointOptions): Promise<DomainAdminMutationResult>;
|
|
100
|
+
export declare function setDomainDelegate(options: SetDomainDelegateOptions): Promise<DomainAdminMutationResult>;
|
|
101
|
+
export declare function clearDomainDelegate(options: ClearDomainDelegateOptions): Promise<DomainAdminMutationResult>;
|
|
102
|
+
export declare function setDomainMiner(options: SetDomainMinerOptions): Promise<DomainAdminMutationResult>;
|
|
103
|
+
export declare function clearDomainMiner(options: ClearDomainMinerOptions): Promise<DomainAdminMutationResult>;
|
|
104
|
+
export declare function setDomainCanonical(options: SetDomainCanonicalOptions): Promise<DomainAdminMutationResult>;
|
|
105
|
+
export {};
|