5 Commits

Author SHA1 Message Date
pezkuwichain 0102315fab feat: switch AI to gpt-oss-120b for fluent Turkish/Kurdish, enforce plain text
llama-3.3-70b's Turkish read like stilted translation ('gostermektedir'
chains). openai/gpt-oss-120b on the same Groq key produces natural,
conversational Turkish (A/B tested on the same prompt). Also: explicit
natural-language + no-markdown style rules in both system prompts, and a
deterministic sanitizer stripping **/# remnants before sending - models
occasionally emit markdown regardless, and Telegram renders it raw.
2026-07-19 09:57:33 -07:00
pezkuwichain 8e49cbc0db fix: correct Mining Simulation framing - counter previews the REAL era airdrop
The previous knowledge text described the diamond counter as purely cosmetic
with no real counterpart. Corrected per Serok: the counter is an ESTIMATE of
the real PEZ airdrop - the actual distribution is calculated transparently
on-chain at era end (pezpallet-pez-rewards, trust-score-weighted) and paid
out to wallets automatically, at which point the counter resets. Diamonds
cannot be manually converted; the purpose is showing how raising trust score
(referrals, staking, tiki roles, education) raises your airdrop.
2026-07-19 09:50:27 -07:00
pezkuwichain 9c7c1a5be9 feat: teach the AI assistant about Pezkuwi Wallet, Mining Simulation and the Bulut Ulusu book
- Add Pezkuwi Wallet knowledge (live on Google Play v1.1.2): native BTC/SOL/TRX,
  USDT bridge (wUSDT<->USDT only), multisig, gift, trust score card
- Add PEZ Mining Simulation section: honest explanation that it is a client-side
  gamified preview (not real mining), session/era mechanics, zero-trust-score gate
- Add trust score guidance: why a score is 0 (needs >=1.1 HEZ on People Chain and
  >=1 HEZ staked) and how to raise it (stake more/longer, referrals, education, roles)
- Add chapter-by-chapter digest of the Bulut Ulusu (Cloud Nation) book
- Update channel links to https://t.me/+DUWJ8wtt5qI4Njgy everywhere
- Replace 'Play Store (Coming Soon)' with the live Google Play link
- ask: add Groq-primary/Claude-fallback (same pattern as telegram-bot) - the
  Anthropic key is out of credit, so the news-site assistant was returning
  'could not answer' on every question
