From 15af7174c6989f6252245abc964935907ee7ca23 Mon Sep 17 00:00:00 2001 From: ZOMBIIIIIII <120676065+Metaton241@users.noreply.github.com> Date: Thu, 28 May 2026 15:40:41 +0300 Subject: [PATCH] init339398989 --- .env.backup-before-rollback | 34 --------- .env.example | 74 ------------------- .../src/services/bridge-execute.service.ts | 8 +- apps/api/src/services/wallet-signer-bridge.ts | 9 ++- 4 files changed, 10 insertions(+), 115 deletions(-) delete mode 100644 .env.backup-before-rollback delete mode 100644 .env.example diff --git a/.env.backup-before-rollback b/.env.backup-before-rollback deleted file mode 100644 index f649749..0000000 --- a/.env.backup-before-rollback +++ /dev/null @@ -1,34 +0,0 @@ -# Local .env for docker compose ${REDIS_PASSWORD} interpolation. -# DO NOT COMMIT (already in .gitignore). На прод-боксе оператор создаёт свой через `cp .env.example .env`. - -VAULT_ADDR= -VAULT_ROLE_ID= -VAULT_SECRET_ID= -VAULT_MOUNT_POINT=dev-secrets -VAULT_SECRET_PATH=database -VAULT_JWT_KID_PATH=jwt/kid -VAULT_JWT_KIDS_PREFIX=jwt/kids -VAULT_CSRF_PATH=csrf -VAULT_CRYPTO_KEY_PATH=crypto/master - -JWT_ALGORITHM=RS256 -JWT_ISSUER=bitok -JWT_AUDIENCE=elcsa - -API_PORT=3001 -LOG_LEVEL=INFO - -CORS_ORIGINS=* -CORS_ALLOW_CREDENTIALS=false - -REDIS_HOST=keydb -REDIS_PORT=6379 -REDIS_PASSWORD=0O7klMYUvwwR19UORSzEtsRn9kUPnDyfkJ9GDH2yMERYV0vRCU -REDIS_DB=0 - -# Price oracle (CoinGecko free tier — без ключа работает). -COINGECKO_API_KEY= - -# Outbound proxy для swap + bridge endpoints. -# Если задан — Jupiter/Relay/RPC calls идут через proxy. Read-only direct. -OUTBOUND_PROXY_URL=http://37.220.84.34:3128 diff --git a/.env.example b/.env.example deleted file mode 100644 index 5f31b24..0000000 --- a/.env.example +++ /dev/null @@ -1,74 +0,0 @@ -# ───────────────────────────────────────────────────────────────────── -# Production .env template для CryptoWallet API. -# Скопируй: cp .env.example .env && chmod 600 .env && nano .env -# ───────────────────────────────────────────────────────────────────── - -# ─── HashiCorp Vault (для master-key, JWT public keys, CSRF secret) ── -VAULT_ADDR=https://vault.your-domain.com -VAULT_ROLE_ID=00000000-0000-0000-0000-000000000000 -VAULT_SECRET_ID=00000000-0000-0000-0000-000000000000 -VAULT_MOUNT_POINT=dev-secrets -VAULT_SECRET_PATH=crypto/master -VAULT_JWT_KID_PATH=jwt/kid -VAULT_JWT_KIDS_PREFIX=jwt/kids/ -VAULT_CSRF_PATH=csrf -VAULT_CRYPTO_KEY_PATH=crypto/master - -# ─── JWT (приём от bitok external issuer) ──────────────────────────── -JWT_ALGORITHM=RS256 -JWT_ISSUER=bitok -JWT_AUDIENCE=cryptowallet-api - -# ─── API runtime ───────────────────────────────────────────────────── -API_PORT=3001 -LOG_LEVEL=info - -# CORS — comma-separated list разрешённых origins (фронтенд hosts) -CORS_ORIGINS=https://app.your-domain.com,https://admin.your-domain.com -CORS_ALLOW_CREDENTIALS=true - -# ─── Postgres (для docker-compose) ─────────────────────────────────── -# Эти переменные используются compose'ом для создания/connect к Postgres контейнеру. -# Если оператор использует external managed Postgres — игнорь POSTGRES_* и впиши -# connection string в DATABASE_URL ниже. -POSTGRES_USER=cryptowallet -POSTGRES_PASSWORD=__GENERATE_STRONG_PASSWORD__ -POSTGRES_DB=cryptowallet - -# Если используешь managed/external Postgres — раскомментируй и заполни: -# DATABASE_URL=postgres://user:pass@host:5432/dbname - -# ─── KeyDB / Redis (idempotency cache + NearIntents asset map cache) ─ -# REDIS_HOST=keydb имя service в compose — НЕ меняй если работаешь через compose -REDIS_HOST=keydb -REDIS_PORT=6379 -REDIS_PASSWORD=__GENERATE_STRONG_PASSWORD__ -REDIS_DB=0 - -# ─── Внешние API ───────────────────────────────────────────────────── -# CoinGecko — для prices/dynamics (без ключа работает с rate limits) -COINGECKO_API_KEY= - -# Jupiter — для SOL custodial swap (без ключа = lower rate limits) -JUPITER_API_KEY= - -# Jupiter referral — если хочешь чтобы SOL swap fees шли через Jupiter feeAccount. -# Сейчас у нас атомарный 0.7% fee atomic в swap-orchestrator (на APP_FEE_WALLET_SOL), -# referral отдельный механизм. Можно оставить пустым. -JUPITER_REFERRAL_ACCOUNT= - -# TronGrid — для TRX queries (без ключа 3 req/sec, с ключом 100/sec) -# Получить: https://www.trongrid.io/dashboard -TRON_API_KEY= - -# Outbound HTTP proxy (опц.) — если хотите чтобы Jupiter/Relay/NearIntents calls -# шли через proxy (rotation IP для rate limits). Формат: http://user:pass@host:port -OUTBOUND_PROXY_URL= - -# ─── App fee wallets ───────────────────────────────────────────────── -# Эти адреса HARDCODED в backend (apps/api/src/lib/app-fee.ts), НЕ настраиваются -# через env. Если нужно изменить — code review + rebuild. -# EVM (ETH+BSC): 0xeb9fbf0d137ef5ea7b9959044c2ed44ec1206c68 -# SOL: DQkQegoX698XkcXZ6VX9P1qUpbV64Sgjz1BCPFgfWpjD -# TRX: TRwpFjnfMBe4aDJbHYEqeUVCG1auF8wFXP -# BTC: — (not collectable) diff --git a/apps/api/src/services/bridge-execute.service.ts b/apps/api/src/services/bridge-execute.service.ts index c87daf1..c16f250 100644 --- a/apps/api/src/services/bridge-execute.service.ts +++ b/apps/api/src/services/bridge-execute.service.ts @@ -28,7 +28,7 @@ import { signAndBroadcastEvmFeeTx, signAndBroadcastSolanaTx, } from './wallet-signer.service'; -import { computeAppFee, getAppFeeWallet, APP_FEE_WALLET_SOL, APP_FEE_WALLET_TRX } from '../lib/app-fee'; +import { computeAppFee, APP_FEE_WALLET_SOL, APP_FEE_WALLET_TRX } from '../lib/app-fee'; import { SOL_TOKENS, TRX_TOKENS } from '../lib/token-registry'; /** @@ -448,8 +448,6 @@ async function executeSol( // ── App fee 0.7% (atomic — fee tx ПЕРЕД main bridge) ── // Native SOL bridge → fee in native SOL. SPL bridge → fee in same SPL token. // Если fee = 0 (amount слишком мал) → throw (anti-bypass). - let feeTxid: string | undefined; - let feeAmount: string | undefined; const feeAmountBig = computeAppFee(p.fromAmount); if (feeAmountBig <= 0n) { throw new Error('SOL bridge: fromAmount too small — fee = 0'); @@ -466,8 +464,8 @@ async function executeSol( amount: feeAmountBig.toString(), token: feeSymbol, }); - feeTxid = feeRes.txid; - feeAmount = feeAmountBig.toString(); + const feeTxid = feeRes.txid; + const feeAmount = feeAmountBig.toString(); logger.info(`SOL bridge fee broadcast: ${feeAmount} ${feeSymbol || 'lamports'} → ${APP_FEE_WALLET_SOL} (txid ${feeTxid})`); // Для SOL LiFi возвращает в `transactionRequest.data` = base64-encoded VersionedTransaction. diff --git a/apps/api/src/services/wallet-signer-bridge.ts b/apps/api/src/services/wallet-signer-bridge.ts index fa0665e..6d6727a 100644 --- a/apps/api/src/services/wallet-signer-bridge.ts +++ b/apps/api/src/services/wallet-signer-bridge.ts @@ -260,7 +260,7 @@ export async function signAndBroadcastRawTron(p: SignRawTronParams): Promise<{ t // Если у нас неизвестный selector (LiFi bridge calls, custom routers) — мы НЕ можем // передать "0x..." как function_selector (TronGrid keccak'нёт строку и получит // полностью другие 4 байта → contract revert). Используем `data` напрямую. - let data = p.callData.startsWith('0x') ? p.callData.slice(2) : p.callData; + const data = p.callData.startsWith('0x') ? p.callData.slice(2) : p.callData; if (data.length < 8) throw new Error('TRX call data too short (need >= 4-byte selector)'); const selector8 = data.slice(0, 8); const knownCanonical = lookupKnownSelector(selector8); @@ -294,7 +294,12 @@ export async function signAndBroadcastRawTron(p: SignRawTronParams): Promise<{ t if (!simOk) { const rawMsg = simRes?.result?.message; const msgDecoded = rawMsg - ? Buffer.from(rawMsg, 'hex').toString().replace(/[-]+/g, ' ').trim() + ? Buffer.from(rawMsg, 'hex') + .toString() + .split('') + .map((ch) => (ch.charCodeAt(0) < 32 ? ' ' : ch)) + .join('') + .trim() : ''; const reason = msgDecoded ||