feat: Implement contract checkout payment service and account management UI.

This commit is contained in:
2569718930@qq.com
2026-03-13 07:31:47 +08:00
parent 54c4a26162
commit 31ee147734
13 changed files with 613 additions and 438 deletions
+9 -1
View File
@@ -42,6 +42,13 @@ SUPABASE_SUB_CACHE_TTL_SEC=60
# - Pro entitlement removed
# - user only needs to be a member of TELEGRAM_CHAT_ID group
POLYWEATHER_BOT_GROUP_INVITE_URL=
# Group message points (anti-spam + ranking)
POLYWEATHER_BOT_MESSAGE_POINTS=4
POLYWEATHER_BOT_MESSAGE_DAILY_CAP=40
POLYWEATHER_BOT_MESSAGE_MIN_LENGTH=3
POLYWEATHER_BOT_MESSAGE_COOLDOWN_SEC=30
POLYWEATHER_BOT_CITY_QUERY_COST=1
POLYWEATHER_BOT_DEB_QUERY_COST=1
# Backend entitlement guard (for /api/cities, /api/city/*, /api/history/*)
POLYWEATHER_REQUIRE_ENTITLEMENT=false
POLYWEATHER_BACKEND_ENTITLEMENT_TOKEN=
@@ -64,7 +71,7 @@ POLYWEATHER_PAYMENT_TELEGRAM_NOTIFY_ENABLED=true
# Default is monthly-only launch.
POLYWEATHER_PAYMENT_ALLOWED_PLAN_CODES=pro_monthly
# JSON object
# Example: {"pro_monthly":{"plan_id":101,"amount_usdc":"29","duration_days":30}}
# Example: {"pro_monthly":{"plan_id":101,"amount_usdc":"5","duration_days":30}}
POLYWEATHER_PAYMENT_PLAN_CATALOG_JSON=
# Polymarket P0 Read-Only Market Layer
@@ -122,3 +129,4 @@ POLYMARKET_WALLET_ACTIVITY_UPDATE_DEBOUNCE_SEC=30
POLYMARKET_WALLET_ACTIVITY_UPDATE_MAX_HOLD_SEC=120
POLYMARKET_WALLET_ACTIVITY_AVG_PRICE_SHOW_MIN=0.01
POLYMARKET_WALLET_ACTIVITY_AVG_PRICE_SHOW_MAX=0.99
@@ -0,0 +1,2 @@
8cb93e59a06d811632ae336df0f6be7e74a10664 {"key":"make-fetch-happen:request-cache:https://registry.npmmirror.com/npm","integrity":"sha512-xePHdYHkp4kEac1FHhITRlDVqNl3EHt4DwARUbax5MhBVMcQQ3IdoY/AuuAcKi0T8tBoPPVPKQ1zbdRcWmyZmw==","time":1773356698813,"size":2200583,"metadata":{"time":1773356698656,"url":"https://registry.npmmirror.com/npm","reqHeaders":{"accept":"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*"},"resHeaders":{"cache-control":"public, max-age=300","content-encoding":"gzip","content-type":"application/json; charset=utf-8","date":"Thu, 12 Mar 2026 23:04:01 GMT","etag":"W/\"42af5864cc03e9bad6ddc5c3f6fff0e916e8b4fc\"","vary":"Origin, Accept, Accept-Encoding"},"options":{"compress":true}}}
@@ -0,0 +1,50 @@
0 verbose cli C:\Program Files\nodejs\node.exe D:\Program Files\nodejs\node_global\node_modules\npm\bin\npm-cli.js
1 info using npm@8.16.0
2 info using node@v24.11.0
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:D:\Program Files\nodejs\node_global\node_modules\npm\npmrc Completed in 2ms
6 timing config:load:builtin Completed in 2ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:E:\web\PolyWeather\frontend\.npmrc Completed in 1ms
10 timing config:load:project Completed in 3ms
11 timing config:load:file:C:\Users\Yang\.npmrc Completed in 0ms
12 timing config:load:user Completed in 0ms
13 verbose config error loading global config [Error: EPERM: operation not permitted, open 'C:\Users\Yang\AppData\Roaming\npm\etc\npmrc'] {
13 verbose config errno: -4048,
13 verbose config code: 'EPERM',
13 verbose config syscall: 'open',
13 verbose config path: 'C:\\Users\\Yang\\AppData\\Roaming\\npm\\etc\\npmrc'
13 verbose config }
14 timing config:load:file:C:\Users\Yang\AppData\Roaming\npm\etc\npmrc Completed in 1ms
15 timing config:load:global Completed in 1ms
16 timing config:load:validate Completed in 1ms
17 timing config:load:credentials Completed in 1ms
18 timing config:load:setEnvs Completed in 0ms
19 timing config:load Completed in 12ms
20 timing npm:load:configload Completed in 13ms
21 timing npm:load:mkdirpcache Completed in 1ms
22 timing npm:load:mkdirplogs Completed in 1ms
23 verbose title npm run build
24 verbose argv "run" "build"
25 timing npm:load:setTitle Completed in 0ms
26 timing config:load:flatten Completed in 2ms
27 timing npm:load:display Completed in 2ms
28 verbose logfile logs-max:10 dir:E:\web\PolyWeather\.npm-cache\_logs
29 verbose logfile E:\web\PolyWeather\.npm-cache\_logs\2026-03-12T23_04_58_382Z-debug-0.log
30 timing npm:load:logFile Completed in 6ms
31 timing npm:load:timers Completed in 0ms
32 timing npm:load:configScope Completed in 0ms
33 timing npm:load Completed in 23ms
34 silly logfile done cleaning log files
35 http fetch GET 200 https://registry.npmmirror.com/npm 354ms (cache miss)
36 timing command:run Completed in 1340ms
37 notice
37 notice New major version of npm available! 8.16.0 -> 11.11.1
37 notice Changelog: <https://github.com/npm/cli/releases/tag/v11.11.1>
37 notice Run `npm install -g npm@11.11.1` to update!
37 notice
38 verbose exit 1
39 timing npm Completed in 1412ms
40 verbose code 1
@@ -0,0 +1,38 @@
0 verbose cli C:\Program Files\nodejs\node.exe D:\Program Files\nodejs\node_global\node_modules\npm\bin\npm-cli.js
1 info using npm@8.16.0
2 info using node@v24.11.0
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:D:\Program Files\nodejs\node_global\node_modules\npm\npmrc Completed in 2ms
6 timing config:load:builtin Completed in 2ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:E:\web\PolyWeather\frontend\.npmrc Completed in 0ms
10 timing config:load:project Completed in 2ms
11 timing config:load:file:C:\Users\Yang\.npmrc Completed in 1ms
12 timing config:load:user Completed in 1ms
13 timing config:load:file:C:\Users\Yang\AppData\Roaming\npm\etc\npmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:credentials Completed in 1ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 12ms
19 timing npm:load:configload Completed in 13ms
20 timing npm:load:mkdirpcache Completed in 1ms
21 timing npm:load:mkdirplogs Completed in 0ms
22 verbose title npm run build
23 verbose argv "run" "build"
24 timing npm:load:setTitle Completed in 1ms
25 timing config:load:flatten Completed in 1ms
26 timing npm:load:display Completed in 2ms
27 verbose logfile logs-max:10 dir:E:\web\PolyWeather\.npm-cache\_logs
28 verbose logfile E:\web\PolyWeather\.npm-cache\_logs\2026-03-12T23_05_44_607Z-debug-0.log
29 timing npm:load:logFile Completed in 5ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 22ms
33 silly logfile done cleaning log files
34 timing command:run Completed in 5592ms
35 verbose exit 1
36 timing npm Completed in 5625ms
37 verbose code 1
@@ -0,0 +1,38 @@
0 verbose cli C:\Program Files\nodejs\node.exe D:\Program Files\nodejs\node_global\node_modules\npm\bin\npm-cli.js
1 info using npm@8.16.0
2 info using node@v24.11.0
3 timing npm:load:whichnode Completed in 1ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:D:\Program Files\nodejs\node_global\node_modules\npm\npmrc Completed in 2ms
6 timing config:load:builtin Completed in 2ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:E:\web\PolyWeather\frontend\.npmrc Completed in 0ms
10 timing config:load:project Completed in 3ms
11 timing config:load:file:C:\Users\Yang\.npmrc Completed in 0ms
12 timing config:load:user Completed in 0ms
13 timing config:load:file:C:\Users\Yang\AppData\Roaming\npm\etc\npmrc Completed in 1ms
14 timing config:load:global Completed in 1ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:credentials Completed in 0ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 12ms
19 timing npm:load:configload Completed in 12ms
20 timing npm:load:mkdirpcache Completed in 1ms
21 timing npm:load:mkdirplogs Completed in 0ms
22 verbose title npm run build
23 verbose argv "run" "build"
24 timing npm:load:setTitle Completed in 1ms
25 timing config:load:flatten Completed in 2ms
26 timing npm:load:display Completed in 2ms
27 verbose logfile logs-max:10 dir:E:\web\PolyWeather\.npm-cache\_logs
28 verbose logfile E:\web\PolyWeather\.npm-cache\_logs\2026-03-12T23_06_24_382Z-debug-0.log
29 timing npm:load:logFile Completed in 5ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 22ms
33 silly logfile done cleaning log files
34 timing command:run Completed in 28008ms
35 verbose exit 0
36 timing npm Completed in 28039ms
37 info ok
@@ -0,0 +1,38 @@
0 verbose cli C:\Program Files\nodejs\node.exe D:\Program Files\nodejs\node_global\node_modules\npm\bin\npm-cli.js
1 info using npm@8.16.0
2 info using node@v24.11.0
3 timing npm:load:whichnode Completed in 0ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:D:\Program Files\nodejs\node_global\node_modules\npm\npmrc Completed in 2ms
6 timing config:load:builtin Completed in 2ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 0ms
9 timing config:load:file:E:\web\PolyWeather\frontend\.npmrc Completed in 0ms
10 timing config:load:project Completed in 3ms
11 timing config:load:file:C:\Users\Yang\.npmrc Completed in 1ms
12 timing config:load:user Completed in 1ms
13 timing config:load:file:C:\Users\Yang\AppData\Roaming\npm\etc\npmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:credentials Completed in 1ms
17 timing config:load:setEnvs Completed in 1ms
18 timing config:load Completed in 13ms
19 timing npm:load:configload Completed in 13ms
20 timing npm:load:mkdirpcache Completed in 0ms
21 timing npm:load:mkdirplogs Completed in 1ms
22 verbose title npm run build
23 verbose argv "run" "build"
24 timing npm:load:setTitle Completed in 0ms
25 timing config:load:flatten Completed in 3ms
26 timing npm:load:display Completed in 4ms
27 verbose logfile logs-max:10 dir:E:\web\PolyWeather\.npm-cache\_logs
28 verbose logfile E:\web\PolyWeather\.npm-cache\_logs\2026-03-12T23_13_24_173Z-debug-0.log
29 timing npm:load:logFile Completed in 5ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 23ms
33 silly logfile done cleaning log files
34 timing command:run Completed in 15766ms
35 verbose exit 1
36 timing npm Completed in 15801ms
37 verbose code 1
@@ -0,0 +1,38 @@
0 verbose cli C:\Program Files\nodejs\node.exe D:\Program Files\nodejs\node_global\node_modules\npm\bin\npm-cli.js
1 info using npm@8.16.0
2 info using node@v24.11.0
3 timing npm:load:whichnode Completed in 1ms
4 timing config:load:defaults Completed in 2ms
5 timing config:load:file:D:\Program Files\nodejs\node_global\node_modules\npm\npmrc Completed in 2ms
6 timing config:load:builtin Completed in 2ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:E:\web\PolyWeather\frontend\.npmrc Completed in 0ms
10 timing config:load:project Completed in 3ms
11 timing config:load:file:C:\Users\Yang\.npmrc Completed in 1ms
12 timing config:load:user Completed in 1ms
13 timing config:load:file:C:\Users\Yang\AppData\Roaming\npm\etc\npmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:validate Completed in 1ms
16 timing config:load:credentials Completed in 1ms
17 timing config:load:setEnvs Completed in 0ms
18 timing config:load Completed in 12ms
19 timing npm:load:configload Completed in 12ms
20 timing npm:load:mkdirpcache Completed in 1ms
21 timing npm:load:mkdirplogs Completed in 1ms
22 verbose title npm run build
23 verbose argv "run" "build"
24 timing npm:load:setTitle Completed in 0ms
25 timing config:load:flatten Completed in 2ms
26 timing npm:load:display Completed in 2ms
27 verbose logfile logs-max:10 dir:E:\web\PolyWeather\.npm-cache\_logs
28 verbose logfile E:\web\PolyWeather\.npm-cache\_logs\2026-03-12T23_24_16_712Z-debug-0.log
29 timing npm:load:logFile Completed in 5ms
30 timing npm:load:timers Completed in 0ms
31 timing npm:load:configScope Completed in 0ms
32 timing npm:load Completed in 22ms
33 silly logfile done cleaning log files
34 timing command:run Completed in 28946ms
35 verbose exit 0
36 timing npm Completed in 28976ms
37 info ok
File diff suppressed because it is too large Load Diff
+6
View File
@@ -71,6 +71,7 @@ class BotIOLayer:
self.db.upsert_user(user.id, self.display_name(user))
user_info = self.db.get_user(user.id)
now = datetime.now()
today_str = now.strftime("%Y-%m-%d")
iso_year, iso_week, _ = now.isocalendar()
week_key = f"{iso_year}-W{iso_week:02d}"
@@ -85,12 +86,17 @@ class BotIOLayer:
if user_info:
daily_points = int(user_info.get("daily_points") or 0)
daily_points_date = str(user_info.get("daily_points_date") or "")
if daily_points_date != today_str:
daily_points = 0
if daily_points > MESSAGE_DAILY_CAP:
daily_points = MESSAGE_DAILY_CAP
weekly_points = int(user_info.get("weekly_points") or 0)
weekly_points_week = str(user_info.get("weekly_points_week") or "")
if weekly_points_week != week_key:
weekly_points = 0
rank_text += "────────────────────\n"
rank_text += (
"👤 <b>我的状态:</b>\n"
+22 -6
View File
@@ -1,6 +1,22 @@
MESSAGE_POINTS = 4
MESSAGE_DAILY_CAP = 10
MESSAGE_MIN_LENGTH = 3
MESSAGE_COOLDOWN_SEC = 30
CITY_QUERY_COST = 1
DEB_QUERY_COST = 1
from __future__ import annotations
import os
def _env_int(name: str, default: int, min_value: int = 0) -> int:
raw = str(os.getenv(name, "")).strip()
if not raw:
return default
try:
value = int(raw)
except (TypeError, ValueError):
return default
return max(min_value, value)
MESSAGE_POINTS = _env_int("POLYWEATHER_BOT_MESSAGE_POINTS", 4, min_value=1)
MESSAGE_DAILY_CAP = _env_int("POLYWEATHER_BOT_MESSAGE_DAILY_CAP", 40, min_value=1)
MESSAGE_MIN_LENGTH = _env_int("POLYWEATHER_BOT_MESSAGE_MIN_LENGTH", 3, min_value=1)
MESSAGE_COOLDOWN_SEC = _env_int("POLYWEATHER_BOT_MESSAGE_COOLDOWN_SEC", 30, min_value=0)
CITY_QUERY_COST = _env_int("POLYWEATHER_BOT_CITY_QUERY_COST", 1, min_value=0)
DEB_QUERY_COST = _env_int("POLYWEATHER_BOT_DEB_QUERY_COST", 1, min_value=0)
+1 -1
View File
@@ -70,7 +70,7 @@ PAYMENT_CONTRACT_ABI = [
]
DEFAULT_PLAN_CATALOG: Dict[str, Dict[str, Any]] = {
"pro_monthly": {"plan_id": 101, "amount_usdc": "29", "duration_days": 30},
"pro_monthly": {"plan_id": 101, "amount_usdc": "5", "duration_days": 30},
"pro_quarterly": {"plan_id": 102, "amount_usdc": "79", "duration_days": 90},
"pro_yearly": {"plan_id": 103, "amount_usdc": "279", "duration_days": 365},
}