This commit is contained in:
thePR0M3TH3AN
2025-07-11 15:26:48 -04:00
parent 4f4dda1fa2
commit d261a244a0
9 changed files with 0 additions and 1831 deletions

View File

@@ -1,114 +0,0 @@
<!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>README</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-documentation">SeedPass Documentation</h1>
<p>This directory contains supplementary guides for using SeedPass.</p>
<h2 id="quick-example-get-a-totp-code">Quick Example: Get a TOTP
Code</h2>
<p>Run <code>seedpass entry get &lt;query&gt;</code> to retrieve a
time-based one-time password (TOTP). The <code>&lt;query&gt;</code> can
be a label, title, or index. A progress bar shows the remaining seconds
in the current period.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> seedpass entry get <span class="st">&quot;email&quot;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">[##########----------]</span> 15s</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">Code:</span> 123456</span></code></pre></div>
<p>To show all stored TOTP codes with their countdown timers, run:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> seedpass entry totp-codes</span></code></pre></div>
<h2 id="cli-and-api-reference">CLI and API Reference</h2>
<p>See <a href="advanced_cli.html">advanced_cli.html</a> for a list of
command examples. Detailed information about the REST API is available
in <a href="api_reference.html">api_reference.html</a>. When starting the
API, set <code>SEEDPASS_CORS_ORIGINS</code> if you need to allow
requests from specific web origins.</p>
</body>
</html>

View File

