bark-wallet 0.1.0

Wallet library and CLI for the bitcoin Ark protocol built by Second
Documentation
use anyhow::Context;

use rusqlite::Transaction;

use super::Migration;

pub struct Migration0001 {}

impl Migration for Migration0001 {

	fn name(&self) -> &str {
		"Create initial tables"
	}

	fn to_version(&self) -> i64 { 1 }

	fn do_migration(&self, conn: &Transaction) -> anyhow::Result<()> {
		let queries = [
			"CREATE TABLE IF NOT EXISTS bark_vtxo (
				id TEXT PRIMARY KEY,
				expiry_height INTEGER,
				amount_sat INTEGER,
				raw_vtxo BLOB,
				created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now'))
			);",
			"CREATE TABLE IF NOT EXISTS bark_vtxo_key (
				public_key TEXT NOT NULL PRIMARY KEY,
				keychain INTEGER NOT NULL,
				idx INTEGER NOT NULL,
				-- each index must be unique in a keychain
				UNIQUE (keychain, idx)
			);",
			"CREATE TABLE IF NOT EXISTS bark_vtxo_state (
				id INTEGER PRIMARY KEY,
				created_at DATETIME NOT NULL DEFAULT  (strftime('%Y-%m-%d %H:%M:%f', 'now')),
				vtxo_id TEXT REFERENCES bark_vtxo(id),
				state_kind TEXT NOT NULL,
				state BLOB NOT NULL
			);",
			"CREATE TABLE IF NOT EXISTS bark_ark_sync (
				id INTEGER PRIMARY KEY AUTOINCREMENT,
				sync_height INTEGER,
				created_at DATETIME NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%f', 'now'))
			);",
			"CREATE TABLE IF NOT EXISTS bark_exit (
				id INTEGER PRIMARY KEY AUTOINCREMENT,
				exit BLOB
			)",
			"CREATE VIEW IF NOT EXISTS most_recent_vtxo_state
				(id, last_updated_at, vtxo_id, state_kind, state)
			AS
			WITH most_recent AS (SELECT MAX(id) as id FROM bark_vtxo_state GROUP BY vtxo_id)
			SELECT
				most_recent.id,
				vs.created_at,
				vs.vtxo_id,
				vs.state_kind,
				vs.state
			FROM most_recent JOIN bark_vtxo_state as vs
				ON vs.id = most_recent.id;
			",
			"CREATE VIEW IF NOT EXISTS vtxo_view
			AS SELECT
				v.id,
				v.expiry_height,
				v.amount_sat,
				vs.state_kind,
				vs.state,
				v.raw_vtxo,
				v.created_at,
				vs.last_updated_at
			FROM bark_vtxo as v
			JOIN most_recent_vtxo_state as vs
				ON v.id = vs.vtxo_id;
			"];

		for query in queries {
			conn.execute(query, ()).with_context(|| format!("Failed to execute migration: {}", self.summary()))?;
		}
		Ok(())
	}
}