Files
seedPass/landing/docs/json_entries.html
2025-07-09 22:08:31 -04:00

704 lines
66 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>json_entries</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
/* The extra [class] is a hack that increases specificity enough to
override a similar rule in reveal.js */
ul.task-list[class]{list-style: none;}
ul.task-list li input[type="checkbox"] {
font-size: inherit;
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
/* CSS for syntax highlighting */
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { color: #008000; } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { color: #008000; font-weight: bold; } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="theme.css" />
</head>
<body>
<h1 id="seedpass-json-entry-management-and-extensibility">SeedPass JSON
Entry Management and Extensibility</h1>
<h2 id="table-of-contents">Table of Contents</h2>
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#json-schema-for-individual-entries">JSON Schema for
Individual Entries</a>
<ul>
<li><a href="#general-structure">General Structure</a></li>
<li><a href="#field-descriptions">Field Descriptions</a></li>
<li><a href="#example-entries">Example Entries</a></li>
</ul></li>
<li><a href="#handling-kind-types-and-extensibility">Handling
<code>kind</code> Types and Extensibility</a>
<ul>
<li><a href="#extensible-json-schema-design">Extensible JSON Schema
Design</a></li>
<li><a href="#ensuring-backward-compatibility">Ensuring Backward
Compatibility</a></li>
<li><a href="#best-practices-for-adding-new-kinds">Best Practices for
Adding New Kinds</a></li>
</ul></li>
<li><a href="#adding-new-kind-types">Adding New <code>kind</code>
Types</a>
<ul>
<li><a href="#example-adding-cryptocurrency_wallet">Example: Adding
<code>cryptocurrency_wallet</code></a></li>
</ul></li>
<li><a href="#backup-and-rollback-mechanism">Backup and Rollback
Mechanism</a></li>
<li><a href="#security-considerations">Security Considerations</a></li>
<li><a href="#updated-roadmap">Updated Roadmap</a>
<ul>
<li><a
href="#phase-1-core-functionality-and-security-enhancements">Phase 1:
Core Functionality and Security Enhancements</a></li>
<li><a href="#phase-2-enhanced-security-and-data-management">Phase 2:
Enhanced Security and Data Management</a></li>
<li><a href="#phase-3-advanced-cli-functionalities">Phase 3: Advanced
CLI Functionalities</a></li>
<li><a
href="#phase-4-data-management-enhancements-and-integrations">Phase 4:
Data Management Enhancements and Integrations</a></li>
<li><a href="#phase-5-documentation-testing-and-finalization">Phase 5:
Documentation, Testing, and Finalization</a></li>
<li><a href="#future-phases-beyond-initial-roadmap">Future Phases
(Beyond Initial Roadmap)</a></li>
</ul></li>
<li><a href="#summary">Summary</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
<hr />
<h2 id="introduction">Introduction</h2>
<p><strong>SeedPass</strong> is a secure password generator and manager
leveraging <strong>Bitcoins BIP-85 standard</strong> and integrating
with the <strong>Nostr network</strong> for decentralized
synchronization. Instead of pushing one large index file, SeedPass posts
<strong>snapshot chunks</strong> of the index followed by lightweight
<strong>delta events</strong> whenever changes occur. This chunked
approach improves reliability and keeps bandwidth usage minimal. To
enhance modularity, scalability, and security, SeedPass stores all
entries in a single encrypted index file named
<code>seedpass_entries_db.json.enc</code>. This document outlines the
entry management system, ensuring that new <code>kind</code> types can
be added seamlessly without disrupting existing functionalities.</p>
<hr />
<h2 id="index-file-format">Index File Format</h2>
<p>All entries belonging to a seed profile are stored in an encrypted
file named <code>seedpass_entries_db.json.enc</code>. This index uses
<code>schema_version</code> <code>3</code> and contains an
<code>entries</code> object keyed by numeric identifiers.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;schema_version&quot;</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entries&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;0&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;label&quot;</span><span class="fu">:</span> <span class="st">&quot;example.com&quot;</span><span class="fu">,</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;length&quot;</span><span class="fu">:</span> <span class="dv">8</span><span class="fu">,</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;username&quot;</span><span class="fu">:</span> <span class="st">&quot;user&quot;</span><span class="fu">,</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;url&quot;</span><span class="fu">:</span> <span class="st">&quot;https://example.com&quot;</span><span class="fu">,</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;archived&quot;</span><span class="fu">:</span> <span class="kw">false</span><span class="fu">,</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;type&quot;</span><span class="fu">:</span> <span class="st">&quot;password&quot;</span><span class="fu">,</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;password&quot;</span><span class="fu">,</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;notes&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span><span class="fu">,</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;custom_fields&quot;</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;origin&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<hr />
<h2 id="json-schema-for-individual-entries">JSON Schema for Individual
Entries</h2>
<p>Each entry is stored within <code>seedpass_entries_db.json.enc</code>
under the <code>entries</code> dictionary. The structure supports
diverse entry types (<code>kind</code>) and allows for future
expansions.</p>
<h3 id="general-structure">General Structure</h3>
<div class="sourceCode" id="cb2"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;label&quot;</span><span class="fu">:</span> <span class="st">&quot;Example&quot;</span><span class="fu">,</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;length&quot;</span><span class="fu">:</span> <span class="dv">8</span><span class="fu">,</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;username&quot;</span><span class="fu">:</span> <span class="st">&quot;user@example.com&quot;</span><span class="fu">,</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;url&quot;</span><span class="fu">:</span> <span class="st">&quot;https://example.com&quot;</span><span class="fu">,</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;archived&quot;</span><span class="fu">:</span> <span class="kw">false</span><span class="fu">,</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;type&quot;</span><span class="fu">:</span> <span class="st">&quot;password&quot;</span><span class="fu">,</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;password&quot;</span><span class="fu">,</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;notes&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span><span class="fu">,</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;custom_fields&quot;</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;origin&quot;</span><span class="fu">:</span> <span class="st">&quot;&quot;</span><span class="fu">,</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;tags&quot;</span><span class="fu">:</span> <span class="ot">[]</span><span class="fu">,</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index&quot;</span><span class="fu">:</span> <span class="dv">0</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h3 id="field-descriptions">Field Descriptions</h3>
<ul>
<li><p><strong>label</strong> (<code>string</code>): Descriptive name
for the entry (e.g., website or service).</p></li>
<li><p><strong>length</strong> (<code>integer</code>, optional): Desired
password length for generated passwords.</p></li>
<li><p><strong>username</strong> (<code>string</code>, optional):
Username associated with the entry.</p></li>
<li><p><strong>url</strong> (<code>string</code>, optional): Website or
service URL.</p></li>
<li><p><strong>archived</strong> (<code>boolean</code>): Marks the entry
as archived when <code>true</code>.</p></li>
<li><p><strong>type</strong> (<code>string</code>): The entry type
(<code>password</code>, <code>totp</code>, <code>ssh</code>,
<code>seed</code>, <code>pgp</code>, <code>nostr</code>,
<code>note</code>, <code>key_value</code>).</p></li>
<li><p><strong>kind</strong> (<code>string</code>): Synonym for
<code>type</code> kept for backward compatibility.</p></li>
<li><p><strong>notes</strong> (<code>string</code>): Free-form
notes.</p></li>
<li><p><strong>custom_fields</strong> (<code>array</code>, optional):
Additional user-defined fields.</p></li>
<li><p><strong>origin</strong> (<code>string</code>, optional): Source
identifier for imported data.</p></li>
<li><p><strong>value</strong> (<code>string</code>, optional): For
<code>key_value</code> entries, stores the secret value.</p></li>
<li><p><strong>index</strong> (<code>integer</code>, optional): BIP-85
derivation index for entries that derive material from a seed.</p></li>
<li><p><strong>word_count</strong> (<code>integer</code>,
managed_account only): Number of words in the child seed. Managed
accounts always use <code>12</code>.</p></li>
<li><p><strong>fingerprint</strong> (<code>string</code>,
managed_account only): Identifier of the child profile, used for its
directory name.</p></li>
<li><p><strong>tags</strong> (<code>array</code>, optional): Category
labels to aid in organization and search. Example:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="er">&quot;custom_fields&quot;:</span> <span class="ot">[</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;account_id&quot;</span><span class="fu">,</span> <span class="dt">&quot;value&quot;</span><span class="fu">:</span> <span class="st">&quot;123&quot;</span><span class="fu">}</span><span class="ot">,</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;recovery_hint&quot;</span><span class="fu">,</span> <span class="dt">&quot;value&quot;</span><span class="fu">:</span> <span class="st">&quot;mother&#39;s maiden name&quot;</span><span class="fu">}</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">]</span></span></code></pre></div></li>
</ul>
<h3 id="example-entries">Example Entries</h3>
<h4 id="generated-password">1. Generated Password</h4>
<div class="sourceCode" id="cb4"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;generated_password&quot;</span><span class="fu">,</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;title&quot;</span><span class="fu">:</span> <span class="st">&quot;Example Website&quot;</span><span class="fu">,</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;username&quot;</span><span class="fu">:</span> <span class="st">&quot;user@example.com&quot;</span><span class="fu">,</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;email&quot;</span><span class="fu">:</span> <span class="st">&quot;user@example.com&quot;</span><span class="fu">,</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;url&quot;</span><span class="fu">:</span> <span class="st">&quot;https://example.com&quot;</span><span class="fu">,</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;password&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_password&gt;&quot;</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;custom_fields&quot;</span><span class="fu">:</span> <span class="ot">[</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">{</span><span class="dt">&quot;name&quot;</span><span class="fu">:</span> <span class="st">&quot;department&quot;</span><span class="fu">,</span> <span class="dt">&quot;value&quot;</span><span class="fu">:</span> <span class="st">&quot;finance&quot;</span><span class="fu">}</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a> <span class="ot">]</span><span class="fu">,</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;tags&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;work&quot;</span><span class="ot">]</span><span class="fu">,</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;abc123def456&quot;</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="stored-password">2. Stored Password</h4>
<div class="sourceCode" id="cb5"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">1</span><span class="fu">,</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;q1wec4d426fs&quot;</span><span class="fu">,</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;stored_password&quot;</span><span class="fu">,</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;title&quot;</span><span class="fu">:</span> <span class="st">&quot;Another Service&quot;</span><span class="fu">,</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;username&quot;</span><span class="fu">:</span> <span class="st">&quot;another_user&quot;</span><span class="fu">,</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;password&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_password&gt;&quot;</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:35:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:35:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:35:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;def789ghi012&quot;</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="managed-user">3. Managed User</h4>
<div class="sourceCode" id="cb6"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">2</span><span class="fu">,</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4e5f6&quot;</span><span class="fu">,</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;managed_user&quot;</span><span class="fu">,</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;users_password&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_users_password&gt;&quot;</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:36:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:36:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:36:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;ghi345jkl678&quot;</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="word-seed">4. 12 Word Seed</h4>
<div class="sourceCode" id="cb7"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">3</span><span class="fu">,</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;f7g8h9i0j1k2&quot;</span><span class="fu">,</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;12_word_seed&quot;</span><span class="fu">,</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;seed_phrase&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_seed_phrase&gt;&quot;</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:37:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:37:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:37:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;jkl901mno234&quot;</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="nostr-keys">5. Nostr Keys</h4>
<div class="sourceCode" id="cb8"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">4</span><span class="fu">,</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;l3m4n5o6p7q8&quot;</span><span class="fu">,</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;nostr_keys&quot;</span><span class="fu">,</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;public_key&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;public_key&gt;&quot;</span><span class="fu">,</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;private_key&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_private_key&gt;&quot;</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:38:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:38:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:38:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;mno567pqr890&quot;</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="note">6. Note</h4>
<div class="sourceCode" id="cb9"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">5</span><span class="fu">,</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;r9s0t1u2v3w4&quot;</span><span class="fu">,</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;note&quot;</span><span class="fu">,</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;content&quot;</span><span class="fu">:</span> <span class="st">&quot;This is a secure note.&quot;</span><span class="fu">,</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;tags&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;personal&quot;</span><span class="ot">,</span> <span class="st">&quot;secure&quot;</span><span class="ot">]</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:39:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:39:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:39:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;pqr345stu678&quot;</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="keyvalue">7. Key/Value</h4>
<div class="sourceCode" id="cb10"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">6</span><span class="fu">,</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;key_value&quot;</span><span class="fu">,</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;key&quot;</span><span class="fu">:</span> <span class="st">&quot;api_key&quot;</span><span class="fu">,</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;value&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_value&gt;&quot;</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;tags&quot;</span><span class="fu">:</span> <span class="ot">[</span><span class="st">&quot;api&quot;</span><span class="ot">]</span><span class="fu">,</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:40:56Z&quot;</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="managed-account">8. Managed Account</h4>
<div class="sourceCode" id="cb11"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">7</span><span class="fu">,</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;managed_account&quot;</span><span class="fu">,</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;account&quot;</span><span class="fu">:</span> <span class="st">&quot;alice@example.com&quot;</span><span class="fu">,</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;password&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_password&gt;&quot;</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:41:56Z&quot;</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<p>Managed accounts store a child seed derived from the parent profile.
The entry is saved under
<code>.seedpass/&lt;parent_fp&gt;/accounts/&lt;child_fp&gt;</code> where
<code>&lt;child_fp&gt;</code> is the managed accounts fingerprint. When
loaded, the CLI displays a breadcrumb like
<code>&lt;parent_fp&gt; &gt; Managed Account &gt; &lt;child_fp&gt;</code>.
Press <strong>Enter</strong> on the main menu to exit back to the parent
profile.</p>
<p>The <code>key</code> field is purely descriptive, while
<code>value</code> holds the sensitive string such as an API token.
Notes and custom fields may also be included alongside the standard
metadata.</p>
<hr />
<h2 id="handling-kind-types-and-extensibility">Handling
<code>kind</code> Types and Extensibility</h2>
<h3 id="extensible-json-schema-design">Extensible JSON Schema
Design</h3>
<p>The JSON schema is designed to be <strong>extensible</strong> and
<strong>forward-compatible</strong>, allowing new <code>kind</code>
types to be added without impacting existing functionalities.</p>
<h4 id="a.-core-structure">a. Core Structure</h4>
<p>Each entry is encapsulated in its own JSON file with a standardized
structure:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="dv">0</span><span class="fu">,</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;generated_password&quot;</span><span class="fu">,</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> <span class="er">//</span> <span class="er">Fields</span> <span class="er">specific</span> <span class="er">to</span> <span class="er">the</span> <span class="er">kind</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:34:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;checksum_value&gt;&quot;</span></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="b.-the-kind-field">b. The <code>kind</code> Field</h4>
<ul>
<li><strong>Purpose:</strong> Specifies the type of entry.</li>
<li><strong>Flexibility:</strong> As a simple string identifier, new
<code>kind</code> values can be introduced without altering the existing
schema.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="er">&quot;kind&quot;:</span> <span class="er">&quot;cryptocurrency_wallet&quot;</span></span></code></pre></div>
<h4 id="c.-the-data-object">c. The <code>data</code> Object</h4>
<ul>
<li><strong>Purpose:</strong> Contains fields specific to the
<code>kind</code>.</li>
<li><strong>Extensibility:</strong> Each <code>kind</code> can define
its unique set of fields without affecting others.</li>
</ul>
<p><strong>Example for a New Kind
(<code>cryptocurrency_wallet</code>):</strong></p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="er">&quot;data&quot;:</span> <span class="fu">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;wallet_name&quot;</span><span class="fu">:</span> <span class="st">&quot;My Bitcoin Wallet&quot;</span><span class="fu">,</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;address&quot;</span><span class="fu">:</span> <span class="st">&quot;1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa&quot;</span><span class="fu">,</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;private_key&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_private_key&gt;&quot;</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h3 id="ensuring-backward-compatibility">Ensuring Backward
Compatibility</h3>
<p>To maintain compatibility as new <code>kind</code> types are
introduced, implement the following practices:</p>
<h4 id="a.-graceful-handling-of-unknown-kinds">a. Graceful Handling of
Unknown Kinds</h4>
<ul>
<li><strong>Implementation:</strong> When encountering an unrecognized
<code>kind</code>, handle it gracefully by ignoring the entry, logging a
warning, or providing a default handling mechanism.</li>
<li><strong>Benefit:</strong> Prevents the application from crashing or
misbehaving due to unrecognized <code>kind</code> types.</li>
</ul>
<p><strong>Pseudo-Code Example:</strong></p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> process_entry(entry):</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> kind <span class="op">=</span> entry.get(<span class="st">&quot;kind&quot;</span>)</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> data <span class="op">=</span> entry.get(<span class="st">&quot;data&quot;</span>)</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> fingerprint <span class="op">=</span> entry.get(<span class="st">&quot;fingerprint&quot;</span>)</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> kind <span class="op">==</span> <span class="st">&quot;generated_password&quot;</span>:</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a> handle_generated_password(data, fingerprint)</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">&quot;stored_password&quot;</span>:</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a> handle_stored_password(data, fingerprint)</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a> <span class="co"># ... other known kinds ...</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a> log_warning(<span class="ss">f&quot;Unknown kind: </span><span class="sc">{</span>kind<span class="sc">}</span><span class="ss">. Skipping entry.&quot;</span>)</span></code></pre></div>
<h4 id="b.-versioning-the-schema">b. Versioning the Schema</h4>
<ul>
<li><strong>Implementation:</strong> Introduce a
<code>schema_version</code> or <code>seedpass_version</code> field to
indicate the version of the JSON schema being used.</li>
<li><strong>Benefit:</strong> Facilitates future updates and migrations
by clearly identifying the schema version.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="er">&quot;seedpass_version&quot;:</span> <span class="er">&quot;1.0.0&quot;</span></span></code></pre></div>
<h4 id="c.-documentation-and-standards">c. Documentation and
Standards</h4>
<ul>
<li><strong>Maintain Clear Documentation:</strong> Keep comprehensive
documentation for each <code>kind</code>, detailing required and
optional fields.</li>
<li><strong>Adhere to Standards:</strong> Follow consistent naming
conventions and data types to ensure uniformity across different
<code>kind</code> types.</li>
</ul>
<h3 id="best-practices-for-adding-new-kinds">Best Practices for Adding
New Kinds</h3>
<p>To ensure seamless integration of new <code>kind</code> types in the
future, consider the following best practices:</p>
<h4 id="a.-consistent-naming-conventions">a. Consistent Naming
Conventions</h4>
<ul>
<li><strong>Use Clear and Descriptive Names:</strong> Aids in
readability and maintenance.</li>
<li><strong>Avoid Reserved Keywords:</strong> Ensure <code>kind</code>
names do not clash with existing or future reserved keywords within the
application or JSON standards.</li>
</ul>
<h4 id="b.-modular-code-architecture">b. Modular Code Architecture</h4>
<ul>
<li><strong>Separate Handlers:</strong> Implement separate functions or
modules for handling each <code>kind</code>. Promotes code modularity
and easier maintenance.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co"># handlers.py</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_generated_password(data, fingerprint):</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_stored_password(data, fingerprint):</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a> <span class="co"># Implementation</span></span></code></pre></div>
<h4 id="c.-validation-and-error-handling">c. Validation and Error
Handling</h4>
<ul>
<li><strong>Validate Data Fields:</strong> Ensure each <code>kind</code>
has the necessary fields before processing.</li>
<li><strong>Handle Missing or Extra Fields:</strong> Implement logic to
manage incomplete or unexpected data gracefully.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a> required_fields <span class="op">=</span> [<span class="st">&quot;wallet_name&quot;</span>, <span class="st">&quot;address&quot;</span>, <span class="st">&quot;private_key&quot;</span>]</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> field <span class="kw">in</span> required_fields:</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> field <span class="kw">not</span> <span class="kw">in</span> data:</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">raise</span> <span class="pp">ValueError</span>(<span class="ss">f&quot;Missing required field &#39;</span><span class="sc">{</span>field<span class="sc">}</span><span class="ss">&#39; in cryptocurrency_wallet entry.&quot;</span>)</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a> <span class="co"># Proceed with processing</span></span></code></pre></div>
<h4 id="d.-backward-compatibility-testing">d. Backward Compatibility
Testing</h4>
<ul>
<li><strong>Automated Tests:</strong> Develop tests that verify the
applications ability to handle both existing and new <code>kind</code>
types.</li>
<li><strong>Regression Testing:</strong> Ensure adding new kinds does
not inadvertently affect existing functionalities.</li>
</ul>
<hr />
<h2 id="adding-new-kind-types">Adding New <code>kind</code> Types</h2>
<p>Adding new <code>kind</code> types is straightforward due to the
extensible JSON schema design. Below is a step-by-step guide to adding a
new <code>kind</code> without affecting existing functionalities.</p>
<h3 id="example-adding-cryptocurrency_wallet">Example: Adding
<code>cryptocurrency_wallet</code></h3>
<h4 id="a.-define-the-new-kind-structure">a. Define the New Kind
Structure</h4>
<p>Create a JSON file following the standardized structure with the new
<code>kind</code> value.</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode json"><code class="sourceCode json"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="fu">{</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;entry_num&quot;</span><span class="fu">:</span> <span class="dv">6</span><span class="fu">,</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;index_num&quot;</span><span class="fu">:</span> <span class="st">&quot;x1y2z3a4b5c6&quot;</span><span class="fu">,</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;fingerprint&quot;</span><span class="fu">:</span> <span class="st">&quot;a1b2c3d4&quot;</span><span class="fu">,</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;kind&quot;</span><span class="fu">:</span> <span class="st">&quot;cryptocurrency_wallet&quot;</span><span class="fu">,</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;data&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;wallet_name&quot;</span><span class="fu">:</span> <span class="st">&quot;My Bitcoin Wallet&quot;</span><span class="fu">,</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;address&quot;</span><span class="fu">:</span> <span class="st">&quot;1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa&quot;</span><span class="fu">,</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;private_key&quot;</span><span class="fu">:</span> <span class="st">&quot;&lt;encrypted_private_key&gt;&quot;</span></span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a> <span class="fu">},</span></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;timestamp&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:40:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;metadata&quot;</span><span class="fu">:</span> <span class="fu">{</span></span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;created_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:40:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;updated_at&quot;</span><span class="fu">:</span> <span class="st">&quot;2024-04-27T12:40:56Z&quot;</span><span class="fu">,</span></span>
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a> <span class="dt">&quot;checksum&quot;</span><span class="fu">:</span> <span class="st">&quot;stu901vwx234&quot;</span></span>
<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">}</span></span>
<span id="cb19-17"><a href="#cb19-17" aria-hidden="true" tabindex="-1"></a><span class="fu">}</span></span></code></pre></div>
<h4 id="b.-update-the-application-to-handle-the-new-kind">b. Update the
Application to Handle the New Kind</h4>
<p><strong>Implement Handler Function:</strong></p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> handle_cryptocurrency_wallet(data, fingerprint):</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a> wallet_name <span class="op">=</span> data.get(<span class="st">&quot;wallet_name&quot;</span>)</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a> address <span class="op">=</span> data.get(<span class="st">&quot;address&quot;</span>)</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a> private_key <span class="op">=</span> decrypt(data.get(<span class="st">&quot;private_key&quot;</span>))</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a> <span class="co"># Process the cryptocurrency wallet entry</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a> <span class="co"># e.g., store in memory, display to user, etc.</span></span></code></pre></div>
<p><strong>Integrate the Handler:</strong></p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> process_entry(entry):</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a> kind <span class="op">=</span> entry.get(<span class="st">&quot;kind&quot;</span>)</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a> data <span class="op">=</span> entry.get(<span class="st">&quot;data&quot;</span>)</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a> fingerprint <span class="op">=</span> entry.get(<span class="st">&quot;fingerprint&quot;</span>)</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> kind <span class="op">==</span> <span class="st">&quot;generated_password&quot;</span>:</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a> handle_generated_password(data, fingerprint)</span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">&quot;stored_password&quot;</span>:</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a> handle_stored_password(data, fingerprint)</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">elif</span> kind <span class="op">==</span> <span class="st">&quot;cryptocurrency_wallet&quot;</span>:</span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a> handle_cryptocurrency_wallet(data, fingerprint)</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a> <span class="co"># ... other known kinds ...</span></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a> log_warning(<span class="ss">f&quot;Unknown kind: </span><span class="sc">{</span>kind<span class="sc">}</span><span class="ss">. Skipping entry.&quot;</span>)</span></code></pre></div>
<h4 id="c.-no-impact-on-existing-kinds">c. No Impact on Existing
Kinds</h4>
<p>Existing kinds such as <code>generated_password</code>,
<code>stored_password</code>, etc., continue to operate without any
changes. The introduction of <code>cryptocurrency_wallet</code> is
additive and does not interfere with the processing of other kinds.</p>
<hr />
<h2 id="backup-and-rollback-mechanism">Backup and Rollback
Mechanism</h2>
<p>To ensure data integrity and provide recovery options, SeedPass
implements a robust backup and rollback system within the
<strong>Fingerprint-Based Backup and Local Storage</strong>
framework.</p>
<h3 id="backup-directory-structure">Backup Directory Structure</h3>
<p>All backups are organized based on fingerprints, ensuring that each
seeds data remains isolated and secure.</p>
<pre><code>~/.seedpass/
├── a1b2c3d4/
│ ├── entries/
│ │ ├── entry_0.json
│ │ ├── entry_1.json
│ │ └── ...
│ ├── backups/
│ │ ├── entry_0_v1.json
│ │ ├── entry_0_v2.json
│ │ ├── entry_1_v1.json
│ │ └── ...
│ ├── parent_seed.enc
│ ├── seedpass_entries_db_checksum.txt
│ └── seedpass_entries_db.json
├── b5c6d7e8/
│ ├── entries/
│ │ ├── entry_0.json
│ │ ├── entry_1.json
│ │ └── ...
│ ├── backups/
│ │ ├── entry_0_v1.json
│ │ ├── entry_0_v2.json
│ │ ├── entry_1_v1.json
│ │ └── ...
│ ├── parent_seed.enc
│ ├── seedpass_entries_db_checksum.txt
│ └── seedpass_entries_db.json
└── ...</code></pre>
<h3 id="backup-process">Backup Process</h3>
<ol type="1">
<li><strong>Upon Modifying an Entry:</strong>
<ul>
<li>The current version of the entry is copied to the
<code>backups/</code> directory within the corresponding fingerprint
folder with a version suffix (e.g., <code>entry_0_v1.json</code>).</li>
<li>The modified entry is saved in the <code>entries/</code> directory
within the same fingerprint folder.</li>
</ul></li>
<li><strong>Versioning:</strong>
<ul>
<li>Each backup file includes a version number to track changes over
time.</li>
</ul></li>
</ol>
<h3 id="rollback-functionality">Rollback Functionality</h3>
<ul>
<li><strong>Restoring an Entry:</strong>
<ul>
<li>Users can select a backup version from the <code>backups/</code>
directory within the specific fingerprint folder.</li>
<li>The selected backup file is copied back to the <code>entries/</code>
directory, replacing the current version.</li>
</ul></li>
</ul>
<p><strong>Example Command:</strong></p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ex">seedpass</span> rollback <span class="at">--fingerprint</span> a1b2c3d4 <span class="at">--file</span> entry_0_v1.json</span></code></pre></div>
<p><strong>Example Directory Structure After Rollback:</strong></p>
<pre><code>~/.seedpass/
├── a1b2c3d4/
│ ├── entries/
│ │ ├── entry_0.json # Restored from entry_0_v1.json
│ │ ├── entry_1.json
│ │ └── ...
│ ├── backups/
│ │ ├── entry_0_v1.json
│ │ ├── entry_0_v2.json
│ │ ├── entry_1_v1.json
│ │ └── ...
│ ├── parent_seed.enc
│ ├── seedpass_script_checksum.txt
│ ├── seedpass_entries_db_checksum.txt
│ └── seedpass_entries_db.json
├── ...</code></pre>
<p><em>Note: Restoring a backup overwrites the current entry. Ensure
that you intend to revert to the selected backup before
proceeding.</em></p>
</body>
</html>