From 2a4ae5a2fbd6d607c597430cafcb275ee9f9d376 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Fri, 1 Nov 2024 23:53:16 -0400 Subject: [PATCH 01/21] Add burning for DIDs and NFTs and fix tx --- Cargo.lock | 1 + crates/sage-api/src/records/sync_status.rs | 1 + .../src/records/transaction_summary.rs | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/commands/data.rs | 5 + src-tauri/src/commands/transactions.rs | 3 + src/bindings.ts | 4 +- src/components/ConfirmationDialog.tsx | 24 ++++- src/components/NftCard.tsx | 93 ++++++++++++++++++- src/pages/DidList.tsx | 88 +++++++++++++++++- 10 files changed, 209 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea4ca60b..f3fac950 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4468,6 +4468,7 @@ dependencies = [ "chia-wallet-sdk", "clvmr", "hex", + "hex-literal", "indexmap 2.5.0", "itertools 0.13.0", "log", diff --git a/crates/sage-api/src/records/sync_status.rs b/crates/sage-api/src/records/sync_status.rs index 035fc654..d8c4b79d 100644 --- a/crates/sage-api/src/records/sync_status.rs +++ b/crates/sage-api/src/records/sync_status.rs @@ -10,4 +10,5 @@ pub struct SyncStatus { pub synced_coins: u32, pub total_coins: u32, pub receive_address: String, + pub burn_address: String, } diff --git a/crates/sage-api/src/records/transaction_summary.rs b/crates/sage-api/src/records/transaction_summary.rs index a2103542..bf260d4a 100644 --- a/crates/sage-api/src/records/transaction_summary.rs +++ b/crates/sage-api/src/records/transaction_summary.rs @@ -46,6 +46,7 @@ pub struct Output { pub amount: Amount, pub address: String, pub receiving: bool, + pub burning: bool, } #[derive(Debug, Clone, Serialize, Deserialize, Type)] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 859f77e2..a263c3c3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -34,6 +34,7 @@ bincode = { workspace = true } toml = { workspace = true, features = ["preserve_order"] } indexmap = { workspace = true, features = ["serde"] } hex = { workspace = true } +hex-literal = { workspace = true } chia = { workspace = true } chia-wallet-sdk = { workspace = true, features = ["rustls"] } clvmr = { workspace = true } diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index 47bab4b6..46ee6f03 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -7,6 +7,7 @@ use chia::{ }; use chia_wallet_sdk::{decode_address, encode_address}; use clvmr::Allocator; +use hex_literal::hex; use sage_api::{ Amount, CatRecord, CoinRecord, DidRecord, GetCollectionNfts, GetNftCollections, GetNfts, NftCollectionRecord, NftInfo, NftRecord, NftSortMode, NftStatus, PendingTransactionRecord, @@ -70,6 +71,10 @@ pub async fn get_sync_status(state: State<'_, AppState>) -> Result { total_coins, synced_coins, receive_address: receive_address.unwrap_or_default(), + burn_address: encode_address( + hex!("000000000000000000000000000000000000000000000000000000000000dead"), + &state.network().address_prefix, + )?, }) } diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 1ebdd121..693bdaed 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -9,6 +9,7 @@ use chia::{ use chia_wallet_sdk::{ decode_address, encode_address, AggSigConstants, MAINNET_CONSTANTS, TESTNET11_CONSTANTS, }; +use hex_literal::hex; use sage_api::{ Amount, BulkMintNfts, BulkMintNftsResponse, CoinJson, CoinSpendJson, Input, InputKind, Output, SpendBundleJson, TransactionSummary, @@ -704,6 +705,8 @@ async fn summarize( amount, address, receiving: wallet.db.is_p2_puzzle_hash(p2_puzzle_hash).await?, + burning: p2_puzzle_hash.to_bytes() + == hex!("000000000000000000000000000000000000000000000000000000000000dead"), }); } diff --git a/src/bindings.ts b/src/bindings.ts index 33decb7d..dbbde41e 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -484,12 +484,12 @@ export type NftMint = { edition_number: number | null; edition_total: number | n export type NftRecord = { launcher_id: string; collection_id: string | null; collection_name: string | null; minter_did: string | null; owner_did: string | null; visible: boolean; sensitive_content: boolean; name: string | null; created_height: number | null; data_mime_type: string | null; data: string | null } export type NftSortMode = "name" | "recent" export type NftStatus = { nfts: number; visible_nfts: number; collections: number; visible_collections: number } -export type Output = { coin_id: string; amount: Amount; address: string; receiving: boolean } +export type Output = { coin_id: string; amount: Amount; address: string; receiving: boolean; burning: boolean } export type PeerRecord = { ip_addr: string; port: number; trusted: boolean; peak_height: number } export type PendingTransactionRecord = { transaction_id: string; fee: Amount; submitted_at: string | null } export type SpendBundleJson = { coin_spends: CoinSpendJson[]; aggregated_signature: string } export type SyncEvent = { type: "start"; ip: string } | { type: "stop" } | { type: "subscribed" } | { type: "derivation" } | { type: "coin_state" } | { type: "puzzle_batch_synced" } | { type: "cat_info" } | { type: "did_info" } | { type: "nft_data" } -export type SyncStatus = { balance: Amount; unit: Unit; synced_coins: number; total_coins: number; receive_address: string } +export type SyncStatus = { balance: Amount; unit: Unit; synced_coins: number; total_coins: number; receive_address: string; burn_address: string } export type TransactionSummary = { fee: Amount; inputs: Input[]; coin_spends: CoinSpendJson[] } export type Unit = { ticker: string; decimals: number } export type WalletConfig = { name?: string; derive_automatically?: boolean; derivation_batch_size?: number } diff --git a/src/components/ConfirmationDialog.tsx b/src/components/ConfirmationDialog.tsx index d29aa987..02871409 100644 --- a/src/components/ConfirmationDialog.tsx +++ b/src/components/ConfirmationDialog.tsx @@ -87,7 +87,11 @@ export default function ConfirmationDialog({ created.push({ badge: 'Chia', label: `${output.amount} ${ticker}`, - address: output.receiving ? 'Change' : output.address, + address: output.burning + ? 'Permanently Burned' + : output.receiving + ? 'Change' + : output.address, sort: 1, }); } @@ -111,7 +115,11 @@ export default function ConfirmationDialog({ created.push({ badge: `CAT ${input.name || input.asset_id}`, label: `${output.amount} ${ticker}`, - address: output.receiving ? 'Change' : output.address, + address: output.burning + ? 'Permanently Burned' + : output.receiving + ? 'Change' + : output.address, sort: 2, }); } @@ -146,7 +154,11 @@ export default function ConfirmationDialog({ created.push({ badge: 'Profile', label: input.name || 'Unnamed', - address: output.receiving ? 'You' : output.address, + address: output.burning + ? 'Permanently Burned' + : output.receiving + ? 'You' + : output.address, sort: 3, }); } @@ -182,7 +194,11 @@ export default function ConfirmationDialog({ created.push({ badge: 'NFT', label: input.name || 'Unknown', - address: output.receiving ? 'You' : output.address, + address: output.burning + ? 'Permanently Burned' + : output.receiving + ? 'You' + : output.address, sort: 4, }); } diff --git a/src/components/NftCard.tsx b/src/components/NftCard.tsx index d4d4dbd3..662be14c 100644 --- a/src/components/NftCard.tsx +++ b/src/components/NftCard.tsx @@ -4,9 +4,9 @@ import { nftUri } from '@/lib/nftUri'; import { useWalletState } from '@/state'; import { zodResolver } from '@hookform/resolvers/zod'; import BigNumber from 'bignumber.js'; -import { EyeIcon, EyeOff, MoreVertical, SendIcon } from 'lucide-react'; +import { EyeIcon, EyeOff, Flame, MoreVertical, SendIcon } from 'lucide-react'; import { PropsWithChildren, useState } from 'react'; -import { Form, useForm } from 'react-hook-form'; +import { useForm } from 'react-hook-form'; import { Link } from 'react-router-dom'; import { z } from 'zod'; import ConfirmationDialog from './ConfirmationDialog'; @@ -27,6 +27,7 @@ import { DropdownMenuTrigger, } from './ui/dropdown-menu'; import { + Form, FormControl, FormField, FormItem, @@ -51,7 +52,8 @@ export function NftCardList({ children }: PropsWithChildren) { export function NftCard({ nft, updateNfts }: NftProps) { const walletState = useWalletState(); - const [isTransferOpen, setTransferOpen] = useState(false); + const [transferOpen, setTransferOpen] = useState(false); + const [burnOpen, setBurnOpen] = useState(false); const [summary, setSummary] = useState(null); const toggleVisibility = () => { @@ -93,6 +95,33 @@ export function NftCard({ nft, updateNfts }: NftProps) { }); }; + const burnFormSchema = z.object({ + fee: amount(walletState.sync.unit.decimals).refine( + (amount) => BigNumber(walletState.sync.balance).gte(amount || 0), + 'Not enough funds to cover the fee', + ), + }); + + const burnForm = useForm>({ + resolver: zodResolver(burnFormSchema), + defaultValues: { + fee: '0', + }, + }); + + const onBurnSubmit = (values: z.infer) => { + commands + .transferNft(nft.launcher_id, walletState.sync.burn_address, values.fee) + .then((result) => { + setBurnOpen(false); + if (result.status === 'error') { + console.error('Failed to burn NFT', result.error); + } else { + setSummary(result.data); + } + }); + }; + return ( <> Transfer + + { + e.stopPropagation(); + burnForm.reset(); + setBurnOpen(true); + }} + disabled={!nft.created_height} + > + + Burn + + { @@ -159,7 +202,7 @@ export function NftCard({ nft, updateNfts }: NftProps) { - + Transfer NFT @@ -213,6 +256,48 @@ export function NftCard({ nft, updateNfts }: NftProps) { + + + + Burn NFT + + This will permanently delete the NFT by sending it to the burn + address. + + +
+ + ( + + Network Fee + + + + + + )} + /> + + + + + + +
+
+ setSummary(null)} diff --git a/src/pages/DidList.tsx b/src/pages/DidList.tsx index 339af678..88c00fe0 100644 --- a/src/pages/DidList.tsx +++ b/src/pages/DidList.tsx @@ -39,6 +39,7 @@ import BigNumber from 'bignumber.js'; import { EyeIcon, EyeOff, + Flame, MoreVerticalIcon, PenIcon, SendIcon, @@ -112,7 +113,8 @@ function Profile({ did, updateDids }: ProfileProps) { const [name, setName] = useState(''); const [renameOpen, setRenameOpen] = useState(false); - const [isTransferOpen, setTransferOpen] = useState(false); + const [transferOpen, setTransferOpen] = useState(false); + const [burnOpen, setBurnOpen] = useState(false); const [summary, setSummary] = useState(null); const rename = () => { @@ -171,6 +173,33 @@ function Profile({ did, updateDids }: ProfileProps) { }); }; + const burnFormSchema = z.object({ + fee: amount(walletState.sync.unit.decimals).refine( + (amount) => BigNumber(walletState.sync.balance).gte(amount || 0), + 'Not enough funds to cover the fee', + ), + }); + + const burnForm = useForm>({ + resolver: zodResolver(burnFormSchema), + defaultValues: { + fee: '0', + }, + }); + + const onBurnSubmit = (values: z.infer) => { + commands + .transferDid(did.launcher_id, walletState.sync.burn_address, values.fee) + .then((result) => { + setBurnOpen(false); + if (result.status === 'error') { + console.error('Failed to burn DID', result.error); + } else { + setSummary(result.data); + } + }); + }; + return ( <> Transfer
+ + { + e.stopPropagation(); + setBurnOpen(true); + }} + > + + Burn + + { @@ -210,6 +251,7 @@ function Profile({ did, updateDids }: ProfileProps) { Rename + { @@ -278,7 +320,7 @@ function Profile({ did, updateDids }: ProfileProps) { - + Transfer Profile @@ -332,6 +374,48 @@ function Profile({ did, updateDids }: ProfileProps) { + + + + Burn Profile + + This will permanently delete the profile by sending it to the burn + address. + + +
+ + ( + + Network Fee + + + + + + )} + /> + + + + + + +
+
+ setSummary(null)} From e6e387f58f98a206ce3da170a204313b95dec459 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Fri, 1 Nov 2024 23:57:01 -0400 Subject: [PATCH 02/21] Add burn addr to state --- src/state.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/state.ts b/src/state.ts index 272a75df..a761c9c7 100644 --- a/src/state.ts +++ b/src/state.ts @@ -16,6 +16,7 @@ export interface WalletState { export const useWalletState = create()(() => ({ sync: { receive_address: 'Unknown', + burn_address: 'Unknown', balance: 'Syncing', unit: { ticker: 'XCH', @@ -37,6 +38,7 @@ export function clearState() { useWalletState.setState({ sync: { receive_address: 'Unknown', + burn_address: 'Unknown', balance: 'Syncing', unit: { ticker: 'XCH', From 6a5543eee281dc5c4281db173de9ccc98be58494 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 15:58:39 -0500 Subject: [PATCH 03/21] Temp --- crates/sage-database/src/coin_states.rs | 32 ++------ crates/sage-database/src/lib.rs | 3 +- crates/sage-database/src/primitives/cats.rs | 91 ++++----------------- crates/sage-database/src/primitives/dids.rs | 2 +- crates/sage-database/src/rows.rs | 7 ++ crates/sage-database/src/rows/cat.rs | 35 ++++++++ crates/sage-database/src/rows/cat_coin.rs | 72 ++++++++++++++++ crates/sage-database/src/rows/coin_state.rs | 35 ++++++++ crates/sage-database/src/utils.rs | 41 ++-------- 9 files changed, 184 insertions(+), 134 deletions(-) create mode 100644 crates/sage-database/src/rows.rs create mode 100644 crates/sage-database/src/rows/cat.rs create mode 100644 crates/sage-database/src/rows/cat_coin.rs create mode 100644 crates/sage-database/src/rows/coin_state.rs diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index b32d532d..7215179a 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -1,13 +1,7 @@ use chia::protocol::{Bytes32, CoinState}; use sqlx::SqliteExecutor; -use crate::{to_bytes32, to_coin, to_coin_state, Database, DatabaseTx, Result}; - -#[derive(Debug, Clone, Copy)] -pub struct CoinStateRow { - pub coin_state: CoinState, - pub transaction_id: Option, -} +use crate::{to_bytes32, CoinStateSql, Database, DatabaseTx, Result}; impl Database { pub async fn unsynced_coin_states(&self, limit: usize) -> Result> { @@ -155,9 +149,10 @@ async fn unsynced_coin_states( limit: usize, ) -> Result> { let limit: i64 = limit.try_into()?; - let rows = sqlx::query!( + let rows = sqlx::query_as!( + CoinStateSql, " - SELECT * + SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `created_height`, `spent_height`, `transaction_id` FROM `coin_states` WHERE `synced` = 0 AND `created_height` IS NOT NULL ORDER BY `spent_height` ASC @@ -168,13 +163,7 @@ async fn unsynced_coin_states( .fetch_all(conn) .await?; rows.into_iter() - .map(|row| { - to_coin_state( - to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - row.created_height, - row.spent_height, - ) - }) + .map(|sql| sql.into_row().map(|row| row.coin_state)) .collect() } @@ -242,9 +231,10 @@ async fn synced_coin_count(conn: impl SqliteExecutor<'_>) -> Result { async fn coin_state(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result> { let coin_id = coin_id.as_ref(); - let Some(row) = sqlx::query!( + let Some(sql) = sqlx::query_as!( + CoinStateSql, " - SELECT * + SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `created_height`, `spent_height`, `transaction_id` FROM `coin_states` WHERE `coin_id` = ? ", @@ -256,11 +246,7 @@ async fn coin_state(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result) -> Result> { diff --git a/crates/sage-database/src/lib.rs b/crates/sage-database/src/lib.rs index 03b894e3..51d901ee 100644 --- a/crates/sage-database/src/lib.rs +++ b/crates/sage-database/src/lib.rs @@ -2,11 +2,12 @@ mod coin_states; mod derivations; mod peaks; mod primitives; +mod rows; mod transactions; mod utils; -pub use coin_states::*; pub use primitives::*; +pub use rows::*; pub use transactions::*; pub(crate) use utils::*; diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 9dd0c92a..54e87666 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -1,32 +1,12 @@ -use chia::{ - protocol::{Bytes32, Coin}, - puzzles::LineageProof, -}; +use chia::{protocol::Bytes32, puzzles::LineageProof}; use chia_wallet_sdk::Cat; use sqlx::SqliteExecutor; use crate::{ - to_bytes, to_bytes32, to_coin, to_coin_state, to_lineage_proof, CoinStateRow, Database, - DatabaseTx, Result, + to_bytes, to_bytes32, CatCoinRow, CatCoinSql, CatRow, CoinStateRow, CoinStateSql, Database, + DatabaseTx, FullCatCoinSql, Result, }; -#[derive(Debug, Clone)] -pub struct CatRow { - pub asset_id: Bytes32, - pub name: Option, - pub ticker: Option, - pub description: Option, - pub icon_url: Option, - pub visible: bool, -} - -#[derive(Debug, Clone, Copy)] -pub struct CatCoin { - pub coin: Coin, - pub lineage_proof: LineageProof, - pub p2_puzzle_hash: Bytes32, -} - impl Database { pub async fn maybe_insert_cat(&self, row: CatRow) -> Result<()> { maybe_insert_cat(&self.pool, row).await @@ -52,7 +32,7 @@ impl Database { unidentified_cat(&self.pool).await } - pub async fn spendable_cat_coins(&self, asset_id: Bytes32) -> Result> { + pub async fn spendable_cat_coins(&self, asset_id: Bytes32) -> Result> { spendable_cat_coins(&self.pool, asset_id).await } @@ -275,10 +255,11 @@ async fn insert_cat_coin( async fn spendable_cat_coins( conn: impl SqliteExecutor<'_>, asset_id: Bytes32, -) -> Result> { +) -> Result> { let asset_id = asset_id.as_ref(); - let rows = sqlx::query!( + let rows = sqlx::query_as!( + CatCoinSql, " SELECT cs.`parent_coin_id`, cs.`puzzle_hash`, cs.`amount`, `p2_puzzle_hash`, @@ -296,19 +277,7 @@ async fn spendable_cat_coins( .fetch_all(conn) .await?; - rows.into_iter() - .map(|row| { - Ok(CatCoin { - coin: to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - lineage_proof: to_lineage_proof( - &row.parent_parent_coin_id, - &row.parent_inner_puzzle_hash, - &row.parent_amount, - )?, - p2_puzzle_hash: to_bytes32(&row.p2_puzzle_hash)?, - }) - }) - .collect() + rows.into_iter().map(|sql| sql.into_row()).collect() } async fn cat_balance(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result { @@ -339,39 +308,27 @@ async fn cat_coin_states( ) -> Result> { let asset_id = asset_id.as_ref(); - let rows = sqlx::query!( + let rows = sqlx::query_as!( + CoinStateSql, " - SELECT - cs.parent_coin_id, cs.puzzle_hash, cs.amount, - cs.spent_height, cs.created_height, cs.transaction_id - FROM `coin_states` AS cs - INNER JOIN `cat_coins` AS cat - ON cs.coin_id = cat.coin_id - WHERE cat.asset_id = ? + SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id` + FROM `cat_coins` + INNER JOIN `coin_states` ON `coin_states`.coin_id = `cat_coins`.coin_id + WHERE `asset_id` = ? ", asset_id ) .fetch_all(conn) .await?; - rows.into_iter() - .map(|row| { - Ok(CoinStateRow { - coin_state: to_coin_state( - to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - row.created_height, - row.spent_height, - )?, - transaction_id: row.transaction_id.map(|id| to_bytes32(&id)).transpose()?, - }) - }) - .collect() + rows.into_iter().map(|sql| sql.into_row()).collect() } async fn cat_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result> { let coin_id = coin_id.as_ref(); - let row = sqlx::query!( + let row = sqlx::query_as!( + FullCatCoinSql, " SELECT `parent_coin_id`, `puzzle_hash`, `amount`, @@ -386,17 +343,5 @@ async fn cat_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result, + pub name: Option, + pub ticker: Option, + pub description: Option, + pub icon_url: Option, + pub visible: bool, +} + +#[derive(Debug, Clone)] +pub struct CatRow { + pub asset_id: Bytes32, + pub name: Option, + pub ticker: Option, + pub description: Option, + pub icon_url: Option, + pub visible: bool, +} + +impl CatSql { + pub(crate) fn into_row(&self) -> Result { + Ok(CatRow { + asset_id: to_bytes32(&self.asset_id)?, + name: self.name.clone(), + ticker: self.ticker.clone(), + description: self.description.clone(), + icon_url: self.icon_url.clone(), + visible: self.visible, + }) + } +} diff --git a/crates/sage-database/src/rows/cat_coin.rs b/crates/sage-database/src/rows/cat_coin.rs new file mode 100644 index 00000000..f4146b28 --- /dev/null +++ b/crates/sage-database/src/rows/cat_coin.rs @@ -0,0 +1,72 @@ +use chia::{ + protocol::{Bytes32, Coin}, + puzzles::LineageProof, +}; +use chia_wallet_sdk::Cat; + +use crate::{to_bytes32, to_u64, DatabaseError}; + +pub(crate) struct CatCoinSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, + pub parent_parent_coin_id: Vec, + pub parent_inner_puzzle_hash: Vec, + pub parent_amount: Vec, + pub p2_puzzle_hash: Vec, +} + +pub(crate) struct FullCatCoinSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, + pub parent_parent_coin_id: Vec, + pub parent_inner_puzzle_hash: Vec, + pub parent_amount: Vec, + pub p2_puzzle_hash: Vec, + pub asset_id: Vec, +} + +#[derive(Debug, Clone, Copy)] +pub struct CatCoinRow { + pub coin: Coin, + pub lineage_proof: LineageProof, + pub p2_puzzle_hash: Bytes32, +} + +impl CatCoinSql { + pub(crate) fn into_row(self) -> Result { + Ok(CatCoinRow { + coin: Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }, + lineage_proof: LineageProof { + parent_parent_coin_info: to_bytes32(&self.parent_parent_coin_id)?, + parent_inner_puzzle_hash: to_bytes32(&self.parent_inner_puzzle_hash)?, + parent_amount: to_u64(&self.parent_amount)?, + }, + p2_puzzle_hash: to_bytes32(&self.p2_puzzle_hash)?, + }) + } +} + +impl FullCatCoinSql { + pub(crate) fn into_row(self) -> Result { + Ok(Cat { + coin: Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }, + lineage_proof: Some(LineageProof { + parent_parent_coin_info: to_bytes32(&self.parent_parent_coin_id)?, + parent_inner_puzzle_hash: to_bytes32(&self.parent_inner_puzzle_hash)?, + parent_amount: to_u64(&self.parent_amount)?, + }), + p2_puzzle_hash: to_bytes32(&self.p2_puzzle_hash)?, + asset_id: to_bytes32(&self.asset_id)?, + }) + } +} diff --git a/crates/sage-database/src/rows/coin_state.rs b/crates/sage-database/src/rows/coin_state.rs new file mode 100644 index 00000000..4d87fa73 --- /dev/null +++ b/crates/sage-database/src/rows/coin_state.rs @@ -0,0 +1,35 @@ +use chia::protocol::{Bytes32, Coin, CoinState}; + +use crate::{to_bytes32, to_u64, DatabaseError}; + +pub(crate) struct CoinStateSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, + pub spent_height: Option, + pub created_height: Option, + pub transaction_id: Option>, +} + +#[derive(Debug, Clone, Copy)] +pub struct CoinStateRow { + pub coin_state: CoinState, + pub transaction_id: Option, +} + +impl CoinStateSql { + pub(crate) fn into_row(self) -> Result { + Ok(CoinStateRow { + coin_state: CoinState { + coin: Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }, + spent_height: self.spent_height.map(TryInto::try_into).transpose()?, + created_height: self.created_height.map(TryInto::try_into).transpose()?, + }, + transaction_id: self.transaction_id.as_deref().map(to_bytes32).transpose()?, + }) + } +} diff --git a/crates/sage-database/src/utils.rs b/crates/sage-database/src/utils.rs index f3cfc209..4d7ecd83 100644 --- a/crates/sage-database/src/utils.rs +++ b/crates/sage-database/src/utils.rs @@ -1,42 +1,7 @@ -use chia::{ - protocol::{Bytes32, Coin, CoinState}, - puzzles::LineageProof, -}; +use chia::protocol::Bytes32; use crate::{DatabaseError, Result}; -pub fn to_coin_state( - coin: Coin, - created_height: Option, - spent_height: Option, -) -> Result { - Ok(CoinState { - coin, - spent_height: spent_height.map(TryInto::try_into).transpose()?, - created_height: created_height.map(TryInto::try_into).transpose()?, - }) -} - -pub fn to_coin(parent_coin_id: &[u8], puzzle_hash: &[u8], amount: &[u8]) -> Result { - Ok(Coin { - parent_coin_info: to_bytes32(parent_coin_id)?, - puzzle_hash: to_bytes32(puzzle_hash)?, - amount: u64::from_be_bytes(to_bytes(amount)?), - }) -} - -pub fn to_lineage_proof( - parent_parent_coin_id: &[u8], - parent_inner_puzzle_hash: &[u8], - parent_amount: &[u8], -) -> Result { - Ok(LineageProof { - parent_parent_coin_info: to_bytes32(parent_parent_coin_id)?, - parent_inner_puzzle_hash: to_bytes32(parent_inner_puzzle_hash)?, - parent_amount: u64::from_be_bytes(to_bytes(parent_amount)?), - }) -} - pub fn to_bytes(slice: &[u8]) -> Result<[u8; N]> { slice .try_into() @@ -46,3 +11,7 @@ pub fn to_bytes(slice: &[u8]) -> Result<[u8; N]> { pub fn to_bytes32(slice: &[u8]) -> Result { to_bytes(slice).map(Bytes32::new) } + +pub fn to_u64(slice: &[u8]) -> Result { + Ok(u64::from_be_bytes(to_bytes::<8>(slice)?)) +} From 0c0d76c9b319cae46c418040f9e19a1aa77b2bed Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 18:10:39 -0500 Subject: [PATCH 04/21] Temp --- crates/sage-database/src/primitives/nfts.rs | 151 ++++++++------------ crates/sage-database/src/rows.rs | 6 + crates/sage-database/src/rows/cat.rs | 2 +- crates/sage-database/src/rows/cat_coin.rs | 2 +- crates/sage-database/src/rows/coin_state.rs | 2 +- crates/sage-database/src/rows/collection.rs | 35 +++++ crates/sage-database/src/rows/nft.rs | 0 crates/sage-database/src/rows/nft_coin.rs | 0 migrations/0001_setup.sql | 22 +-- 9 files changed, 111 insertions(+), 109 deletions(-) create mode 100644 crates/sage-database/src/rows/collection.rs create mode 100644 crates/sage-database/src/rows/nft.rs create mode 100644 crates/sage-database/src/rows/nft_coin.rs diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index 545529c3..2b4eb9f9 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -5,17 +5,7 @@ use chia::{ use chia_wallet_sdk::{Nft, NftInfo}; use sqlx::SqliteExecutor; -use crate::{to_bytes32, to_coin, to_lineage_proof, Database, DatabaseTx, Result}; - -#[derive(Debug, Clone)] -pub struct NftCollectionRow { - pub collection_id: Bytes32, - pub did_id: Bytes32, - pub metadata_collection_id: String, - pub visible: bool, - pub name: Option, - pub icon: Option, -} +use crate::{to_bytes32, CollectionRow, CollectionSql, Database, DatabaseTx, Result}; #[derive(Debug, Clone)] pub struct NftRow { @@ -76,26 +66,26 @@ impl Database { fetch_nft_data(&self.pool, hash).await } - pub async fn nft_collection(&self, collection_id: Bytes32) -> Result { - nft_collection(&self.pool, collection_id).await + pub async fn collection(&self, collection_id: Bytes32) -> Result { + collection(&self.pool, collection_id).await } } impl<'a> DatabaseTx<'a> { - pub async fn nft_collections_visible_named( + pub async fn collections_visible_named( &mut self, limit: u32, offset: u32, - ) -> Result> { - nft_collections_visible_named(&mut *self.tx, offset, limit).await + ) -> Result> { + collections_visible_named(&mut *self.tx, offset, limit).await } - pub async fn nft_collections_named( + pub async fn collections_named( &mut self, limit: u32, offset: u32, - ) -> Result> { - nft_collections_named(&mut *self.tx, offset, limit).await + ) -> Result> { + collections_named(&mut *self.tx, offset, limit).await } pub async fn insert_nft_coin( @@ -119,12 +109,12 @@ impl<'a> DatabaseTx<'a> { .await } - pub async fn nft_collection_count(&mut self) -> Result { - nft_collection_count(&mut *self.tx).await + pub async fn collection_count(&mut self) -> Result { + collection_count(&mut *self.tx).await } - pub async fn visible_nft_collection_count(&mut self) -> Result { - visible_nft_collection_count(&mut *self.tx).await + pub async fn visible_collection_count(&mut self) -> Result { + visible_collection_count(&mut *self.tx).await } pub async fn nfts_visible_named(&mut self, limit: u32, offset: u32) -> Result> { @@ -283,20 +273,20 @@ impl<'a> DatabaseTx<'a> { nft(&mut *self.tx, launcher_id).await } - pub async fn insert_nft_collection(&mut self, row: NftCollectionRow) -> Result<()> { - insert_nft_collection(&mut *self.tx, row).await + pub async fn insert_collection(&mut self, row: CollectionRow) -> Result<()> { + insert_collection(&mut *self.tx, row).await } pub async fn nft_launcher_id(&mut self, coin_id: Bytes32) -> Result> { nft_launcher_id(&mut *self.tx, coin_id).await } - pub async fn nft_collection_name(&mut self, collection_id: Bytes32) -> Result> { - nft_collection_name(&mut *self.tx, collection_id).await + pub async fn collection_name(&mut self, collection_id: Bytes32) -> Result> { + collection_name(&mut *self.tx, collection_id).await } } -async fn insert_nft_collection(conn: impl SqliteExecutor<'_>, row: NftCollectionRow) -> Result<()> { +async fn insert_collection(conn: impl SqliteExecutor<'_>, row: CollectionRow) -> Result<()> { let collection_id = row.collection_id.as_ref(); let did_id = row.did_id.as_ref(); let name = row.name.as_deref(); @@ -304,7 +294,7 @@ async fn insert_nft_collection(conn: impl SqliteExecutor<'_>, row: NftCollection sqlx::query!( " - REPLACE INTO `nft_collections` ( + REPLACE INTO `collections` ( `collection_id`, `did_id`, `metadata_collection_id`, @@ -327,14 +317,14 @@ async fn insert_nft_collection(conn: impl SqliteExecutor<'_>, row: NftCollection Ok(()) } -async fn nft_collection_name( +async fn collection_name( conn: impl SqliteExecutor<'_>, collection_id: Bytes32, ) -> Result> { let collection_id = collection_id.as_ref(); let row = sqlx::query!( - "SELECT `name` FROM `nft_collections` WHERE `collection_id` = ?", + "SELECT `name` FROM `collections` WHERE `collection_id` = ?", collection_id ) .fetch_one(conn) @@ -343,13 +333,14 @@ async fn nft_collection_name( Ok(row.name) } -async fn nft_collection( +async fn collection( conn: impl SqliteExecutor<'_>, collection_id: Bytes32, -) -> Result { +) -> Result { let collection_id = collection_id.as_ref(); - let row = sqlx::query!( + sqlx::query_as!( + CollectionSql, " SELECT `collection_id`, @@ -358,30 +349,23 @@ async fn nft_collection( `visible`, `name`, `icon` - FROM `nft_collections` + FROM `collections` WHERE `collection_id` = ? ", collection_id ) .fetch_one(conn) - .await?; - - Ok(NftCollectionRow { - collection_id: to_bytes32(&row.collection_id)?, - did_id: to_bytes32(&row.did_id)?, - metadata_collection_id: row.metadata_collection_id, - visible: row.visible, - name: row.name, - icon: row.icon, - }) + .await? + .into_row() } -async fn nft_collections_visible_named( +async fn collections_visible_named( conn: impl SqliteExecutor<'_>, offset: u32, limit: u32, -) -> Result> { - let rows = sqlx::query!( +) -> Result> { + sqlx::query_as!( + CollectionSql, " SELECT `collection_id`, @@ -390,7 +374,7 @@ async fn nft_collections_visible_named( `visible`, `name`, `icon` - FROM `nft_collections` INDEXED BY `col_named` + FROM `collections` INDEXED BY `col_name` WHERE `visible` = 1 ORDER BY `is_named` DESC, `name` ASC, `collection_id` ASC LIMIT ? OFFSET ? @@ -399,30 +383,19 @@ async fn nft_collections_visible_named( offset ) .fetch_all(conn) - .await?; - - let mut collections = Vec::new(); - - for row in rows { - collections.push(NftCollectionRow { - collection_id: to_bytes32(&row.collection_id)?, - did_id: to_bytes32(&row.did_id)?, - metadata_collection_id: row.metadata_collection_id, - visible: row.visible, - name: row.name, - icon: row.icon, - }); - } - - Ok(collections) + .await? + .into_iter() + .map(|sql| sql.into_row()) + .collect() } -async fn nft_collections_named( +async fn collections_named( conn: impl SqliteExecutor<'_>, offset: u32, limit: u32, -) -> Result> { - let rows = sqlx::query!( +) -> Result> { + sqlx::query_as!( + CollectionSql, " SELECT `collection_id`, @@ -431,7 +404,7 @@ async fn nft_collections_named( `visible`, `name`, `icon` - FROM `nft_collections` INDEXED BY `col_named` + FROM `collections` INDEXED BY `col_name` ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC LIMIT ? OFFSET ? ", @@ -439,28 +412,16 @@ async fn nft_collections_named( offset ) .fetch_all(conn) - .await?; - - let mut collections = Vec::new(); - - for row in rows { - collections.push(NftCollectionRow { - collection_id: to_bytes32(&row.collection_id)?, - did_id: to_bytes32(&row.did_id)?, - metadata_collection_id: row.metadata_collection_id, - visible: row.visible, - name: row.name, - icon: row.icon, - }); - } - - Ok(collections) + .await? + .into_iter() + .map(|sql| sql.into_row()) + .collect() } -async fn nft_collection_count(conn: impl SqliteExecutor<'_>) -> Result { +async fn collection_count(conn: impl SqliteExecutor<'_>) -> Result { let row = sqlx::query!( " - SELECT COUNT(*) AS `count` FROM `nft_collections` + SELECT COUNT(*) AS `count` FROM `collections` WHERE `visible` = 1 " ) @@ -470,10 +431,10 @@ async fn nft_collection_count(conn: impl SqliteExecutor<'_>) -> Result { Ok(row.count.try_into()?) } -async fn visible_nft_collection_count(conn: impl SqliteExecutor<'_>) -> Result { +async fn visible_collection_count(conn: impl SqliteExecutor<'_>) -> Result { let row = sqlx::query!( " - SELECT COUNT(*) AS `count` FROM `nft_collections` + SELECT COUNT(*) AS `count` FROM `collections` WHERE `visible` = 1 " ) @@ -911,7 +872,7 @@ async fn nfts_visible_named( sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_named` + SELECT * FROM `nfts` INDEXED BY `nft_name` WHERE `visible` = 1 ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? @@ -953,7 +914,7 @@ async fn nfts_named(conn: impl SqliteExecutor<'_>, limit: u32, offset: u32) -> R sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_named` + SELECT * FROM `nfts` INDEXED BY `nft_name` ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -1000,7 +961,7 @@ async fn collection_nfts_visible_named( sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_col_named` + SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? AND `visible` = 1 ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? @@ -1054,7 +1015,7 @@ async fn collection_nfts_named( sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_col_named` + SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? @@ -1105,7 +1066,7 @@ async fn no_collection_nfts_visible_named( sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_col_named` + SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL AND `visible` = 1 ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? @@ -1151,7 +1112,7 @@ async fn no_collection_nfts_named( sqlx::query_as!( SqlNftRow, " - SELECT * FROM `nfts` INDEXED BY `nft_col_named` + SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? diff --git a/crates/sage-database/src/rows.rs b/crates/sage-database/src/rows.rs index 574edbc2..8553a2f4 100644 --- a/crates/sage-database/src/rows.rs +++ b/crates/sage-database/src/rows.rs @@ -1,7 +1,13 @@ mod cat; mod cat_coin; mod coin_state; +mod collection; +mod nft; +mod nft_coin; pub use cat::*; pub use cat_coin::*; pub use coin_state::*; +pub use collection::*; +pub use nft::*; +pub use nft_coin::*; diff --git a/crates/sage-database/src/rows/cat.rs b/crates/sage-database/src/rows/cat.rs index 42a45c6e..6dd6497a 100644 --- a/crates/sage-database/src/rows/cat.rs +++ b/crates/sage-database/src/rows/cat.rs @@ -22,7 +22,7 @@ pub struct CatRow { } impl CatSql { - pub(crate) fn into_row(&self) -> Result { + pub fn into_row(&self) -> Result { Ok(CatRow { asset_id: to_bytes32(&self.asset_id)?, name: self.name.clone(), diff --git a/crates/sage-database/src/rows/cat_coin.rs b/crates/sage-database/src/rows/cat_coin.rs index f4146b28..edcdee90 100644 --- a/crates/sage-database/src/rows/cat_coin.rs +++ b/crates/sage-database/src/rows/cat_coin.rs @@ -35,7 +35,7 @@ pub struct CatCoinRow { } impl CatCoinSql { - pub(crate) fn into_row(self) -> Result { + pub fn into_row(self) -> Result { Ok(CatCoinRow { coin: Coin { parent_coin_info: to_bytes32(&self.parent_coin_id)?, diff --git a/crates/sage-database/src/rows/coin_state.rs b/crates/sage-database/src/rows/coin_state.rs index 4d87fa73..e77f2d2b 100644 --- a/crates/sage-database/src/rows/coin_state.rs +++ b/crates/sage-database/src/rows/coin_state.rs @@ -18,7 +18,7 @@ pub struct CoinStateRow { } impl CoinStateSql { - pub(crate) fn into_row(self) -> Result { + pub fn into_row(self) -> Result { Ok(CoinStateRow { coin_state: CoinState { coin: Coin { diff --git a/crates/sage-database/src/rows/collection.rs b/crates/sage-database/src/rows/collection.rs new file mode 100644 index 00000000..cc5732c6 --- /dev/null +++ b/crates/sage-database/src/rows/collection.rs @@ -0,0 +1,35 @@ +use chia::protocol::Bytes32; + +use crate::{to_bytes32, DatabaseError}; + +pub(crate) struct CollectionSql { + pub collection_id: Vec, + pub did_id: Vec, + pub metadata_collection_id: String, + pub visible: bool, + pub name: Option, + pub icon: Option, +} + +#[derive(Debug, Clone)] +pub struct CollectionRow { + pub collection_id: Bytes32, + pub did_id: Bytes32, + pub metadata_collection_id: String, + pub visible: bool, + pub name: Option, + pub icon: Option, +} + +impl CollectionSql { + pub fn into_row(&self) -> Result { + Ok(CollectionRow { + collection_id: to_bytes32(&self.collection_id)?, + did_id: to_bytes32(&self.did_id)?, + metadata_collection_id: self.metadata_collection_id.clone(), + visible: self.visible, + name: self.name.clone(), + icon: self.icon.clone(), + }) + } +} diff --git a/crates/sage-database/src/rows/nft.rs b/crates/sage-database/src/rows/nft.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/sage-database/src/rows/nft_coin.rs b/crates/sage-database/src/rows/nft_coin.rs new file mode 100644 index 00000000..e69de29b diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index b3b06373..423811d1 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -69,11 +69,14 @@ CREATE TABLE `cats` ( `asset_id` BLOB NOT NULL PRIMARY KEY, `name` TEXT, `ticker` TEXT, + `visible` BOOLEAN NOT NULL, + `icon` TEXT, `description` TEXT, - `icon_url` TEXT, - `visible` BOOLEAN NOT NULL + `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED ); +CREATE INDEX `cat_name` ON `cats` (`visible` DESC, `is_named` DESC, `name` ASC, `asset_id` ASC); + CREATE TABLE `cat_coins` ( `coin_id` BLOB NOT NULL PRIMARY KEY, `parent_parent_coin_id` BLOB NOT NULL, @@ -84,7 +87,6 @@ CREATE TABLE `cat_coins` ( FOREIGN KEY (`coin_id`) REFERENCES `coin_states` (`coin_id`) ON DELETE CASCADE ); -CREATE INDEX `cat_p2` ON `cat_coins` (`p2_puzzle_hash`); CREATE INDEX `cat_asset_id` ON `cat_coins` (`asset_id`); CREATE TABLE `dids` ( @@ -94,7 +96,7 @@ CREATE TABLE `dids` ( `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED ); -CREATE INDEX `did_index` ON `dids` (`visible` DESC, `is_named` DESC, `name` ASC); +CREATE INDEX `did_name` ON `dids` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE TABLE `did_coins` ( `coin_id` BLOB NOT NULL PRIMARY KEY, @@ -110,19 +112,18 @@ CREATE TABLE `did_coins` ( ); CREATE INDEX `did_launcher_id` ON `did_coins` (`launcher_id`); -CREATE INDEX `did_p2` ON `did_coins` (`p2_puzzle_hash`); -CREATE TABLE `nft_collections` ( +CREATE TABLE `collections` ( `collection_id` BLOB NOT NULL PRIMARY KEY, `did_id` BLOB NOT NULL, `metadata_collection_id` TEXT NOT NULL, + `name` TEXT, `visible` BOOLEAN NOT NULL, `icon` TEXT, - `name` TEXT, `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED ); -CREATE INDEX `col_named` ON `nft_collections` (`visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC); +CREATE INDEX `col_name` ON `collections` (`visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC); CREATE TABLE `nfts` ( `launcher_id` BLOB NOT NULL PRIMARY KEY, @@ -141,9 +142,9 @@ CREATE TABLE `nfts` ( ); CREATE INDEX `nft_metadata` ON `nfts` (`metadata_hash`); -CREATE INDEX `nft_named` ON `nfts` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_name` ON `nfts` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE INDEX `nft_recent` ON `nfts` (`visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); -CREATE INDEX `nft_col_named` ON `nfts` (`collection_id`, `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_col_name` ON `nfts` (`collection_id`, `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE INDEX `nft_col_recent` ON `nfts` (`collection_id`, `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); CREATE TABLE `nft_coins` ( @@ -165,7 +166,6 @@ CREATE TABLE `nft_coins` ( ); CREATE INDEX `nft_launcher_id` ON `nft_coins` (`launcher_id`); -CREATE INDEX `nft_p2` ON `nft_coins` (`p2_puzzle_hash`); CREATE TABLE `nft_data` ( `hash` BLOB NOT NULL PRIMARY KEY, From b6ddf77dc17e139c8e77313fd8e09aff018d360f Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 18:19:54 -0500 Subject: [PATCH 05/21] Temp --- crates/sage-database/src/primitives/cats.rs | 16 +++---- crates/sage-database/src/primitives/nfts.rs | 48 +++++--------------- crates/sage-database/src/primitives/xch.rs | 35 +++++---------- crates/sage-database/src/rows/cat.rs | 6 +-- crates/sage-database/src/rows/coin_state.rs | 16 +++++++ crates/sage-database/src/rows/nft.rs | 1 + crates/sage-database/src/rows/nft_coin.rs | 49 +++++++++++++++++++++ 7 files changed, 99 insertions(+), 72 deletions(-) diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 54e87666..149b9b7b 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -78,7 +78,7 @@ async fn maybe_insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result< `name`, `ticker`, `description`, - `icon_url`, + `icon`, `visible` ) VALUES (?, ?, ?, ?, ?, ?) ", @@ -86,7 +86,7 @@ async fn maybe_insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result< row.name, row.ticker, row.description, - row.icon_url, + row.icon, row.visible, ) .execute(conn) @@ -104,7 +104,7 @@ async fn update_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { `name`, `ticker`, `description`, - `icon_url`, + `icon`, `visible` ) VALUES (?, ?, ?, ?, ?, ?) ", @@ -112,7 +112,7 @@ async fn update_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { row.name, row.ticker, row.description, - row.icon_url, + row.icon, row.visible ) .execute(conn) @@ -143,7 +143,7 @@ async fn cats(conn: impl SqliteExecutor<'_>) -> Result> { `name`, `ticker`, `description`, - `icon_url`, + `icon`, `visible` FROM `cats` ORDER BY `name` ASC, `asset_id` ASC @@ -159,7 +159,7 @@ async fn cats(conn: impl SqliteExecutor<'_>) -> Result> { name: row.name, ticker: row.ticker, description: row.description, - icon_url: row.icon_url, + icon: row.icon, visible: row.visible, }) }) @@ -176,7 +176,7 @@ async fn cat(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result, asset_id: Bytes32) -> Result Result>> { let launcher_id = launcher_id.as_ref(); - let Some(row) = sqlx::query!( + let Some(sql) = sqlx::query_as!( + FullNftCoinSql, " SELECT `coin_states`.`parent_coin_id`, @@ -771,29 +774,14 @@ async fn spendable_nft( return Ok(None); }; - Ok(Some(Nft { - coin: to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - proof: Proof::Lineage(to_lineage_proof( - &row.parent_parent_coin_id, - &row.parent_inner_puzzle_hash, - &row.parent_amount, - )?), - info: NftInfo { - launcher_id: to_bytes32(&row.launcher_id)?, - metadata: row.metadata.into(), - metadata_updater_puzzle_hash: to_bytes32(&row.metadata_updater_puzzle_hash)?, - current_owner: row.current_owner.as_deref().map(to_bytes32).transpose()?, - royalty_puzzle_hash: to_bytes32(&row.royalty_puzzle_hash)?, - royalty_ten_thousandths: row.royalty_ten_thousandths.try_into()?, - p2_puzzle_hash: to_bytes32(&row.p2_puzzle_hash)?, - }, - })) + Ok(Some(sql.into_row()?)) } async fn nft(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result>> { let launcher_id = launcher_id.as_ref(); - let Some(row) = sqlx::query!( + let Some(sql) = sqlx::query_as!( + FullNftCoinSql, " SELECT `coin_states`.`parent_coin_id`, @@ -824,23 +812,7 @@ async fn nft(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result Result> { @@ -59,7 +57,8 @@ async fn balance(conn: impl SqliteExecutor<'_>) -> Result { } async fn spendable_coins(conn: impl SqliteExecutor<'_>) -> Result> { - let rows = sqlx::query!( + sqlx::query_as!( + CoinSql, " SELECT `coin_states`.`parent_coin_id`, `coin_states`.`puzzle_hash`, `coin_states`.`amount` FROM `coin_states` INNER JOIN `p2_coins` ON `coin_states`.`coin_id` = `p2_coins`.`coin_id` @@ -70,33 +69,23 @@ async fn spendable_coins(conn: impl SqliteExecutor<'_>) -> Result> { " ) .fetch_all(conn) - .await?; - - rows.iter() - .map(|row| to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)) - .collect() + .await? + .into_iter() + .map(|sql| sql.into_row()) + .collect() } async fn p2_coin_states(conn: impl SqliteExecutor<'_>) -> Result> { - let rows = sqlx::query!( + let rows = sqlx::query_as!( + CoinStateSql, " - SELECT `coin_states`.* FROM `coin_states` + SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id` + FROM `coin_states` INNER JOIN `p2_coins` ON `coin_states`.`coin_id` = `p2_coins`.`coin_id` " ) .fetch_all(conn) .await?; - rows.into_iter() - .map(|row| { - Ok(CoinStateRow { - coin_state: to_coin_state( - to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - row.created_height, - row.spent_height, - )?, - transaction_id: row.transaction_id.map(|id| to_bytes32(&id)).transpose()?, - }) - }) - .collect() + rows.into_iter().map(|sql| sql.into_row()).collect() } diff --git a/crates/sage-database/src/rows/cat.rs b/crates/sage-database/src/rows/cat.rs index 6dd6497a..0381ee0c 100644 --- a/crates/sage-database/src/rows/cat.rs +++ b/crates/sage-database/src/rows/cat.rs @@ -7,7 +7,7 @@ pub(crate) struct CatSql { pub name: Option, pub ticker: Option, pub description: Option, - pub icon_url: Option, + pub icon: Option, pub visible: bool, } @@ -17,7 +17,7 @@ pub struct CatRow { pub name: Option, pub ticker: Option, pub description: Option, - pub icon_url: Option, + pub icon: Option, pub visible: bool, } @@ -28,7 +28,7 @@ impl CatSql { name: self.name.clone(), ticker: self.ticker.clone(), description: self.description.clone(), - icon_url: self.icon_url.clone(), + icon: self.icon.clone(), visible: self.visible, }) } diff --git a/crates/sage-database/src/rows/coin_state.rs b/crates/sage-database/src/rows/coin_state.rs index e77f2d2b..0fce7bd2 100644 --- a/crates/sage-database/src/rows/coin_state.rs +++ b/crates/sage-database/src/rows/coin_state.rs @@ -11,6 +11,12 @@ pub(crate) struct CoinStateSql { pub transaction_id: Option>, } +pub(crate) struct CoinSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, +} + #[derive(Debug, Clone, Copy)] pub struct CoinStateRow { pub coin_state: CoinState, @@ -33,3 +39,13 @@ impl CoinStateSql { }) } } + +impl CoinSql { + pub fn into_row(self) -> Result { + Ok(Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }) + } +} diff --git a/crates/sage-database/src/rows/nft.rs b/crates/sage-database/src/rows/nft.rs index e69de29b..8b137891 100644 --- a/crates/sage-database/src/rows/nft.rs +++ b/crates/sage-database/src/rows/nft.rs @@ -0,0 +1 @@ + diff --git a/crates/sage-database/src/rows/nft_coin.rs b/crates/sage-database/src/rows/nft_coin.rs index e69de29b..ddc12965 100644 --- a/crates/sage-database/src/rows/nft_coin.rs +++ b/crates/sage-database/src/rows/nft_coin.rs @@ -0,0 +1,49 @@ +use chia::{ + protocol::{Coin, Program}, + puzzles::{LineageProof, Proof}, +}; +use chia_wallet_sdk::{Nft, NftInfo}; + +use crate::{to_bytes32, to_u64, DatabaseError}; + +pub(crate) struct FullNftCoinSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, + pub parent_parent_coin_id: Vec, + pub parent_inner_puzzle_hash: Vec, + pub parent_amount: Vec, + pub launcher_id: Vec, + pub metadata: Vec, + pub metadata_updater_puzzle_hash: Vec, + pub current_owner: Option>, + pub royalty_puzzle_hash: Vec, + pub royalty_ten_thousandths: i64, + pub p2_puzzle_hash: Vec, +} + +impl FullNftCoinSql { + pub fn into_row(self) -> Result, DatabaseError> { + Ok(Nft { + coin: Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }, + proof: Proof::Lineage(LineageProof { + parent_parent_coin_info: to_bytes32(&self.parent_parent_coin_id)?, + parent_inner_puzzle_hash: to_bytes32(&self.parent_inner_puzzle_hash)?, + parent_amount: to_u64(&self.parent_amount)?, + }), + info: NftInfo { + launcher_id: to_bytes32(&self.launcher_id)?, + metadata: self.metadata.into(), + metadata_updater_puzzle_hash: to_bytes32(&self.metadata_updater_puzzle_hash)?, + current_owner: self.current_owner.as_deref().map(to_bytes32).transpose()?, + royalty_puzzle_hash: to_bytes32(&self.royalty_puzzle_hash)?, + royalty_ten_thousandths: self.royalty_ten_thousandths.try_into()?, + p2_puzzle_hash: to_bytes32(&self.p2_puzzle_hash)?, + }, + }) + } +} From 49ccadbfb47ccdf654f6d4171a21672efee0afe2 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 18:26:54 -0500 Subject: [PATCH 06/21] Temp --- crates/sage-database/src/primitives/dids.rs | 9 ------- crates/sage-database/src/rows.rs | 8 ++++++ crates/sage-database/src/rows/did.rs | 25 +++++++++++++++++++ crates/sage-database/src/rows/did_coin.rs | 0 crates/sage-database/src/rows/nft_data.rs | 0 crates/sage-database/src/rows/nft_uri.rs | 0 crates/sage-wallet/src/lib.rs | 4 +-- crates/sage-wallet/src/{data.rs => utils.rs} | 0 .../src/{data => utils}/fetch_nft_did.rs | 0 .../src/{data => utils}/fetch_uri.rs | 0 .../src/{data => utils}/insert_transaction.rs | 0 .../src/{data => utils}/offchain_metadata.rs | 0 12 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 crates/sage-database/src/rows/did.rs create mode 100644 crates/sage-database/src/rows/did_coin.rs create mode 100644 crates/sage-database/src/rows/nft_data.rs create mode 100644 crates/sage-database/src/rows/nft_uri.rs rename crates/sage-wallet/src/{data.rs => utils.rs} (100%) rename crates/sage-wallet/src/{data => utils}/fetch_nft_did.rs (100%) rename crates/sage-wallet/src/{data => utils}/fetch_uri.rs (100%) rename crates/sage-wallet/src/{data => utils}/insert_transaction.rs (100%) rename crates/sage-wallet/src/{data => utils}/offchain_metadata.rs (100%) diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index d15ae765..b0b9f6d8 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -7,15 +7,6 @@ use sqlx::SqliteExecutor; use crate::{to_bytes, to_bytes32, Database, DatabaseTx, Result}; -#[derive(Debug, Clone)] -pub struct DidRow { - pub did: Did, - pub name: Option, - pub visible: bool, - pub create_transaction_id: Option, - pub created_height: Option, -} - impl Database { pub async fn insert_new_did( &self, diff --git a/crates/sage-database/src/rows.rs b/crates/sage-database/src/rows.rs index 8553a2f4..764234df 100644 --- a/crates/sage-database/src/rows.rs +++ b/crates/sage-database/src/rows.rs @@ -2,12 +2,20 @@ mod cat; mod cat_coin; mod coin_state; mod collection; +mod did; +mod did_coin; mod nft; mod nft_coin; +mod nft_data; +mod nft_uri; pub use cat::*; pub use cat_coin::*; pub use coin_state::*; pub use collection::*; +pub use did::*; +pub use did_coin::*; pub use nft::*; pub use nft_coin::*; +pub use nft_data::*; +pub use nft_uri::*; diff --git a/crates/sage-database/src/rows/did.rs b/crates/sage-database/src/rows/did.rs new file mode 100644 index 00000000..31bea5be --- /dev/null +++ b/crates/sage-database/src/rows/did.rs @@ -0,0 +1,25 @@ +use chia::protocol::Bytes32; + +use crate::{to_bytes32, DatabaseError}; + +pub(crate) struct DidSql { + pub launcher_id: Vec, + pub name: Option, + pub visible: bool, +} + +pub struct DidRow { + pub launcher_id: Bytes32, + pub name: Option, + pub visible: bool, +} + +impl DidSql { + pub fn into_row(self) -> Result { + Ok(DidRow { + launcher_id: to_bytes32(&self.launcher_id)?, + name: self.name, + visible: self.visible, + }) + } +} diff --git a/crates/sage-database/src/rows/did_coin.rs b/crates/sage-database/src/rows/did_coin.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/sage-database/src/rows/nft_data.rs b/crates/sage-database/src/rows/nft_data.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/sage-database/src/rows/nft_uri.rs b/crates/sage-database/src/rows/nft_uri.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/sage-wallet/src/lib.rs b/crates/sage-wallet/src/lib.rs index ff3cb1d8..0494a2a5 100644 --- a/crates/sage-wallet/src/lib.rs +++ b/crates/sage-wallet/src/lib.rs @@ -1,17 +1,17 @@ mod child_kind; mod coin_kind; -mod data; mod error; mod queues; mod sync_manager; mod transaction; +mod utils; mod wallet; pub use child_kind::*; pub use coin_kind::*; -pub use data::*; pub use error::*; pub use queues::*; pub use sync_manager::*; pub use transaction::*; +pub use utils::*; pub use wallet::*; diff --git a/crates/sage-wallet/src/data.rs b/crates/sage-wallet/src/utils.rs similarity index 100% rename from crates/sage-wallet/src/data.rs rename to crates/sage-wallet/src/utils.rs diff --git a/crates/sage-wallet/src/data/fetch_nft_did.rs b/crates/sage-wallet/src/utils/fetch_nft_did.rs similarity index 100% rename from crates/sage-wallet/src/data/fetch_nft_did.rs rename to crates/sage-wallet/src/utils/fetch_nft_did.rs diff --git a/crates/sage-wallet/src/data/fetch_uri.rs b/crates/sage-wallet/src/utils/fetch_uri.rs similarity index 100% rename from crates/sage-wallet/src/data/fetch_uri.rs rename to crates/sage-wallet/src/utils/fetch_uri.rs diff --git a/crates/sage-wallet/src/data/insert_transaction.rs b/crates/sage-wallet/src/utils/insert_transaction.rs similarity index 100% rename from crates/sage-wallet/src/data/insert_transaction.rs rename to crates/sage-wallet/src/utils/insert_transaction.rs diff --git a/crates/sage-wallet/src/data/offchain_metadata.rs b/crates/sage-wallet/src/utils/offchain_metadata.rs similarity index 100% rename from crates/sage-wallet/src/data/offchain_metadata.rs rename to crates/sage-wallet/src/utils/offchain_metadata.rs From d786a47367a04c7b205aeab402fee0dc58521712 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 21:31:13 -0500 Subject: [PATCH 07/21] Temp --- crates/sage-database/src/coin_states.rs | 22 ++++- crates/sage-database/src/primitives.rs | 2 - crates/sage-database/src/primitives/cats.rs | 10 +- crates/sage-database/src/primitives/dids.rs | 92 ++++--------------- crates/sage-database/src/primitives/nfts.rs | 7 +- crates/sage-database/src/primitives/xch.rs | 8 +- crates/sage-database/src/rows.rs | 12 +++ crates/sage-database/src/rows/cat.rs | 8 +- crates/sage-database/src/rows/cat_coin.rs | 14 ++- crates/sage-database/src/rows/coin_state.rs | 14 ++- crates/sage-database/src/rows/collection.rs | 8 +- crates/sage-database/src/rows/did.rs | 9 +- crates/sage-database/src/rows/did_coin.rs | 53 +++++++++++ crates/sage-database/src/rows/nft_coin.rs | 8 +- crates/sage-database/src/transactions.rs | 20 ++-- crates/sage-wallet/src/database.rs | 51 ++++++++++ crates/sage-wallet/src/lib.rs | 1 + .../src/utils/offchain_metadata.rs | 6 +- 18 files changed, 225 insertions(+), 120 deletions(-) create mode 100644 crates/sage-wallet/src/database.rs diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index 7215179a..6893e441 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -1,7 +1,7 @@ use chia::protocol::{Bytes32, CoinState}; use sqlx::SqliteExecutor; -use crate::{to_bytes32, CoinStateSql, Database, DatabaseTx, Result}; +use crate::{to_bytes32, CoinStateSql, Database, DatabaseTx, IntoRow, Result}; impl Database { pub async fn unsynced_coin_states(&self, limit: usize) -> Result> { @@ -19,13 +19,21 @@ impl<'a> DatabaseTx<'a> { insert_coin_state(&mut *self.tx, coin_state, synced, transaction_id).await } - pub async fn set_coin_height( + pub async fn update_coin_state( &mut self, coin_id: Bytes32, created_height: Option, spent_height: Option, + transaction_id: Option, ) -> Result<()> { - set_coin_height(&mut *self.tx, coin_id, created_height, spent_height).await + update_coin_state( + &mut *self.tx, + coin_id, + created_height, + spent_height, + transaction_id, + ) + .await } pub async fn sync_coin(&mut self, coin_id: Bytes32, hint: Option) -> Result<()> { @@ -107,21 +115,25 @@ async fn insert_coin_state( Ok(()) } -async fn set_coin_height( +async fn update_coin_state( conn: impl SqliteExecutor<'_>, coin_id: Bytes32, created_height: Option, spent_height: Option, + transaction_id: Option, ) -> Result<()> { let coin_id = coin_id.as_ref(); + let transaction_id = transaction_id.as_deref(); + sqlx::query!( " UPDATE `coin_states` - SET `created_height` = ?, `spent_height` = ?, `transaction_id` = NULL + SET `created_height` = ?, `spent_height` = ?, `transaction_id` = ? WHERE `coin_id` = ? ", created_height, spent_height, + transaction_id, coin_id ) .execute(conn) diff --git a/crates/sage-database/src/primitives.rs b/crates/sage-database/src/primitives.rs index 1343ae7e..79938611 100644 --- a/crates/sage-database/src/primitives.rs +++ b/crates/sage-database/src/primitives.rs @@ -3,6 +3,4 @@ mod dids; mod nfts; mod xch; -pub use cats::*; -pub use dids::*; pub use nfts::*; diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 149b9b7b..56976320 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -3,8 +3,8 @@ use chia_wallet_sdk::Cat; use sqlx::SqliteExecutor; use crate::{ - to_bytes, to_bytes32, CatCoinRow, CatCoinSql, CatRow, CoinStateRow, CoinStateSql, Database, - DatabaseTx, FullCatCoinSql, Result, + into_row, to_bytes, to_bytes32, CatCoinRow, CatCoinSql, CatRow, CoinStateRow, CoinStateSql, + Database, DatabaseTx, FullCatCoinSql, Result, }; impl Database { @@ -277,7 +277,7 @@ async fn spendable_cat_coins( .fetch_all(conn) .await?; - rows.into_iter().map(|sql| sql.into_row()).collect() + rows.into_iter().map(into_row).collect() } async fn cat_balance(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result { @@ -321,7 +321,7 @@ async fn cat_coin_states( .fetch_all(conn) .await?; - rows.into_iter().map(|sql| sql.into_row()).collect() + rows.into_iter().map(into_row).collect() } async fn cat_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result> { @@ -343,5 +343,5 @@ async fn cat_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result Result> { - did_coins(&self.pool).await + pub async fn dids_by_name(&self) -> Result> { + dids_by_name(&self.pool).await } pub async fn did(&self, did_id: Bytes32) -> Result>> { @@ -162,66 +162,27 @@ async fn insert_did_coin( Ok(()) } -async fn did_coins(conn: impl SqliteExecutor<'_>) -> Result> { - let rows = sqlx::query!( +async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { + sqlx::query_as!( + DidSql, " - SELECT - cs.parent_coin_id, cs.puzzle_hash, cs.amount, - cs.transaction_id AS create_transaction_id, cs.created_height, - did.parent_parent_coin_id, did.parent_inner_puzzle_hash, did.parent_amount, - did.launcher_id, did.recovery_list_hash, did.num_verifications_required, - did.metadata, did.p2_puzzle_hash, name, visible - FROM `coin_states` AS cs - INNER JOIN `did_coins` AS did ON cs.coin_id = did.coin_id - INNER JOIN `dids` ON did.launcher_id = dids.launcher_id - LEFT JOIN `transaction_spends` ON cs.coin_id = transaction_spends.coin_id - WHERE cs.spent_height IS NULL - AND transaction_spends.transaction_id IS NULL + SELECT `launcher_id`, `name`, `visible` + FROM `dids` INDEXED BY `did_name` + ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC " ) .fetch_all(conn) - .await?; - - rows.into_iter() - .map(|row| { - Ok(DidRow { - did: Did { - coin: to_coin(&row.parent_coin_id, &row.puzzle_hash, &row.amount)?, - proof: Proof::Lineage(to_lineage_proof( - &row.parent_parent_coin_id, - &row.parent_inner_puzzle_hash, - &row.parent_amount, - )?), - info: DidInfo:: { - launcher_id: to_bytes32(&row.launcher_id)?, - recovery_list_hash: row - .recovery_list_hash - .map(|hash| to_bytes32(&hash)) - .transpose()?, - num_verifications_required: u64::from_be_bytes(to_bytes( - &row.num_verifications_required, - )?), - metadata: row.metadata.into(), - p2_puzzle_hash: to_bytes32(&row.p2_puzzle_hash)?, - }, - }, - name: row.name, - visible: row.visible, - create_transaction_id: row - .create_transaction_id - .as_deref() - .map(to_bytes32) - .transpose()?, - created_height: row.created_height.map(TryInto::try_into).transpose()?, - }) - }) - .collect() + .await? + .into_iter() + .map(into_row) + .collect() } async fn did(conn: impl SqliteExecutor<'_>, did_id: Bytes32) -> Result>> { let did_id = did_id.as_ref(); - let Some(row) = sqlx::query!( + let Some(sql) = sqlx::query_as!( + FullDidCoinSql, " SELECT cs.parent_coin_id, cs.puzzle_hash, cs.amount, @@ -245,26 +206,7 @@ async fn did(conn: impl SqliteExecutor<'_>, did_id: Bytes32) -> Result { - launcher_id: to_bytes32(&row.launcher_id)?, - recovery_list_hash: row - .recovery_list_hash - .map(|hash| to_bytes32(&hash)) - .transpose()?, - num_verifications_required: u64::from_be_bytes(to_bytes( - &row.num_verifications_required, - )?), - metadata: row.metadata.into(), - p2_puzzle_hash: to_bytes32(&row.p2_puzzle_hash)?, - }, - })) + Ok(Some(sql.into_row()?)) } async fn did_name(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result> { diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index 36e55c3a..c4e5e43c 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -6,7 +6,8 @@ use chia_wallet_sdk::{Nft, NftInfo}; use sqlx::SqliteExecutor; use crate::{ - to_bytes32, CollectionRow, CollectionSql, Database, DatabaseTx, FullNftCoinSql, Result, + into_row, to_bytes32, CollectionRow, CollectionSql, Database, DatabaseTx, FullNftCoinSql, + IntoRow, Result, }; #[derive(Debug, Clone)] @@ -387,7 +388,7 @@ async fn collections_visible_named( .fetch_all(conn) .await? .into_iter() - .map(|sql| sql.into_row()) + .map(into_row) .collect() } @@ -416,7 +417,7 @@ async fn collections_named( .fetch_all(conn) .await? .into_iter() - .map(|sql| sql.into_row()) + .map(into_row) .collect() } diff --git a/crates/sage-database/src/primitives/xch.rs b/crates/sage-database/src/primitives/xch.rs index f7d013fb..023d9f30 100644 --- a/crates/sage-database/src/primitives/xch.rs +++ b/crates/sage-database/src/primitives/xch.rs @@ -1,7 +1,9 @@ use chia::protocol::{Bytes32, Coin}; use sqlx::SqliteExecutor; -use crate::{to_bytes, CoinSql, CoinStateRow, CoinStateSql, Database, DatabaseTx, Result}; +use crate::{ + into_row, to_bytes, CoinSql, CoinStateRow, CoinStateSql, Database, DatabaseTx, Result, +}; impl Database { pub async fn spendable_coins(&self) -> Result> { @@ -71,7 +73,7 @@ async fn spendable_coins(conn: impl SqliteExecutor<'_>) -> Result> { .fetch_all(conn) .await? .into_iter() - .map(|sql| sql.into_row()) + .map(into_row) .collect() } @@ -87,5 +89,5 @@ async fn p2_coin_states(conn: impl SqliteExecutor<'_>) -> Result Result; +} + +pub(crate) fn into_row(t: T) -> Result { + t.into_row() +} diff --git a/crates/sage-database/src/rows/cat.rs b/crates/sage-database/src/rows/cat.rs index 0381ee0c..f3b09b78 100644 --- a/crates/sage-database/src/rows/cat.rs +++ b/crates/sage-database/src/rows/cat.rs @@ -2,6 +2,8 @@ use chia::protocol::Bytes32; use crate::{to_bytes32, DatabaseError}; +use super::IntoRow; + pub(crate) struct CatSql { pub asset_id: Vec, pub name: Option, @@ -21,8 +23,10 @@ pub struct CatRow { pub visible: bool, } -impl CatSql { - pub fn into_row(&self) -> Result { +impl IntoRow for CatSql { + type Row = CatRow; + + fn into_row(self) -> Result { Ok(CatRow { asset_id: to_bytes32(&self.asset_id)?, name: self.name.clone(), diff --git a/crates/sage-database/src/rows/cat_coin.rs b/crates/sage-database/src/rows/cat_coin.rs index edcdee90..82c753c9 100644 --- a/crates/sage-database/src/rows/cat_coin.rs +++ b/crates/sage-database/src/rows/cat_coin.rs @@ -6,6 +6,8 @@ use chia_wallet_sdk::Cat; use crate::{to_bytes32, to_u64, DatabaseError}; +use super::IntoRow; + pub(crate) struct CatCoinSql { pub parent_coin_id: Vec, pub puzzle_hash: Vec, @@ -34,8 +36,10 @@ pub struct CatCoinRow { pub p2_puzzle_hash: Bytes32, } -impl CatCoinSql { - pub fn into_row(self) -> Result { +impl IntoRow for CatCoinSql { + type Row = CatCoinRow; + + fn into_row(self) -> Result { Ok(CatCoinRow { coin: Coin { parent_coin_info: to_bytes32(&self.parent_coin_id)?, @@ -52,8 +56,10 @@ impl CatCoinSql { } } -impl FullCatCoinSql { - pub(crate) fn into_row(self) -> Result { +impl IntoRow for FullCatCoinSql { + type Row = Cat; + + fn into_row(self) -> Result { Ok(Cat { coin: Coin { parent_coin_info: to_bytes32(&self.parent_coin_id)?, diff --git a/crates/sage-database/src/rows/coin_state.rs b/crates/sage-database/src/rows/coin_state.rs index 0fce7bd2..45416897 100644 --- a/crates/sage-database/src/rows/coin_state.rs +++ b/crates/sage-database/src/rows/coin_state.rs @@ -2,6 +2,8 @@ use chia::protocol::{Bytes32, Coin, CoinState}; use crate::{to_bytes32, to_u64, DatabaseError}; +use super::IntoRow; + pub(crate) struct CoinStateSql { pub parent_coin_id: Vec, pub puzzle_hash: Vec, @@ -23,8 +25,10 @@ pub struct CoinStateRow { pub transaction_id: Option, } -impl CoinStateSql { - pub fn into_row(self) -> Result { +impl IntoRow for CoinStateSql { + type Row = CoinStateRow; + + fn into_row(self) -> Result { Ok(CoinStateRow { coin_state: CoinState { coin: Coin { @@ -40,8 +44,10 @@ impl CoinStateSql { } } -impl CoinSql { - pub fn into_row(self) -> Result { +impl IntoRow for CoinSql { + type Row = Coin; + + fn into_row(self) -> Result { Ok(Coin { parent_coin_info: to_bytes32(&self.parent_coin_id)?, puzzle_hash: to_bytes32(&self.puzzle_hash)?, diff --git a/crates/sage-database/src/rows/collection.rs b/crates/sage-database/src/rows/collection.rs index cc5732c6..72292c14 100644 --- a/crates/sage-database/src/rows/collection.rs +++ b/crates/sage-database/src/rows/collection.rs @@ -2,6 +2,8 @@ use chia::protocol::Bytes32; use crate::{to_bytes32, DatabaseError}; +use super::IntoRow; + pub(crate) struct CollectionSql { pub collection_id: Vec, pub did_id: Vec, @@ -21,8 +23,10 @@ pub struct CollectionRow { pub icon: Option, } -impl CollectionSql { - pub fn into_row(&self) -> Result { +impl IntoRow for CollectionSql { + type Row = CollectionRow; + + fn into_row(self) -> Result { Ok(CollectionRow { collection_id: to_bytes32(&self.collection_id)?, did_id: to_bytes32(&self.did_id)?, diff --git a/crates/sage-database/src/rows/did.rs b/crates/sage-database/src/rows/did.rs index 31bea5be..29561c25 100644 --- a/crates/sage-database/src/rows/did.rs +++ b/crates/sage-database/src/rows/did.rs @@ -2,20 +2,25 @@ use chia::protocol::Bytes32; use crate::{to_bytes32, DatabaseError}; +use super::IntoRow; + pub(crate) struct DidSql { pub launcher_id: Vec, pub name: Option, pub visible: bool, } +#[derive(Debug, Clone)] pub struct DidRow { pub launcher_id: Bytes32, pub name: Option, pub visible: bool, } -impl DidSql { - pub fn into_row(self) -> Result { +impl IntoRow for DidSql { + type Row = DidRow; + + fn into_row(self) -> Result { Ok(DidRow { launcher_id: to_bytes32(&self.launcher_id)?, name: self.name, diff --git a/crates/sage-database/src/rows/did_coin.rs b/crates/sage-database/src/rows/did_coin.rs index e69de29b..422577b2 100644 --- a/crates/sage-database/src/rows/did_coin.rs +++ b/crates/sage-database/src/rows/did_coin.rs @@ -0,0 +1,53 @@ +use chia::{ + protocol::{Coin, Program}, + puzzles::{LineageProof, Proof}, +}; +use chia_wallet_sdk::{Did, DidInfo}; + +use crate::{to_bytes32, to_u64, DatabaseError}; + +use super::IntoRow; + +pub(crate) struct FullDidCoinSql { + pub parent_coin_id: Vec, + pub puzzle_hash: Vec, + pub amount: Vec, + pub parent_parent_coin_id: Vec, + pub parent_inner_puzzle_hash: Vec, + pub parent_amount: Vec, + pub launcher_id: Vec, + pub recovery_list_hash: Option>, + pub num_verifications_required: Vec, + pub metadata: Vec, + pub p2_puzzle_hash: Vec, +} + +impl IntoRow for FullDidCoinSql { + type Row = Did; + + fn into_row(self) -> Result, DatabaseError> { + Ok(Did { + coin: Coin { + parent_coin_info: to_bytes32(&self.parent_coin_id)?, + puzzle_hash: to_bytes32(&self.puzzle_hash)?, + amount: to_u64(&self.amount)?, + }, + proof: Proof::Lineage(LineageProof { + parent_parent_coin_info: to_bytes32(&self.parent_parent_coin_id)?, + parent_inner_puzzle_hash: to_bytes32(&self.parent_inner_puzzle_hash)?, + parent_amount: to_u64(&self.parent_amount)?, + }), + info: DidInfo { + launcher_id: to_bytes32(&self.launcher_id)?, + recovery_list_hash: self + .recovery_list_hash + .as_deref() + .map(to_bytes32) + .transpose()?, + num_verifications_required: to_u64(&self.num_verifications_required)?, + metadata: self.metadata.into(), + p2_puzzle_hash: to_bytes32(&self.p2_puzzle_hash)?, + }, + }) + } +} diff --git a/crates/sage-database/src/rows/nft_coin.rs b/crates/sage-database/src/rows/nft_coin.rs index ddc12965..22544c98 100644 --- a/crates/sage-database/src/rows/nft_coin.rs +++ b/crates/sage-database/src/rows/nft_coin.rs @@ -6,6 +6,8 @@ use chia_wallet_sdk::{Nft, NftInfo}; use crate::{to_bytes32, to_u64, DatabaseError}; +use super::IntoRow; + pub(crate) struct FullNftCoinSql { pub parent_coin_id: Vec, pub puzzle_hash: Vec, @@ -22,8 +24,10 @@ pub(crate) struct FullNftCoinSql { pub p2_puzzle_hash: Vec, } -impl FullNftCoinSql { - pub fn into_row(self) -> Result, DatabaseError> { +impl IntoRow for FullNftCoinSql { + type Row = Nft; + + fn into_row(self) -> Result, DatabaseError> { Ok(Nft { coin: Coin { parent_coin_info: to_bytes32(&self.parent_coin_id)?, diff --git a/crates/sage-database/src/transactions.rs b/crates/sage-database/src/transactions.rs index 55a9ff96..77ab380b 100644 --- a/crates/sage-database/src/transactions.rs +++ b/crates/sage-database/src/transactions.rs @@ -69,7 +69,10 @@ impl<'a> DatabaseTx<'a> { remove_transaction(&mut *self.tx, transaction_id).await } - pub async fn transaction_for_spent_coin(&mut self, coin_id: Bytes32) -> Result> { + pub async fn transaction_for_spent_coin( + &mut self, + coin_id: Bytes32, + ) -> Result> { transaction_for_spent_coin(&mut *self.tx, coin_id).await } } @@ -321,10 +324,10 @@ async fn confirm_coins(conn: impl SqliteExecutor<'_>, transaction_id: Bytes32) - async fn transaction_for_spent_coin( conn: impl SqliteExecutor<'_>, coin_id: Bytes32, -) -> Result> { +) -> Result> { let coin_id = coin_id.as_ref(); - let rows = sqlx::query!( + let Some(row) = sqlx::query!( " SELECT `transaction_id` FROM `transaction_spends` @@ -332,10 +335,11 @@ async fn transaction_for_spent_coin( ", coin_id ) - .fetch_all(conn) - .await?; + .fetch_optional(conn) + .await? + else { + return Ok(None); + }; - rows.into_iter() - .map(|row| to_bytes32(&row.transaction_id)) - .collect() + Ok(Some(to_bytes32(&row.transaction_id)?)) } diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs new file mode 100644 index 00000000..135afaf0 --- /dev/null +++ b/crates/sage-wallet/src/database.rs @@ -0,0 +1,51 @@ +use chia::protocol::{Bytes32, CoinState}; +use sage_database::DatabaseTx; + +use crate::WalletError; + +pub async fn upsert_coin( + tx: &mut DatabaseTx<'_>, + coin_state: CoinState, + transaction_id: Option, +) -> Result<(), WalletError> { + let coin_id = coin_state.coin.coin_id(); + + // Check if the coin is plain XCH, rather than an asset that wraps the p2 puzzle hash. + let is_p2 = tx.is_p2_puzzle_hash(coin_state.coin.puzzle_hash).await?; + + // If the coin is XCH, there's no reason to sync the puzzle. + tx.insert_coin_state(coin_state, is_p2, transaction_id) + .await?; + + // If the coin already existed, instead of replacing it we will just update it. + tx.update_coin_state( + coin_id, + coin_state.created_height, + coin_state.spent_height, + transaction_id, + ) + .await?; + + // This allows querying for XCH coins without joining on the derivations table. + if is_p2 { + tx.insert_p2_coin(coin_id).await?; + } + + if coin_state.spent_height.is_some() { + spend_coin(tx, coin_id).await?; + } + + Ok(()) +} + +pub async fn spend_coin(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { + if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { + tx.remove_transaction(transaction_id).await?; + } + + if let Some(launcher_id) = tx.nft_launcher_id(coin_id).await? { + tx.delete_nft(launcher_id).await?; + } + + Ok(()) +} diff --git a/crates/sage-wallet/src/lib.rs b/crates/sage-wallet/src/lib.rs index 0494a2a5..26236518 100644 --- a/crates/sage-wallet/src/lib.rs +++ b/crates/sage-wallet/src/lib.rs @@ -1,5 +1,6 @@ mod child_kind; mod coin_kind; +mod database; mod error; mod queues; mod sync_manager; diff --git a/crates/sage-wallet/src/utils/offchain_metadata.rs b/crates/sage-wallet/src/utils/offchain_metadata.rs index eec9a37a..2ff95c3b 100644 --- a/crates/sage-wallet/src/utils/offchain_metadata.rs +++ b/crates/sage-wallet/src/utils/offchain_metadata.rs @@ -1,5 +1,5 @@ use chia::{protocol::Bytes32, sha2::Sha256}; -use sage_database::NftCollectionRow; +use sage_database::CollectionRow; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -40,7 +40,7 @@ struct Attribute { pub struct ComputedNftInfo { pub name: Option, pub sensitive_content: bool, - pub collection: Option, + pub collection: Option, } pub fn compute_nft_info(did_id: Option, blob: Option<&[u8]>) -> ComputedNftInfo { @@ -57,7 +57,7 @@ pub fn compute_nft_info(did_id: Option, blob: Option<&[u8]>) -> Compute }), ) = (did_id, json.collection) { - Some(NftCollectionRow { + Some(CollectionRow { collection_id: calculate_collection_id(did_id, &metadata_collection_id), did_id, metadata_collection_id, From 7d79e93bf92c307a9905b20865c140d5ab3ab9e1 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 22:00:27 -0500 Subject: [PATCH 08/21] Temp --- crates/sage-database/src/coin_states.rs | 15 +- crates/sage-database/src/rows/nft_uri.rs | 1 + crates/sage-wallet/src/child_kind.rs | 13 ++ crates/sage-wallet/src/database.rs | 124 +++++++++++- crates/sage-wallet/src/queues/cat_queue.rs | 2 +- .../sage-wallet/src/queues/nft_uri_queue.rs | 2 +- crates/sage-wallet/src/queues/puzzle_queue.rs | 178 +++++------------- .../src/sync_manager/wallet_sync.rs | 11 +- .../src/utils/insert_transaction.rs | 139 ++------------ migrations/0001_setup.sql | 5 - src-tauri/src/commands/actions.rs | 2 +- src-tauri/src/commands/data.rs | 21 +-- src-tauri/src/commands/transactions.rs | 17 +- 13 files changed, 239 insertions(+), 291 deletions(-) diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index 6893e441..8dcb328c 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -36,6 +36,10 @@ impl<'a> DatabaseTx<'a> { .await } + pub async fn delete_coin_state(&mut self, coin_id: Bytes32) -> Result<()> { + delete_coin_state(&mut *self.tx, coin_id).await + } + pub async fn sync_coin(&mut self, coin_id: Bytes32, hint: Option) -> Result<()> { sync_coin(&mut *self.tx, coin_id, hint).await } @@ -56,10 +60,6 @@ impl<'a> DatabaseTx<'a> { coin_state(&mut *self.tx, coin_id).await } - pub async fn insert_unknown_coin(&mut self, coin_id: Bytes32) -> Result<()> { - insert_unknown_coin(&mut *self.tx, coin_id).await - } - pub async fn unspent_nft_coin_ids(&mut self) -> Result> { unspent_nft_coin_ids(&mut *self.tx).await } @@ -141,18 +141,17 @@ async fn update_coin_state( Ok(()) } -async fn insert_unknown_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { +async fn delete_coin_state(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { let coin_id = coin_id.as_ref(); - sqlx::query!( " - REPLACE INTO `unknown_coins` (`coin_id`) VALUES (?) + DELETE FROM `coin_states` + WHERE `coin_id` = ? ", coin_id ) .execute(conn) .await?; - Ok(()) } diff --git a/crates/sage-database/src/rows/nft_uri.rs b/crates/sage-database/src/rows/nft_uri.rs index e69de29b..8b137891 100644 --- a/crates/sage-database/src/rows/nft_uri.rs +++ b/crates/sage-database/src/rows/nft_uri.rs @@ -0,0 +1 @@ + diff --git a/crates/sage-wallet/src/child_kind.rs b/crates/sage-wallet/src/child_kind.rs index bfa4e4ef..40cf29f2 100644 --- a/crates/sage-wallet/src/child_kind.rs +++ b/crates/sage-wallet/src/child_kind.rs @@ -191,4 +191,17 @@ impl ChildKind { Ok(unknown) } + + pub fn p2_puzzle_hash(&self) -> Option { + match self { + Self::Launcher | Self::Unknown { .. } => None, + Self::Cat { p2_puzzle_hash, .. } => Some(*p2_puzzle_hash), + Self::Did { info, .. } => Some(info.p2_puzzle_hash), + Self::Nft { info, .. } => Some(info.p2_puzzle_hash), + } + } + + pub fn subscribe(&self) -> bool { + matches!(self, Self::Cat { .. } | Self::Did { .. } | Self::Nft { .. }) + } } diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index 135afaf0..f1246dcb 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -1,7 +1,7 @@ use chia::protocol::{Bytes32, CoinState}; -use sage_database::DatabaseTx; +use sage_database::{DatabaseTx, NftRow}; -use crate::WalletError; +use crate::{compute_nft_info, ChildKind, WalletError}; pub async fn upsert_coin( tx: &mut DatabaseTx<'_>, @@ -31,6 +31,7 @@ pub async fn upsert_coin( tx.insert_p2_coin(coin_id).await?; } + // If the coin has been spent, we need to handle the side effects. if coin_state.spent_height.is_some() { spend_coin(tx, coin_id).await?; } @@ -38,6 +39,125 @@ pub async fn upsert_coin( Ok(()) } +pub async fn insert_puzzle( + tx: &mut DatabaseTx<'_>, + coin_state: CoinState, + info: ChildKind, + minter_did: Option, +) -> Result<(), WalletError> { + let coin_id = coin_state.coin.coin_id(); + + match info { + ChildKind::Launcher | ChildKind::Unknown { .. } => {} + ChildKind::Cat { + asset_id, + lineage_proof, + p2_puzzle_hash, + } => { + tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; + tx.insert_cat_coin(coin_id, lineage_proof, p2_puzzle_hash, asset_id) + .await?; + } + ChildKind::Did { + lineage_proof, + info, + } => { + tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; + tx.insert_new_did(info.launcher_id, None, true).await?; + tx.insert_did_coin(coin_id, lineage_proof, info).await?; + } + ChildKind::Nft { + lineage_proof, + info, + metadata, + } => { + let data_hash = metadata.as_ref().and_then(|m| m.data_hash); + let metadata_hash = metadata.as_ref().and_then(|m| m.metadata_hash); + let license_hash = metadata.as_ref().and_then(|m| m.license_hash); + let launcher_id = info.launcher_id; + let owner_did = info.current_owner; + + tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; + + tx.insert_nft_coin( + coin_id, + lineage_proof, + info, + data_hash, + metadata_hash, + license_hash, + ) + .await?; + + if coin_state.spent_height.is_some() { + return Ok(()); + } + + let mut row = tx.nft_row(launcher_id).await?.unwrap_or(NftRow { + launcher_id, + coin_id, + collection_id: None, + minter_did, + owner_did, + visible: true, + sensitive_content: false, + name: None, + created_height: coin_state.created_height, + metadata_hash, + }); + + let metadata_blob = if let Some(metadata_hash) = metadata_hash { + tx.fetch_nft_data(metadata_hash) + .await? + .map(|data| data.blob) + } else { + None + }; + + let computed_info = compute_nft_info(minter_did, metadata_blob.as_deref()); + + row.coin_id = coin_id; + row.sensitive_content = computed_info.sensitive_content; + row.name = computed_info.name; + row.collection_id = computed_info + .collection + .as_ref() + .map(|col| col.collection_id); + + if let Some(collection) = computed_info.collection { + tx.insert_collection(collection).await?; + } + + row.owner_did = owner_did; + row.created_height = coin_state.created_height; + + tx.insert_nft(row).await?; + + if let Some(metadata) = metadata { + if let Some(hash) = data_hash { + for uri in metadata.data_uris { + tx.insert_nft_uri(uri, hash).await?; + } + } + + if let Some(hash) = metadata_hash { + for uri in metadata.metadata_uris { + tx.insert_nft_uri(uri, hash).await?; + } + } + + if let Some(hash) = license_hash { + for uri in metadata.license_uris { + tx.insert_nft_uri(uri, hash).await?; + } + } + } + } + } + + Ok(()) +} + pub async fn spend_coin(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { tx.remove_transaction(transaction_id).await?; diff --git a/crates/sage-wallet/src/queues/cat_queue.rs b/crates/sage-wallet/src/queues/cat_queue.rs index abf72df7..6f052760 100644 --- a/crates/sage-wallet/src/queues/cat_queue.rs +++ b/crates/sage-wallet/src/queues/cat_queue.rs @@ -95,7 +95,7 @@ impl CatQueue { name: asset.name, ticker: asset.code, description: asset.description, - icon_url: Some(format!("{dexie_image_base_url}/{asset_id}.webp")), + icon: Some(format!("{dexie_image_base_url}/{asset_id}.webp")), visible: true, }) .await?; diff --git a/crates/sage-wallet/src/queues/nft_uri_queue.rs b/crates/sage-wallet/src/queues/nft_uri_queue.rs index 59c87017..cee89d97 100644 --- a/crates/sage-wallet/src/queues/nft_uri_queue.rs +++ b/crates/sage-wallet/src/queues/nft_uri_queue.rs @@ -72,7 +72,7 @@ impl NftUriQueue { info.collection.as_ref().map(|col| col.collection_id); if let Some(collection) = info.collection { - tx.insert_nft_collection(collection).await?; + tx.insert_collection(collection).await?; } tx.insert_nft(nft).await?; diff --git a/crates/sage-wallet/src/queues/puzzle_queue.rs b/crates/sage-wallet/src/queues/puzzle_queue.rs index 253c0bf9..8708078d 100644 --- a/crates/sage-wallet/src/queues/puzzle_queue.rs +++ b/crates/sage-wallet/src/queues/puzzle_queue.rs @@ -3,7 +3,7 @@ use std::{sync::Arc, time::Duration}; use chia::protocol::{Bytes32, CoinState}; use chia_wallet_sdk::Peer; use futures_util::{stream::FuturesUnordered, StreamExt}; -use sage_database::{Database, NftRow}; +use sage_database::Database; use tokio::{ sync::{mpsc, Mutex}, task::spawn_blocking, @@ -12,8 +12,8 @@ use tokio::{ use tracing::{debug, instrument}; use crate::{ - compute_nft_info, fetch_nft_did, ChildKind, PeerState, SyncCommand, SyncError, SyncEvent, - WalletError, + database::insert_puzzle, fetch_nft_did, ChildKind, PeerState, SyncCommand, SyncError, + SyncEvent, WalletError, }; #[derive(Debug)] @@ -81,32 +81,46 @@ impl PuzzleQueue { let genesis_challenge = self.genesis_challenge; let addr = peer.socket_addr(); let coin_id = coin_state.coin.coin_id(); - let command_sender = self.command_sender.clone(); futures.push(tokio::spawn(async move { - let result = - fetch_puzzle(&peer, &db, genesis_challenge, coin_state, command_sender).await; + let result = fetch_puzzle(&peer, &db, genesis_challenge, coin_state).await; (addr, coin_id, result) })); } + let mut subscriptions = Vec::new(); + while let Some(result) = futures.next().await { let (addr, coin_id, result) = result?; - if let Err(error) = result { - // TODO: Not all errors should result in this exact behavior. - debug!( - "Failed to lookup puzzle of {} from peer {}: {}", - coin_id, addr, error - ); - - self.state - .lock() - .await - .ban(addr.ip(), Duration::from_secs(300)); + match result { + Ok(subscribe) => { + if subscribe { + subscriptions.push(coin_id); + } + } + Err(error) => { + // TODO: Not all errors should result in this exact behavior. + debug!( + "Failed to lookup puzzle of {} from peer {}: {}", + coin_id, addr, error + ); + + self.state + .lock() + .await + .ban(addr.ip(), Duration::from_secs(300)); + } } } + self.command_sender + .send(SyncCommand::SubscribeCoins { + coin_ids: subscriptions, + }) + .await + .ok(); + self.sync_sender .send(SyncEvent::PuzzleBatchSynced) .await @@ -117,14 +131,13 @@ impl PuzzleQueue { } /// Fetches info for a coin's puzzle and inserts it into the database. -#[instrument(skip(peer, db, command_sender))] +#[instrument(skip(peer, db))] async fn fetch_puzzle( peer: &Peer, db: &Database, genesis_challenge: Bytes32, coin_state: CoinState, - command_sender: mpsc::Sender, -) -> Result<(), WalletError> { +) -> Result { let parent_id = coin_state.coin.parent_coin_info; let Some(parent_coin_state) = timeout( @@ -170,125 +183,22 @@ async fn fetch_puzzle( None }; - let mut ids = Vec::new(); - let mut tx = db.tx().await?; + let subscribe = info.subscribe(); - match info { - ChildKind::Launcher => {} - ChildKind::Cat { - asset_id, - lineage_proof, - p2_puzzle_hash, - } => { - tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; - tx.insert_cat_coin(coin_id, lineage_proof, p2_puzzle_hash, asset_id) - .await?; - ids.push(coin_id); - } - ChildKind::Did { - lineage_proof, - info, - } => { - tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; - tx.insert_new_did(info.launcher_id, None, true).await?; - tx.insert_did_coin(coin_id, lineage_proof, info).await?; - ids.push(coin_id); - } - ChildKind::Nft { - lineage_proof, - info, - metadata, - } => { - let data_hash = metadata.as_ref().and_then(|m| m.data_hash); - let metadata_hash = metadata.as_ref().and_then(|m| m.metadata_hash); - let license_hash = metadata.as_ref().and_then(|m| m.license_hash); - - tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; - - let mut row = tx.nft_row(info.launcher_id).await?.unwrap_or(NftRow { - launcher_id: info.launcher_id, - coin_id, - collection_id: None, - minter_did, - owner_did: info.current_owner, - visible: true, - sensitive_content: false, - name: None, - created_height: coin_state.created_height, - metadata_hash, - }); - - let metadata_blob = if let Some(metadata_hash) = metadata_hash { - tx.fetch_nft_data(metadata_hash) - .await? - .map(|data| data.blob) - } else { - None - }; - - let computed_info = compute_nft_info(minter_did, metadata_blob.as_deref()); - - row.coin_id = coin_id; - row.sensitive_content = computed_info.sensitive_content; - row.name = computed_info.name; - row.collection_id = computed_info - .collection - .as_ref() - .map(|col| col.collection_id); - - if let Some(collection) = computed_info.collection { - tx.insert_nft_collection(collection).await?; - } - - row.owner_did = info.current_owner; - row.created_height = coin_state.created_height; - - tx.insert_nft_coin( - coin_id, - lineage_proof, - info, - data_hash, - metadata_hash, - license_hash, - ) - .await?; - - tx.insert_nft(row).await?; - - if let Some(metadata) = metadata { - if let Some(hash) = data_hash { - for uri in metadata.data_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } - - if let Some(hash) = metadata_hash { - for uri in metadata.metadata_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } + let mut tx = db.tx().await?; - if let Some(hash) = license_hash { - for uri in metadata.license_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } - } + let remove = match info.p2_puzzle_hash() { + Some(p2_puzzle_hash) => !tx.is_p2_puzzle_hash(p2_puzzle_hash).await?, + None => true, + }; - ids.push(coin_id); - } - ChildKind::Unknown { hint } => { - tx.sync_coin(coin_id, hint).await?; - tx.insert_unknown_coin(coin_id).await?; - } + if remove { + tx.delete_coin_state(coin_id).await?; + } else { + insert_puzzle(&mut tx, coin_state, info, minter_did).await?; } tx.commit().await?; - command_sender - .send(SyncCommand::SubscribeCoins { coin_ids: ids }) - .await - .ok(); - - Ok(()) + Ok(subscribe) } diff --git a/crates/sage-wallet/src/sync_manager/wallet_sync.rs b/crates/sage-wallet/src/sync_manager/wallet_sync.rs index e4360866..beb822c9 100644 --- a/crates/sage-wallet/src/sync_manager/wallet_sync.rs +++ b/crates/sage-wallet/src/sync_manager/wallet_sync.rs @@ -267,15 +267,20 @@ pub async fn incremental_sync( tx.insert_coin_state(coin_state, is_p2, None).await?; - tx.set_coin_height(coin_id, coin_state.created_height, coin_state.spent_height) - .await?; + tx.update_coin_state( + coin_id, + coin_state.created_height, + coin_state.spent_height, + None, + ) + .await?; if is_p2 { tx.insert_p2_coin(coin_id).await?; } if coin_state.spent_height.is_some() { - for transaction_id in tx.transaction_for_spent_coin(coin_id).await? { + if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { tx.remove_transaction(transaction_id).await?; } diff --git a/crates/sage-wallet/src/utils/insert_transaction.rs b/crates/sage-wallet/src/utils/insert_transaction.rs index f0d86e7b..6d234760 100644 --- a/crates/sage-wallet/src/utils/insert_transaction.rs +++ b/crates/sage-wallet/src/utils/insert_transaction.rs @@ -2,18 +2,18 @@ use chia::{ bls::Signature, protocol::{Bytes32, CoinState}, }; -use sage_database::{DatabaseTx, NftRow}; +use sage_database::DatabaseTx; -use crate::{ChildKind, Transaction, WalletError}; - -use super::compute_nft_info; +use crate::{database::insert_puzzle, Transaction, WalletError}; pub async fn insert_transaction( tx: &mut DatabaseTx<'_>, transaction_id: Bytes32, transaction: Transaction, aggregated_signature: Signature, -) -> Result<(), WalletError> { +) -> Result, WalletError> { + let mut subscriptions = Vec::new(); + tx.insert_pending_transaction(transaction_id, aggregated_signature, transaction.fee) .await?; @@ -32,126 +32,25 @@ pub async fn insert_transaction( continue; } - match output.kind { - ChildKind::Launcher => {} - ChildKind::Cat { - asset_id, - lineage_proof, - p2_puzzle_hash, - } => { - if tx.is_p2_puzzle_hash(p2_puzzle_hash).await? { - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; - tx.insert_cat_coin(coin_id, lineage_proof, p2_puzzle_hash, asset_id) - .await?; - } - } - ChildKind::Did { - lineage_proof, - info, - } => { - if tx.is_p2_puzzle_hash(info.p2_puzzle_hash).await? { - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; - tx.insert_new_did(info.launcher_id, None, true).await?; - tx.insert_did_coin(coin_id, lineage_proof, info).await?; - } - } - ChildKind::Nft { - lineage_proof, - info, - metadata, - } => { - let data_hash = metadata.as_ref().and_then(|m| m.data_hash); - let metadata_hash = metadata.as_ref().and_then(|m| m.metadata_hash); - let license_hash = metadata.as_ref().and_then(|m| m.license_hash); - - if tx.is_p2_puzzle_hash(info.p2_puzzle_hash).await? { - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - - tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; - - let mut row = tx.nft_row(info.launcher_id).await?.unwrap_or(NftRow { - launcher_id: info.launcher_id, - coin_id, - collection_id: None, - minter_did: None, - owner_did: info.current_owner, - visible: true, - sensitive_content: false, - name: None, - created_height: None, - metadata_hash, - }); - - if let Some(metadata_hash) = metadata_hash { - let blob = tx - .fetch_nft_data(metadata_hash) - .await? - .map(|data| data.blob); - - // TODO: Handle Minter DID for pending transactions. - let info = compute_nft_info(None, blob.as_deref()); - - row.sensitive_content = info.sensitive_content; - row.name = info.name; - } - - row.coin_id = coin_id; - row.owner_did = info.current_owner; - row.created_height = None; - - tx.insert_nft_coin( - coin_id, - lineage_proof, - info, - data_hash, - metadata_hash, - license_hash, - ) - .await?; - - tx.insert_nft(row).await?; - - if let Some(metadata) = metadata { - if let Some(hash) = data_hash { - for uri in metadata.data_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } + let Some(p2_puzzle_hash) = output.kind.p2_puzzle_hash() else { + continue; + }; - if let Some(hash) = metadata_hash { - for uri in metadata.metadata_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } + if !tx.is_p2_puzzle_hash(p2_puzzle_hash).await? { + continue; + } - if let Some(hash) = license_hash { - for uri in metadata.license_uris { - tx.insert_nft_uri(uri, hash).await?; - } - } - } - } - } - ChildKind::Unknown { hint } => { - let Some(p2_puzzle_hash) = hint else { - continue; - }; + tx.insert_coin_state(coin_state, true, Some(transaction_id)) + .await?; + tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; - if tx.is_p2_puzzle_hash(p2_puzzle_hash).await? { - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - tx.sync_coin(coin_id, hint).await?; - tx.insert_unknown_coin(coin_id).await?; - } - } + if output.kind.subscribe() { + subscriptions.push(coin_id); } + + insert_puzzle(tx, coin_state, output.kind, None).await?; } } - Ok(()) + Ok(subscriptions) } diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index 423811d1..0e336f66 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -55,11 +55,6 @@ CREATE TABLE `transaction_spends` ( CREATE INDEX `indexed_spend` ON `transaction_spends` (`transaction_id`, `index` ASC); -CREATE TABLE `unknown_coins` ( - `coin_id` BLOB NOT NULL PRIMARY KEY, - FOREIGN KEY (`coin_id`) REFERENCES `coin_states` (`coin_id`) ON DELETE CASCADE -); - CREATE TABLE `p2_coins` ( `coin_id` BLOB NOT NULL PRIMARY KEY, FOREIGN KEY (`coin_id`) REFERENCES `coin_states` (`coin_id`) ON DELETE CASCADE diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index fcb3a1bb..7fdd9a55 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -41,7 +41,7 @@ pub async fn update_cat_info(state: State<'_, AppState>, record: CatRecord) -> R name: record.name, description: record.description, ticker: record.ticker, - icon_url: record.icon_url, + icon: record.icon_url, visible: record.visible, }) .await?; diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index 46ee6f03..998af9e3 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -178,7 +178,7 @@ pub async fn get_cats(state: State<'_, AppState>) -> Result> { name: cat.name, ticker: cat.ticker, description: cat.description, - icon_url: cat.icon_url, + icon_url: cat.icon, visible: cat.visible, balance: Amount::from_mojos(balance, 3), }); @@ -206,7 +206,7 @@ pub async fn get_cat(state: State<'_, AppState>, asset_id: String) -> Result) -> Result { let mut tx = wallet.db.tx().await?; let nfts = tx.nft_count().await?; - let collections = tx.nft_collection_count().await?; + let collections = tx.collection_count().await?; let visible_nfts = tx.visible_nft_count().await?; - let visible_collections = tx.visible_nft_collection_count().await?; + let visible_collections = tx.visible_collection_count().await?; tx.commit().await?; @@ -312,10 +312,9 @@ pub async fn get_nft_collections( let mut tx = wallet.db.tx().await?; let collections = if request.include_hidden { - tx.nft_collections_named(request.limit, request.offset) - .await? + tx.collections_named(request.limit, request.offset).await? } else { - tx.nft_collections_visible_named(request.limit, request.offset) + tx.collections_visible_named(request.limit, request.offset) .await? }; @@ -362,7 +361,7 @@ pub async fn get_nft_collection( }; let collection = if let Some(collection_id) = collection_id { - Some(wallet.db.nft_collection(collection_id).await?) + Some(wallet.db.collection(collection_id).await?) } else { None }; @@ -436,7 +435,7 @@ pub async fn get_nfts(state: State<'_, AppState>, request: GetNfts) -> Result, launcher_id: String) -> Result< }; let collection_name = if let Some(collection_id) = nft_row.collection_id { - tx.nft_collection_name(collection_id).await? + tx.collection_name(collection_id).await? } else { None }; diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 693bdaed..4a3f0f54 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -16,8 +16,8 @@ use sage_api::{ }; use sage_database::{CatRow, Database}; use sage_wallet::{ - compute_nft_info, fetch_uris, insert_transaction, ChildKind, CoinKind, Data, Transaction, - Wallet, WalletError, WalletNftMint, + compute_nft_info, fetch_uris, insert_transaction, ChildKind, CoinKind, Data, SyncCommand, + Transaction, Wallet, WalletError, WalletNftMint, }; use specta::specta; use tauri::{command, State}; @@ -280,7 +280,7 @@ pub async fn issue_cat( name: Some(name), ticker: Some(ticker), description: None, - icon_url: None, + icon: None, visible: true, }) .await?; @@ -594,7 +594,7 @@ pub async fn submit_transaction( let mut tx = wallet.db.tx().await?; - insert_transaction( + let subscriptions = insert_transaction( &mut tx, spend_bundle.name(), Transaction::from_coin_spends(spend_bundle.coin_spends)?, @@ -604,6 +604,13 @@ pub async fn submit_transaction( tx.commit().await?; + state + .command_sender + .send(SyncCommand::SubscribeCoins { + coin_ids: subscriptions, + }) + .await?; + Ok(()) } @@ -647,7 +654,7 @@ async fn summarize( asset_id: hex::encode(asset_id), name: cat.as_ref().and_then(|cat| cat.name.clone()), ticker: cat.as_ref().and_then(|cat| cat.ticker.clone()), - icon_url: cat.as_ref().and_then(|cat| cat.icon_url.clone()), + icon_url: cat.as_ref().and_then(|cat| cat.icon.clone()), }; amount = Amount::from_mojos(coin.amount as u128, 3); (kind, p2_puzzle_hash) From 9ff4ea05979e359dc6b408dacbe67a1e86656721 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 22:27:47 -0500 Subject: [PATCH 09/21] Temp --- crates/sage-database/src/coin_states.rs | 4 ++ crates/sage-database/src/primitives/dids.rs | 44 +++++++++++++-- crates/sage-database/src/rows/did_coin.rs | 33 ++++++++++- crates/sage-wallet/src/database.rs | 56 ++++++++++++++++++- crates/sage-wallet/src/lib.rs | 1 + crates/sage-wallet/src/utils.rs | 2 - .../src/utils/insert_transaction.rs | 56 ------------------- crates/sage-wallet/src/wallet.rs | 4 +- src-tauri/src/commands/data.rs | 54 ++++++++---------- 9 files changed, 157 insertions(+), 97 deletions(-) delete mode 100644 crates/sage-wallet/src/utils/insert_transaction.rs diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index 8dcb328c..88063a18 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -7,6 +7,10 @@ impl Database { pub async fn unsynced_coin_states(&self, limit: usize) -> Result> { unsynced_coin_states(&self.pool, limit).await } + + pub async fn coin_state(&self, coin_id: Bytes32) -> Result> { + coin_state(&self.pool, coin_id).await + } } impl<'a> DatabaseTx<'a> { diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index d341a50f..1d0f3e93 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -5,7 +5,10 @@ use chia::{ use chia_wallet_sdk::{Did, DidInfo}; use sqlx::SqliteExecutor; -use crate::{into_row, Database, DatabaseTx, DidRow, DidSql, FullDidCoinSql, IntoRow, Result}; +use crate::{ + into_row, Database, DatabaseTx, DidCoinInfo, DidCoinInfoSql, DidRow, DidSql, FullDidCoinSql, + IntoRow, Result, +}; impl Database { pub async fn insert_new_did( @@ -30,8 +33,12 @@ impl Database { dids_by_name(&self.pool).await } - pub async fn did(&self, did_id: Bytes32) -> Result>> { - did(&self.pool, did_id).await + pub async fn did_coin_info(&self, did_id: Bytes32) -> Result> { + did_coin_info(&self.pool, did_id).await + } + + pub async fn spendable_did(&self, did_id: Bytes32) -> Result>> { + spendable_did(&self.pool, did_id).await } pub async fn did_name(&self, launcher_id: Bytes32) -> Result> { @@ -178,7 +185,36 @@ async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { .collect() } -async fn did(conn: impl SqliteExecutor<'_>, did_id: Bytes32) -> Result>> { +async fn did_coin_info( + conn: impl SqliteExecutor<'_>, + did_id: Bytes32, +) -> Result> { + let did_id = did_id.as_ref(); + + let Some(sql) = sqlx::query_as!( + DidCoinInfoSql, + " + SELECT + `did_coins`.`coin_id`, `amount`, `p2_puzzle_hash`, `created_height`, `transaction_id` + FROM `did_coins` + INNER JOIN `coin_states` ON `coin_states`.coin_id = `did_coins`.coin_id + WHERE `launcher_id` = ? + ", + did_id + ) + .fetch_optional(conn) + .await? + else { + return Ok(None); + }; + + Ok(Some(sql.into_row()?)) +} + +async fn spendable_did( + conn: impl SqliteExecutor<'_>, + did_id: Bytes32, +) -> Result>> { let did_id = did_id.as_ref(); let Some(sql) = sqlx::query_as!( diff --git a/crates/sage-database/src/rows/did_coin.rs b/crates/sage-database/src/rows/did_coin.rs index 422577b2..d66d1bf8 100644 --- a/crates/sage-database/src/rows/did_coin.rs +++ b/crates/sage-database/src/rows/did_coin.rs @@ -1,5 +1,5 @@ use chia::{ - protocol::{Coin, Program}, + protocol::{Bytes32, Coin, Program}, puzzles::{LineageProof, Proof}, }; use chia_wallet_sdk::{Did, DidInfo}; @@ -22,6 +22,23 @@ pub(crate) struct FullDidCoinSql { pub p2_puzzle_hash: Vec, } +pub(crate) struct DidCoinInfoSql { + pub coin_id: Vec, + pub amount: Vec, + pub p2_puzzle_hash: Vec, + pub created_height: Option, + pub transaction_id: Option>, +} + +#[derive(Debug, Clone, Copy)] +pub struct DidCoinInfo { + pub coin_id: Bytes32, + pub amount: u64, + pub p2_puzzle_hash: Bytes32, + pub created_height: Option, + pub transaction_id: Option, +} + impl IntoRow for FullDidCoinSql { type Row = Did; @@ -51,3 +68,17 @@ impl IntoRow for FullDidCoinSql { }) } } + +impl IntoRow for DidCoinInfoSql { + type Row = DidCoinInfo; + + fn into_row(self) -> Result { + Ok(DidCoinInfo { + coin_id: to_bytes32(&self.coin_id)?, + amount: to_u64(&self.amount)?, + p2_puzzle_hash: to_bytes32(&self.p2_puzzle_hash)?, + created_height: self.created_height.map(TryInto::try_into).transpose()?, + transaction_id: self.transaction_id.as_deref().map(to_bytes32).transpose()?, + }) + } +} diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index f1246dcb..a8ef9aae 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -1,7 +1,10 @@ -use chia::protocol::{Bytes32, CoinState}; +use chia::{ + bls::Signature, + protocol::{Bytes32, CoinState}, +}; use sage_database::{DatabaseTx, NftRow}; -use crate::{compute_nft_info, ChildKind, WalletError}; +use crate::{compute_nft_info, ChildKind, Transaction, WalletError}; pub async fn upsert_coin( tx: &mut DatabaseTx<'_>, @@ -169,3 +172,52 @@ pub async fn spend_coin(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), Ok(()) } + +pub async fn insert_transaction( + tx: &mut DatabaseTx<'_>, + transaction_id: Bytes32, + transaction: Transaction, + aggregated_signature: Signature, +) -> Result, WalletError> { + let mut subscriptions = Vec::new(); + + tx.insert_pending_transaction(transaction_id, aggregated_signature, transaction.fee) + .await?; + + for (index, input) in transaction.inputs.into_iter().enumerate() { + tx.insert_transaction_spend(transaction_id, input.coin_spend, index) + .await?; + + for output in input.outputs { + let coin_state = CoinState::new(output.coin, None, None); + let coin_id = output.coin.coin_id(); + + if tx.is_p2_puzzle_hash(output.coin.puzzle_hash).await? { + tx.insert_coin_state(coin_state, true, Some(transaction_id)) + .await?; + tx.insert_p2_coin(coin_id).await?; + continue; + } + + let Some(p2_puzzle_hash) = output.kind.p2_puzzle_hash() else { + continue; + }; + + if !tx.is_p2_puzzle_hash(p2_puzzle_hash).await? { + continue; + } + + tx.insert_coin_state(coin_state, true, Some(transaction_id)) + .await?; + tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; + + if output.kind.subscribe() { + subscriptions.push(coin_id); + } + + insert_puzzle(tx, coin_state, output.kind, None).await?; + } + } + + Ok(subscriptions) +} diff --git a/crates/sage-wallet/src/lib.rs b/crates/sage-wallet/src/lib.rs index 26236518..aa88118a 100644 --- a/crates/sage-wallet/src/lib.rs +++ b/crates/sage-wallet/src/lib.rs @@ -10,6 +10,7 @@ mod wallet; pub use child_kind::*; pub use coin_kind::*; +pub use database::*; pub use error::*; pub use queues::*; pub use sync_manager::*; diff --git a/crates/sage-wallet/src/utils.rs b/crates/sage-wallet/src/utils.rs index 4f157e6c..4650ade8 100644 --- a/crates/sage-wallet/src/utils.rs +++ b/crates/sage-wallet/src/utils.rs @@ -1,9 +1,7 @@ mod fetch_nft_did; mod fetch_uri; -mod insert_transaction; mod offchain_metadata; pub use fetch_nft_did::*; pub use fetch_uri::*; -pub use insert_transaction::*; pub use offchain_metadata::*; diff --git a/crates/sage-wallet/src/utils/insert_transaction.rs b/crates/sage-wallet/src/utils/insert_transaction.rs deleted file mode 100644 index 6d234760..00000000 --- a/crates/sage-wallet/src/utils/insert_transaction.rs +++ /dev/null @@ -1,56 +0,0 @@ -use chia::{ - bls::Signature, - protocol::{Bytes32, CoinState}, -}; -use sage_database::DatabaseTx; - -use crate::{database::insert_puzzle, Transaction, WalletError}; - -pub async fn insert_transaction( - tx: &mut DatabaseTx<'_>, - transaction_id: Bytes32, - transaction: Transaction, - aggregated_signature: Signature, -) -> Result, WalletError> { - let mut subscriptions = Vec::new(); - - tx.insert_pending_transaction(transaction_id, aggregated_signature, transaction.fee) - .await?; - - for (index, input) in transaction.inputs.into_iter().enumerate() { - tx.insert_transaction_spend(transaction_id, input.coin_spend, index) - .await?; - - for output in input.outputs { - let coin_state = CoinState::new(output.coin, None, None); - let coin_id = output.coin.coin_id(); - - if tx.is_p2_puzzle_hash(output.coin.puzzle_hash).await? { - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - tx.insert_p2_coin(coin_id).await?; - continue; - } - - let Some(p2_puzzle_hash) = output.kind.p2_puzzle_hash() else { - continue; - }; - - if !tx.is_p2_puzzle_hash(p2_puzzle_hash).await? { - continue; - } - - tx.insert_coin_state(coin_state, true, Some(transaction_id)) - .await?; - tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; - - if output.kind.subscribe() { - subscriptions.push(coin_id); - } - - insert_puzzle(tx, coin_state, output.kind, None).await?; - } - } - - Ok(subscriptions) -} diff --git a/crates/sage-wallet/src/wallet.rs b/crates/sage-wallet/src/wallet.rs index 5aea325a..8898ed5d 100644 --- a/crates/sage-wallet/src/wallet.rs +++ b/crates/sage-wallet/src/wallet.rs @@ -744,7 +744,7 @@ impl Wallet { hardened: bool, reuse: bool, ) -> Result<(Vec, Vec>, Did), WalletError> { - let Some(did) = self.db.did(did_id).await? else { + let Some(did) = self.db.spendable_did(did_id).await? else { return Err(WalletError::MissingDid(did_id)); }; @@ -863,7 +863,7 @@ impl Wallet { hardened: bool, reuse: bool, ) -> Result<(Vec, Did), WalletError> { - let Some(did) = self.db.did(did_id).await? else { + let Some(did) = self.db.spendable_did(did_id).await? else { return Err(WalletError::MissingDid(did_id)); }; diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index 998af9e3..fb96fd7a 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -13,7 +13,7 @@ use sage_api::{ NftCollectionRecord, NftInfo, NftRecord, NftSortMode, NftStatus, PendingTransactionRecord, SyncStatus, }; -use sage_database::{DidRow, NftData, NftRow}; +use sage_database::{NftData, NftRow}; use sage_wallet::WalletError; use specta::specta; use tauri::{command, State}; @@ -220,35 +220,29 @@ pub async fn get_dids(state: State<'_, AppState>) -> Result> { let state = state.lock().await; let wallet = state.wallet()?; - wallet - .db - .did_coins() - .await? - .into_iter() - .map( - |DidRow { - did, - name, - visible, - created_height, - create_transaction_id, - }| { - Ok(DidRecord { - launcher_id: encode_address(did.info.launcher_id.to_bytes(), "did:chia:")?, - name, - visible, - coin_id: hex::encode(did.coin.coin_id()), - address: encode_address( - did.info.p2_puzzle_hash.to_bytes(), - &state.network().address_prefix, - )?, - amount: Amount::from_mojos(did.coin.amount as u128, state.unit.decimals), - created_height, - create_transaction_id: create_transaction_id.map(hex::encode), - }) - }, - ) - .collect() + let mut records = Vec::new(); + + for row in wallet.db.dids_by_name().await? { + let Some(did) = wallet.db.did_coin_info(row.launcher_id).await? else { + continue; + }; + + records.push(DidRecord { + launcher_id: encode_address(row.launcher_id.to_bytes(), "did:chia:")?, + name: row.name, + visible: row.visible, + coin_id: hex::encode(did.coin_id), + address: encode_address( + did.p2_puzzle_hash.to_bytes(), + &state.network().address_prefix, + )?, + amount: Amount::from_mojos(did.amount as u128, state.unit.decimals), + created_height: did.created_height, + create_transaction_id: did.transaction_id.map(hex::encode), + }); + } + + Ok(records) } #[command] From b5f417b9556777428a0d18c402179fca5f0cb46a Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 22:32:28 -0500 Subject: [PATCH 10/21] Cleanup --- crates/sage-database/src/primitives/nfts.rs | 73 ++++----------------- 1 file changed, 14 insertions(+), 59 deletions(-) diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index c4e5e43c..084eb81b 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -345,15 +345,8 @@ async fn collection( sqlx::query_as!( CollectionSql, " - SELECT - `collection_id`, - `did_id`, - `metadata_collection_id`, - `visible`, - `name`, - `icon` - FROM `collections` - WHERE `collection_id` = ? + SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon` + FROM `collections` WHERE `collection_id` = ? ", collection_id ) @@ -370,13 +363,7 @@ async fn collections_visible_named( sqlx::query_as!( CollectionSql, " - SELECT - `collection_id`, - `did_id`, - `metadata_collection_id`, - `visible`, - `name`, - `icon` + SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon` FROM `collections` INDEXED BY `col_name` WHERE `visible` = 1 ORDER BY `is_named` DESC, `name` ASC, `collection_id` ASC @@ -400,13 +387,7 @@ async fn collections_named( sqlx::query_as!( CollectionSql, " - SELECT - `collection_id`, - `did_id`, - `metadata_collection_id`, - `visible`, - `name`, - `icon` + SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon` FROM `collections` INDEXED BY `col_name` ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC LIMIT ? OFFSET ? @@ -672,16 +653,8 @@ async fn nft_row(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result< let Some(row) = sqlx::query!( " SELECT - `launcher_id`, - `coin_id`, - `collection_id`, - `minter_did`, - `owner_did`, - `visible`, - `sensitive_content`, - `name`, - `created_height`, - `metadata_hash` + `launcher_id`, `coin_id`, `collection_id`, `minter_did`, `owner_did`, + `visible`, `sensitive_content`, `name`, `created_height`, `metadata_hash` FROM `nfts` WHERE `launcher_id` = ? ", @@ -745,19 +718,10 @@ async fn spendable_nft( FullNftCoinSql, " SELECT - `coin_states`.`parent_coin_id`, - `coin_states`.`puzzle_hash`, - `coin_states`.`amount`, - `parent_parent_coin_id`, - `parent_inner_puzzle_hash`, - `parent_amount`, - `launcher_id`, - `metadata`, - `metadata_updater_puzzle_hash`, - `current_owner`, - `royalty_puzzle_hash`, - `royalty_ten_thousandths`, - `p2_puzzle_hash` + `coin_states`.`parent_coin_id`, `coin_states`.`puzzle_hash`, `coin_states`.`amount`, + `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount`, + `launcher_id`, `metadata`, `metadata_updater_puzzle_hash`, `current_owner`, + `royalty_puzzle_hash`, `royalty_ten_thousandths`, `p2_puzzle_hash` FROM `nft_coins` INNER JOIN `coin_states` INDEXED BY `coin_height` ON `nft_coins`.`coin_id` = `coin_states`.`coin_id` LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id` @@ -785,19 +749,10 @@ async fn nft(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result Date: Sun, 3 Nov 2024 22:45:16 -0500 Subject: [PATCH 11/21] More cleanup --- crates/sage-database/src/coin_states.rs | 4 - crates/sage-database/src/primitives/nfts.rs | 99 +++++-------------- crates/sage-database/src/rows/nft.rs | 52 ++++++++++ crates/sage-wallet/src/queues/puzzle_queue.rs | 1 + src-tauri/src/commands/transactions.rs | 12 +-- 5 files changed, 82 insertions(+), 86 deletions(-) diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index 88063a18..bc6f3124 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -60,10 +60,6 @@ impl<'a> DatabaseTx<'a> { synced_coin_count(&mut *self.tx).await } - pub async fn coin_state(&mut self, coin_id: Bytes32) -> Result> { - coin_state(&mut *self.tx, coin_id).await - } - pub async fn unspent_nft_coin_ids(&mut self) -> Result> { unspent_nft_coin_ids(&mut *self.tx).await } diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index 084eb81b..dd1bdd35 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -7,23 +7,9 @@ use sqlx::SqliteExecutor; use crate::{ into_row, to_bytes32, CollectionRow, CollectionSql, Database, DatabaseTx, FullNftCoinSql, - IntoRow, Result, + IntoRow, NftRow, NftSql, Result, }; -#[derive(Debug, Clone)] -pub struct NftRow { - pub launcher_id: Bytes32, - pub coin_id: Bytes32, - pub collection_id: Option, - pub minter_did: Option, - pub owner_did: Option, - pub visible: bool, - pub sensitive_content: bool, - pub name: Option, - pub created_height: Option, - pub metadata_hash: Option, -} - #[derive(Debug, Clone)] pub struct NftData { pub blob: Vec, @@ -36,22 +22,6 @@ pub struct NftUri { pub uri: String, } -#[allow(unused)] -struct SqlNftRow { - pub launcher_id: Vec, - pub coin_id: Vec, - pub collection_id: Option>, - pub minter_did: Option>, - pub owner_did: Option>, - pub visible: bool, - pub sensitive_content: bool, - pub name: Option, - pub created_height: Option, - pub metadata_hash: Option>, - pub is_named: Option, - pub is_pending: Option, -} - impl Database { pub async fn unchecked_nft_uris(&self, limit: u32) -> Result> { unchecked_nft_uris(&self.pool, limit).await @@ -778,7 +748,7 @@ async fn nfts_by_metadata_hash( let metadata_hash = metadata_hash.as_ref(); sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_metadata` WHERE `metadata_hash` = ? @@ -788,7 +758,7 @@ async fn nfts_by_metadata_hash( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -798,7 +768,7 @@ async fn nfts_visible_named( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_name` WHERE `visible` = 1 @@ -811,7 +781,7 @@ async fn nfts_visible_named( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -821,7 +791,7 @@ async fn nfts_visible_recent( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_recent` WHERE `visible` = 1 @@ -834,13 +804,13 @@ async fn nfts_visible_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } async fn nfts_named(conn: impl SqliteExecutor<'_>, limit: u32, offset: u32) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_name` ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC @@ -852,7 +822,7 @@ async fn nfts_named(conn: impl SqliteExecutor<'_>, limit: u32, offset: u32) -> R .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -862,7 +832,7 @@ async fn nfts_recent( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_recent` ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC @@ -874,7 +844,7 @@ async fn nfts_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -887,7 +857,7 @@ async fn collection_nfts_visible_named( let collection_id = collection_id.as_ref(); sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? AND `visible` = 1 @@ -901,7 +871,7 @@ async fn collection_nfts_visible_named( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -914,7 +884,7 @@ async fn collection_nfts_visible_recent( let collection_id = collection_id.as_ref(); sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` WHERE `collection_id` = ? AND `visible` = 1 @@ -928,7 +898,7 @@ async fn collection_nfts_visible_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -941,7 +911,7 @@ async fn collection_nfts_named( let collection_id = collection_id.as_ref(); sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? @@ -955,7 +925,7 @@ async fn collection_nfts_named( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -968,7 +938,7 @@ async fn collection_nfts_recent( let collection_id = collection_id.as_ref(); sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` WHERE `collection_id` = ? @@ -982,7 +952,7 @@ async fn collection_nfts_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -992,7 +962,7 @@ async fn no_collection_nfts_visible_named( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL AND `visible` = 1 @@ -1005,7 +975,7 @@ async fn no_collection_nfts_visible_named( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -1015,7 +985,7 @@ async fn no_collection_nfts_visible_recent( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` WHERE `collection_id` IS NULL AND `visible` = 1 @@ -1028,7 +998,7 @@ async fn no_collection_nfts_visible_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -1038,7 +1008,7 @@ async fn no_collection_nfts_named( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL @@ -1051,7 +1021,7 @@ async fn no_collection_nfts_named( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -1061,7 +1031,7 @@ async fn no_collection_nfts_recent( offset: u32, ) -> Result> { sqlx::query_as!( - SqlNftRow, + NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` WHERE `collection_id` IS NULL @@ -1074,7 +1044,7 @@ async fn no_collection_nfts_recent( .fetch_all(conn) .await? .into_iter() - .map(to_nft_row) + .map(into_row) .collect() } @@ -1227,18 +1197,3 @@ async fn nft_launcher_id( Ok(Some(to_bytes32(&row.launcher_id)?)) } - -fn to_nft_row(row: SqlNftRow) -> Result { - Ok(NftRow { - launcher_id: to_bytes32(&row.launcher_id)?, - coin_id: to_bytes32(&row.coin_id)?, - collection_id: row.collection_id.as_deref().map(to_bytes32).transpose()?, - minter_did: row.minter_did.as_deref().map(to_bytes32).transpose()?, - owner_did: row.owner_did.as_deref().map(to_bytes32).transpose()?, - visible: row.visible, - sensitive_content: row.sensitive_content, - name: row.name, - created_height: row.created_height.map(TryInto::try_into).transpose()?, - metadata_hash: row.metadata_hash.as_deref().map(to_bytes32).transpose()?, - }) -} diff --git a/crates/sage-database/src/rows/nft.rs b/crates/sage-database/src/rows/nft.rs index 8b137891..676fbb3a 100644 --- a/crates/sage-database/src/rows/nft.rs +++ b/crates/sage-database/src/rows/nft.rs @@ -1 +1,53 @@ +use chia::protocol::Bytes32; +use crate::{to_bytes32, DatabaseError}; + +use super::IntoRow; + +pub(crate) struct NftSql { + pub launcher_id: Vec, + pub coin_id: Vec, + pub collection_id: Option>, + pub minter_did: Option>, + pub owner_did: Option>, + pub visible: bool, + pub sensitive_content: bool, + pub name: Option, + pub created_height: Option, + pub metadata_hash: Option>, + pub is_named: Option, + pub is_pending: Option, +} + +#[derive(Debug, Clone)] +pub struct NftRow { + pub launcher_id: Bytes32, + pub coin_id: Bytes32, + pub collection_id: Option, + pub minter_did: Option, + pub owner_did: Option, + pub visible: bool, + pub sensitive_content: bool, + pub name: Option, + pub created_height: Option, + pub metadata_hash: Option, +} + +impl IntoRow for NftSql { + type Row = NftRow; + + fn into_row(self) -> Result { + Ok(NftRow { + launcher_id: to_bytes32(&self.launcher_id)?, + coin_id: to_bytes32(&self.coin_id)?, + collection_id: self.collection_id.as_deref().map(to_bytes32).transpose()?, + minter_did: self.minter_did.as_deref().map(to_bytes32).transpose()?, + owner_did: self.owner_did.as_deref().map(to_bytes32).transpose()?, + visible: self.visible, + sensitive_content: self.sensitive_content, + name: self.name, + created_height: self.created_height.map(TryInto::try_into).transpose()?, + metadata_hash: self.metadata_hash.as_deref().map(to_bytes32).transpose()?, + }) + } +} diff --git a/crates/sage-wallet/src/queues/puzzle_queue.rs b/crates/sage-wallet/src/queues/puzzle_queue.rs index 8708078d..faec518e 100644 --- a/crates/sage-wallet/src/queues/puzzle_queue.rs +++ b/crates/sage-wallet/src/queues/puzzle_queue.rs @@ -64,6 +64,7 @@ impl PuzzleQueue { } let coin_states = self.db.unsynced_coin_states(peers.len()).await?; + if coin_states.is_empty() { sleep(Duration::from_secs(3)).await; return Ok(()); diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 4a3f0f54..0d08f785 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -96,12 +96,10 @@ pub async fn combine( .map(|coin_id| Ok(hex::decode(coin_id)?.try_into()?)) .collect::>>()?; - let mut tx = wallet.db.tx().await?; - let mut coins = Vec::new(); for coin_id in coin_ids { - let Some(coin_state) = tx.coin_state(coin_id).await? else { + let Some(coin_state) = wallet.db.coin_state(coin_id).await? else { return Err(Error::unknown_coin_id()); }; @@ -112,8 +110,6 @@ pub async fn combine( coins.push(coin_state.coin); } - tx.commit().await?; - let coin_spends = wallet.combine_xch(coins, fee, false, true).await?; summarize(&state, &wallet, coin_spends, ConfirmationInfo::default()).await @@ -143,12 +139,10 @@ pub async fn split( .map(|coin_id| Ok(hex::decode(coin_id)?.try_into()?)) .collect::>>()?; - let mut tx = wallet.db.tx().await?; - let mut coins = Vec::new(); for coin_id in coin_ids { - let Some(coin_state) = tx.coin_state(coin_id).await? else { + let Some(coin_state) = wallet.db.coin_state(coin_id).await? else { return Err(Error::unknown_coin_id()); }; @@ -159,8 +153,6 @@ pub async fn split( coins.push(coin_state.coin); } - tx.commit().await?; - let coin_spends = wallet .split_xch(&coins, output_count as usize, fee, false, true) .await?; From ad0c146df17dc01f331300b3aaf27d1f34a3797b Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 23:12:18 -0500 Subject: [PATCH 12/21] More work --- crates/sage-database/src/coin_states.rs | 23 +++++++-- crates/sage-database/src/primitives/dids.rs | 21 +++++++- crates/sage-database/src/primitives/nfts.rs | 32 ++---------- crates/sage-database/src/rows/nft.rs | 1 + crates/sage-database/src/transactions.rs | 24 +++++++++ crates/sage-wallet/src/database.rs | 49 ++++++++++++++----- .../src/queues/transaction_queue.rs | 8 +-- .../src/sync_manager/wallet_sync.rs | 27 ++-------- migrations/0001_setup.sql | 4 +- 9 files changed, 117 insertions(+), 72 deletions(-) diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index bc6f3124..6161c78f 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -48,6 +48,10 @@ impl<'a> DatabaseTx<'a> { sync_coin(&mut *self.tx, coin_id, hint).await } + pub async fn unsync_coin(&mut self, coin_id: Bytes32) -> Result<()> { + unsync_coin(&mut *self.tx, coin_id).await + } + pub async fn remove_coin_transaction_id(&mut self, coin_id: Bytes32) -> Result<()> { remove_coin_transaction_id(&mut *self.tx, coin_id).await } @@ -185,17 +189,30 @@ async fn sync_coin( ) -> Result<()> { let coin_id = coin_id.as_ref(); let hint = hint.as_deref(); + sqlx::query!( " - UPDATE `coin_states` - SET `synced` = 1, `hint` = ? - WHERE `coin_id` = ? + UPDATE `coin_states` SET `synced` = 1, `hint` = ? WHERE `coin_id` = ? ", hint, coin_id ) .execute(conn) .await?; + + Ok(()) +} + +async fn unsync_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { + let coin_id = coin_id.as_ref(); + + sqlx::query!( + "UPDATE `coin_states` SET `synced` = 0 WHERE `coin_id` = ?", + coin_id + ) + .execute(conn) + .await?; + Ok(()) } diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index 1d0f3e93..56227fe7 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -64,6 +64,10 @@ impl<'a> DatabaseTx<'a> { ) -> Result<()> { insert_did_coin(&mut *self.tx, coin_id, lineage_proof, did_info).await } + + pub async fn delete_did(&mut self, coin_id: Bytes32) -> Result<()> { + delete_did(&mut *self.tx, coin_id).await + } } async fn insert_new_did( @@ -140,7 +144,7 @@ async fn insert_did_coin( sqlx::query!( " - REPLACE INTO `did_coins` ( + INSERT OR IGNORE INTO `did_coins` ( `coin_id`, `parent_parent_coin_id`, `parent_inner_puzzle_hash`, @@ -264,3 +268,18 @@ async fn did_name(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result Ok(row.name) } + +async fn delete_did(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { + let coin_id = coin_id.as_ref(); + + sqlx::query!( + " + DELETE FROM `dids` WHERE `coin_id` = ? + ", + coin_id + ) + .execute(conn) + .await?; + + Ok(()) +} diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index dd1bdd35..e6ab12d9 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -222,8 +222,8 @@ impl<'a> DatabaseTx<'a> { nft_row(&mut *self.tx, launcher_id).await } - pub async fn delete_nft(&mut self, launcher_id: Bytes32) -> Result<()> { - delete_nft(&mut *self.tx, launcher_id).await + pub async fn delete_nft(&mut self, coin_id: Bytes32) -> Result<()> { + delete_nft(&mut *self.tx, coin_id).await } pub async fn data_hash(&mut self, launcher_id: Bytes32) -> Result> { @@ -250,10 +250,6 @@ impl<'a> DatabaseTx<'a> { insert_collection(&mut *self.tx, row).await } - pub async fn nft_launcher_id(&mut self, coin_id: Bytes32) -> Result> { - nft_launcher_id(&mut *self.tx, coin_id).await - } - pub async fn collection_name(&mut self, collection_id: Bytes32) -> Result> { collection_name(&mut *self.tx, collection_id).await } @@ -650,10 +646,10 @@ async fn nft_row(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result< })) } -async fn delete_nft(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result<()> { - let launcher_id = launcher_id.as_ref(); +async fn delete_nft(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { + let coin_id = coin_id.as_ref(); - sqlx::query!("DELETE FROM `nfts` WHERE `launcher_id` = ?", launcher_id) + sqlx::query!("DELETE FROM `nfts` WHERE `coin_id` = ?", coin_id) .execute(conn) .await?; @@ -1179,21 +1175,3 @@ async fn license_hash( Ok(Some(to_bytes32(&license_hash)?)) } -async fn nft_launcher_id( - conn: impl SqliteExecutor<'_>, - coin_id: Bytes32, -) -> Result> { - let coin_id = coin_id.as_ref(); - - let Some(row) = sqlx::query!( - "SELECT `launcher_id` FROM `nft_coins` WHERE `coin_id` = ?", - coin_id - ) - .fetch_optional(conn) - .await? - else { - return Ok(None); - }; - - Ok(Some(to_bytes32(&row.launcher_id)?)) -} diff --git a/crates/sage-database/src/rows/nft.rs b/crates/sage-database/src/rows/nft.rs index 676fbb3a..458cd0a5 100644 --- a/crates/sage-database/src/rows/nft.rs +++ b/crates/sage-database/src/rows/nft.rs @@ -4,6 +4,7 @@ use crate::{to_bytes32, DatabaseError}; use super::IntoRow; +#[allow(unused)] pub(crate) struct NftSql { pub launcher_id: Vec, pub coin_id: Vec, diff --git a/crates/sage-database/src/transactions.rs b/crates/sage-database/src/transactions.rs index 77ab380b..a76d1a86 100644 --- a/crates/sage-database/src/transactions.rs +++ b/crates/sage-database/src/transactions.rs @@ -75,6 +75,10 @@ impl<'a> DatabaseTx<'a> { ) -> Result> { transaction_for_spent_coin(&mut *self.tx, coin_id).await } + + pub async fn transaction_coin_ids(&mut self, transaction_id: Bytes32) -> Result> { + transaction_coin_ids(&mut *self.tx, transaction_id).await + } } async fn insert_pending_transaction( @@ -343,3 +347,23 @@ async fn transaction_for_spent_coin( Ok(Some(to_bytes32(&row.transaction_id)?)) } + +async fn transaction_coin_ids( + conn: impl SqliteExecutor<'_>, + transaction_id: Bytes32, +) -> Result> { + let transaction_id = transaction_id.as_ref(); + + let rows = sqlx::query!( + " + SELECT `coin_id` FROM `transaction_spends` WHERE `transaction_id` = ? + ", + transaction_id + ) + .fetch_all(conn) + .await?; + + rows.into_iter() + .map(|row| to_bytes32(&row.coin_id)) + .collect() +} diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index a8ef9aae..8df1e01d 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -34,11 +34,19 @@ pub async fn upsert_coin( tx.insert_p2_coin(coin_id).await?; } - // If the coin has been spent, we need to handle the side effects. - if coin_state.spent_height.is_some() { - spend_coin(tx, coin_id).await?; + Ok(()) +} + +pub async fn handle_spent_coin( + tx: &mut DatabaseTx<'_>, + coin_id: Bytes32, +) -> Result<(), WalletError> { + if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { + safely_remove_transaction(tx, transaction_id).await?; } + delete_puzzle(tx, coin_id).await?; + Ok(()) } @@ -161,15 +169,9 @@ pub async fn insert_puzzle( Ok(()) } -pub async fn spend_coin(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { - if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { - tx.remove_transaction(transaction_id).await?; - } - - if let Some(launcher_id) = tx.nft_launcher_id(coin_id).await? { - tx.delete_nft(launcher_id).await?; - } - +pub async fn delete_puzzle(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { + tx.delete_nft(coin_id).await?; + tx.delete_did(coin_id).await?; Ok(()) } @@ -184,6 +186,12 @@ pub async fn insert_transaction( tx.insert_pending_transaction(transaction_id, aggregated_signature, transaction.fee) .await?; + let inputs: Vec = transaction + .inputs + .iter() + .map(|input| input.coin_spend.coin.coin_id()) + .collect(); + for (index, input) in transaction.inputs.into_iter().enumerate() { tx.insert_transaction_spend(transaction_id, input.coin_spend, index) .await?; @@ -219,5 +227,22 @@ pub async fn insert_transaction( } } + for coin_id in inputs { + delete_puzzle(tx, coin_id).await?; + } + Ok(subscriptions) } + +pub async fn safely_remove_transaction( + tx: &mut DatabaseTx<'_>, + transaction_id: Bytes32, +) -> Result<(), WalletError> { + for coin_id in tx.transaction_coin_ids(transaction_id).await? { + tx.unsync_coin(coin_id).await?; + } + + tx.remove_transaction(transaction_id).await?; + + Ok(()) +} diff --git a/crates/sage-wallet/src/queues/transaction_queue.rs b/crates/sage-wallet/src/queues/transaction_queue.rs index ed69ab36..c2b9ea75 100644 --- a/crates/sage-wallet/src/queues/transaction_queue.rs +++ b/crates/sage-wallet/src/queues/transaction_queue.rs @@ -12,7 +12,7 @@ use tokio::{ }; use tracing::{info, warn}; -use crate::{PeerState, SyncEvent, WalletError}; +use crate::{safely_remove_transaction, PeerState, SyncEvent, WalletError}; #[derive(Debug)] pub struct TransactionQueue { @@ -163,7 +163,7 @@ impl TransactionQueue { let mut tx = self.db.tx().await?; tx.confirm_coins(transaction_id).await?; - tx.remove_transaction(transaction_id).await?; + safely_remove_transaction(&mut tx, transaction_id).await?; tx.commit().await?; continue; @@ -171,7 +171,7 @@ impl TransactionQueue { info!("Transaction {transaction_id} failed"); let mut tx = self.db.tx().await?; - tx.remove_transaction(transaction_id).await?; + safely_remove_transaction(&mut tx, transaction_id).await?; tx.commit().await?; continue; @@ -221,7 +221,7 @@ impl TransactionQueue { } else { info!("Transaction {transaction_id} failed"); let mut tx = self.db.tx().await?; - tx.remove_transaction(transaction_id).await?; + safely_remove_transaction(&mut tx, transaction_id).await?; tx.commit().await?; } } diff --git a/crates/sage-wallet/src/sync_manager/wallet_sync.rs b/crates/sage-wallet/src/sync_manager/wallet_sync.rs index beb822c9..33a058da 100644 --- a/crates/sage-wallet/src/sync_manager/wallet_sync.rs +++ b/crates/sage-wallet/src/sync_manager/wallet_sync.rs @@ -14,7 +14,7 @@ use tokio::{ }; use tracing::{debug, info, instrument, warn}; -use crate::{SyncError, Wallet, WalletError}; +use crate::{handle_spent_coin, upsert_coin, SyncError, Wallet, WalletError}; use super::{PeerState, SyncEvent}; @@ -262,31 +262,10 @@ pub async fn incremental_sync( let mut tx = wallet.db.tx().await?; for coin_state in coin_states { - let coin_id = coin_state.coin.coin_id(); - let is_p2 = tx.is_p2_puzzle_hash(coin_state.coin.puzzle_hash).await?; - - tx.insert_coin_state(coin_state, is_p2, None).await?; - - tx.update_coin_state( - coin_id, - coin_state.created_height, - coin_state.spent_height, - None, - ) - .await?; - - if is_p2 { - tx.insert_p2_coin(coin_id).await?; - } + upsert_coin(&mut tx, coin_state, None).await?; if coin_state.spent_height.is_some() { - if let Some(transaction_id) = tx.transaction_for_spent_coin(coin_id).await? { - tx.remove_transaction(transaction_id).await?; - } - - if let Some(launcher_id) = tx.nft_launcher_id(coin_id).await? { - tx.delete_nft(launcher_id).await?; - } + handle_spent_coin(&mut tx, coin_state.coin.coin_id()).await?; } } diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index 0e336f66..98a56bdd 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -86,9 +86,11 @@ CREATE INDEX `cat_asset_id` ON `cat_coins` (`asset_id`); CREATE TABLE `dids` ( `launcher_id` BLOB NOT NULL PRIMARY KEY, + `coin_id` BLOB NOT NULL, `name` TEXT, `visible` BOOLEAN NOT NULL, - `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED + `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED, + FOREIGN KEY (`coin_id`) REFERENCES `did_coins` (`coin_id`) ON DELETE CASCADE ); CREATE INDEX `did_name` ON `dids` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); From 95c5e43b2d4602bd8b793f4384ae8cc9e7704977 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 23:16:43 -0500 Subject: [PATCH 13/21] Prepare --- ...55d13fa2554ed7ef81b52d9cce472d9e01e9f.json | 12 ++ ...2a627dc5d84bec1519e0779dc61c13ab0a26.json} | 4 +- ...77e9ac441d499a1557331b4e29ace0843c08f.json | 12 ++ ...7b87aa72b444b6add6860c7b43446c000110.json} | 6 +- ...792640044041b1aeef30761f76e7499ef3611.json | 12 -- ...f60caf0240ca348a85d51034432840571324.json} | 4 +- ...f33acd8125a09e05672703f14cd6ed70d51f.json} | 4 +- ...cd40fc44738708a5972273bb86d17f7a7694a.json | 44 ++++++++ ...e3430d1a7dcf3f0efcc68ae81c4fbcdda633.json} | 4 +- ...16dda2b562874ab963de6b38f6ae7ca3b63c.json} | 34 ++---- ...f39252f564f3f545da7e9e5b01cc6177f19b.json} | 4 +- ...edd9110a65bfacd3008d28e0e9440b1f65301.json | 12 ++ ...2585883f04923429fd3e2f2bdea33833d5c0.json} | 34 ++---- ...97ef0088d86a2fa00036dc8d8f0eefc5f156.json} | 4 +- ...54cc9e4b4fed669abb1d308d4f21a4460a0b.json} | 4 +- ...1166e7d08b7b2bdbda73426e1908d1599ce26.json | 12 -- ...bf8301dff3615197f78ecbf238529030c5930.json | 12 ++ ...b5041032fd39983269421d9884d43259314c.json} | 4 +- ...de663c57bb48d6ab125e6ac16ed2b892c6ac.json} | 4 +- ...01827988910b5ec9e7a0cab753c8f7d7fc0a9.json | 12 ++ ...f5ef2822be7c119d8cbe35b3b437717ddf835.json | 12 ++ ...8841dd4c45ebf343d91d51eb82f425dcccc3.json} | 4 +- ...e6042acf426ff734ebff07a6a139a7f6ab1a3.json | 32 ++++++ ...aed228797892e896eccb47d26483d8ab771d.json} | 4 +- ...49e0301e113380b8c592a1c8043fff773575d.json | 12 -- ...661e54fe2e09e49a4173fc3424edad610f04.json} | 6 +- ...7ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4.json | 12 -- ...6d89c3b6424b4d42d1dc89747ce3742387204.json | 12 -- ...d24224319e2f51e3b060d0374555afd9ef34.json} | 4 +- ...884632bb1e1040b87ae9a478645dd5497e3b8.json | 12 ++ ...b8c6146b91682e2d0391772350c60b7444f8a.json | 12 -- ...36b4141b4eab5ab0078649d931c6d1344a303.json | 12 ++ ...a111ce22987b95dbdc255dc3f404bd269197.json} | 4 +- ...8593903bccf9dd3509d3c2550c4d60ca5d77.json} | 4 +- ...10085a115f7d5900802ade79722b0c4ed560.json} | 4 +- ...2aaa2452c0e2ae62b455d351e22e34db387f0.json | 104 ------------------ ...5537719edeec73b4d9b10f85b913cff8a03a.json} | 6 +- ...eb44da635c7ad061dd532bbc4066c164c162.json} | 34 ++---- ...deeb3765c89c9fc78576f447c646c46f445c.json} | 4 +- ...82039a5d00c8ab27f09c12887a76d2291a3f.json} | 4 +- 40 files changed, 239 insertions(+), 297 deletions(-) create mode 100644 .sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json rename .sqlx/{query-9a1dc322a4232077760ee3ce3944dadacd3017271df05a10a422f2081e5cf7e4.json => query-0df4d6f44db6d5a751b180496df02a627dc5d84bec1519e0779dc61c13ab0a26.json} (64%) create mode 100644 .sqlx/query-1697370a7e61f088e103f2d8e1977e9ac441d499a1557331b4e29ace0843c08f.json rename .sqlx/{query-a28ff078551783cf5d9e464cb67d1d1e12af17b48def0ee2e1d776123f37994b.json => query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json} (80%) delete mode 100644 .sqlx/query-1fe5b5434dc598439f1c231bc2e792640044041b1aeef30761f76e7499ef3611.json rename .sqlx/{query-d7a3add5a8a68e06d62d7c36a1a2e43c6d31ab1e5a68e0e7508e6c2df12d90ce.json => query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json} (73%) rename .sqlx/{query-0a91e174471ba30d7bfd038757608e80bc06489227456c68410c51ee85b981f5.json => query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json} (57%) create mode 100644 .sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json rename .sqlx/{query-f8f90aeb7acc83ffbf53abf01430e751523a53e110ef8928e1fa47cd769f5714.json => query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json} (86%) rename .sqlx/{query-7e00419012ca5e1f372f20820a5326a278caf5870c682710a9207a190db26418.json => query-47860ec7d51fb4a817cadd380db316dda2b562874ab963de6b38f6ae7ca3b63c.json} (59%) rename .sqlx/{query-618dd472f460afbe45071305e0bc1474e9a119724c30b9e64adf0a715663335e.json => query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json} (67%) create mode 100644 .sqlx/query-4fc797762589a9e2e86965a8d92edd9110a65bfacd3008d28e0e9440b1f65301.json rename .sqlx/{query-c591e46250ecb00a96c4bed2d2b66a5ffb5b43d3619d58ec40b97dbee20c285c.json => query-5392fdc9a2639c97cc4499738c652585883f04923429fd3e2f2bdea33833d5c0.json} (62%) rename .sqlx/{query-c0e6db915ac0e819bc93fcd0c5f425f0914503516964aa0f84a74831583ae908.json => query-58a5fc4e0127de1f53d3071b1d7597ef0088d86a2fa00036dc8d8f0eefc5f156.json} (61%) rename .sqlx/{query-d3875a35dee1eff7ee98d34463c7fdbf4369e49d5e80f562b8e8802592187620.json => query-698d8b6ac1efd117a366920a9d1954cc9e4b4fed669abb1d308d4f21a4460a0b.json} (65%) delete mode 100644 .sqlx/query-6be4988c3235564550184d3fbd31166e7d08b7b2bdbda73426e1908d1599ce26.json create mode 100644 .sqlx/query-6c9af1c832bcead88d180b884b4bf8301dff3615197f78ecbf238529030c5930.json rename .sqlx/{query-daaab247a40dc935aa61ad816de864adfc4aafa690e1b1617e488e4e90f11705.json => query-6d70a25c3dc7e5d3507a28d5394bb5041032fd39983269421d9884d43259314c.json} (69%) rename .sqlx/{query-34001e7754bb8a374e1caf1b920e2e0fcb7a8cb019995a1ff373d967a71de902.json => query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json} (86%) create mode 100644 .sqlx/query-7ac44bd2934972682709ad97f7f01827988910b5ec9e7a0cab753c8f7d7fc0a9.json create mode 100644 .sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json rename .sqlx/{query-588925471a8a00ac4c99646e2237210d8f6b49c06bf1f8aef5c63685559f8979.json => query-82e25960cba013361d6f302dbf318841dd4c45ebf343d91d51eb82f425dcccc3.json} (63%) create mode 100644 .sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json rename .sqlx/{query-6b25d729076afa7ba1451b086dc6d81bfc3678da93a440625f7f40422570aaa5.json => query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json} (56%) delete mode 100644 .sqlx/query-a2ba0a97b52dabd90fc39a952ee49e0301e113380b8c592a1c8043fff773575d.json rename .sqlx/{query-b9a57ebb3e57678d69b47459e6b970e3cec6ccea097c7e3eafaf4da244e79ce0.json => query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json} (79%) delete mode 100644 .sqlx/query-ace44d37f3726b3bdeab85040527ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4.json delete mode 100644 .sqlx/query-ae2ee53354d87b940e93e72efb26d89c3b6424b4d42d1dc89747ce3742387204.json rename .sqlx/{query-a9411b6655d01e2722f4b6ad5737e5a1804b11062d6914bdfc86a433f921ee4d.json => query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json} (86%) create mode 100644 .sqlx/query-c03961b6da91bf8a86937bf0789884632bb1e1040b87ae9a478645dd5497e3b8.json delete mode 100644 .sqlx/query-c08595117fedb45dc34273c694ab8c6146b91682e2d0391772350c60b7444f8a.json create mode 100644 .sqlx/query-cbe56b7b03c2cd4c662a183791936b4141b4eab5ab0078649d931c6d1344a303.json rename .sqlx/{query-354e992e7b1c796745d4bea684cb2c393585c611a05518b2ef2e11fe4f4ffdf8.json => query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json} (86%) rename .sqlx/{query-801601660931eb990ebb78de182d03e8bd52bfc797b3694c6c2de8908910fc55.json => query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json} (84%) rename .sqlx/{query-6f75552f083ab3b9cbed52e38a9f9c59e36aaecd3c70500731ed7e6ca6736de5.json => query-db46b3d7d5af874af5981ec8beb210085a115f7d5900802ade79722b0c4ed560.json} (63%) delete mode 100644 .sqlx/query-dfcde1ea41ddc345990e32827c02aaa2452c0e2ae62b455d351e22e34db387f0.json rename .sqlx/{query-bb6e5713867c9ff2b4ad68c6d28c695460a9a74d23111af67f80e85df2ccc5d8.json => query-e87cae330e1ce739c1ddf2cdbf3b5537719edeec73b4d9b10f85b913cff8a03a.json} (51%) rename .sqlx/{query-8ff157723ba335104fe877458b242b3755b8f95063daed3cf990617e766cb66c.json => query-f60979af832a6d514b6249708dfdeb44da635c7ad061dd532bbc4066c164c162.json} (58%) rename .sqlx/{query-fc2bc853db0bb5424bb821675c6412ab4fe23d6937fa683075129603f9fc708b.json => query-fd9f732f3a7ed809b9d4c2ededebdeeb3765c89c9fc78576f447c646c46f445c.json} (56%) rename .sqlx/{query-f73e22a087da79c84fad58ae25cfe13414ebb751a0cc82c611f035f6b97b8e27.json => query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json} (84%) diff --git a/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json b/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json new file mode 100644 index 00000000..cedc8d4d --- /dev/null +++ b/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n DELETE FROM `dids` WHERE `coin_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f" +} diff --git a/.sqlx/query-9a1dc322a4232077760ee3ce3944dadacd3017271df05a10a422f2081e5cf7e4.json b/.sqlx/query-0df4d6f44db6d5a751b180496df02a627dc5d84bec1519e0779dc61c13ab0a26.json similarity index 64% rename from .sqlx/query-9a1dc322a4232077760ee3ce3944dadacd3017271df05a10a422f2081e5cf7e4.json rename to .sqlx/query-0df4d6f44db6d5a751b180496df02a627dc5d84bec1519e0779dc61c13ab0a26.json index 5137f10d..ce3643a2 100644 --- a/.sqlx/query-9a1dc322a4232077760ee3ce3944dadacd3017271df05a10a422f2081e5cf7e4.json +++ b/.sqlx/query-0df4d6f44db6d5a751b180496df02a627dc5d84bec1519e0779dc61c13ab0a26.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `collection_id`,\n `did_id`,\n `metadata_collection_id`,\n `visible`,\n `name`,\n `icon`\n FROM `nft_collections` INDEXED BY `col_named`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon`\n FROM `collections` INDEXED BY `col_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `collection_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -46,5 +46,5 @@ true ] }, - "hash": "9a1dc322a4232077760ee3ce3944dadacd3017271df05a10a422f2081e5cf7e4" + "hash": "0df4d6f44db6d5a751b180496df02a627dc5d84bec1519e0779dc61c13ab0a26" } diff --git a/.sqlx/query-1697370a7e61f088e103f2d8e1977e9ac441d499a1557331b4e29ace0843c08f.json b/.sqlx/query-1697370a7e61f088e103f2d8e1977e9ac441d499a1557331b4e29ace0843c08f.json new file mode 100644 index 00000000..c5cb6a7a --- /dev/null +++ b/.sqlx/query-1697370a7e61f088e103f2d8e1977e9ac441d499a1557331b4e29ace0843c08f.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n UPDATE `coin_states`\n SET `created_height` = ?, `spent_height` = ?, `transaction_id` = ?\n WHERE `coin_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 4 + }, + "nullable": [] + }, + "hash": "1697370a7e61f088e103f2d8e1977e9ac441d499a1557331b4e29ace0843c08f" +} diff --git a/.sqlx/query-a28ff078551783cf5d9e464cb67d1d1e12af17b48def0ee2e1d776123f37994b.json b/.sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json similarity index 80% rename from .sqlx/query-a28ff078551783cf5d9e464cb67d1d1e12af17b48def0ee2e1d776123f37994b.json rename to .sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json index d963122e..4b58e0fa 100644 --- a/.sqlx/query-a28ff078551783cf5d9e464cb67d1d1e12af17b48def0ee2e1d776123f37994b.json +++ b/.sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon_url`,\n `visible`\n FROM `cats`\n WHERE `asset_id` = ?\n ", + "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n FROM `cats`\n WHERE `asset_id` = ?\n ", "describe": { "columns": [ { @@ -24,7 +24,7 @@ "type_info": "Text" }, { - "name": "icon_url", + "name": "icon", "ordinal": 4, "type_info": "Text" }, @@ -46,5 +46,5 @@ false ] }, - "hash": "a28ff078551783cf5d9e464cb67d1d1e12af17b48def0ee2e1d776123f37994b" + "hash": "1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110" } diff --git a/.sqlx/query-1fe5b5434dc598439f1c231bc2e792640044041b1aeef30761f76e7499ef3611.json b/.sqlx/query-1fe5b5434dc598439f1c231bc2e792640044041b1aeef30761f76e7499ef3611.json deleted file mode 100644 index 167be0be..00000000 --- a/.sqlx/query-1fe5b5434dc598439f1c231bc2e792640044041b1aeef30761f76e7499ef3611.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n REPLACE INTO `did_coins` (\n `coin_id`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `launcher_id`,\n `recovery_list_hash`,\n `num_verifications_required`,\n `metadata`,\n `p2_puzzle_hash`\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 9 - }, - "nullable": [] - }, - "hash": "1fe5b5434dc598439f1c231bc2e792640044041b1aeef30761f76e7499ef3611" -} diff --git a/.sqlx/query-d7a3add5a8a68e06d62d7c36a1a2e43c6d31ab1e5a68e0e7508e6c2df12d90ce.json b/.sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json similarity index 73% rename from .sqlx/query-d7a3add5a8a68e06d62d7c36a1a2e43c6d31ab1e5a68e0e7508e6c2df12d90ce.json rename to .sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json index 463bd971..d5180397 100644 --- a/.sqlx/query-d7a3add5a8a68e06d62d7c36a1a2e43c6d31ab1e5a68e0e7508e6c2df12d90ce.json +++ b/.sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `launcher_id`,\n `coin_id`,\n `collection_id`,\n `minter_did`,\n `owner_did`,\n `visible`,\n `sensitive_content`,\n `name`,\n `created_height`,\n `metadata_hash`\n FROM `nfts`\n WHERE `launcher_id` = ?\n ", + "query": "\n SELECT\n `launcher_id`, `coin_id`, `collection_id`, `minter_did`, `owner_did`,\n `visible`, `sensitive_content`, `name`, `created_height`, `metadata_hash`\n FROM `nfts`\n WHERE `launcher_id` = ?\n ", "describe": { "columns": [ { @@ -70,5 +70,5 @@ true ] }, - "hash": "d7a3add5a8a68e06d62d7c36a1a2e43c6d31ab1e5a68e0e7508e6c2df12d90ce" + "hash": "27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324" } diff --git a/.sqlx/query-0a91e174471ba30d7bfd038757608e80bc06489227456c68410c51ee85b981f5.json b/.sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json similarity index 57% rename from .sqlx/query-0a91e174471ba30d7bfd038757608e80bc06489227456c68410c51ee85b981f5.json rename to .sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json index 8ae73599..acac3f88 100644 --- a/.sqlx/query-0a91e174471ba30d7bfd038757608e80bc06489227456c68410c51ee85b981f5.json +++ b/.sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n REPLACE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon_url`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "query": "\n REPLACE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", "describe": { "columns": [], "parameters": { @@ -8,5 +8,5 @@ }, "nullable": [] }, - "hash": "0a91e174471ba30d7bfd038757608e80bc06489227456c68410c51ee85b981f5" + "hash": "290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f" } diff --git a/.sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json b/.sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json new file mode 100644 index 00000000..ae6c3ff9 --- /dev/null +++ b/.sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json @@ -0,0 +1,44 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT\n `did_coins`.`coin_id`, `amount`, `p2_puzzle_hash`, `created_height`, `transaction_id`\n FROM `did_coins`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `did_coins`.coin_id\n WHERE `launcher_id` = ?\n ", + "describe": { + "columns": [ + { + "name": "coin_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "amount", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "p2_puzzle_hash", + "ordinal": 2, + "type_info": "Blob" + }, + { + "name": "created_height", + "ordinal": 3, + "type_info": "Integer" + }, + { + "name": "transaction_id", + "ordinal": 4, + "type_info": "Blob" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + false, + true, + true + ] + }, + "hash": "3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a" +} diff --git a/.sqlx/query-f8f90aeb7acc83ffbf53abf01430e751523a53e110ef8928e1fa47cd769f5714.json b/.sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json similarity index 86% rename from .sqlx/query-f8f90aeb7acc83ffbf53abf01430e751523a53e110ef8928e1fa47cd769f5714.json rename to .sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json index 6c31c034..d2ebecc4 100644 --- a/.sqlx/query-f8f90aeb7acc83ffbf53abf01430e751523a53e110ef8928e1fa47cd769f5714.json +++ b/.sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_named`\n WHERE `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "f8f90aeb7acc83ffbf53abf01430e751523a53e110ef8928e1fa47cd769f5714" + "hash": "4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633" } diff --git a/.sqlx/query-7e00419012ca5e1f372f20820a5326a278caf5870c682710a9207a190db26418.json b/.sqlx/query-47860ec7d51fb4a817cadd380db316dda2b562874ab963de6b38f6ae7ca3b63c.json similarity index 59% rename from .sqlx/query-7e00419012ca5e1f372f20820a5326a278caf5870c682710a9207a190db26418.json rename to .sqlx/query-47860ec7d51fb4a817cadd380db316dda2b562874ab963de6b38f6ae7ca3b63c.json index e29620ab..20e453f7 100644 --- a/.sqlx/query-7e00419012ca5e1f372f20820a5326a278caf5870c682710a9207a190db26418.json +++ b/.sqlx/query-47860ec7d51fb4a817cadd380db316dda2b562874ab963de6b38f6ae7ca3b63c.json @@ -1,51 +1,36 @@ { "db_name": "SQLite", - "query": "\n SELECT `coin_states`.* FROM `coin_states`\n INNER JOIN `p2_coins` ON `coin_states`.`coin_id` = `p2_coins`.`coin_id`\n ", + "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id`\n FROM `coin_states`\n INNER JOIN `p2_coins` ON `coin_states`.`coin_id` = `p2_coins`.`coin_id`\n ", "describe": { "columns": [ - { - "name": "coin_id", - "ordinal": 0, - "type_info": "Blob" - }, { "name": "parent_coin_id", - "ordinal": 1, + "ordinal": 0, "type_info": "Blob" }, { "name": "puzzle_hash", - "ordinal": 2, + "ordinal": 1, "type_info": "Blob" }, { "name": "amount", - "ordinal": 3, + "ordinal": 2, "type_info": "Blob" }, { "name": "spent_height", - "ordinal": 4, + "ordinal": 3, "type_info": "Integer" }, { "name": "created_height", - "ordinal": 5, + "ordinal": 4, "type_info": "Integer" }, - { - "name": "hint", - "ordinal": 6, - "type_info": "Blob" - }, - { - "name": "synced", - "ordinal": 7, - "type_info": "Bool" - }, { "name": "transaction_id", - "ordinal": 8, + "ordinal": 5, "type_info": "Blob" } ], @@ -56,13 +41,10 @@ false, false, false, - false, true, true, - true, - false, true ] }, - "hash": "7e00419012ca5e1f372f20820a5326a278caf5870c682710a9207a190db26418" + "hash": "47860ec7d51fb4a817cadd380db316dda2b562874ab963de6b38f6ae7ca3b63c" } diff --git a/.sqlx/query-618dd472f460afbe45071305e0bc1474e9a119724c30b9e64adf0a715663335e.json b/.sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json similarity index 67% rename from .sqlx/query-618dd472f460afbe45071305e0bc1474e9a119724c30b9e64adf0a715663335e.json rename to .sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json index f085b057..a5f8a671 100644 --- a/.sqlx/query-618dd472f460afbe45071305e0bc1474e9a119724c30b9e64adf0a715663335e.json +++ b/.sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n cs.parent_coin_id, cs.puzzle_hash, cs.amount,\n cs.spent_height, cs.created_height, cs.transaction_id\n FROM `coin_states` AS cs\n INNER JOIN `cat_coins` AS cat\n ON cs.coin_id = cat.coin_id\n WHERE cat.asset_id = ?\n ", + "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id`\n FROM `cat_coins`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `cat_coins`.coin_id\n WHERE `asset_id` = ?\n ", "describe": { "columns": [ { @@ -46,5 +46,5 @@ true ] }, - "hash": "618dd472f460afbe45071305e0bc1474e9a119724c30b9e64adf0a715663335e" + "hash": "4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b" } diff --git a/.sqlx/query-4fc797762589a9e2e86965a8d92edd9110a65bfacd3008d28e0e9440b1f65301.json b/.sqlx/query-4fc797762589a9e2e86965a8d92edd9110a65bfacd3008d28e0e9440b1f65301.json new file mode 100644 index 00000000..00abede5 --- /dev/null +++ b/.sqlx/query-4fc797762589a9e2e86965a8d92edd9110a65bfacd3008d28e0e9440b1f65301.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "UPDATE `coin_states` SET `synced` = 0 WHERE `coin_id` = ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "4fc797762589a9e2e86965a8d92edd9110a65bfacd3008d28e0e9440b1f65301" +} diff --git a/.sqlx/query-c591e46250ecb00a96c4bed2d2b66a5ffb5b43d3619d58ec40b97dbee20c285c.json b/.sqlx/query-5392fdc9a2639c97cc4499738c652585883f04923429fd3e2f2bdea33833d5c0.json similarity index 62% rename from .sqlx/query-c591e46250ecb00a96c4bed2d2b66a5ffb5b43d3619d58ec40b97dbee20c285c.json rename to .sqlx/query-5392fdc9a2639c97cc4499738c652585883f04923429fd3e2f2bdea33833d5c0.json index 4927ed07..c3a3b2cb 100644 --- a/.sqlx/query-c591e46250ecb00a96c4bed2d2b66a5ffb5b43d3619d58ec40b97dbee20c285c.json +++ b/.sqlx/query-5392fdc9a2639c97cc4499738c652585883f04923429fd3e2f2bdea33833d5c0.json @@ -1,51 +1,36 @@ { "db_name": "SQLite", - "query": "\n SELECT *\n FROM `coin_states`\n WHERE `coin_id` = ?\n ", + "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `created_height`, `spent_height`, `transaction_id`\n FROM `coin_states`\n WHERE `coin_id` = ?\n ", "describe": { "columns": [ { - "name": "coin_id", + "name": "parent_coin_id", "ordinal": 0, "type_info": "Blob" }, { - "name": "parent_coin_id", + "name": "puzzle_hash", "ordinal": 1, "type_info": "Blob" }, { - "name": "puzzle_hash", + "name": "amount", "ordinal": 2, "type_info": "Blob" }, { - "name": "amount", + "name": "created_height", "ordinal": 3, - "type_info": "Blob" + "type_info": "Integer" }, { "name": "spent_height", "ordinal": 4, "type_info": "Integer" }, - { - "name": "created_height", - "ordinal": 5, - "type_info": "Integer" - }, - { - "name": "hint", - "ordinal": 6, - "type_info": "Blob" - }, - { - "name": "synced", - "ordinal": 7, - "type_info": "Bool" - }, { "name": "transaction_id", - "ordinal": 8, + "ordinal": 5, "type_info": "Blob" } ], @@ -56,13 +41,10 @@ false, false, false, - false, true, true, - true, - false, true ] }, - "hash": "c591e46250ecb00a96c4bed2d2b66a5ffb5b43d3619d58ec40b97dbee20c285c" + "hash": "5392fdc9a2639c97cc4499738c652585883f04923429fd3e2f2bdea33833d5c0" } diff --git a/.sqlx/query-c0e6db915ac0e819bc93fcd0c5f425f0914503516964aa0f84a74831583ae908.json b/.sqlx/query-58a5fc4e0127de1f53d3071b1d7597ef0088d86a2fa00036dc8d8f0eefc5f156.json similarity index 61% rename from .sqlx/query-c0e6db915ac0e819bc93fcd0c5f425f0914503516964aa0f84a74831583ae908.json rename to .sqlx/query-58a5fc4e0127de1f53d3071b1d7597ef0088d86a2fa00036dc8d8f0eefc5f156.json index b3601e88..24e007ec 100644 --- a/.sqlx/query-c0e6db915ac0e819bc93fcd0c5f425f0914503516964aa0f84a74831583ae908.json +++ b/.sqlx/query-58a5fc4e0127de1f53d3071b1d7597ef0088d86a2fa00036dc8d8f0eefc5f156.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT `name` FROM `nft_collections` WHERE `collection_id` = ?", + "query": "SELECT `name` FROM `collections` WHERE `collection_id` = ?", "describe": { "columns": [ { @@ -16,5 +16,5 @@ true ] }, - "hash": "c0e6db915ac0e819bc93fcd0c5f425f0914503516964aa0f84a74831583ae908" + "hash": "58a5fc4e0127de1f53d3071b1d7597ef0088d86a2fa00036dc8d8f0eefc5f156" } diff --git a/.sqlx/query-d3875a35dee1eff7ee98d34463c7fdbf4369e49d5e80f562b8e8802592187620.json b/.sqlx/query-698d8b6ac1efd117a366920a9d1954cc9e4b4fed669abb1d308d4f21a4460a0b.json similarity index 65% rename from .sqlx/query-d3875a35dee1eff7ee98d34463c7fdbf4369e49d5e80f562b8e8802592187620.json rename to .sqlx/query-698d8b6ac1efd117a366920a9d1954cc9e4b4fed669abb1d308d4f21a4460a0b.json index 8d9ef5d2..8fe11b68 100644 --- a/.sqlx/query-d3875a35dee1eff7ee98d34463c7fdbf4369e49d5e80f562b8e8802592187620.json +++ b/.sqlx/query-698d8b6ac1efd117a366920a9d1954cc9e4b4fed669abb1d308d4f21a4460a0b.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `coin_states`.`parent_coin_id`,\n `coin_states`.`puzzle_hash`,\n `coin_states`.`amount`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `launcher_id`,\n `metadata`,\n `metadata_updater_puzzle_hash`,\n `current_owner`,\n `royalty_puzzle_hash`,\n `royalty_ten_thousandths`,\n `p2_puzzle_hash`\n FROM `nft_coins`\n INNER JOIN `coin_states` INDEXED BY `coin_height` ON `nft_coins`.`coin_id` = `coin_states`.`coin_id`\n LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `launcher_id` = ?\n AND `spent_height` IS NULL\n AND `transaction_spends`.`transaction_id` IS NULL\n ", + "query": "\n SELECT\n `coin_states`.`parent_coin_id`, `coin_states`.`puzzle_hash`, `coin_states`.`amount`,\n `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount`,\n `launcher_id`, `metadata`, `metadata_updater_puzzle_hash`, `current_owner`,\n `royalty_puzzle_hash`, `royalty_ten_thousandths`, `p2_puzzle_hash`\n FROM `nft_coins`\n INNER JOIN `coin_states` INDEXED BY `coin_height` ON `nft_coins`.`coin_id` = `coin_states`.`coin_id`\n LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `launcher_id` = ?\n AND `spent_height` IS NULL\n AND `transaction_spends`.`transaction_id` IS NULL\n ", "describe": { "columns": [ { @@ -88,5 +88,5 @@ false ] }, - "hash": "d3875a35dee1eff7ee98d34463c7fdbf4369e49d5e80f562b8e8802592187620" + "hash": "698d8b6ac1efd117a366920a9d1954cc9e4b4fed669abb1d308d4f21a4460a0b" } diff --git a/.sqlx/query-6be4988c3235564550184d3fbd31166e7d08b7b2bdbda73426e1908d1599ce26.json b/.sqlx/query-6be4988c3235564550184d3fbd31166e7d08b7b2bdbda73426e1908d1599ce26.json deleted file mode 100644 index ab349229..00000000 --- a/.sqlx/query-6be4988c3235564550184d3fbd31166e7d08b7b2bdbda73426e1908d1599ce26.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE `coin_states`\n SET `created_height` = ?, `spent_height` = ?, `transaction_id` = NULL\n WHERE `coin_id` = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "6be4988c3235564550184d3fbd31166e7d08b7b2bdbda73426e1908d1599ce26" -} diff --git a/.sqlx/query-6c9af1c832bcead88d180b884b4bf8301dff3615197f78ecbf238529030c5930.json b/.sqlx/query-6c9af1c832bcead88d180b884b4bf8301dff3615197f78ecbf238529030c5930.json new file mode 100644 index 00000000..14256766 --- /dev/null +++ b/.sqlx/query-6c9af1c832bcead88d180b884b4bf8301dff3615197f78ecbf238529030c5930.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n DELETE FROM `coin_states`\n WHERE `coin_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "6c9af1c832bcead88d180b884b4bf8301dff3615197f78ecbf238529030c5930" +} diff --git a/.sqlx/query-daaab247a40dc935aa61ad816de864adfc4aafa690e1b1617e488e4e90f11705.json b/.sqlx/query-6d70a25c3dc7e5d3507a28d5394bb5041032fd39983269421d9884d43259314c.json similarity index 69% rename from .sqlx/query-daaab247a40dc935aa61ad816de864adfc4aafa690e1b1617e488e4e90f11705.json rename to .sqlx/query-6d70a25c3dc7e5d3507a28d5394bb5041032fd39983269421d9884d43259314c.json index 1590abea..baa925a5 100644 --- a/.sqlx/query-daaab247a40dc935aa61ad816de864adfc4aafa690e1b1617e488e4e90f11705.json +++ b/.sqlx/query-6d70a25c3dc7e5d3507a28d5394bb5041032fd39983269421d9884d43259314c.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `collection_id`,\n `did_id`,\n `metadata_collection_id`,\n `visible`,\n `name`,\n `icon`\n FROM `nft_collections`\n WHERE `collection_id` = ?\n ", + "query": "\n SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon`\n FROM `collections` WHERE `collection_id` = ?\n ", "describe": { "columns": [ { @@ -46,5 +46,5 @@ true ] }, - "hash": "daaab247a40dc935aa61ad816de864adfc4aafa690e1b1617e488e4e90f11705" + "hash": "6d70a25c3dc7e5d3507a28d5394bb5041032fd39983269421d9884d43259314c" } diff --git a/.sqlx/query-34001e7754bb8a374e1caf1b920e2e0fcb7a8cb019995a1ff373d967a71de902.json b/.sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json similarity index 86% rename from .sqlx/query-34001e7754bb8a374e1caf1b920e2e0fcb7a8cb019995a1ff373d967a71de902.json rename to .sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json index ab53897d..cface394 100644 --- a/.sqlx/query-34001e7754bb8a374e1caf1b920e2e0fcb7a8cb019995a1ff373d967a71de902.json +++ b/.sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_named`\n WHERE `collection_id` = ? AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` = ? AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "34001e7754bb8a374e1caf1b920e2e0fcb7a8cb019995a1ff373d967a71de902" + "hash": "7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac" } diff --git a/.sqlx/query-7ac44bd2934972682709ad97f7f01827988910b5ec9e7a0cab753c8f7d7fc0a9.json b/.sqlx/query-7ac44bd2934972682709ad97f7f01827988910b5ec9e7a0cab753c8f7d7fc0a9.json new file mode 100644 index 00000000..78fdfdf7 --- /dev/null +++ b/.sqlx/query-7ac44bd2934972682709ad97f7f01827988910b5ec9e7a0cab753c8f7d7fc0a9.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT OR IGNORE INTO `did_coins` (\n `coin_id`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `launcher_id`,\n `recovery_list_hash`,\n `num_verifications_required`,\n `metadata`,\n `p2_puzzle_hash`\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 9 + }, + "nullable": [] + }, + "hash": "7ac44bd2934972682709ad97f7f01827988910b5ec9e7a0cab753c8f7d7fc0a9" +} diff --git a/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json b/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json new file mode 100644 index 00000000..04a209c9 --- /dev/null +++ b/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "DELETE FROM `nfts` WHERE `coin_id` = ?", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835" +} diff --git a/.sqlx/query-588925471a8a00ac4c99646e2237210d8f6b49c06bf1f8aef5c63685559f8979.json b/.sqlx/query-82e25960cba013361d6f302dbf318841dd4c45ebf343d91d51eb82f425dcccc3.json similarity index 63% rename from .sqlx/query-588925471a8a00ac4c99646e2237210d8f6b49c06bf1f8aef5c63685559f8979.json rename to .sqlx/query-82e25960cba013361d6f302dbf318841dd4c45ebf343d91d51eb82f425dcccc3.json index c136a9d2..c8082721 100644 --- a/.sqlx/query-588925471a8a00ac4c99646e2237210d8f6b49c06bf1f8aef5c63685559f8979.json +++ b/.sqlx/query-82e25960cba013361d6f302dbf318841dd4c45ebf343d91d51eb82f425dcccc3.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `coin_states`.`parent_coin_id`,\n `coin_states`.`puzzle_hash`,\n `coin_states`.`amount`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `launcher_id`,\n `metadata`,\n `metadata_updater_puzzle_hash`,\n `current_owner`,\n `royalty_puzzle_hash`,\n `royalty_ten_thousandths`,\n `p2_puzzle_hash`\n FROM `nft_coins`\n INNER JOIN `coin_states` INDEXED BY `coin_height` ON `nft_coins`.`coin_id` = `coin_states`.`coin_id`\n LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `launcher_id` = ?\n AND `spent_height` IS NULL\n AND `created_height` IS NOT NULL\n AND `coin_states`.`transaction_id` IS NULL\n AND `transaction_spends`.`transaction_id` IS NULL\n ", + "query": "\n SELECT\n `coin_states`.`parent_coin_id`, `coin_states`.`puzzle_hash`, `coin_states`.`amount`,\n `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount`,\n `launcher_id`, `metadata`, `metadata_updater_puzzle_hash`, `current_owner`,\n `royalty_puzzle_hash`, `royalty_ten_thousandths`, `p2_puzzle_hash`\n FROM `nft_coins`\n INNER JOIN `coin_states` INDEXED BY `coin_height` ON `nft_coins`.`coin_id` = `coin_states`.`coin_id`\n LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `launcher_id` = ?\n AND `spent_height` IS NULL\n AND `created_height` IS NOT NULL\n AND `coin_states`.`transaction_id` IS NULL\n AND `transaction_spends`.`transaction_id` IS NULL\n ", "describe": { "columns": [ { @@ -88,5 +88,5 @@ false ] }, - "hash": "588925471a8a00ac4c99646e2237210d8f6b49c06bf1f8aef5c63685559f8979" + "hash": "82e25960cba013361d6f302dbf318841dd4c45ebf343d91d51eb82f425dcccc3" } diff --git a/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json b/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json new file mode 100644 index 00000000..fe313b88 --- /dev/null +++ b/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json @@ -0,0 +1,32 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT `launcher_id`, `name`, `visible`\n FROM `dids` INDEXED BY `did_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "name", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "visible", + "ordinal": 2, + "type_info": "Bool" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false, + true, + false + ] + }, + "hash": "885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3" +} diff --git a/.sqlx/query-6b25d729076afa7ba1451b086dc6d81bfc3678da93a440625f7f40422570aaa5.json b/.sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json similarity index 56% rename from .sqlx/query-6b25d729076afa7ba1451b086dc6d81bfc3678da93a440625f7f40422570aaa5.json rename to .sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json index 00506c08..90ead4d4 100644 --- a/.sqlx/query-6b25d729076afa7ba1451b086dc6d81bfc3678da93a440625f7f40422570aaa5.json +++ b/.sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon_url`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "query": "\n INSERT OR IGNORE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", "describe": { "columns": [], "parameters": { @@ -8,5 +8,5 @@ }, "nullable": [] }, - "hash": "6b25d729076afa7ba1451b086dc6d81bfc3678da93a440625f7f40422570aaa5" + "hash": "9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d" } diff --git a/.sqlx/query-a2ba0a97b52dabd90fc39a952ee49e0301e113380b8c592a1c8043fff773575d.json b/.sqlx/query-a2ba0a97b52dabd90fc39a952ee49e0301e113380b8c592a1c8043fff773575d.json deleted file mode 100644 index fe4c062b..00000000 --- a/.sqlx/query-a2ba0a97b52dabd90fc39a952ee49e0301e113380b8c592a1c8043fff773575d.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM `nfts` WHERE `launcher_id` = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "a2ba0a97b52dabd90fc39a952ee49e0301e113380b8c592a1c8043fff773575d" -} diff --git a/.sqlx/query-b9a57ebb3e57678d69b47459e6b970e3cec6ccea097c7e3eafaf4da244e79ce0.json b/.sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json similarity index 79% rename from .sqlx/query-b9a57ebb3e57678d69b47459e6b970e3cec6ccea097c7e3eafaf4da244e79ce0.json rename to .sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json index 38bee465..d70a8869 100644 --- a/.sqlx/query-b9a57ebb3e57678d69b47459e6b970e3cec6ccea097c7e3eafaf4da244e79ce0.json +++ b/.sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon_url`,\n `visible`\n FROM `cats`\n ORDER BY `name` ASC, `asset_id` ASC\n ", + "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n FROM `cats`\n ORDER BY `name` ASC, `asset_id` ASC\n ", "describe": { "columns": [ { @@ -24,7 +24,7 @@ "type_info": "Text" }, { - "name": "icon_url", + "name": "icon", "ordinal": 4, "type_info": "Text" }, @@ -46,5 +46,5 @@ false ] }, - "hash": "b9a57ebb3e57678d69b47459e6b970e3cec6ccea097c7e3eafaf4da244e79ce0" + "hash": "a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04" } diff --git a/.sqlx/query-ace44d37f3726b3bdeab85040527ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4.json b/.sqlx/query-ace44d37f3726b3bdeab85040527ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4.json deleted file mode 100644 index ab15f65f..00000000 --- a/.sqlx/query-ace44d37f3726b3bdeab85040527ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n REPLACE INTO `nft_collections` (\n `collection_id`,\n `did_id`,\n `metadata_collection_id`,\n `visible`,\n `name`,\n `icon`\n )\n VALUES (?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "ace44d37f3726b3bdeab85040527ff2c3cc895e4d7a07dc4c1119eadf7a7b0c4" -} diff --git a/.sqlx/query-ae2ee53354d87b940e93e72efb26d89c3b6424b4d42d1dc89747ce3742387204.json b/.sqlx/query-ae2ee53354d87b940e93e72efb26d89c3b6424b4d42d1dc89747ce3742387204.json deleted file mode 100644 index 3590e815..00000000 --- a/.sqlx/query-ae2ee53354d87b940e93e72efb26d89c3b6424b4d42d1dc89747ce3742387204.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n REPLACE INTO `unknown_coins` (`coin_id`) VALUES (?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "ae2ee53354d87b940e93e72efb26d89c3b6424b4d42d1dc89747ce3742387204" -} diff --git a/.sqlx/query-a9411b6655d01e2722f4b6ad5737e5a1804b11062d6914bdfc86a433f921ee4d.json b/.sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json similarity index 86% rename from .sqlx/query-a9411b6655d01e2722f4b6ad5737e5a1804b11062d6914bdfc86a433f921ee4d.json rename to .sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json index 873227b6..92ca55f6 100644 --- a/.sqlx/query-a9411b6655d01e2722f4b6ad5737e5a1804b11062d6914bdfc86a433f921ee4d.json +++ b/.sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_named`\n WHERE `collection_id` = ?\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` = ?\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "a9411b6655d01e2722f4b6ad5737e5a1804b11062d6914bdfc86a433f921ee4d" + "hash": "bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34" } diff --git a/.sqlx/query-c03961b6da91bf8a86937bf0789884632bb1e1040b87ae9a478645dd5497e3b8.json b/.sqlx/query-c03961b6da91bf8a86937bf0789884632bb1e1040b87ae9a478645dd5497e3b8.json new file mode 100644 index 00000000..13f1c0c2 --- /dev/null +++ b/.sqlx/query-c03961b6da91bf8a86937bf0789884632bb1e1040b87ae9a478645dd5497e3b8.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n UPDATE `coin_states` SET `synced` = 1, `hint` = ? WHERE `coin_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "c03961b6da91bf8a86937bf0789884632bb1e1040b87ae9a478645dd5497e3b8" +} diff --git a/.sqlx/query-c08595117fedb45dc34273c694ab8c6146b91682e2d0391772350c60b7444f8a.json b/.sqlx/query-c08595117fedb45dc34273c694ab8c6146b91682e2d0391772350c60b7444f8a.json deleted file mode 100644 index 14c0399b..00000000 --- a/.sqlx/query-c08595117fedb45dc34273c694ab8c6146b91682e2d0391772350c60b7444f8a.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE `coin_states`\n SET `synced` = 1, `hint` = ?\n WHERE `coin_id` = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "c08595117fedb45dc34273c694ab8c6146b91682e2d0391772350c60b7444f8a" -} diff --git a/.sqlx/query-cbe56b7b03c2cd4c662a183791936b4141b4eab5ab0078649d931c6d1344a303.json b/.sqlx/query-cbe56b7b03c2cd4c662a183791936b4141b4eab5ab0078649d931c6d1344a303.json new file mode 100644 index 00000000..6bf50fea --- /dev/null +++ b/.sqlx/query-cbe56b7b03c2cd4c662a183791936b4141b4eab5ab0078649d931c6d1344a303.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n REPLACE INTO `collections` (\n `collection_id`,\n `did_id`,\n `metadata_collection_id`,\n `visible`,\n `name`,\n `icon`\n )\n VALUES (?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "cbe56b7b03c2cd4c662a183791936b4141b4eab5ab0078649d931c6d1344a303" +} diff --git a/.sqlx/query-354e992e7b1c796745d4bea684cb2c393585c611a05518b2ef2e11fe4f4ffdf8.json b/.sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json similarity index 86% rename from .sqlx/query-354e992e7b1c796745d4bea684cb2c393585c611a05518b2ef2e11fe4f4ffdf8.json rename to .sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json index 9d8de119..e25e5a66 100644 --- a/.sqlx/query-354e992e7b1c796745d4bea684cb2c393585c611a05518b2ef2e11fe4f4ffdf8.json +++ b/.sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_named`\n WHERE `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "354e992e7b1c796745d4bea684cb2c393585c611a05518b2ef2e11fe4f4ffdf8" + "hash": "ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197" } diff --git a/.sqlx/query-801601660931eb990ebb78de182d03e8bd52bfc797b3694c6c2de8908910fc55.json b/.sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json similarity index 84% rename from .sqlx/query-801601660931eb990ebb78de182d03e8bd52bfc797b3694c6c2de8908910fc55.json rename to .sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json index 05af2ac3..dca812b0 100644 --- a/.sqlx/query-801601660931eb990ebb78de182d03e8bd52bfc797b3694c6c2de8908910fc55.json +++ b/.sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_named`\n WHERE `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n WHERE `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "801601660931eb990ebb78de182d03e8bd52bfc797b3694c6c2de8908910fc55" + "hash": "da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77" } diff --git a/.sqlx/query-6f75552f083ab3b9cbed52e38a9f9c59e36aaecd3c70500731ed7e6ca6736de5.json b/.sqlx/query-db46b3d7d5af874af5981ec8beb210085a115f7d5900802ade79722b0c4ed560.json similarity index 63% rename from .sqlx/query-6f75552f083ab3b9cbed52e38a9f9c59e36aaecd3c70500731ed7e6ca6736de5.json rename to .sqlx/query-db46b3d7d5af874af5981ec8beb210085a115f7d5900802ade79722b0c4ed560.json index 5070d937..46774271 100644 --- a/.sqlx/query-6f75552f083ab3b9cbed52e38a9f9c59e36aaecd3c70500731ed7e6ca6736de5.json +++ b/.sqlx/query-db46b3d7d5af874af5981ec8beb210085a115f7d5900802ade79722b0c4ed560.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `collection_id`,\n `did_id`,\n `metadata_collection_id`,\n `visible`,\n `name`,\n `icon`\n FROM `nft_collections` INDEXED BY `col_named`\n WHERE `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `collection_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT `collection_id`, `did_id`, `metadata_collection_id`, `visible`, `name`, `icon`\n FROM `collections` INDEXED BY `col_name`\n WHERE `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `collection_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -46,5 +46,5 @@ true ] }, - "hash": "6f75552f083ab3b9cbed52e38a9f9c59e36aaecd3c70500731ed7e6ca6736de5" + "hash": "db46b3d7d5af874af5981ec8beb210085a115f7d5900802ade79722b0c4ed560" } diff --git a/.sqlx/query-dfcde1ea41ddc345990e32827c02aaa2452c0e2ae62b455d351e22e34db387f0.json b/.sqlx/query-dfcde1ea41ddc345990e32827c02aaa2452c0e2ae62b455d351e22e34db387f0.json deleted file mode 100644 index 874580f4..00000000 --- a/.sqlx/query-dfcde1ea41ddc345990e32827c02aaa2452c0e2ae62b455d351e22e34db387f0.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n cs.parent_coin_id, cs.puzzle_hash, cs.amount,\n cs.transaction_id AS create_transaction_id, cs.created_height,\n did.parent_parent_coin_id, did.parent_inner_puzzle_hash, did.parent_amount,\n did.launcher_id, did.recovery_list_hash, did.num_verifications_required,\n did.metadata, did.p2_puzzle_hash, name, visible\n FROM `coin_states` AS cs\n INNER JOIN `did_coins` AS did ON cs.coin_id = did.coin_id\n INNER JOIN `dids` ON did.launcher_id = dids.launcher_id\n LEFT JOIN `transaction_spends` ON cs.coin_id = transaction_spends.coin_id\n WHERE cs.spent_height IS NULL\n AND transaction_spends.transaction_id IS NULL\n ", - "describe": { - "columns": [ - { - "name": "parent_coin_id", - "ordinal": 0, - "type_info": "Blob" - }, - { - "name": "puzzle_hash", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "amount", - "ordinal": 2, - "type_info": "Blob" - }, - { - "name": "create_transaction_id", - "ordinal": 3, - "type_info": "Blob" - }, - { - "name": "created_height", - "ordinal": 4, - "type_info": "Integer" - }, - { - "name": "parent_parent_coin_id", - "ordinal": 5, - "type_info": "Blob" - }, - { - "name": "parent_inner_puzzle_hash", - "ordinal": 6, - "type_info": "Blob" - }, - { - "name": "parent_amount", - "ordinal": 7, - "type_info": "Blob" - }, - { - "name": "launcher_id", - "ordinal": 8, - "type_info": "Blob" - }, - { - "name": "recovery_list_hash", - "ordinal": 9, - "type_info": "Blob" - }, - { - "name": "num_verifications_required", - "ordinal": 10, - "type_info": "Blob" - }, - { - "name": "metadata", - "ordinal": 11, - "type_info": "Blob" - }, - { - "name": "p2_puzzle_hash", - "ordinal": 12, - "type_info": "Blob" - }, - { - "name": "name", - "ordinal": 13, - "type_info": "Text" - }, - { - "name": "visible", - "ordinal": 14, - "type_info": "Bool" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false, - false, - false, - true, - true, - false, - false, - false, - false, - true, - false, - false, - false, - true, - false - ] - }, - "hash": "dfcde1ea41ddc345990e32827c02aaa2452c0e2ae62b455d351e22e34db387f0" -} diff --git a/.sqlx/query-bb6e5713867c9ff2b4ad68c6d28c695460a9a74d23111af67f80e85df2ccc5d8.json b/.sqlx/query-e87cae330e1ce739c1ddf2cdbf3b5537719edeec73b4d9b10f85b913cff8a03a.json similarity index 51% rename from .sqlx/query-bb6e5713867c9ff2b4ad68c6d28c695460a9a74d23111af67f80e85df2ccc5d8.json rename to .sqlx/query-e87cae330e1ce739c1ddf2cdbf3b5537719edeec73b4d9b10f85b913cff8a03a.json index 52b4127b..351a4919 100644 --- a/.sqlx/query-bb6e5713867c9ff2b4ad68c6d28c695460a9a74d23111af67f80e85df2ccc5d8.json +++ b/.sqlx/query-e87cae330e1ce739c1ddf2cdbf3b5537719edeec73b4d9b10f85b913cff8a03a.json @@ -1,10 +1,10 @@ { "db_name": "SQLite", - "query": "SELECT `launcher_id` FROM `nft_coins` WHERE `coin_id` = ?", + "query": "\n SELECT `coin_id` FROM `transaction_spends` WHERE `transaction_id` = ?\n ", "describe": { "columns": [ { - "name": "launcher_id", + "name": "coin_id", "ordinal": 0, "type_info": "Blob" } @@ -16,5 +16,5 @@ false ] }, - "hash": "bb6e5713867c9ff2b4ad68c6d28c695460a9a74d23111af67f80e85df2ccc5d8" + "hash": "e87cae330e1ce739c1ddf2cdbf3b5537719edeec73b4d9b10f85b913cff8a03a" } diff --git a/.sqlx/query-8ff157723ba335104fe877458b242b3755b8f95063daed3cf990617e766cb66c.json b/.sqlx/query-f60979af832a6d514b6249708dfdeb44da635c7ad061dd532bbc4066c164c162.json similarity index 58% rename from .sqlx/query-8ff157723ba335104fe877458b242b3755b8f95063daed3cf990617e766cb66c.json rename to .sqlx/query-f60979af832a6d514b6249708dfdeb44da635c7ad061dd532bbc4066c164c162.json index cc4e51a6..28c85851 100644 --- a/.sqlx/query-8ff157723ba335104fe877458b242b3755b8f95063daed3cf990617e766cb66c.json +++ b/.sqlx/query-f60979af832a6d514b6249708dfdeb44da635c7ad061dd532bbc4066c164c162.json @@ -1,51 +1,36 @@ { "db_name": "SQLite", - "query": "\n SELECT *\n FROM `coin_states`\n WHERE `synced` = 0 AND `created_height` IS NOT NULL\n ORDER BY `spent_height` ASC\n LIMIT ?\n ", + "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `created_height`, `spent_height`, `transaction_id`\n FROM `coin_states`\n WHERE `synced` = 0 AND `created_height` IS NOT NULL\n ORDER BY `spent_height` ASC\n LIMIT ?\n ", "describe": { "columns": [ { - "name": "coin_id", + "name": "parent_coin_id", "ordinal": 0, "type_info": "Blob" }, { - "name": "parent_coin_id", + "name": "puzzle_hash", "ordinal": 1, "type_info": "Blob" }, { - "name": "puzzle_hash", + "name": "amount", "ordinal": 2, "type_info": "Blob" }, { - "name": "amount", + "name": "created_height", "ordinal": 3, - "type_info": "Blob" + "type_info": "Integer" }, { "name": "spent_height", "ordinal": 4, "type_info": "Integer" }, - { - "name": "created_height", - "ordinal": 5, - "type_info": "Integer" - }, - { - "name": "hint", - "ordinal": 6, - "type_info": "Blob" - }, - { - "name": "synced", - "ordinal": 7, - "type_info": "Bool" - }, { "name": "transaction_id", - "ordinal": 8, + "ordinal": 5, "type_info": "Blob" } ], @@ -56,13 +41,10 @@ false, false, false, - false, true, true, - true, - false, true ] }, - "hash": "8ff157723ba335104fe877458b242b3755b8f95063daed3cf990617e766cb66c" + "hash": "f60979af832a6d514b6249708dfdeb44da635c7ad061dd532bbc4066c164c162" } diff --git a/.sqlx/query-fc2bc853db0bb5424bb821675c6412ab4fe23d6937fa683075129603f9fc708b.json b/.sqlx/query-fd9f732f3a7ed809b9d4c2ededebdeeb3765c89c9fc78576f447c646c46f445c.json similarity index 56% rename from .sqlx/query-fc2bc853db0bb5424bb821675c6412ab4fe23d6937fa683075129603f9fc708b.json rename to .sqlx/query-fd9f732f3a7ed809b9d4c2ededebdeeb3765c89c9fc78576f447c646c46f445c.json index 7c3cb321..e1af1b05 100644 --- a/.sqlx/query-fc2bc853db0bb5424bb821675c6412ab4fe23d6937fa683075129603f9fc708b.json +++ b/.sqlx/query-fd9f732f3a7ed809b9d4c2ededebdeeb3765c89c9fc78576f447c646c46f445c.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT COUNT(*) AS `count` FROM `nft_collections`\n WHERE `visible` = 1\n ", + "query": "\n SELECT COUNT(*) AS `count` FROM `collections`\n WHERE `visible` = 1\n ", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "fc2bc853db0bb5424bb821675c6412ab4fe23d6937fa683075129603f9fc708b" + "hash": "fd9f732f3a7ed809b9d4c2ededebdeeb3765c89c9fc78576f447c646c46f445c" } diff --git a/.sqlx/query-f73e22a087da79c84fad58ae25cfe13414ebb751a0cc82c611f035f6b97b8e27.json b/.sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json similarity index 84% rename from .sqlx/query-f73e22a087da79c84fad58ae25cfe13414ebb751a0cc82c611f035f6b97b8e27.json rename to .sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json index 9920ff32..821357ef 100644 --- a/.sqlx/query-f73e22a087da79c84fad58ae25cfe13414ebb751a0cc82c611f035f6b97b8e27.json +++ b/.sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_named`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -82,5 +82,5 @@ true ] }, - "hash": "f73e22a087da79c84fad58ae25cfe13414ebb751a0cc82c611f035f6b97b8e27" + "hash": "fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f" } From 8ab6592ac68c7fe453f001fe0964ca31b92e42ee Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 23:35:28 -0500 Subject: [PATCH 14/21] Cleanup --- crates/sage-database/src/primitives/cats.rs | 110 +++++++------------- crates/sage-database/src/rows/cat.rs | 3 + crates/sage-wallet/src/database.rs | 1 + crates/sage-wallet/src/queues/cat_queue.rs | 3 +- migrations/0001_setup.sql | 2 + src-tauri/src/commands/actions.rs | 3 +- src-tauri/src/commands/transactions.rs | 3 +- 7 files changed, 51 insertions(+), 74 deletions(-) diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 56976320..0f0e62dd 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -3,23 +3,19 @@ use chia_wallet_sdk::Cat; use sqlx::SqliteExecutor; use crate::{ - into_row, to_bytes, to_bytes32, CatCoinRow, CatCoinSql, CatRow, CoinStateRow, CoinStateSql, - Database, DatabaseTx, FullCatCoinSql, Result, + into_row, to_bytes, to_bytes32, CatCoinRow, CatCoinSql, CatRow, CatSql, CoinStateRow, + CoinStateSql, Database, DatabaseTx, FullCatCoinSql, Result, }; impl Database { - pub async fn maybe_insert_cat(&self, row: CatRow) -> Result<()> { - maybe_insert_cat(&self.pool, row).await + pub async fn insert_cat(&self, row: CatRow) -> Result<()> { + insert_cat(&self.pool, row).await } pub async fn update_cat(&self, row: CatRow) -> Result<()> { update_cat(&self.pool, row).await } - pub async fn delete_cat(&self, asset_id: Bytes32) -> Result<()> { - delete_cat(&self.pool, asset_id).await - } - pub async fn cats(&self) -> Result> { cats(&self.pool).await } @@ -28,8 +24,8 @@ impl Database { cat(&self.pool, asset_id).await } - pub async fn unidentified_cat(&self) -> Result> { - unidentified_cat(&self.pool).await + pub async fn unfetched_cat(&self) -> Result> { + unfetched_cat(&self.pool).await } pub async fn spendable_cat_coins(&self, asset_id: Bytes32) -> Result> { @@ -43,6 +39,10 @@ impl Database { pub async fn cat_coin(&self, coin_id: Bytes32) -> Result> { cat_coin(&self.pool, coin_id).await } + + pub async fn refetch_cat(&self, asset_id: Bytes32) -> Result<()> { + refetch_cat(&self.pool, asset_id).await + } } impl<'a> DatabaseTx<'a> { @@ -68,7 +68,7 @@ impl<'a> DatabaseTx<'a> { } } -async fn maybe_insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { +async fn insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { let asset_id = row.asset_id.as_ref(); sqlx::query!( @@ -120,64 +120,28 @@ async fn update_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { Ok(()) } -async fn delete_cat(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result<()> { - let asset_id = asset_id.as_ref(); - - sqlx::query!( - " - DELETE FROM `cats` WHERE `asset_id` = ? - ", - asset_id - ) - .execute(conn) - .await?; - - Ok(()) -} - async fn cats(conn: impl SqliteExecutor<'_>) -> Result> { - let rows = sqlx::query!( + let rows = sqlx::query_as!( + CatSql, " - SELECT - `asset_id`, - `name`, - `ticker`, - `description`, - `icon`, - `visible` - FROM `cats` + SELECT `asset_id`, `name`, `ticker`, `description`, `icon`, `visible`, `fetched` + FROM `cats` INDEXED BY `cat_name` ORDER BY `name` ASC, `asset_id` ASC " ) .fetch_all(conn) .await?; - rows.into_iter() - .map(|row| { - Ok(CatRow { - asset_id: to_bytes32(&row.asset_id)?, - name: row.name, - ticker: row.ticker, - description: row.description, - icon: row.icon, - visible: row.visible, - }) - }) - .collect() + rows.into_iter().map(into_row).collect() } async fn cat(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result> { let asset_id = asset_id.as_ref(); - let row = sqlx::query!( + let row = sqlx::query_as!( + CatSql, " - SELECT - `asset_id`, - `name`, - `ticker`, - `description`, - `icon`, - `visible` + SELECT `asset_id`, `name`, `ticker`, `description`, `icon`, `visible`, `fetched` FROM `cats` WHERE `asset_id` = ? ", @@ -186,24 +150,13 @@ async fn cat(conn: impl SqliteExecutor<'_>, asset_id: Bytes32) -> Result) -> Result> { +async fn unfetched_cat(conn: impl SqliteExecutor<'_>) -> Result> { let rows = sqlx::query!( " - SELECT `asset_id` FROM `cat_coins` - WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `cats`) + SELECT `asset_id` FROM `cats` WHERE `fetched` = 0 LIMIT 1 " ) @@ -264,7 +217,7 @@ async fn spendable_cat_coins( SELECT cs.`parent_coin_id`, cs.`puzzle_hash`, cs.`amount`, `p2_puzzle_hash`, `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount` - FROM `cat_coins` + FROM `cat_coins` INDEXED BY `cat_asset_id` INNER JOIN `coin_states` AS cs ON `cat_coins`.`coin_id` = cs.`coin_id` LEFT JOIN `transaction_spends` ON cs.`coin_id` = `transaction_spends`.`coin_id` WHERE `cat_coins`.`asset_id` = ? @@ -312,7 +265,7 @@ async fn cat_coin_states( CoinStateSql, " SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id` - FROM `cat_coins` + FROM `cat_coins` INDEXED BY `cat_asset_id` INNER JOIN `coin_states` ON `coin_states`.coin_id = `cat_coins`.coin_id WHERE `asset_id` = ? ", @@ -345,3 +298,18 @@ async fn cat_coin(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result, asset_id: Bytes32) -> Result<()> { + let asset_id = asset_id.as_ref(); + + sqlx::query!( + " + UPDATE `cats` SET `fetched` = 0 WHERE `asset_id` = ? + ", + asset_id + ) + .execute(conn) + .await?; + + Ok(()) +} diff --git a/crates/sage-database/src/rows/cat.rs b/crates/sage-database/src/rows/cat.rs index f3b09b78..ad52c4b2 100644 --- a/crates/sage-database/src/rows/cat.rs +++ b/crates/sage-database/src/rows/cat.rs @@ -11,6 +11,7 @@ pub(crate) struct CatSql { pub description: Option, pub icon: Option, pub visible: bool, + pub fetched: bool, } #[derive(Debug, Clone)] @@ -21,6 +22,7 @@ pub struct CatRow { pub description: Option, pub icon: Option, pub visible: bool, + pub fetched: bool, } impl IntoRow for CatSql { @@ -34,6 +36,7 @@ impl IntoRow for CatSql { description: self.description.clone(), icon: self.icon.clone(), visible: self.visible, + fetched: self.fetched, }) } } diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index 8df1e01d..b9f090e4 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -172,6 +172,7 @@ pub async fn insert_puzzle( pub async fn delete_puzzle(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { tx.delete_nft(coin_id).await?; tx.delete_did(coin_id).await?; + Ok(()) } diff --git a/crates/sage-wallet/src/queues/cat_queue.rs b/crates/sage-wallet/src/queues/cat_queue.rs index 6f052760..54736202 100644 --- a/crates/sage-wallet/src/queues/cat_queue.rs +++ b/crates/sage-wallet/src/queues/cat_queue.rs @@ -48,7 +48,7 @@ impl CatQueue { } async fn process_batch(&self) -> Result<(), WalletError> { - let Some(asset_id) = self.db.unidentified_cat().await? else { + let Some(asset_id) = self.db.unfetched_cat().await? else { return Ok(()); }; @@ -97,6 +97,7 @@ impl CatQueue { description: asset.description, icon: Some(format!("{dexie_image_base_url}/{asset_id}.webp")), visible: true, + fetched: true, }) .await?; diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index 98a56bdd..7fb2408b 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -67,9 +67,11 @@ CREATE TABLE `cats` ( `visible` BOOLEAN NOT NULL, `icon` TEXT, `description` TEXT, + `fetched` BOOLEAN NOT NULL, `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED ); +CREATE INDEX `cat_lookup` ON `cats` (`fetched`); CREATE INDEX `cat_name` ON `cats` (`visible` DESC, `is_named` DESC, `name` ASC, `asset_id` ASC); CREATE TABLE `cat_coins` ( diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index 7fdd9a55..cf79f8e7 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -19,7 +19,7 @@ pub async fn remove_cat_info(state: State<'_, AppState>, asset_id: String) -> Re .try_into() .map_err(|_| Error::invalid_asset_id())?; - wallet.db.delete_cat(asset_id.into()).await?; + wallet.db.refetch_cat(asset_id.into()).await?; Ok(()) } @@ -43,6 +43,7 @@ pub async fn update_cat_info(state: State<'_, AppState>, record: CatRecord) -> R ticker: record.ticker, icon: record.icon_url, visible: record.visible, + fetched: true, }) .await?; diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 0d08f785..4283d038 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -267,13 +267,14 @@ pub async fn issue_cat( wallet .db - .maybe_insert_cat(CatRow { + .insert_cat(CatRow { asset_id, name: Some(name), ticker: Some(ticker), description: None, icon: None, visible: true, + fetched: true, }) .await?; From 1f47d23967497c96638947e9f3d620b579d3d216 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Sun, 3 Nov 2024 23:59:51 -0500 Subject: [PATCH 15/21] More query BS --- ...295f7116bbc3674f64a2ae680aef0fa33256.json} | 4 +- ...c4dddf34afffa9ab95e17eaebf2eac7cc1ca6.json | 12 +++++ ...daf0b4f0aed18e288f55c7e0963f187e1500.json} | 10 +++- ...30029ab451f22f4adbc3672deb2982b757955.json | 12 ----- ...9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6.json} | 10 +++- ...275d7abafd101b48cbc32ecd53b76c8016cf.json} | 4 +- ...f433128d7f5144e30c4b5371e0a87dd5caabf.json | 12 +++++ ...e6d3552d84b6975c7758e46a11f39c0081c4.json} | 4 +- ...f09c14b738a16057000572f3331210fe40477.json | 12 ----- crates/sage-database/src/primitives/cats.rs | 10 ++-- crates/sage-database/src/primitives/dids.rs | 53 +++++-------------- crates/sage-wallet/src/database.rs | 9 +++- src-tauri/src/commands/actions.rs | 8 ++- src-tauri/src/commands/data.rs | 2 +- src-tauri/src/commands/transactions.rs | 8 ++- 15 files changed, 85 insertions(+), 85 deletions(-) rename .sqlx/{query-15dd76d270dedad79549058ce3d733cf121b3d2b1298abf5fb73cede00f464c3.json => query-128ef3d7d903189eea35f141e1fa295f7116bbc3674f64a2ae680aef0fa33256.json} (51%) create mode 100644 .sqlx/query-18d3d050762544ca73050ff24bec4dddf34afffa9ab95e17eaebf2eac7cc1ca6.json rename .sqlx/{query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json => query-2698bed1b4a0d3d753b8357d3debdaf0b4f0aed18e288f55c7e0963f187e1500.json} (64%) delete mode 100644 .sqlx/query-5539bfb49fb06b8bbb53b750cff30029ab451f22f4adbc3672deb2982b757955.json rename .sqlx/{query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json => query-65c223a91702ea7b5e4e4483f1dd9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6.json} (68%) rename .sqlx/{query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json => query-ccf24ae534c77cdbfa1e6030ad4e275d7abafd101b48cbc32ecd53b76c8016cf.json} (79%) create mode 100644 .sqlx/query-d2defd73743b149b96d3e5e9597f433128d7f5144e30c4b5371e0a87dd5caabf.json rename .sqlx/{query-653a506c85f4efa9fd0c36dd496b617baa99229605a2ee9f0a1d43f3e723279c.json => query-d3303c8a5c766f3eefcb0ab2b3f3e6d3552d84b6975c7758e46a11f39c0081c4.json} (69%) delete mode 100644 .sqlx/query-ecbce622de80e215612a9e7edb0f09c14b738a16057000572f3331210fe40477.json diff --git a/.sqlx/query-15dd76d270dedad79549058ce3d733cf121b3d2b1298abf5fb73cede00f464c3.json b/.sqlx/query-128ef3d7d903189eea35f141e1fa295f7116bbc3674f64a2ae680aef0fa33256.json similarity index 51% rename from .sqlx/query-15dd76d270dedad79549058ce3d733cf121b3d2b1298abf5fb73cede00f464c3.json rename to .sqlx/query-128ef3d7d903189eea35f141e1fa295f7116bbc3674f64a2ae680aef0fa33256.json index b3f1496b..67f65e1b 100644 --- a/.sqlx/query-15dd76d270dedad79549058ce3d733cf121b3d2b1298abf5fb73cede00f464c3.json +++ b/.sqlx/query-128ef3d7d903189eea35f141e1fa295f7116bbc3674f64a2ae680aef0fa33256.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT `asset_id` FROM `cat_coins`\n WHERE `asset_id` NOT IN (SELECT `asset_id` FROM `cats`)\n LIMIT 1\n ", + "query": "\n SELECT `asset_id` FROM `cats` WHERE `fetched` = 0\n LIMIT 1\n ", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "15dd76d270dedad79549058ce3d733cf121b3d2b1298abf5fb73cede00f464c3" + "hash": "128ef3d7d903189eea35f141e1fa295f7116bbc3674f64a2ae680aef0fa33256" } diff --git a/.sqlx/query-18d3d050762544ca73050ff24bec4dddf34afffa9ab95e17eaebf2eac7cc1ca6.json b/.sqlx/query-18d3d050762544ca73050ff24bec4dddf34afffa9ab95e17eaebf2eac7cc1ca6.json new file mode 100644 index 00000000..3804c5d9 --- /dev/null +++ b/.sqlx/query-18d3d050762544ca73050ff24bec4dddf34afffa9ab95e17eaebf2eac7cc1ca6.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n INSERT OR IGNORE INTO `cat_coins` (\n `coin_id`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `p2_puzzle_hash`,\n `asset_id`\n )\n VALUES (?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "18d3d050762544ca73050ff24bec4dddf34afffa9ab95e17eaebf2eac7cc1ca6" +} diff --git a/.sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json b/.sqlx/query-2698bed1b4a0d3d753b8357d3debdaf0b4f0aed18e288f55c7e0963f187e1500.json similarity index 64% rename from .sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json rename to .sqlx/query-2698bed1b4a0d3d753b8357d3debdaf0b4f0aed18e288f55c7e0963f187e1500.json index d70a8869..45a0cb1a 100644 --- a/.sqlx/query-a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04.json +++ b/.sqlx/query-2698bed1b4a0d3d753b8357d3debdaf0b4f0aed18e288f55c7e0963f187e1500.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n FROM `cats`\n ORDER BY `name` ASC, `asset_id` ASC\n ", + "query": "\n SELECT `asset_id`, `name`, `ticker`, `description`, `icon`, `visible`, `fetched`\n FROM `cats` INDEXED BY `cat_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `asset_id` ASC\n ", "describe": { "columns": [ { @@ -32,6 +32,11 @@ "name": "visible", "ordinal": 5, "type_info": "Bool" + }, + { + "name": "fetched", + "ordinal": 6, + "type_info": "Bool" } ], "parameters": { @@ -43,8 +48,9 @@ true, true, true, + false, false ] }, - "hash": "a4c0ef8cceafaa3b340918b21eeb661e54fe2e09e49a4173fc3424edad610f04" + "hash": "2698bed1b4a0d3d753b8357d3debdaf0b4f0aed18e288f55c7e0963f187e1500" } diff --git a/.sqlx/query-5539bfb49fb06b8bbb53b750cff30029ab451f22f4adbc3672deb2982b757955.json b/.sqlx/query-5539bfb49fb06b8bbb53b750cff30029ab451f22f4adbc3672deb2982b757955.json deleted file mode 100644 index 5d7c3be3..00000000 --- a/.sqlx/query-5539bfb49fb06b8bbb53b750cff30029ab451f22f4adbc3672deb2982b757955.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n REPLACE INTO `cat_coins` (\n `coin_id`,\n `parent_parent_coin_id`,\n `parent_inner_puzzle_hash`,\n `parent_amount`,\n `p2_puzzle_hash`,\n `asset_id`\n )\n VALUES (?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "5539bfb49fb06b8bbb53b750cff30029ab451f22f4adbc3672deb2982b757955" -} diff --git a/.sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json b/.sqlx/query-65c223a91702ea7b5e4e4483f1dd9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6.json similarity index 68% rename from .sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json rename to .sqlx/query-65c223a91702ea7b5e4e4483f1dd9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6.json index 4b58e0fa..65484e6f 100644 --- a/.sqlx/query-1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110.json +++ b/.sqlx/query-65c223a91702ea7b5e4e4483f1dd9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n FROM `cats`\n WHERE `asset_id` = ?\n ", + "query": "\n SELECT `asset_id`, `name`, `ticker`, `description`, `icon`, `visible`, `fetched`\n FROM `cats`\n WHERE `asset_id` = ?\n ", "describe": { "columns": [ { @@ -32,6 +32,11 @@ "name": "visible", "ordinal": 5, "type_info": "Bool" + }, + { + "name": "fetched", + "ordinal": 6, + "type_info": "Bool" } ], "parameters": { @@ -43,8 +48,9 @@ true, true, true, + false, false ] }, - "hash": "1ab2ee2bb15de4687ce53f8578f17b87aa72b444b6add6860c7b43446c000110" + "hash": "65c223a91702ea7b5e4e4483f1dd9ae3f3f7f2c42a7776b6ada4e6f51dd25fb6" } diff --git a/.sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json b/.sqlx/query-ccf24ae534c77cdbfa1e6030ad4e275d7abafd101b48cbc32ecd53b76c8016cf.json similarity index 79% rename from .sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json rename to .sqlx/query-ccf24ae534c77cdbfa1e6030ad4e275d7abafd101b48cbc32ecd53b76c8016cf.json index a5f8a671..3dd6dcec 100644 --- a/.sqlx/query-4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b.json +++ b/.sqlx/query-ccf24ae534c77cdbfa1e6030ad4e275d7abafd101b48cbc32ecd53b76c8016cf.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id`\n FROM `cat_coins`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `cat_coins`.coin_id\n WHERE `asset_id` = ?\n ", + "query": "\n SELECT `parent_coin_id`, `puzzle_hash`, `amount`, `spent_height`, `created_height`, `transaction_id`\n FROM `cat_coins` INDEXED BY `cat_asset_id`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `cat_coins`.coin_id\n WHERE `asset_id` = ?\n ", "describe": { "columns": [ { @@ -46,5 +46,5 @@ true ] }, - "hash": "4c781575943434e23e4e030fd2bff39252f564f3f545da7e9e5b01cc6177f19b" + "hash": "ccf24ae534c77cdbfa1e6030ad4e275d7abafd101b48cbc32ecd53b76c8016cf" } diff --git a/.sqlx/query-d2defd73743b149b96d3e5e9597f433128d7f5144e30c4b5371e0a87dd5caabf.json b/.sqlx/query-d2defd73743b149b96d3e5e9597f433128d7f5144e30c4b5371e0a87dd5caabf.json new file mode 100644 index 00000000..0dd6ce16 --- /dev/null +++ b/.sqlx/query-d2defd73743b149b96d3e5e9597f433128d7f5144e30c4b5371e0a87dd5caabf.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n UPDATE `cats` SET `fetched` = 0 WHERE `asset_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "d2defd73743b149b96d3e5e9597f433128d7f5144e30c4b5371e0a87dd5caabf" +} diff --git a/.sqlx/query-653a506c85f4efa9fd0c36dd496b617baa99229605a2ee9f0a1d43f3e723279c.json b/.sqlx/query-d3303c8a5c766f3eefcb0ab2b3f3e6d3552d84b6975c7758e46a11f39c0081c4.json similarity index 69% rename from .sqlx/query-653a506c85f4efa9fd0c36dd496b617baa99229605a2ee9f0a1d43f3e723279c.json rename to .sqlx/query-d3303c8a5c766f3eefcb0ab2b3f3e6d3552d84b6975c7758e46a11f39c0081c4.json index d3b817b6..a8685fd9 100644 --- a/.sqlx/query-653a506c85f4efa9fd0c36dd496b617baa99229605a2ee9f0a1d43f3e723279c.json +++ b/.sqlx/query-d3303c8a5c766f3eefcb0ab2b3f3e6d3552d84b6975c7758e46a11f39c0081c4.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n cs.`parent_coin_id`, cs.`puzzle_hash`, cs.`amount`, `p2_puzzle_hash`,\n `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount`\n FROM `cat_coins`\n INNER JOIN `coin_states` AS cs ON `cat_coins`.`coin_id` = cs.`coin_id`\n LEFT JOIN `transaction_spends` ON cs.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `cat_coins`.`asset_id` = ?\n AND cs.`spent_height` IS NULL\n AND `transaction_spends`.`coin_id` IS NULL\n AND cs.`transaction_id` IS NULL\n ", + "query": "\n SELECT\n cs.`parent_coin_id`, cs.`puzzle_hash`, cs.`amount`, `p2_puzzle_hash`,\n `parent_parent_coin_id`, `parent_inner_puzzle_hash`, `parent_amount`\n FROM `cat_coins` INDEXED BY `cat_asset_id`\n INNER JOIN `coin_states` AS cs ON `cat_coins`.`coin_id` = cs.`coin_id`\n LEFT JOIN `transaction_spends` ON cs.`coin_id` = `transaction_spends`.`coin_id`\n WHERE `cat_coins`.`asset_id` = ?\n AND cs.`spent_height` IS NULL\n AND `transaction_spends`.`coin_id` IS NULL\n AND cs.`transaction_id` IS NULL\n ", "describe": { "columns": [ { @@ -52,5 +52,5 @@ false ] }, - "hash": "653a506c85f4efa9fd0c36dd496b617baa99229605a2ee9f0a1d43f3e723279c" + "hash": "d3303c8a5c766f3eefcb0ab2b3f3e6d3552d84b6975c7758e46a11f39c0081c4" } diff --git a/.sqlx/query-ecbce622de80e215612a9e7edb0f09c14b738a16057000572f3331210fe40477.json b/.sqlx/query-ecbce622de80e215612a9e7edb0f09c14b738a16057000572f3331210fe40477.json deleted file mode 100644 index 0233f393..00000000 --- a/.sqlx/query-ecbce622de80e215612a9e7edb0f09c14b738a16057000572f3331210fe40477.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM `cats` WHERE `asset_id` = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "ecbce622de80e215612a9e7edb0f09c14b738a16057000572f3331210fe40477" -} diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 0f0e62dd..4006f2ae 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -16,8 +16,8 @@ impl Database { update_cat(&self.pool, row).await } - pub async fn cats(&self) -> Result> { - cats(&self.pool).await + pub async fn cats_by_name(&self) -> Result> { + cats_by_name(&self.pool).await } pub async fn cat(&self, asset_id: Bytes32) -> Result> { @@ -120,13 +120,13 @@ async fn update_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { Ok(()) } -async fn cats(conn: impl SqliteExecutor<'_>) -> Result> { +async fn cats_by_name(conn: impl SqliteExecutor<'_>) -> Result> { let rows = sqlx::query_as!( CatSql, " SELECT `asset_id`, `name`, `ticker`, `description`, `icon`, `visible`, `fetched` FROM `cats` INDEXED BY `cat_name` - ORDER BY `name` ASC, `asset_id` ASC + ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `asset_id` ASC " ) .fetch_all(conn) @@ -182,7 +182,7 @@ async fn insert_cat_coin( sqlx::query!( " - REPLACE INTO `cat_coins` ( + INSERT OR IGNORE INTO `cat_coins` ( `coin_id`, `parent_parent_coin_id`, `parent_inner_puzzle_hash`, diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index 56227fe7..afb0588b 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -11,22 +11,12 @@ use crate::{ }; impl Database { - pub async fn insert_new_did( - &self, - launcher_id: Bytes32, - name: Option, - visible: bool, - ) -> Result<()> { - insert_new_did(&self.pool, launcher_id, name, visible).await + pub async fn insert_did(&self, row: DidRow) -> Result<()> { + insert_did(&self.pool, row).await } - pub async fn update_did( - &self, - launcher_id: Bytes32, - name: Option, - visible: bool, - ) -> Result<()> { - update_did(&self.pool, launcher_id, name, visible).await + pub async fn update_did(&self, row: DidRow) -> Result<()> { + update_did(&self.pool, row).await } pub async fn dids_by_name(&self) -> Result> { @@ -47,13 +37,8 @@ impl Database { } impl<'a> DatabaseTx<'a> { - pub async fn insert_new_did( - &mut self, - launcher_id: Bytes32, - name: Option, - visible: bool, - ) -> Result<()> { - insert_new_did(&mut *self.tx, launcher_id, name, visible).await + pub async fn insert_did(&mut self, row: DidRow) -> Result<()> { + insert_did(&mut *self.tx, row).await } pub async fn insert_did_coin( @@ -70,13 +55,8 @@ impl<'a> DatabaseTx<'a> { } } -async fn insert_new_did( - conn: impl SqliteExecutor<'_>, - launcher_id: Bytes32, - name: Option, - visible: bool, -) -> Result<()> { - let launcher_id = launcher_id.as_ref(); +async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { + let launcher_id = row.launcher_id.as_ref(); sqlx::query!( " @@ -88,8 +68,8 @@ async fn insert_new_did( VALUES (?, ?, ?) ", launcher_id, - name, - visible + row.name, + row.visible ) .execute(conn) .await?; @@ -97,13 +77,8 @@ async fn insert_new_did( Ok(()) } -async fn update_did( - conn: impl SqliteExecutor<'_>, - launcher_id: Bytes32, - name: Option, - visible: bool, -) -> Result<()> { - let launcher_id = launcher_id.as_ref(); +async fn update_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { + let launcher_id = row.launcher_id.as_ref(); sqlx::query!( " @@ -115,8 +90,8 @@ async fn update_did( VALUES (?, ?, ?) ", launcher_id, - name, - visible + row.name, + row.visible ) .execute(conn) .await?; diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index b9f090e4..efa7986e 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -2,7 +2,7 @@ use chia::{ bls::Signature, protocol::{Bytes32, CoinState}, }; -use sage_database::{DatabaseTx, NftRow}; +use sage_database::{DatabaseTx, DidRow, NftRow}; use crate::{compute_nft_info, ChildKind, Transaction, WalletError}; @@ -74,7 +74,12 @@ pub async fn insert_puzzle( info, } => { tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; - tx.insert_new_did(info.launcher_id, None, true).await?; + tx.insert_did(DidRow { + launcher_id: info.launcher_id, + name: None, + visible: true, + }) + .await?; tx.insert_did_coin(coin_id, lineage_proof, info).await?; } ChildKind::Nft { diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index cf79f8e7..34012187 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -1,6 +1,6 @@ use chia_wallet_sdk::decode_address; use sage_api::CatRecord; -use sage_database::CatRow; +use sage_database::{CatRow, DidRow}; use specta::specta; use tauri::{command, State}; @@ -69,7 +69,11 @@ pub async fn update_did( wallet .db - .update_did(launcher_id.into(), name, visible) + .update_did(DidRow { + launcher_id: launcher_id.into(), + name, + visible, + }) .await?; Ok(()) diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index fb96fd7a..fcc8a22f 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -166,7 +166,7 @@ pub async fn get_cat_coins( pub async fn get_cats(state: State<'_, AppState>) -> Result> { let state = state.lock().await; let wallet = state.wallet()?; - let cats = wallet.db.cats().await?; + let cats = wallet.db.cats_by_name().await?; let mut records = Vec::with_capacity(cats.len()); diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 4283d038..3bf9e4ae 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -14,7 +14,7 @@ use sage_api::{ Amount, BulkMintNfts, BulkMintNftsResponse, CoinJson, CoinSpendJson, Input, InputKind, Output, SpendBundleJson, TransactionSummary, }; -use sage_database::{CatRow, Database}; +use sage_database::{CatRow, Database, DidRow}; use sage_wallet::{ compute_nft_info, fetch_uris, insert_transaction, ChildKind, CoinKind, Data, SyncCommand, Transaction, Wallet, WalletError, WalletNftMint, @@ -341,7 +341,11 @@ pub async fn create_did( wallet .db - .insert_new_did(did.info.launcher_id, Some(name.clone()), true) + .insert_did(DidRow { + launcher_id: did.info.launcher_id, + name: Some(name.clone()), + visible: true, + }) .await?; let mut confirm_info = ConfirmationInfo::default(); From d960bd0f720ed1ef9ff44a7934b42037893d049d Mon Sep 17 00:00:00 2001 From: Rigidity Date: Mon, 4 Nov 2024 00:00:19 -0500 Subject: [PATCH 16/21] Fix warnings --- crates/sage-database/src/rows.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/sage-database/src/rows.rs b/crates/sage-database/src/rows.rs index 7c242b3d..3bd16039 100644 --- a/crates/sage-database/src/rows.rs +++ b/crates/sage-database/src/rows.rs @@ -16,9 +16,7 @@ pub use collection::*; pub use did::*; pub use did_coin::*; pub use nft::*; -pub use nft_coin::*; -pub use nft_data::*; -pub use nft_uri::*; +pub(crate) use nft_coin::*; use crate::DatabaseError; From 4a011f0d3a539558ce69663095bfafdff0c5dafd Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 5 Nov 2024 13:26:34 -0500 Subject: [PATCH 17/21] temp --- crates/sage-database/src/primitives/cats.rs | 4 + crates/sage-database/src/primitives/dids.rs | 126 ++++++++++++++++-- crates/sage-database/src/primitives/nfts.rs | 12 +- crates/sage-database/src/rows/did.rs | 6 + crates/sage-wallet/src/database.rs | 43 ++++-- crates/sage-wallet/src/queues/puzzle_queue.rs | 9 +- crates/sage-wallet/src/sync_manager.rs | 18 ++- .../src/sync_manager/peer_discovery.rs | 39 ++++-- .../src/sync_manager/peer_state.rs | 5 +- migrations/0001_setup.sql | 13 +- src-tauri/src/commands/actions.rs | 6 + src-tauri/src/commands/data.rs | 2 +- src-tauri/src/commands/settings.rs | 2 +- src-tauri/src/commands/transactions.rs | 8 +- 14 files changed, 230 insertions(+), 63 deletions(-) diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 4006f2ae..29e9b1dd 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -46,6 +46,10 @@ impl Database { } impl<'a> DatabaseTx<'a> { + pub async fn insert_cat(&mut self, row: CatRow) -> Result<()> { + insert_cat(&mut *self.tx, row).await + } + pub async fn insert_cat_coin( &mut self, coin_id: Bytes32, diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index afb0588b..1ba5bc6e 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -23,8 +23,12 @@ impl Database { dids_by_name(&self.pool).await } - pub async fn did_coin_info(&self, did_id: Bytes32) -> Result> { - did_coin_info(&self.pool, did_id).await + pub async fn did(&self, launcher_id: Bytes32) -> Result> { + did(&self.pool, launcher_id).await + } + + pub async fn did_coin_info(&self, coin_id: Bytes32) -> Result> { + did_coin_info(&self.pool, coin_id).await } pub async fn spendable_did(&self, did_id: Bytes32) -> Result>> { @@ -34,6 +38,10 @@ impl Database { pub async fn did_name(&self, launcher_id: Bytes32) -> Result> { did_name(&self.pool, launcher_id).await } + + pub async fn set_future_did_name(&self, launcher_id: Bytes32, name: String) -> Result<()> { + set_future_did_name(&self.pool, launcher_id, name).await + } } impl<'a> DatabaseTx<'a> { @@ -53,23 +61,36 @@ impl<'a> DatabaseTx<'a> { pub async fn delete_did(&mut self, coin_id: Bytes32) -> Result<()> { delete_did(&mut *self.tx, coin_id).await } + + pub async fn delete_future_did_name(&mut self, launcher_id: Bytes32) -> Result<()> { + delete_future_did_name(&mut *self.tx, launcher_id).await + } + + pub async fn get_future_did_name(&mut self, launcher_id: Bytes32) -> Result> { + get_future_did_name(&mut *self.tx, launcher_id).await + } } async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { let launcher_id = row.launcher_id.as_ref(); + let coin_id = row.coin_id.as_ref(); sqlx::query!( " INSERT OR IGNORE INTO `dids` ( `launcher_id`, + `coin_id`, `name`, - `visible` + `visible`, + `created_height` ) - VALUES (?, ?, ?) + VALUES (?, ?, ?, ?, ?) ", launcher_id, + coin_id, row.name, - row.visible + row.visible, + row.created_height ) .execute(conn) .await?; @@ -79,19 +100,24 @@ async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { async fn update_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { let launcher_id = row.launcher_id.as_ref(); + let coin_id = row.coin_id.as_ref(); sqlx::query!( " REPLACE INTO `dids` ( `launcher_id`, + `coin_id`, `name`, - `visible` + `visible`, + `created_height` ) - VALUES (?, ?, ?) + VALUES (?, ?, ?, ?, ?) ", launcher_id, + coin_id, row.name, - row.visible + row.visible, + row.created_height ) .execute(conn) .await?; @@ -152,9 +178,9 @@ async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { sqlx::query_as!( DidSql, " - SELECT `launcher_id`, `name`, `visible` + SELECT `launcher_id`, `coin_id`, `name`, `visible`, `created_height` FROM `dids` INDEXED BY `did_name` - ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC " ) .fetch_all(conn) @@ -164,11 +190,29 @@ async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { .collect() } +async fn did(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result> { + let launcher_id = launcher_id.as_ref(); + + sqlx::query_as!( + DidSql, + " + SELECT `launcher_id`, `coin_id`, `name`, `visible`, `created_height` + FROM `dids` + WHERE `launcher_id` = ? + ", + launcher_id + ) + .fetch_optional(conn) + .await? + .map(into_row) + .transpose() +} + async fn did_coin_info( conn: impl SqliteExecutor<'_>, - did_id: Bytes32, + coin_id: Bytes32, ) -> Result> { - let did_id = did_id.as_ref(); + let coin_id = coin_id.as_ref(); let Some(sql) = sqlx::query_as!( DidCoinInfoSql, @@ -177,9 +221,9 @@ async fn did_coin_info( `did_coins`.`coin_id`, `amount`, `p2_puzzle_hash`, `created_height`, `transaction_id` FROM `did_coins` INNER JOIN `coin_states` ON `coin_states`.coin_id = `did_coins`.coin_id - WHERE `launcher_id` = ? + WHERE `did_coins`.`coin_id` = ? ", - did_id + coin_id ) .fetch_optional(conn) .await? @@ -258,3 +302,57 @@ async fn delete_did(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<( Ok(()) } + +async fn set_future_did_name( + conn: impl SqliteExecutor<'_>, + launcher_id: Bytes32, + name: String, +) -> Result<()> { + let launcher_id = launcher_id.as_ref(); + + sqlx::query!( + " + REPLACE INTO `future_did_names` (`launcher_id`, `name`) + VALUES (?, ?) + ", + launcher_id, + name + ) + .execute(conn) + .await?; + + Ok(()) +} + +async fn get_future_did_name( + conn: impl SqliteExecutor<'_>, + launcher_id: Bytes32, +) -> Result> { + let launcher_id = launcher_id.as_ref(); + + Ok(sqlx::query!( + " + SELECT `name` FROM `future_did_names` + WHERE `launcher_id` = ? + ", + launcher_id + ) + .fetch_optional(conn) + .await? + .map(|row| row.name)) +} + +async fn delete_future_did_name(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result<()> { + let launcher_id = launcher_id.as_ref(); + + sqlx::query!( + " + DELETE FROM `future_did_names` WHERE `launcher_id` = ? + ", + launcher_id + ) + .execute(conn) + .await?; + + Ok(()) +} diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index e6ab12d9..ebc58220 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -768,7 +768,7 @@ async fn nfts_visible_named( " SELECT * FROM `nfts` INDEXED BY `nft_name` WHERE `visible` = 1 - ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", limit, @@ -809,7 +809,7 @@ async fn nfts_named(conn: impl SqliteExecutor<'_>, limit: u32, offset: u32) -> R NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_name` - ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", limit, @@ -857,7 +857,7 @@ async fn collection_nfts_visible_named( " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? AND `visible` = 1 - ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", collection_id, @@ -911,7 +911,7 @@ async fn collection_nfts_named( " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` = ? - ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", collection_id, @@ -962,7 +962,7 @@ async fn no_collection_nfts_visible_named( " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL AND `visible` = 1 - ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", limit, @@ -1008,7 +1008,7 @@ async fn no_collection_nfts_named( " SELECT * FROM `nfts` INDEXED BY `nft_col_name` WHERE `collection_id` IS NULL - ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC + ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", limit, diff --git a/crates/sage-database/src/rows/did.rs b/crates/sage-database/src/rows/did.rs index 29561c25..ea577941 100644 --- a/crates/sage-database/src/rows/did.rs +++ b/crates/sage-database/src/rows/did.rs @@ -6,15 +6,19 @@ use super::IntoRow; pub(crate) struct DidSql { pub launcher_id: Vec, + pub coin_id: Vec, pub name: Option, pub visible: bool, + pub created_height: Option, } #[derive(Debug, Clone)] pub struct DidRow { pub launcher_id: Bytes32, + pub coin_id: Bytes32, pub name: Option, pub visible: bool, + pub created_height: Option, } impl IntoRow for DidSql { @@ -23,8 +27,10 @@ impl IntoRow for DidSql { fn into_row(self) -> Result { Ok(DidRow { launcher_id: to_bytes32(&self.launcher_id)?, + coin_id: to_bytes32(&self.coin_id)?, name: self.name, visible: self.visible, + created_height: self.created_height.map(TryInto::try_into).transpose()?, }) } } diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index efa7986e..09c76ea2 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -2,7 +2,7 @@ use chia::{ bls::Signature, protocol::{Bytes32, CoinState}, }; -use sage_database::{DatabaseTx, DidRow, NftRow}; +use sage_database::{CatRow, DatabaseTx, DidRow, NftRow}; use crate::{compute_nft_info, ChildKind, Transaction, WalletError}; @@ -66,6 +66,16 @@ pub async fn insert_puzzle( p2_puzzle_hash, } => { tx.sync_coin(coin_id, Some(p2_puzzle_hash)).await?; + tx.insert_cat(CatRow { + asset_id, + name: None, + ticker: None, + description: None, + icon: None, + visible: true, + fetched: false, + }) + .await?; tx.insert_cat_coin(coin_id, lineage_proof, p2_puzzle_hash, asset_id) .await?; } @@ -73,14 +83,29 @@ pub async fn insert_puzzle( lineage_proof, info, } => { + let launcher_id = info.launcher_id; + tx.sync_coin(coin_id, Some(info.p2_puzzle_hash)).await?; + tx.insert_did_coin(coin_id, lineage_proof, info).await?; + + if coin_state.spent_height.is_some() { + return Ok(()); + } + + let name = tx.get_future_did_name(launcher_id).await?; + + if name.is_some() { + tx.delete_future_did_name(launcher_id).await?; + } + tx.insert_did(DidRow { - launcher_id: info.launcher_id, - name: None, + launcher_id, + coin_id, + name, visible: true, + created_height: coin_state.created_height, }) .await?; - tx.insert_did_coin(coin_id, lineage_proof, info).await?; } ChildKind::Nft { lineage_proof, @@ -192,11 +217,13 @@ pub async fn insert_transaction( tx.insert_pending_transaction(transaction_id, aggregated_signature, transaction.fee) .await?; - let inputs: Vec = transaction + for coin_id in transaction .inputs .iter() .map(|input| input.coin_spend.coin.coin_id()) - .collect(); + { + delete_puzzle(tx, coin_id).await?; + } for (index, input) in transaction.inputs.into_iter().enumerate() { tx.insert_transaction_spend(transaction_id, input.coin_spend, index) @@ -233,10 +260,6 @@ pub async fn insert_transaction( } } - for coin_id in inputs { - delete_puzzle(tx, coin_id).await?; - } - Ok(subscriptions) } diff --git a/crates/sage-wallet/src/queues/puzzle_queue.rs b/crates/sage-wallet/src/queues/puzzle_queue.rs index faec518e..43ac36a4 100644 --- a/crates/sage-wallet/src/queues/puzzle_queue.rs +++ b/crates/sage-wallet/src/queues/puzzle_queue.rs @@ -107,10 +107,11 @@ impl PuzzleQueue { coin_id, addr, error ); - self.state - .lock() - .await - .ban(addr.ip(), Duration::from_secs(300)); + self.state.lock().await.ban( + addr.ip(), + Duration::from_secs(300), + "failed puzzle lookup", + ); } } } diff --git a/crates/sage-wallet/src/sync_manager.rs b/crates/sage-wallet/src/sync_manager.rs index 152415ff..06ca4ad9 100644 --- a/crates/sage-wallet/src/sync_manager.rs +++ b/crates/sage-wallet/src/sync_manager.rs @@ -152,7 +152,11 @@ impl SyncManager { SyncCommand::HandleMessage { ip, message } => { if let Err(error) = self.handle_message(ip, message).await { debug!("Failed to handle message from {ip}: {error}"); - self.state.lock().await.ban(ip, Duration::from_secs(300)); + self.state.lock().await.ban( + ip, + Duration::from_secs(300), + "failed to handle message", + ); } } SyncCommand::ConnectPeer { ip, trusted } => { @@ -418,13 +422,21 @@ impl SyncManager { } Ok(Err(error)) => { warn!("Initial wallet sync failed: {error}"); - self.state.lock().await.ban(*ip, Duration::from_secs(300)); + self.state.lock().await.ban( + *ip, + Duration::from_secs(300), + "wallet sync failed", + ); self.initial_wallet_sync = InitialWalletSync::Idle; self.event_sender.send(SyncEvent::Stop).await.ok(); } Err(_timeout) => { warn!("Initial wallet sync timed out"); - self.state.lock().await.ban(*ip, Duration::from_secs(300)); + self.state.lock().await.ban( + *ip, + Duration::from_secs(300), + "wallet sync timed out", + ); self.initial_wallet_sync = InitialWalletSync::Idle; self.event_sender.send(SyncEvent::Stop).await.ok(); } diff --git a/crates/sage-wallet/src/sync_manager/peer_discovery.rs b/crates/sage-wallet/src/sync_manager/peer_discovery.rs index 7a730085..f0d7ad66 100644 --- a/crates/sage-wallet/src/sync_manager/peer_discovery.rs +++ b/crates/sage-wallet/src/sync_manager/peer_discovery.rs @@ -131,7 +131,11 @@ impl SyncManager { for item in response.peer_list { let Some(new_ip) = IpAddr::from_str(&item.host).ok() else { debug!("Invalid IP address in peer list"); - self.state.lock().await.ban(ip, Duration::from_secs(300)); + self.state.lock().await.ban( + ip, + Duration::from_secs(300), + "invalid ip in peer list", + ); break; }; addrs.push(SocketAddr::new(new_ip, self.network.default_port)); @@ -145,7 +149,11 @@ impl SyncManager { } Ok(Err(error)) => { debug!("Failed to request peers from {}: {}", ip, error); - self.state.lock().await.ban(ip, Duration::from_secs(300)); + self.state.lock().await.ban( + ip, + Duration::from_secs(300), + "failed to request peers", + ); } Err(_timeout) => {} } @@ -183,25 +191,28 @@ impl SyncManager { return true; } } else { - self.state - .lock() - .await - .ban(socket_addr.ip(), Duration::from_secs(60 * 10)); + self.state.lock().await.ban( + socket_addr.ip(), + Duration::from_secs(60 * 10), + "could not add peer", + ); } } Ok(Err(error)) => { debug!("Failed to connect to peer {socket_addr}: {error}"); - self.state - .lock() - .await - .ban(socket_addr.ip(), Duration::from_secs(60 * 10)); + self.state.lock().await.ban( + socket_addr.ip(), + Duration::from_secs(60 * 10), + "failed to connect", + ); } Err(_timeout) => { debug!("Connection to peer {socket_addr} timed out"); - self.state - .lock() - .await - .ban(socket_addr.ip(), Duration::from_secs(60 * 10)); + self.state.lock().await.ban( + socket_addr.ip(), + Duration::from_secs(60 * 10), + "connection timed out", + ); } } } diff --git a/crates/sage-wallet/src/sync_manager/peer_state.rs b/crates/sage-wallet/src/sync_manager/peer_state.rs index b0177a40..ed48494b 100644 --- a/crates/sage-wallet/src/sync_manager/peer_state.rs +++ b/crates/sage-wallet/src/sync_manager/peer_state.rs @@ -8,6 +8,7 @@ use chia::protocol::Bytes32; use chia_wallet_sdk::Peer; use itertools::Itertools; use tokio::task::JoinHandle; +use tracing::debug; #[derive(Debug)] pub struct PeerInfo { @@ -70,7 +71,9 @@ impl PeerState { .map(|peer| peer.peer.clone()) } - pub fn ban(&mut self, ip: IpAddr, duration: Duration) { + pub fn ban(&mut self, ip: IpAddr, duration: Duration, message: &str) { + debug!("Banning peer {ip} ({duration:?}): {message}"); + if self.trusted_peers.contains(&ip) { return; } diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index 7fb2408b..52bc9bf1 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -92,10 +92,17 @@ CREATE TABLE `dids` ( `name` TEXT, `visible` BOOLEAN NOT NULL, `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED, + `created_height` INTEGER, + `is_pending` BOOLEAN GENERATED ALWAYS AS (`created_height` IS NULL) STORED, FOREIGN KEY (`coin_id`) REFERENCES `did_coins` (`coin_id`) ON DELETE CASCADE ); -CREATE INDEX `did_name` ON `dids` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `did_name` ON `dids` (`visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); + +CREATE TABLE `future_did_names` ( + `launcher_id` BLOB NOT NULL PRIMARY KEY, + `name` TEXT NOT NULL +); CREATE TABLE `did_coins` ( `coin_id` BLOB NOT NULL PRIMARY KEY, @@ -141,9 +148,9 @@ CREATE TABLE `nfts` ( ); CREATE INDEX `nft_metadata` ON `nfts` (`metadata_hash`); -CREATE INDEX `nft_name` ON `nfts` (`visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_name` ON `nfts` (`visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE INDEX `nft_recent` ON `nfts` (`visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); -CREATE INDEX `nft_col_name` ON `nfts` (`collection_id`, `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_col_name` ON `nfts` (`collection_id`, `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE INDEX `nft_col_recent` ON `nfts` (`collection_id`, `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); CREATE TABLE `nft_coins` ( diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index 34012187..0ee39ba7 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -67,12 +67,18 @@ pub async fn update_did( return Err(Error::invalid_prefix(&prefix)); } + let Some(row) = wallet.db.did(launcher_id.into()).await? else { + return Err(Error::invalid_launcher_id()); + }; + wallet .db .update_did(DidRow { launcher_id: launcher_id.into(), + coin_id: row.coin_id, name, visible, + created_height: row.created_height, }) .await?; diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index fcc8a22f..341ce7a5 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -223,7 +223,7 @@ pub async fn get_dids(state: State<'_, AppState>) -> Result> { let mut records = Vec::new(); for row in wallet.db.dids_by_name().await? { - let Some(did) = wallet.db.did_coin_info(row.launcher_id).await? else { + let Some(did) = wallet.db.did_coin_info(row.coin_id).await? else { continue; }; diff --git a/src-tauri/src/commands/settings.rs b/src-tauri/src/commands/settings.rs index 47cd2c7d..06f6af23 100644 --- a/src-tauri/src/commands/settings.rs +++ b/src-tauri/src/commands/settings.rs @@ -35,7 +35,7 @@ pub async fn remove_peer(state: State<'_, AppState>, ip_addr: IpAddr, ban: bool) let mut peer_state = state.peer_state.lock().await; if ban { - peer_state.ban(ip_addr, Duration::from_secs(60 * 60)); + peer_state.ban(ip_addr, Duration::from_secs(60 * 60), "manually banned"); } else { peer_state.remove_peer(ip_addr); } diff --git a/src-tauri/src/commands/transactions.rs b/src-tauri/src/commands/transactions.rs index 3bf9e4ae..2932a46b 100644 --- a/src-tauri/src/commands/transactions.rs +++ b/src-tauri/src/commands/transactions.rs @@ -14,7 +14,7 @@ use sage_api::{ Amount, BulkMintNfts, BulkMintNftsResponse, CoinJson, CoinSpendJson, Input, InputKind, Output, SpendBundleJson, TransactionSummary, }; -use sage_database::{CatRow, Database, DidRow}; +use sage_database::{CatRow, Database}; use sage_wallet::{ compute_nft_info, fetch_uris, insert_transaction, ChildKind, CoinKind, Data, SyncCommand, Transaction, Wallet, WalletError, WalletNftMint, @@ -341,11 +341,7 @@ pub async fn create_did( wallet .db - .insert_did(DidRow { - launcher_id: did.info.launcher_id, - name: Some(name.clone()), - visible: true, - }) + .set_future_did_name(did.info.launcher_id, name.clone()) .await?; let mut confirm_info = ConfirmationInfo::default(); From 3feb7bcfd8468695bb2cf778c54cf1fa8bb7a1c6 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 5 Nov 2024 13:46:28 -0500 Subject: [PATCH 18/21] Attempt --- crates/sage-database/src/primitives/dids.rs | 67 +++++++++------ crates/sage-database/src/primitives/nfts.rs | 90 ++++++++++----------- crates/sage-database/src/rows/did.rs | 3 + crates/sage-database/src/rows/nft.rs | 3 + crates/sage-wallet/src/database.rs | 13 ++- migrations/0001_setup.sql | 16 ++-- src-tauri/src/commands/actions.rs | 3 +- 7 files changed, 113 insertions(+), 82 deletions(-) diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index 1ba5bc6e..973cb423 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -23,8 +23,8 @@ impl Database { dids_by_name(&self.pool).await } - pub async fn did(&self, launcher_id: Bytes32) -> Result> { - did(&self.pool, launcher_id).await + pub async fn did_row(&self, launcher_id: Bytes32) -> Result> { + did_row(&self.pool, launcher_id).await } pub async fn did_coin_info(&self, coin_id: Bytes32) -> Result> { @@ -58,10 +58,6 @@ impl<'a> DatabaseTx<'a> { insert_did_coin(&mut *self.tx, coin_id, lineage_proof, did_info).await } - pub async fn delete_did(&mut self, coin_id: Bytes32) -> Result<()> { - delete_did(&mut *self.tx, coin_id).await - } - pub async fn delete_future_did_name(&mut self, launcher_id: Bytes32) -> Result<()> { delete_future_did_name(&mut *self.tx, launcher_id).await } @@ -69,6 +65,14 @@ impl<'a> DatabaseTx<'a> { pub async fn get_future_did_name(&mut self, launcher_id: Bytes32) -> Result> { get_future_did_name(&mut *self.tx, launcher_id).await } + + pub async fn did_row_by_coin(&mut self, coin_id: Bytes32) -> Result> { + did_row_by_coin(&mut *self.tx, coin_id).await + } + + pub async fn update_did(&mut self, row: DidRow) -> Result<()> { + update_did(&mut *self.tx, row).await + } } async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { @@ -81,14 +85,16 @@ async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { `launcher_id`, `coin_id`, `name`, + `is_owned`, `visible`, `created_height` ) - VALUES (?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?) ", launcher_id, coin_id, row.name, + row.is_owned, row.visible, row.created_height ) @@ -108,14 +114,16 @@ async fn update_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { `launcher_id`, `coin_id`, `name`, + `is_owned`, `visible`, `created_height` ) - VALUES (?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?) ", launcher_id, coin_id, row.name, + row.is_owned, row.visible, row.created_height ) @@ -178,8 +186,9 @@ async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { sqlx::query_as!( DidSql, " - SELECT `launcher_id`, `coin_id`, `name`, `visible`, `created_height` + SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height` FROM `dids` INDEXED BY `did_name` + WHERE `is_owned` = 1 ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC " ) @@ -190,13 +199,13 @@ async fn dids_by_name(conn: impl SqliteExecutor<'_>) -> Result> { .collect() } -async fn did(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result> { +async fn did_row(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result> { let launcher_id = launcher_id.as_ref(); sqlx::query_as!( DidSql, " - SELECT `launcher_id`, `coin_id`, `name`, `visible`, `created_height` + SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height` FROM `dids` WHERE `launcher_id` = ? ", @@ -208,6 +217,27 @@ async fn did(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result, + coin_id: Bytes32, +) -> Result> { + let coin_id = coin_id.as_ref(); + + sqlx::query_as!( + DidSql, + " + SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height` + FROM `dids` + WHERE `coin_id` = ? + ", + coin_id + ) + .fetch_optional(conn) + .await? + .map(into_row) + .transpose() +} + async fn did_coin_info( conn: impl SqliteExecutor<'_>, coin_id: Bytes32, @@ -288,21 +318,6 @@ async fn did_name(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result Ok(row.name) } -async fn delete_did(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { - let coin_id = coin_id.as_ref(); - - sqlx::query!( - " - DELETE FROM `dids` WHERE `coin_id` = ? - ", - coin_id - ) - .execute(conn) - .await?; - - Ok(()) -} - async fn set_future_did_name( conn: impl SqliteExecutor<'_>, launcher_id: Bytes32, diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index ebc58220..ac6e5533 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -222,8 +222,8 @@ impl<'a> DatabaseTx<'a> { nft_row(&mut *self.tx, launcher_id).await } - pub async fn delete_nft(&mut self, coin_id: Bytes32) -> Result<()> { - delete_nft(&mut *self.tx, coin_id).await + pub async fn nft_row_by_coin(&mut self, coin_id: Bytes32) -> Result> { + nft_row_by_coin(&mut *self.tx, coin_id).await } pub async fn data_hash(&mut self, launcher_id: Bytes32) -> Result> { @@ -398,7 +398,7 @@ async fn nft_count(conn: impl SqliteExecutor<'_>) -> Result { let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` - WHERE `visible` = 1 + WHERE `is_owned` = 1 AND `visible` = 1 " ) .fetch_one(conn) @@ -411,7 +411,7 @@ async fn visible_nft_count(conn: impl SqliteExecutor<'_>) -> Result { let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` - WHERE `visible` = 1 + WHERE `is_owned` = 1 AND `visible` = 1 " ) .fetch_one(conn) @@ -429,7 +429,7 @@ async fn collection_nft_count( let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` = ? AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1 ", collection_id ) @@ -448,7 +448,7 @@ async fn collection_visible_nft_count( let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` = ? AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1 ", collection_id ) @@ -462,7 +462,7 @@ async fn no_collection_nft_count(conn: impl SqliteExecutor<'_>) -> Result { let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` IS NULL AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1 " ) .fetch_one(conn) @@ -475,7 +475,7 @@ async fn no_collection_visible_nft_count(conn: impl SqliteExecutor<'_>) -> Resul let row = sqlx::query!( " SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` IS NULL AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1 " ) .fetch_one(conn) @@ -593,9 +593,10 @@ async fn insert_nft(conn: impl SqliteExecutor<'_>, row: NftRow) -> Result<()> { `visible`, `sensitive_content`, `name`, + `is_owned`, `created_height`, `metadata_hash` - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", launcher_id, coin_id, collection_id, @@ -604,6 +605,7 @@ async fn insert_nft(conn: impl SqliteExecutor<'_>, row: NftRow) -> Result<()> { row.visible, row.sensitive_content, name, + row.is_owned, row.created_height, metadata_hash ) @@ -616,44 +618,36 @@ async fn insert_nft(conn: impl SqliteExecutor<'_>, row: NftRow) -> Result<()> { async fn nft_row(conn: impl SqliteExecutor<'_>, launcher_id: Bytes32) -> Result> { let launcher_id = launcher_id.as_ref(); - let Some(row) = sqlx::query!( + sqlx::query_as!( + NftSql, " - SELECT - `launcher_id`, `coin_id`, `collection_id`, `minter_did`, `owner_did`, - `visible`, `sensitive_content`, `name`, `created_height`, `metadata_hash` - FROM `nfts` - WHERE `launcher_id` = ? + SELECT * FROM `nfts` WHERE `launcher_id` = ? ", launcher_id ) .fetch_optional(conn) .await? - else { - return Ok(None); - }; - - Ok(Some(NftRow { - launcher_id: to_bytes32(&row.launcher_id)?, - coin_id: to_bytes32(&row.coin_id)?, - collection_id: row.collection_id.as_deref().map(to_bytes32).transpose()?, - minter_did: row.minter_did.as_deref().map(to_bytes32).transpose()?, - owner_did: row.owner_did.as_deref().map(to_bytes32).transpose()?, - visible: row.visible, - sensitive_content: row.sensitive_content, - name: row.name, - created_height: row.created_height.map(TryInto::try_into).transpose()?, - metadata_hash: row.metadata_hash.as_deref().map(to_bytes32).transpose()?, - })) + .map(into_row) + .transpose() } -async fn delete_nft(conn: impl SqliteExecutor<'_>, coin_id: Bytes32) -> Result<()> { +async fn nft_row_by_coin( + conn: impl SqliteExecutor<'_>, + coin_id: Bytes32, +) -> Result> { let coin_id = coin_id.as_ref(); - sqlx::query!("DELETE FROM `nfts` WHERE `coin_id` = ?", coin_id) - .execute(conn) - .await?; - - Ok(()) + sqlx::query_as!( + NftSql, + " + SELECT * FROM `nfts` WHERE `coin_id` = ? + ", + coin_id + ) + .fetch_optional(conn) + .await? + .map(into_row) + .transpose() } async fn set_nft_visible( @@ -767,7 +761,7 @@ async fn nfts_visible_named( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_name` - WHERE `visible` = 1 + WHERE `is_owned` = 1 AND `visible` = 1 ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -790,7 +784,7 @@ async fn nfts_visible_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_recent` - WHERE `visible` = 1 + WHERE `is_owned` = 1 AND `visible` = 1 ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -809,6 +803,7 @@ async fn nfts_named(conn: impl SqliteExecutor<'_>, limit: u32, offset: u32) -> R NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_name` + WHERE `is_owned` = 1 ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -831,6 +826,7 @@ async fn nfts_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_recent` + WHERE `is_owned` = 1 ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -856,7 +852,7 @@ async fn collection_nfts_visible_named( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` - WHERE `collection_id` = ? AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1 ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -883,7 +879,7 @@ async fn collection_nfts_visible_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` = ? AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1 ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -910,7 +906,7 @@ async fn collection_nfts_named( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` - WHERE `collection_id` = ? + WHERE `is_owned` = 1 AND `collection_id` = ? ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -937,7 +933,7 @@ async fn collection_nfts_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` = ? + WHERE `is_owned` = 1 AND `collection_id` = ? ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -961,7 +957,7 @@ async fn no_collection_nfts_visible_named( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` - WHERE `collection_id` IS NULL AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1 ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -984,7 +980,7 @@ async fn no_collection_nfts_visible_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` IS NULL AND `visible` = 1 + WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1 ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -1007,7 +1003,7 @@ async fn no_collection_nfts_named( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_name` - WHERE `collection_id` IS NULL + WHERE `is_owned` = 1 AND `collection_id` IS NULL ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC LIMIT ? OFFSET ? ", @@ -1030,7 +1026,7 @@ async fn no_collection_nfts_recent( NftSql, " SELECT * FROM `nfts` INDEXED BY `nft_col_recent` - WHERE `collection_id` IS NULL + WHERE `is_owned` = 1 AND `collection_id` IS NULL ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC LIMIT ? OFFSET ? ", diff --git a/crates/sage-database/src/rows/did.rs b/crates/sage-database/src/rows/did.rs index ea577941..f3f0b53b 100644 --- a/crates/sage-database/src/rows/did.rs +++ b/crates/sage-database/src/rows/did.rs @@ -9,6 +9,7 @@ pub(crate) struct DidSql { pub coin_id: Vec, pub name: Option, pub visible: bool, + pub is_owned: bool, pub created_height: Option, } @@ -17,6 +18,7 @@ pub struct DidRow { pub launcher_id: Bytes32, pub coin_id: Bytes32, pub name: Option, + pub is_owned: bool, pub visible: bool, pub created_height: Option, } @@ -29,6 +31,7 @@ impl IntoRow for DidSql { launcher_id: to_bytes32(&self.launcher_id)?, coin_id: to_bytes32(&self.coin_id)?, name: self.name, + is_owned: self.is_owned, visible: self.visible, created_height: self.created_height.map(TryInto::try_into).transpose()?, }) diff --git a/crates/sage-database/src/rows/nft.rs b/crates/sage-database/src/rows/nft.rs index 458cd0a5..a0a0646d 100644 --- a/crates/sage-database/src/rows/nft.rs +++ b/crates/sage-database/src/rows/nft.rs @@ -14,6 +14,7 @@ pub(crate) struct NftSql { pub visible: bool, pub sensitive_content: bool, pub name: Option, + pub is_owned: bool, pub created_height: Option, pub metadata_hash: Option>, pub is_named: Option, @@ -30,6 +31,7 @@ pub struct NftRow { pub visible: bool, pub sensitive_content: bool, pub name: Option, + pub is_owned: bool, pub created_height: Option, pub metadata_hash: Option, } @@ -47,6 +49,7 @@ impl IntoRow for NftSql { visible: self.visible, sensitive_content: self.sensitive_content, name: self.name, + is_owned: self.is_owned, created_height: self.created_height.map(TryInto::try_into).transpose()?, metadata_hash: self.metadata_hash.as_deref().map(to_bytes32).transpose()?, }) diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index 09c76ea2..2873edf9 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -102,6 +102,7 @@ pub async fn insert_puzzle( launcher_id, coin_id, name, + is_owned: coin_state.spent_height.is_none(), visible: true, created_height: coin_state.created_height, }) @@ -143,6 +144,7 @@ pub async fn insert_puzzle( visible: true, sensitive_content: false, name: None, + is_owned: coin_state.spent_height.is_none(), created_height: coin_state.created_height, metadata_hash, }); @@ -200,8 +202,15 @@ pub async fn insert_puzzle( } pub async fn delete_puzzle(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { - tx.delete_nft(coin_id).await?; - tx.delete_did(coin_id).await?; + if let Some(mut row) = tx.did_row_by_coin(coin_id).await? { + row.is_owned = false; + tx.update_did(row).await?; + } + + if let Some(mut row) = tx.nft_row_by_coin(coin_id).await? { + row.is_owned = false; + tx.insert_nft(row).await?; + } Ok(()) } diff --git a/migrations/0001_setup.sql b/migrations/0001_setup.sql index 52bc9bf1..7990ff6c 100644 --- a/migrations/0001_setup.sql +++ b/migrations/0001_setup.sql @@ -91,13 +91,15 @@ CREATE TABLE `dids` ( `coin_id` BLOB NOT NULL, `name` TEXT, `visible` BOOLEAN NOT NULL, + `is_owned` BOOLEAN NOT NULL, `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED, `created_height` INTEGER, `is_pending` BOOLEAN GENERATED ALWAYS AS (`created_height` IS NULL) STORED, FOREIGN KEY (`coin_id`) REFERENCES `did_coins` (`coin_id`) ON DELETE CASCADE ); -CREATE INDEX `did_name` ON `dids` (`visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `did_coin_id` ON `dids` (`coin_id`); +CREATE INDEX `did_name` ON `dids` (`is_owned`, `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); CREATE TABLE `future_did_names` ( `launcher_id` BLOB NOT NULL PRIMARY KEY, @@ -140,6 +142,7 @@ CREATE TABLE `nfts` ( `visible` BOOLEAN NOT NULL, `sensitive_content` BOOLEAN NOT NULL, `name` TEXT, + `is_owned` BOOLEAN NOT NULL, `is_named` BOOLEAN GENERATED ALWAYS AS (`name` IS NOT NULL) STORED, `created_height` INTEGER, `is_pending` BOOLEAN GENERATED ALWAYS AS (`created_height` IS NULL) STORED, @@ -147,11 +150,12 @@ CREATE TABLE `nfts` ( FOREIGN KEY (`coin_id`) REFERENCES `nft_coins` (`coin_id`) ON DELETE CASCADE ); -CREATE INDEX `nft_metadata` ON `nfts` (`metadata_hash`); -CREATE INDEX `nft_name` ON `nfts` (`visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); -CREATE INDEX `nft_recent` ON `nfts` (`visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); -CREATE INDEX `nft_col_name` ON `nfts` (`collection_id`, `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); -CREATE INDEX `nft_col_recent` ON `nfts` (`collection_id`, `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); +CREATE INDEX `nft_coin_id` ON `nfts` (`coin_id`); +CREATE INDEX `nft_metadata` ON `nfts` (`is_owned`, `metadata_hash`); +CREATE INDEX `nft_name` ON `nfts` (`is_owned`, `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_recent` ON `nfts` (`is_owned`, `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); +CREATE INDEX `nft_col_name` ON `nfts` (`is_owned`, `collection_id`, `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC); +CREATE INDEX `nft_col_recent` ON `nfts` (`is_owned`, `collection_id`, `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC); CREATE TABLE `nft_coins` ( `coin_id` BLOB NOT NULL PRIMARY KEY, diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index 0ee39ba7..22767287 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -67,7 +67,7 @@ pub async fn update_did( return Err(Error::invalid_prefix(&prefix)); } - let Some(row) = wallet.db.did(launcher_id.into()).await? else { + let Some(row) = wallet.db.did_row(launcher_id.into()).await? else { return Err(Error::invalid_launcher_id()); }; @@ -77,6 +77,7 @@ pub async fn update_did( launcher_id: launcher_id.into(), coin_id: row.coin_id, name, + is_owned: row.is_owned, visible, created_height: row.created_height, }) From 6454401106ad7658350ce865204657d5d3782e91 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 5 Nov 2024 14:53:37 -0500 Subject: [PATCH 19/21] temp --- crates/sage-database/src/coin_states.rs | 48 ++--- crates/sage-database/src/derivations.rs | 8 +- crates/sage-database/src/primitives/cats.rs | 8 +- crates/sage-database/src/primitives/dids.rs | 41 +--- crates/sage-database/src/primitives/nfts.rs | 198 +++++++++--------- crates/sage-database/src/primitives/xch.rs | 16 +- crates/sage-database/src/transactions.rs | 30 +-- crates/sage-wallet/src/database.rs | 41 +++- crates/sage-wallet/src/queues/puzzle_queue.rs | 10 +- .../src/queues/transaction_queue.rs | 7 +- .../src/sync_manager/wallet_sync.rs | 14 +- crates/sage-wallet/src/wallet.rs | 7 +- src-tauri/src/commands/actions.rs | 2 +- src-tauri/src/commands/data.rs | 148 ++++++------- 14 files changed, 285 insertions(+), 293 deletions(-) diff --git a/crates/sage-database/src/coin_states.rs b/crates/sage-database/src/coin_states.rs index 6161c78f..edda11f7 100644 --- a/crates/sage-database/src/coin_states.rs +++ b/crates/sage-database/src/coin_states.rs @@ -11,6 +11,30 @@ impl Database { pub async fn coin_state(&self, coin_id: Bytes32) -> Result> { coin_state(&self.pool, coin_id).await } + + pub async fn unspent_nft_coin_ids(&self) -> Result> { + unspent_nft_coin_ids(&self.pool).await + } + + pub async fn unspent_did_coin_ids(&self) -> Result> { + unspent_did_coin_ids(&self.pool).await + } + + pub async fn unspent_cat_coin_ids(&self) -> Result> { + unspent_cat_coin_ids(&self.pool).await + } + + pub async fn delete_coin_state(&self, coin_id: Bytes32) -> Result<()> { + delete_coin_state(&self.pool, coin_id).await + } + + pub async fn total_coin_count(&self) -> Result { + total_coin_count(&self.pool).await + } + + pub async fn synced_coin_count(&self) -> Result { + synced_coin_count(&self.pool).await + } } impl<'a> DatabaseTx<'a> { @@ -40,10 +64,6 @@ impl<'a> DatabaseTx<'a> { .await } - pub async fn delete_coin_state(&mut self, coin_id: Bytes32) -> Result<()> { - delete_coin_state(&mut *self.tx, coin_id).await - } - pub async fn sync_coin(&mut self, coin_id: Bytes32, hint: Option) -> Result<()> { sync_coin(&mut *self.tx, coin_id, hint).await } @@ -55,26 +75,6 @@ impl<'a> DatabaseTx<'a> { pub async fn remove_coin_transaction_id(&mut self, coin_id: Bytes32) -> Result<()> { remove_coin_transaction_id(&mut *self.tx, coin_id).await } - - pub async fn total_coin_count(&mut self) -> Result { - total_coin_count(&mut *self.tx).await - } - - pub async fn synced_coin_count(&mut self) -> Result { - synced_coin_count(&mut *self.tx).await - } - - pub async fn unspent_nft_coin_ids(&mut self) -> Result> { - unspent_nft_coin_ids(&mut *self.tx).await - } - - pub async fn unspent_did_coin_ids(&mut self) -> Result> { - unspent_did_coin_ids(&mut *self.tx).await - } - - pub async fn unspent_cat_coin_ids(&mut self) -> Result> { - unspent_cat_coin_ids(&mut *self.tx).await - } } async fn insert_coin_state( diff --git a/crates/sage-database/src/derivations.rs b/crates/sage-database/src/derivations.rs index cd7e997d..32c25957 100644 --- a/crates/sage-database/src/derivations.rs +++ b/crates/sage-database/src/derivations.rs @@ -8,6 +8,10 @@ impl Database { p2_puzzle_hashes_unhardened(&self.pool).await } + pub async fn p2_puzzle_hashes(&self) -> Result> { + p2_puzzle_hashes(&self.pool).await + } + pub async fn synthetic_key(&self, p2_puzzle_hash: Bytes32) -> Result { synthetic_key(&self.pool, p2_puzzle_hash).await } @@ -47,10 +51,6 @@ impl<'a> DatabaseTx<'a> { max_used_derivation_index(&mut *self.tx, hardened).await } - pub async fn p2_puzzle_hashes(&mut self) -> Result> { - p2_puzzle_hashes(&mut *self.tx).await - } - pub async fn synthetic_key(&mut self, p2_puzzle_hash: Bytes32) -> Result { synthetic_key(&mut *self.tx, p2_puzzle_hash).await } diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 29e9b1dd..127e76b0 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -43,6 +43,10 @@ impl Database { pub async fn refetch_cat(&self, asset_id: Bytes32) -> Result<()> { refetch_cat(&self.pool, asset_id).await } + + pub async fn cat_coin_states(&self, asset_id: Bytes32) -> Result> { + cat_coin_states(&self.pool, asset_id).await + } } impl<'a> DatabaseTx<'a> { @@ -66,10 +70,6 @@ impl<'a> DatabaseTx<'a> { ) .await } - - pub async fn cat_coin_states(&mut self, asset_id: Bytes32) -> Result> { - cat_coin_states(&mut *self.tx, asset_id).await - } } async fn insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { diff --git a/crates/sage-database/src/primitives/dids.rs b/crates/sage-database/src/primitives/dids.rs index 973cb423..b6fc8752 100644 --- a/crates/sage-database/src/primitives/dids.rs +++ b/crates/sage-database/src/primitives/dids.rs @@ -15,10 +15,6 @@ impl Database { insert_did(&self.pool, row).await } - pub async fn update_did(&self, row: DidRow) -> Result<()> { - update_did(&self.pool, row).await - } - pub async fn dids_by_name(&self) -> Result> { dids_by_name(&self.pool).await } @@ -66,12 +62,12 @@ impl<'a> DatabaseTx<'a> { get_future_did_name(&mut *self.tx, launcher_id).await } - pub async fn did_row_by_coin(&mut self, coin_id: Bytes32) -> Result> { - did_row_by_coin(&mut *self.tx, coin_id).await + pub async fn did_row(&mut self, launcher_id: Bytes32) -> Result> { + did_row(&mut *self.tx, launcher_id).await } - pub async fn update_did(&mut self, row: DidRow) -> Result<()> { - update_did(&mut *self.tx, row).await + pub async fn did_row_by_coin(&mut self, coin_id: Bytes32) -> Result> { + did_row_by_coin(&mut *self.tx, coin_id).await } } @@ -79,35 +75,6 @@ async fn insert_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { let launcher_id = row.launcher_id.as_ref(); let coin_id = row.coin_id.as_ref(); - sqlx::query!( - " - INSERT OR IGNORE INTO `dids` ( - `launcher_id`, - `coin_id`, - `name`, - `is_owned`, - `visible`, - `created_height` - ) - VALUES (?, ?, ?, ?, ?, ?) - ", - launcher_id, - coin_id, - row.name, - row.is_owned, - row.visible, - row.created_height - ) - .execute(conn) - .await?; - - Ok(()) -} - -async fn update_did(conn: impl SqliteExecutor<'_>, row: DidRow) -> Result<()> { - let launcher_id = row.launcher_id.as_ref(); - let coin_id = row.coin_id.as_ref(); - sqlx::query!( " REPLACE INTO `dids` ( diff --git a/crates/sage-database/src/primitives/nfts.rs b/crates/sage-database/src/primitives/nfts.rs index ac6e5533..5906a9f2 100644 --- a/crates/sage-database/src/primitives/nfts.rs +++ b/crates/sage-database/src/primitives/nfts.rs @@ -42,160 +42,172 @@ impl Database { pub async fn collection(&self, collection_id: Bytes32) -> Result { collection(&self.pool, collection_id).await } -} -impl<'a> DatabaseTx<'a> { - pub async fn collections_visible_named( - &mut self, - limit: u32, - offset: u32, - ) -> Result> { - collections_visible_named(&mut *self.tx, offset, limit).await + pub async fn collection_count(&self) -> Result { + collection_count(&self.pool).await } - pub async fn collections_named( - &mut self, - limit: u32, - offset: u32, - ) -> Result> { - collections_named(&mut *self.tx, offset, limit).await + pub async fn visible_collection_count(&self) -> Result { + visible_collection_count(&self.pool).await } - pub async fn insert_nft_coin( - &mut self, - coin_id: Bytes32, - lineage_proof: LineageProof, - nft_info: NftInfo, - data_hash: Option, - metadata_hash: Option, - license_hash: Option, - ) -> Result<()> { - insert_nft_coin( - &mut *self.tx, - coin_id, - lineage_proof, - nft_info, - data_hash, - metadata_hash, - license_hash, - ) - .await - } - - pub async fn collection_count(&mut self) -> Result { - collection_count(&mut *self.tx).await - } - - pub async fn visible_collection_count(&mut self) -> Result { - visible_collection_count(&mut *self.tx).await + pub async fn nfts_visible_named(&self, limit: u32, offset: u32) -> Result> { + nfts_visible_named(&self.pool, limit, offset).await } - pub async fn nfts_visible_named(&mut self, limit: u32, offset: u32) -> Result> { - nfts_visible_named(&mut *self.tx, limit, offset).await + pub async fn nfts_visible_recent(&self, limit: u32, offset: u32) -> Result> { + nfts_visible_recent(&self.pool, limit, offset).await } - pub async fn nfts_visible_recent(&mut self, limit: u32, offset: u32) -> Result> { - nfts_visible_recent(&mut *self.tx, limit, offset).await + pub async fn nfts_named(&self, limit: u32, offset: u32) -> Result> { + nfts_named(&self.pool, limit, offset).await } - pub async fn nfts_named(&mut self, limit: u32, offset: u32) -> Result> { - nfts_named(&mut *self.tx, limit, offset).await + pub async fn nfts_recent(&self, limit: u32, offset: u32) -> Result> { + nfts_recent(&self.pool, limit, offset).await } - pub async fn nfts_recent(&mut self, limit: u32, offset: u32) -> Result> { - nfts_recent(&mut *self.tx, limit, offset).await + pub async fn nft_count(&self) -> Result { + nft_count(&self.pool).await } - pub async fn nft_count(&mut self) -> Result { - nft_count(&mut *self.tx).await - } - - pub async fn visible_nft_count(&mut self) -> Result { - visible_nft_count(&mut *self.tx).await + pub async fn visible_nft_count(&self) -> Result { + visible_nft_count(&self.pool).await } pub async fn collection_nfts_visible_named( - &mut self, + &self, collection_id: Bytes32, limit: u32, offset: u32, ) -> Result> { - collection_nfts_visible_named(&mut *self.tx, collection_id, limit, offset).await + collection_nfts_visible_named(&self.pool, collection_id, limit, offset).await } pub async fn collection_nfts_visible_recent( - &mut self, + &self, collection_id: Bytes32, limit: u32, offset: u32, ) -> Result> { - collection_nfts_visible_recent(&mut *self.tx, collection_id, limit, offset).await + collection_nfts_visible_recent(&self.pool, collection_id, limit, offset).await } pub async fn collection_nfts_named( - &mut self, + &self, collection_id: Bytes32, limit: u32, offset: u32, ) -> Result> { - collection_nfts_named(&mut *self.tx, collection_id, limit, offset).await + collection_nfts_named(&self.pool, collection_id, limit, offset).await } pub async fn collection_nfts_recent( - &mut self, + &self, collection_id: Bytes32, limit: u32, offset: u32, ) -> Result> { - collection_nfts_recent(&mut *self.tx, collection_id, limit, offset).await + collection_nfts_recent(&self.pool, collection_id, limit, offset).await } pub async fn no_collection_nfts_visible_named( - &mut self, + &self, limit: u32, offset: u32, ) -> Result> { - no_collection_nfts_visible_named(&mut *self.tx, limit, offset).await + no_collection_nfts_visible_named(&self.pool, limit, offset).await } pub async fn no_collection_nfts_visible_recent( - &mut self, + &self, limit: u32, offset: u32, ) -> Result> { - no_collection_nfts_visible_recent(&mut *self.tx, limit, offset).await + no_collection_nfts_visible_recent(&self.pool, limit, offset).await } - pub async fn no_collection_nfts_named( - &mut self, - limit: u32, - offset: u32, - ) -> Result> { - no_collection_nfts_named(&mut *self.tx, limit, offset).await + pub async fn no_collection_nfts_named(&self, limit: u32, offset: u32) -> Result> { + no_collection_nfts_named(&self.pool, limit, offset).await } - pub async fn no_collection_nfts_recent( - &mut self, + pub async fn no_collection_nfts_recent(&self, limit: u32, offset: u32) -> Result> { + no_collection_nfts_recent(&self.pool, limit, offset).await + } + + pub async fn collection_nft_count(&self, collection_id: Bytes32) -> Result { + collection_nft_count(&self.pool, collection_id).await + } + + pub async fn collection_visible_nft_count(&self, collection_id: Bytes32) -> Result { + collection_visible_nft_count(&self.pool, collection_id).await + } + + pub async fn no_collection_nft_count(&self) -> Result { + no_collection_nft_count(&self.pool).await + } + + pub async fn no_collection_visible_nft_count(&self) -> Result { + no_collection_visible_nft_count(&self.pool).await + } + + pub async fn collections_visible_named( + &self, limit: u32, offset: u32, - ) -> Result> { - no_collection_nfts_recent(&mut *self.tx, limit, offset).await + ) -> Result> { + collections_visible_named(&self.pool, offset, limit).await + } + + pub async fn collections_named(&self, limit: u32, offset: u32) -> Result> { + collections_named(&self.pool, offset, limit).await + } + + pub async fn nft_row(&self, launcher_id: Bytes32) -> Result> { + nft_row(&self.pool, launcher_id).await + } + + pub async fn nft(&self, launcher_id: Bytes32) -> Result>> { + nft(&self.pool, launcher_id).await + } + + pub async fn collection_name(&self, collection_id: Bytes32) -> Result> { + collection_name(&self.pool, collection_id).await } - pub async fn collection_nft_count(&mut self, collection_id: Bytes32) -> Result { - collection_nft_count(&mut *self.tx, collection_id).await + pub async fn data_hash(&self, launcher_id: Bytes32) -> Result> { + data_hash(&self.pool, launcher_id).await } - pub async fn collection_visible_nft_count(&mut self, collection_id: Bytes32) -> Result { - collection_visible_nft_count(&mut *self.tx, collection_id).await + pub async fn metadata_hash(&self, launcher_id: Bytes32) -> Result> { + metadata_hash(&self.pool, launcher_id).await } - pub async fn no_collection_nft_count(&mut self) -> Result { - no_collection_nft_count(&mut *self.tx).await + pub async fn license_hash(&self, launcher_id: Bytes32) -> Result> { + license_hash(&self.pool, launcher_id).await } +} - pub async fn no_collection_visible_nft_count(&mut self) -> Result { - no_collection_visible_nft_count(&mut *self.tx).await +impl<'a> DatabaseTx<'a> { + pub async fn insert_nft_coin( + &mut self, + coin_id: Bytes32, + lineage_proof: LineageProof, + nft_info: NftInfo, + data_hash: Option, + metadata_hash: Option, + license_hash: Option, + ) -> Result<()> { + insert_nft_coin( + &mut *self.tx, + coin_id, + lineage_proof, + nft_info, + data_hash, + metadata_hash, + license_hash, + ) + .await } pub async fn insert_nft_uri(&mut self, uri: String, hash: Bytes32) -> Result<()> { @@ -226,18 +238,6 @@ impl<'a> DatabaseTx<'a> { nft_row_by_coin(&mut *self.tx, coin_id).await } - pub async fn data_hash(&mut self, launcher_id: Bytes32) -> Result> { - data_hash(&mut *self.tx, launcher_id).await - } - - pub async fn metadata_hash(&mut self, launcher_id: Bytes32) -> Result> { - metadata_hash(&mut *self.tx, launcher_id).await - } - - pub async fn license_hash(&mut self, launcher_id: Bytes32) -> Result> { - license_hash(&mut *self.tx, launcher_id).await - } - pub async fn nfts_by_metadata_hash(&mut self, metadata_hash: Bytes32) -> Result> { nfts_by_metadata_hash(&mut *self.tx, metadata_hash).await } @@ -249,10 +249,6 @@ impl<'a> DatabaseTx<'a> { pub async fn insert_collection(&mut self, row: CollectionRow) -> Result<()> { insert_collection(&mut *self.tx, row).await } - - pub async fn collection_name(&mut self, collection_id: Bytes32) -> Result> { - collection_name(&mut *self.tx, collection_id).await - } } async fn insert_collection(conn: impl SqliteExecutor<'_>, row: CollectionRow) -> Result<()> { diff --git a/crates/sage-database/src/primitives/xch.rs b/crates/sage-database/src/primitives/xch.rs index 023d9f30..0161a64c 100644 --- a/crates/sage-database/src/primitives/xch.rs +++ b/crates/sage-database/src/primitives/xch.rs @@ -9,19 +9,19 @@ impl Database { pub async fn spendable_coins(&self) -> Result> { spendable_coins(&self.pool).await } -} -impl<'a> DatabaseTx<'a> { - pub async fn p2_coin_states(&mut self) -> Result> { - p2_coin_states(&mut *self.tx).await + pub async fn balance(&self) -> Result { + balance(&self.pool).await } - pub async fn insert_p2_coin(&mut self, coin_id: Bytes32) -> Result<()> { - insert_p2_coin(&mut *self.tx, coin_id).await + pub async fn p2_coin_states(&self) -> Result> { + p2_coin_states(&self.pool).await } +} - pub async fn balance(&mut self) -> Result { - balance(&mut *self.tx).await +impl<'a> DatabaseTx<'a> { + pub async fn insert_p2_coin(&mut self, coin_id: Bytes32) -> Result<()> { + insert_p2_coin(&mut *self.tx, coin_id).await } } diff --git a/crates/sage-database/src/transactions.rs b/crates/sage-database/src/transactions.rs index a76d1a86..a89a4e82 100644 --- a/crates/sage-database/src/transactions.rs +++ b/crates/sage-database/src/transactions.rs @@ -25,6 +25,21 @@ impl Database { pub async fn transactions(&self) -> Result> { transactions(&self.pool).await } + + pub async fn resubmittable_transactions( + &self, + threshold: i64, + ) -> Result> { + resubmittable_transactions(&self.pool, threshold).await + } + + pub async fn coin_spends(&self, transaction_id: Bytes32) -> Result> { + coin_spends(&self.pool, transaction_id).await + } + + pub async fn transactions_for_coin(&self, coin_id: Bytes32) -> Result> { + transactions_for_coin(&self.pool, coin_id).await + } } impl<'a> DatabaseTx<'a> { @@ -46,21 +61,6 @@ impl<'a> DatabaseTx<'a> { insert_transaction_spend(&mut *self.tx, transaction_id, coin_spend, index).await } - pub async fn transactions_for_coin(&mut self, coin_id: Bytes32) -> Result> { - transactions_for_coin(&mut *self.tx, coin_id).await - } - - pub async fn resubmittable_transactions( - &mut self, - threshold: i64, - ) -> Result> { - resubmittable_transactions(&mut *self.tx, threshold).await - } - - pub async fn coin_spends(&mut self, transaction_id: Bytes32) -> Result> { - coin_spends(&mut *self.tx, transaction_id).await - } - pub async fn confirm_coins(&mut self, transaction_id: Bytes32) -> Result<()> { confirm_coins(&mut *self.tx, transaction_id).await } diff --git a/crates/sage-wallet/src/database.rs b/crates/sage-wallet/src/database.rs index 2873edf9..a9e362aa 100644 --- a/crates/sage-wallet/src/database.rs +++ b/crates/sage-wallet/src/database.rs @@ -32,6 +32,8 @@ pub async fn upsert_coin( // This allows querying for XCH coins without joining on the derivations table. if is_p2 { tx.insert_p2_coin(coin_id).await?; + } else { + update_created_puzzle(tx, coin_state).await?; } Ok(()) @@ -98,15 +100,23 @@ pub async fn insert_puzzle( tx.delete_future_did_name(launcher_id).await?; } - tx.insert_did(DidRow { + let mut row = tx.did_row(launcher_id).await?.unwrap_or(DidRow { launcher_id, coin_id, name, is_owned: coin_state.spent_height.is_none(), visible: true, created_height: coin_state.created_height, - }) - .await?; + }); + + if coin_state.spent_height.is_none() { + row.is_owned = true; + } + + row.coin_id = coin_id; + row.created_height = coin_state.created_height; + + tx.insert_did(row).await?; } ChildKind::Nft { lineage_proof, @@ -149,6 +159,10 @@ pub async fn insert_puzzle( metadata_hash, }); + if coin_state.spent_height.is_none() { + row.is_owned = true; + } + let metadata_blob = if let Some(metadata_hash) = metadata_hash { tx.fetch_nft_data(metadata_hash) .await? @@ -204,7 +218,7 @@ pub async fn insert_puzzle( pub async fn delete_puzzle(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result<(), WalletError> { if let Some(mut row) = tx.did_row_by_coin(coin_id).await? { row.is_owned = false; - tx.update_did(row).await?; + tx.insert_did(row).await?; } if let Some(mut row) = tx.nft_row_by_coin(coin_id).await? { @@ -215,6 +229,25 @@ pub async fn delete_puzzle(tx: &mut DatabaseTx<'_>, coin_id: Bytes32) -> Result< Ok(()) } +pub async fn update_created_puzzle( + tx: &mut DatabaseTx<'_>, + coin_state: CoinState, +) -> Result<(), WalletError> { + let coin_id = coin_state.coin.coin_id(); + + if let Some(mut row) = tx.did_row_by_coin(coin_id).await? { + row.created_height = coin_state.created_height; + tx.insert_did(row).await?; + } + + if let Some(mut row) = tx.nft_row_by_coin(coin_id).await? { + row.created_height = coin_state.created_height; + tx.insert_nft(row).await?; + } + + Ok(()) +} + pub async fn insert_transaction( tx: &mut DatabaseTx<'_>, transaction_id: Bytes32, diff --git a/crates/sage-wallet/src/queues/puzzle_queue.rs b/crates/sage-wallet/src/queues/puzzle_queue.rs index 43ac36a4..d9177807 100644 --- a/crates/sage-wallet/src/queues/puzzle_queue.rs +++ b/crates/sage-wallet/src/queues/puzzle_queue.rs @@ -187,20 +187,18 @@ async fn fetch_puzzle( let subscribe = info.subscribe(); - let mut tx = db.tx().await?; - let remove = match info.p2_puzzle_hash() { - Some(p2_puzzle_hash) => !tx.is_p2_puzzle_hash(p2_puzzle_hash).await?, + Some(p2_puzzle_hash) => !db.is_p2_puzzle_hash(p2_puzzle_hash).await?, None => true, }; if remove { - tx.delete_coin_state(coin_id).await?; + db.delete_coin_state(coin_id).await?; } else { + let mut tx = db.tx().await?; insert_puzzle(&mut tx, coin_state, info, minter_did).await?; + tx.commit().await?; } - tx.commit().await?; - Ok(subscribe) } diff --git a/crates/sage-wallet/src/queues/transaction_queue.rs b/crates/sage-wallet/src/queues/transaction_queue.rs index c2b9ea75..a9b867d2 100644 --- a/crates/sage-wallet/src/queues/transaction_queue.rs +++ b/crates/sage-wallet/src/queues/transaction_queue.rs @@ -63,10 +63,9 @@ impl TransactionQueue { .try_into() .expect("timestamp does not fit in i64"); - let mut tx = self.db.tx().await?; let mut spend_bundles = Vec::new(); - let rows = tx.resubmittable_transactions(timestamp - 180).await?; + let rows = self.db.resubmittable_transactions(timestamp - 180).await?; if rows.is_empty() { return Ok(()); @@ -75,12 +74,10 @@ impl TransactionQueue { info!("Submitting the following transactions: {rows:?}"); for (transaction_id, aggregated_signature) in rows { - let coin_spends = tx.coin_spends(transaction_id).await?; + let coin_spends = self.db.coin_spends(transaction_id).await?; spend_bundles.push(SpendBundle::new(coin_spends, aggregated_signature)); } - tx.commit().await?; - for spend_bundle in spend_bundles { sleep(Duration::from_secs(1)).await; diff --git a/crates/sage-wallet/src/sync_manager/wallet_sync.rs b/crates/sage-wallet/src/sync_manager/wallet_sync.rs index 33a058da..ebab7fdf 100644 --- a/crates/sage-wallet/src/sync_manager/wallet_sync.rs +++ b/crates/sage-wallet/src/sync_manager/wallet_sync.rs @@ -26,22 +26,18 @@ pub async fn sync_wallet( ) -> Result<(), WalletError> { info!("Starting sync against peer {}", peer.socket_addr()); - let mut tx = wallet.db.tx().await?; - let mut coin_ids = Vec::new(); - coin_ids.extend(tx.unspent_nft_coin_ids().await?); - coin_ids.extend(tx.unspent_did_coin_ids().await?); - coin_ids.extend(tx.unspent_cat_coin_ids().await?); + coin_ids.extend(wallet.db.unspent_nft_coin_ids().await?); + coin_ids.extend(wallet.db.unspent_did_coin_ids().await?); + coin_ids.extend(wallet.db.unspent_cat_coin_ids().await?); - let p2_puzzle_hashes = tx.p2_puzzle_hashes().await?; + let p2_puzzle_hashes = wallet.db.p2_puzzle_hashes().await?; - let (start_height, start_header_hash) = tx.latest_peak().await?.map_or_else( + let (start_height, start_header_hash) = wallet.db.latest_peak().await?.map_or_else( || (None, wallet.genesis_challenge), |(peak, header_hash)| (Some(peak), header_hash), ); - tx.commit().await?; - sync_coin_ids( &wallet, &peer, diff --git a/crates/sage-wallet/src/wallet.rs b/crates/sage-wallet/src/wallet.rs index 8898ed5d..1a6748ee 100644 --- a/crates/sage-wallet/src/wallet.rs +++ b/crates/sage-wallet/src/wallet.rs @@ -175,11 +175,9 @@ impl Wallet { ctx: &mut SpendContext, coins: impl Iterator, ) -> Result<(), WalletError> { - let mut tx = self.db.tx().await?; - for (coin, conditions) in coins { // We need to figure out what the synthetic public key is for this p2 coin. - let synthetic_key = tx.synthetic_key(coin.puzzle_hash).await?; + let synthetic_key = self.db.synthetic_key(coin.puzzle_hash).await?; // Create the standard p2 layer for the key. let p2 = StandardLayer::new(synthetic_key); @@ -222,12 +220,11 @@ impl Wallet { ctx: &mut SpendContext, cats: impl Iterator, ) -> Result<(), WalletError> { - let mut tx = self.db.tx().await?; let mut cat_spends = Vec::new(); for (cat, conditions) in cats { // We need to figure out what the synthetic public key is for this CAT coin. - let synthetic_key = tx.synthetic_key(cat.p2_puzzle_hash).await?; + let synthetic_key = self.db.synthetic_key(cat.p2_puzzle_hash).await?; // Create the standard p2 layer for the key. let p2 = StandardLayer::new(synthetic_key); diff --git a/src-tauri/src/commands/actions.rs b/src-tauri/src/commands/actions.rs index 22767287..0f76b43e 100644 --- a/src-tauri/src/commands/actions.rs +++ b/src-tauri/src/commands/actions.rs @@ -73,7 +73,7 @@ pub async fn update_did( wallet .db - .update_did(DidRow { + .insert_did(DidRow { launcher_id: launcher_id.into(), coin_id: row.coin_id, name, diff --git a/src-tauri/src/commands/data.rs b/src-tauri/src/commands/data.rs index 341ce7a5..53a64099 100644 --- a/src-tauri/src/commands/data.rs +++ b/src-tauri/src/commands/data.rs @@ -49,11 +49,9 @@ pub async fn get_sync_status(state: State<'_, AppState>) -> Result { let state = state.lock().await; let wallet = state.wallet()?; - let mut tx = wallet.db.tx().await?; - let balance = tx.balance().await?; - let total_coins = tx.total_coin_count().await?; - let synced_coins = tx.synced_coin_count().await?; - tx.commit().await?; + let balance = wallet.db.balance().await?; + let total_coins = wallet.db.total_coin_count().await?; + let synced_coins = wallet.db.synced_coin_count().await?; let puzzle_hash = match wallet.p2_puzzle_hash(false, false).await { Ok(puzzle_hash) => Some(puzzle_hash), @@ -84,15 +82,15 @@ pub async fn get_coins(state: State<'_, AppState>) -> Result> { let state = state.lock().await; let wallet = state.wallet()?; - let mut tx = wallet.db.tx().await?; let mut records = Vec::new(); - let rows = tx.p2_coin_states().await?; + let rows = wallet.db.p2_coin_states().await?; for row in rows { let cs = row.coin_state; - let spend_transaction_id = tx + let spend_transaction_id = wallet + .db .transactions_for_coin(cs.coin.coin_id()) .await? .into_iter() @@ -129,15 +127,15 @@ pub async fn get_cat_coins( .try_into() .map_err(|_| Error::invalid_asset_id())?; - let mut tx = wallet.db.tx().await?; let mut records = Vec::new(); - let rows = tx.cat_coin_states(asset_id.into()).await?; + let rows = wallet.db.cat_coin_states(asset_id.into()).await?; for row in rows { let cs = row.coin_state; - let spend_transaction_id = tx + let spend_transaction_id = wallet + .db .transactions_for_coin(cs.coin.coin_id()) .await? .into_iter() @@ -275,14 +273,10 @@ pub async fn get_nft_status(state: State<'_, AppState>) -> Result { let state = state.lock().await; let wallet = state.wallet()?; - let mut tx = wallet.db.tx().await?; - - let nfts = tx.nft_count().await?; - let collections = tx.collection_count().await?; - let visible_nfts = tx.visible_nft_count().await?; - let visible_collections = tx.visible_collection_count().await?; - - tx.commit().await?; + let nfts = wallet.db.nft_count().await?; + let collections = wallet.db.collection_count().await?; + let visible_nfts = wallet.db.visible_nft_count().await?; + let visible_collections = wallet.db.visible_collection_count().await?; Ok(NftStatus { nfts, @@ -303,18 +297,24 @@ pub async fn get_nft_collections( let mut records = Vec::new(); - let mut tx = wallet.db.tx().await?; - let collections = if request.include_hidden { - tx.collections_named(request.limit, request.offset).await? + wallet + .db + .collections_named(request.limit, request.offset) + .await? } else { - tx.collections_visible_named(request.limit, request.offset) + wallet + .db + .collections_visible_named(request.limit, request.offset) .await? }; for col in collections { - let total = tx.collection_nft_count(col.collection_id).await?; - let total_visible = tx.collection_visible_nft_count(col.collection_id).await?; + let total = wallet.db.collection_nft_count(col.collection_id).await?; + let total_visible = wallet + .db + .collection_visible_nft_count(col.collection_id) + .await?; records.push(NftCollectionRecord { collection_id: encode_address(col.collection_id.to_bytes(), "col")?, @@ -328,8 +328,6 @@ pub async fn get_nft_collections( }); } - tx.commit().await?; - Ok(records) } @@ -360,22 +358,21 @@ pub async fn get_nft_collection( None }; - let mut tx = wallet.db.tx().await?; - let total = if let Some(collection_id) = collection_id { - tx.collection_nft_count(collection_id).await? + wallet.db.collection_nft_count(collection_id).await? } else { - tx.no_collection_nft_count().await? + wallet.db.no_collection_nft_count().await? }; let total_visible = if let Some(collection_id) = collection_id { - tx.collection_visible_nft_count(collection_id).await? + wallet + .db + .collection_visible_nft_count(collection_id) + .await? } else { - tx.no_collection_visible_nft_count().await? + wallet.db.no_collection_visible_nft_count().await? }; - tx.commit().await?; - Ok(if let Some(collection) = collection { NftCollectionRecord { collection_id: encode_address(collection.collection_id.to_bytes(), "col")?, @@ -409,27 +406,32 @@ pub async fn get_nfts(state: State<'_, AppState>, request: GetNfts) -> Result tx.nfts_named(request.limit, request.offset).await?, - (NftSortMode::Name, false) => tx.nfts_visible_named(request.limit, request.offset).await?, - (NftSortMode::Recent, true) => tx.nfts_recent(request.limit, request.offset).await?, + (NftSortMode::Name, true) => wallet.db.nfts_named(request.limit, request.offset).await?, + (NftSortMode::Name, false) => { + wallet + .db + .nfts_visible_named(request.limit, request.offset) + .await? + } + (NftSortMode::Recent, true) => wallet.db.nfts_recent(request.limit, request.offset).await?, (NftSortMode::Recent, false) => { - tx.nfts_visible_recent(request.limit, request.offset) + wallet + .db + .nfts_visible_recent(request.limit, request.offset) .await? } }; for nft in nfts { - let data = if let Some(hash) = tx.data_hash(nft.launcher_id).await? { - tx.fetch_nft_data(hash).await? + let data = if let Some(hash) = wallet.db.data_hash(nft.launcher_id).await? { + wallet.db.fetch_nft_data(hash).await? } else { None }; let collection_name = if let Some(collection_id) = nft.collection_id { - tx.collection_name(collection_id).await? + wallet.db.collection_name(collection_id).await? } else { None }; @@ -437,8 +439,6 @@ pub async fn get_nfts(state: State<'_, AppState>, request: GetNfts) -> Result { - tx.collection_nfts_named(collection_id, request.limit, request.offset) + wallet + .db + .collection_nfts_named(collection_id, request.limit, request.offset) .await? } (NftSortMode::Name, false, Some(collection_id)) => { - tx.collection_nfts_visible_named(collection_id, request.limit, request.offset) + wallet + .db + .collection_nfts_visible_named(collection_id, request.limit, request.offset) .await? } (NftSortMode::Recent, true, Some(collection_id)) => { - tx.collection_nfts_recent(collection_id, request.limit, request.offset) + wallet + .db + .collection_nfts_recent(collection_id, request.limit, request.offset) .await? } (NftSortMode::Recent, false, Some(collection_id)) => { - tx.collection_nfts_visible_recent(collection_id, request.limit, request.offset) + wallet + .db + .collection_nfts_visible_recent(collection_id, request.limit, request.offset) .await? } (NftSortMode::Name, true, None) => { - tx.no_collection_nfts_named(request.limit, request.offset) + wallet + .db + .no_collection_nfts_named(request.limit, request.offset) .await? } (NftSortMode::Name, false, None) => { - tx.no_collection_nfts_visible_named(request.limit, request.offset) + wallet + .db + .no_collection_nfts_visible_named(request.limit, request.offset) .await? } (NftSortMode::Recent, true, None) => { - tx.no_collection_nfts_recent(request.limit, request.offset) + wallet + .db + .no_collection_nfts_recent(request.limit, request.offset) .await? } (NftSortMode::Recent, false, None) => { - tx.no_collection_nfts_visible_recent(request.limit, request.offset) + wallet + .db + .no_collection_nfts_visible_recent(request.limit, request.offset) .await? } }; for nft in nfts { - let data = if let Some(hash) = tx.data_hash(nft.launcher_id).await? { - tx.fetch_nft_data(hash).await? + let data = if let Some(hash) = wallet.db.data_hash(nft.launcher_id).await? { + wallet.db.fetch_nft_data(hash).await? } else { None }; let collection_name = if let Some(collection_id) = nft.collection_id { - tx.collection_name(collection_id).await? + wallet.db.collection_name(collection_id).await? } else { None }; @@ -518,8 +532,6 @@ pub async fn get_collection_nfts( records.push(nft_record(nft, collection_name, data)?); } - tx.commit().await?; - Ok(records) } @@ -534,13 +546,11 @@ pub async fn get_nft(state: State<'_, AppState>, launcher_id: String) -> Result< return Err(Error::invalid_prefix(&prefix)); } - let mut tx = wallet.db.tx().await?; - - let Some(nft_row) = tx.nft_row(launcher_id.into()).await? else { + let Some(nft_row) = wallet.db.nft_row(launcher_id.into()).await? else { return Ok(None); }; - let Some(nft) = tx.nft(launcher_id.into()).await? else { + let Some(nft) = wallet.db.nft(launcher_id.into()).await? else { return Ok(None); }; @@ -553,25 +563,23 @@ pub async fn get_nft(state: State<'_, AppState>, launcher_id: String) -> Result< let license_hash = metadata.as_ref().and_then(|m| m.license_hash); let data = if let Some(hash) = data_hash { - tx.fetch_nft_data(hash).await? + wallet.db.fetch_nft_data(hash).await? } else { None }; let offchain_metadata = if let Some(hash) = metadata_hash { - tx.fetch_nft_data(hash).await? + wallet.db.fetch_nft_data(hash).await? } else { None }; let collection_name = if let Some(collection_id) = nft_row.collection_id { - tx.collection_name(collection_id).await? + wallet.db.collection_name(collection_id).await? } else { None }; - tx.commit().await?; - Ok(Some(NftInfo { launcher_id: encode_address(nft_row.launcher_id.to_bytes(), "nft")?, collection_id: nft_row From 98a6759adfbec4830d15c915801865116453513f Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 5 Nov 2024 15:21:36 -0500 Subject: [PATCH 20/21] bug fix --- crates/sage-database/src/primitives/cats.rs | 14 +++++++++----- crates/sage-wallet/src/queues/puzzle_queue.rs | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/sage-database/src/primitives/cats.rs b/crates/sage-database/src/primitives/cats.rs index 127e76b0..0665ff91 100644 --- a/crates/sage-database/src/primitives/cats.rs +++ b/crates/sage-database/src/primitives/cats.rs @@ -83,8 +83,9 @@ async fn insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { `ticker`, `description`, `icon`, - `visible` - ) VALUES (?, ?, ?, ?, ?, ?) + `visible`, + `fetched` + ) VALUES (?, ?, ?, ?, ?, ?, ?) ", asset_id, row.name, @@ -92,6 +93,7 @@ async fn insert_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { row.description, row.icon, row.visible, + row.fetched ) .execute(conn) .await?; @@ -109,15 +111,17 @@ async fn update_cat(conn: impl SqliteExecutor<'_>, row: CatRow) -> Result<()> { `ticker`, `description`, `icon`, - `visible` - ) VALUES (?, ?, ?, ?, ?, ?) + `visible`, + `fetched` + ) VALUES (?, ?, ?, ?, ?, ?, ?) ", asset_id, row.name, row.ticker, row.description, row.icon, - row.visible + row.visible, + row.fetched ) .execute(conn) .await?; diff --git a/crates/sage-wallet/src/queues/puzzle_queue.rs b/crates/sage-wallet/src/queues/puzzle_queue.rs index d9177807..4b500cc3 100644 --- a/crates/sage-wallet/src/queues/puzzle_queue.rs +++ b/crates/sage-wallet/src/queues/puzzle_queue.rs @@ -160,7 +160,7 @@ async fn fetch_puzzle( .ok_or(SyncError::UnconfirmedCoin(parent_id))?; let response = timeout( - Duration::from_secs(5), + Duration::from_secs(10), peer.request_puzzle_and_solution(parent_id, height), ) .await From cbeb9d96b46476abb78fbe290c3072d8c2a19e23 Mon Sep 17 00:00:00 2001 From: Rigidity Date: Tue, 5 Nov 2024 15:21:57 -0500 Subject: [PATCH 21/21] prepare --- ...9dd1506bb3ac5b040e71c70a6f929e6a49f44.json | 50 ++++++++++ ...55d13fa2554ed7ef81b52d9cce472d9e01e9f.json | 12 --- ...bfca53d56dd3250106bcafff91862a56a454a.json | 12 --- ...80176c38ec677470f4698520123113eda896.json} | 18 ++-- ...3380a1312e0530c1ba0418e783a7be8a521cb.json | 14 ++- ...a74ae9c6b0b6efafdc2a41d2597691ada155e.json | 92 +++++++++++++++++++ ...51533e25a0291ce0f05f4f68c70cb6daba94.json} | 6 +- ...ecfa5223ab64a169a5d2ec75eed7610a4480.json} | 6 +- ...debc939d2d2e4c3fc788ce2a492eb5c2840d6.json | 20 ++++ ...ff60caf0240ca348a85d51034432840571324.json | 74 --------------- ...3b9b2e0d01e9bd45d8052018a2a93ad57b30.json} | 18 ++-- ...52176fee280f2734f0a13fd7d38147062cd8.json} | 18 ++-- ...f64350fe914edea4a35d21dbf77bd687c1eb4.json | 12 +++ ...05e9e52c4da96efff2543052066628928ab3.json} | 18 ++-- ...c7d92948cf8cdbd4b286c933ee5837c7742d.json} | 20 ++-- ...31b27088d9184f057d65ab3905f871f75f45.json} | 6 +- ...65ca9044f8c312bedeff84f7b43a7d8828ca6.json | 12 +++ ...93c9228c8e9d3599ef18ac27b3eb21fe62493.json | 50 ++++++++++ ...be8955ea8f6ae27b3ee149c45e4c4e48e8356.json | 92 +++++++++++++++++++ ...f5ef2822be7c119d8cbe35b3b437717ddf835.json | 12 --- ...6ac83d1faff5885ff3ac3347aa0dbb578ed7.json} | 20 ++-- ...e6042acf426ff734ebff07a6a139a7f6ab1a3.json | 32 ------- ...27a59beec55d8f7a752ba53c31ea6213a4e9.json} | 4 +- ...9e1c44b7200b2c5c01ac168a0889b5978cbf.json} | 4 +- ...0d8961cfb668bd090841c282e46ea5e17daa.json} | 4 +- ...dc38ed92ac74d690c3f5a70a1fb94d9164a89.json | 50 ++++++++++ ...b37a40c0c536d5a22906ca3e219dee574889.json} | 18 ++-- ...7d450056592c1e2dffa1f1607835a926ef43.json} | 18 ++-- ...60df566158a3b021474b893f40acabd21757.json} | 18 ++-- ...39e0752c151529f6e2c0f79438064bd426d3.json} | 4 +- ...833933ed9544178376d20330697fd294bad5.json} | 18 ++-- ...9538b32e20487791f8f5066872dbccf55254.json} | 18 ++-- ...15d94b57d8ad2516f2ee3aee5434d833f9136.json | 12 --- ...b91b537664d85c6970b8ef8d495ea201957a.json} | 18 ++-- ...dcf3854a56af2ae3bb1d31a5334db682b7471.json | 12 +++ 35 files changed, 563 insertions(+), 249 deletions(-) create mode 100644 .sqlx/query-06802a4efba6dc3e16e65769f739dd1506bb3ac5b040e71c70a6f929e6a49f44.json delete mode 100644 .sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json delete mode 100644 .sqlx/query-120103ccc25632c23e168d21bf1bfca53d56dd3250106bcafff91862a56a454a.json rename .sqlx/{query-fd6d6e505e9619e149c6868fe4af5c2564050ff0583c62a2d2c449a808d421e0.json => query-18324ab210540c63143113e4ccaa80176c38ec677470f4698520123113eda896.json} (79%) create mode 100644 .sqlx/query-1faa3ca5ae4dd907238ffac15c6a74ae9c6b0b6efafdc2a41d2597691ada155e.json rename .sqlx/{query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json => query-20505bc0166a86dc2be61d1ce71251533e25a0291ce0f05f4f68c70cb6daba94.json} (63%) rename .sqlx/{query-b8e2f31145c5fb41476b842038c101485e6bacbbf9c47dacae28c680445d537a.json => query-2462446e09a04413761893bfc3d3ecfa5223ab64a169a5d2ec75eed7610a4480.json} (62%) create mode 100644 .sqlx/query-275b72aec6c3642621c64403265debc939d2d2e4c3fc788ce2a492eb5c2840d6.json delete mode 100644 .sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json rename .sqlx/{query-651c1fd0f3ce348d243a2ed185b540d444022f3cdaa2e79cb1fa77c8a80b0437.json => query-3bd7cba585f5be0c92ad3bbea36c3b9b2e0d01e9bd45d8052018a2a93ad57b30.json} (81%) rename .sqlx/{query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json => query-49f9b8dedcf7ac304d7f622e011452176fee280f2734f0a13fd7d38147062cd8.json} (79%) create mode 100644 .sqlx/query-4e57a9bc7318609e6c2b2fe3130f64350fe914edea4a35d21dbf77bd687c1eb4.json rename .sqlx/{query-f3703966c1cb30cfff1d68ab2f6019868d0263f46896585a2318a4d14d2f286c.json => query-4fc58bf2b8411d20038f202a387005e9e52c4da96efff2543052066628928ab3.json} (81%) rename .sqlx/{query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json => query-5a182a71c0ec051f1922c9acc230c7d92948cf8cdbd4b286c933ee5837c7742d.json} (83%) rename .sqlx/{query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json => query-5e37c04f21a27b0fc6d2f9601c3431b27088d9184f057d65ab3905f871f75f45.json} (51%) create mode 100644 .sqlx/query-6845c1ccfd21971b75aeed84b8b65ca9044f8c312bedeff84f7b43a7d8828ca6.json create mode 100644 .sqlx/query-76438520a51fa88577083a3afbb93c9228c8e9d3599ef18ac27b3eb21fe62493.json create mode 100644 .sqlx/query-7a6197ba144639d082b045df8edbe8955ea8f6ae27b3ee149c45e4c4e48e8356.json delete mode 100644 .sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json rename .sqlx/{query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json => query-8038e5565e848d879610eec67d066ac83d1faff5885ff3ac3347aa0dbb578ed7.json} (83%) delete mode 100644 .sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json rename .sqlx/{query-e5aae22fd1a1340ba316f075db39714f2512ce12f4ae8c1adedc62c1568318b4.json => query-8e6cb215f790a4accafbcc2bea1027a59beec55d8f7a752ba53c31ea6213a4e9.json} (62%) rename .sqlx/{query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json => query-8f47974042b589d0c86cebf3928f9e1c44b7200b2c5c01ac168a0889b5978cbf.json} (83%) rename .sqlx/{query-729272d426ab025f035127591ead571b903aaf7d79f007ae9dc2b2a3e1e1a4fe.json => query-916604612f143e88df80a52509c50d8961cfb668bd090841c282e46ea5e17daa.json} (62%) create mode 100644 .sqlx/query-955b4fba4689c0ae0a5eb46631fdc38ed92ac74d690c3f5a70a1fb94d9164a89.json rename .sqlx/{query-cb138592ce7742ff0c805aebfb2039f6f10db6b56ec1c735e826b41eb7b544bb.json => query-9fa338a4791d1d98c23ffe4284f1b37a40c0c536d5a22906ca3e219dee574889.json} (79%) rename .sqlx/{query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json => query-a8a971bb02c8be9dfdb99fd47f397d450056592c1e2dffa1f1607835a926ef43.json} (79%) rename .sqlx/{query-426e89855980908db46b9566e8ea3112c0e3ec26148b24cf8afae3da998b2793.json => query-af6e8be6d3535ac46c84233012c860df566158a3b021474b893f40acabd21757.json} (79%) rename .sqlx/{query-a4b03897d84e7da9d601dd6c8a52a43ecbbaf55d1bb151895cab114db06aa3c9.json => query-b4e65188357c477e6ed29ad64b0039e0752c151529f6e2c0f79438064bd426d3.json} (69%) rename .sqlx/{query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json => query-bd1b6e92faeb94dac5799a94848f833933ed9544178376d20330697fd294bad5.json} (79%) rename .sqlx/{query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json => query-c8787e1811247788ec9793a5e94a9538b32e20487791f8f5066872dbccf55254.json} (79%) delete mode 100644 .sqlx/query-cbd40393c1353f301aff405b97415d94b57d8ad2516f2ee3aee5434d833f9136.json rename .sqlx/{query-92ea44776acc20cd60fa608be4274ba0758e778a533048802b3ddfe71b5df035.json => query-dce1744d3f53d3dbda512f9f489ab91b537664d85c6970b8ef8d495ea201957a.json} (80%) create mode 100644 .sqlx/query-ffeb193a66da6b7d218b6e21353dcf3854a56af2ae3bb1d31a5334db682b7471.json diff --git a/.sqlx/query-06802a4efba6dc3e16e65769f739dd1506bb3ac5b040e71c70a6f929e6a49f44.json b/.sqlx/query-06802a4efba6dc3e16e65769f739dd1506bb3ac5b040e71c70a6f929e6a49f44.json new file mode 100644 index 00000000..83fbae97 --- /dev/null +++ b/.sqlx/query-06802a4efba6dc3e16e65769f739dd1506bb3ac5b040e71c70a6f929e6a49f44.json @@ -0,0 +1,50 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height`\n FROM `dids`\n WHERE `coin_id` = ?\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "coin_id", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_owned", + "ordinal": 3, + "type_info": "Bool" + }, + { + "name": "visible", + "ordinal": 4, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 5, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + true, + false, + false, + true + ] + }, + "hash": "06802a4efba6dc3e16e65769f739dd1506bb3ac5b040e71c70a6f929e6a49f44" +} diff --git a/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json b/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json deleted file mode 100644 index cedc8d4d..00000000 --- a/.sqlx/query-09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM `dids` WHERE `coin_id` = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "09141039687b4746422caea968855d13fa2554ed7ef81b52d9cce472d9e01e9f" -} diff --git a/.sqlx/query-120103ccc25632c23e168d21bf1bfca53d56dd3250106bcafff91862a56a454a.json b/.sqlx/query-120103ccc25632c23e168d21bf1bfca53d56dd3250106bcafff91862a56a454a.json deleted file mode 100644 index 39f095b9..00000000 --- a/.sqlx/query-120103ccc25632c23e168d21bf1bfca53d56dd3250106bcafff91862a56a454a.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n REPLACE INTO `dids` (\n `launcher_id`,\n `name`,\n `visible`\n )\n VALUES (?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "120103ccc25632c23e168d21bf1bfca53d56dd3250106bcafff91862a56a454a" -} diff --git a/.sqlx/query-fd6d6e505e9619e149c6868fe4af5c2564050ff0583c62a2d2c449a808d421e0.json b/.sqlx/query-18324ab210540c63143113e4ccaa80176c38ec677470f4698520123113eda896.json similarity index 79% rename from .sqlx/query-fd6d6e505e9619e149c6868fe4af5c2564050ff0583c62a2d2c449a808d421e0.json rename to .sqlx/query-18324ab210540c63143113e4ccaa80176c38ec677470f4698520123113eda896.json index 5321648f..cc23aca5 100644 --- a/.sqlx/query-fd6d6e505e9619e149c6868fe4af5c2564050ff0583c62a2d2c449a808d421e0.json +++ b/.sqlx/query-18324ab210540c63143113e4ccaa80176c38ec677470f4698520123113eda896.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "fd6d6e505e9619e149c6868fe4af5c2564050ff0583c62a2d2c449a808d421e0" + "hash": "18324ab210540c63143113e4ccaa80176c38ec677470f4698520123113eda896" } diff --git a/.sqlx/query-1a6d7c18b1fb2286ebade255b4f3380a1312e0530c1ba0418e783a7be8a521cb.json b/.sqlx/query-1a6d7c18b1fb2286ebade255b4f3380a1312e0530c1ba0418e783a7be8a521cb.json index 21490521..a66b7856 100644 --- a/.sqlx/query-1a6d7c18b1fb2286ebade255b4f3380a1312e0530c1ba0418e783a7be8a521cb.json +++ b/.sqlx/query-1a6d7c18b1fb2286ebade255b4f3380a1312e0530c1ba0418e783a7be8a521cb.json @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,6 +81,7 @@ false, false, true, + false, true, true, true, diff --git a/.sqlx/query-1faa3ca5ae4dd907238ffac15c6a74ae9c6b0b6efafdc2a41d2597691ada155e.json b/.sqlx/query-1faa3ca5ae4dd907238ffac15c6a74ae9c6b0b6efafdc2a41d2597691ada155e.json new file mode 100644 index 00000000..8379ce71 --- /dev/null +++ b/.sqlx/query-1faa3ca5ae4dd907238ffac15c6a74ae9c6b0b6efafdc2a41d2597691ada155e.json @@ -0,0 +1,92 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n WHERE `is_owned` = 1 AND `visible` = 1\n ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "coin_id", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "collection_id", + "ordinal": 2, + "type_info": "Blob" + }, + { + "name": "minter_did", + "ordinal": 3, + "type_info": "Blob" + }, + { + "name": "owner_did", + "ordinal": 4, + "type_info": "Blob" + }, + { + "name": "visible", + "ordinal": 5, + "type_info": "Bool" + }, + { + "name": "sensitive_content", + "ordinal": 6, + "type_info": "Bool" + }, + { + "name": "name", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "is_owned", + "ordinal": 8, + "type_info": "Bool" + }, + { + "name": "is_named", + "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, + "type_info": "Integer" + }, + { + "name": "is_pending", + "ordinal": 11, + "type_info": "Bool" + }, + { + "name": "metadata_hash", + "ordinal": 12, + "type_info": "Blob" + } + ], + "parameters": { + "Right": 2 + }, + "nullable": [ + false, + false, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + true + ] + }, + "hash": "1faa3ca5ae4dd907238ffac15c6a74ae9c6b0b6efafdc2a41d2597691ada155e" +} diff --git a/.sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json b/.sqlx/query-20505bc0166a86dc2be61d1ce71251533e25a0291ce0f05f4f68c70cb6daba94.json similarity index 63% rename from .sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json rename to .sqlx/query-20505bc0166a86dc2be61d1ce71251533e25a0291ce0f05f4f68c70cb6daba94.json index 90ead4d4..82303739 100644 --- a/.sqlx/query-9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d.json +++ b/.sqlx/query-20505bc0166a86dc2be61d1ce71251533e25a0291ce0f05f4f68c70cb6daba94.json @@ -1,12 +1,12 @@ { "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "query": "\n INSERT OR IGNORE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`,\n `fetched`\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ", "describe": { "columns": [], "parameters": { - "Right": 6 + "Right": 7 }, "nullable": [] }, - "hash": "9372f01c10a7efdc7526534994ceaed228797892e896eccb47d26483d8ab771d" + "hash": "20505bc0166a86dc2be61d1ce71251533e25a0291ce0f05f4f68c70cb6daba94" } diff --git a/.sqlx/query-b8e2f31145c5fb41476b842038c101485e6bacbbf9c47dacae28c680445d537a.json b/.sqlx/query-2462446e09a04413761893bfc3d3ecfa5223ab64a169a5d2ec75eed7610a4480.json similarity index 62% rename from .sqlx/query-b8e2f31145c5fb41476b842038c101485e6bacbbf9c47dacae28c680445d537a.json rename to .sqlx/query-2462446e09a04413761893bfc3d3ecfa5223ab64a169a5d2ec75eed7610a4480.json index 80225d1a..16960949 100644 --- a/.sqlx/query-b8e2f31145c5fb41476b842038c101485e6bacbbf9c47dacae28c680445d537a.json +++ b/.sqlx/query-2462446e09a04413761893bfc3d3ecfa5223ab64a169a5d2ec75eed7610a4480.json @@ -1,12 +1,12 @@ { "db_name": "SQLite", - "query": "REPLACE INTO `nfts` (\n `launcher_id`,\n `coin_id`,\n `collection_id`,\n `minter_did`,\n `owner_did`,\n `visible`,\n `sensitive_content`,\n `name`,\n `created_height`,\n `metadata_hash`\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "query": "REPLACE INTO `nfts` (\n `launcher_id`,\n `coin_id`,\n `collection_id`,\n `minter_did`,\n `owner_did`,\n `visible`,\n `sensitive_content`,\n `name`,\n `is_owned`,\n `created_height`,\n `metadata_hash`\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "describe": { "columns": [], "parameters": { - "Right": 10 + "Right": 11 }, "nullable": [] }, - "hash": "b8e2f31145c5fb41476b842038c101485e6bacbbf9c47dacae28c680445d537a" + "hash": "2462446e09a04413761893bfc3d3ecfa5223ab64a169a5d2ec75eed7610a4480" } diff --git a/.sqlx/query-275b72aec6c3642621c64403265debc939d2d2e4c3fc788ce2a492eb5c2840d6.json b/.sqlx/query-275b72aec6c3642621c64403265debc939d2d2e4c3fc788ce2a492eb5c2840d6.json new file mode 100644 index 00000000..b844f1f4 --- /dev/null +++ b/.sqlx/query-275b72aec6c3642621c64403265debc939d2d2e4c3fc788ce2a492eb5c2840d6.json @@ -0,0 +1,20 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT `name` FROM `future_did_names`\n WHERE `launcher_id` = ?\n ", + "describe": { + "columns": [ + { + "name": "name", + "ordinal": 0, + "type_info": "Text" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false + ] + }, + "hash": "275b72aec6c3642621c64403265debc939d2d2e4c3fc788ce2a492eb5c2840d6" +} diff --git a/.sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json b/.sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json deleted file mode 100644 index d5180397..00000000 --- a/.sqlx/query-27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n `launcher_id`, `coin_id`, `collection_id`, `minter_did`, `owner_did`,\n `visible`, `sensitive_content`, `name`, `created_height`, `metadata_hash`\n FROM `nfts`\n WHERE `launcher_id` = ?\n ", - "describe": { - "columns": [ - { - "name": "launcher_id", - "ordinal": 0, - "type_info": "Blob" - }, - { - "name": "coin_id", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "collection_id", - "ordinal": 2, - "type_info": "Blob" - }, - { - "name": "minter_did", - "ordinal": 3, - "type_info": "Blob" - }, - { - "name": "owner_did", - "ordinal": 4, - "type_info": "Blob" - }, - { - "name": "visible", - "ordinal": 5, - "type_info": "Bool" - }, - { - "name": "sensitive_content", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "name", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "created_height", - "ordinal": 8, - "type_info": "Integer" - }, - { - "name": "metadata_hash", - "ordinal": 9, - "type_info": "Blob" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - true, - true, - true, - false, - false, - true, - true, - true - ] - }, - "hash": "27bcc863bcb231d0842ead57e9bff60caf0240ca348a85d51034432840571324" -} diff --git a/.sqlx/query-651c1fd0f3ce348d243a2ed185b540d444022f3cdaa2e79cb1fa77c8a80b0437.json b/.sqlx/query-3bd7cba585f5be0c92ad3bbea36c3b9b2e0d01e9bd45d8052018a2a93ad57b30.json similarity index 81% rename from .sqlx/query-651c1fd0f3ce348d243a2ed185b540d444022f3cdaa2e79cb1fa77c8a80b0437.json rename to .sqlx/query-3bd7cba585f5be0c92ad3bbea36c3b9b2e0d01e9bd45d8052018a2a93ad57b30.json index 138d171e..c65dc6e3 100644 --- a/.sqlx/query-651c1fd0f3ce348d243a2ed185b540d444022f3cdaa2e79cb1fa77c8a80b0437.json +++ b/.sqlx/query-3bd7cba585f5be0c92ad3bbea36c3b9b2e0d01e9bd45d8052018a2a93ad57b30.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_recent`\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_recent`\n WHERE `is_owned` = 1\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "651c1fd0f3ce348d243a2ed185b540d444022f3cdaa2e79cb1fa77c8a80b0437" + "hash": "3bd7cba585f5be0c92ad3bbea36c3b9b2e0d01e9bd45d8052018a2a93ad57b30" } diff --git a/.sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json b/.sqlx/query-49f9b8dedcf7ac304d7f622e011452176fee280f2734f0a13fd7d38147062cd8.json similarity index 79% rename from .sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json rename to .sqlx/query-49f9b8dedcf7ac304d7f622e011452176fee280f2734f0a13fd7d38147062cd8.json index 92ca55f6..19e26a87 100644 --- a/.sqlx/query-bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34.json +++ b/.sqlx/query-49f9b8dedcf7ac304d7f622e011452176fee280f2734f0a13fd7d38147062cd8.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` = ?\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `is_owned` = 1 AND `collection_id` = ?\n ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "bcf99e416d5b9dba799561190583d24224319e2f51e3b060d0374555afd9ef34" + "hash": "49f9b8dedcf7ac304d7f622e011452176fee280f2734f0a13fd7d38147062cd8" } diff --git a/.sqlx/query-4e57a9bc7318609e6c2b2fe3130f64350fe914edea4a35d21dbf77bd687c1eb4.json b/.sqlx/query-4e57a9bc7318609e6c2b2fe3130f64350fe914edea4a35d21dbf77bd687c1eb4.json new file mode 100644 index 00000000..83510500 --- /dev/null +++ b/.sqlx/query-4e57a9bc7318609e6c2b2fe3130f64350fe914edea4a35d21dbf77bd687c1eb4.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n REPLACE INTO `dids` (\n `launcher_id`,\n `coin_id`,\n `name`,\n `is_owned`,\n `visible`,\n `created_height`\n )\n VALUES (?, ?, ?, ?, ?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 6 + }, + "nullable": [] + }, + "hash": "4e57a9bc7318609e6c2b2fe3130f64350fe914edea4a35d21dbf77bd687c1eb4" +} diff --git a/.sqlx/query-f3703966c1cb30cfff1d68ab2f6019868d0263f46896585a2318a4d14d2f286c.json b/.sqlx/query-4fc58bf2b8411d20038f202a387005e9e52c4da96efff2543052066628928ab3.json similarity index 81% rename from .sqlx/query-f3703966c1cb30cfff1d68ab2f6019868d0263f46896585a2318a4d14d2f286c.json rename to .sqlx/query-4fc58bf2b8411d20038f202a387005e9e52c4da96efff2543052066628928ab3.json index c439cdeb..b695a601 100644 --- a/.sqlx/query-f3703966c1cb30cfff1d68ab2f6019868d0263f46896585a2318a4d14d2f286c.json +++ b/.sqlx/query-4fc58bf2b8411d20038f202a387005e9e52c4da96efff2543052066628928ab3.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_recent`\n WHERE `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_recent`\n WHERE `is_owned` = 1 AND `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "f3703966c1cb30cfff1d68ab2f6019868d0263f46896585a2318a4d14d2f286c" + "hash": "4fc58bf2b8411d20038f202a387005e9e52c4da96efff2543052066628928ab3" } diff --git a/.sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json b/.sqlx/query-5a182a71c0ec051f1922c9acc230c7d92948cf8cdbd4b286c933ee5837c7742d.json similarity index 83% rename from .sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json rename to .sqlx/query-5a182a71c0ec051f1922c9acc230c7d92948cf8cdbd4b286c933ee5837c7742d.json index 821357ef..6b6b329c 100644 --- a/.sqlx/query-fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f.json +++ b/.sqlx/query-5a182a71c0ec051f1922c9acc230c7d92948cf8cdbd4b286c933ee5837c7742d.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` WHERE `coin_id` = ?\n ", "describe": { "columns": [ { @@ -44,28 +44,33 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], "parameters": { - "Right": 2 + "Right": 1 }, "nullable": [ false, @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "fedfc41e839aab794f9e89e6c20a82039a5d00c8ab27f09c12887a76d2291a3f" + "hash": "5a182a71c0ec051f1922c9acc230c7d92948cf8cdbd4b286c933ee5837c7742d" } diff --git a/.sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json b/.sqlx/query-5e37c04f21a27b0fc6d2f9601c3431b27088d9184f057d65ab3905f871f75f45.json similarity index 51% rename from .sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json rename to .sqlx/query-5e37c04f21a27b0fc6d2f9601c3431b27088d9184f057d65ab3905f871f75f45.json index acac3f88..28ce79d9 100644 --- a/.sqlx/query-290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f.json +++ b/.sqlx/query-5e37c04f21a27b0fc6d2f9601c3431b27088d9184f057d65ab3905f871f75f45.json @@ -1,12 +1,12 @@ { "db_name": "SQLite", - "query": "\n REPLACE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`\n ) VALUES (?, ?, ?, ?, ?, ?)\n ", + "query": "\n REPLACE INTO `cats` (\n `asset_id`,\n `name`,\n `ticker`,\n `description`,\n `icon`,\n `visible`,\n `fetched`\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ", "describe": { "columns": [], "parameters": { - "Right": 6 + "Right": 7 }, "nullable": [] }, - "hash": "290801ae0a77e2a98d8834373edaf33acd8125a09e05672703f14cd6ed70d51f" + "hash": "5e37c04f21a27b0fc6d2f9601c3431b27088d9184f057d65ab3905f871f75f45" } diff --git a/.sqlx/query-6845c1ccfd21971b75aeed84b8b65ca9044f8c312bedeff84f7b43a7d8828ca6.json b/.sqlx/query-6845c1ccfd21971b75aeed84b8b65ca9044f8c312bedeff84f7b43a7d8828ca6.json new file mode 100644 index 00000000..7cd960e1 --- /dev/null +++ b/.sqlx/query-6845c1ccfd21971b75aeed84b8b65ca9044f8c312bedeff84f7b43a7d8828ca6.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n REPLACE INTO `future_did_names` (`launcher_id`, `name`)\n VALUES (?, ?)\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 2 + }, + "nullable": [] + }, + "hash": "6845c1ccfd21971b75aeed84b8b65ca9044f8c312bedeff84f7b43a7d8828ca6" +} diff --git a/.sqlx/query-76438520a51fa88577083a3afbb93c9228c8e9d3599ef18ac27b3eb21fe62493.json b/.sqlx/query-76438520a51fa88577083a3afbb93c9228c8e9d3599ef18ac27b3eb21fe62493.json new file mode 100644 index 00000000..abf20210 --- /dev/null +++ b/.sqlx/query-76438520a51fa88577083a3afbb93c9228c8e9d3599ef18ac27b3eb21fe62493.json @@ -0,0 +1,50 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height`\n FROM `dids`\n WHERE `launcher_id` = ?\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "coin_id", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_owned", + "ordinal": 3, + "type_info": "Bool" + }, + { + "name": "visible", + "ordinal": 4, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 5, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + true, + false, + false, + true + ] + }, + "hash": "76438520a51fa88577083a3afbb93c9228c8e9d3599ef18ac27b3eb21fe62493" +} diff --git a/.sqlx/query-7a6197ba144639d082b045df8edbe8955ea8f6ae27b3ee149c45e4c4e48e8356.json b/.sqlx/query-7a6197ba144639d082b045df8edbe8955ea8f6ae27b3ee149c45e4c4e48e8356.json new file mode 100644 index 00000000..f7258cb7 --- /dev/null +++ b/.sqlx/query-7a6197ba144639d082b045df8edbe8955ea8f6ae27b3ee149c45e4c4e48e8356.json @@ -0,0 +1,92 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n WHERE `is_owned` = 1\n ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "coin_id", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "collection_id", + "ordinal": 2, + "type_info": "Blob" + }, + { + "name": "minter_did", + "ordinal": 3, + "type_info": "Blob" + }, + { + "name": "owner_did", + "ordinal": 4, + "type_info": "Blob" + }, + { + "name": "visible", + "ordinal": 5, + "type_info": "Bool" + }, + { + "name": "sensitive_content", + "ordinal": 6, + "type_info": "Bool" + }, + { + "name": "name", + "ordinal": 7, + "type_info": "Text" + }, + { + "name": "is_owned", + "ordinal": 8, + "type_info": "Bool" + }, + { + "name": "is_named", + "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, + "type_info": "Integer" + }, + { + "name": "is_pending", + "ordinal": 11, + "type_info": "Bool" + }, + { + "name": "metadata_hash", + "ordinal": 12, + "type_info": "Blob" + } + ], + "parameters": { + "Right": 2 + }, + "nullable": [ + false, + false, + true, + true, + true, + false, + false, + true, + false, + true, + true, + true, + true + ] + }, + "hash": "7a6197ba144639d082b045df8edbe8955ea8f6ae27b3ee149c45e4c4e48e8356" +} diff --git a/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json b/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json deleted file mode 100644 index 04a209c9..00000000 --- a/.sqlx/query-7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM `nfts` WHERE `coin_id` = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "7e0928eb4ca01ac787f91951ed3f5ef2822be7c119d8cbe35b3b437717ddf835" -} diff --git a/.sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json b/.sqlx/query-8038e5565e848d879610eec67d066ac83d1faff5885ff3ac3347aa0dbb578ed7.json similarity index 83% rename from .sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json rename to .sqlx/query-8038e5565e848d879610eec67d066ac83d1faff5885ff3ac3347aa0dbb578ed7.json index dca812b0..d053995d 100644 --- a/.sqlx/query-da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77.json +++ b/.sqlx/query-8038e5565e848d879610eec67d066ac83d1faff5885ff3ac3347aa0dbb578ed7.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_name`\n WHERE `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` WHERE `launcher_id` = ?\n ", "describe": { "columns": [ { @@ -44,28 +44,33 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], "parameters": { - "Right": 2 + "Right": 1 }, "nullable": [ false, @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "da7cd3f299ba4af0f1212fae19798593903bccf9dd3509d3c2550c4d60ca5d77" + "hash": "8038e5565e848d879610eec67d066ac83d1faff5885ff3ac3347aa0dbb578ed7" } diff --git a/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json b/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json deleted file mode 100644 index fe313b88..00000000 --- a/.sqlx/query-885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT `launcher_id`, `name`, `visible`\n FROM `dids` INDEXED BY `did_name`\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n ", - "describe": { - "columns": [ - { - "name": "launcher_id", - "ordinal": 0, - "type_info": "Blob" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "visible", - "ordinal": 2, - "type_info": "Bool" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false, - true, - false - ] - }, - "hash": "885a68dd9e657daf1a45386c78ce6042acf426ff734ebff07a6a139a7f6ab1a3" -} diff --git a/.sqlx/query-e5aae22fd1a1340ba316f075db39714f2512ce12f4ae8c1adedc62c1568318b4.json b/.sqlx/query-8e6cb215f790a4accafbcc2bea1027a59beec55d8f7a752ba53c31ea6213a4e9.json similarity index 62% rename from .sqlx/query-e5aae22fd1a1340ba316f075db39714f2512ce12f4ae8c1adedc62c1568318b4.json rename to .sqlx/query-8e6cb215f790a4accafbcc2bea1027a59beec55d8f7a752ba53c31ea6213a4e9.json index 91561943..aa5d2f0a 100644 --- a/.sqlx/query-e5aae22fd1a1340ba316f075db39714f2512ce12f4ae8c1adedc62c1568318b4.json +++ b/.sqlx/query-8e6cb215f790a4accafbcc2bea1027a59beec55d8f7a752ba53c31ea6213a4e9.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` IS NULL AND `visible` = 1\n ", + "query": "\n SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1\n ", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "e5aae22fd1a1340ba316f075db39714f2512ce12f4ae8c1adedc62c1568318b4" + "hash": "8e6cb215f790a4accafbcc2bea1027a59beec55d8f7a752ba53c31ea6213a4e9" } diff --git a/.sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json b/.sqlx/query-8f47974042b589d0c86cebf3928f9e1c44b7200b2c5c01ac168a0889b5978cbf.json similarity index 83% rename from .sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json rename to .sqlx/query-8f47974042b589d0c86cebf3928f9e1c44b7200b2c5c01ac168a0889b5978cbf.json index ae6c3ff9..2b61b43d 100644 --- a/.sqlx/query-3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a.json +++ b/.sqlx/query-8f47974042b589d0c86cebf3928f9e1c44b7200b2c5c01ac168a0889b5978cbf.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT\n `did_coins`.`coin_id`, `amount`, `p2_puzzle_hash`, `created_height`, `transaction_id`\n FROM `did_coins`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `did_coins`.coin_id\n WHERE `launcher_id` = ?\n ", + "query": "\n SELECT\n `did_coins`.`coin_id`, `amount`, `p2_puzzle_hash`, `created_height`, `transaction_id`\n FROM `did_coins`\n INNER JOIN `coin_states` ON `coin_states`.coin_id = `did_coins`.coin_id\n WHERE `did_coins`.`coin_id` = ?\n ", "describe": { "columns": [ { @@ -40,5 +40,5 @@ true ] }, - "hash": "3ee0f50cd35af4a9774535f01a0cd40fc44738708a5972273bb86d17f7a7694a" + "hash": "8f47974042b589d0c86cebf3928f9e1c44b7200b2c5c01ac168a0889b5978cbf" } diff --git a/.sqlx/query-729272d426ab025f035127591ead571b903aaf7d79f007ae9dc2b2a3e1e1a4fe.json b/.sqlx/query-916604612f143e88df80a52509c50d8961cfb668bd090841c282e46ea5e17daa.json similarity index 62% rename from .sqlx/query-729272d426ab025f035127591ead571b903aaf7d79f007ae9dc2b2a3e1e1a4fe.json rename to .sqlx/query-916604612f143e88df80a52509c50d8961cfb668bd090841c282e46ea5e17daa.json index 98751477..ee2263b0 100644 --- a/.sqlx/query-729272d426ab025f035127591ead571b903aaf7d79f007ae9dc2b2a3e1e1a4fe.json +++ b/.sqlx/query-916604612f143e88df80a52509c50d8961cfb668bd090841c282e46ea5e17daa.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` = ? AND `visible` = 1\n ", + "query": "\n SELECT COUNT(*) AS `count` FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1\n ", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "729272d426ab025f035127591ead571b903aaf7d79f007ae9dc2b2a3e1e1a4fe" + "hash": "916604612f143e88df80a52509c50d8961cfb668bd090841c282e46ea5e17daa" } diff --git a/.sqlx/query-955b4fba4689c0ae0a5eb46631fdc38ed92ac74d690c3f5a70a1fb94d9164a89.json b/.sqlx/query-955b4fba4689c0ae0a5eb46631fdc38ed92ac74d690c3f5a70a1fb94d9164a89.json new file mode 100644 index 00000000..99db9ff7 --- /dev/null +++ b/.sqlx/query-955b4fba4689c0ae0a5eb46631fdc38ed92ac74d690c3f5a70a1fb94d9164a89.json @@ -0,0 +1,50 @@ +{ + "db_name": "SQLite", + "query": "\n SELECT `launcher_id`, `coin_id`, `name`, `is_owned`, `visible`, `created_height`\n FROM `dids` INDEXED BY `did_name`\n WHERE `is_owned` = 1\n ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n ", + "describe": { + "columns": [ + { + "name": "launcher_id", + "ordinal": 0, + "type_info": "Blob" + }, + { + "name": "coin_id", + "ordinal": 1, + "type_info": "Blob" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_owned", + "ordinal": 3, + "type_info": "Bool" + }, + { + "name": "visible", + "ordinal": 4, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 5, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + false, + false, + true, + false, + false, + true + ] + }, + "hash": "955b4fba4689c0ae0a5eb46631fdc38ed92ac74d690c3f5a70a1fb94d9164a89" +} diff --git a/.sqlx/query-cb138592ce7742ff0c805aebfb2039f6f10db6b56ec1c735e826b41eb7b544bb.json b/.sqlx/query-9fa338a4791d1d98c23ffe4284f1b37a40c0c536d5a22906ca3e219dee574889.json similarity index 79% rename from .sqlx/query-cb138592ce7742ff0c805aebfb2039f6f10db6b56ec1c735e826b41eb7b544bb.json rename to .sqlx/query-9fa338a4791d1d98c23ffe4284f1b37a40c0c536d5a22906ca3e219dee574889.json index 67cdd296..5e5164ce 100644 --- a/.sqlx/query-cb138592ce7742ff0c805aebfb2039f6f10db6b56ec1c735e826b41eb7b544bb.json +++ b/.sqlx/query-9fa338a4791d1d98c23ffe4284f1b37a40c0c536d5a22906ca3e219dee574889.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "cb138592ce7742ff0c805aebfb2039f6f10db6b56ec1c735e826b41eb7b544bb" + "hash": "9fa338a4791d1d98c23ffe4284f1b37a40c0c536d5a22906ca3e219dee574889" } diff --git a/.sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json b/.sqlx/query-a8a971bb02c8be9dfdb99fd47f397d450056592c1e2dffa1f1607835a926ef43.json similarity index 79% rename from .sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json rename to .sqlx/query-a8a971bb02c8be9dfdb99fd47f397d450056592c1e2dffa1f1607835a926ef43.json index d2ebecc4..e9930d11 100644 --- a/.sqlx/query-4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633.json +++ b/.sqlx/query-a8a971bb02c8be9dfdb99fd47f397d450056592c1e2dffa1f1607835a926ef43.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `is_owned` = 1 AND `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "4418e81b920e44358f62c0fac6cbe3430d1a7dcf3f0efcc68ae81c4fbcdda633" + "hash": "a8a971bb02c8be9dfdb99fd47f397d450056592c1e2dffa1f1607835a926ef43" } diff --git a/.sqlx/query-426e89855980908db46b9566e8ea3112c0e3ec26148b24cf8afae3da998b2793.json b/.sqlx/query-af6e8be6d3535ac46c84233012c860df566158a3b021474b893f40acabd21757.json similarity index 79% rename from .sqlx/query-426e89855980908db46b9566e8ea3112c0e3ec26148b24cf8afae3da998b2793.json rename to .sqlx/query-af6e8be6d3535ac46c84233012c860df566158a3b021474b893f40acabd21757.json index 01ff6847..e81f8426 100644 --- a/.sqlx/query-426e89855980908db46b9566e8ea3112c0e3ec26148b24cf8afae3da998b2793.json +++ b/.sqlx/query-af6e8be6d3535ac46c84233012c860df566158a3b021474b893f40acabd21757.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` = ?\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "426e89855980908db46b9566e8ea3112c0e3ec26148b24cf8afae3da998b2793" + "hash": "af6e8be6d3535ac46c84233012c860df566158a3b021474b893f40acabd21757" } diff --git a/.sqlx/query-a4b03897d84e7da9d601dd6c8a52a43ecbbaf55d1bb151895cab114db06aa3c9.json b/.sqlx/query-b4e65188357c477e6ed29ad64b0039e0752c151529f6e2c0f79438064bd426d3.json similarity index 69% rename from .sqlx/query-a4b03897d84e7da9d601dd6c8a52a43ecbbaf55d1bb151895cab114db06aa3c9.json rename to .sqlx/query-b4e65188357c477e6ed29ad64b0039e0752c151529f6e2c0f79438064bd426d3.json index 7f781ff0..a015660b 100644 --- a/.sqlx/query-a4b03897d84e7da9d601dd6c8a52a43ecbbaf55d1bb151895cab114db06aa3c9.json +++ b/.sqlx/query-b4e65188357c477e6ed29ad64b0039e0752c151529f6e2c0f79438064bd426d3.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT COUNT(*) AS `count` FROM `nfts`\n WHERE `visible` = 1\n ", + "query": "\n SELECT COUNT(*) AS `count` FROM `nfts`\n WHERE `is_owned` = 1 AND `visible` = 1\n ", "describe": { "columns": [ { @@ -16,5 +16,5 @@ false ] }, - "hash": "a4b03897d84e7da9d601dd6c8a52a43ecbbaf55d1bb151895cab114db06aa3c9" + "hash": "b4e65188357c477e6ed29ad64b0039e0752c151529f6e2c0f79438064bd426d3" } diff --git a/.sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json b/.sqlx/query-bd1b6e92faeb94dac5799a94848f833933ed9544178376d20330697fd294bad5.json similarity index 79% rename from .sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json rename to .sqlx/query-bd1b6e92faeb94dac5799a94848f833933ed9544178376d20330697fd294bad5.json index cface394..3cca8344 100644 --- a/.sqlx/query-7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac.json +++ b/.sqlx/query-bd1b6e92faeb94dac5799a94848f833933ed9544178376d20330697fd294bad5.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` = ? AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `is_owned` = 1 AND `collection_id` = ? AND `visible` = 1\n ORDER BY `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "7763bd090bb529a3a99b01247481de663c57bb48d6ab125e6ac16ed2b892c6ac" + "hash": "bd1b6e92faeb94dac5799a94848f833933ed9544178376d20330697fd294bad5" } diff --git a/.sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json b/.sqlx/query-c8787e1811247788ec9793a5e94a9538b32e20487791f8f5066872dbccf55254.json similarity index 79% rename from .sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json rename to .sqlx/query-c8787e1811247788ec9793a5e94a9538b32e20487791f8f5066872dbccf55254.json index e25e5a66..53428667 100644 --- a/.sqlx/query-ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197.json +++ b/.sqlx/query-c8787e1811247788ec9793a5e94a9538b32e20487791f8f5066872dbccf55254.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `collection_id` IS NULL AND `visible` = 1\n ORDER BY `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_name`\n WHERE `is_owned` = 1 AND `collection_id` IS NULL\n ORDER BY `visible` DESC, `is_pending` DESC, `is_named` DESC, `name` ASC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "ccc8aae7152c89876d3bb3cdb95da111ce22987b95dbdc255dc3f404bd269197" + "hash": "c8787e1811247788ec9793a5e94a9538b32e20487791f8f5066872dbccf55254" } diff --git a/.sqlx/query-cbd40393c1353f301aff405b97415d94b57d8ad2516f2ee3aee5434d833f9136.json b/.sqlx/query-cbd40393c1353f301aff405b97415d94b57d8ad2516f2ee3aee5434d833f9136.json deleted file mode 100644 index facb5d85..00000000 --- a/.sqlx/query-cbd40393c1353f301aff405b97415d94b57d8ad2516f2ee3aee5434d833f9136.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO `dids` (\n `launcher_id`,\n `name`,\n `visible`\n )\n VALUES (?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "cbd40393c1353f301aff405b97415d94b57d8ad2516f2ee3aee5434d833f9136" -} diff --git a/.sqlx/query-92ea44776acc20cd60fa608be4274ba0758e778a533048802b3ddfe71b5df035.json b/.sqlx/query-dce1744d3f53d3dbda512f9f489ab91b537664d85c6970b8ef8d495ea201957a.json similarity index 80% rename from .sqlx/query-92ea44776acc20cd60fa608be4274ba0758e778a533048802b3ddfe71b5df035.json rename to .sqlx/query-dce1744d3f53d3dbda512f9f489ab91b537664d85c6970b8ef8d495ea201957a.json index 1ca6bc7e..717e708c 100644 --- a/.sqlx/query-92ea44776acc20cd60fa608be4274ba0758e778a533048802b3ddfe71b5df035.json +++ b/.sqlx/query-dce1744d3f53d3dbda512f9f489ab91b537664d85c6970b8ef8d495ea201957a.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `collection_id` = ? AND `visible` = 1\n ORDER BY `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", + "query": "\n SELECT * FROM `nfts` INDEXED BY `nft_col_recent`\n WHERE `is_owned` = 1 AND `collection_id` = ?\n ORDER BY `visible` DESC, `is_pending` DESC, `created_height` DESC, `launcher_id` ASC\n LIMIT ? OFFSET ?\n ", "describe": { "columns": [ { @@ -44,23 +44,28 @@ "type_info": "Text" }, { - "name": "is_named", + "name": "is_owned", "ordinal": 8, "type_info": "Bool" }, { - "name": "created_height", + "name": "is_named", "ordinal": 9, + "type_info": "Bool" + }, + { + "name": "created_height", + "ordinal": 10, "type_info": "Integer" }, { "name": "is_pending", - "ordinal": 10, + "ordinal": 11, "type_info": "Bool" }, { "name": "metadata_hash", - "ordinal": 11, + "ordinal": 12, "type_info": "Blob" } ], @@ -76,11 +81,12 @@ false, false, true, + false, true, true, true, true ] }, - "hash": "92ea44776acc20cd60fa608be4274ba0758e778a533048802b3ddfe71b5df035" + "hash": "dce1744d3f53d3dbda512f9f489ab91b537664d85c6970b8ef8d495ea201957a" } diff --git a/.sqlx/query-ffeb193a66da6b7d218b6e21353dcf3854a56af2ae3bb1d31a5334db682b7471.json b/.sqlx/query-ffeb193a66da6b7d218b6e21353dcf3854a56af2ae3bb1d31a5334db682b7471.json new file mode 100644 index 00000000..4124cf74 --- /dev/null +++ b/.sqlx/query-ffeb193a66da6b7d218b6e21353dcf3854a56af2ae3bb1d31a5334db682b7471.json @@ -0,0 +1,12 @@ +{ + "db_name": "SQLite", + "query": "\n DELETE FROM `future_did_names` WHERE `launcher_id` = ?\n ", + "describe": { + "columns": [], + "parameters": { + "Right": 1 + }, + "nullable": [] + }, + "hash": "ffeb193a66da6b7d218b6e21353dcf3854a56af2ae3bb1d31a5334db682b7471" +}