Table of Contents

Class SingleKeyVtxoRecoveryService

Namespace
NArk.Core.Recovery
Assembly
NArk.Core.dll

Recovery for SingleKey wallets. There is no derivation index to scan: the flat tr(pubkey) descriptor yields one candidate set. We probe every IContractDiscoveryProvider ONCE with that descriptor; the indexer provider internally probes { current signer ∪ deprecated signers } (IndexerVtxoDiscoveryProvider.BuildCandidates), so funds stranded under a rotated signer are discovered. Discovered contracts are persisted Active.

public class SingleKeyVtxoRecoveryService : ISingleKeyDefaultEnsurer
Inheritance
SingleKeyVtxoRecoveryService
Implements
Inherited Members

Constructors

SingleKeyVtxoRecoveryService(IEnumerable<IContractDiscoveryProvider>, IWalletStorage, IContractStorage, IClientTransport, ILogger<SingleKeyVtxoRecoveryService>?)

Recovery for SingleKey wallets. There is no derivation index to scan: the flat tr(pubkey) descriptor yields one candidate set. We probe every IContractDiscoveryProvider ONCE with that descriptor; the indexer provider internally probes { current signer ∪ deprecated signers } (IndexerVtxoDiscoveryProvider.BuildCandidates), so funds stranded under a rotated signer are discovered. Discovered contracts are persisted Active.

public SingleKeyVtxoRecoveryService(IEnumerable<IContractDiscoveryProvider> providers, IWalletStorage walletStorage, IContractStorage contractStorage, IClientTransport clientTransport, ILogger<SingleKeyVtxoRecoveryService>? logger = null)

Parameters

providers IEnumerable<IContractDiscoveryProvider>
walletStorage IWalletStorage
contractStorage IContractStorage
clientTransport IClientTransport
logger ILogger<SingleKeyVtxoRecoveryService>

Methods

DiscoverAsync(string, CancellationToken)

public Task<int> DiscoverAsync(string walletId, CancellationToken cancellationToken = default)

Parameters

walletId string
cancellationToken CancellationToken

Returns

Task<int>

EnsureDefaultAsync(string, CancellationToken)

Idempotently ensures the SingleKey wallet's CURRENT-signer default contract exists (Active, Source="Default"). The canonical default is the ArkPaymentContract under the current ArkServerInfo.SignerKey — the very contract StoreOverview / the dashboard render. We build it DIRECTLY rather than via the SendToSelf provider path, because GetNextContract(NextContractPurpose, ContractActivityState, ArkContract[]?, CancellationToken) redirects SendToSelf to the sweep Destination (as an Inactive UnknownArkContract) when one is configured; going through that path would return the destination's script and let the reconciler deactivate the genuine payment default. Persisting upserts on {Script, WalletId}, so this is a no-op when the current default already exists, and after a signer rotation it creates the new-signer default. Deactivating the stale old-signer default is the reconciliation service's job, not this one.

public Task<string> EnsureDefaultAsync(string walletId, CancellationToken cancellationToken = default)

Parameters

walletId string
cancellationToken CancellationToken

Returns

Task<string>

The script hex of the ensured current-signer Default contract.