diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp
--- a/src/rpc/avalanche.cpp
+++ b/src/rpc/avalanche.cpp
@@ -147,10 +147,6 @@
     RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM,
                                   UniValue::VSTR, UniValue::VARR});
 
-    if (!g_avalanche) {
-        throw JSONRPCError(RPC_INTERNAL_ERROR, "Avalanche is not initialized");
-    }
-
     const uint64_t sequence = request.params[0].get_int64();
     const int64_t expiration = request.params[1].get_int64();
     avalanche::ProofBuilder pb(sequence, expiration,
@@ -209,6 +205,90 @@
     return HexStr(ss);
 }
 
+static UniValue decodeavalancheproof(const Config &config,
+                                     const JSONRPCRequest &request) {
+    RPCHelpMan{
+        "decodeavalancheproof",
+        "Convert a serialized, hex-encoded proof, into JSON object. "
+        "The validity of the proof is not verified.\n",
+        {
+            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO,
+             "The proof hex string"},
+        },
+        RPCResult{
+            RPCResult::Type::OBJ,
+            "",
+            "",
+            {
+                {RPCResult::Type::NUM, "sequence",
+                 "The proof's sequential number"},
+                {RPCResult::Type::NUM, "expiration",
+                 "A timestamp indicating when the proof expires"},
+                {RPCResult::Type::STR_HEX, "master", "The master public key"},
+                {RPCResult::Type::STR_HEX, "proofid",
+                 "The proof's unique identifier"},
+                {RPCResult::Type::ARR,
+                 "stakes",
+                 "",
+                 {
+                     {RPCResult::Type::OBJ,
+                      "",
+                      "",
+                      {
+                          {RPCResult::Type::STR_HEX, "txid",
+                           "The transaction id"},
+                          {RPCResult::Type::NUM, "vout", "The output number"},
+                          {RPCResult::Type::STR_AMOUNT, "amount",
+                           "The amount in this UTXO"},
+                          {RPCResult::Type::NUM, "height",
+                           "The height at which this UTXO was mined"},
+                          {RPCResult::Type::BOOL, "iscoinbase",
+                           "Indicate whether the UTXO is a coinbase"},
+                          {RPCResult::Type::STR_HEX, "pubkey",
+                           "This UTXO's public key"},
+                          {RPCResult::Type::STR_HEX, "signature",
+                           "Signature of the proofid with this UTXO's private "
+                           "key"},
+                      }},
+                 }},
+            }},
+        RPCExamples{HelpExampleCli("decodeavalancheproof", "\"<hex proof>\"") +
+                    HelpExampleRpc("decodeavalancheproof", "\"<hex proof>\"")},
+    }
+        .Check(request);
+
+    RPCTypeCheck(request.params, {UniValue::VSTR});
+
+    avalanche::Proof proof;
+    bilingual_str error;
+    if (!avalanche::Proof::FromHex(proof, request.params[0].get_str(), error)) {
+        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, error.original);
+    }
+
+    UniValue result(UniValue::VOBJ);
+    result.pushKV("sequence", proof.getSequence());
+    result.pushKV("expiration", proof.getExpirationTime());
+    result.pushKV("master", HexStr(proof.getMaster()));
+    result.pushKV("proofid", proof.getId().ToString());
+
+    UniValue stakes(UniValue::VARR);
+    for (avalanche::SignedStake s : proof.getStakes()) {
+        COutPoint utxo = s.getStake().getUTXO();
+        UniValue stake(UniValue::VOBJ);
+        stake.pushKV("txid", utxo.GetTxId().GetHex());
+        stake.pushKV("vout", int64_t(utxo.GetN()));
+        stake.pushKV("amount", ValueFromAmount(s.getStake().getAmount()));
+        stake.pushKV("height", uint64_t(s.getStake().getHeight()));
+        stake.pushKV("iscoinbase", s.getStake().isCoinbase());
+        stake.pushKV("pubkey", HexStr(s.getStake().getPubkey()));
+        stake.pushKV("signature", HexStr(s.getSignature()));
+        stakes.push_back(stake);
+    }
+    result.pushKV("stakes", stakes);
+
+    return result;
+}
+
 static UniValue delegateavalancheproof(const Config &config,
                                        const JSONRPCRequest &request) {
     RPCHelpMan{
@@ -448,6 +528,7 @@
         { "avalanche",          "getavalanchekey",        getavalanchekey,        {}},
         { "avalanche",          "addavalanchenode",       addavalanchenode,       {"nodeid"}},
         { "avalanche",          "buildavalancheproof",    buildavalancheproof,    {"sequence", "expiration", "master", "stakes"}},
+        { "avalanche",          "decodeavalancheproof",   decodeavalancheproof,   {"proof"}},
         { "avalanche",          "delegateavalancheproof", delegateavalancheproof, {"proof", "privatekey", "publickey", "delegation"}},
         { "avalanche",          "getavalanchepeerinfo",   getavalanchepeerinfo,   {}},
         { "avalanche",          "verifyavalancheproof",   verifyavalancheproof,   {"proof"}},
diff --git a/test/functional/abc_rpc_avalancheproof.py b/test/functional/abc_rpc_avalancheproof.py
--- a/test/functional/abc_rpc_avalancheproof.py
+++ b/test/functional/abc_rpc_avalancheproof.py
@@ -10,12 +10,17 @@
     create_stakes,
 )
 from test_framework.key import ECKey, bytes_to_wif
-from test_framework.messages import AvalancheDelegation
+from test_framework.messages import (
+    AvalancheDelegation,
+    AvalancheProof,
+    FromHex,
+)
 from test_framework.mininode import P2PInterface
 from test_framework.test_framework import BitcoinTestFramework
 from test_framework.test_node import ErrorMatch
 from test_framework.util import (
     append_config,
+    assert_equal,
     wait_until,
     assert_raises_rpc_error,
 )
@@ -62,9 +67,33 @@
         proof_master = get_hex_pubkey(privkey)
         proof_sequence = 11
         proof_expiration = 12
+        stakes = create_coinbase_stakes(node, [blockhashes[0]], addrkey0.key)
         proof = node.buildavalancheproof(
-            proof_sequence, proof_expiration, proof_master,
-            create_coinbase_stakes(node, [blockhashes[0]], addrkey0.key))
+            proof_sequence, proof_expiration, proof_master, stakes)
+
+        self.log.info("Test decodeavalancheproof RPC")
+        proofobj = FromHex(AvalancheProof(), proof)
+        decodedproof = node.decodeavalancheproof(proof)
+        assert_equal(decodedproof["sequence"], proof_sequence)
+        assert_equal(decodedproof["expiration"], proof_expiration)
+        assert_equal(decodedproof["master"], proof_master)
+        assert_equal(decodedproof["proofid"], f"{proofobj.proofid:0{64}x}")
+        assert_equal(decodedproof["stakes"][0]["txid"], stakes[0]["txid"])
+        assert_equal(decodedproof["stakes"][0]["vout"], stakes[0]["vout"])
+        assert_equal(decodedproof["stakes"][0]["height"], stakes[0]["height"])
+        assert_equal(
+            decodedproof["stakes"][0]["iscoinbase"],
+            stakes[0]["iscoinbase"])
+        assert_equal(
+            decodedproof["stakes"][0]["signature"],
+            proofobj.stakes[0].sig.hex())
+
+        # Invalid hex (odd number of hex digits)
+        assert_raises_rpc_error(-22, "Proof must be an hexadecimal string",
+                                node.decodeavalancheproof, proof[:-1])
+        # Valid hex but invalid proof
+        assert_raises_rpc_error(-22, "Proof has invalid format",
+                                node.decodeavalancheproof, proof[:-2])
 
         # Restart the node, making sure it is initially in IBD mode
         minchainwork = int(node.getblockchaininfo()["chainwork"], 16) + 1