update: upgrade @pezkuwi/api to 16.5.36, clean up images and assets
- Upgrade @pezkuwi/api 16.5.11 -> 16.5.36 in supabase edge functions - Remove manual SS58-to-hex workaround, use native SS58 addresses - Add kurdistan flag and Dijital Kurdistan images - Add PezkuwiExplorer to web public assets - Remove unused react-logo and telegram_welcome images - Add *.bak to gitignore
@@ -156,3 +156,6 @@ COMMISSION_SYSTEM_SUMMARY - Copy.md:Zone.Identifier
|
||||
# APK files (too large for GitHub)
|
||||
*.apk
|
||||
mobile/credentials.json
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
|
||||
|
Before Width: | Height: | Size: 388 KiB After Width: | Height: | Size: 388 KiB |
|
Before Width: | Height: | Size: 597 KiB After Width: | Height: | Size: 648 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 597 KiB |
@@ -1,35 +1,11 @@
|
||||
// process-withdraw Edge Function
|
||||
// Processes withdrawal requests by sending tokens from hot wallet to user wallet
|
||||
// Uses @pezkuwi/api for blockchain transactions
|
||||
// Uses @pezkuwi/api for Asset Hub blockchain transactions
|
||||
|
||||
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
||||
import { createClient } from 'npm:@supabase/supabase-js@2'
|
||||
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.11'
|
||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.11'
|
||||
|
||||
// Decode SS58 address to raw 32-byte public key hex
|
||||
function ss58ToHex(address: string): string {
|
||||
const CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
let leadingZeros = 0
|
||||
for (const c of address) {
|
||||
if (c !== '1') break
|
||||
leadingZeros++
|
||||
}
|
||||
let num = 0n
|
||||
for (const c of address) {
|
||||
num = num * 58n + BigInt(CHARS.indexOf(c))
|
||||
}
|
||||
const hex = num.toString(16)
|
||||
const paddedHex = hex.length % 2 ? '0' + hex : hex
|
||||
const decoded = new Uint8Array(leadingZeros + paddedHex.length / 2)
|
||||
for (let i = 0; i < leadingZeros; i++) decoded[i] = 0
|
||||
for (let i = 0; i < paddedHex.length / 2; i++) {
|
||||
decoded[leadingZeros + i] = parseInt(paddedHex.slice(i * 2, i * 2 + 2), 16)
|
||||
}
|
||||
// SS58: [1-byte prefix] [32 bytes pubkey] [2 bytes checksum]
|
||||
const pubkey = decoded.slice(1, 33)
|
||||
return '0x' + Array.from(pubkey, (b: number) => b.toString(16).padStart(2, '0')).join('')
|
||||
}
|
||||
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.36'
|
||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.25'
|
||||
|
||||
// Allowed origins for CORS
|
||||
const ALLOWED_ORIGINS = [
|
||||
@@ -119,22 +95,19 @@ async function sendTokens(
|
||||
// Convert amount to chain units
|
||||
const amountBN = BigInt(Math.floor(amount * Math.pow(10, DECIMALS)))
|
||||
|
||||
// Convert all addresses to hex (Deno npm shim breaks SS58 decoding in @pezkuwi/api types)
|
||||
const destHex = ss58ToHex(toAddress)
|
||||
const signerHex = '0x' + Array.from(hotWallet.publicKey, (b: number) => b.toString(16).padStart(2, '0')).join('')
|
||||
console.log(`Sending ${amount} ${token}: ${signerHex} → ${destHex}`)
|
||||
console.log(`Sending ${amount} ${token}: ${hotWallet.address} → ${toAddress}`)
|
||||
|
||||
let tx
|
||||
if (token === 'HEZ') {
|
||||
tx = api.tx.balances.transferKeepAlive({ Id: destHex }, amountBN)
|
||||
tx = api.tx.balances.transferKeepAlive(toAddress, amountBN)
|
||||
} else if (token === 'PEZ') {
|
||||
tx = api.tx.assets.transfer(PEZ_ASSET_ID, { Id: destHex }, amountBN)
|
||||
tx = api.tx.assets.transfer(PEZ_ASSET_ID, toAddress, amountBN)
|
||||
} else {
|
||||
return { success: false, error: 'Invalid token' }
|
||||
}
|
||||
|
||||
// Fetch nonce via hex pubkey to avoid SS58 → AccountId32 decoding issue
|
||||
const accountInfo = await api.query.system.account(signerHex)
|
||||
// Fetch nonce
|
||||
const accountInfo = await api.query.system.account(hotWallet.address)
|
||||
const nonce = accountInfo.nonce
|
||||
|
||||
// Sign and send transaction
|
||||
|
||||
@@ -21,31 +21,8 @@
|
||||
|
||||
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
||||
import { createClient } from 'npm:@supabase/supabase-js@2'
|
||||
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.11'
|
||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.11'
|
||||
|
||||
// Decode SS58 address to raw 32-byte public key hex
|
||||
function ss58ToHex(address: string): string {
|
||||
const CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||||
let leadingZeros = 0;
|
||||
for (const c of address) {
|
||||
if (c !== '1') break;
|
||||
leadingZeros++;
|
||||
}
|
||||
let num = 0n;
|
||||
for (const c of address) {
|
||||
num = num * 58n + BigInt(CHARS.indexOf(c));
|
||||
}
|
||||
const hex = num.toString(16);
|
||||
const paddedHex = hex.length % 2 ? '0' + hex : hex;
|
||||
const decoded = new Uint8Array(leadingZeros + paddedHex.length / 2);
|
||||
for (let i = 0; i < leadingZeros; i++) decoded[i] = 0;
|
||||
for (let i = 0; i < paddedHex.length / 2; i++) {
|
||||
decoded[leadingZeros + i] = parseInt(paddedHex.slice(i * 2, i * 2 + 2), 16);
|
||||
}
|
||||
const pubkey = decoded.slice(1, 33);
|
||||
return '0x' + Array.from(pubkey, (b: number) => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.36'
|
||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.25'
|
||||
|
||||
// Configuration
|
||||
const SUPABASE_URL = Deno.env.get("SUPABASE_URL")!;
|
||||
@@ -91,24 +68,21 @@ async function processWithdrawal(
|
||||
// 2. Calculate amount in planck (smallest unit)
|
||||
const amountPlanck = BigInt(Math.floor(amount * Math.pow(10, DECIMALS)));
|
||||
|
||||
// 3. Convert addresses to hex (Deno npm shim breaks SS58 decoding in @pezkuwi/api types)
|
||||
const destHex = ss58ToHex(wallet_address);
|
||||
const signerHex = '0x' + Array.from(platformWallet.publicKey, (b: number) => b.toString(16).padStart(2, '0')).join('');
|
||||
console.log(`Sending ${amount} ${token}: ${signerHex} → ${destHex}`);
|
||||
console.log(`Sending ${amount} ${token}: ${platformWallet.address} → ${wallet_address}`);
|
||||
|
||||
let tx;
|
||||
if (token === "HEZ" || ASSET_IDS[token] === null) {
|
||||
tx = api.tx.balances.transferKeepAlive({ Id: destHex }, amountPlanck);
|
||||
tx = api.tx.balances.transferKeepAlive(wallet_address, amountPlanck);
|
||||
} else {
|
||||
const assetId = ASSET_IDS[token];
|
||||
if (assetId === undefined) {
|
||||
throw new Error(`Unknown token: ${token}`);
|
||||
}
|
||||
tx = api.tx.assets.transfer(assetId, { Id: destHex }, amountPlanck);
|
||||
tx = api.tx.assets.transfer(assetId, wallet_address, amountPlanck);
|
||||
}
|
||||
|
||||
// 4. Fetch nonce via hex pubkey to avoid SS58 → AccountId32 decoding issue
|
||||
const accountInfo = await api.query.system.account(signerHex);
|
||||
// 3. Fetch nonce
|
||||
const accountInfo = await api.query.system.account(platformWallet.address);
|
||||
const nonce = accountInfo.nonce;
|
||||
|
||||
// 5. Sign and send transaction
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
||||
import { createClient } from 'npm:@supabase/supabase-js@2'
|
||||
import { ApiPromise, WsProvider } from 'npm:@pezkuwi/api@16.5.11'
|
||||
import { ApiPromise, WsProvider } from 'npm:@pezkuwi/api@16.5.36'
|
||||
import { blake2b } from 'npm:@noble/hashes@1.7.1/blake2b'
|
||||
import { base58 } from 'npm:@scure/base@1.2.4'
|
||||
|
||||
|
||||