@@ -1,613 +0,0 @@
<!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>advanced_cli</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-advanced-cli-and-api-documentation">SeedPass Advanced
CLI and API Documentation</h1>
<h2 id="overview">Overview</h2>
<p>Welcome to the <strong>Advanced CLI and API Documentation</strong>
for <strong>SeedPass</strong>, a secure, deterministic password manager
built on Bitcoins BIP85 standard. This guide is designed for power
users, developers, and system administrators who wish to leverage the
full capabilities of SeedPass through the command line for scripting,
automation, and integration.</p>
<p>SeedPass uses a <code>noun-verb</code> command structure (e.g.,
<code>seedpass entry get &lt;query&gt;</code>) for a clear, scalable,
and discoverable interface. You can explore the available actions for
any command group with the <code>--help</code> flag (for example,
<code>seedpass entry --help</code>).</p>
<p>The commands in this document reflect the Typer-based CLI shipped
with SeedPass. Each command accepts the optional
<code>--fingerprint</code> flag to operate on a specific seed
profile.</p>
<hr />
<h2 id="table-of-contents">Table of Contents</h2>
<ol type="1">
<li><a href="#global-options">Global Options</a></li>
<li><a href="#command-group-reference">Command Group Reference</a>
<ul>
<li><a href="#entry-commands">Entry Commands</a></li>
<li><a href="#vault-commands">Vault Commands</a></li>
<li><a href="#nostr-commands">Nostr Commands</a></li>
<li><a href="#config-commands">Config Commands</a></li>
<li><a href="#fingerprint-commands">Fingerprint Commands</a></li>
<li><a href="#utility-commands">Utility Commands</a></li>
<li><a href="#api-commands">API Commands</a></li>
</ul></li>
<li><a href="#detailed-command-descriptions">Detailed Command
Descriptions</a></li>
<li><a href="#api-integration">API Integration</a></li>
<li><a href="#usage-guidelines">Usage Guidelines</a></li>
</ol>
<hr />
<h2 id="global-options">Global Options</h2>
<p>These options can be used with any command.</p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Flag</th>
<th style="text-align: left;">Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;"><code>--fingerprint &lt;fp&gt;</code></td>
<td style="text-align: left;">Specify which seed profile to use. If
omitted, the most recently used profile is selected.</td>
</tr>
<tr class="even">
<td style="text-align: left;"><code>--help</code>, <code>-h</code></td>
<td style="text-align: left;">Display help information for a command or
subcommand.</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="command-group-reference">Command Group Reference</h2>
<h3 id="entry-commands">Entry Commands</h3>
<p>Manage individual entries within a vault.</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">List entries</td>
<td style="text-align: left;"><code>entry list</code></td>
<td
style="text-align: left;"><code>seedpass entry list --sort label</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Search for entries</td>
<td style="text-align: left;"><code>entry search</code></td>
<td
style="text-align: left;"><code>seedpass entry search "GitHub"</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Retrieve an entrys secret (password or
TOTP code)</td>
<td style="text-align: left;"><code>entry get</code></td>
<td
style="text-align: left;"><code>seedpass entry get "GitHub"</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a password entry</td>
<td style="text-align: left;"><code>entry add</code></td>
<td
style="text-align: left;"><code>seedpass entry add Example --length 16</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add a TOTP entry</td>
<td style="text-align: left;"><code>entry add-totp</code></td>
<td
style="text-align: left;"><code>seedpass entry add-totp Email --secret JBSW...</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add an SSH key entry</td>
<td style="text-align: left;"><code>entry add-ssh</code></td>
<td
style="text-align: left;"><code>seedpass entry add-ssh Server --index 0</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add a PGP key entry</td>
<td style="text-align: left;"><code>entry add-pgp</code></td>
<td
style="text-align: left;"><code>seedpass entry add-pgp Personal --user-id me@example.com</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a Nostr key entry</td>
<td style="text-align: left;"><code>entry add-nostr</code></td>
<td
style="text-align: left;"><code>seedpass entry add-nostr Chat</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add a seed phrase entry</td>
<td style="text-align: left;"><code>entry add-seed</code></td>
<td
style="text-align: left;"><code>seedpass entry add-seed Backup --words 24</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a key/value entry</td>
<td style="text-align: left;"><code>entry add-key-value</code></td>
<td
style="text-align: left;"><code>seedpass entry add-key-value "API Token" --value abc123</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Add a managed account entry</td>
<td
style="text-align: left;"><code>entry add-managed-account</code></td>
<td
style="text-align: left;"><code>seedpass entry add-managed-account Trading</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Modify an entry</td>
<td style="text-align: left;"><code>entry modify</code></td>
<td
style="text-align: left;"><code>seedpass entry modify 1 --username alice</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Archive an entry</td>
<td style="text-align: left;"><code>entry archive</code></td>
<td style="text-align: left;"><code>seedpass entry archive 1</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Unarchive an entry</td>
<td style="text-align: left;"><code>entry unarchive</code></td>
<td
style="text-align: left;"><code>seedpass entry unarchive 1</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Export all TOTP secrets</td>
<td style="text-align: left;"><code>entry export-totp</code></td>
<td
style="text-align: left;"><code>seedpass entry export-totp --file totp.json</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Show all TOTP codes</td>
<td style="text-align: left;"><code>entry totp-codes</code></td>
<td
style="text-align: left;"><code>seedpass entry totp-codes</code></td>
</tr>
</tbody>
</table>
<h3 id="vault-commands">Vault Commands</h3>
<p>Manage the entire vault for a profile.</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Export the vault</td>
<td style="text-align: left;"><code>vault export</code></td>
<td
style="text-align: left;"><code>seedpass vault export --file backup.json</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Import a vault</td>
<td style="text-align: left;"><code>vault import</code></td>
<td
style="text-align: left;"><code>seedpass vault import --file backup.json</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Change the master password</td>
<td style="text-align: left;"><code>vault change-password</code></td>
<td
style="text-align: left;"><code>seedpass vault change-password</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Lock the vault</td>
<td style="text-align: left;"><code>vault lock</code></td>
<td style="text-align: left;"><code>seedpass vault lock</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Show profile statistics</td>
<td style="text-align: left;"><code>vault stats</code></td>
<td style="text-align: left;"><code>seedpass vault stats</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Reveal or back up the parent seed</td>
<td style="text-align: left;"><code>vault reveal-parent-seed</code></td>
<td
style="text-align: left;"><code>seedpass vault reveal-parent-seed --file backup.enc</code></td>
</tr>
</tbody>
</table>
<h3 id="nostr-commands">Nostr Commands</h3>
<p>Interact with the Nostr network for backup and synchronization.</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Sync with relays</td>
<td style="text-align: left;"><code>nostr sync</code></td>
<td style="text-align: left;"><code>seedpass nostr sync</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Get public key</td>
<td style="text-align: left;"><code>nostr get-pubkey</code></td>
<td
style="text-align: left;"><code>seedpass nostr get-pubkey</code></td>
</tr>
</tbody>
</table>
<h3 id="config-commands">Config Commands</h3>
<p>Manage profilespecific settings.</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Get a setting value</td>
<td style="text-align: left;"><code>config get</code></td>
<td
style="text-align: left;"><code>seedpass config get inactivity_timeout</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Set a setting value</td>
<td style="text-align: left;"><code>config set</code></td>
<td
style="text-align: left;"><code>seedpass config set inactivity_timeout 300</code></td>
</tr>
</tbody>
</table>
<h3 id="fingerprint-commands">Fingerprint Commands</h3>
<p>Manage seed profiles (fingerprints).</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">List all profiles</td>
<td style="text-align: left;"><code>fingerprint list</code></td>
<td
style="text-align: left;"><code>seedpass fingerprint list</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Add a profile</td>
<td style="text-align: left;"><code>fingerprint add</code></td>
<td style="text-align: left;"><code>seedpass fingerprint add</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Remove a profile</td>
<td style="text-align: left;"><code>fingerprint remove</code></td>
<td
style="text-align: left;"><code>seedpass fingerprint remove &lt;fp&gt;</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Switch profile</td>
<td style="text-align: left;"><code>fingerprint switch</code></td>
<td
style="text-align: left;"><code>seedpass fingerprint switch &lt;fp&gt;</code></td>
</tr>
</tbody>
</table>
<h3 id="utility-commands">Utility Commands</h3>
<p>Miscellaneous helper commands.</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Generate a password</td>
<td style="text-align: left;"><code>util generate-password</code></td>
<td
style="text-align: left;"><code>seedpass util generate-password --length 24</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Verify script checksum</td>
<td style="text-align: left;"><code>util verify-checksum</code></td>
<td
style="text-align: left;"><code>seedpass util verify-checksum</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Update script checksum</td>
<td style="text-align: left;"><code>util update-checksum</code></td>
<td
style="text-align: left;"><code>seedpass util update-checksum</code></td>
</tr>
</tbody>
</table>
<h3 id="api-commands">API Commands</h3>
<p>Run or stop the local HTTP API.</p>
<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Action</th>
<th style="text-align: left;">Command</th>
<th style="text-align: left;">Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Start the API</td>
<td style="text-align: left;"><code>api start</code></td>
<td
style="text-align: left;"><code>seedpass api start --host 0.0.0.0 --port 8000</code></td>
</tr>
<tr class="even">
<td style="text-align: left;">Stop the API</td>
<td style="text-align: left;"><code>api stop</code></td>
<td style="text-align: left;"><code>seedpass api stop</code></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="detailed-command-descriptions">Detailed Command
Descriptions</h2>
<h3 id="entry-commands-1"><code>entry</code> Commands</h3>
<ul>
<li><strong><code>seedpass entry list</code></strong> List entries in
the vault, optionally sorted or filtered.</li>
<li><strong><code>seedpass entry search &lt;query&gt;</code></strong>
Search across labels, usernames, URLs and notes.</li>
<li><strong><code>seedpass entry get &lt;query&gt;</code></strong>
Retrieve the password or TOTP code for one matching entry, depending on
the entrys type.</li>
<li><strong><code>seedpass entry add &lt;label&gt;</code></strong>
Create a new password entry. Use <code>--length</code> to set the
password length and optional <code>--username</code>/<code>--url</code>
values.</li>
<li><strong><code>seedpass entry add-totp &lt;label&gt;</code></strong>
Create a TOTP entry. Use <code>--secret</code> to import an existing
secret or <code>--index</code> to derive from the seed.</li>
<li><strong><code>seedpass entry add-ssh &lt;label&gt;</code></strong>
Create an SSH key entry derived from the seed.</li>
<li><strong><code>seedpass entry add-pgp &lt;label&gt;</code></strong>
Create a PGP key entry. Provide <code>--user-id</code> and
<code>--key-type</code> as needed.</li>
<li><strong><code>seedpass entry add-nostr &lt;label&gt;</code></strong>
Create a Nostr key entry for decentralised chat.</li>
<li><strong><code>seedpass entry add-seed &lt;label&gt;</code></strong>
Store a derived seed phrase. Use <code>--words</code> to set the word
count.</li>
<li><strong><code>seedpass entry add-key-value &lt;label&gt;</code></strong>
Store arbitrary data with <code>--value</code>.</li>
<li><strong><code>seedpass entry add-managed-account &lt;label&gt;</code></strong>
Store a BIP85 derived account seed.</li>
<li><strong><code>seedpass entry modify &lt;id&gt;</code></strong>
Update an entrys label, username, URL or notes.</li>
<li><strong><code>seedpass entry archive &lt;id&gt;</code></strong>
Mark an entry as archived so it is hidden from normal lists.</li>
<li><strong><code>seedpass entry unarchive &lt;id&gt;</code></strong>
Restore an archived entry.</li>
<li><strong><code>seedpass entry export-totp --file &lt;path&gt;</code></strong>
Export all stored TOTP secrets to a JSON file.</li>
<li><strong><code>seedpass entry totp-codes</code></strong> Display
all current TOTP codes with remaining time.</li>
</ul>
<p>Example retrieving a TOTP code:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> seedpass entry get <span class="st">&quot;email&quot;</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">[##########----------]</span> 15s</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">Code:</span> 123456</span></code></pre></div>
<h3 id="vault-commands-1"><code>vault</code> Commands</h3>
<ul>
<li><strong><code>seedpass vault export</code></strong> Export the
entire vault to an encrypted JSON file.</li>
<li><strong><code>seedpass vault import</code></strong> Import a vault
from an encrypted JSON file.</li>
<li><strong><code>seedpass vault change-password</code></strong>
Change the master password used for encryption.</li>
<li><strong><code>seedpass vault lock</code></strong> Clear sensitive
data from memory and require reauthentication.</li>
<li><strong><code>seedpass vault stats</code></strong> Display
statistics about the active seed profile.</li>
<li><strong><code>seedpass vault reveal-parent-seed</code></strong>
Print the parent seed or write an encrypted backup with
<code>--file</code>.</li>
</ul>
<h3 id="nostr-commands-1"><code>nostr</code> Commands</h3>
<ul>
<li><strong><code>seedpass nostr sync</code></strong> Perform a
twoway sync with configured Nostr relays.</li>
<li><strong><code>seedpass nostr get-pubkey</code></strong> Display
the Nostr public key for the active profile.</li>
</ul>
<h3 id="config-commands-1"><code>config</code> Commands</h3>
<ul>
<li><strong><code>seedpass config get &lt;key&gt;</code></strong>
Retrieve a configuration value such as <code>inactivity_timeout</code>,
<code>secret_mode</code>, or <code>auto_sync</code>.</li>
<li><strong><code>seedpass config set &lt;key&gt; &lt;value&gt;</code></strong>
Update a configuration option. Example:
<code>seedpass config set inactivity_timeout 300</code>.</li>
<li><strong><code>seedpass config toggle-secret-mode</code></strong>
Interactively enable or disable Secret Mode and set the clipboard
delay.</li>
</ul>
<h3 id="fingerprint-commands-1"><code>fingerprint</code> Commands</h3>
<ul>
<li><strong><code>seedpass fingerprint list</code></strong> List
available profiles by fingerprint.</li>
<li><strong><code>seedpass fingerprint add</code></strong> Create a
new seed profile.</li>
<li><strong><code>seedpass fingerprint remove &lt;fp&gt;</code></strong>
Delete the specified profile.</li>
<li><strong><code>seedpass fingerprint switch &lt;fp&gt;</code></strong>
Switch the active profile.</li>
</ul>
<h3 id="util-commands"><code>util</code> Commands</h3>
<ul>
<li><strong><code>seedpass util generate-password</code></strong>
Generate a strong password of the requested length.</li>
<li><strong><code>seedpass util verify-checksum</code></strong> Verify
the SeedPass script checksum.</li>
<li><strong><code>seedpass util update-checksum</code></strong>
Regenerate the script checksum file.</li>
</ul>
<hr />
<h2 id="api-integration">API Integration</h2>
<p>SeedPass provides a small REST API for automation. Run
<code>seedpass api start</code> to launch the server. The command prints
a onetime token which clients must include in the
<code>Authorization</code> header.</p>
<p>Set the <code>SEEDPASS_CORS_ORIGINS</code> environment variable to a
commaseparated list of allowed origins when you need crossorigin
requests:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="va">SEEDPASS_CORS_ORIGINS</span><span class="op">=</span>http://localhost:3000 <span class="ex">seedpass</span> api start</span></code></pre></div>
<p>Shut down the server with <code>seedpass api stop</code>.</p>
<hr />
<h2 id="usage-guidelines">Usage Guidelines</h2>
<ul>
<li>Use the <code>--help</code> flag for details on any command.</li>
<li>Set a strong master password and regularly export encrypted
backups.</li>
<li>Adjust configuration values like <code>inactivity_timeout</code> or
<code>secret_mode</code> through the <code>config</code> commands.</li>
<li><code>entry get</code> is scriptfriendly and can be piped into
other commands.</li>
</ul>
</body>
</html>

