diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -130,7 +130,7 @@
         }
         bool getPubKey(const CScript &script, const CKeyID &address,
                        CPubKey &pub_key) override {
-            const SigningProvider *provider =
+            std::unique_ptr<SigningProvider> provider =
                 m_wallet->GetSigningProvider(script);
             if (provider) {
                 return provider->GetPubKey(address, pub_key);
@@ -139,7 +139,7 @@
         }
         bool getPrivKey(const CScript &script, const CKeyID &address,
                         CKey &key) override {
-            const SigningProvider *provider =
+            std::unique_ptr<SigningProvider> provider =
                 m_wallet->GetSigningProvider(script);
             if (provider) {
                 return provider->GetKey(address, key);
diff --git a/src/wallet/psbtwallet.cpp b/src/wallet/psbtwallet.cpp
--- a/src/wallet/psbtwallet.cpp
+++ b/src/wallet/psbtwallet.cpp
@@ -54,27 +54,28 @@
         }
         SignatureData sigdata;
         input.FillSignatureData(sigdata);
-        const SigningProvider *provider =
+        std::unique_ptr<SigningProvider> provider =
             pwallet->GetSigningProvider(script, sigdata);
         if (!provider) {
             complete = false;
             continue;
         }
 
-        complete &=
-            SignPSBTInput(HidingSigningProvider(provider, !sign, !bip32derivs),
-                          psbtx, i, sighash_type);
+        complete &= SignPSBTInput(
+            HidingSigningProvider(provider.get(), !sign, !bip32derivs), psbtx,
+            i, sighash_type);
     }
 
     // Fill in the bip32 keypaths and redeemscripts for the outputs so that
     // hardware wallets can identify change
     for (size_t i = 0; i < psbtx.tx->vout.size(); ++i) {
         const CTxOut &out = psbtx.tx->vout.at(i);
-        const SigningProvider *provider =
+        std::unique_ptr<SigningProvider> provider =
             pwallet->GetSigningProvider(out.scriptPubKey);
         if (provider) {
             UpdatePSBTOutput(
-                HidingSigningProvider(provider, true, !bip32derivs), psbtx, i);
+                HidingSigningProvider(provider.get(), true, !bip32derivs),
+                psbtx, i);
         }
     }
 
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -628,7 +628,7 @@
     }
 
     CScript script_pub_key = GetScriptForDestination(*pkhash);
-    const SigningProvider *provider =
+    std::unique_ptr<SigningProvider> provider =
         pwallet->GetSigningProvider(script_pub_key);
     if (!provider) {
         throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
@@ -3545,7 +3545,7 @@
                 entry.pushKV("label", address_book_entry->GetLabel());
             }
 
-            const SigningProvider *provider =
+            std::unique_ptr<SigningProvider> provider =
                 pwallet->GetSigningProvider(scriptPubKey);
             if (provider) {
                 if (scriptPubKey.IsPayToScriptHash()) {
@@ -3568,7 +3568,7 @@
         entry.pushKV("spendable", out.fSpendable);
         entry.pushKV("solvable", out.fSolvable);
         if (out.fSolvable) {
-            const SigningProvider *provider =
+            std::unique_ptr<SigningProvider> provider =
                 pwallet->GetSigningProvider(scriptPubKey);
             if (provider) {
                 auto descriptor = InferDescriptor(scriptPubKey, *provider);
@@ -3927,23 +3927,23 @@
     // Parse the prevtxs array
     ParsePrevouts(request.params[1], nullptr, coins);
 
-    std::set<const SigningProvider *> providers;
+    std::set<std::shared_ptr<SigningProvider>> providers;
     for (const std::pair<COutPoint, Coin> coin_pair : coins) {
-        const SigningProvider *provider = pwallet->GetSigningProvider(
+        std::unique_ptr<SigningProvider> provider = pwallet->GetSigningProvider(
             coin_pair.second.GetTxOut().scriptPubKey);
         if (provider) {
             providers.insert(std::move(provider));
         }
     }
     if (providers.size() == 0) {
-        // When there are no available providers, use DUMMY_SIGNING_PROVIDER so
+        // When there are no available providers, use a dummy SigningProvider so
         // we can check if the tx is complete
-        providers.insert(&DUMMY_SIGNING_PROVIDER);
+        providers.insert(std::make_shared<SigningProvider>());
     }
 
     UniValue result(UniValue::VOBJ);
-    for (const SigningProvider *provider : providers) {
-        SignTransaction(mtx, provider, coins, request.params[2], result);
+    for (std::shared_ptr<SigningProvider> provider : providers) {
+        SignTransaction(mtx, provider.get(), coins, request.params[2], result);
     }
     return result;
 }
@@ -4134,13 +4134,13 @@
     UniValue ret(UniValue::VOBJ);
     UniValue detail = DescribeAddress(dest);
     CScript script = GetScriptForDestination(dest);
-    const SigningProvider *provider = nullptr;
+    std::unique_ptr<SigningProvider> provider = nullptr;
     if (pwallet) {
         provider = pwallet->GetSigningProvider(script);
     }
     ret.pushKVs(detail);
-    ret.pushKVs(
-        boost::apply_visitor(DescribeWalletAddressVisitor(provider), dest));
+    ret.pushKVs(boost::apply_visitor(
+        DescribeWalletAddressVisitor(provider.get()), dest));
     return ret;
 }
 
@@ -4279,7 +4279,8 @@
     ret.pushKV("scriptPubKey",
                HexStr(scriptPubKey.begin(), scriptPubKey.end()));
 
-    const SigningProvider *provider = pwallet->GetSigningProvider(scriptPubKey);
+    std::unique_ptr<SigningProvider> provider =
+        pwallet->GetSigningProvider(scriptPubKey);
 
     isminetype mine = pwallet->IsMine(dest);
     ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE));
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -234,7 +234,7 @@
         return nullptr;
     }
 
-    virtual const SigningProvider *
+    virtual std::unique_ptr<SigningProvider>
     GetSigningProvider(const CScript &script) const {
         return nullptr;
     }
@@ -408,7 +408,7 @@
 
     bool CanGetAddresses(bool internal = false) override;
 
-    const SigningProvider *
+    std::unique_ptr<SigningProvider>
     GetSigningProvider(const CScript &script) const override;
 
     bool CanProvide(const CScript &script, SignatureData &sigdata) override;
@@ -532,4 +532,34 @@
     std::set<CKeyID> GetKeys() const override;
 };
 
