@cogcoin/client 1.1.6 → 1.1.7
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 +2 -2
- package/dist/bitcoind/indexer-daemon.js +29 -79
- package/dist/bitcoind/managed-runtime/bitcoind-runtime.d.ts +20 -0
- package/dist/bitcoind/managed-runtime/bitcoind-runtime.js +74 -0
- package/dist/bitcoind/managed-runtime/bitcoind-status.d.ts +11 -0
- package/dist/bitcoind/managed-runtime/bitcoind-status.js +44 -0
- package/dist/bitcoind/managed-runtime/indexer-runtime.d.ts +15 -0
- package/dist/bitcoind/managed-runtime/indexer-runtime.js +82 -0
- package/dist/bitcoind/managed-runtime/types.d.ts +40 -0
- package/dist/bitcoind/node.d.ts +2 -2
- package/dist/bitcoind/node.js +2 -2
- package/dist/bitcoind/rpc.d.ts +2 -1
- package/dist/bitcoind/rpc.js +53 -3
- package/dist/bitcoind/service.js +46 -126
- package/dist/cli/command-registry.d.ts +1 -1
- package/dist/cli/command-registry.js +2 -64
- package/dist/cli/commands/client-admin.js +3 -18
- package/dist/cli/commands/mining-runtime.js +4 -60
- package/dist/cli/commands/wallet-admin.js +6 -6
- package/dist/cli/context.js +1 -3
- package/dist/cli/mining-json.d.ts +1 -22
- package/dist/cli/mining-json.js +0 -23
- package/dist/cli/output.js +16 -2
- package/dist/cli/parse.js +0 -2
- package/dist/cli/preview-json.d.ts +1 -22
- package/dist/cli/preview-json.js +0 -19
- package/dist/cli/types.d.ts +1 -3
- package/dist/cli/wallet-format.js +1 -1
- package/dist/cli/workflow-hints.d.ts +1 -2
- package/dist/cli/workflow-hints.js +5 -8
- package/dist/wallet/lifecycle/context.js +0 -1
- package/dist/wallet/lifecycle/repair-mining.d.ts +1 -5
- package/dist/wallet/lifecycle/repair-mining.js +5 -39
- package/dist/wallet/lifecycle/repair.js +0 -3
- package/dist/wallet/lifecycle/setup.js +10 -8
- package/dist/wallet/lifecycle/types.d.ts +1 -4
- package/dist/wallet/managed-core-wallet.d.ts +2 -0
- package/dist/wallet/managed-core-wallet.js +27 -1
- package/dist/wallet/mining/candidate.d.ts +1 -0
- package/dist/wallet/mining/candidate.js +38 -6
- package/dist/wallet/mining/competitiveness.d.ts +1 -0
- package/dist/wallet/mining/competitiveness.js +6 -0
- package/dist/wallet/mining/cycle.d.ts +2 -0
- package/dist/wallet/mining/cycle.js +14 -4
- package/dist/wallet/mining/engine-types.d.ts +1 -0
- package/dist/wallet/mining/index.d.ts +1 -1
- package/dist/wallet/mining/index.js +1 -1
- package/dist/wallet/mining/publish.d.ts +3 -0
- package/dist/wallet/mining/publish.js +78 -6
- package/dist/wallet/mining/runner.d.ts +0 -32
- package/dist/wallet/mining/runner.js +59 -104
- package/dist/wallet/mining/stop.d.ts +7 -0
- package/dist/wallet/mining/stop.js +23 -0
- package/dist/wallet/mining/supervisor.d.ts +2 -36
- package/dist/wallet/mining/supervisor.js +139 -246
- package/dist/wallet/read/context.d.ts +1 -5
- package/dist/wallet/read/context.js +20 -204
- package/dist/wallet/read/managed-services.d.ts +33 -0
- package/dist/wallet/read/managed-services.js +222 -0
- package/dist/wallet/state/client-password/bootstrap.d.ts +2 -0
- package/dist/wallet/state/client-password/bootstrap.js +3 -0
- package/dist/wallet/state/client-password/context.d.ts +10 -0
- package/dist/wallet/state/client-password/context.js +46 -0
- package/dist/wallet/state/client-password/crypto.d.ts +34 -0
- package/dist/wallet/state/client-password/crypto.js +117 -0
- package/dist/wallet/state/client-password/files.d.ts +10 -0
- package/dist/wallet/state/client-password/files.js +109 -0
- package/dist/wallet/state/client-password/legacy-cleanup.d.ts +11 -0
- package/dist/wallet/state/client-password/legacy-cleanup.js +338 -0
- package/dist/wallet/state/client-password/messages.d.ts +3 -0
- package/dist/wallet/state/client-password/messages.js +9 -0
- package/dist/wallet/state/client-password/migration.d.ts +4 -0
- package/dist/wallet/state/client-password/migration.js +32 -0
- package/dist/wallet/state/client-password/prompts.d.ts +12 -0
- package/dist/wallet/state/client-password/prompts.js +79 -0
- package/dist/wallet/state/client-password/protected-secrets.d.ts +13 -0
- package/dist/wallet/state/client-password/protected-secrets.js +90 -0
- package/dist/wallet/state/client-password/readiness.d.ts +4 -0
- package/dist/wallet/state/client-password/readiness.js +48 -0
- package/dist/wallet/state/client-password/references.d.ts +1 -0
- package/dist/wallet/state/client-password/references.js +56 -0
- package/dist/wallet/state/client-password/rotation.d.ts +6 -0
- package/dist/wallet/state/client-password/rotation.js +98 -0
- package/dist/wallet/state/client-password/session-policy.d.ts +6 -0
- package/dist/wallet/state/client-password/session-policy.js +28 -0
- package/dist/wallet/state/client-password/session.d.ts +19 -0
- package/dist/wallet/state/client-password/session.js +170 -0
- package/dist/wallet/state/client-password/setup.d.ts +8 -0
- package/dist/wallet/state/client-password/setup.js +49 -0
- package/dist/wallet/state/client-password/types.d.ts +82 -0
- package/dist/wallet/state/client-password/types.js +5 -0
- package/dist/wallet/state/client-password.d.ts +7 -38
- package/dist/wallet/state/client-password.js +52 -937
- package/dist/wallet/tx/anchor.js +123 -216
- package/dist/wallet/tx/cog.js +294 -489
- package/dist/wallet/tx/common.d.ts +2 -0
- package/dist/wallet/tx/common.js +2 -0
- package/dist/wallet/tx/domain-admin.js +111 -220
- package/dist/wallet/tx/domain-market.js +401 -681
- package/dist/wallet/tx/executor.d.ts +176 -0
- package/dist/wallet/tx/executor.js +302 -0
- package/dist/wallet/tx/field.js +109 -215
- package/dist/wallet/tx/register.js +158 -269
- package/dist/wallet/tx/reputation.js +120 -227
- package/package.json +1 -1
- package/dist/wallet/mining/worker-main.d.ts +0 -1
- package/dist/wallet/mining/worker-main.js +0 -17
- package/dist/wallet/state/client-password-agent.d.ts +0 -1
- package/dist/wallet/state/client-password-agent.js +0 -211
package/dist/wallet/tx/cog.js
CHANGED
|
@@ -2,15 +2,15 @@ import { createHash, randomBytes } from "node:crypto";
|
|
|
2
2
|
import { getBalance, getLock, lookupDomain } from "@cogcoin/indexer/queries";
|
|
3
3
|
import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
|
|
4
4
|
import { createRpcClient } from "../../bitcoind/node.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { createDefaultWalletSecretProvider, } from "../state/provider.js";
|
|
5
|
+
import {} from "../runtime.js";
|
|
6
|
+
import {} from "../state/provider.js";
|
|
8
7
|
import { serializeCogClaim, serializeCogLock, serializeCogTransfer, } from "../cogop/index.js";
|
|
9
8
|
import { openWalletReadContext } from "../read/index.js";
|
|
10
|
-
import { assertFixedInputPrefixMatches, assertFundingInputsAfterFixedPrefix, assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback,
|
|
9
|
+
import { assertFixedInputPrefixMatches, assertFundingInputsAfterFixedPrefix, assertWalletMutationContextReady, buildWalletMutationTransactionWithReserveFallback, createFundingMutationSender, createWalletMutationFeeMetadata, formatCogAmount, getDecodedInputScriptPubKeyHex, isLocalWalletScript, mergeFixedWalletInputs, outpointKey, saveWalletStatePreservingUnlock, unlockTemporaryBuilderLocks, updateMutationRecord, } from "./common.js";
|
|
11
10
|
import { confirmTypedAcknowledgement, confirmYesNo } from "./confirm.js";
|
|
11
|
+
import { executeWalletMutationOperation, publishWalletMutation, resolveExistingWalletMutation, } from "./executor.js";
|
|
12
12
|
import { getCanonicalIdentitySelector, resolveIdentityBySelector, } from "./identity-selector.js";
|
|
13
|
-
import {
|
|
13
|
+
import { upsertPendingMutation } from "./journal.js";
|
|
14
14
|
import { normalizeBtcTarget } from "./targets.js";
|
|
15
15
|
const MAX_LOCK_DURATION_BLOCKS = 262_800;
|
|
16
16
|
const ZERO_PREIMAGE_HEX = "00".repeat(32);
|
|
@@ -411,278 +411,141 @@ async function confirmClaim(prompter, options) {
|
|
|
411
411
|
: "wallet_reclaim_requires_tty",
|
|
412
412
|
});
|
|
413
413
|
}
|
|
414
|
-
async function sendBuiltTransaction(options) {
|
|
415
|
-
let nextState = options.state;
|
|
416
|
-
const broadcasting = updateMutationRecord(options.mutation, "broadcasting", options.nowUnixMs, {
|
|
417
|
-
attemptedTxid: options.built.txid,
|
|
418
|
-
attemptedWtxid: options.built.wtxid,
|
|
419
|
-
temporaryBuilderLockedOutpoints: options.built.temporaryBuilderLockedOutpoints,
|
|
420
|
-
});
|
|
421
|
-
nextState = {
|
|
422
|
-
...upsertPendingMutation(nextState, broadcasting),
|
|
423
|
-
stateRevision: nextState.stateRevision + 1,
|
|
424
|
-
lastWrittenAtUnixMs: options.nowUnixMs,
|
|
425
|
-
};
|
|
426
|
-
await saveWalletStatePreservingUnlock({
|
|
427
|
-
state: nextState,
|
|
428
|
-
provider: options.provider,
|
|
429
|
-
nowUnixMs: options.nowUnixMs,
|
|
430
|
-
paths: options.paths,
|
|
431
|
-
});
|
|
432
|
-
if (options.snapshotHeight !== null && options.snapshotHeight !== (await options.rpc.getBlockchainInfo()).blocks) {
|
|
433
|
-
await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.built.temporaryBuilderLockedOutpoints);
|
|
434
|
-
throw new Error(`${options.errorPrefix}_tip_mismatch`);
|
|
435
|
-
}
|
|
436
|
-
try {
|
|
437
|
-
await options.rpc.sendRawTransaction(options.built.rawHex);
|
|
438
|
-
}
|
|
439
|
-
catch (error) {
|
|
440
|
-
if (!isAlreadyAcceptedError(error)) {
|
|
441
|
-
if (isBroadcastUnknownError(error)) {
|
|
442
|
-
const unknown = updateMutationRecord(broadcasting, "broadcast-unknown", options.nowUnixMs, {
|
|
443
|
-
attemptedTxid: options.built.txid,
|
|
444
|
-
attemptedWtxid: options.built.wtxid,
|
|
445
|
-
temporaryBuilderLockedOutpoints: options.built.temporaryBuilderLockedOutpoints,
|
|
446
|
-
});
|
|
447
|
-
nextState = {
|
|
448
|
-
...upsertPendingMutation(nextState, unknown),
|
|
449
|
-
stateRevision: nextState.stateRevision + 1,
|
|
450
|
-
lastWrittenAtUnixMs: options.nowUnixMs,
|
|
451
|
-
};
|
|
452
|
-
await saveWalletStatePreservingUnlock({
|
|
453
|
-
state: nextState,
|
|
454
|
-
provider: options.provider,
|
|
455
|
-
nowUnixMs: options.nowUnixMs,
|
|
456
|
-
paths: options.paths,
|
|
457
|
-
});
|
|
458
|
-
throw new Error(`${options.errorPrefix}_broadcast_unknown`);
|
|
459
|
-
}
|
|
460
|
-
await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.built.temporaryBuilderLockedOutpoints);
|
|
461
|
-
const canceled = updateMutationRecord(broadcasting, "canceled", options.nowUnixMs, {
|
|
462
|
-
attemptedTxid: options.built.txid,
|
|
463
|
-
attemptedWtxid: options.built.wtxid,
|
|
464
|
-
temporaryBuilderLockedOutpoints: [],
|
|
465
|
-
});
|
|
466
|
-
nextState = {
|
|
467
|
-
...upsertPendingMutation(nextState, canceled),
|
|
468
|
-
stateRevision: nextState.stateRevision + 1,
|
|
469
|
-
lastWrittenAtUnixMs: options.nowUnixMs,
|
|
470
|
-
};
|
|
471
|
-
await saveWalletStatePreservingUnlock({
|
|
472
|
-
state: nextState,
|
|
473
|
-
provider: options.provider,
|
|
474
|
-
nowUnixMs: options.nowUnixMs,
|
|
475
|
-
paths: options.paths,
|
|
476
|
-
});
|
|
477
|
-
throw error;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
await unlockTemporaryBuilderLocks(options.rpc, options.walletName, options.built.temporaryBuilderLockedOutpoints);
|
|
481
|
-
const live = updateMutationRecord(broadcasting, "live", options.nowUnixMs, {
|
|
482
|
-
attemptedTxid: options.built.txid,
|
|
483
|
-
attemptedWtxid: options.built.wtxid,
|
|
484
|
-
temporaryBuilderLockedOutpoints: [],
|
|
485
|
-
});
|
|
486
|
-
nextState = {
|
|
487
|
-
...upsertPendingMutation(nextState, live),
|
|
488
|
-
stateRevision: nextState.stateRevision + 1,
|
|
489
|
-
lastWrittenAtUnixMs: options.nowUnixMs,
|
|
490
|
-
};
|
|
491
|
-
await saveWalletStatePreservingUnlock({
|
|
492
|
-
state: nextState,
|
|
493
|
-
provider: options.provider,
|
|
494
|
-
nowUnixMs: options.nowUnixMs,
|
|
495
|
-
paths: options.paths,
|
|
496
|
-
});
|
|
497
|
-
return { state: nextState, mutation: live };
|
|
498
|
-
}
|
|
499
414
|
export async function sendCog(options) {
|
|
500
|
-
const provider = options.provider ?? createDefaultWalletSecretProvider();
|
|
501
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
502
|
-
const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
|
|
503
|
-
const controlLock = await acquireFileLock(paths.walletControlLockPath, {
|
|
504
|
-
purpose: "wallet-send",
|
|
505
|
-
walletRootId: null,
|
|
506
|
-
});
|
|
507
415
|
const amountCogtoshi = normalizePositiveAmount(options.amountCogtoshi, "wallet_send_invalid_amount");
|
|
508
416
|
const recipient = normalizeBtcTarget(options.target);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
const readContext = await (options.openReadContext ?? openWalletReadContext)({
|
|
515
|
-
dataDir: options.dataDir,
|
|
516
|
-
databasePath: options.databasePath,
|
|
517
|
-
secretProvider: provider,
|
|
518
|
-
walletControlLockHeld: true,
|
|
519
|
-
paths,
|
|
520
|
-
});
|
|
521
|
-
try {
|
|
417
|
+
const execution = await executeWalletMutationOperation({
|
|
418
|
+
...options,
|
|
419
|
+
controlLockPurpose: "wallet-send",
|
|
420
|
+
preemptionReason: "wallet-send",
|
|
421
|
+
resolveOperation(readContext) {
|
|
522
422
|
const operation = resolveIdentitySender(readContext, "wallet_send", amountCogtoshi, options.fromIdentity);
|
|
523
423
|
if (operation.sender.scriptPubKeyHex === recipient.scriptPubKeyHex) {
|
|
524
424
|
throw new Error("wallet_send_self_transfer");
|
|
525
425
|
}
|
|
526
|
-
|
|
426
|
+
return {
|
|
427
|
+
...operation,
|
|
428
|
+
amountCogtoshi,
|
|
429
|
+
recipient,
|
|
430
|
+
};
|
|
431
|
+
},
|
|
432
|
+
createIntentFingerprint(operation) {
|
|
433
|
+
return createIntentFingerprint([
|
|
527
434
|
"send",
|
|
528
435
|
operation.state.walletRootId,
|
|
529
436
|
operation.sender.scriptPubKeyHex,
|
|
530
|
-
recipient.scriptPubKeyHex,
|
|
531
|
-
amountCogtoshi,
|
|
437
|
+
operation.recipient.scriptPubKeyHex,
|
|
438
|
+
operation.amountCogtoshi,
|
|
532
439
|
]);
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
walletRootId: operation.state.walletRootId,
|
|
538
|
-
});
|
|
539
|
-
const rpc = (options.rpcFactory ?? createRpcClient)(node.rpc);
|
|
540
|
-
const walletName = operation.state.managedCoreWallet.walletName;
|
|
541
|
-
const feeSelection = await resolveWalletMutationFeeSelection({
|
|
542
|
-
rpc,
|
|
543
|
-
feeRateSatVb: options.feeRateSatVb ?? null,
|
|
544
|
-
});
|
|
545
|
-
const existingMutation = findPendingMutationByIntent(operation.state, intentFingerprintHex);
|
|
546
|
-
let workingState = operation.state;
|
|
547
|
-
let replacementFixedInputs = null;
|
|
548
|
-
if (existingMutation !== null) {
|
|
549
|
-
const reconciled = await reconcilePendingCogMutation({
|
|
550
|
-
state: operation.state,
|
|
551
|
-
mutation: existingMutation,
|
|
552
|
-
provider,
|
|
553
|
-
nowUnixMs,
|
|
554
|
-
paths,
|
|
555
|
-
rpc,
|
|
556
|
-
walletName,
|
|
557
|
-
context: readContext,
|
|
558
|
-
});
|
|
559
|
-
workingState = reconciled.state;
|
|
560
|
-
if (reconciled.resolution === "confirmed" || reconciled.resolution === "live") {
|
|
561
|
-
const reuse = await resolvePendingMutationReuseDecision({
|
|
562
|
-
rpc,
|
|
563
|
-
walletName,
|
|
564
|
-
mutation: reconciled.mutation,
|
|
565
|
-
nextFeeSelection: feeSelection,
|
|
566
|
-
});
|
|
567
|
-
if (reuse.reuseExisting) {
|
|
568
|
-
return {
|
|
569
|
-
kind: "send",
|
|
570
|
-
txid: reconciled.mutation.attemptedTxid ?? "unknown",
|
|
571
|
-
status: reconciled.resolution,
|
|
572
|
-
reusedExisting: true,
|
|
573
|
-
amountCogtoshi,
|
|
574
|
-
recipientScriptPubKeyHex: recipient.scriptPubKeyHex,
|
|
575
|
-
resolved: operation.resolved,
|
|
576
|
-
fees: reuse.fees,
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
replacementFixedInputs = reuse.replacementFixedInputs;
|
|
580
|
-
}
|
|
581
|
-
if (reconciled.resolution === "repair-required") {
|
|
582
|
-
throw new Error("wallet_send_repair_required");
|
|
583
|
-
}
|
|
440
|
+
},
|
|
441
|
+
async resolveExistingMutation({ operation, existingMutation, execution }) {
|
|
442
|
+
if (existingMutation === null) {
|
|
443
|
+
return { state: operation.state, replacementFixedInputs: null, result: null };
|
|
584
444
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
445
|
+
return resolveExistingWalletMutation({
|
|
446
|
+
existingMutation,
|
|
447
|
+
execution,
|
|
448
|
+
repairRequiredErrorCode: "wallet_send_repair_required",
|
|
449
|
+
reconcileExistingMutation: (mutation) => reconcilePendingCogMutation({
|
|
450
|
+
state: operation.state,
|
|
451
|
+
mutation,
|
|
452
|
+
provider: execution.provider,
|
|
453
|
+
nowUnixMs: execution.nowUnixMs,
|
|
454
|
+
paths: execution.paths,
|
|
455
|
+
rpc: execution.rpc,
|
|
456
|
+
walletName: execution.walletName,
|
|
457
|
+
context: execution.readContext,
|
|
458
|
+
}),
|
|
459
|
+
createReuseResult: ({ mutation, resolution, fees }) => ({
|
|
460
|
+
kind: "send",
|
|
461
|
+
txid: mutation.attemptedTxid ?? "unknown",
|
|
462
|
+
status: resolution,
|
|
463
|
+
reusedExisting: true,
|
|
464
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
465
|
+
recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
|
|
466
|
+
resolved: operation.resolved,
|
|
467
|
+
fees,
|
|
468
|
+
}),
|
|
606
469
|
});
|
|
470
|
+
},
|
|
471
|
+
confirm({ operation }) {
|
|
472
|
+
return confirmSend(options.prompter, operation.resolved, options.target, operation.recipient, operation.amountCogtoshi, options.assumeYes);
|
|
473
|
+
},
|
|
474
|
+
createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
|
|
475
|
+
return {
|
|
476
|
+
mutation: createDraftMutation({
|
|
477
|
+
kind: "send",
|
|
478
|
+
sender: operation.sender,
|
|
479
|
+
recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
|
|
480
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
481
|
+
intentFingerprintHex,
|
|
482
|
+
nowUnixMs: execution.nowUnixMs,
|
|
483
|
+
feeSelection: execution.feeSelection,
|
|
484
|
+
existing: existingMutation,
|
|
485
|
+
}),
|
|
486
|
+
prepared: null,
|
|
487
|
+
};
|
|
488
|
+
},
|
|
489
|
+
async build({ operation, state, execution, replacementFixedInputs }) {
|
|
607
490
|
const sendPlan = buildPlanForCogOperation({
|
|
608
|
-
state
|
|
609
|
-
allUtxos: await rpc.listUnspent(walletName, 1),
|
|
491
|
+
state,
|
|
492
|
+
allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
|
|
610
493
|
sender: operation.sender,
|
|
611
|
-
opReturnData: serializeCogTransfer(amountCogtoshi, Buffer.from(recipient.scriptPubKeyHex, "hex")).opReturnData,
|
|
494
|
+
opReturnData: serializeCogTransfer(operation.amountCogtoshi, Buffer.from(operation.recipient.scriptPubKeyHex, "hex")).opReturnData,
|
|
612
495
|
errorPrefix: "wallet_send",
|
|
613
496
|
});
|
|
614
|
-
|
|
615
|
-
rpc,
|
|
616
|
-
walletName,
|
|
617
|
-
state
|
|
497
|
+
return buildTransaction({
|
|
498
|
+
rpc: execution.rpc,
|
|
499
|
+
walletName: execution.walletName,
|
|
500
|
+
state,
|
|
618
501
|
plan: {
|
|
619
502
|
...sendPlan,
|
|
620
503
|
fixedInputs: mergeFixedWalletInputs(sendPlan.fixedInputs, replacementFixedInputs),
|
|
621
504
|
},
|
|
622
|
-
feeRateSatVb: feeSelection.feeRateSatVb,
|
|
505
|
+
feeRateSatVb: execution.feeSelection.feeRateSatVb,
|
|
623
506
|
});
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
507
|
+
},
|
|
508
|
+
publish({ state, execution, built, mutation }) {
|
|
509
|
+
return publishWalletMutation({
|
|
510
|
+
rpc: execution.rpc,
|
|
511
|
+
walletName: execution.walletName,
|
|
512
|
+
snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
|
|
628
513
|
built,
|
|
629
|
-
mutation
|
|
630
|
-
state
|
|
631
|
-
provider,
|
|
632
|
-
nowUnixMs,
|
|
633
|
-
paths,
|
|
514
|
+
mutation,
|
|
515
|
+
state,
|
|
516
|
+
provider: execution.provider,
|
|
517
|
+
nowUnixMs: execution.nowUnixMs,
|
|
518
|
+
paths: execution.paths,
|
|
634
519
|
errorPrefix: "wallet_send",
|
|
635
520
|
});
|
|
521
|
+
},
|
|
522
|
+
createResult({ operation, mutation, built, status, reusedExisting, fees }) {
|
|
636
523
|
return {
|
|
637
524
|
kind: "send",
|
|
638
|
-
txid:
|
|
639
|
-
status:
|
|
640
|
-
reusedExisting
|
|
641
|
-
amountCogtoshi,
|
|
642
|
-
recipientScriptPubKeyHex: recipient.scriptPubKeyHex,
|
|
525
|
+
txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
|
|
526
|
+
status: status,
|
|
527
|
+
reusedExisting,
|
|
528
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
529
|
+
recipientScriptPubKeyHex: operation.recipient.scriptPubKeyHex,
|
|
643
530
|
resolved: operation.resolved,
|
|
644
|
-
fees
|
|
645
|
-
selection: feeSelection,
|
|
646
|
-
built,
|
|
647
|
-
}),
|
|
531
|
+
fees,
|
|
648
532
|
};
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
await miningPreemption.release();
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
finally {
|
|
656
|
-
await controlLock.release();
|
|
657
|
-
}
|
|
533
|
+
},
|
|
534
|
+
});
|
|
535
|
+
return execution.result;
|
|
658
536
|
}
|
|
659
537
|
export async function lockCogToDomain(options) {
|
|
660
|
-
const provider = options.provider ?? createDefaultWalletSecretProvider();
|
|
661
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
662
|
-
const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
|
|
663
|
-
const controlLock = await acquireFileLock(paths.walletControlLockPath, {
|
|
664
|
-
purpose: "wallet-lock-cog",
|
|
665
|
-
walletRootId: null,
|
|
666
|
-
});
|
|
667
538
|
const amountCogtoshi = normalizePositiveAmount(options.amountCogtoshi, "wallet_lock_invalid_amount");
|
|
668
539
|
const normalizedRecipientDomainName = normalizeDomainName(options.recipientDomainName);
|
|
669
540
|
const condition = parseHex32(options.conditionHex, "wallet_lock_invalid_condition");
|
|
670
541
|
if (condition.equals(Buffer.alloc(32))) {
|
|
671
542
|
throw new Error("wallet_lock_invalid_condition");
|
|
672
543
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const readContext = await (options.openReadContext ?? openWalletReadContext)({
|
|
679
|
-
dataDir: options.dataDir,
|
|
680
|
-
databasePath: options.databasePath,
|
|
681
|
-
secretProvider: provider,
|
|
682
|
-
walletControlLockHeld: true,
|
|
683
|
-
paths,
|
|
684
|
-
});
|
|
685
|
-
try {
|
|
544
|
+
const execution = await executeWalletMutationOperation({
|
|
545
|
+
...options,
|
|
546
|
+
controlLockPurpose: "wallet-lock-cog",
|
|
547
|
+
preemptionReason: "wallet-cog-lock",
|
|
548
|
+
resolveOperation(readContext) {
|
|
686
549
|
assertWalletMutationContextReady(readContext, "wallet_lock");
|
|
687
550
|
const currentHeight = readContext.snapshot.state.history.currentHeight;
|
|
688
551
|
if (currentHeight === null) {
|
|
@@ -702,311 +565,253 @@ export async function lockCogToDomain(options) {
|
|
|
702
565
|
if (readContext.snapshot.state.consensus.nextLockId === 0xffff_ffff) {
|
|
703
566
|
throw new Error("wallet_lock_id_space_exhausted");
|
|
704
567
|
}
|
|
705
|
-
|
|
706
|
-
|
|
568
|
+
return {
|
|
569
|
+
...resolveIdentitySender(readContext, "wallet_lock", amountCogtoshi, options.fromIdentity),
|
|
570
|
+
amountCogtoshi,
|
|
571
|
+
normalizedRecipientDomainName,
|
|
572
|
+
recipientDomain,
|
|
573
|
+
timeoutHeight,
|
|
574
|
+
conditionHex: Buffer.from(condition).toString("hex"),
|
|
575
|
+
};
|
|
576
|
+
},
|
|
577
|
+
createIntentFingerprint(operation) {
|
|
578
|
+
return createIntentFingerprint([
|
|
707
579
|
"lock",
|
|
708
580
|
operation.state.walletRootId,
|
|
709
581
|
operation.sender.scriptPubKeyHex,
|
|
710
|
-
normalizedRecipientDomainName,
|
|
711
|
-
amountCogtoshi,
|
|
712
|
-
timeoutHeight,
|
|
713
|
-
|
|
582
|
+
operation.normalizedRecipientDomainName,
|
|
583
|
+
operation.amountCogtoshi,
|
|
584
|
+
operation.timeoutHeight,
|
|
585
|
+
operation.conditionHex,
|
|
714
586
|
]);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
walletRootId: operation.state.walletRootId,
|
|
720
|
-
});
|
|
721
|
-
const rpc = (options.rpcFactory ?? createRpcClient)(node.rpc);
|
|
722
|
-
const walletName = operation.state.managedCoreWallet.walletName;
|
|
723
|
-
const feeSelection = await resolveWalletMutationFeeSelection({
|
|
724
|
-
rpc,
|
|
725
|
-
feeRateSatVb: options.feeRateSatVb ?? null,
|
|
726
|
-
});
|
|
727
|
-
const existingMutation = findPendingMutationByIntent(operation.state, intentFingerprintHex);
|
|
728
|
-
let workingState = operation.state;
|
|
729
|
-
let replacementFixedInputs = null;
|
|
730
|
-
if (existingMutation !== null) {
|
|
731
|
-
const reconciled = await reconcilePendingCogMutation({
|
|
732
|
-
state: operation.state,
|
|
733
|
-
mutation: existingMutation,
|
|
734
|
-
provider,
|
|
735
|
-
nowUnixMs,
|
|
736
|
-
paths,
|
|
737
|
-
rpc,
|
|
738
|
-
walletName,
|
|
739
|
-
context: readContext,
|
|
740
|
-
});
|
|
741
|
-
workingState = reconciled.state;
|
|
742
|
-
if (reconciled.resolution === "confirmed" || reconciled.resolution === "live") {
|
|
743
|
-
const reuse = await resolvePendingMutationReuseDecision({
|
|
744
|
-
rpc,
|
|
745
|
-
walletName,
|
|
746
|
-
mutation: reconciled.mutation,
|
|
747
|
-
nextFeeSelection: feeSelection,
|
|
748
|
-
});
|
|
749
|
-
if (reuse.reuseExisting) {
|
|
750
|
-
return {
|
|
751
|
-
kind: "lock",
|
|
752
|
-
txid: reconciled.mutation.attemptedTxid ?? "unknown",
|
|
753
|
-
status: reconciled.resolution,
|
|
754
|
-
reusedExisting: true,
|
|
755
|
-
amountCogtoshi,
|
|
756
|
-
recipientDomainName: normalizedRecipientDomainName,
|
|
757
|
-
resolved: operation.resolved,
|
|
758
|
-
fees: reuse.fees,
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
replacementFixedInputs = reuse.replacementFixedInputs;
|
|
762
|
-
}
|
|
763
|
-
if (reconciled.resolution === "repair-required") {
|
|
764
|
-
throw new Error("wallet_lock_repair_required");
|
|
765
|
-
}
|
|
587
|
+
},
|
|
588
|
+
async resolveExistingMutation({ operation, existingMutation, execution }) {
|
|
589
|
+
if (existingMutation === null) {
|
|
590
|
+
return { state: operation.state, replacementFixedInputs: null, result: null };
|
|
766
591
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
592
|
+
return resolveExistingWalletMutation({
|
|
593
|
+
existingMutation,
|
|
594
|
+
execution,
|
|
595
|
+
repairRequiredErrorCode: "wallet_lock_repair_required",
|
|
596
|
+
reconcileExistingMutation: (mutation) => reconcilePendingCogMutation({
|
|
597
|
+
state: operation.state,
|
|
598
|
+
mutation,
|
|
599
|
+
provider: execution.provider,
|
|
600
|
+
nowUnixMs: execution.nowUnixMs,
|
|
601
|
+
paths: execution.paths,
|
|
602
|
+
rpc: execution.rpc,
|
|
603
|
+
walletName: execution.walletName,
|
|
604
|
+
context: execution.readContext,
|
|
605
|
+
}),
|
|
606
|
+
createReuseResult: ({ mutation, resolution, fees }) => ({
|
|
607
|
+
kind: "lock",
|
|
608
|
+
txid: mutation.attemptedTxid ?? "unknown",
|
|
609
|
+
status: resolution,
|
|
610
|
+
reusedExisting: true,
|
|
611
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
612
|
+
recipientDomainName: operation.normalizedRecipientDomainName,
|
|
613
|
+
resolved: operation.resolved,
|
|
614
|
+
fees,
|
|
615
|
+
}),
|
|
790
616
|
});
|
|
617
|
+
},
|
|
618
|
+
confirm({ operation }) {
|
|
619
|
+
return confirmLock(options.prompter, operation.resolved, operation.amountCogtoshi, operation.normalizedRecipientDomainName, operation.timeoutHeight, options.assumeYes);
|
|
620
|
+
},
|
|
621
|
+
createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
|
|
622
|
+
return {
|
|
623
|
+
mutation: createDraftMutation({
|
|
624
|
+
kind: "lock",
|
|
625
|
+
sender: operation.sender,
|
|
626
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
627
|
+
recipientDomainName: operation.normalizedRecipientDomainName,
|
|
628
|
+
timeoutHeight: operation.timeoutHeight,
|
|
629
|
+
conditionHex: operation.conditionHex,
|
|
630
|
+
intentFingerprintHex,
|
|
631
|
+
nowUnixMs: execution.nowUnixMs,
|
|
632
|
+
feeSelection: execution.feeSelection,
|
|
633
|
+
existing: existingMutation,
|
|
634
|
+
}),
|
|
635
|
+
prepared: null,
|
|
636
|
+
};
|
|
637
|
+
},
|
|
638
|
+
async build({ operation, state, execution, replacementFixedInputs }) {
|
|
791
639
|
const lockPlan = buildPlanForCogOperation({
|
|
792
|
-
state
|
|
793
|
-
allUtxos: await rpc.listUnspent(walletName, 1),
|
|
640
|
+
state,
|
|
641
|
+
allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
|
|
794
642
|
sender: operation.sender,
|
|
795
|
-
opReturnData: serializeCogLock(amountCogtoshi, timeoutHeight, recipientDomain.domainId,
|
|
643
|
+
opReturnData: serializeCogLock(operation.amountCogtoshi, operation.timeoutHeight, operation.recipientDomain.domainId, Buffer.from(operation.conditionHex, "hex")).opReturnData,
|
|
796
644
|
errorPrefix: "wallet_lock",
|
|
797
645
|
});
|
|
798
|
-
|
|
799
|
-
rpc,
|
|
800
|
-
walletName,
|
|
801
|
-
state
|
|
646
|
+
return buildTransaction({
|
|
647
|
+
rpc: execution.rpc,
|
|
648
|
+
walletName: execution.walletName,
|
|
649
|
+
state,
|
|
802
650
|
plan: {
|
|
803
651
|
...lockPlan,
|
|
804
652
|
fixedInputs: mergeFixedWalletInputs(lockPlan.fixedInputs, replacementFixedInputs),
|
|
805
653
|
},
|
|
806
|
-
feeRateSatVb: feeSelection.feeRateSatVb,
|
|
654
|
+
feeRateSatVb: execution.feeSelection.feeRateSatVb,
|
|
807
655
|
});
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
656
|
+
},
|
|
657
|
+
publish({ state, execution, built, mutation }) {
|
|
658
|
+
return publishWalletMutation({
|
|
659
|
+
rpc: execution.rpc,
|
|
660
|
+
walletName: execution.walletName,
|
|
661
|
+
snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
|
|
812
662
|
built,
|
|
813
|
-
mutation
|
|
814
|
-
state
|
|
815
|
-
provider,
|
|
816
|
-
nowUnixMs,
|
|
817
|
-
paths,
|
|
663
|
+
mutation,
|
|
664
|
+
state,
|
|
665
|
+
provider: execution.provider,
|
|
666
|
+
nowUnixMs: execution.nowUnixMs,
|
|
667
|
+
paths: execution.paths,
|
|
818
668
|
errorPrefix: "wallet_lock",
|
|
819
669
|
});
|
|
670
|
+
},
|
|
671
|
+
createResult({ operation, mutation, built, status, reusedExisting, fees }) {
|
|
820
672
|
return {
|
|
821
673
|
kind: "lock",
|
|
822
|
-
txid:
|
|
823
|
-
status:
|
|
824
|
-
reusedExisting
|
|
825
|
-
amountCogtoshi,
|
|
826
|
-
recipientDomainName: normalizedRecipientDomainName,
|
|
674
|
+
txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
|
|
675
|
+
status: status,
|
|
676
|
+
reusedExisting,
|
|
677
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
678
|
+
recipientDomainName: operation.normalizedRecipientDomainName,
|
|
827
679
|
resolved: operation.resolved,
|
|
828
|
-
fees
|
|
829
|
-
selection: feeSelection,
|
|
830
|
-
built,
|
|
831
|
-
}),
|
|
680
|
+
fees,
|
|
832
681
|
};
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
await miningPreemption.release();
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
finally {
|
|
840
|
-
await controlLock.release();
|
|
841
|
-
}
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
return execution.result;
|
|
842
685
|
}
|
|
843
686
|
async function runClaimLikeMutation(options, reclaim) {
|
|
844
|
-
const provider = options.provider ?? createDefaultWalletSecretProvider();
|
|
845
|
-
const nowUnixMs = options.nowUnixMs ?? Date.now();
|
|
846
|
-
const paths = options.paths ?? resolveWalletRuntimePathsForTesting();
|
|
847
|
-
const controlLock = await acquireFileLock(paths.walletControlLockPath, {
|
|
848
|
-
purpose: reclaim ? "wallet-reclaim" : "wallet-claim",
|
|
849
|
-
walletRootId: null,
|
|
850
|
-
});
|
|
851
687
|
const preimageHex = reclaim ? ZERO_PREIMAGE_HEX : options.preimageHex;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
const errorPrefix = reclaim ? "wallet_reclaim" : "wallet_claim";
|
|
867
|
-
const intentFingerprintHex = createIntentFingerprint([
|
|
688
|
+
const errorPrefix = reclaim ? "wallet_reclaim" : "wallet_claim";
|
|
689
|
+
const execution = await executeWalletMutationOperation({
|
|
690
|
+
...options,
|
|
691
|
+
controlLockPurpose: reclaim ? "wallet-reclaim" : "wallet-claim",
|
|
692
|
+
preemptionReason: reclaim ? "wallet-reclaim" : "wallet-claim",
|
|
693
|
+
resolveOperation(readContext) {
|
|
694
|
+
return {
|
|
695
|
+
...resolveClaimSender(readContext, options.lockId, preimageHex, reclaim),
|
|
696
|
+
preimageHex,
|
|
697
|
+
errorPrefix,
|
|
698
|
+
};
|
|
699
|
+
},
|
|
700
|
+
createIntentFingerprint(operation) {
|
|
701
|
+
return createIntentFingerprint([
|
|
868
702
|
reclaim ? "reclaim" : "claim",
|
|
869
703
|
operation.state.walletRootId,
|
|
870
704
|
operation.sender.scriptPubKeyHex,
|
|
871
705
|
operation.lockId,
|
|
872
|
-
preimageHex,
|
|
706
|
+
operation.preimageHex,
|
|
873
707
|
]);
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
walletRootId: operation.state.walletRootId,
|
|
879
|
-
});
|
|
880
|
-
const rpc = (options.rpcFactory ?? createRpcClient)(node.rpc);
|
|
881
|
-
const walletName = operation.state.managedCoreWallet.walletName;
|
|
882
|
-
const feeSelection = await resolveWalletMutationFeeSelection({
|
|
883
|
-
rpc,
|
|
884
|
-
feeRateSatVb: options.feeRateSatVb ?? null,
|
|
885
|
-
});
|
|
886
|
-
const existingMutation = findPendingMutationByIntent(operation.state, intentFingerprintHex);
|
|
887
|
-
let workingState = operation.state;
|
|
888
|
-
let replacementFixedInputs = null;
|
|
889
|
-
if (existingMutation !== null) {
|
|
890
|
-
const reconciled = await reconcilePendingCogMutation({
|
|
891
|
-
state: operation.state,
|
|
892
|
-
mutation: existingMutation,
|
|
893
|
-
provider,
|
|
894
|
-
nowUnixMs,
|
|
895
|
-
paths,
|
|
896
|
-
rpc,
|
|
897
|
-
walletName,
|
|
898
|
-
context: readContext,
|
|
899
|
-
});
|
|
900
|
-
workingState = reconciled.state;
|
|
901
|
-
if (reconciled.resolution === "confirmed" || reconciled.resolution === "live") {
|
|
902
|
-
const reuse = await resolvePendingMutationReuseDecision({
|
|
903
|
-
rpc,
|
|
904
|
-
walletName,
|
|
905
|
-
mutation: reconciled.mutation,
|
|
906
|
-
nextFeeSelection: feeSelection,
|
|
907
|
-
});
|
|
908
|
-
if (reuse.reuseExisting) {
|
|
909
|
-
return {
|
|
910
|
-
kind: "claim",
|
|
911
|
-
txid: reconciled.mutation.attemptedTxid ?? "unknown",
|
|
912
|
-
status: reconciled.resolution,
|
|
913
|
-
reusedExisting: true,
|
|
914
|
-
amountCogtoshi: operation.amountCogtoshi,
|
|
915
|
-
recipientDomainName: operation.recipientDomainName,
|
|
916
|
-
lockId: options.lockId,
|
|
917
|
-
resolved: operation.resolved,
|
|
918
|
-
fees: reuse.fees,
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
replacementFixedInputs = reuse.replacementFixedInputs;
|
|
922
|
-
}
|
|
923
|
-
if (reconciled.resolution === "repair-required") {
|
|
924
|
-
throw new Error(`${errorPrefix}_repair_required`);
|
|
925
|
-
}
|
|
708
|
+
},
|
|
709
|
+
async resolveExistingMutation({ operation, existingMutation, execution }) {
|
|
710
|
+
if (existingMutation === null) {
|
|
711
|
+
return { state: operation.state, replacementFixedInputs: null, result: null };
|
|
926
712
|
}
|
|
927
|
-
|
|
713
|
+
return resolveExistingWalletMutation({
|
|
714
|
+
existingMutation,
|
|
715
|
+
execution,
|
|
716
|
+
repairRequiredErrorCode: `${errorPrefix}_repair_required`,
|
|
717
|
+
reconcileExistingMutation: (mutation) => reconcilePendingCogMutation({
|
|
718
|
+
state: operation.state,
|
|
719
|
+
mutation,
|
|
720
|
+
provider: execution.provider,
|
|
721
|
+
nowUnixMs: execution.nowUnixMs,
|
|
722
|
+
paths: execution.paths,
|
|
723
|
+
rpc: execution.rpc,
|
|
724
|
+
walletName: execution.walletName,
|
|
725
|
+
context: execution.readContext,
|
|
726
|
+
}),
|
|
727
|
+
createReuseResult: ({ mutation, resolution, fees }) => ({
|
|
728
|
+
kind: "claim",
|
|
729
|
+
txid: mutation.attemptedTxid ?? "unknown",
|
|
730
|
+
status: resolution,
|
|
731
|
+
reusedExisting: true,
|
|
732
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
733
|
+
recipientDomainName: operation.recipientDomainName,
|
|
734
|
+
lockId: operation.lockId,
|
|
735
|
+
resolved: operation.resolved,
|
|
736
|
+
fees,
|
|
737
|
+
}),
|
|
738
|
+
});
|
|
739
|
+
},
|
|
740
|
+
confirm({ operation }) {
|
|
741
|
+
return confirmClaim(options.prompter, {
|
|
928
742
|
kind: reclaim ? "reclaim" : "claim",
|
|
929
|
-
lockId:
|
|
743
|
+
lockId: operation.lockId,
|
|
930
744
|
recipientDomainName: operation.recipientDomainName,
|
|
931
745
|
amountCogtoshi: operation.amountCogtoshi,
|
|
932
746
|
resolved: operation.resolved,
|
|
933
747
|
assumeYes: options.assumeYes,
|
|
934
748
|
});
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
749
|
+
},
|
|
750
|
+
createDraftMutation({ operation, existingMutation, execution, intentFingerprintHex }) {
|
|
751
|
+
return {
|
|
752
|
+
mutation: createDraftMutation({
|
|
753
|
+
kind: "claim",
|
|
754
|
+
sender: operation.sender,
|
|
755
|
+
amountCogtoshi: operation.amountCogtoshi,
|
|
756
|
+
recipientDomainName: operation.recipientDomainName,
|
|
757
|
+
lockId: operation.lockId,
|
|
758
|
+
preimageHex: operation.preimageHex,
|
|
759
|
+
intentFingerprintHex,
|
|
760
|
+
nowUnixMs: execution.nowUnixMs,
|
|
761
|
+
feeSelection: execution.feeSelection,
|
|
762
|
+
existing: existingMutation,
|
|
763
|
+
}),
|
|
764
|
+
prepared: null,
|
|
951
765
|
};
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
provider,
|
|
955
|
-
nowUnixMs,
|
|
956
|
-
paths,
|
|
957
|
-
});
|
|
766
|
+
},
|
|
767
|
+
async build({ operation, state, execution, replacementFixedInputs }) {
|
|
958
768
|
const claimPlan = buildPlanForCogOperation({
|
|
959
|
-
state
|
|
960
|
-
allUtxos: await rpc.listUnspent(walletName, 1),
|
|
769
|
+
state,
|
|
770
|
+
allUtxos: await execution.rpc.listUnspent(execution.walletName, 1),
|
|
961
771
|
sender: operation.sender,
|
|
962
|
-
opReturnData: serializeCogClaim(
|
|
772
|
+
opReturnData: serializeCogClaim(operation.lockId, Buffer.from(operation.preimageHex, "hex")).opReturnData,
|
|
963
773
|
errorPrefix,
|
|
964
774
|
});
|
|
965
|
-
|
|
966
|
-
rpc,
|
|
967
|
-
walletName,
|
|
968
|
-
state
|
|
775
|
+
return buildTransaction({
|
|
776
|
+
rpc: execution.rpc,
|
|
777
|
+
walletName: execution.walletName,
|
|
778
|
+
state,
|
|
969
779
|
plan: {
|
|
970
780
|
...claimPlan,
|
|
971
781
|
fixedInputs: mergeFixedWalletInputs(claimPlan.fixedInputs, replacementFixedInputs),
|
|
972
782
|
},
|
|
973
|
-
feeRateSatVb: feeSelection.feeRateSatVb,
|
|
783
|
+
feeRateSatVb: execution.feeSelection.feeRateSatVb,
|
|
974
784
|
});
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
785
|
+
},
|
|
786
|
+
publish({ state, execution, built, mutation }) {
|
|
787
|
+
return publishWalletMutation({
|
|
788
|
+
rpc: execution.rpc,
|
|
789
|
+
walletName: execution.walletName,
|
|
790
|
+
snapshotHeight: execution.readContext.snapshot?.tip?.height ?? null,
|
|
979
791
|
built,
|
|
980
|
-
mutation
|
|
981
|
-
state
|
|
982
|
-
provider,
|
|
983
|
-
nowUnixMs,
|
|
984
|
-
paths,
|
|
792
|
+
mutation,
|
|
793
|
+
state,
|
|
794
|
+
provider: execution.provider,
|
|
795
|
+
nowUnixMs: execution.nowUnixMs,
|
|
796
|
+
paths: execution.paths,
|
|
985
797
|
errorPrefix,
|
|
986
798
|
});
|
|
799
|
+
},
|
|
800
|
+
createResult({ operation, mutation, built, status, reusedExisting, fees }) {
|
|
987
801
|
return {
|
|
988
802
|
kind: "claim",
|
|
989
|
-
txid:
|
|
990
|
-
status:
|
|
991
|
-
reusedExisting
|
|
803
|
+
txid: mutation.attemptedTxid ?? built?.txid ?? "unknown",
|
|
804
|
+
status: status,
|
|
805
|
+
reusedExisting,
|
|
992
806
|
amountCogtoshi: operation.amountCogtoshi,
|
|
993
807
|
recipientDomainName: operation.recipientDomainName,
|
|
994
|
-
lockId:
|
|
808
|
+
lockId: operation.lockId,
|
|
995
809
|
resolved: operation.resolved,
|
|
996
|
-
fees
|
|
997
|
-
selection: feeSelection,
|
|
998
|
-
built,
|
|
999
|
-
}),
|
|
810
|
+
fees,
|
|
1000
811
|
};
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
await miningPreemption.release();
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
finally {
|
|
1008
|
-
await controlLock.release();
|
|
1009
|
-
}
|
|
812
|
+
},
|
|
813
|
+
});
|
|
814
|
+
return execution.result;
|
|
1010
815
|
}
|
|
1011
816
|
export async function claimCogLock(options) {
|
|
1012
817
|
return runClaimLikeMutation(options, false);
|