diff --git a/contact/contactbot.py b/contact/contactbot.py
index b75b7773..bd48ad71 100644
--- a/contact/contactbot.py
+++ b/contact/contactbot.py
@@ -176,7 +176,7 @@ async def do_mkgroup(self, message: Message, target_number: str) -> str:
async def payment_response(self, msg: Message, amount_pmob: int) -> str:
del amount_pmob
- diff = await self.get_user_balance(msg.source) - self.usd_price
+ diff = await self.get_user_usd_balance(msg.source) - self.usd_price
if diff < 0:
return f"Please send another {abs(diff)} USD to buy a phone number"
if diff == 0:
@@ -196,7 +196,7 @@ async def do_status(self, message: Message) -> Union[list[str], str]:
if numbers:
return f"Hi {message.name}! We found several numbers {numbers} registered for your user. Try '/send {message.source} Hello from Forest Contact via {numbers[0]}!'."
# paid but not registered
- if await self.get_user_balance(message.source) > 0 and not numbers:
+ if await self.get_user_usd_balance(message.source) > 0 and not numbers:
return [
"Welcome to the beta! Thank you for your payment. Please contact support to finish setting up your account by requesting to join this group. We will reach out within 12 hours.",
"https://signal.group/#CjQKINbHvfKoeUx_pPjipkXVspTj5HiTiUjoNQeNgmGvCmDnEhCTYgZZ0puiT-hUG0hUUwlS",
@@ -228,13 +228,13 @@ async def do_register(self, message: Message) -> Response:
"Upon payment, you will be able to select the area code for your new phone number!",
]
- async def get_user_balance(self, account: str) -> float:
+ async def get_user_usd_balance(self, account: str) -> float:
res = await self.mobster.ledger_manager.get_usd_balance(account)
return float(round(res[0].get("balance"), 2))
async def do_balance(self, message: Message) -> str:
"""Check your balance"""
- balance = await self.get_user_balance(message.source)
+ balance = await self.get_user_usd_balance(message.source)
return f"Your balance is {balance} USD"
async def do_pay(self, message: Message) -> str:
@@ -251,7 +251,7 @@ async def do_order(self, msg: Message) -> str:
"""Usage: /order """
if not (msg.arg1 and len(msg.arg1) == 3 and msg.arg1.isnumeric()):
return """Usage: /order """
- diff = await self.get_user_balance(msg.source) - self.usd_price
+ diff = await self.get_user_usd_balance(msg.source) - self.usd_price
if diff < 0:
return "Make a payment with Signal Pay or /register first"
await self.routing_manager.sweep_expired_destinations()
diff --git a/forest/core.py b/forest/core.py
index e4c5c405..a6c65e0d 100755
--- a/forest/core.py
+++ b/forest/core.py
@@ -1014,10 +1014,14 @@ async def handle_message(self, message: Message) -> Response:
return None
return await super().handle_message(message)
- async def get_user_balance(self, account: str) -> float:
+ async def get_user_usd_balance(self, account: str) -> float:
res = await self.mobster.ledger_manager.get_usd_balance(account)
return float(round(res[0].get("balance"), 2))
+ async def get_user_pmob_balance(self, account: str) -> float:
+ res = await self.mobster.ledger_manager.get_pmob_balance(account)
+ return res[0].get("balance")
+
async def handle_payment(self, message: Message) -> None:
"""Decode the receipt, then update balances.
Blocks on transaction completion, run concurrently"""
@@ -1651,6 +1655,7 @@ async def ask_email_question(
return email
+ @hide
async def do_challenge(self, msg: Message) -> Response:
"""Challenges a user to do a simple math problem,
optionally provided as an image to increase attacker complexity."""
diff --git a/forest/payments_monitor.py b/forest/payments_monitor.py
index cfd72c4b..3c4a5437 100644
--- a/forest/payments_monitor.py
+++ b/forest/payments_monitor.py
@@ -52,6 +52,8 @@
VALUES($1, $2, $3, $4, CURRENT_TIMESTAMP);",
get_usd_balance="SELECT COALESCE(SUM(amount_usd_cents)/100, 0.0) AS balance \
FROM {self.table} WHERE account=$1",
+ get_pmob_balance="SELECT COALESCE(SUM(amount_pmob), 0.0) AS balance \
+ FROM {self.table} WHERE account=$1",
)
InvoicePGEExpressions = PGExpressions(
diff --git a/forest/pghelp.py b/forest/pghelp.py
index 91c7815d..66a4b542 100644
--- a/forest/pghelp.py
+++ b/forest/pghelp.py
@@ -133,6 +133,8 @@ async def connect_pg(self) -> None:
self.pool = await asyncpg.create_pool(self.database)
pools.append(self.pool)
+ _autocreating_table = False
+
async def execute(
self,
qstring: str,
@@ -156,10 +158,24 @@ async def execute(
# )
# return self.execute(qstring, *args, timeout=timeout)
# _execute takes query, args, limit, timeout
- result = await connection._execute(
- qstring, args, 0, timeout, return_status=True
- )
- # list[asyncpg.Record], str, bool
+ try:
+ result = await connection._execute(
+ qstring, args, 0, timeout, return_status=True
+ )
+ # list[asyncpg.Record], str, bool
+ except asyncpg.UndefinedTableError:
+ if self._autocreating_table:
+ logging.error(
+ "would try creating the table, but we already tried to do that"
+ )
+ raise
+ self._autocreating_table = True
+ logging.info("creating table %s", self.table)
+ await self.create_table()
+ self._autocreating_table = False
+ result = await connection._execute(
+ qstring, args, 0, timeout, return_status=True
+ )
return result[0]
return None
diff --git a/mc_util/__init__.py b/mc_util/__init__.py
index 3f9f24fe..ec4e3ec2 100644
--- a/mc_util/__init__.py
+++ b/mc_util/__init__.py
@@ -13,6 +13,7 @@
PMOB = Decimal("1e12")
+FEE_PMOB = int(1e12 * 0.0004) # mobilecoin transaction fee in picomob.
def mob2pmob(x: Union[Decimal, float]) -> int: