#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 ); } }