@cogcoin/client 0.5.12 → 0.5.14
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/README.md +1 -1
- package/dist/bitcoind/bootstrap/getblock-archive.d.ts +23 -1
- package/dist/bitcoind/bootstrap/getblock-archive.js +127 -37
- package/dist/bitcoind/bootstrap.d.ts +1 -1
- package/dist/bitcoind/bootstrap.js +1 -1
- package/dist/bitcoind/client/managed-client.js +62 -40
- package/dist/bitcoind/client/sync-engine.js +7 -2
- package/dist/bitcoind/testing.d.ts +1 -1
- package/dist/bitcoind/testing.js +1 -1
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/commands/sync.js +99 -1
- package/dist/cli/commands/wallet-mutation.js +39 -2
- package/dist/cli/context.js +20 -3
- package/dist/cli/mutation-success.d.ts +2 -0
- package/dist/cli/mutation-success.js +2 -0
- package/dist/cli/mutation-text-write.d.ts +2 -0
- package/dist/cli/mutation-text-write.js +7 -0
- package/dist/cli/output.js +22 -1
- package/dist/cli/types.d.ts +2 -0
- package/dist/cli/wallet-format.d.ts +1 -1
- package/dist/cli/wallet-format.js +2 -2
- package/dist/wallet/archive.js +10 -8
- package/dist/wallet/coin-control.d.ts +41 -0
- package/dist/wallet/coin-control.js +406 -0
- package/dist/wallet/lifecycle.js +39 -2
- package/dist/wallet/mining/runner.js +46 -44
- package/dist/wallet/read/context.js +15 -6
- package/dist/wallet/reset.js +2 -0
- package/dist/wallet/state/storage.js +5 -4
- package/dist/wallet/tx/anchor.d.ts +2 -0
- package/dist/wallet/tx/anchor.js +76 -56
- package/dist/wallet/tx/cog.js +19 -22
- package/dist/wallet/tx/common.d.ts +45 -10
- package/dist/wallet/tx/common.js +178 -6
- package/dist/wallet/tx/domain-admin.js +15 -9
- package/dist/wallet/tx/domain-market.js +19 -22
- package/dist/wallet/tx/field.js +19 -18
- package/dist/wallet/tx/register.js +19 -22
- package/dist/wallet/tx/reputation.js +15 -9
- package/dist/wallet/types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ import { resolveWalletRuntimePathsForTesting } from "../runtime.js";
|
|
|
8
8
|
import { createDefaultWalletSecretProvider, } from "../state/provider.js";
|
|
9
9
|
import { computeRootRegistrationPriceSats, serializeDomainReg } from "../cogop/index.js";
|
|
10
10
|
import { openWalletReadContext } from "../read/index.js";
|
|
11
|
-
import { assertWalletMutationContextReady,
|
|
11
|
+
import { assertFixedInputPrefixMatches, assertFundingInputsAfterFixedPrefix, assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback, formatCogAmount, isAlreadyAcceptedError, isBroadcastUnknownError, outpointKey, pauseMiningForWalletMutation, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "./common.js";
|
|
12
12
|
import { confirmTypedAcknowledgement, confirmYesNo } from "./confirm.js";
|
|
13
13
|
import { getCanonicalIdentitySelector, resolveIdentityBySelector, } from "./identity-selector.js";
|
|
14
14
|
import { findPendingMutationByIntent, upsertPendingMutation } from "./journal.js";
|
|
@@ -401,14 +401,17 @@ function validateFundedDraft(decoded, funded, plan) {
|
|
|
401
401
|
if (inputs.length === 0) {
|
|
402
402
|
throw new Error("wallet_register_missing_sender_input");
|
|
403
403
|
}
|
|
404
|
+
assertFixedInputPrefixMatches(inputs, plan.fixedInputs, "wallet_register_sender_input_mismatch");
|
|
404
405
|
if (inputs[0]?.prevout?.scriptPubKey?.hex !== plan.sender.scriptPubKeyHex) {
|
|
405
406
|
throw new Error("wallet_register_sender_input_mismatch");
|
|
406
407
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
408
|
+
assertFundingInputsAfterFixedPrefix({
|
|
409
|
+
inputs,
|
|
410
|
+
fixedInputs: plan.fixedInputs,
|
|
411
|
+
allowedFundingScriptPubKeyHex: plan.allowedFundingScriptPubKeyHex,
|
|
412
|
+
eligibleFundingOutpointKeys: plan.eligibleFundingOutpointKeys,
|
|
413
|
+
errorCode: "wallet_register_unexpected_funding_input",
|
|
414
|
+
});
|
|
412
415
|
if (outputs[0]?.scriptPubKey?.hex !== plan.expectedOpReturnScriptHex) {
|
|
413
416
|
throw new Error("wallet_register_opreturn_mismatch");
|
|
414
417
|
}
|
|
@@ -456,21 +459,11 @@ function buildRegisterPlan(options) {
|
|
|
456
459
|
anchorValueSats: options.anchorOutpoint === null ? null : options.anchorValueSats,
|
|
457
460
|
});
|
|
458
461
|
if (options.anchorOutpoint === null) {
|
|
459
|
-
if (fundingUtxos.length === 0) {
|
|
460
|
-
throw new Error("wallet_register_sender_utxo_unavailable");
|
|
461
|
-
}
|
|
462
|
-
const senderInput = fundingUtxos[0];
|
|
463
|
-
const additionalFunding = fundingUtxos
|
|
464
|
-
.slice(1)
|
|
465
|
-
.map((entry) => ({ txid: entry.txid, vout: entry.vout }));
|
|
466
462
|
return {
|
|
467
463
|
registerKind: "root",
|
|
468
464
|
sender: options.sender,
|
|
469
465
|
changeAddress: options.state.funding.address,
|
|
470
|
-
|
|
471
|
-
{ txid: senderInput.txid, vout: senderInput.vout },
|
|
472
|
-
...additionalFunding,
|
|
473
|
-
],
|
|
466
|
+
fixedInputs: [],
|
|
474
467
|
outputs: rootOutputs.outputs,
|
|
475
468
|
changePosition: rootOutputs.changePosition,
|
|
476
469
|
expectedOpReturnScriptHex: rootOutputs.expectedOpReturnScriptHex,
|
|
@@ -481,6 +474,7 @@ function buildRegisterPlan(options) {
|
|
|
481
474
|
expectedAnchorScriptHex: null,
|
|
482
475
|
expectedAnchorValueSats: null,
|
|
483
476
|
allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
|
|
477
|
+
eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey(entry))),
|
|
484
478
|
};
|
|
485
479
|
}
|
|
486
480
|
const anchorUtxo = options.allUtxos.find((entry) => entry.txid === options.anchorOutpoint?.txid
|
|
@@ -494,9 +488,8 @@ function buildRegisterPlan(options) {
|
|
|
494
488
|
registerKind: "root",
|
|
495
489
|
sender: options.sender,
|
|
496
490
|
changeAddress: options.state.funding.address,
|
|
497
|
-
|
|
491
|
+
fixedInputs: [
|
|
498
492
|
{ txid: anchorUtxo.txid, vout: anchorUtxo.vout },
|
|
499
|
-
...fundingUtxos.map((entry) => ({ txid: entry.txid, vout: entry.vout })),
|
|
500
493
|
],
|
|
501
494
|
outputs: rootOutputs.outputs,
|
|
502
495
|
changePosition: rootOutputs.changePosition,
|
|
@@ -508,6 +501,7 @@ function buildRegisterPlan(options) {
|
|
|
508
501
|
expectedAnchorScriptHex: options.sender.scriptPubKeyHex,
|
|
509
502
|
expectedAnchorValueSats: options.anchorValueSats,
|
|
510
503
|
allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
|
|
504
|
+
eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey(entry))),
|
|
511
505
|
};
|
|
512
506
|
}
|
|
513
507
|
const anchor = options.anchorOutpoint;
|
|
@@ -530,9 +524,8 @@ function buildRegisterPlan(options) {
|
|
|
530
524
|
registerKind: "subdomain",
|
|
531
525
|
sender: options.sender,
|
|
532
526
|
changeAddress: options.state.funding.address,
|
|
533
|
-
|
|
527
|
+
fixedInputs: [
|
|
534
528
|
{ txid: anchorUtxo.txid, vout: anchorUtxo.vout },
|
|
535
|
-
...fundingUtxos.map((entry) => ({ txid: entry.txid, vout: entry.vout })),
|
|
536
529
|
],
|
|
537
530
|
outputs: subdomainOutputs.outputs,
|
|
538
531
|
changePosition: subdomainOutputs.changePosition,
|
|
@@ -544,16 +537,19 @@ function buildRegisterPlan(options) {
|
|
|
544
537
|
expectedAnchorScriptHex: options.sender.scriptPubKeyHex,
|
|
545
538
|
expectedAnchorValueSats: options.anchorValueSats,
|
|
546
539
|
allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
|
|
540
|
+
eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey(entry))),
|
|
547
541
|
};
|
|
548
542
|
}
|
|
549
543
|
async function buildRegisterTransaction(options) {
|
|
550
|
-
return
|
|
544
|
+
return buildWalletMutationTransactionWithReserveFallback({
|
|
551
545
|
rpc: options.rpc,
|
|
552
546
|
walletName: options.walletName,
|
|
547
|
+
state: options.state,
|
|
553
548
|
plan: options.plan,
|
|
554
549
|
validateFundedDraft,
|
|
555
550
|
finalizeErrorCode: "wallet_register_finalize_failed",
|
|
556
551
|
mempoolRejectPrefix: "wallet_register_mempool_rejected",
|
|
552
|
+
reserveCandidates: options.state.proactiveReserveOutpoints,
|
|
557
553
|
});
|
|
558
554
|
}
|
|
559
555
|
async function reconcilePendingRegisterMutation(options) {
|
|
@@ -810,6 +806,7 @@ export async function registerDomain(options) {
|
|
|
810
806
|
const built = await buildRegisterTransaction({
|
|
811
807
|
rpc,
|
|
812
808
|
walletName,
|
|
809
|
+
state: nextState,
|
|
813
810
|
plan,
|
|
814
811
|
});
|
|
815
812
|
const currentMutation = nextState.pendingMutations?.find((mutation) => mutation.intentFingerprintHex === intentFingerprintHex)
|
|
@@ -8,7 +8,7 @@ import { resolveWalletRuntimePathsForTesting } from "../runtime.js";
|
|
|
8
8
|
import { createDefaultWalletSecretProvider, } from "../state/provider.js";
|
|
9
9
|
import { serializeRepCommit, serializeRepRevoke, validateDomainName, } from "../cogop/index.js";
|
|
10
10
|
import { openWalletReadContext } from "../read/index.js";
|
|
11
|
-
import { assertWalletMutationContextReady,
|
|
11
|
+
import { assertFixedInputPrefixMatches, assertFundingInputsAfterFixedPrefix, assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback, formatCogAmount, isAlreadyAcceptedError, isBroadcastUnknownError, outpointKey, pauseMiningForWalletMutation, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "./common.js";
|
|
12
12
|
import { confirmTypedAcknowledgement as confirmSharedTypedAcknowledgement, confirmYesNo as confirmSharedYesNo, } from "./confirm.js";
|
|
13
13
|
import { getCanonicalIdentitySelector } from "./identity-selector.js";
|
|
14
14
|
import { findPendingMutationByIntent, upsertPendingMutation } from "./journal.js";
|
|
@@ -162,9 +162,8 @@ function buildPlanForReputationOperation(options) {
|
|
|
162
162
|
return {
|
|
163
163
|
sender: options.sender,
|
|
164
164
|
changeAddress: options.state.funding.address,
|
|
165
|
-
|
|
165
|
+
fixedInputs: [
|
|
166
166
|
{ txid: anchorUtxo.txid, vout: anchorUtxo.vout },
|
|
167
|
-
...fundingUtxos.map((entry) => ({ txid: entry.txid, vout: entry.vout })),
|
|
168
167
|
],
|
|
169
168
|
outputs: [
|
|
170
169
|
{ data: Buffer.from(options.opReturnData).toString("hex") },
|
|
@@ -175,6 +174,7 @@ function buildPlanForReputationOperation(options) {
|
|
|
175
174
|
expectedAnchorScriptHex: options.sender.scriptPubKeyHex,
|
|
176
175
|
expectedAnchorValueSats: BigInt(options.state.anchorValueSats),
|
|
177
176
|
allowedFundingScriptPubKeyHex: options.state.funding.scriptPubKeyHex,
|
|
177
|
+
eligibleFundingOutpointKeys: new Set(fundingUtxos.map((entry) => outpointKey({ txid: entry.txid, vout: entry.vout }))),
|
|
178
178
|
errorPrefix: options.errorPrefix,
|
|
179
179
|
};
|
|
180
180
|
}
|
|
@@ -184,14 +184,17 @@ function validateFundedDraft(decoded, funded, plan) {
|
|
|
184
184
|
if (inputs.length === 0) {
|
|
185
185
|
throw new Error(`${plan.errorPrefix}_missing_sender_input`);
|
|
186
186
|
}
|
|
187
|
+
assertFixedInputPrefixMatches(inputs, plan.fixedInputs, `${plan.errorPrefix}_sender_input_mismatch`);
|
|
187
188
|
if (inputs[0]?.prevout?.scriptPubKey?.hex !== plan.sender.scriptPubKeyHex) {
|
|
188
189
|
throw new Error(`${plan.errorPrefix}_sender_input_mismatch`);
|
|
189
190
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
assertFundingInputsAfterFixedPrefix({
|
|
192
|
+
inputs,
|
|
193
|
+
fixedInputs: plan.fixedInputs,
|
|
194
|
+
allowedFundingScriptPubKeyHex: plan.allowedFundingScriptPubKeyHex,
|
|
195
|
+
eligibleFundingOutpointKeys: plan.eligibleFundingOutpointKeys,
|
|
196
|
+
errorCode: `${plan.errorPrefix}_unexpected_funding_input`,
|
|
197
|
+
});
|
|
195
198
|
if (outputs[0]?.scriptPubKey?.hex !== plan.expectedOpReturnScriptHex) {
|
|
196
199
|
throw new Error(`${plan.errorPrefix}_opreturn_mismatch`);
|
|
197
200
|
}
|
|
@@ -215,13 +218,15 @@ function validateFundedDraft(decoded, funded, plan) {
|
|
|
215
218
|
}
|
|
216
219
|
}
|
|
217
220
|
async function buildTransaction(options) {
|
|
218
|
-
return
|
|
221
|
+
return buildWalletMutationTransactionWithReserveFallback({
|
|
219
222
|
rpc: options.rpc,
|
|
220
223
|
walletName: options.walletName,
|
|
224
|
+
state: options.state,
|
|
221
225
|
plan: options.plan,
|
|
222
226
|
validateFundedDraft,
|
|
223
227
|
finalizeErrorCode: `${options.plan.errorPrefix}_finalize_failed`,
|
|
224
228
|
mempoolRejectPrefix: `${options.plan.errorPrefix}_mempool_rejected`,
|
|
229
|
+
reserveCandidates: options.state.proactiveReserveOutpoints,
|
|
225
230
|
});
|
|
226
231
|
}
|
|
227
232
|
function createDraftMutation(options) {
|
|
@@ -635,6 +640,7 @@ async function submitReputationMutation(options) {
|
|
|
635
640
|
const built = await buildTransaction({
|
|
636
641
|
rpc,
|
|
637
642
|
walletName,
|
|
643
|
+
state: nextState,
|
|
638
644
|
plan: buildPlanForReputationOperation({
|
|
639
645
|
state: nextState,
|
|
640
646
|
allUtxos: await rpc.listUnspent(walletName, 1),
|
package/dist/wallet/types.d.ts
CHANGED
|
@@ -142,6 +142,8 @@ export interface WalletStateV1 {
|
|
|
142
142
|
walletRootId: string;
|
|
143
143
|
network: WalletNetwork;
|
|
144
144
|
anchorValueSats: number;
|
|
145
|
+
proactiveReserveSats: number;
|
|
146
|
+
proactiveReserveOutpoints: OutpointRecord[];
|
|
145
147
|
nextDedicatedIndex: number;
|
|
146
148
|
fundingIndex: 0;
|
|
147
149
|
mnemonic: {
|
|
@@ -191,6 +193,8 @@ export interface PortableWalletArchivePayloadV1 {
|
|
|
191
193
|
walletRootId: string;
|
|
192
194
|
network: WalletNetwork;
|
|
193
195
|
anchorValueSats: number;
|
|
196
|
+
proactiveReserveSats: number;
|
|
197
|
+
proactiveReserveOutpoints: OutpointRecord[];
|
|
194
198
|
nextDedicatedIndex: number;
|
|
195
199
|
fundingIndex: 0;
|
|
196
200
|
mnemonic: {
|
package/package.json
CHANGED