#nullable enable
using System.Security.Claims;
using System.Threading.Tasks;
using BTCPayServer.Client;
using BTCPayServer.Data;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using NBitcoin;
using NBXplorer;
namespace BTCPayServer.Plugins.Wallets;
public class HotwalletSafe(
StoreRepository storeRepository,
IAuthorizationService authorizationService,
ExplorerClientProvider explorerClientProvider,
PaymentMethodHandlerDictionary handlers)
{
///
/// Represents the result of successfully unlocking a store hot wallet, including the wallet key material
/// and the permissions granted to the current user.
///
/// The store that owns the wallet.
/// The user for whom the wallet was unlocked.
/// The derivation scheme settings associated with the wallet.
/// The master extended private key used by the hot wallet.
/// The mnemonic phrase associated with the hot wallet, if available.
/// Whether the user is authorized to sign wallet transactions.
/// Whether the user is authorized to see the seed.
public record HotwalletRecord(StoreData Store, ClaimsPrincipal User, DerivationSchemeSettings Settings, ExtKey ExtKey, string? Mnemonic, bool CanSign, bool CanSee);
public async Task TryUnlock(ClaimsPrincipal user, WalletId walletId)
{
var store = await storeRepository.FindStore(walletId.StoreId, user);
if (store is null)
return null;
var client = explorerClientProvider.GetExplorerClient(walletId.CryptoCode);
var d = store.GetDerivationSchemeSettings(handlers, walletId.CryptoCode);
if (d?.IsHotWallet is not true)
return null;
var metadata = await client.GetMetadataAsync(d.AccountDerivation, WellknownMetadataKeys.MasterHDKey);
if (string.IsNullOrWhiteSpace(metadata))
return null;
var mnemo = await client.GetMetadataAsync(d.AccountDerivation, WellknownMetadataKeys.Mnemonic);
return new(
store,
user,
d,
client.Network.NBitcoinNetwork.Parse(metadata).ExtKey,
mnemo,
(await authorizationService.AuthorizeAsync(user, walletId.StoreId, WalletPolicies.CanSignWalletTransactions)).Succeeded,
(await authorizationService.AuthorizeAsync(user, walletId.StoreId, Policies.CanModifyStoreSettings)).Succeeded
);
}
}