Compare commits
12 Commits
f2cda461ba
...
test/gitea
| Author | SHA1 | Date | |
|---|---|---|---|
|
53148f573e
|
|||
|
e8f052e0d1
|
|||
|
7f450d620a
|
|||
|
41a1bc743f
|
|||
|
30108e3bc5
|
|||
|
a2dc9f43e3
|
|||
|
1203719eac
|
|||
|
373a71f04d
|
|||
|
b76b873036
|
|||
|
23e714fad8
|
|||
|
a36c69ecfc
|
|||
|
1fd9987bf1
|
32
.dockerignore
Normal file
32
.dockerignore
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
.env
|
||||
.env*
|
||||
__pycache__/
|
||||
|
||||
templates/assets/css/styles.min.css
|
||||
|
||||
ignore/
|
||||
|
||||
plugins/signatures.json
|
||||
|
||||
.venv/
|
||||
|
||||
user_data/
|
||||
customPlugins/
|
||||
cache/
|
||||
build/
|
||||
dist/
|
||||
hsd/
|
||||
hsd-data/
|
||||
hsd.lock
|
||||
hsdconfig.json
|
||||
|
||||
Dockerfile
|
||||
Dockerfile.hsd
|
||||
FireWalletBrowser.bsdesign
|
||||
LICENSE.md
|
||||
README.md
|
||||
docker-compose.yml
|
||||
example.env
|
||||
plugins.md
|
||||
|
||||
@@ -4,11 +4,22 @@ on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
Build Image:
|
||||
Build Images:
|
||||
runs-on: [ubuntu-latest, amd]
|
||||
strategy:
|
||||
matrix:
|
||||
variant:
|
||||
- target: default
|
||||
tag_suffix: ""
|
||||
dockerfile: "Dockerfile"
|
||||
- target: hsd
|
||||
tag_suffix: "-hsd"
|
||||
dockerfile: "Dockerfile.hsd"
|
||||
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Docker
|
||||
run : |
|
||||
apt-get install ca-certificates curl gnupg
|
||||
@@ -17,7 +28,7 @@ jobs:
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt-get update
|
||||
apt-get install docker-ce-cli -y
|
||||
apt-get install docker-ce-cli -y
|
||||
- name: Build Docker image
|
||||
run : |
|
||||
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin
|
||||
@@ -34,8 +45,8 @@ jobs:
|
||||
fi
|
||||
|
||||
|
||||
docker build -t firewallet:$tag_num .
|
||||
docker tag firewallet:$tag_num git.woodburn.au/nathanwoodburn/firewallet:$tag_num
|
||||
docker push git.woodburn.au/nathanwoodburn/firewallet:$tag_num
|
||||
docker tag firewallet:$tag_num git.woodburn.au/nathanwoodburn/firewallet:$tag
|
||||
docker push git.woodburn.au/nathanwoodburn/firewallet:$tag
|
||||
docker build --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') --build-arg VCS_REF=$GITEA_SHA --build-arg VERSION=$GITEA_TAG --file ${{matrix.variant.dockerfile}} -t firewallet${{matrix.variant.tag_suffix}}:$tag_num .
|
||||
docker tag firewallet${{matrix.variant.tag_suffix}}:$tag_num git.woodburn.au/nathanwoodburn/firewallet${{matrix.variant.tag_suffix}}:$tag_num
|
||||
docker push git.woodburn.au/nathanwoodburn/firewallet${{matrix.variant.tag_suffix}}:$tag_num
|
||||
docker tag firewallet${{matrix.variant.tag_suffix}}:$tag_num git.woodburn.au/nathanwoodburn/firewallet${{matrix.variant.tag_suffix}}:$tag
|
||||
docker push git.woodburn.au/nathanwoodburn/firewallet${{matrix.variant.tag_suffix}}:$tag
|
||||
22
Dockerfile
22
Dockerfile
@@ -1,7 +1,7 @@
|
||||
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder
|
||||
FROM --platform=$BUILDPLATFORM python:3.13-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add git openssl curl
|
||||
COPY requirements.txt /app
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip3 install -r requirements.txt
|
||||
@@ -9,10 +9,22 @@ RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
COPY . /app
|
||||
|
||||
# Add mount point for data volume
|
||||
# VOLUME /data
|
||||
RUN apk add git openssl curl
|
||||
VOLUME /app/user_data
|
||||
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
|
||||
LABEL org.opencontainers.image.title="FireWallet" \
|
||||
org.opencontainers.image.description="The Handshake Wallet That is Fire" \
|
||||
org.opencontainers.image.url="https://firewallet.au" \
|
||||
org.opencontainers.image.source="https://git.woodburn.au/nathanwoodburn/firewalletbrowser" \
|
||||
org.opencontainers.image.version="2.0.0" \
|
||||
org.opencontainers.image.created=$BUILD_DATE \
|
||||
org.opencontainers.image.revision=$VCS_REF \
|
||||
org.opencontainers.image.licenses="AGPL-3.0-only"
|
||||
|
||||
ENTRYPOINT ["python3"]
|
||||
CMD ["server.py"]
|
||||
|
||||
FROM builder as dev-envs
|
||||
FROM builder AS dev-envs
|
||||
|
||||
58
Dockerfile.hsd
Normal file
58
Dockerfile.hsd
Normal file
@@ -0,0 +1,58 @@
|
||||
# ---- HSD build stage ----
|
||||
FROM node:22-alpine AS hsd-build
|
||||
WORKDIR /opt/hsd
|
||||
RUN apk add --no-cache git bash unbound-dev gmp-dev g++ gcc make python3
|
||||
RUN git clone --depth=1 --branch v8.0.0 https://github.com/handshake-org/hsd.git .
|
||||
RUN npm install --omit=dev
|
||||
|
||||
# ---- Final stage ----
|
||||
FROM python:3.13-alpine
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime deps only
|
||||
RUN apk add --no-cache unbound-dev gmp
|
||||
|
||||
|
||||
# Copy node and npm from hsd-build stage
|
||||
COPY --from=hsd-build /usr/local/bin/node /usr/local/bin/node
|
||||
COPY --from=hsd-build /usr/local/lib/node_modules/npm /usr/local/lib/node
|
||||
COPY --from=hsd-build /usr/local/bin/npm /usr/local/bin/npm
|
||||
|
||||
# Copy FireWallet dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy HSD from build stage
|
||||
COPY --from=hsd-build /opt/hsd /app/hsd
|
||||
|
||||
# Copy FireWallet source
|
||||
COPY . .
|
||||
|
||||
# Expose ports
|
||||
EXPOSE 5000
|
||||
# Optional HSD ports
|
||||
# EXPOSE 12037
|
||||
# EXPOSE 12039
|
||||
|
||||
ENV INTERNAL_HSD=true
|
||||
ENV HSD_DOCKER_CONTAINER=true
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
|
||||
LABEL org.opencontainers.image.title="FireWallet (HSD)" \
|
||||
org.opencontainers.image.description="The Handshake Wallet That is Fire" \
|
||||
org.opencontainers.image.url="https://firewallet.au" \
|
||||
org.opencontainers.image.source="https://git.woodburn.au/nathanwoodburn/firewalletbrowser" \
|
||||
org.opencontainers.image.version="2.0.0" \
|
||||
org.opencontainers.image.created=$BUILD_DATE \
|
||||
org.opencontainers.image.revision=$VCS_REF \
|
||||
org.opencontainers.image.licenses="AGPL-3.0-only"
|
||||
|
||||
|
||||
|
||||
VOLUME ["/app/hsd-data", "/app/user_data"]
|
||||
|
||||
|
||||
ENTRYPOINT ["python3"]
|
||||
CMD ["server.py"]
|
||||
Binary file not shown.
19
README.md
19
README.md
@@ -143,6 +143,25 @@ If you set INTERNAL_HSD=true in the .env file the wallet will start and manage i
|
||||
}
|
||||
```
|
||||
|
||||
Supported config options are:
|
||||
```yaml
|
||||
spv: true/false
|
||||
prefix: path to hsd data directory
|
||||
flags: list of additional flags to pass to hsd
|
||||
version: version of hsd to use (used when installing HSD from source)
|
||||
chainMigrate: <int> (for users migrating from older versions of HSD)
|
||||
walletMigrate: <int> (for users migrating from older versions of HSD)
|
||||
```
|
||||
|
||||
## Support the Project
|
||||
|
||||
If you find FireWallet useful and would like to support its continued development, please consider making a donation. Your contributions help maintain the project and develop new features.
|
||||
|
||||
HNS donations can be sent to: `hs1qh7uzytf2ftwkd9dmjjs7az9qfver5m7dd7x4ej`
|
||||
Other donation options can be found at [my website](https://nathan.woodburn.au/donate)
|
||||
|
||||
Thank you for your support!
|
||||
|
||||
## Warnings
|
||||
|
||||
- This is a work in progress and is not guaranteed to work
|
||||
|
||||
189
account.py
189
account.py
@@ -64,7 +64,8 @@ HSD_CONFIG = {
|
||||
]
|
||||
}
|
||||
|
||||
CACHE_TTL = int(os.getenv("CACHE_TTL",90))
|
||||
TX_CACHE_TTL = 3600
|
||||
DOMAIN_CACHE_TTL = int(os.getenv("CACHE_TTL",90))
|
||||
|
||||
if not os.path.exists('hsdconfig.json'):
|
||||
with open('hsdconfig.json', 'w') as f:
|
||||
@@ -78,8 +79,6 @@ else:
|
||||
hsd = api.hsd(HSD_API, HSD_IP, HSD_NODE_PORT)
|
||||
hsw = api.hsw(HSD_API, HSD_IP, HSD_WALLET_PORT)
|
||||
|
||||
cacheTime = 3600
|
||||
|
||||
# Verify the connection
|
||||
response = hsd.getInfo()
|
||||
|
||||
@@ -377,7 +376,7 @@ def getBalance(account: str):
|
||||
cursor = conn.cursor()
|
||||
|
||||
now = int(time.time())
|
||||
cache_cutoff = now - (CACHE_TTL * 86400) # Cache TTL in days
|
||||
cache_cutoff = now - (DOMAIN_CACHE_TTL * 86400) # Cache TTL in days
|
||||
|
||||
for domain in domains:
|
||||
domain_name = domain['name']
|
||||
@@ -488,40 +487,74 @@ def getDomains(account, own=True):
|
||||
|
||||
return domains
|
||||
|
||||
def init_tx_page_db():
|
||||
"""Initialize the SQLite database for transaction page cache."""
|
||||
os.makedirs('cache', exist_ok=True)
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create the tx_pages table if it doesn't exist
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS tx_pages (
|
||||
account TEXT,
|
||||
page_key TEXT,
|
||||
txid TEXT,
|
||||
timestamp INTEGER,
|
||||
PRIMARY KEY (account, page_key)
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def getPageTXCache(account, page, size=100):
|
||||
page = f"{page}-{size}"
|
||||
if not os.path.exists(f'cache'):
|
||||
os.mkdir(f'cache')
|
||||
|
||||
if not os.path.exists(f'cache/{account}_page.json'):
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
f.write('{}')
|
||||
with open(f'cache/{account}_page.json') as f:
|
||||
pageCache = json.load(f)
|
||||
|
||||
if page in pageCache and pageCache[page]['time'] > int(time.time()) - cacheTime:
|
||||
return pageCache[page]['txid']
|
||||
"""Get cached transaction ID from SQLite database."""
|
||||
account = getxPub(account)
|
||||
page_key = f"{page}-{size}"
|
||||
|
||||
# Initialize database if needed
|
||||
init_tx_page_db()
|
||||
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Query for the cached transaction ID
|
||||
cursor.execute(
|
||||
'SELECT txid, timestamp FROM tx_pages WHERE account = ? AND page_key = ?',
|
||||
(account, page_key)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
conn.close()
|
||||
|
||||
if row and row[1] > int(time.time()) - TX_CACHE_TTL:
|
||||
return row[0] # Return the cached txid
|
||||
return None
|
||||
|
||||
|
||||
def pushPageTXCache(account, page, txid, size=100):
|
||||
page = f"{page}-{size}"
|
||||
if not os.path.exists(f'cache/{account}_page.json'):
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
f.write('{}')
|
||||
with open(f'cache/{account}_page.json') as f:
|
||||
pageCache = json.load(f)
|
||||
|
||||
pageCache[page] = {
|
||||
'time': int(time.time()),
|
||||
'txid': txid
|
||||
}
|
||||
with open(f'cache/{account}_page.json', 'w') as f:
|
||||
json.dump(pageCache, f, indent=4)
|
||||
|
||||
return pageCache[page]['txid']
|
||||
|
||||
"""Store transaction ID in SQLite database."""
|
||||
account = getxPub(account)
|
||||
page_key = f"{page}-{size}"
|
||||
|
||||
# Initialize database if needed
|
||||
init_tx_page_db()
|
||||
|
||||
db_path = os.path.join('cache', 'tx_pages.db')
|
||||
conn = sqlite3.connect(db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Insert or replace the transaction ID
|
||||
cursor.execute(
|
||||
'INSERT OR REPLACE INTO tx_pages (account, page_key, txid, timestamp) VALUES (?, ?, ?, ?)',
|
||||
(account, page_key, txid, int(time.time()))
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
return txid
|
||||
|
||||
def getTXFromPage(account, page, size=100):
|
||||
if page == 1:
|
||||
@@ -740,7 +773,6 @@ def getDomain(domain: str):
|
||||
"message": response['error']['message']
|
||||
}
|
||||
}
|
||||
|
||||
return response['result']
|
||||
|
||||
def isKnownDomain(domain: str) -> bool:
|
||||
@@ -783,6 +815,17 @@ def renewDomain(account, domain):
|
||||
|
||||
def getDNS(domain: str):
|
||||
# Get the DNS
|
||||
|
||||
if isSPV():
|
||||
response = requests.get(f"https://hsd.hns.au/api/v1/nameresource/{domain}")
|
||||
if response.status_code != 200:
|
||||
return {
|
||||
"error": f"Error fetching DNS records: {response.status_code}"
|
||||
}
|
||||
response = response.json()
|
||||
return response.get('records', [])
|
||||
|
||||
|
||||
response = hsd.rpc_getNameResource(domain)
|
||||
if response['error'] is not None:
|
||||
return {
|
||||
@@ -1569,7 +1612,9 @@ def zapTXs(account):
|
||||
|
||||
|
||||
def getxPub(account):
|
||||
account_name = check_account(account)
|
||||
account_name = account
|
||||
if account.count(":") > 0:
|
||||
account_name = check_account(account)
|
||||
|
||||
if account_name == False:
|
||||
return {
|
||||
@@ -1587,8 +1632,6 @@ def getxPub(account):
|
||||
}
|
||||
}
|
||||
return response['accountKey']
|
||||
|
||||
return response
|
||||
except Exception as e:
|
||||
return {
|
||||
"error": {
|
||||
@@ -1741,32 +1784,39 @@ def checkPreRequisites() -> dict[str, bool]:
|
||||
"git": False,
|
||||
"hsd": False
|
||||
}
|
||||
|
||||
try:
|
||||
# Check if node is installed and get version
|
||||
nodeSubprocess = subprocess.run(["node", "-v"], capture_output=True, text=True,timeout=2)
|
||||
if nodeSubprocess.returncode == 0:
|
||||
major_version = int(nodeSubprocess.stdout.strip().lstrip('v').split('.')[0])
|
||||
if major_version >= HSD_CONFIG.get("minNodeVersion", 20):
|
||||
prerequisites["node"] = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
# Check if npm is installed
|
||||
npmSubprocess = subprocess.run(["npm", "-v"], capture_output=True, text=True,timeout=2)
|
||||
if npmSubprocess.returncode == 0:
|
||||
major_version = int(npmSubprocess.stdout.strip().split('.')[0])
|
||||
if major_version >= HSD_CONFIG.get("minNPMVersion", 8):
|
||||
prerequisites["npm"] = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Check if node is installed and get version
|
||||
nodeSubprocess = subprocess.run(["node", "-v"], capture_output=True, text=True)
|
||||
if nodeSubprocess.returncode == 0:
|
||||
major_version = int(nodeSubprocess.stdout.strip().lstrip('v').split('.')[0])
|
||||
if major_version >= HSD_CONFIG.get("minNodeVersion", 20):
|
||||
prerequisites["node"] = True
|
||||
try:
|
||||
# Check if git is installed
|
||||
gitSubprocess = subprocess.run(["git", "-v"], capture_output=True, text=True,timeout=2)
|
||||
if gitSubprocess.returncode == 0:
|
||||
prerequisites["git"] = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Check if npm is installed
|
||||
npmSubprocess = subprocess.run(["npm", "-v"], capture_output=True, text=True)
|
||||
if npmSubprocess.returncode == 0:
|
||||
major_version = int(npmSubprocess.stdout.strip().split('.')[0])
|
||||
if major_version >= HSD_CONFIG.get("minNPMVersion", 8):
|
||||
prerequisites["npm"] = True
|
||||
|
||||
# Check if git is installed
|
||||
gitSubprocess = subprocess.run(["git", "-v"], capture_output=True, text=True)
|
||||
if gitSubprocess.returncode == 0:
|
||||
prerequisites["git"] = True
|
||||
|
||||
# Check if hsd is installed
|
||||
if os.path.exists("./hsd/bin/hsd"):
|
||||
prerequisites["hsd"] = True
|
||||
|
||||
|
||||
|
||||
|
||||
return prerequisites
|
||||
|
||||
@@ -1775,11 +1825,23 @@ def checkPreRequisites() -> dict[str, bool]:
|
||||
def hsdInit():
|
||||
if not HSD_INTERNAL_NODE:
|
||||
return
|
||||
prerequisites = checkPreRequisites()
|
||||
|
||||
# Don't check prerequisites if HSD is included in a docker container
|
||||
if os.getenv("HSD_DOCKER_CONTAINER", "false").lower() == "true":
|
||||
prerequisites = {
|
||||
"node": True,
|
||||
"npm": True,
|
||||
"git": True,
|
||||
"hsd": True
|
||||
}
|
||||
else:
|
||||
prerequisites = checkPreRequisites()
|
||||
|
||||
minNodeVersion = HSD_CONFIG.get("minNodeVersion", 20)
|
||||
minNPMVersion = HSD_CONFIG.get("minNPMVersion", 8)
|
||||
PREREQ_MESSAGES = {
|
||||
"node": "Install Node.js from https://nodejs.org/en/download (Version >= {minNodeVersion})",
|
||||
"npm": "Install npm (version >= {minNPMVersion}) - usually comes with Node.js",
|
||||
"node": f"Install Node.js from https://nodejs.org/en/download (Version >= {minNodeVersion})",
|
||||
"npm": f"Install npm (version >= {minNPMVersion}) - usually comes with Node.js",
|
||||
"git": "Install Git from https://git-scm.com/downloads"}
|
||||
|
||||
|
||||
@@ -1788,8 +1850,10 @@ def hsdInit():
|
||||
print("HSD Internal Node prerequisites not met:")
|
||||
for key, value in prerequisites.items():
|
||||
if not value:
|
||||
print(f" - {key} is missing or does not meet the version requirement.")
|
||||
exit(1)
|
||||
print(f" - {key} is missing or does not meet the version requirement.",flush=True)
|
||||
if key in PREREQ_MESSAGES:
|
||||
print(PREREQ_MESSAGES[key],flush=True)
|
||||
exit(1)
|
||||
return
|
||||
|
||||
# Check if hsd is installed
|
||||
@@ -1915,7 +1979,6 @@ def hsdRestart():
|
||||
hsdStart()
|
||||
|
||||
|
||||
checkPreRequisites()
|
||||
hsdInit()
|
||||
hsdStart()
|
||||
# endregion
|
||||
14
docker-compose-internal.yml
Normal file
14
docker-compose-internal.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
services:
|
||||
firewallet:
|
||||
image: firewallet-hsd:latest
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
- hsd_data:/app/hsd-data
|
||||
- user_data:/app/user_data
|
||||
environment:
|
||||
- INTERNAL_HSD=true
|
||||
|
||||
volumes:
|
||||
hsd_data:
|
||||
user_data:
|
||||
26
docker-compose.yml
Normal file
26
docker-compose.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
services:
|
||||
hsd:
|
||||
image: ghcr.io/handshake-org/hsd:8
|
||||
volumes:
|
||||
- hsd_data:/root/.hsd
|
||||
environment:
|
||||
- HSD_HTTP_HOST=0.0.0.0
|
||||
- HSD_WALLET_HTTP_HOST=0.0.0.0
|
||||
- HSD_LOG_LEVEL=error
|
||||
- HSD_API_KEY=changeme
|
||||
|
||||
|
||||
firewallet:
|
||||
image: git.woodburn.au/nathanwoodburn/firewallet:latest
|
||||
ports:
|
||||
- "5000:5000"
|
||||
environment:
|
||||
- HSD_IP=hsd
|
||||
- HSD_API=changeme
|
||||
volumes:
|
||||
- user_data:/app/user_data
|
||||
|
||||
|
||||
volumes:
|
||||
hsd_data:
|
||||
user_data:
|
||||
45
grant.md
45
grant.md
@@ -1,45 +0,0 @@
|
||||
What have you built previously?
|
||||
- [HNSHosting](https://hnshosting.au)
|
||||
- [ShakeCities](https://shakecities.com)
|
||||
- [FireWallet](https://firewallet.au)
|
||||
- [Git Profile](https://github.com/nathanwoodburn)
|
||||
|
||||
Project summary
|
||||
A Handshake wallet web ui. This will be a HSD wallet web ui that will allow users to manage their Handshake domains via a web interface. This will allow users to easily manage their domains without having to use the command line or bob. One benefit of this is that it will allow users to easily manage their domains from their mobile devices that don't have access to any HNS wallet. This could be done in a secure way by only allowing connections on local network devices (in addition to requiring the wallet credentials).
|
||||
|
||||
Features:
|
||||
- Login with HSD wallet name + password (by default don't show a list of wallets to login to as this could be a security risk)
|
||||
- View account information in a dashboard
|
||||
- Available balance
|
||||
- Total balance
|
||||
- Pending Transactions
|
||||
- List of domains
|
||||
- List of transactions
|
||||
- Manage domains
|
||||
- Transfer domains
|
||||
- Finalize domains
|
||||
- Edit domains
|
||||
- Revoke domains (with a warning and requiring the account password)
|
||||
- Manage wallet
|
||||
- Send HNS
|
||||
- Receive HNS
|
||||
- Auctions
|
||||
- View bids on domain
|
||||
- Open auction
|
||||
- Bid on auction
|
||||
- Reveal bid
|
||||
- Redeem bid
|
||||
- Register domain
|
||||
|
||||
Completion requirements:
|
||||
- Basic functionality including
|
||||
- View info
|
||||
- Send/Receive HNS
|
||||
- Manage domains
|
||||
|
||||
After the initial version is completed I will be looking to add more features including the above mentioned features.
|
||||
|
||||
|
||||
The initial version will be completed in 2-3 weeks with a fully fledged version released later as the features are developed and tested.
|
||||
|
||||
You can contact me at handshake @ nathan.woodburn.au
|
||||
14
main.py
14
main.py
@@ -30,7 +30,7 @@ fees = 0.02
|
||||
revokeCheck = random.randint(100000,999999)
|
||||
|
||||
|
||||
THEME = os.getenv("THEME")
|
||||
THEME = os.getenv("THEME", "black")
|
||||
|
||||
|
||||
def blocks_to_time(blocks: int) -> str:
|
||||
@@ -1148,15 +1148,20 @@ def settings():
|
||||
if success == None:
|
||||
success = ""
|
||||
|
||||
|
||||
if not os.path.exists(".git"):
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version="Error",internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version="Error",
|
||||
internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
info = gitinfo.get_git_info()
|
||||
if not info:
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version="Error",internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version="Error",
|
||||
internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
|
||||
branch = info['refs']
|
||||
if branch != "main":
|
||||
@@ -1171,7 +1176,8 @@ def settings():
|
||||
version += ' (New version available)'
|
||||
return render_template("settings.html", account=account,
|
||||
hsd_version=account_module.hsdVersion(False),
|
||||
error=error,success=success,version=version,internal=account_module.HSD_INTERNAL_NODE)
|
||||
error=error,success=success,version=version,internal=account_module.HSD_INTERNAL_NODE,
|
||||
spv=account_module.isSPV())
|
||||
|
||||
@app.route('/settings/<action>')
|
||||
def settings_action(action):
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<h3 class="mb-1" style="text-align: center;color: rgb(0,255,0);">{{success}}</h3>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Node Settings</h4><small>HSD Version: v{{hsd_version}}</small>
|
||||
<h4 class="card-title">Node Settings</h4><small>HSD Version: v{{hsd_version}} Type: {% if internal %} Internal {% else %} Remote {% endif %} ({% if spv %}SPV{% else %}Full Node{% endif %})</small>
|
||||
<h6 class="text-muted mb-2 card-subtitle">Settings that affect all wallets</h6><ul class="list-group">
|
||||
<li class="list-group-item">
|
||||
<div><a class="btn btn-primary stick-right" role="button" href="/settings/rescan">Rescan</a>
|
||||
|
||||
Reference in New Issue
Block a user