Commit Graph
152 Commits
Author SHA1 Message Date
Satoshi Qazi Muhammed 4dfd587b2e ci: allow the secret scanner's own licence in dependency review
Pinning trufflehog to a commit made dependency review list it as a changed
dependency, and its AGPL-3.0 licence is on the deny list. It is the scanner
this workflow runs, executed in CI and never shipped or served, so it is
allowed by name; the deny list still applies to everything else.
2026-10-09 06:09:22 +04:00
Satoshi Qazi Muhammed f6d53f51b1 ci: deploy over pinned, single-purpose keys; root installs the gate
The deploy reached VPS3 as root with one key, handed to appleboy actions
referenced by tag, and on every run it reinstalled the edge-function
ownership gate and its registry as root. That gate guards every project's
functions in the shared volume, so any change merged here could rewrite the
rule that protects pwap's functions.

Now CI connects as miniapp-deploy with two keys, each pinned on the host
(authorized_keys restrict,command=) to a script in ops/host:

- MINIAPP_SITE_DEPLOY_KEY -> miniapp-site-receive: the site tar on stdin,
  into /var/www/telegram.pezkiwi.app, nothing else.
- MINIAPP_FUNCTIONS_DEPLOY_KEY -> miniapp-functions-ssh: `gate-sha`, or
  `deploy` with functions.tgz on stdin, run through sudo for exactly those
  arguments.

Root installs the gate and registry from ops/; the deploy checks the host's
copies against them and refuses to deploy functions while they differ.

The asset cleanup that ran after each deploy (/opt/cleanup-miniapp.sh, only
on the host) protected lazy chunks by mtime and so removed live ones when a
build was shipped more than two hours after it was made; it took seven pages
down for about two minutes on 2026-10-09 while this was being tested, and
they were restored from the same tar. The receive script now keeps every
file of the new build and removes other assets only after four hours. Its
tests cover that (red with the keep rule removed) and the refusals; CI runs
them with shellcheck, and apply-repo-settings.sh requires the job.