+/** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr
+ */
+class LegacySigningProvider : public SigningProvider {
+private:
+    const LegacyScriptPubKeyMan &m_spk_man;
+
+public:
+    LegacySigningProvider(const LegacyScriptPubKeyMan &spk_man)
+        : m_spk_man(spk_man) {}
+
+    bool GetCScript(const CScriptID &scriptid, CScript &script) const override {
+        return m_spk_man.GetCScript(scriptid, script);
+    }
+    bool HaveCScript(const CScriptID &scriptid) const override {
+        return m_spk_man.HaveCScript(scriptid);
+    }
+    bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const override {
+        return m_spk_man.GetPubKey(address, pubkey);
+    }
+    bool GetKey(const CKeyID &address, CKey &key) const override {
+        return m_spk_man.GetKey(address, key);
+    }
+    bool HaveKey(const CKeyID &address) const override {
+        return m_spk_man.HaveKey(address);
+    }
+    bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const override {
+        return m_spk_man.GetKeyOrigin(keyid, info);
+    }
+};
+
 #endif // BITCOIN_WALLET_SCRIPTPUBKEYMAN_H
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -427,9 +427,9 @@
     return nTimeFirstKey;
 }
 
-const SigningProvider *
+std::unique_ptr<SigningProvider>
 LegacyScriptPubKeyMan::GetSigningProvider(const CScript &script) const {
-    return this;
+    return std::make_unique<LegacySigningProvider>(*this);
 }
 
 bool LegacyScriptPubKeyMan::CanProvide(const CScript &script,
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -1429,9 +1429,10 @@
     ScriptPubKeyMan *GetScriptPubKeyMan(const uint256 &id) const;
 
     //! Get the SigningProvider for a script
-    const SigningProvider *GetSigningProvider(const CScript &script) const;
-    const SigningProvider *GetSigningProvider(const CScript &script,
-                                              SignatureData &sigdata) const;
+    std::unique_ptr<SigningProvider>
+    GetSigningProvider(const CScript &script) const;
+    std::unique_ptr<SigningProvider>
+    GetSigningProvider(const CScript &script, SignatureData &sigdata) const;
 
     //! Get the LegacyScriptPubKeyMan which is used for all types, internal, and
     //! external.
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1501,7 +1501,8 @@
     const CScript &scriptPubKey = txout.scriptPubKey;
     SignatureData sigdata;
 
-    const SigningProvider *provider = GetSigningProvider(scriptPubKey);
+    std::unique_ptr<SigningProvider> provider =
+        GetSigningProvider(scriptPubKey);
     if (!provider) {
         // We don't know about this scriptpbuKey;
         return false;
@@ -2400,7 +2401,7 @@
                 continue;
             }
 
-            const SigningProvider *provider =
+            std::unique_ptr<SigningProvider> provider =
                 GetSigningProvider(wtx.tx->vout[i].scriptPubKey);
 
             bool solvable =
@@ -2732,7 +2733,8 @@
         SignatureData sigdata;
         SigHashType sigHashType = SigHashType().withForkId();
 
-        const SigningProvider *provider = GetSigningProvider(scriptPubKey);
+        std::unique_ptr<SigningProvider> provider =
+            GetSigningProvider(scriptPubKey);
         if (!provider) {
             // We don't know about this scriptpbuKey;
             return false;
@@ -3216,7 +3218,7 @@
                 const CScript &scriptPubKey = coin.txout.scriptPubKey;
                 SignatureData sigdata;
 
-                const SigningProvider *provider =
+                std::unique_ptr<SigningProvider> provider =
                     GetSigningProvider(scriptPubKey);
                 if (!provider ||
                     !ProduceSignature(
@@ -4709,13 +4711,13 @@
     return nullptr;
 }
 
-const SigningProvider *
+std::unique_ptr<SigningProvider>
 CWallet::GetSigningProvider(const CScript &script) const {
     SignatureData sigdata;
     return GetSigningProvider(script, sigdata);
 }
 
-const SigningProvider *
+std::unique_ptr<SigningProvider>
 CWallet::GetSigningProvider(const CScript &script,
                             SignatureData &sigdata) const {
     for (const auto &spk_man_pair : m_spk_managers) {