Replace [mM]yextension with [sS]at[mM]achine[aA]dmin

This commit is contained in:
padreug 2025-06-20 22:16:58 +02:00
parent 896ca5f3ca
commit 6db94179cc
21 changed files with 153 additions and 117 deletions

View file

@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
This is an LNBits extension called "satoshimachine" (currently using template name "MyExtension"). LNBits extensions are modular add-ons that extend the functionality of the LNBits Lightning Network wallet platform.
This is an LNBits extension called "satoshimachine" (currently using template name "SatMachineAdmin"). LNBits extensions are modular add-ons that extend the functionality of the LNBits Lightning Network wallet platform.
## Development Commands
@ -99,7 +99,7 @@ The global `this.g` object provides access to:
## Important Notes
- This extension is currently a template with placeholder "MyExtension" naming
- This extension is currently a template with placeholder "SatMachineAdmin" naming
- The actual functionality appears to be related to "satoshimachine" based on directory structure
- The `tmp/` directory contains a more developed version with DCA (Dollar Cost Averaging) functionality
- Extensions must follow snake_case naming conventions for Python files
@ -217,4 +217,4 @@ sudo chmod 600 /var/lib/postgresql/.ssh/authorized_keys
- `crud.py` - Database operations including poll tracking
- `migrations.py` - Schema evolution (m001-m009)
- `static/js/index.js` - Admin interface JavaScript
- `templates/myextension/index.html` - Admin UI templates
- `templates/satmachineadmin/index.html` - Admin UI templates

View file

@ -188,7 +188,7 @@ The extension creates several tables:
├── config.json # Extension configuration
├── manifest.json # Extension manifest
├── templates/
│ └── myextension/
│ └── satmachineadmin/
│ └── index.html # Main UI template
└── static/
└── js/

View file