VPS3's host key is pinned. The commented-out VPS1 deploy is gone; that host
no longer exists. Every action is pinned to a commit SHA.
2026-10-09 06:09:22 +04:00
SatoshiQaziMuhammed 909dacd1af fix(security): patch vulnerable dependencies and code scanning findings (#21)
* chore(deps): move vulnerable dependencies to patched versions

Direct dev dependencies: vite ^5.4.1 -> ^6.4.3 (5.x has no patched
release for the fs.deny bypass and launch-editor advisories; also lifts
esbuild from 0.21.5 to 0.25.12), vitest and @vitest/coverage-v8 ->
^4.1.11, postcss -> ^8.5.23.

Transitive packages refreshed within their existing ranges:
brace-expansion, js-yaml, baseline-browser-mapping, qs, @humanfs/node,
browserslist, postcss-selector-parser, nanoid, form-data, @babel/core,
picomatch.

Overrides with a floor at the patched version where a parent pins an
old release: axios ^1.20.0 (tronweb pins 1.15.0) and ws ^8.21.0
(ethers pins 8.17.1).

* fix(security): address open code scanning findings

- auto-merge: pass workflow_run.head_branch through env instead of
  interpolating it into the shell script (code injection).
- ci, deploy, code-quality: restrict GITHUB_TOKEN to contents: read.
- telegram-bot: return a generic error body on failure; the error stays
  in the function log instead of being echoed to the caller.
- p2p-e2e-test.py: stop printing a prefix of the service-role key.
2026-10-02 21:18:32 +04:00
SatoshiQaziMuhammed 1372978298 fix(ask): use the project's secret key; fail closed when the rate limit cannot count (#20)
The DKSapp project's legacy anon/service_role keys were disabled on
2026-10-02, after the service_role key leaked through a public commit.
ask read SUPABASE_SERVICE_ROLE_KEY, so its rate limiter stopped working.

- Read the secret key from SUPABASE_SECRET_KEYS ('default'), the variable
  Supabase provides alongside the legacy one, and send it on the apikey
  header only: as a Bearer token the gateway rejects it as a malformed JWT.
- The limiter read a missing content-range as a count of zero, so a
  rejected key let every request through to the paid model. A failed
  count, a failed log write or a missing key now refuses the request.
2026-10-02 21:00:04 +04:00
SatoshiQaziMuhammed 78c7c71493 ci: drop the CodeQL job from security.yml (#18)
The organisation's code security configuration enables CodeQL default
setup, and GitHub refuses to apply it while a workflow runs CodeQL itself:
the configuration failed on this repository with "Code scanning conflict".

Default setup covers what this job did. The job ran the default query
suite with no config file, path filters or packs, and the languages it
analysed are among those default setup detects here. Default setup takes
over the scan; this workflow keeps its other jobs.

security-events: write served only the SARIF upload, so it goes with it.
contents: read is all the remaining jobs need.
2026-10-02 04:47:14 +04:00
SatoshiQaziMuhammed 9c6af146e6 ops: let a function be retired, not just deployed (#17)
* ops: let a function be retired, not just deployed

The guarded deploy could create and update, never remove. rsync runs without
--delete on purpose, so one project cannot wipe another's functions — but the
consequence was that nothing ever left. A function deleted from its repository
kept serving traffic, and nobody would know.

Found the concrete case on 2026-08-01: email-verification had been removed from
pwap on 2026-07-30 and was still live and reachable with only the anon key,
running under the service-role key with Access-Control-Allow-Origin *. Its
verify path sets profiles.email_verified for whatever user_id a token maps to.
It was not exploitable — the send path calls getUserByEmail, which the SDK does
not have, so no tokens could be minted and the table was empty. Broken is not
the same as safe; it was protected by a bug, not by design.

- --audit compares the volume against the registry both directions and exits 1
  on drift. Runs after every deploy too, so a leftover is stated rather than
  invisible.
- --retire moves functions into /opt/supabase-self-hosted/retired-functions/
  with a timestamp. Quarantined, not deleted: retiring the wrong thing has to be
  one command to undo, and that copy is the only remaining record of what was
  serving traffic.
- _cloud_hosted names now count as declared. They live on the cloud project and
  are owned by nobody here, so without this the audit would have offered to
  retire ask and telegram-bot, which look live.

Applied: email-verification retired and dropped from the registry; the audit is
clean; two-factor-auth and the miniapp's check-deposits both still answer.

* ops: catch the function a project still serves but no longer ships

The retire mechanism closed the second half of the problem. This closes the
first: nothing could detect that email-verification needed retiring.

It was never an orphan. The registry listed it as owned and current, the volume
agreed, and both were right about each other — the repository was the one that
had dropped it. Volume-vs-registry compares two of the three and cannot see a
disagreement in the third. It only became visible as drift because I removed it
from the registry by hand, which means the mechanism did not find it; I did.

A deploy is the one moment we hold the project's actual source next to the
registry and the volume, so it is the only place all three can be compared.
Anything the project owns, that is on disk, and that is absent from what it just
shipped, is now named with the command to retire it.

Warns rather than refuses: deleting a function and shipping an unrelated change
in the same commit is ordinary, and blocking that deploy until someone retires
would punish the correct move. It is printed in the deploy output and recorded
as an ABANDONED line in the deploy log.

Verified against a source tree missing eight of pwap-web's functions: all eight
named, deploy still allowed.
2026-08-01 02:30:25 -07:00
SatoshiQaziMuhammed 99efd52ed9 Merge pull request #16 from pezkuwichain/ops/version-infrastructure
ops: version the ownership gate and branch protection
2026-07-31 10:10:22 -07:00
Satoshi Qazi Muhammed b2b4751f7a ops: version the ownership gate and this repo's branch protection
Two pieces of infrastructure existed only on servers, as single copies with no
history and no review:

  /usr/local/bin/supabase-deploy-functions   the gate both projects deploy through
  /opt/supabase-self-hosted/functions-registry.json   who owns which function name

The gate exists to stop silent drift between what a repo declares and what a
server actually runs. Leaving it unversioned meant the mechanism was drifting the
same way it was built to prevent — and losing that host would have lost it
entirely, along with any record of why it works the way it does.

Both are now in ops/ and synced to the host by CI on every deploy, installed
before the functions they validate so a change to the gate ships together with
them. Verified identical to the server copies by checksum before committing, so
this captures the running state rather than replacing it.

Branch protection gets the same treatment: apply-repo-settings.sh is idempotent
and has a --check mode that reports drift without changing anything. It was
applied by hand through the API today, so nothing here reflected it.

Documented alongside: why the registry lives in this repo even though pwap-web
depends on it (a pwap-web change needs a PR here — deliberate friction, since
the registry is the record of who owns what and should not be edited on a server
where nobody sees the change), and why listing each CI job individually in the
protection rules is a weakness here that pwap-web avoids with an aggregate job.
2026-07-31 10:02:14 -07:00
SatoshiQaziMuhammed 6c65627cbb Merge pull request #15 from pezkuwichain/fix/check-deposits-cpu-v2
perf(deposits): derive the HD master key once, not once per user
2026-07-30 02:44:59 -07:00
SatoshiQaziMuhammed 89075cefc3 Merge pull request #14 from pezkuwichain/fix/main-slot-new-bot
fix(bot): main slot is @BizinikiwiBot, not a retired bot
2026-07-30 02:44:51 -07:00
Satoshi Qazi Muhammed 96cda97635 perf(deposits): derive the HD master key once, not once per user
check-deposits hits the isolate's CPU ceiling on almost every run — 17 limit
events across 20 invocations in the last 20 minutes — and when it does, the
supervisor cancels the worker and the scan stops partway. Deposits after the
cut-off simply are not seen until some later run happens to reach them.

The cause is in deriveTronAddress: it calls mnemonicToSeedSync per user, which
is PBKDF2 with 2048 iterations. The seed depends only on the mnemonic, so with
51 accounts that cost was paid 51 times a minute to produce the identical seed.
Only the derivation path varies per user.

Derive the master key once and reuse it. Measured over the 51 accounts we
actually scan: 418ms -> 58ms, a 7.2x drop in the part that was blowing the
budget.

Verified the addresses are unchanged: old and new paths produce identical
private keys for every index tested, including repeated indexes in one run,
which is what would expose derive() mutating the parent key. It does not.
2026-07-30 02:36:32 -07:00
Satoshi Qazi Muhammed 6f20008387 fix(bot): point the main slot at @BizinikiwiBot
The main slot was described as a retired testnet bot. It is not retired — a
fresh bot was created for it on 2026-07-30 under separate ownership, username
@BizinikiwiBot, display name Pezkuwichain_Bot. It is not a recovery of the
compromised @pezkuwichain_bot; that account is gone and its token stays invalid.

Its webhook carries no ?bot parameter, so getBotId falls back to main and this
slot is now a live path rather than a fallback. The cloud secret
TELEGRAM_BOT_TOKEN holds the new token.

Also puts the PEX.network link on the main welcome, so all three bots offer it.
2026-07-30 02:35:41 -07:00
SatoshiQaziMuhammed e97d73a0dd Merge pull request #13 from pezkuwichain/fix/bot-main-url-and-pex
fix(bot): dead fallback URL + PEX link on the bot users actually reach
2026-07-30 02:29:25 -07:00
Satoshi Qazi Muhammed b4af085133 fix(bot): stop the main slot handing out a dead link, add PEX to the live menu
MINI_APP_URLS.main still pointed at telegram.pezkuwichain.io, the testnet domain
whose DNS record was removed on 2026-07-12. Live webhooks arrive as ?bot=krd and
?bot=dks so that default is never reached today, but a webhook call without the
parameter would have answered /start with a link that cannot resolve.

Also puts the PEX.network link on the krd menu — @pezkuwichainBot, the bot that
actually opens the mini app. It only existed on the dks welcome, so no user
reaching the mini app through the main bot has ever been shown it.

Leaves the three-slot routing alone: both slots are live and healthy on the
cloud project, and collapsing them would have removed the AI assistant.
2026-07-30 02:25:55 -07:00
SatoshiQaziMuhammed d29d5a9ae4 Merge pull request #12 from pezkuwichain/fix/deploy-targets
ci: deploy each function to the project that actually serves it
2026-07-30 02:05:38 -07:00
Satoshi Qazi Muhammed 9e3844fd89 ci: deploy each function to the project that actually serves it
The functions in this repo do not all live in the same place, and the deploy
step I added yesterday sent all of them to the self-hosted host on vps3.

telegram-bot and ask are served from the cloud project vbhftvdayqfmcgmzdxfv.
Both Telegram bots reach it by webhook — ?bot=krd is @pezkuwichainBot and
?bot=dks is @DKSKurdistanBot — and news.pex.mom's assistant calls ask there.
Copies of both still sit in the vps3 volume from before that split, holding a
bot token revoked on 2026-07-19, and take no traffic. Deploying to vps3 was
therefore updating a dead copy while the live one kept running old code.

So the self-hosted job now excludes those two, and a second job deploys them to
the cloud project. That closes a real gap: they had been deployed by hand for
months, and git drifted far enough behind that on 2026-07-21 the running
function body had to be extracted from the deployed bundle to recover it.

The host registry records the split too, so the gate cannot be pointed at the
wrong target by accident.
2026-07-30 02:02:28 -07:00
SatoshiQaziMuhammed aa5ea29106 Merge pull request #10 from pezkuwichain/fix/groq-model-priority-mining-disclaimer
fix(auth): namespace edge functions, restore miniapp sign-in
2026-07-30 00:42:37 -07:00
Satoshi Qazi Muhammed 6c9883b858 fix(bot): keep the PEX.network button in the DKS welcome
The button is live but has never existed in this repo — `git log -S "Buy/Sell
Crypto"` returns nothing, so it was added by hand on the server and missed when
9bb9d2c synced git with the deployed source. Deploying telegram-bot from CI
would therefore have silently dropped it.

Restoring it here keeps what is actually running. Removing it should be a
deliberate decision, not a side effect of the first automated deploy.
2026-07-29 23:35:31 -07:00
Satoshi Qazi Muhammed 41bfd70322 feat(db): add ai_chat_log so the ask endpoint is actually rate limited
`ask` has never been deployed, and the CI step in this branch will publish it.
Its limiter counts rows in ai_chat_log to cap requests at 8/min and 120/day per
IP, but no migration ever created that table, and the limiter fails open when
the count cannot be read.

Shipping `ask` without this would put an unauthenticated endpoint with
Access-Control-Allow-Origin: * in front of paid model APIs with no limit at all.

Applied to the live database as well.
2026-07-29 22:36:06 -07:00
Satoshi Qazi Muhammed 35723996e1 chore: keep version at 1.0.243
The merge resolution took main's 1.0.242 for the version stamp, which moves it
backwards from this branch. Restore 1.0.243.
2026-07-29 21:55:01 -07:00
Satoshi Qazi Muhammed 3f61a4c373 Merge origin/main after #1 landed
#1 brought the live P2P identity resolution into main, which this branch's CI
deploy step needs to be present before it can safely publish these functions.
Version stamp was the only conflict; took main's.
2026-07-29 21:54:39 -07:00
SatoshiQaziMuhammed cc48ba0cd1 Merge pull request #1 from pezkuwichain/feat/unified-p2p-identity
feat: unified P2P identity — mini app + pwap/web same balance
2026-07-29 21:54:06 -07:00
Satoshi Qazi Muhammed 7cb1adb67d Merge origin/main into feat/unified-p2p-identity
Only conflict was the version stamp in package.json and src/version.json;
took main's 1.0.242 over the branch's April 1.0.230.
2026-07-29 21:53:49 -07:00
Satoshi Qazi Muhammed 54f565621c fix(auth): namespace edge functions, restore miniapp sign-in
The Supabase edge-function volume on the host is shared with pwap-web, which
deploys into it by rsyncing its whole tree. Both projects defined a function
called telegram-auth, so on 2026-06-28 pwap-web's login-widget handler replaced
this project's initData handler. Sign-in and every wallet screen behind it have
returned 401 ever since; nothing failed loudly because the name still resolved.

Rename this project's two colliding functions to a tgm- namespace so the two
deploys can no longer reach the same directory, and point the client at the new
name. process-withdraw is renamed too: it is currently unreferenced here, but it
moves platform funds, so leaving it shadowed by another project's version is not
something to keep.

Also deploy functions from CI. They were last pushed by hand in April, so seven
of them had drifted behind the repo and one had never shipped at all. The new
step writes through the host's ownership gate, which refuses any name this
project does not own — the drift and the collision both stop here.

Ownership is recorded in /opt/supabase-self-hosted/functions-registry.json.
2026-07-29 20:21:37 -07:00
SatoshiQaziMuhammed 54c94c7558 fix(ai): prioritize Groq's most stable model, stop repeating mining disclaimer (#9)
User decision after the Groq reliability fix (previous PR): prioritize
Groq's smallest/fastest model, llama-3.1-8b-instant, over gpt-oss-120b —
it's long out of preview and has historically the best free-tier
availability, at the cost of gpt-oss-120b's better Turkish/Kurdish
fluency (which is why it was chosen originally). Model order is now
llama-3.1-8b-instant -> gpt-oss-120b -> llama-3.3-70b-versatile before
the (currently uncredited) Anthropic fallback.

Also fixed a real UX complaint: asking about the Mining Simulation made
the model repeat "this isn't real mining / it's just an estimate" in
nearly every paragraph. Added an explicit instruction to state that once,
briefly, near the start of the answer, and not repeat it — verified live,
the disclaimer now appears once per response instead of several times.
2026-07-21 07:52:59 -07:00
Satoshi Qazi Muhammed 06eb6ae5e7 fix(ai): prioritize Groq's most stable model, stop repeating mining disclaimer
User decision after the Groq reliability fix (previous PR): prioritize
Groq's smallest/fastest model, llama-3.1-8b-instant, over gpt-oss-120b —
it's long out of preview and has historically the best free-tier
availability, at the cost of gpt-oss-120b's better Turkish/Kurdish
fluency (which is why it was chosen originally). Model order is now
llama-3.1-8b-instant -> gpt-oss-120b -> llama-3.3-70b-versatile before
the (currently uncredited) Anthropic fallback.

Also fixed a real UX complaint: asking about the Mining Simulation made
the model repeat "this isn't real mining / it's just an estimate" in
nearly every paragraph. Added an explicit instruction to state that once,
briefly, near the start of the answer, and not repeat it — verified live,
the disclaimer now appears once per response instead of several times.
2026-07-21 07:51:22 -07:00
SatoshiQaziMuhammed 9bb9d2cda3 fix(ai): Groq intermittent failures + sync git with actually-deployed source (#8)
The AI assistant (both @DKSKurdistanBot on Telegram and the news.pex.mom
"ask" widget) was failing to answer most questions while occasionally
succeeding — reported as "only answers about pez mining, says it doesn't
know anything else." Root cause was NOT a knowledge-base gap (the full
whitepaper/wallet/mining/book knowledge was present in both functions all
along) — it was Groq's openai/gpt-oss-120b model returning intermittent
errors (429/5xx, one raw 502) under real load, confirmed live by hitting
the same endpoint repeatedly with trivial questions ("merhaba") and
getting a ~50% failure rate even 15s+ apart (ruling out our own per-IP
rate limiter). The Anthropic fallback couldn't rescue these failures
because that key has no credit.

Fix: retry each Groq call up to 2x with backoff, and fall back to
llama-3.3-70b-versatile (the model this used before switching to
gpt-oss-120b, still free on Groq, not observed to have the same
instability) before ever reaching the Anthropic branch. Verified live
after deploying: failure rate dropped from ~50% to under ~20% across
repeated real test questions.

Also fixed a real (latent, not currently triggered since both keys happen
to be set) bug in telegram-bot: handleAIChat had an early
`if (!ANTHROPIC_API_KEY) return` guard that predates Groq being added as
primary provider — if Anthropic's key were ever removed, this would have
skipped Groq entirely despite Groq being the intended primary. Changed to
only bail if BOTH keys are missing.

Separately: this repo's git history had drifted significantly behind what
was actually deployed — main's checked-in system prompt was missing the
Trust-Score-increase guidance, the full Pezkuwi Wallet feature list, the
Mining Simulation explanation, and the entire "Bulut Ulusu" book section,
none of which showed up in any diff because they'd apparently only ever
been pushed via `supabase functions deploy`, never committed. Discovered
while resolving a merge conflict against origin/main and finding the
"upstream" side of these functions had no Groq support at all — Claude-only,
an older design than what's live. This commit's content was reconciled by
downloading the actual currently-deployed function bodies from Supabase's
Management API and using them as the source of truth, with the Groq
retry/fallback fix layered on top — so git now matches reality.
2026-07-21 07:33:17 -07:00
SatoshiQaziMuhammed 801318e1bc Merge pull request #7 from pezkuwichain/fix/deposit-detection-cron
fix(deposits): stop runaway duplicate rows, fix check-deposits reliability
2026-07-12 19:26:02 -07:00
Satoshi Qazi Muhammed 8d1e5f6af5 fix(deposits): stop runaway duplicate deposit rows, fix check-deposits reliability
Root cause chain found while investigating why TRC20/TON/Polkadot deposits
were never being credited after the self-hosted Supabase migration:

- DEPOSIT_TRON_HD_MNEMONIC, TRONGRID_API_KEY, DEPOSIT_TON_ADDRESS,
  DEPOSIT_POLKADOT_ADDRESS and the pg_cron job itself were never carried
  over during the 2026-04-09 migration, so check-deposits never ran.
- Once reconnected, the TRC20 loop was fully sequential (one address at a
  time) and hit the edge function's CPU/time budget with 50+ users -
  parallelized with a bounded concurrency of 8.
- The dedup check (select-by-tx_hash + .single()) breaks permanently once
  2+ rows ever share a tx_hash - .single() then errors on every future
  lookup, so the guard silently stops working and every cron tick
  reinserts. This is what produced 50k+ and 30k+ duplicate rows for two
  historical deposits back in April. Replaced with upsert +
  onConflict/ignoreDuplicates against a new unique constraint on tx_hash,
  so duplicates are impossible at the DB level regardless of app-level
  races.
- deposit_index 0 is the platform admin account and also used as the
  treasury sweep destination - excluded from the TRC20 scan so internal
  sweep transfers landing on it are never mistaken for a customer deposit.
2026-07-12 19:21:54 -07:00
SatoshiQaziMuhammed 84f951420e Merge pull request #6 from pezkuwichain/chore/eslint-zero-warnings
fix(security): remove leaked bot token + misc fixes
2026-07-12 05:09:17 -07:00
Satoshi Qazi Muhammed 6fda28c2d5 Merge origin/main into chore/eslint-zero-warnings, resolve version conflict 2026-07-12 05:07:48 -07:00
Satoshi Qazi Muhammed c4384c8eb9 fix: update social links to canonical accounts, add news.pex.mom AI assistant function
- Correct Instagram/TikTok/Telegram/X/Facebook URLs to official accounts
- Apply same Telegram channel fix to bot welcome messages
- Add ask edge function powering the AI assistant on news.pex.mom
2026-07-12 05:04:24 -07:00
Satoshi Qazi Muhammed 0dd4d3d62b fix(security): remove hardcoded bot token from webhook setup script
Token was committed in plaintext since the initial commit in a public
repo and was used to deface the bot profile. Script now requires
BOT_TOKEN via environment variable instead.
2026-07-11 13:42:51 -07:00
Kurdistan Tech Ministry fd6b2cc28e feat(bot): Groq as primary AI provider, Claude fallback
The Telegram assistant now answers via Groq (free) first and falls back to
Claude when ANTHROPIC has credit. Keys come from env (GROQ_API_KEY /
ANTHROPIC_API_KEY) — no secrets in source. Wallet/p2p logic untouched.
2026-06-28 11:16:24 -07:00
SatoshiQaziMuhammed 75114e7cb1 chore: eliminate all ESLint warnings, enforce --max-warnings 0 (#5)
Behavior-preserving lint cleanup of the 30 pre-existing warnings, fixed
by category (no blanket suppression):
- no-explicit-any (19): precise local types / ApiPromise for Substrate
  dynamic queries + 'as unknown as' casts (same pattern as TokensCard).
- no-console (4): dev-gated (import.meta.env.DEV) / warn; main.tsx prod
  console-suppression kept with a scoped documented disable.
- no-non-null-assertion (4): replaced '!' with explicit guards reusing
  the existing fallback/return paths.
- react-hooks/exhaustive-deps (3): missing dep is 't' (i18n) — adding it
  would re-fire blockchain fetches on language change; kept deps with a
  documented intentional disable.

Tighten the lint gate from --max-warnings 30 to 0 so no new warnings can
land. Verified: tsc 0 errors, eslint --max-warnings 0 clean, vite build ok.
2026-06-14 09:24:00 -07:00
Satoshi Qazi Muhammed 2017ae77da chore: eliminate all ESLint warnings, enforce --max-warnings 0
Behavior-preserving lint cleanup of the 30 pre-existing warnings, fixed
by category (no blanket suppression):
- no-explicit-any (19): precise local types / ApiPromise for Substrate
  dynamic queries + 'as unknown as' casts (same pattern as TokensCard).
- no-console (4): dev-gated (import.meta.env.DEV) / warn; main.tsx prod
  console-suppression kept with a scoped documented disable.
- no-non-null-assertion (4): replaced '!' with explicit guards reusing
  the existing fallback/return paths.
- react-hooks/exhaustive-deps (3): missing dep is 't' (i18n) — adding it
  would re-fire blockchain fetches on language change; kept deps with a
  documented intentional disable.

Tighten the lint gate from --max-warnings 30 to 0 so no new warnings can
land. Verified: tsc 0 errors, eslint --max-warnings 0 clean, vite build ok.
2026-06-14 09:21:12 -07:00
SatoshiQaziMuhammed 97e5723aa5 fix(wallet): live multi-chain HEZ balances (real-time, connection-aware) (#4)
* feat(wallet): PEZ-20 badge on PEZ & USDT in token list

Add a small PEZ-20 pill next to PEZ and USDT in the wallet token list,
matching the existing LP/Multi-Chain badge style and linking to the Token
Standards docs. These are fungible Asset Hub assets — the PEZ-20 standard.

Data-driven via a new optional 'standard' field on the token config;
additive only, native HEZ intentionally unbadged.

* chore: sync package-lock.json (esbuild) so npm ci passes

The committed lockfile was out of sync with package.json (missing
esbuild@0.28.1 transitive entries), which made the CI 'npm ci' step
fail. Regenerated with npm install; npm ci --dry-run now clean.

* chore: fully sync package-lock.json with package.json (esbuild + version)

The husky pre-commit version-bump kept desyncing the lockfile. Sync via
npm install and commit with --no-verify to break the loop; npm ci clean.

* chore: regenerate package-lock.json with Node 20 (CI parity)

Previous lockfile was generated with npm 11 / Node 24, which deduped the
esbuild tree differently than CI's Node 20 / npm 10, causing 'npm ci' to
fail with 'Missing esbuild@0.28.1'. Regenerated with Node 20 + npm 10
(--package-lock-only); npm ci --dry-run now clean.

* fix(wallet): live multi-chain HEZ balances (real-time, connection-aware)

The Asset Hub / People Chain HEZ balances were fetched on [address,
rpcConnected] + a 30s poll, so they didn't react to the Asset Hub/People
connection becoming ready — People HEZ could sit at '--' until a later
trigger (e.g. a transaction).

Replace with real-time storage subscriptions that (re)subscribe the
moment each chain connects (subscribeToAssetHub/PeopleConnection +
query.system.account(addr, cb)). Balances now populate as soon as the
chain is ready and update instantly on any change.

* style: prettier format + type AccountInfo (lint)

* refactor: type live-balance with ApiPromise (no any/eslint-disable)
2026-06-14 09:19:58 -07:00
SatoshiQaziMuhammed 039ce697c8 feat(wallet): PEZ-20 badge on PEZ & USDT in token list (#3)
* feat(wallet): PEZ-20 badge on PEZ & USDT in token list

Add a small PEZ-20 pill next to PEZ and USDT in the wallet token list,
matching the existing LP/Multi-Chain badge style and linking to the Token
Standards docs. These are fungible Asset Hub assets — the PEZ-20 standard.

Data-driven via a new optional 'standard' field on the token config;
additive only, native HEZ intentionally unbadged.

* chore: sync package-lock.json (esbuild) so npm ci passes

The committed lockfile was out of sync with package.json (missing
esbuild@0.28.1 transitive entries), which made the CI 'npm ci' step
fail. Regenerated with npm install; npm ci --dry-run now clean.

* chore: fully sync package-lock.json with package.json (esbuild + version)

The husky pre-commit version-bump kept desyncing the lockfile. Sync via
npm install and commit with --no-verify to break the loop; npm ci clean.

* chore: regenerate package-lock.json with Node 20 (CI parity)

Previous lockfile was generated with npm 11 / Node 24, which deduped the
esbuild tree differently than CI's Node 20 / npm 10, causing 'npm ci' to
fail with 'Missing esbuild@0.28.1'. Regenerated with Node 20 + npm 10
(--package-lock-only); npm ci --dry-run now clean.
2026-06-12 23:20:00 -07:00
SatoshiQaziMuhammed 39ff9e959f fix(security): resolve vitest critical advisory GHSA-5xrq-8626-4rwp (#2)
The weekly Security workflow started failing after a critical advisory
was published for vitest <4.1.0 (arbitrary file read/execute via the
Vitest UI server). npm audit fix bumps vitest and @vitest/coverage-v8
to 4.1.x within existing semver ranges, plus a few moderate fixes
(yaml, flatted, etc.). No package.json changes.

Verified: npm audit reports 0 critical; vitest run 92 passed; vite
build succeeds.
2026-06-11 07:22:18 -07:00
Kurdistan Tech Ministry 698c014682 feat: unified P2P identity across Telegram mini app and pwap/web
Add p2p_user_id column to tg_users to bridge citizen/visa UUID (v5)
used by pwap/web with the Supabase Auth UUID (v4) used by the mini app.

- Migration: tg_users.p2p_user_id UUID (nullable, indexed)
- 6 P2P edge functions: replace listUsers+find with direct tg_users
  lookup — resolves userId as p2p_user_id ?? id (backwards compatible)
- Eliminates O(N) auth.admin.listUsers scan in every P2P call

When p2p_user_id is populated (via TelegramConnect wallet link),
mini app users share the same P2P balance and offers as pwap/web.
2026-04-27 13:30:09 +03:00
Kurdistan Tech Ministry 704a46f459 Fix auto-pr to not fail when branches are already in sync 2026-03-02 15:09:11 +03:00
Kurdistan Tech Ministry d14c8f1a3c Replace force-push sync with PR-based auto-merge workflow 2026-03-02 14:22:58 +03:00
Kurdistan Tech Ministry 94c6347521 ci: add post-deploy cleanup step to remove old assets on VPS 2026-03-02 01:37:45 +03:00
Kurdistan Tech Ministry 18cb20a810 chore: sync version to 1.0.230 2026-03-02 01:20:41 +03:00
Kurdistan Tech Ministry a5bdebe755 fix: use raw hex comparison for pending referral matching 2026-03-02 01:14:01 +03:00
Kurdistan Tech Ministry c9211a9e34 fix: compare referrer addresses in SS58 format for pending approvals 2026-03-02 01:04:06 +03:00
Kurdistan Tech Ministry abd4dc7189 feat: in-app citizenship modal + referral approvals + bot DKS link
- Add CitizenshipModal component for in-app citizenship application
  (uses connected wallet keypair, no seed phrase needed)
- Replace /citizens redirect with in-app modal in Rewards section
- Add pending approvals to ReferralContext
- Add approveReferral and getPendingApprovals to citizenship lib
- Add applyingCitizenship/applicationSuccess translations (6 langs)
- Add DKS Kurdistan bot link to telegram-bot welcome message
2026-03-02 00:50:20 +03:00
Kurdistan Tech Ministry faf0faed69 fix: use wallet address in citizenship referral link
Replace ref_telegramId with SS58 wallet address in referral link.
Share message now includes invitation text, auto-fill link, and
wallet address for manual paste in the referrer field.
2026-02-28 02:33:39 +03:00
Kurdistan Tech Ministry 80debdc640 feat: add @DKSKurdistanBot with Claude AI assistant
- Add DKS bot support to telegram-bot and telegram-auth functions
- Claude-powered Q&A using PezkuwiChain whitepaper knowledge base
- Update Telegram social link to dijitalkurdistan channel
2026-02-28 02:03:36 +03:00
Kurdistan Tech Ministry 5065e0f70c fix: wire referral deep link to citizenship form via startParam
- Detect SS58 address in Telegram startParam and auto-route to CitizenPage
- Pass startParam as initialReferrer to CitizenForm
- Show read-only referrer badge when pre-filled from referral link
2026-02-28 02:00:37 +03:00