Skip to content

Commit 7f00989

Browse files
committed
feat: update sql and vue for v1.0.0
1 parent 990fed2 commit 7f00989

File tree

7 files changed

+962
-895
lines changed

7 files changed

+962
-895
lines changed

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "Onchain Wallet",
33
"short_description": "Onchain watch only wallets",
44
"tile": "/watchonly/static/bitcoin-wallet.png",
5-
"min_lnbits_version": "0.11.0",
5+
"min_lnbits_version": "1.0.0",
66
"contributors": [
77
{
88
"name": "motorina0",

crud.py

Lines changed: 83 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,54 @@
22
from typing import Optional
33

44
from lnbits.db import Database
5-
from lnbits.helpers import urlsafe_short_hash
5+
from lnbits.helpers import insert_query, update_query, urlsafe_short_hash
66

77
from .helpers import derive_address
88
from .models import Address, Config, WalletAccount
99

1010
db = Database("ext_watchonly")
1111

1212

13-
async def create_watch_wallet(user: str, w: WalletAccount) -> WalletAccount:
14-
wallet_id = urlsafe_short_hash()
13+
async def create_watch_wallet(wallet: WalletAccount) -> WalletAccount:
1514
await db.execute(
16-
"""
17-
INSERT INTO watchonly.wallets (
18-
id,
19-
"user",
20-
masterpub,
21-
fingerprint,
22-
title,
23-
type,
24-
address_no,
25-
balance,
26-
network,
27-
meta
28-
)
29-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
30-
""",
31-
(
32-
wallet_id,
33-
user,
34-
w.masterpub,
35-
w.fingerprint,
36-
w.title,
37-
w.type,
38-
w.address_no,
39-
w.balance,
40-
w.network,
41-
w.meta,
42-
),
15+
insert_query("watchonly.wallets", wallet),
16+
wallet.dict(),
4317
)
44-
wallet = await get_watch_wallet(wallet_id)
45-
assert wallet
4618
return wallet
4719

4820

4921
async def get_watch_wallet(wallet_id: str) -> Optional[WalletAccount]:
5022
row = await db.fetchone(
51-
"SELECT * FROM watchonly.wallets WHERE id = ?", (wallet_id,)
23+
"SELECT * FROM watchonly.wallets WHERE id = :id",
24+
{"id": wallet_id},
5225
)
53-
return WalletAccount.from_row(row) if row else None
26+
return WalletAccount(**row) if row else None
5427

5528

5629
async def get_watch_wallets(user: str, network: str) -> list[WalletAccount]:
5730
rows = await db.fetchall(
58-
"""SELECT * FROM watchonly.wallets WHERE "user" = ? AND network = ?""",
59-
(user, network),
31+
"""
32+
SELECT * FROM watchonly.wallets
33+
WHERE "user" = :user AND network = :network
34+
""",
35+
{"user": user, "network": network},
6036
)
6137
return [WalletAccount(**row) for row in rows]
6238

6339

64-
async def update_watch_wallet(wallet_id: str, **kwargs) -> Optional[WalletAccount]:
65-
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
66-
40+
async def update_watch_wallet(wallet: WalletAccount) -> WalletAccount:
6741
await db.execute(
68-
f"UPDATE watchonly.wallets SET {q} WHERE id = ?", (*kwargs.values(), wallet_id)
42+
update_query("watchonly.wallets", wallet),
43+
wallet.dict(),
6944
)
70-
row = await db.fetchone(
71-
"SELECT * FROM watchonly.wallets WHERE id = ?", (wallet_id,)
72-
)
73-
return WalletAccount.from_row(row) if row else None
45+
return wallet
7446

7547

7648
async def delete_watch_wallet(wallet_id: str) -> None:
77-
await db.execute("DELETE FROM watchonly.wallets WHERE id = ?", (wallet_id,))
78-
79-
80-
########################ADDRESSES#######################
49+
await db.execute(
50+
"DELETE FROM watchonly.wallets WHERE id = :id",
51+
{"id": wallet_id},
52+
)
8153

8254

8355
async def get_fresh_address(wallet_id: str) -> Optional[Address]:
@@ -110,7 +82,8 @@ async def get_fresh_address(wallet_id: str) -> Optional[Address]:
11082
)
11183
address = addresses.pop()
11284

113-
await update_watch_wallet(wallet_id, **{"address_no": address_index + 1})
85+
wallet.address_no = address_index + 1
86+
await update_watch_wallet(wallet)
11487

11588
return address
11689

@@ -132,41 +105,55 @@ async def create_fresh_addresses(
132105

133106
for address_index in range(start_address_index, end_address_index):
134107
address = await derive_address(wallet.masterpub, address_index, branch_index)
108+
assert address # TODO: why optional
109+
110+
addr = Address(
111+
id=urlsafe_short_hash(),
112+
address=address,
113+
wallet=wallet_id,
114+
branch_index=branch_index,
115+
address_index=address_index,
116+
)
135117

136118
await db.execute(
137-
"""
138-
INSERT INTO watchonly.addresses (
139-
id,
140-
address,
141-
wallet,
142-
amount,
143-
branch_index,
144-
address_index
145-
)
146-
VALUES (?, ?, ?, ?, ?, ?)
147-
""",
148-
(urlsafe_short_hash(), address, wallet_id, 0, branch_index, address_index),
119+
insert_query("watchonly.addresses", addr),
120+
addr.dict(),
149121
)
150122

151123
# return fresh addresses
152124
rows = await db.fetchall(
153125
"""
154-
SELECT * FROM watchonly.addresses
155-
WHERE wallet = ? AND branch_index = ?
156-
AND address_index >= ? AND address_index < ?
126+
SELECT * FROM watchonly.addresses WHERE wallet = :wallet
127+
AND branch_index = :branch_index
128+
AND address_index >= :start_address_index
129+
AND address_index < :end_address_index
157130
ORDER BY branch_index, address_index
158131
""",
159-
(wallet_id, branch_index, start_address_index, end_address_index),
132+
{
133+
"wallet": wallet_id,
134+
"branch_index": branch_index,
135+
"start_address_index": start_address_index,
136+
"end_address_index": end_address_index,
137+
},
160138
)
161139

162140
return [Address(**row) for row in rows]
163141

164142

165143
async def get_address(address: str) -> Optional[Address]:
166144
row = await db.fetchone(
167-
"SELECT * FROM watchonly.addresses WHERE address = ?", (address,)
145+
"SELECT * FROM watchonly.addresses WHERE address = :address",
146+
{"address": address},
147+
)
148+
return Address(**row) if row else None
149+
150+
151+
async def get_address_by_id(address_id: str) -> Optional[Address]:
152+
row = await db.fetchone(
153+
"SELECT * FROM watchonly.addresses WHERE id = :id",
154+
{"id": address_id},
168155
)
169-
return Address.from_row(row) if row else None
156+
return Address(**row) if row else None
170157

171158

172159
async def get_address_at_index(
@@ -175,75 +162,75 @@ async def get_address_at_index(
175162
row = await db.fetchone(
176163
"""
177164
SELECT * FROM watchonly.addresses
178-
WHERE wallet = ? AND branch_index = ? AND address_index = ?
165+
WHERE wallet = :wallet AND branch_index = :branch_index
166+
AND address_index = :address_index
179167
""",
180-
(
181-
wallet_id,
182-
branch_index,
183-
address_index,
184-
),
168+
{
169+
"wallet": wallet_id,
170+
"branch_index": branch_index,
171+
"address_index": address_index,
172+
},
185173
)
186-
return Address.from_row(row) if row else None
174+
return Address(**row) if row else None
187175

188176

189177
async def get_addresses(wallet_id: str) -> list[Address]:
190178
rows = await db.fetchall(
191179
"""
192-
SELECT * FROM watchonly.addresses WHERE wallet = ?
193-
ORDER BY branch_index, address_index
180+
SELECT * FROM watchonly.addresses WHERE wallet = :wallet
181+
ORDER BY branch_index, address_index
194182
""",
195-
(wallet_id,),
183+
{"wallet": wallet_id},
196184
)
197185

198186
return [Address(**row) for row in rows]
199187

200188

201-
async def update_address(address_id: str, **kwargs) -> Address:
202-
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
203-
189+
async def update_address(address: Address) -> Address:
204190
await db.execute(
205-
f"""UPDATE watchonly.addresses SET {q} WHERE id = ? """,
206-
(*kwargs.values(), address_id),
207-
)
208-
row = await db.fetchone(
209-
"SELECT * FROM watchonly.addresses WHERE id = ?", (address_id,)
191+
update_query("watchonly.addresses", address),
192+
address.dict(),
210193
)
211-
assert row, "updated address not found"
212-
return Address.from_row(row)
194+
return address
213195

214196

215197
async def delete_addresses_for_wallet(wallet_id: str) -> None:
216-
await db.execute("DELETE FROM watchonly.addresses WHERE wallet = ?", (wallet_id,))
198+
await db.execute(
199+
"DELETE FROM watchonly.addresses WHERE wallet = :wallet", {"wallet": wallet_id}
200+
)
217201

218202

219203
async def create_config(user: str) -> Config:
220204
config = Config()
221205
await db.execute(
222206
"""
223207
INSERT INTO watchonly.config ("user", json_data)
224-
VALUES (?, ?)
208+
VALUES (:user, :data)
225209
""",
226-
(user, json.dumps(config.dict())),
210+
{"user": user, "data": json.dumps(config.dict())},
227211
)
228212
row = await db.fetchone(
229-
"""SELECT json_data FROM watchonly.config WHERE "user" = ?""", (user,)
213+
"""SELECT json_data FROM watchonly.config WHERE "user" = :user""",
214+
{"user": user},
230215
)
231216
return json.loads(row[0], object_hook=lambda d: Config(**d))
232217

233218

234-
async def update_config(config: Config, user: str) -> Optional[Config]:
219+
async def update_config(config: Config, user: str) -> Config:
235220
await db.execute(
236-
"""UPDATE watchonly.config SET json_data = ? WHERE "user" = ?""",
237-
(json.dumps(config.dict()), user),
221+
"""UPDATE watchonly.config SET json_data = :data WHERE "user" = :user""",
222+
{"data": json.dumps(config.dict()), "user": user},
238223
)
239224
row = await db.fetchone(
240-
"""SELECT json_data FROM watchonly.config WHERE "user" = ?""", (user,)
225+
"""SELECT json_data FROM watchonly.config WHERE "user" = :user""",
226+
{"user": user},
241227
)
242228
return json.loads(row[0], object_hook=lambda d: Config(**d))
243229

244230

245231
async def get_config(user: str) -> Optional[Config]:
246232
row = await db.fetchone(
247-
"""SELECT json_data FROM watchonly.config WHERE "user" = ?""", (user,)
233+
"""SELECT json_data FROM watchonly.config WHERE "user" = :user""",
234+
{"user": user},
248235
)
249236
return json.loads(row[0], object_hook=lambda d: Config(**d)) if row else None

models.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from sqlite3 import Row
21
from typing import Optional
32

43
from fastapi import Query
@@ -14,6 +13,7 @@ class CreateWallet(BaseModel):
1413

1514
class WalletAccount(BaseModel):
1615
id: str
16+
user: str
1717
masterpub: str
1818
fingerprint: str
1919
title: str
@@ -23,10 +23,6 @@ class WalletAccount(BaseModel):
2323
network: str = "Mainnet"
2424
meta: str = "{}"
2525

26-
@classmethod
27-
def from_row(cls, row: Row) -> "WalletAccount":
28-
return cls(**dict(row))
29-
3026

3127
class Address(BaseModel):
3228
id: str
@@ -38,10 +34,6 @@ class Address(BaseModel):
3834
note: Optional[str] = None
3935
has_activity: bool = False
4036

41-
@classmethod
42-
def from_row(cls, row: Row) -> "Address":
43-
return cls(**dict(row))
44-
4537

4638
class TransactionInput(BaseModel):
4739
tx_id: str

0 commit comments

Comments
 (0)