2026-07-19 01:24:10 -07:00
pezkuwichain 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
6 changed files with 292 additions and 123 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pezkuwi-telegram-miniapp",
"version": "1.0.239",
"version": "1.0.243",
"type": "module",
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
"author": "Pezkuwichain Team",
+3 -3
View File
@@ -1,5 +1,5 @@
{
"version": "1.0.239",
"buildTime": "2026-07-12T12:07:48.783Z",
"buildNumber": 1783858068783
"version": "1.0.243",
"buildTime": "2026-07-19T16:57:33.951Z",
"buildNumber": 1784480253951
}
+107 -18
View File
@@ -1,6 +1,8 @@
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
const ANTHROPIC_API_KEY = Deno.env.get('ANTHROPIC_API_KEY') || '';
// AI provider: Groq (free) is primary; Claude is fallback when it has credit.
const GROQ_API_KEY = Deno.env.get('GROQ_API_KEY') || '';
const SUPABASE_URL = Deno.env.get('SUPABASE_URL') || '';
const SERVICE_KEY = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') || '';
@@ -8,6 +10,8 @@ const SYSTEM = `You are the official PezkuwiChain AI Assistant on the news site
RULES:
- Answer in the SAME LANGUAGE the user writes in. If they write in Kurdish (Kurmancî), answer in Kurdish. If Turkish, answer in Turkish. If English, answer in English. If Arabic, answer in Arabic. If Persian, answer in Persian.
- Write NATURAL, fluent, conversational language - especially in Turkish and Kurdish, avoid stilted formal suffixes ("bulunmaktadır", "göstermektedir") and translation-flavored phrasing; short clear sentences, like a knowledgeable friend explaining.
- STRICTLY plain text: never use markdown (**, ##, bullet asterisks). Simple dashes for lists are fine.
- Be concise — website answers should be short, clear and helpful.
- Use plain text, no markdown headers. You can use bold with *text* sparingly.
- If you don't know something, say so honestly.
@@ -44,6 +48,14 @@ Role Score: Soulbound NFT roles via pezpallet-tiki. 49 variants: Applicant (Daxw
Validator Pool: 10 Stake Validators + 6 Parliamentary Validators + 5 Merit Validators = 21 total.
TRUST SCORE — HOW TO INCREASE IT (VERY IMPORTANT — users frequently ask this):
If a user asks "why is my trust score 0?": To have a trust score at all, you must have at least 1.1 HEZ on People Chain and have STAKED at least 1 HEZ. Staking is the multiplier of the whole formula — with zero stake, referrals/education/roles cannot produce any score (S=0 means trust_score=0).
If a user asks "how do I increase my trust score?": The more you do of these, the higher your score:
1. Stake more HEZ, and keep it staked longer (staking amount tiers: 1-100 HEZ: 20pts, 101-250: 30pts, 251-750: 40pts, 751+: 50pts; duration multiplier grows from 1.0x up to 2.0x at 12+ months).
2. Refer more people (each verified referral adds points, up to 500 max at 101+ referrals).
3. Educate yourself — complete on-chain courses and certificate programs via the Perwerde education network (education score).
4. Become a citizen (Welati soulbound NFT: +10pts) and earn community roles (teacher, moderator, etc. add larger bonuses).
DUAL-TOKEN ECONOMY:
HEZ Token (Security): 200M genesis, 8% annual inflation, 85% stakers / 15% treasury. 12 decimals (TYR base unit).
Genesis: 100M (50%) presale pool, 40M (20%) Kurdistan Treasury, 40M (20%) airdrop reserve, 20M (10%) founder.
@@ -117,12 +129,52 @@ Relay Chain: wss://rpc.pezkuwichain.io
Asset Hub: wss://asset-hub-rpc.pezkuwichain.io
People Chain: wss://people-rpc.pezkuwichain.io
PEZKUWI WALLET — OFFICIAL ANDROID APP (live on Google Play since July 2026, v1.1.2):
Download: https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet
The official mobile wallet of PezkuwiChain / Digital Kurdistan State. Features:
- Manage HEZ and PEZ tokens, staking, on-chain governance voting
- Full Polkadot ecosystem support (DOT, Asset Hub tokens) inherited from its Nova Wallet foundation
- Native multi-chain support: Bitcoin (BTC), Solana (SOL), Tron (TRX + TRC-20 USDT) — send and receive directly on their own chains, real on-chain transactions, keys derived from the same seed phrase
- USDT Bridge: converts between wUSDT on Pezkuwi Asset Hub and USDT on Polkadot Asset Hub, in both directions. This is the ONLY bridge pair — the app does not bridge SOL, TRX or ETH.
- Multisig accounts (shared-control wallets with threshold approvals), including approving operations via deep links
- Trust Score dashboard card showing your on-chain trust score, roles, and citizen count
- Gift feature: send tokens as a QR/link gift that the recipient claims in-app
- Cloud backup, multiple wallets, hardware wallet (Polkadot Vault / Ledger) support
PEZ MINING SIMULATION (in the Pezkuwi Wallet app — users frequently ask about this):
Inside the Trust Score card there is a small "Mining Simulation" square with a diamond counter, labeled "PEZ Airdrop".
- What it is: a simulation that PREVIEWS your estimated PEZ airdrop. It shows, based on your Trust Score, approximately how much PEZ you could receive from the era's distribution. It is not literal mining — the diamond count is an ESTIMATE.
- The diamonds cannot be manually converted by the user. The REAL PEZ airdrop is calculated transparently on-chain at the end of each era (~30 days) and distributed AUTOMATICALLY to wallets (trust-score-weighted share of the era pool, via pezpallet-pez-rewards). When the era ends and the real airdrop is paid out, the diamond counter automatically resets to zero. So the counter shows the PEZ airdrop you are estimated to earn.
- Purpose: to let users SEE how raising their Trust Score — through referrals, staking HEZ, earning tiki roles, and completing education — increases their PEZ airdrop.
- How the counter works: tap the square to start a 24-hour mining session. While a session is active, diamonds accrue every minute, proportional to your Trust Score: rate = (92.5M PEZ era pool / 43,200 minutes) × (your trust score / 500,000 reference network total). Example: trust score 340 ≈ 1.46 diamonds/minute. When the 24h session ends, accrual stops — tap the square again to start a new session (your accumulated total is kept within the era).
- If your Trust Score is 0, the counter cannot start — the app shows a warning that your trust score must be greater than 0. To fix this: become a citizen, stake HEZ (required for any trust score), refer others, complete education courses.
- Colors: red square = inactive (tap to start), gold = actively mining.
- The small Telegram icon next to it opens the official channel: https://t.me/+DUWJ8wtt5qI4Njgy
"BULUT ULUSU" (CLOUD NATION) — THE BOOK BEHIND PEZKUWICHAIN (chapter-by-chapter knowledge):
PezkuwiChain's philosophical foundation is the book "Bulut Ulusu" (Cloud Nation), written by the project's architect (a software developer AND sociologist — the "two desks" of the opening chapter). Available in Turkish, English and Kurdish. Core theses:
- Code is law in a literal sense: every cryptographic design choice is a political claim about who holds authority, how censorship is escaped, and how trust is established without a central institution.
- "Westphalia's collapse": the 20th-century nation-state model (absolute borders, assimilation) is cracking. Path Dependency explains why humanity stays on inefficient old roads; the Network State ("Fikir Birliği Ulusu" — consensus nation) is the emerging alternative: a nation built on shared ideas and cryptographic consensus rather than territory.
- Plurality and the mathematics of justice: stories like Berivan (an unbanked Kurdish refugee rejected by traditional finance) show the cost of statelessness; "Hyper-Hawala" — trust networks scaled beyond the Dunbar number by cryptography.
- The sociology of statelessness: Kurds (40+ million, no state, Agamben's "Homo Sacer") are candidates to be this era's "Vanguard Nation" (Öncü Ulus) — historical victimhood becomes "zero friction" flexibility: no legacy state apparatus to defend, freedom to build a new civilization model from scratch.
- Three chains, one nation: the multi-chain architecture (Relay + Asset Hub + People Chain) is philosophy made executable — praxis running in compilers and distributed nodes instead of squares and manifestos.
- TNPoS and "Bext û Soz" (a Kurdish concept: honor and one's word): moving from the dictatorship of money (pure Proof-of-Stake plutocracy) to the transparency of trust — social reputation, education and community roles encoded into consensus.
- Dual economy: central banks as an "apparatus of capture" (Deleuze & Guattari) facing structural, mathematical inefficiency; HEZ as network fuel and PEZ as the community's value/governance asset.
- Self-Sovereign Identity (SSI): the modern state turned identity into a file number — a vast alienation. PezkuwiChain returns identity ownership to the person (encrypted hashes on-chain, the person holds the keys).
- Education's frozen evolution: schools barely changed in 150 years while everything else transformed; the Perwerde network puts verified learning on-chain and rewards it with trust score.
- A universal Layer 1: not only for Kurds — an infrastructure for 100M+ stateless people worldwide; the excluded are "read-only" in today's systems, PezkuwiChain gives them write access.
- Capacity thresholds: growth is modeled as concrete capacity thresholds (illustrated by Zana, a stateless Ezidi youth), explicitly avoiding prophecy.
- The old world's resistance: regulatory, sociological and diplomatic thresholds are expected; the project's stance is COMPLEMENTARY PARTICIPATION — it does not challenge regional states and does not seek to change any border. A digital nation, not a territorial claim.
- Conclusion: the statelessness experience is no longer a curse but one of humanity's paths to freedom; the book is "not a completed victory but the record of an ongoing construction."
When asked about the book, its ideas, or "why does PezkuwiChain exist": answer from these theses. The book's preface is deliberately left half-finished — it belongs to the community that will write the future.
LINKS:
Website: pezkuwichain.io
GitHub: github.com/pezkuwichain/pezkuwi-sdk
Discord: discord.gg/Y3VyEC6h8W
Telegram Channel: t.me/kurdishmedya
Telegram Channel: https://t.me/+DUWJ8wtt5qI4Njgy
Telegram App: @DKSKurdistanBot
Android App (Pezkuwi Wallet, live on Google Play): https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet
PROBLEM SOLVED: Over 100 million stateless people. Kurdish population 40+ million across 4 countries — financial exclusion, identity fragmentation, governance vacuum. PezkuwiChain provides digital nation-state infrastructure.
@@ -198,23 +250,60 @@ serve(async (req) => {
.slice(-6)
: [];
const messages = [...hist, { role: 'user', content: q }];
const r = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 900,
system: SYSTEM,
messages,
}),
});
if (!r.ok) return J({ answer: 'Sorry, I could not answer right now. Please try again.' }, 200);
const d = await r.json();
const answer = (d.content && d.content[0] && d.content[0].text) || '…';
// Primary provider: Groq (free). Fallback: Claude when it has credit.
let answer: string | null = null;
if (GROQ_API_KEY) {
try {
const gr = await fetch('https://api.groq.com/openai/v1/chat/completions', {
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'openai/gpt-oss-120b',
temperature: 0.3,
max_tokens: 900,
messages: [{ role: 'system', content: SYSTEM }, ...messages],
}),
});
if (gr.ok) {
const gd = await gr.json();
answer = gd.choices?.[0]?.message?.content || null;
} else {
console.error('[AI] Groq error:', gr.status, await gr.text());
}
} catch (e) {
console.error('[AI] Groq exception:', e);
}
}
if (!answer && ANTHROPIC_API_KEY) {
const r = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-sonnet-4-20250514',
max_tokens: 900,
system: SYSTEM,
messages,
}),
});
if (r.ok) {
const d = await r.json();
answer = (d.content && d.content[0] && d.content[0].text) || null;
} else {
console.error('[AI] Claude API error:', r.status, await r.text());
}
}
if (!answer)
return J({ answer: 'Sorry, I could not answer right now. Please try again.' }, 200);
// Models occasionally emit markdown despite the plain-text rule.
answer = answer.replace(/\*\*/g, '').replace(/^#+\s*/gm, '');
return J({ answer }, 200);
} catch (_e) {
return J({ answer: 'Something went wrong. Please try again.' }, 200);
+104 -93
View File
@@ -118,17 +118,6 @@ async function checkTonDeposits(
if (amount < MIN_DEPOSIT) continue;
// Check if already processed
const { data: existing } = await supabase
.from('tg_deposits')
.select('id')
.eq('tx_hash', txHash)
.single();
if (existing) continue;
result.found++;
// Find user by memo code
const { data: depositCode } = await supabase
.from('tg_user_deposit_codes')
@@ -144,17 +133,29 @@ async function checkTonDeposits(
// Calculate net amount after platform fee
const netAmount = Math.max(0, amount - TON_FEE);
// Create deposit record with net amount
const { error } = await supabase.from('tg_deposits').insert({
user_id: depositCode.user_id,
network: 'ton',
amount: netAmount,
tx_hash: txHash,
memo: comment,
status: 'confirming',
});
// Create deposit record with net amount. tx_hash has a unique DB
// constraint - on conflict (already processed on a prior run) this
// is a no-op, avoiding the check-then-insert race that used to
// produce runaway duplicate rows.
const { error, data: inserted } = await supabase
.from('tg_deposits')
.upsert(
{
user_id: depositCode.user_id,
network: 'ton',
amount: netAmount,
tx_hash: txHash,
memo: comment,
status: 'confirming',
},
{ onConflict: 'tx_hash', ignoreDuplicates: true }
)
.select('id');
if (!error) result.processed++;
if (!error && inserted && inserted.length > 0) {
result.found++;
result.processed++;
}
}
}
} catch (err) {
@@ -201,31 +202,29 @@ async function checkPolkadotDeposits(
if (amount < MIN_DEPOSIT) continue;
// Check if already processed
const { data: existing } = await supabase
.from('tg_deposits')
.select('id')
.eq('tx_hash', txHash)
.single();
if (existing) continue;
result.found++;
// Calculate net amount after platform fee
const netAmount = Math.max(0, amount - POLKADOT_FEE);
// For Polkadot, memo might be in extrinsic data
// Try to find user by checking system.remark in same block
// For now, create as pending without user
const { error } = await supabase.from('tg_deposits').insert({
network: 'polkadot',
amount: netAmount,
tx_hash: txHash,
status: 'confirming',
});
const { error, data: inserted } = await supabase
.from('tg_deposits')
.upsert(
{
network: 'polkadot',
amount: netAmount,
tx_hash: txHash,
status: 'confirming',
},
{ onConflict: 'tx_hash', ignoreDuplicates: true }
)
.select('id');
if (!error) result.processed++;
if (!error && inserted && inserted.length > 0) {
result.found++;
result.processed++;
}
}
} catch (err) {
result.errors.push(`Polkadot error: ${err}`);
@@ -242,70 +241,82 @@ async function checkTrc20Deposits(
const result = { found: 0, processed: 0, errors: [] as string[] };
try {
// Get all users with deposit_index
// Get all users with deposit_index. deposit_index 0 belongs to the
// platform admin account and doubles as the treasury sweep destination -
// excluded here so internal sweep transfers landing on it are never
// mistaken for a customer deposit.
const { data: users } = await supabase
.from('tg_users')
.select('id, deposit_index')
.not('deposit_index', 'is', null)
.neq('deposit_index', 0)
.order('deposit_index', { ascending: true });
if (!users || users.length === 0) return result;
// Check each user's derived address
for (const user of users) {
try {
const address = deriveTronAddress(hdMnemonic, user.deposit_index);
// Check each user's derived address, with bounded concurrency so we
// don't exceed the edge function's CPU/time budget on large user counts.
const CONCURRENCY = 8;
for (let i = 0; i < users.length; i += CONCURRENCY) {
const batch = users.slice(i, i + CONCURRENCY);
await Promise.all(
batch.map(async (user) => {
try {
const address = deriveTronAddress(hdMnemonic, user.deposit_index);
// Get TRC20 transfers to this address
const response = await fetch(
`${TRON_API}/v1/accounts/${address}/transactions/trc20?limit=20&contract_address=${TRON_USDT_CONTRACT}`,
{
headers: { 'TRON-PRO-API-KEY': Deno.env.get('TRONGRID_API_KEY') || '' },
// Get TRC20 transfers to this address
const response = await fetch(
`${TRON_API}/v1/accounts/${address}/transactions/trc20?limit=20&contract_address=${TRON_USDT_CONTRACT}`,
{
headers: { 'TRON-PRO-API-KEY': Deno.env.get('TRONGRID_API_KEY') || '' },
}
);
if (!response.ok) return;
const data = await response.json();
const transfers = data.data || [];
for (const tx of transfers) {
// Only incoming transfers
if (tx.to?.toLowerCase() !== address.toLowerCase()) continue;
const txHash = tx.transaction_id;
const amount = parseInt(tx.value) / 1e6; // USDT has 6 decimals
if (amount < MIN_DEPOSIT) continue;
// Create deposit record (with fee deduction note). tx_hash
// has a unique DB constraint - on conflict this is a no-op,
// avoiding the check-then-insert race that used to produce
// runaway duplicate rows.
const netAmount = Math.max(0, amount - TRC20_FEE);
const { error, data: inserted } = await supabase
.from('tg_deposits')
.upsert(
{
user_id: user.id,
network: 'trc20',
amount: netAmount, // Store net amount after fee
tx_hash: txHash,
status: 'confirming',
},
{ onConflict: 'tx_hash', ignoreDuplicates: true }
)
.select('id');
if (!error && inserted && inserted.length > 0) {
result.found++;
result.processed++;
}
}
} catch (err) {
// Skip individual user errors
return;
}
);
if (!response.ok) continue;
const data = await response.json();
const transfers = data.data || [];
for (const tx of transfers) {
// Only incoming transfers
if (tx.to?.toLowerCase() !== address.toLowerCase()) continue;
const txHash = tx.transaction_id;
const amount = parseInt(tx.value) / 1e6; // USDT has 6 decimals
if (amount < MIN_DEPOSIT) continue;
// Check if already processed
const { data: existing } = await supabase
.from('tg_deposits')
.select('id')
.eq('tx_hash', txHash)
.single();
if (existing) continue;
result.found++;
// Create deposit record (with fee deduction note)
const netAmount = Math.max(0, amount - TRC20_FEE);
const { error } = await supabase.from('tg_deposits').insert({
user_id: user.id,
network: 'trc20',
amount: netAmount, // Store net amount after fee
tx_hash: txHash,
status: 'confirming',
});
if (!error) result.processed++;
}
} catch (err) {
// Skip individual user errors
continue;
}
})
);
}
} catch (err) {
result.errors.push(`TRC20 error: ${err}`);
+69 -8
View File
@@ -90,6 +90,8 @@ const CLAUDE_SYSTEM_PROMPT = `You are the official PezkuwiChain AI Assistant on
RULES:
- Answer in the SAME LANGUAGE the user writes in. If they write in Kurdish (Kurmancî), answer in Kurdish. If Turkish, answer in Turkish. If English, answer in English. If Arabic, answer in Arabic. If Persian, answer in Persian.
- Write NATURAL, fluent, conversational language - especially in Turkish and Kurdish, avoid stilted formal suffixes ("bulunmaktadır", "göstermektedir") and translation-flavored phrasing; short clear sentences, like a knowledgeable friend explaining.
- STRICTLY plain text: never use markdown (**, ##, bullet asterisks). Simple dashes for lists are fine.
- Be concise — Telegram messages should be short and readable.
- Use plain text, no markdown headers. You can use bold with *text* sparingly.
- If you don't know something, say so honestly.
@@ -97,7 +99,7 @@ RULES:
- You represent PezkuwiChain officially — be professional and helpful.
- Do not discuss other blockchain projects comparatively unless asked.
- For technical questions about source code, direct users to: github.com/pezkuwichain/pezkuwi-sdk
- For the wallet app, direct users to: @DKSKurdistanBot on Telegram (they can click "Open PezkuwiChain App" after /start)
- For the wallet app, direct users to: the Pezkuwi Wallet Android app on Google Play (https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet) or the Telegram MiniApp via @DKSKurdistanBot (click "Open PezkuwiChain App" after /start)
- INVESTOR/IDEA REFERRAL: If a user expresses genuine interest in investing in PezkuwiChain, partnering, contributing financially, or proposes a serious idea for the development of DijitalKurdistan, direct them to contact @Pezkuw on Telegram. Only do this when the user's intent is clearly serious — not for casual questions about tokenomics or "how to buy". Example triggers: "I want to invest", "I have funding", "I represent a fund/company", "I have a business proposal", "I want to contribute to the project's development".
PEZKUWICHAIN WHITEPAPER v5.0 — KNOWLEDGE BASE:
@@ -126,6 +128,14 @@ Role Score: Soulbound NFT roles via pezpallet-tiki. 49 variants: Applicant (Daxw
Validator Pool: 10 Stake Validators + 6 Parliamentary Validators + 5 Merit Validators = 21 total.
TRUST SCORE — HOW TO INCREASE IT (VERY IMPORTANT — users frequently ask this):
If a user asks "why is my trust score 0?": To have a trust score at all, you must have at least 1.1 HEZ on People Chain and have STAKED at least 1 HEZ. Staking is the multiplier of the whole formula — with zero stake, referrals/education/roles cannot produce any score (S=0 means trust_score=0).
If a user asks "how do I increase my trust score?": The more you do of these, the higher your score:
1. Stake more HEZ, and keep it staked longer (staking amount tiers: 1-100 HEZ: 20pts, 101-250: 30pts, 251-750: 40pts, 751+: 50pts; duration multiplier grows from 1.0x up to 2.0x at 12+ months).
2. Refer more people (each verified referral adds points, up to 500 max at 101+ referrals).
3. Educate yourself — complete on-chain courses and certificate programs via the Perwerde education network (education score).
4. Become a citizen (Welati soulbound NFT: +10pts) and earn community roles (teacher, moderator, etc. add larger bonuses).
DUAL-TOKEN ECONOMY:
HEZ Token (Security): 200M genesis, 8% annual inflation, 85% stakers / 15% treasury. 12 decimals (TYR base unit).
Genesis: 100M (50%) presale pool, 40M (20%) Kurdistan Treasury, 40M (20%) airdrop reserve, 20M (10%) founder.
@@ -199,12 +209,52 @@ Relay Chain: wss://rpc.pezkuwichain.io
Asset Hub: wss://asset-hub-rpc.pezkuwichain.io
People Chain: wss://people-rpc.pezkuwichain.io
PEZKUWI WALLET — OFFICIAL ANDROID APP (live on Google Play since July 2026, v1.1.2):
Download: https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet
The official mobile wallet of PezkuwiChain / Digital Kurdistan State. Features:
- Manage HEZ and PEZ tokens, staking, on-chain governance voting
- Full Polkadot ecosystem support (DOT, Asset Hub tokens) inherited from its Nova Wallet foundation
- Native multi-chain support: Bitcoin (BTC), Solana (SOL), Tron (TRX + TRC-20 USDT) — send and receive directly on their own chains, real on-chain transactions, keys derived from the same seed phrase
- USDT Bridge: converts between wUSDT on Pezkuwi Asset Hub and USDT on Polkadot Asset Hub, in both directions. This is the ONLY bridge pair — the app does not bridge SOL, TRX or ETH.
- Multisig accounts (shared-control wallets with threshold approvals), including approving operations via deep links
- Trust Score dashboard card showing your on-chain trust score, roles, and citizen count
- Gift feature: send tokens as a QR/link gift that the recipient claims in-app
- Cloud backup, multiple wallets, hardware wallet (Polkadot Vault / Ledger) support
PEZ MINING SIMULATION (in the Pezkuwi Wallet app — users frequently ask about this):
Inside the Trust Score card there is a small "Mining Simulation" square with a diamond counter, labeled "PEZ Airdrop".
- What it is: a simulation that PREVIEWS your estimated PEZ airdrop. It shows, based on your Trust Score, approximately how much PEZ you could receive from the era's distribution. It is not literal mining — the diamond count is an ESTIMATE.
- The diamonds cannot be manually converted by the user. The REAL PEZ airdrop is calculated transparently on-chain at the end of each era (~30 days) and distributed AUTOMATICALLY to wallets (trust-score-weighted share of the era pool, via pezpallet-pez-rewards). When the era ends and the real airdrop is paid out, the diamond counter automatically resets to zero. So the counter shows the PEZ airdrop you are estimated to earn.
- Purpose: to let users SEE how raising their Trust Score — through referrals, staking HEZ, earning tiki roles, and completing education — increases their PEZ airdrop.
- How the counter works: tap the square to start a 24-hour mining session. While a session is active, diamonds accrue every minute, proportional to your Trust Score: rate = (92.5M PEZ era pool / 43,200 minutes) × (your trust score / 500,000 reference network total). Example: trust score 340 ≈ 1.46 diamonds/minute. When the 24h session ends, accrual stops — tap the square again to start a new session (your accumulated total is kept within the era).
- If your Trust Score is 0, the counter cannot start — the app shows a warning that your trust score must be greater than 0. To fix this: become a citizen, stake HEZ (required for any trust score), refer others, complete education courses.
- Colors: red square = inactive (tap to start), gold = actively mining.
- The small Telegram icon next to it opens the official channel: https://t.me/+DUWJ8wtt5qI4Njgy
"BULUT ULUSU" (CLOUD NATION) — THE BOOK BEHIND PEZKUWICHAIN (chapter-by-chapter knowledge):
PezkuwiChain's philosophical foundation is the book "Bulut Ulusu" (Cloud Nation), written by the project's architect (a software developer AND sociologist — the "two desks" of the opening chapter). Available in Turkish, English and Kurdish. Core theses:
- Code is law in a literal sense: every cryptographic design choice is a political claim about who holds authority, how censorship is escaped, and how trust is established without a central institution.
- "Westphalia's collapse": the 20th-century nation-state model (absolute borders, assimilation) is cracking. Path Dependency explains why humanity stays on inefficient old roads; the Network State ("Fikir Birliği Ulusu" — consensus nation) is the emerging alternative: a nation built on shared ideas and cryptographic consensus rather than territory.
- Plurality and the mathematics of justice: stories like Berivan (an unbanked Kurdish refugee rejected by traditional finance) show the cost of statelessness; "Hyper-Hawala" — trust networks scaled beyond the Dunbar number by cryptography.
- The sociology of statelessness: Kurds (40+ million, no state, Agamben's "Homo Sacer") are candidates to be this era's "Vanguard Nation" (Öncü Ulus) — historical victimhood becomes "zero friction" flexibility: no legacy state apparatus to defend, freedom to build a new civilization model from scratch.
- Three chains, one nation: the multi-chain architecture (Relay + Asset Hub + People Chain) is philosophy made executable — praxis running in compilers and distributed nodes instead of squares and manifestos.
- TNPoS and "Bext û Soz" (a Kurdish concept: honor and one's word): moving from the dictatorship of money (pure Proof-of-Stake plutocracy) to the transparency of trust — social reputation, education and community roles encoded into consensus.
- Dual economy: central banks as an "apparatus of capture" (Deleuze & Guattari) facing structural, mathematical inefficiency; HEZ as network fuel and PEZ as the community's value/governance asset.
- Self-Sovereign Identity (SSI): the modern state turned identity into a file number — a vast alienation. PezkuwiChain returns identity ownership to the person (encrypted hashes on-chain, the person holds the keys).
- Education's frozen evolution: schools barely changed in 150 years while everything else transformed; the Perwerde network puts verified learning on-chain and rewards it with trust score.
- A universal Layer 1: not only for Kurds — an infrastructure for 100M+ stateless people worldwide; the excluded are "read-only" in today's systems, PezkuwiChain gives them write access.
- Capacity thresholds: growth is modeled as concrete capacity thresholds (illustrated by Zana, a stateless Ezidi youth), explicitly avoiding prophecy.
- The old world's resistance: regulatory, sociological and diplomatic thresholds are expected; the project's stance is COMPLEMENTARY PARTICIPATION — it does not challenge regional states and does not seek to change any border. A digital nation, not a territorial claim.
- Conclusion: the statelessness experience is no longer a curse but one of humanity's paths to freedom; the book is "not a completed victory but the record of an ongoing construction."
When asked about the book, its ideas, or "why does PezkuwiChain exist": answer from these theses. The book's preface is deliberately left half-finished — it belongs to the community that will write the future.
LINKS:
Website: pezkuwichain.io
GitHub: github.com/pezkuwichain/pezkuwi-sdk
Discord: discord.gg/Y3VyEC6h8W
Telegram Channel: t.me/kurdishmedya
Telegram Channel: https://t.me/+DUWJ8wtt5qI4Njgy
Telegram App: @DKSKurdistanBot
Android App: https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet
PROBLEM SOLVED: Over 100 million stateless people. Kurdish population 40+ million across 4 countries — financial exclusion, identity fragmentation, governance vacuum. PezkuwiChain provides digital nation-state infrastructure.
@@ -245,7 +295,7 @@ async function handleAIChat(token: string, chatId: number, userMessage: string,
method: 'POST',
headers: { Authorization: 'Bearer ' + GROQ_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'llama-3.3-70b-versatile',
model: 'openai/gpt-oss-120b',
temperature: 0.3,
max_tokens: 900,
messages: [
@@ -288,6 +338,9 @@ async function handleAIChat(token: string, chatId: number, userMessage: string,
}
}
// Models occasionally emit markdown despite the plain-text rule; Telegram renders it raw.
if (aiReply) aiReply = aiReply.replace(/\*\*/g, '').replace(/^#+\s*/gm, '');
if (!aiReply) {
await sendTelegramRequest(token, 'sendMessage', {
chat_id: chatId,
@@ -382,8 +435,8 @@ async function sendMainWelcome(token: string, chatId: number) {
],
[
{
text: '🤖 Play Store (Coming Soon)',
callback_data: 'playstore_coming_soon',
text: '🤖 Get it on Google Play',
url: 'https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet',
},
],
],
@@ -477,7 +530,7 @@ async function sendDksWelcome(token: string, chatId: number) {
[
{
text: '📢 Join Channel / Kanalê Tev Bibin',
url: 'https://t.me/kurdishmedya',
url: 'https://t.me/+DUWJ8wtt5qI4Njgy',
},
],
],
@@ -559,11 +612,18 @@ async function handleCallbackQuery(
});
await handleCreateWallet(token, chatId);
} else if (data === 'playstore_coming_soon') {
// Legacy button on old messages - the app is live now, send the real link
await sendTelegramRequest(token, 'answerCallbackQuery', {
callback_query_id: callbackQueryId,
text: '🚀 Android app coming soon! Stay tuned.',
text: '🚀 The Android app is live on Google Play!',
show_alert: true,
});
if (chatId) {
await sendTelegramRequest(token, 'sendMessage', {
chat_id: chatId,
text: '📱 Pezkuwi Wallet is live on Google Play:\nhttps://play.google.com/store/apps/details?id=io.pezkuwichain.wallet',
});
}
}
}
@@ -582,7 +642,8 @@ Just type your question in any language and I'll answer!
<b>Links:</b>
🌐 Website: pezkuwichain.io
📢 Channel: t.me/kurdishmedya
📢 Channel: https://t.me/+DUWJ8wtt5qI4Njgy
📱 Android App: https://play.google.com/store/apps/details?id=io.pezkuwichain.wallet
💬 Discord: discord.gg/Y3VyEC6h8W
`;
await sendTelegramRequest(token, 'sendMessage', {
@@ -0,0 +1,8 @@
-- Prevent duplicate deposit records for the same on-chain transaction.
-- Without this constraint, a check-then-insert race in check-deposits
-- (concurrent invocations, or any transient duplicate) permanently breaks
-- the .single() dedup lookup once 2+ rows share a tx_hash, causing every
-- subsequent cron run to re-insert indefinitely. This happened in
-- production: two tx_hashes accumulated 50k+ and 30k+ duplicate rows
-- respectively before being cleaned up.
ALTER TABLE tg_deposits ADD CONSTRAINT tg_deposits_tx_hash_unique UNIQUE (tx_hash);