View File

@@ -1,320 +0,0 @@
<!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>api_reference</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-rest-api-reference">SeedPass REST API Reference</h1>
<p>This guide covers how to start the SeedPass API, authenticate
requests, and interact with the available endpoints.</p>
<h2 id="starting-the-api">Starting the API</h2>
<p>Run <code>seedpass api start</code> from your terminal. The command
prints a onetime token used for authentication:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> seedpass api start</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">API</span> token: abcdef1234567890</span></code></pre></div>
<p>Keep this token secret. Every request must include it in the
<code>Authorization</code> header using the <code>Bearer</code>
scheme.</p>
<h2 id="endpoints">Endpoints</h2>
<ul>
<li><code>GET /api/v1/entry?query=&lt;text&gt;</code> Search entries
matching a query.</li>
<li><code>GET /api/v1/entry/{id}</code> Retrieve a single entry by its
index.</li>
<li><code>POST /api/v1/entry</code> Create a new entry of any
supported type.</li>
<li><code>PUT /api/v1/entry/{id}</code> Modify an existing entry.</li>
<li><code>PUT /api/v1/config/{key}</code> Update a configuration
value.</li>
<li><code>POST /api/v1/secret-mode</code> Enable or disable Secret
Mode and set the clipboard delay.</li>
<li><code>POST /api/v1/entry/{id}/archive</code> Archive an
entry.</li>
<li><code>POST /api/v1/entry/{id}/unarchive</code> Unarchive an
entry.</li>
<li><code>GET /api/v1/config/{key}</code> Return the value for a
configuration key.</li>
<li><code>GET /api/v1/fingerprint</code> List available seed
fingerprints.</li>
<li><code>POST /api/v1/fingerprint</code> Add a new seed
fingerprint.</li>
<li><code>DELETE /api/v1/fingerprint/{fp}</code> Remove a
fingerprint.</li>
<li><code>POST /api/v1/fingerprint/select</code> Switch the active
fingerprint.</li>
<li><code>GET /api/v1/totp/export</code> Export all TOTP entries as
JSON.</li>
<li><code>GET /api/v1/totp</code> Return current TOTP codes and
remaining time.</li>
<li><code>GET /api/v1/stats</code> Return statistics about the active
seed profile.</li>
<li><code>GET /api/v1/parent-seed</code> Reveal the parent seed or
save it with <code>?file=</code>.</li>
<li><code>GET /api/v1/nostr/pubkey</code> Fetch the Nostr public key
for the active seed.</li>
<li><code>POST /api/v1/checksum/verify</code> Verify the checksum of
the running script.</li>
<li><code>POST /api/v1/checksum/update</code> Update the stored script
checksum.</li>
<li><code>POST /api/v1/change-password</code> Change the master
password for the active profile.</li>
<li><code>POST /api/v1/vault/import</code> Import a vault backup from
a file or path.</li>
<li><code>POST /api/v1/vault/export</code> Export the vault and
download the encrypted file.</li>
<li><code>POST /api/v1/vault/backup-parent-seed</code> Save an
encrypted backup of the parent seed.</li>
<li><code>POST /api/v1/vault/lock</code> Lock the vault and clear
sensitive data from memory.</li>
<li><code>GET /api/v1/relays</code> List configured Nostr relays.</li>
<li><code>POST /api/v1/relays</code> Add a relay URL.</li>
<li><code>DELETE /api/v1/relays/{idx}</code> Remove the relay at the
given index (1based).</li>
<li><code>POST /api/v1/relays/reset</code> Reset the relay list to
defaults.</li>
<li><code>POST /api/v1/shutdown</code> Stop the server
gracefully.</li>
</ul>
<p><strong>Security Warning:</strong> Accessing
<code>/api/v1/parent-seed</code> exposes your master seed in plain text.
Use it only from a trusted environment.</p>
<h2 id="example-requests">Example Requests</h2>
<p>Send requests with the token in the header:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="st">&quot;http://127.0.0.1:8000/api/v1/entry?query=email&quot;</span></span></code></pre></div>
<h3 id="creating-an-entry">Creating an Entry</h3>
<p><code>POST /api/v1/entry</code> accepts a JSON body with at least a
<code>label</code> field. Set <code>type</code> (or <code>kind</code>)
to choose the entry variant (<code>password</code>, <code>totp</code>,
<code>ssh</code>, <code>pgp</code>, <code>nostr</code>,
<code>seed</code>, <code>key_value</code>, or
<code>managed_account</code>). Additional fields vary by type:</p>
<ul>
<li><strong>password</strong> <code>length</code>, optional
<code>username</code>, <code>url</code> and <code>notes</code></li>
<li><strong>totp</strong> <code>secret</code> or <code>index</code>,
optional <code>period</code>, <code>digits</code>, <code>notes</code>,
<code>archived</code></li>
<li><strong>ssh/nostr/seed/managed_account</strong>
<code>index</code>, optional <code>notes</code>,
<code>archived</code></li>
<li><strong>pgp</strong> <code>index</code>, <code>key_type</code>,
<code>user_id</code>, optional <code>notes</code>,
<code>archived</code></li>
<li><strong>key_value</strong> <code>value</code>, optional
<code>notes</code></li>
</ul>
<p>Example creating a TOTP entry:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/entry <span class="dt">\</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;type&quot;: &quot;totp&quot;, &quot;label&quot;: &quot;Email&quot;, &quot;secret&quot;: &quot;JBSW...&quot;}&#39;</span></span></code></pre></div>
<h3 id="updating-an-entry">Updating an Entry</h3>
<p>Use <code>PUT /api/v1/entry/{id}</code> to change fields such as
<code>label</code>, <code>username</code>, <code>url</code>,
<code>notes</code>, <code>period</code>, <code>digits</code> or
<code>value</code> depending on the entry type.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> PUT http://127.0.0.1:8000/api/v1/entry/1 <span class="dt">\</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;username&quot;: &quot;alice&quot;}&#39;</span></span></code></pre></div>
<h3 id="updating-configuration">Updating Configuration</h3>
<p>Send a JSON body containing a <code>value</code> field to
<code>PUT /api/v1/config/{key}</code>:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> PUT http://127.0.0.1:8000/api/v1/config/inactivity_timeout <span class="dt">\</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;value&quot;: 300}&#39;</span></span></code></pre></div>
<h3 id="toggling-secret-mode">Toggling Secret Mode</h3>
<p>Send both <code>enabled</code> and <code>delay</code> values to
<code>/api/v1/secret-mode</code>:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/secret-mode <span class="dt">\</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;enabled&quot;: true, &quot;delay&quot;: 20}&#39;</span></span></code></pre></div>
<h3 id="switching-fingerprints">Switching Fingerprints</h3>
<p>Change the active seed profile via
<code>POST /api/v1/fingerprint/select</code>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/fingerprint/select <span class="dt">\</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;fingerprint&quot;: &quot;abc123&quot;}&#39;</span></span></code></pre></div>
<h3 id="exporting-the-vault">Exporting the Vault</h3>
<p>Download an encrypted vault backup via
<code>POST /api/v1/vault/export</code>:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/vault/export <span class="dt">\</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-o</span> backup.json</span></code></pre></div>
<h3 id="importing-a-vault">Importing a Vault</h3>
<p>Restore a backup with <code>POST /api/v1/vault/import</code>. Use
<code>-F</code> to upload a file:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/vault/import <span class="dt">\</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-F</span> file=@backup.json</span></code></pre></div>
<h3 id="locking-the-vault">Locking the Vault</h3>
<p>Clear sensitive data from memory using
<code>/api/v1/vault/lock</code>:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/vault/lock <span class="dt">\</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span></code></pre></div>
<h3 id="backing-up-the-parent-seed">Backing Up the Parent Seed</h3>
<p>Trigger an encrypted seed backup with
<code>/api/v1/vault/backup-parent-seed</code>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/vault/backup-parent-seed <span class="dt">\</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;path&quot;: &quot;seed_backup.enc&quot;}&#39;</span></span></code></pre></div>
<h3 id="retrieving-vault-statistics">Retrieving Vault Statistics</h3>
<p>Get profile stats such as entry counts with
<code>GET /api/v1/stats</code>:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a> http://127.0.0.1:8000/api/v1/stats</span></code></pre></div>
<h3 id="changing-the-master-password">Changing the Master Password</h3>
<p>Update the vault password via
<code>POST /api/v1/change-password</code>:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/change-password <span class="dt">\</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span></code></pre></div>
<h3 id="verifying-the-script-checksum">Verifying the Script
Checksum</h3>
<p>Check that the running script matches the stored checksum:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/checksum/verify <span class="dt">\</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span></code></pre></div>
<h3 id="updating-the-script-checksum">Updating the Script Checksum</h3>
<p>Regenerate the stored checksum using
<code>/api/v1/checksum/update</code>:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/checksum/update <span class="dt">\</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span></code></pre></div>
<h3 id="managing-relays">Managing Relays</h3>
<p>List, add, or remove Nostr relays:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="co"># list</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> http://127.0.0.1:8000/api/v1/relays</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="co"># add</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/relays <span class="dt">\</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span> <span class="dt">\</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Content-Type: application/json&quot;</span> <span class="dt">\</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a> <span class="at">-d</span> <span class="st">&#39;{&quot;url&quot;: &quot;wss://relay.example.com&quot;}&#39;</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="co"># remove first relay</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> DELETE http://127.0.0.1:8000/api/v1/relays/1 <span class="dt">\</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a><span class="co"># reset to defaults</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-X</span> POST http://127.0.0.1:8000/api/v1/relays/reset <span class="dt">\</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a> <span class="at">-H</span> <span class="st">&quot;Authorization: Bearer &lt;token&gt;&quot;</span></span></code></pre></div>
<h3 id="enabling-cors">Enabling CORS</h3>
<p>Crossorigin requests are disabled by default. Set
<code>SEEDPASS_CORS_ORIGINS</code> to a commaseparated list of allowed
origins before starting the API:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="va">SEEDPASS_CORS_ORIGINS</span><span class="op">=</span>http://localhost:3000 <span class="ex">seedpass</span> api start</span></code></pre></div>
<p>Browsers can then call the API from the specified origins, for
example using JavaScript:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode javascript"><code class="sourceCode javascript"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fetch</span>(<span class="st">&#39;http://127.0.0.1:8000/api/v1/entry?query=email&#39;</span><span class="op">,</span> {</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a> <span class="dt">headers</span><span class="op">:</span> { <span class="dt">Authorization</span><span class="op">:</span> <span class="st">&#39;Bearer &lt;token&gt;&#39;</span> }</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>})<span class="op">;</span></span></code></pre></div>
<p>Without CORS enabled, only sameorigin or commandline tools like
<code>curl</code> can access the API.</p>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SeedPass Documentation</title>
<link rel="stylesheet" href="theme.css">
</head>
<body>
<div class="rst-container">
<div class="rst-sidebar">
<ul class="simple">
<li><a href="README.html">Overview</a></li>
<li><a href="advanced_cli.html">Advanced CLI</a></li>
<li><a href="api_reference.html">API Reference</a></li>
<li><a href="json_entries.html">JSON Entries</a></li>
<li><a href="migrations.html">Migrations</a></li>
</ul>
</div>
<div class="rst-content">
<h1>SeedPass Documentation</h1>
<p>Select a topic from the sidebar.</p>
</div>
</div>
</body>
</html>