@ -6,30 +6,30 @@ from loguru import logger
from .crud import db
from .tasks import wait_for_paid_invoices, hourly_transaction_polling
from .views import myextension_generic_router
from .views_api import myextension_api_router
from .views import satmachineadmin_generic_router
from .views_api import satmachineadmin_api_router
logger.debug(
"This logged message is from myextension/__init__.py, you can debug in your "
"This logged message is from satmachineadmin/__init__.py, you can debug in your "
"extension using 'import logger from loguru' and 'logger.debug(<thing-to-log>)'."
)
myextension_ext: APIRouter = APIRouter(prefix="/myextension", tags=["DCA Admin"])
myextension_ext.include_router(myextension_generic_router)
myextension_ext.include_router(myextension_api_router)
satmachineadmin_ext: APIRouter = APIRouter(prefix="/satmachineadmin", tags=["DCA Admin"])
satmachineadmin_ext.include_router(satmachineadmin_generic_router)
satmachineadmin_ext.include_router(satmachineadmin_api_router)
myextension_static_files = [
satmachineadmin_static_files = [
{
"path": "/myextension/static",
"name": "myextension_static",
"path": "/satmachineadmin/static",
"name": "satmachineadmin_static",
}
]
scheduled_tasks: list[asyncio.Task] = []
def myextension_stop():
def satmachineadmin_stop():
for task in scheduled_tasks:
try:
task.cancel()
@ -37,20 +37,20 @@ def myextension_stop():
logger.warning(ex)
def myextension_start():
def satmachineadmin_start():
# Start invoice listener task
invoice_task = create_permanent_unique_task("ext_myextension", wait_for_paid_invoices)
invoice_task = create_permanent_unique_task("ext_satmachineadmin", wait_for_paid_invoices)
scheduled_tasks.append(invoice_task)
# Start hourly transaction polling task
polling_task = create_permanent_unique_task("ext_myextension_polling", hourly_transaction_polling)
polling_task = create_permanent_unique_task("ext_satmachineadmin_polling", hourly_transaction_polling)
scheduled_tasks.append(polling_task)
__all__ = [
"db",
"myextension_ext",
"myextension_static_files",
"myextension_start",
"myextension_stop",
"satmachineadmin_ext",
"satmachineadmin_static_files",
"satmachineadmin_start",
"satmachineadmin_stop",
]

View file

@ -1,7 +1,7 @@
{
"name": "DCA Admin",
"short_description": "Dollar Cost Averaging administration for Lamassu ATM integration",
"tile": "/myextension/static/image/myextension.png",
"tile": "/satmachineadmin/static/image/aio.png",
"min_lnbits_version": "1.0.0",
"contributors": [
{
@ -26,7 +26,7 @@
}
],
"images": [],
"description_md": "/myextension/description.md",
"terms_and_conditions_md": "/myextension/toc.md",
"description_md": "/satmachineadmin/description.md",
"terms_and_conditions_md": "/satmachineadmin/toc.md",
"license": "MIT"
}

74
crud.py
View file

@ -15,7 +15,7 @@ from .models import (
CreateLamassuTransactionData, StoredLamassuTransaction
)
db = Database("ext_myextension")
db = Database("ext_satmachineadmin")
# DCA Client CRUD Operations
@ -23,7 +23,7 @@ async def create_dca_client(data: CreateDcaClientData) -> DcaClient:
client_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO myextension.dca_clients
INSERT INTO satmachineadmin.dca_clients
(id, user_id, wallet_id, username, dca_mode, fixed_mode_daily_limit, status, created_at, updated_at)
VALUES (:id, :user_id, :wallet_id, :username, :dca_mode, :fixed_mode_daily_limit, :status, :created_at, :updated_at)
""",
@ -44,7 +44,7 @@ async def create_dca_client(data: CreateDcaClientData) -> DcaClient:
async def get_dca_client(client_id: str) -> Optional[DcaClient]:
return await db.fetchone(
"SELECT * FROM myextension.dca_clients WHERE id = :id",
"SELECT * FROM satmachineadmin.dca_clients WHERE id = :id",
{"id": client_id},
DcaClient,
)
@ -52,14 +52,14 @@ async def get_dca_client(client_id: str) -> Optional[DcaClient]:
async def get_dca_clients() -> List[DcaClient]:
return await db.fetchall(
"SELECT * FROM myextension.dca_clients ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.dca_clients ORDER BY created_at DESC",
model=DcaClient,
)
async def get_dca_client_by_user(user_id: str) -> Optional[DcaClient]:
return await db.fetchone(
"SELECT * FROM myextension.dca_clients WHERE user_id = :user_id",
"SELECT * FROM satmachineadmin.dca_clients WHERE user_id = :user_id",
{"user_id": user_id},
DcaClient,
)
@ -75,7 +75,7 @@ async def update_dca_client(client_id: str, data: UpdateDcaClientData) -> Option
update_data["id"] = client_id
await db.execute(
f"UPDATE myextension.dca_clients SET {set_clause} WHERE id = :id",
f"UPDATE satmachineadmin.dca_clients SET {set_clause} WHERE id = :id",
update_data
)
return await get_dca_client(client_id)
@ -83,7 +83,7 @@ async def update_dca_client(client_id: str, data: UpdateDcaClientData) -> Option
async def delete_dca_client(client_id: str) -> None:
await db.execute(
"DELETE FROM myextension.dca_clients WHERE id = :id",
"DELETE FROM satmachineadmin.dca_clients WHERE id = :id",
{"id": client_id}
)
@ -93,7 +93,7 @@ async def create_deposit(data: CreateDepositData) -> DcaDeposit:
deposit_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO myextension.dca_deposits
INSERT INTO satmachineadmin.dca_deposits
(id, client_id, amount, currency, status, notes, created_at)
VALUES (:id, :client_id, :amount, :currency, :status, :notes, :created_at)
""",
@ -112,7 +112,7 @@ async def create_deposit(data: CreateDepositData) -> DcaDeposit:
async def get_deposit(deposit_id: str) -> Optional[DcaDeposit]:
return await db.fetchone(
"SELECT * FROM myextension.dca_deposits WHERE id = :id",
"SELECT * FROM satmachineadmin.dca_deposits WHERE id = :id",
{"id": deposit_id},
DcaDeposit,
)
@ -120,7 +120,7 @@ async def get_deposit(deposit_id: str) -> Optional[DcaDeposit]:
async def get_deposits_by_client(client_id: str) -> List[DcaDeposit]:
return await db.fetchall(
"SELECT * FROM myextension.dca_deposits WHERE client_id = :client_id ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.dca_deposits WHERE client_id = :client_id ORDER BY created_at DESC",
{"client_id": client_id},
DcaDeposit,
)
@ -128,7 +128,7 @@ async def get_deposits_by_client(client_id: str) -> List[DcaDeposit]:
async def get_all_deposits() -> List[DcaDeposit]:
return await db.fetchall(
"SELECT * FROM myextension.dca_deposits ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.dca_deposits ORDER BY created_at DESC",
model=DcaDeposit,
)
@ -147,7 +147,7 @@ async def update_deposit_status(deposit_id: str, data: UpdateDepositStatusData)
filtered_data["id"] = deposit_id
await db.execute(
f"UPDATE myextension.dca_deposits SET {set_clause} WHERE id = :id",
f"UPDATE satmachineadmin.dca_deposits SET {set_clause} WHERE id = :id",
filtered_data
)
return await get_deposit(deposit_id)
@ -158,7 +158,7 @@ async def create_dca_payment(data: CreateDcaPaymentData) -> DcaPayment:
payment_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO myextension.dca_payments
INSERT INTO satmachineadmin.dca_payments
(id, client_id, amount_sats, amount_fiat, exchange_rate, transaction_type,
lamassu_transaction_id, payment_hash, status, created_at)
VALUES (:id, :client_id, :amount_sats, :amount_fiat, :exchange_rate, :transaction_type,
@ -182,7 +182,7 @@ async def create_dca_payment(data: CreateDcaPaymentData) -> DcaPayment:
async def get_dca_payment(payment_id: str) -> Optional[DcaPayment]:
return await db.fetchone(
"SELECT * FROM myextension.dca_payments WHERE id = :id",
"SELECT * FROM satmachineadmin.dca_payments WHERE id = :id",
{"id": payment_id},
DcaPayment,
)
@ -190,7 +190,7 @@ async def get_dca_payment(payment_id: str) -> Optional[DcaPayment]:
async def get_payments_by_client(client_id: str) -> List[DcaPayment]:
return await db.fetchall(
"SELECT * FROM myextension.dca_payments WHERE client_id = :client_id ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.dca_payments WHERE client_id = :client_id ORDER BY created_at DESC",
{"client_id": client_id},
DcaPayment,
)
@ -198,7 +198,7 @@ async def get_payments_by_client(client_id: str) -> List[DcaPayment]:
async def get_all_payments() -> List[DcaPayment]:
return await db.fetchall(
"SELECT * FROM myextension.dca_payments ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.dca_payments ORDER BY created_at DESC",
model=DcaPayment,
)
@ -206,14 +206,14 @@ async def get_all_payments() -> List[DcaPayment]:
async def update_dca_payment_status(payment_id: str, status: str) -> None:
"""Update the status of a DCA payment"""
await db.execute(
"UPDATE myextension.dca_payments SET status = :status WHERE id = :id",
"UPDATE satmachineadmin.dca_payments SET status = :status WHERE id = :id",
{"status": status, "id": payment_id}
)
async def get_payments_by_lamassu_transaction(lamassu_transaction_id: str) -> List[DcaPayment]:
return await db.fetchall(
"SELECT * FROM myextension.dca_payments WHERE lamassu_transaction_id = :transaction_id",
"SELECT * FROM satmachineadmin.dca_payments WHERE lamassu_transaction_id = :transaction_id",
{"transaction_id": lamassu_transaction_id},
DcaPayment,
)
@ -225,7 +225,7 @@ async def get_client_balance_summary(client_id: str) -> ClientBalanceSummary:
total_deposits_result = await db.fetchone(
"""
SELECT COALESCE(SUM(amount), 0) as total, currency
FROM myextension.dca_deposits
FROM satmachineadmin.dca_deposits
WHERE client_id = :client_id AND status = 'confirmed'
GROUP BY currency
""",
@ -236,7 +236,7 @@ async def get_client_balance_summary(client_id: str) -> ClientBalanceSummary:
total_payments_result = await db.fetchone(
"""
SELECT COALESCE(SUM(amount_fiat), 0) as total
FROM myextension.dca_payments
FROM satmachineadmin.dca_payments
WHERE client_id = :client_id AND status = 'confirmed'
""",
{"client_id": client_id}
@ -257,14 +257,14 @@ async def get_client_balance_summary(client_id: str) -> ClientBalanceSummary:
async def get_flow_mode_clients() -> List[DcaClient]:
return await db.fetchall(
"SELECT * FROM myextension.dca_clients WHERE dca_mode = 'flow' AND status = 'active'",
"SELECT * FROM satmachineadmin.dca_clients WHERE dca_mode = 'flow' AND status = 'active'",
model=DcaClient,
)
async def get_fixed_mode_clients() -> List[DcaClient]:
return await db.fetchall(
"SELECT * FROM myextension.dca_clients WHERE dca_mode = 'fixed' AND status = 'active'",
"SELECT * FROM satmachineadmin.dca_clients WHERE dca_mode = 'fixed' AND status = 'active'",
model=DcaClient,
)
@ -275,13 +275,13 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig:
# Deactivate any existing configs first (only one active config allowed)
await db.execute(
"UPDATE myextension.lamassu_config SET is_active = false, updated_at = :updated_at",
"UPDATE satmachineadmin.lamassu_config SET is_active = false, updated_at = :updated_at",
{"updated_at": datetime.now()}
)
await db.execute(
"""
INSERT INTO myextension.lamassu_config
INSERT INTO satmachineadmin.lamassu_config
(id, host, port, database_name, username, password, source_wallet_id, commission_wallet_id, is_active, created_at, updated_at,
use_ssh_tunnel, ssh_host, ssh_port, ssh_username, ssh_password, ssh_private_key)
VALUES (:id, :host, :port, :database_name, :username, :password, :source_wallet_id, :commission_wallet_id, :is_active, :created_at, :updated_at,
@ -312,7 +312,7 @@ async def create_lamassu_config(data: CreateLamassuConfigData) -> LamassuConfig:
async def get_lamassu_config(config_id: str) -> Optional[LamassuConfig]:
return await db.fetchone(
"SELECT * FROM myextension.lamassu_config WHERE id = :id",
"SELECT * FROM satmachineadmin.lamassu_config WHERE id = :id",
{"id": config_id},
LamassuConfig,
)
@ -320,14 +320,14 @@ async def get_lamassu_config(config_id: str) -> Optional[LamassuConfig]:
async def get_active_lamassu_config() -> Optional[LamassuConfig]:
return await db.fetchone(
"SELECT * FROM myextension.lamassu_config WHERE is_active = true ORDER BY created_at DESC LIMIT 1",
"SELECT * FROM satmachineadmin.lamassu_config WHERE is_active = true ORDER BY created_at DESC LIMIT 1",
model=LamassuConfig,
)
async def get_all_lamassu_configs() -> List[LamassuConfig]:
return await db.fetchall(
"SELECT * FROM myextension.lamassu_config ORDER BY created_at DESC",
"SELECT * FROM satmachineadmin.lamassu_config ORDER BY created_at DESC",
model=LamassuConfig,
)
@ -342,7 +342,7 @@ async def update_lamassu_config(config_id: str, data: UpdateLamassuConfigData) -
update_data["id"] = config_id
await db.execute(
f"UPDATE myextension.lamassu_config SET {set_clause} WHERE id = :id",
f"UPDATE satmachineadmin.lamassu_config SET {set_clause} WHERE id = :id",
update_data
)
return await get_lamassu_config(config_id)
@ -352,7 +352,7 @@ async def update_config_test_result(config_id: str, success: bool) -> None:
utc_now = datetime.now(timezone.utc)
await db.execute(
"""
UPDATE myextension.lamassu_config
UPDATE satmachineadmin.lamassu_config
SET test_connection_last = :test_time, test_connection_success = :success, updated_at = :updated_at
WHERE id = :id
""",
@ -367,7 +367,7 @@ async def update_config_test_result(config_id: str, success: bool) -> None:
async def delete_lamassu_config(config_id: str) -> None:
await db.execute(
"DELETE FROM myextension.lamassu_config WHERE id = :id",
"DELETE FROM satmachineadmin.lamassu_config WHERE id = :id",
{"id": config_id}
)
@ -377,7 +377,7 @@ async def update_poll_start_time(config_id: str) -> None:
utc_now = datetime.now(timezone.utc)
await db.execute(
"""
UPDATE myextension.lamassu_config
UPDATE satmachineadmin.lamassu_config
SET last_poll_time = :poll_time, updated_at = :updated_at
WHERE id = :id
""",
@ -394,7 +394,7 @@ async def update_poll_success_time(config_id: str) -> None:
utc_now = datetime.now(timezone.utc)
await db.execute(
"""
UPDATE myextension.lamassu_config
UPDATE satmachineadmin.lamassu_config
SET last_successful_poll = :poll_time, updated_at = :updated_at
WHERE id = :id
""",
@ -412,7 +412,7 @@ async def create_lamassu_transaction(data: CreateLamassuTransactionData) -> Stor
transaction_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO myextension.lamassu_transactions
INSERT INTO satmachineadmin.lamassu_transactions
(id, lamassu_transaction_id, fiat_amount, crypto_amount, commission_percentage,
discount, effective_commission, commission_amount_sats, base_amount_sats,
exchange_rate, crypto_code, fiat_code, device_id, transaction_time, processed_at,
@ -448,7 +448,7 @@ async def create_lamassu_transaction(data: CreateLamassuTransactionData) -> Stor
async def get_lamassu_transaction(transaction_id: str) -> Optional[StoredLamassuTransaction]:
"""Get a stored Lamassu transaction by ID"""
return await db.fetchone(
"SELECT * FROM myextension.lamassu_transactions WHERE id = :id",
"SELECT * FROM satmachineadmin.lamassu_transactions WHERE id = :id",
{"id": transaction_id},
StoredLamassuTransaction,
)
@ -457,7 +457,7 @@ async def get_lamassu_transaction(transaction_id: str) -> Optional[StoredLamassu
async def get_lamassu_transaction_by_lamassu_id(lamassu_transaction_id: str) -> Optional[StoredLamassuTransaction]:
"""Get a stored Lamassu transaction by Lamassu transaction ID"""
return await db.fetchone(
"SELECT * FROM myextension.lamassu_transactions WHERE lamassu_transaction_id = :lamassu_id",
"SELECT * FROM satmachineadmin.lamassu_transactions WHERE lamassu_transaction_id = :lamassu_id",
{"lamassu_id": lamassu_transaction_id},
StoredLamassuTransaction,
)
@ -466,7 +466,7 @@ async def get_lamassu_transaction_by_lamassu_id(lamassu_transaction_id: str) ->
async def get_all_lamassu_transactions() -> List[StoredLamassuTransaction]:
"""Get all stored Lamassu transactions"""
return await db.fetchall(
"SELECT * FROM myextension.lamassu_transactions ORDER BY transaction_time DESC",
"SELECT * FROM satmachineadmin.lamassu_transactions ORDER BY transaction_time DESC",
model=StoredLamassuTransaction,
)
@ -479,7 +479,7 @@ async def update_lamassu_transaction_distribution_stats(
"""Update distribution statistics for a Lamassu transaction"""
await db.execute(
"""
UPDATE myextension.lamassu_transactions
UPDATE satmachineadmin.lamassu_transactions
SET clients_count = :clients_count, distributions_total_sats = :distributions_total_sats
WHERE id = :id
""",

View file

@ -1,4 +1,4 @@
MyExtension can be used as a template for building new extensions, it includes a bunch of functions that can be edited/deleted as you need them.
SatMachineAdmin can be used as a template for building new extensions, it includes a bunch of functions that can be edited/deleted as you need them.
This is a longform description that will be used in the advanced description when users click on the "more" button on the extension cards.

View file

@ -1,9 +1,9 @@
{
"repos": [
{
"id": "myextension",
"id": "satmachineadmin",
"organisation": "lnbits",
"repository": "myextension"
"repository": "satmachineadmin"
}
]
}

View file

@ -10,7 +10,7 @@ async def m001_initial_dca_schema(db):
# DCA Clients table
await db.execute(
f"""
CREATE TABLE myextension.dca_clients (
CREATE TABLE satmachineadmin.dca_clients (
id TEXT PRIMARY KEY NOT NULL,
user_id TEXT NOT NULL,
wallet_id TEXT NOT NULL,
@ -27,7 +27,7 @@ async def m001_initial_dca_schema(db):
# DCA Deposits table
await db.execute(
f"""
CREATE TABLE myextension.dca_deposits (
CREATE TABLE satmachineadmin.dca_deposits (
id TEXT PRIMARY KEY NOT NULL,
client_id TEXT NOT NULL,
amount INTEGER NOT NULL,
@ -43,7 +43,7 @@ async def m001_initial_dca_schema(db):
# DCA Payments table
await db.execute(
f"""
CREATE TABLE myextension.dca_payments (
CREATE TABLE satmachineadmin.dca_payments (
id TEXT PRIMARY KEY NOT NULL,
client_id TEXT NOT NULL,
amount_sats INTEGER NOT NULL,
@ -61,7 +61,7 @@ async def m001_initial_dca_schema(db):
# Lamassu Configuration table
await db.execute(
f"""
CREATE TABLE myextension.lamassu_config (
CREATE TABLE satmachineadmin.lamassu_config (
id TEXT PRIMARY KEY NOT NULL,
host TEXT NOT NULL,
port INTEGER NOT NULL DEFAULT 5432,
@ -90,7 +90,7 @@ async def m001_initial_dca_schema(db):
# Lamassu Transactions table (for audit trail)
await db.execute(
f"""
CREATE TABLE myextension.lamassu_transactions (
CREATE TABLE satmachineadmin.lamassu_transactions (
id TEXT PRIMARY KEY NOT NULL,
lamassu_transaction_id TEXT NOT NULL UNIQUE,
fiat_amount INTEGER NOT NULL,

View file

@ -1,5 +1,5 @@
[tool.poetry]
name = "myextension"
name = "satmachineadmin"
version = "0.0.0"
description = "Eightball is a simple API that allows you to create a random number generator."
authors = ["benarc", "dni <dni@lnbits.com>"]

36
replaceStuff.sh Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Usage: ./rename-plugin.sh oldname newname
# Example: ./rename-plugin.sh example mysuperplugin
set -euo pipefail
OLD_NAME="$1"
NEW_NAME="$2"
# 1. Rename files with OLD_NAME in the filename
find . -type f -name "*${OLD_NAME}*" | while read -r file; do
dir=$(dirname "$file")
base=$(basename "$file")
new_base="${base//$OLD_NAME/$NEW_NAME}"
new_path="$dir/$new_base"
mv "$file" "$new_path"
echo "Renamed file: $file -> $new_path"
done
# 2. Replace occurrences of OLD_NAME in file content
echo "Replacing content inside files..."
find . -type f -print0 | xargs -0 sed -i "s/${OLD_NAME}/${NEW_NAME}/g"
# 3. Rename directories with OLD_NAME in the path (from deepest up)
echo "Renaming directories..."
find . -depth -type d -name "*${OLD_NAME}*" | while read -r dir; do
parent=$(dirname "$dir")
base=$(basename "$dir")
new_base="${base//$OLD_NAME/$NEW_NAME}"
new_path="$parent/$new_base"
mv "$dir" "$new_path"
echo "Renamed directory: $dir -> $new_path"
done
echo "✅ All done."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before After
Before After

View file

@ -165,7 +165,7 @@ window.app = Vue.createApp({
try {
const {data} = await LNbits.api.request(
'GET',
'/myextension/api/v1/dca/config',
'/satmachineadmin/api/v1/dca/config',
this.g.user.wallets[0].inkey
)
this.lamassuConfig = data
@ -210,7 +210,7 @@ window.app = Vue.createApp({
const {data: config} = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/config',
'/satmachineadmin/api/v1/dca/config',
this.g.user.wallets[0].adminkey,
data
)
@ -253,7 +253,7 @@ window.app = Vue.createApp({
try {
const { data } = await LNbits.api.request(
'GET',
'/myextension/api/v1/dca/clients',
'/satmachineadmin/api/v1/dca/clients',
this.g.user.wallets[0].inkey
)
@ -263,7 +263,7 @@ window.app = Vue.createApp({
try {
const { data: balance } = await LNbits.api.request(
'GET',
`/myextension/api/v1/dca/clients/${client.id}/balance`,
`/satmachineadmin/api/v1/dca/clients/${client.id}/balance`,
this.g.user.wallets[0].inkey
)
return {
@ -298,7 +298,7 @@ window.app = Vue.createApp({
const { data: newClient } = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/clients',
'/satmachineadmin/api/v1/dca/clients',
this.g.user.wallets[0].adminkey,
testData
)
@ -327,7 +327,7 @@ window.app = Vue.createApp({
const { data: newDeposit } = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/deposits',
'/satmachineadmin/api/v1/dca/deposits',
this.g.user.wallets[0].adminkey,
data
)
@ -355,7 +355,7 @@ window.app = Vue.createApp({
try {
const { data: balance } = await LNbits.api.request(
'GET',
`/myextension/api/v1/dca/clients/${client.id}/balance`,
`/satmachineadmin/api/v1/dca/clients/${client.id}/balance`,
this.g.user.wallets[0].inkey
)
this.clientDetailsDialog.data = client
@ -371,7 +371,7 @@ window.app = Vue.createApp({
try {
const { data } = await LNbits.api.request(
'GET',
'/myextension/api/v1/dca/deposits',
'/satmachineadmin/api/v1/dca/deposits',
this.g.user.wallets[0].inkey
)
this.deposits = data
@ -402,7 +402,7 @@ window.app = Vue.createApp({
// Update existing deposit (mainly for notes/status)
const { data: updatedDeposit } = await LNbits.api.request(
'PUT',
`/myextension/api/v1/dca/deposits/${this.depositFormDialog.data.id}`,
`/satmachineadmin/api/v1/dca/deposits/${this.depositFormDialog.data.id}`,
this.g.user.wallets[0].adminkey,
{ status: this.depositFormDialog.data.status, notes: data.notes }
)
@ -414,7 +414,7 @@ window.app = Vue.createApp({
// Create new deposit
const { data: newDeposit } = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/deposits',
'/satmachineadmin/api/v1/dca/deposits',
this.g.user.wallets[0].adminkey,
data
)
@ -446,7 +446,7 @@ window.app = Vue.createApp({
.onOk(async () => {
const { data: updatedDeposit } = await LNbits.api.request(
'PUT',
`/myextension/api/v1/dca/deposits/${deposit.id}/status`,
`/satmachineadmin/api/v1/dca/deposits/${deposit.id}/status`,
this.g.user.wallets[0].adminkey,
{ status: 'confirmed', notes: 'Confirmed by admin - money placed in machine' }
)
@ -489,7 +489,7 @@ window.app = Vue.createApp({
try {
const {data} = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/test-connection',
'/satmachineadmin/api/v1/dca/test-connection',
this.g.user.wallets[0].adminkey
)
@ -535,7 +535,7 @@ window.app = Vue.createApp({
try {
const {data} = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/manual-poll',
'/satmachineadmin/api/v1/dca/manual-poll',
this.g.user.wallets[0].adminkey
)
@ -563,7 +563,7 @@ window.app = Vue.createApp({
try {
const {data} = await LNbits.api.request(
'POST',
'/myextension/api/v1/dca/test-transaction',
'/satmachineadmin/api/v1/dca/test-transaction',
this.g.user.wallets[0].adminkey
)
@ -616,7 +616,7 @@ window.app = Vue.createApp({
try {
const { data } = await LNbits.api.request(
'GET',
'/myextension/api/v1/dca/transactions',
'/satmachineadmin/api/v1/dca/transactions',
this.g.user.wallets[0].inkey
)
this.lamassuTransactions = data
@ -629,7 +629,7 @@ window.app = Vue.createApp({
try {
const { data: distributions } = await LNbits.api.request(
'GET',
`/myextension/api/v1/dca/transactions/${transaction.id}/distributions`,
`/satmachineadmin/api/v1/dca/transactions/${transaction.id}/distributions`,
this.g.user.wallets[0].inkey
)

View file

@ -18,7 +18,7 @@ from .transaction_processor import poll_lamassu_transactions
async def wait_for_paid_invoices():
"""Invoice listener for DCA-related payments"""
invoice_queue = asyncio.Queue()
register_invoice_listener(invoice_queue, "ext_myextension")
register_invoice_listener(invoice_queue, "ext_satmachineadmin")
while True:
payment = await invoice_queue.get()
await on_invoice_paid(payment)

View file

@ -4,5 +4,5 @@
label="API info"
:content-inset-level="0.5"
>
<q-btn flat label="Swagger API" type="a" href="../docs#/MyExtension"></q-btn>
<q-btn flat label="Swagger API" type="a" href="../docs#/SatMachineAdmin"></q-btn>
</q-expansion-item>

View file

@ -4,7 +4,7 @@
{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
%} {% block scripts %} {{ window_vars(user) }}
<script src="{{ static_url_for('myextension/static', path='js/index.js') }}"></script>
<script src="{{ static_url_for('satmachineadmin/static', path='js/index.js') }}"></script>
{% endblock %} {% block page %}
<div class="row q-col-gutter-md" id="dcaAdmin">
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
@ -367,7 +367,7 @@
</q-card-section>
</q-expansion-item>
<q-separator></q-separator>
{% include "myextension/_api_docs.html" %}
{% include "satmachineadmin/_api_docs.html" %}
</q-list>
</q-card-section>
</q-card>

View file

@ -1,11 +1,11 @@
import pytest
from fastapi import APIRouter
from .. import myextension_ext
from .. import satmachineadmin_ext
# just import router and add it to a test router
@pytest.mark.asyncio
async def test_router():
router = APIRouter()
router.include_router(myextension_ext)
router.include_router(satmachineadmin_ext)

View file

@ -6,16 +6,16 @@ from lnbits.core.models import User
from lnbits.decorators import check_user_exists
from lnbits.helpers import template_renderer
myextension_generic_router = APIRouter()
satmachineadmin_generic_router = APIRouter()
def myextension_renderer():
return template_renderer(["myextension/templates"])
def satmachineadmin_renderer():
return template_renderer(["satmachineadmin/templates"])
# DCA Admin page
@myextension_generic_router.get("/", response_class=HTMLResponse)
@satmachineadmin_generic_router.get("/", response_class=HTMLResponse)
async def index(req: Request, user: User = Depends(check_user_exists)):
return myextension_renderer().TemplateResponse(
"myextension/index.html", {"request": req, "user": user.json()}
return satmachineadmin_renderer().TemplateResponse(
"satmachineadmin/index.html", {"request": req, "user": user.json()}
)

View file

@ -43,7 +43,7 @@ from .models import (
StoredLamassuTransaction
)
myextension_api_router = APIRouter()
satmachineadmin_api_router = APIRouter()
###################################################
@ -52,7 +52,7 @@ myextension_api_router = APIRouter()
# DCA Client Endpoints
@myextension_api_router.get("/api/v1/dca/clients")
@satmachineadmin_api_router.get("/api/v1/dca/clients")
async def api_get_dca_clients(
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> list[DcaClient]:
@ -60,7 +60,7 @@ async def api_get_dca_clients(
return await get_dca_clients()
@myextension_api_router.get("/api/v1/dca/clients/{client_id}")
@satmachineadmin_api_router.get("/api/v1/dca/clients/{client_id}")
async def api_get_dca_client(
client_id: str,
wallet: WalletTypeInfo = Depends(require_invoice_key),
@ -78,7 +78,7 @@ async def api_get_dca_client(
# Admin extension only reads existing clients and manages their deposits
# TEMPORARY: Test client creation endpoint (remove in production)
@myextension_api_router.post("/api/v1/dca/clients", status_code=HTTPStatus.CREATED)
@satmachineadmin_api_router.post("/api/v1/dca/clients", status_code=HTTPStatus.CREATED)
async def api_create_test_dca_client(
data: CreateDcaClientData,
wallet: WalletTypeInfo = Depends(require_admin_key),
@ -87,7 +87,7 @@ async def api_create_test_dca_client(
return await create_dca_client(data)
@myextension_api_router.get("/api/v1/dca/clients/{client_id}/balance")
@satmachineadmin_api_router.get("/api/v1/dca/clients/{client_id}/balance")
async def api_get_client_balance(
client_id: str,
wallet: WalletTypeInfo = Depends(require_invoice_key),
@ -104,7 +104,7 @@ async def api_get_client_balance(
# DCA Deposit Endpoints
@myextension_api_router.get("/api/v1/dca/deposits")
@satmachineadmin_api_router.get("/api/v1/dca/deposits")
async def api_get_deposits(
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> list[DcaDeposit]:
@ -112,7 +112,7 @@ async def api_get_deposits(
return await get_all_deposits()
@myextension_api_router.get("/api/v1/dca/deposits/{deposit_id}")
@satmachineadmin_api_router.get("/api/v1/dca/deposits/{deposit_id}")
async def api_get_deposit(
deposit_id: str,
wallet: WalletTypeInfo = Depends(require_invoice_key),
@ -126,7 +126,7 @@ async def api_get_deposit(
return deposit
@myextension_api_router.post("/api/v1/dca/deposits", status_code=HTTPStatus.CREATED)
@satmachineadmin_api_router.post("/api/v1/dca/deposits", status_code=HTTPStatus.CREATED)
async def api_create_deposit(
data: CreateDepositData,
wallet: WalletTypeInfo = Depends(require_admin_key),
@ -142,7 +142,7 @@ async def api_create_deposit(
return await create_deposit(data)
@myextension_api_router.put("/api/v1/dca/deposits/{deposit_id}/status")
@satmachineadmin_api_router.put("/api/v1/dca/deposits/{deposit_id}/status")
async def api_update_deposit_status(
deposit_id: str,
data: UpdateDepositStatusData,
@ -165,7 +165,7 @@ async def api_update_deposit_status(
# Transaction Polling Endpoints
@myextension_api_router.post("/api/v1/dca/test-connection")
@satmachineadmin_api_router.post("/api/v1/dca/test-connection")
async def api_test_database_connection(
wallet: WalletTypeInfo = Depends(require_admin_key),
):
@ -188,7 +188,7 @@ async def api_test_database_connection(
}
@myextension_api_router.post("/api/v1/dca/manual-poll")
@satmachineadmin_api_router.post("/api/v1/dca/manual-poll")
async def api_manual_poll(
wallet: WalletTypeInfo = Depends(require_admin_key),
):
@ -234,7 +234,7 @@ async def api_manual_poll(
)
@myextension_api_router.post("/api/v1/dca/test-transaction")
@satmachineadmin_api_router.post("/api/v1/dca/test-transaction")
async def api_test_transaction(
wallet: WalletTypeInfo = Depends(require_admin_key),
crypto_atoms: int = 103,
@ -296,7 +296,7 @@ async def api_test_transaction(
# Lamassu Transaction Endpoints
@myextension_api_router.get("/api/v1/dca/transactions")
@satmachineadmin_api_router.get("/api/v1/dca/transactions")
async def api_get_lamassu_transactions(
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> list[StoredLamassuTransaction]:
@ -304,7 +304,7 @@ async def api_get_lamassu_transactions(
return await get_all_lamassu_transactions()
@myextension_api_router.get("/api/v1/dca/transactions/{transaction_id}")
@satmachineadmin_api_router.get("/api/v1/dca/transactions/{transaction_id}")
async def api_get_lamassu_transaction(
transaction_id: str,
wallet: WalletTypeInfo = Depends(require_invoice_key),
@ -318,7 +318,7 @@ async def api_get_lamassu_transaction(
return transaction
@myextension_api_router.get("/api/v1/dca/transactions/{transaction_id}/distributions")
@satmachineadmin_api_router.get("/api/v1/dca/transactions/{transaction_id}/distributions")
async def api_get_transaction_distributions(
transaction_id: str,
wallet: WalletTypeInfo = Depends(require_invoice_key),
@ -356,7 +356,7 @@ async def api_get_transaction_distributions(
# Lamassu Configuration Endpoints
@myextension_api_router.get("/api/v1/dca/config")
@satmachineadmin_api_router.get("/api/v1/dca/config")
async def api_get_lamassu_config(
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> Optional[LamassuConfig]:
@ -364,7 +364,7 @@ async def api_get_lamassu_config(
return await get_active_lamassu_config()
@myextension_api_router.post("/api/v1/dca/config", status_code=HTTPStatus.CREATED)
@satmachineadmin_api_router.post("/api/v1/dca/config", status_code=HTTPStatus.CREATED)
async def api_create_lamassu_config(
data: CreateLamassuConfigData,
wallet: WalletTypeInfo = Depends(require_admin_key),
@ -373,7 +373,7 @@ async def api_create_lamassu_config(
return await create_lamassu_config(data)
@myextension_api_router.put("/api/v1/dca/config/{config_id}")
@satmachineadmin_api_router.put("/api/v1/dca/config/{config_id}")
async def api_update_lamassu_config(
config_id: str,
data: UpdateLamassuConfigData,
@ -394,7 +394,7 @@ async def api_update_lamassu_config(
return updated_config
@myextension_api_router.delete("/api/v1/dca/config/{config_id}")
@satmachineadmin_api_router.delete("/api/v1/dca/config/{config_id}")
async def api_delete_lamassu_config(
config_id: str,
wallet: WalletTypeInfo = Depends(require_admin_key),