c9432a16ba
- SIWE auth flow: challenge/login/logout/me API routes + JWT middleware
- Fixed [...path] catch-all: Kubo proxy with matchRoute() + mapToKuboAPI()
- Fixed session_id → nonce field mismatch in AuthProvider
- Fixed dashboard pins crash: Kubo returns {Keys: {...}}, not array
- Added middleware route guard (307 redirect to /login)
- Added login, register, profile, usage, upload pages
- Added dashboard components (StorageGauge, FreeTierProgress)
- Added SWR hooks + AuthGuard + Providers + Toast/ErrorBoundary
- Added payment integration (smart contract ABI, tiers, tokens)
- Fixed IPNS key listing: Name/Id → name/id mapping
- Added PWA support (manifest, service worker, icons)
- Added tests for helpers, limits, search-index, wallet
88 lines
5.5 KiB
TypeScript
88 lines
5.5 KiB
TypeScript
/* ── IPFS Portal Payment ABI & Constants ── */
|
|
|
|
import { type Chain } from 'viem';
|
|
|
|
/* ── Chain 270 (zkSync Local) ── */
|
|
export const zkSyncLocal: Chain = {
|
|
id: 270,
|
|
name: 'zkSync Local',
|
|
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
|
|
rpcUrls: {
|
|
default: { http: ['http://tom1687.no-ip.org:3050'] },
|
|
},
|
|
blockExplorers: {
|
|
default: { name: 'Explorer', url: 'http://tom1687.no-ip.org:3050' },
|
|
},
|
|
};
|
|
|
|
/* ── Contract ABI ── */
|
|
export const IPFS_PORTAL_PAYMENT_ABI = [
|
|
// ── State ──
|
|
{ type: 'function', name: 'owner', inputs: [], outputs: [{ type: 'address' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'maosTokenAddress', inputs: [], outputs: [{ type: 'address' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'freeTierBytes', inputs: [], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'basePricePerMB', inputs: [], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'userTotalBytes', inputs: [{ type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'totalRevenue', inputs: [{ type: 'string' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'totalUploads', inputs: [], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'supportedTokens', inputs: [{ type: 'uint256' }], outputs: [{ type: 'string' }], stateMutability: 'view' },
|
|
|
|
// ── View ──
|
|
{ type: 'function', name: 'getPrice', inputs: [{ type: 'uint256' }, { type: 'address' }], outputs: [
|
|
{ type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }, { type: 'bool' }
|
|
], stateMutability: 'view' },
|
|
{ type: 'function', name: 'getUserStats', inputs: [{ type: 'address' }], outputs: [
|
|
{ type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' },
|
|
{ type: 'tuple[]', components: [
|
|
{ type: 'string' }, { type: 'uint256' }, { type: 'string' }, { type: 'uint256' }, { type: 'uint256' }
|
|
]}
|
|
], stateMutability: 'view' },
|
|
{ type: 'function', name: 'getMAOSDiscountTiers', inputs: [], outputs: [
|
|
{ type: 'tuple[]', components: [{ type: 'uint256' }, { type: 'uint256' }] }
|
|
], stateMutability: 'view' },
|
|
{ type: 'function', name: 'getSupportedTokens', inputs: [], outputs: [{ type: 'string[]' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'tokenConfigs', inputs: [{ type: 'string' }], outputs: [
|
|
{ type: 'address' }, { type: 'uint8' }, { type: 'uint256' }, { type: 'bool' }
|
|
], stateMutability: 'view' },
|
|
|
|
// ── Write ──
|
|
{ type: 'function', name: 'payWithETH', inputs: [{ type: 'string' }, { type: 'uint256' }], outputs: [], stateMutability: 'payable' },
|
|
{ type: 'function', name: 'payWithToken', inputs: [{ type: 'string' }, { type: 'uint256' }, { type: 'string' }], outputs: [], stateMutability: 'nonpayable' },
|
|
|
|
// ── Admin Write ──
|
|
{ type: 'function', name: 'setPricePerMB', inputs: [{ type: 'uint256' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'setFreeTierBytes', inputs: [{ type: 'uint256' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'setMAOSDiscountTier', inputs: [{ type: 'uint256' }, { type: 'uint256' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'removeMAOSDiscountTier', inputs: [{ type: 'uint256' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'configureToken', inputs: [{ type: 'string' }, { type: 'address' }, { type: 'uint8' }, { type: 'uint256' }, { type: 'bool' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'setMAOSTokenAddress', inputs: [{ type: 'address' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'withdrawETH', inputs: [{ type: 'address' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'withdrawToken', inputs: [{ type: 'string' }, { type: 'address' }], outputs: [], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'transferOwnership', inputs: [{ type: 'address' }], outputs: [], stateMutability: 'nonpayable' },
|
|
|
|
// ── Events ──
|
|
{ type: 'event', name: 'UploadPaidETH', inputs: [
|
|
{ type: 'address', indexed: true }, { type: 'string', indexed: true },
|
|
{ type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }
|
|
]},
|
|
{ type: 'event', name: 'UploadPaidToken', inputs: [
|
|
{ type: 'address', indexed: true }, { type: 'string', indexed: true },
|
|
{ type: 'uint256' }, { type: 'string', indexed: true }, { type: 'uint256' }, { type: 'uint256' }
|
|
]},
|
|
{ type: 'event', name: 'FreeUploadUsed', inputs: [
|
|
{ type: 'address', indexed: true }, { type: 'string', indexed: true },
|
|
{ type: 'uint256' }, { type: 'uint256' }
|
|
]},
|
|
] as const;
|
|
|
|
/* ── Default contract address (set after deploy) ── */
|
|
export const DEFAULT_CONTRACT_ADDRESS = '0xCBc6b8aeea129c206F4836799621C833Bf8B9BDe';
|
|
|
|
/* ── ERC20 ABI (minimal for approve + balanceOf) ── */
|
|
export const ERC20_ABI = [
|
|
{ type: 'function', name: 'balanceOf', inputs: [{ type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'approve', inputs: [{ type: 'address' }, { type: 'uint256' }], outputs: [{ type: 'bool' }], stateMutability: 'nonpayable' },
|
|
{ type: 'function', name: 'allowance', inputs: [{ type: 'address' }, { type: 'address' }], outputs: [{ type: 'uint256' }], stateMutability: 'view' },
|
|
{ type: 'function', name: 'decimals', inputs: [], outputs: [{ type: 'uint8' }], stateMutability: 'view' },
|
|
] as const;
|