View File

@@ -1,703 +0,0 @@
<!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>

View File

@@ -1,51 +0,0 @@
<!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>migrations</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;}
</style>
<link rel="stylesheet" href="theme.css" />
</head>
<body>
<h1 id="index-migrations">Index Migrations</h1>
<p>SeedPass stores its password index in an encrypted JSON file. Each
index contains a <code>schema_version</code> field so the application
knows how to upgrade older files.</p>
<h2 id="how-migrations-work">How migrations work</h2>
<p>When the vault loads the index, <code>Vault.load_index()</code>
checks the version and applies migrations defined in
<code>password_manager/migrations.py</code>. The
<code>apply_migrations()</code> function iterates through registered
migrations until the file reaches <code>LATEST_VERSION</code>.</p>
<p>If an old file lacks <code>schema_version</code>, it is treated as
version 0 and upgraded to the latest format. Attempting to load an index
from a future version will raise an error.</p>
<h2 id="upgrading-an-index">Upgrading an index</h2>
<ol type="1">
<li>The JSON is decrypted and parsed.</li>
<li><code>apply_migrations()</code> applies any necessary steps, such as
injecting the <code>schema_version</code> field on first upgrade.</li>
<li>After migration, the updated index is saved back to disk.</li>
</ol>
<p>This process happens automatically; users only need to open their
vault to upgrade older indices.</p>
</body>
</html>

File diff suppressed because one or more lines are too long