Projek ini adalah aplikasi Web3 pertama saya, dan ia bersambung ke blok blok Cardano melalui dompet Yoroi. Ia agak mudah sebenarnya, hanya satu cara untuk menyemak baki dompet anda, tetapi ia menandakan permulaan banyak projek menarik yang akan datang. Saya ingin berkongsi proses pembelajaran saya, dengan anda semasa kami menjalani tutorial ini.
Sebelum kita bermula, mari kita jelaskan tentang perkara yang kita buat. Ini ialah alat ringkas yang membolehkan anda:
Pengetahuan JavaScript asas (jika anda boleh console.log("hello world"), anda bagus!)
Buat folder baharu pada komputer anda bernama CardanoWalletExplorer (atau junky justyk jika anda mahu, nama tidak begitu penting). Buka folder dalam editor kod anda (saya menggunakan Kod Visual Studio).
Di dalam folder, buat dua fail:
index.html dan style.css
Sekarang buka index.html dan tampal ini:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Cardano Wallet Explorer</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> </head> <body> <div> <p>Let's add some style to our creation. Inside the style.css file paste this in:<br> </p> <pre class="brush:php;toolbar:false">:root { --primary-color: #0033ad; --secondary-color: #2a71d4; --accent-color: #17d1aa; --background-color: #f8faff; --card-background: #ffffff; --text-primary: #1a202c; --text-secondary: #4a5568; --border-color: #e2e8f0; --shadow: 0 4px 6px rgba(0,0,0,0.1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', system-ui, sans-serif; background: var(--background-color); color: var(--text-primary); line-height: 1.5; min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 2rem; } .container { background: var(--card-background); border-radius: 1.5rem; box-shadow: var(--shadow); width: 100%; max-width: 800px; overflow: hidden; } .app-header { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; padding: 2rem; text-align: center; } .logo { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 0.5rem; } .logo i { font-size: 2rem; } h1 { font-size: 1.8rem; font-weight: 600; } .subtitle { opacity: 0.9; } .content { padding: 2rem; } .search-section { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; margin-bottom: 2rem; } .search-box { display: flex; gap: 1rem; width: 100%; max-width: 600px; } #wallet-search { flex: 1; padding: 0.875rem 1rem; border: 2px solid var(--border-color); border-radius: 12px; font-size: 0.95rem; transition: 0.3s ease; } #wallet-search:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 3px rgba(23, 209, 170, 0.1); } button { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.875rem 1.5rem; border: none; border-radius: 12px; font-size: 0.95rem; font-weight: 500; cursor: pointer; transition: 0.3s ease; } #search-button { background: var(--accent-color); color: white; } #search-button:hover { background: #15bea0; transform: translateY(-2px); } .divider { width: 100%; max-width: 600px; text-align: center; position: relative; color: var(--text-secondary); } .divider::before, .divider::after { content: ''; position: absolute; top: 50%; width: calc(50% - 2rem); height: 1px; background: var(--border-color); } .divider::before { left: 0; } .divider::after { right: 0; } .connect-button { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; padding: 1rem 2rem; } .connect-button:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .wallet-info { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .info-card { background: var(--card-background); border: 1px solid var(--border-color); border-radius: 1rem; padding: 1.5rem; transition: 0.3s ease; } .info-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .card-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; color: var(--text-secondary); } .card-header i { font-size: 1.25rem; color: var(--primary-color); } .card-content { font-size: 0.95rem; color: var(--text-primary); word-break: break-all; } .app-footer { text-align: center; padding: 1.5rem; background: var(--background-color); color: var(--text-secondary); font-size: 0.9rem; } .app-footer a { color: var(--primary-color); text-decoration: none; } .app-footer a:hover { text-decoration: underline; } @media (max-width: 640px) { body { padding: 1rem; } .container { border-radius: 1.5rem; } .app-header { padding: 1.5rem; } .content { padding: 1.5rem; } .search-box { flex-direction: column; } button { width: 100%; justify-content: center; } .wallet-info { grid-template-columns: 1fr; } }
Untuk mendapatkan baki dompet, kami memerlukan Blockfrost, yang membolehkan kami berinteraksi dengan blockchain Cardano. Begini cara anda boleh mendapatkan Kunci API anda:
Sekarang untuk bahagian yang menyeronokkan, menjadikan semuanya berfungsi! buat fail bernama script.js dalam folder yang kami buat.
function checkYoroiInstalled() { return window.cardano && window.cardano.yoroi; }
? Fungsi ini menyemak sama ada sambungan dompet Yoroi dipasang dalam penyemak imbas anda. Window.cardano ialah objek yang didedahkan oleh dompet Cardano seperti Yoroi. Kami menyemak sama ada ini wujud dan sama ada window.cardano.yoroi tersedia untuk mengesahkan bahawa dompet Yoroi telah dipasang.
Jika kedua-duanya benar, fungsi mengembalikan benar; jika tidak, ia kembali palsu.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Cardano Wallet Explorer</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> </head> <body> <div> <p>Let's add some style to our creation. Inside the style.css file paste this in:<br> </p> <pre class="brush:php;toolbar:false">:root { --primary-color: #0033ad; --secondary-color: #2a71d4; --accent-color: #17d1aa; --background-color: #f8faff; --card-background: #ffffff; --text-primary: #1a202c; --text-secondary: #4a5568; --border-color: #e2e8f0; --shadow: 0 4px 6px rgba(0,0,0,0.1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Inter', system-ui, sans-serif; background: var(--background-color); color: var(--text-primary); line-height: 1.5; min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 2rem; } .container { background: var(--card-background); border-radius: 1.5rem; box-shadow: var(--shadow); width: 100%; max-width: 800px; overflow: hidden; } .app-header { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; padding: 2rem; text-align: center; } .logo { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 0.5rem; } .logo i { font-size: 2rem; } h1 { font-size: 1.8rem; font-weight: 600; } .subtitle { opacity: 0.9; } .content { padding: 2rem; } .search-section { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; margin-bottom: 2rem; } .search-box { display: flex; gap: 1rem; width: 100%; max-width: 600px; } #wallet-search { flex: 1; padding: 0.875rem 1rem; border: 2px solid var(--border-color); border-radius: 12px; font-size: 0.95rem; transition: 0.3s ease; } #wallet-search:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 3px rgba(23, 209, 170, 0.1); } button { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.875rem 1.5rem; border: none; border-radius: 12px; font-size: 0.95rem; font-weight: 500; cursor: pointer; transition: 0.3s ease; } #search-button { background: var(--accent-color); color: white; } #search-button:hover { background: #15bea0; transform: translateY(-2px); } .divider { width: 100%; max-width: 600px; text-align: center; position: relative; color: var(--text-secondary); } .divider::before, .divider::after { content: ''; position: absolute; top: 50%; width: calc(50% - 2rem); height: 1px; background: var(--border-color); } .divider::before { left: 0; } .divider::after { right: 0; } .connect-button { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); color: white; padding: 1rem 2rem; } .connect-button:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .wallet-info { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .info-card { background: var(--card-background); border: 1px solid var(--border-color); border-radius: 1rem; padding: 1.5rem; transition: 0.3s ease; } .info-card:hover { transform: translateY(-2px); box-shadow: var(--shadow); } .card-header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; color: var(--text-secondary); } .card-header i { font-size: 1.25rem; color: var(--primary-color); } .card-content { font-size: 0.95rem; color: var(--text-primary); word-break: break-all; } .app-footer { text-align: center; padding: 1.5rem; background: var(--background-color); color: var(--text-secondary); font-size: 0.9rem; } .app-footer a { color: var(--primary-color); text-decoration: none; } .app-footer a:hover { text-decoration: underline; } @media (max-width: 640px) { body { padding: 1rem; } .container { border-radius: 1.5rem; } .app-header { padding: 1.5rem; } .content { padding: 1.5rem; } .search-box { flex-direction: column; } button { width: 100%; justify-content: center; } .wallet-info { grid-template-columns: 1fr; } }
Fungsi ini memformat baki ADA dengan cara yang mesra pengguna.
Cardano menggunakan lovelace sebagai unit terkecil (1 ADA = 1,000,000 lovelace), jadi kita perlu menukarnya kepada ADA dengan membahagikan dengan 1,000,000.
Ia juga memastikan baki dipaparkan dengan 6 tempat perpuluhan (seperti 1.234567 ADA), atau mengembalikan "0.000000" jika baki tidak sah atau kosong.
function checkYoroiInstalled() { return window.cardano && window.cardano.yoroi; }
Kami menggunakan API Ambil untuk membuat permintaan GET kepada Blockfrost. Blockfrost menyediakan API untuk berinteraksi dengan blockchain Cardano. Kami menghantar permintaan GET ke titik akhir untuk alamat dompet tertentu, menggunakan kunci API untuk kebenaran. Fungsi ini mengambil baki alamat dompet tertentu dengan membuat permintaan kepada API Blockfrost.
Jika respons berjaya, kami menghuraikan data JSON dan mengembalikan kuantiti ADA dalam alamat tersebut.
Jika terdapat ralat (mis., alamat tidak sah atau isu API), ia akan membuang ralat dan lognya ke konsol. URL titik akhir termasuk alamat dompet yang ingin kami semak. Pastikan anda menggantikan pemegang tempat YOUR_API_KEY dalam fungsi checkWalletBalance dengan Kunci API anda.
function formatBalance(lovelaceBalance) { if (!lovelaceBalance || isNaN(lovelaceBalance)) { return "0.000000"; } const adaBalance = parseFloat(lovelaceBalance) / 1_000_000; return adaBalance.toFixed(6); }
**Fetching Wallet Balance Using Blockfrost API async function checkWalletBalance(address) { try { const API_KEY = 'YOUR_API_KEY'; const response = await fetch(`https://cardano-mainnet.blockfrost.io/api/v0/addresses/${address}`, { headers: { 'project_id': API_KEY } }); if (!response.ok) { throw new Error('Invalid address or API error'); } const data = await response.json(); return data.amount[0].quantity; } catch (error) { console.error('Error fetching balance:', error); throw error; } }
Kod ini melampirkan pendengar acara pada elemen HTML:
Apabila butang "Sambungkan Dompet Yoroi" diklik, ia akan memanggil fungsi sambung Dompet.
Apabila butang "Semak Baki" diklik, ia memanggil fungsi handleWalletSearch.
Jika pengguna menekan kekunci "Enter" dalam medan input alamat dompet, ia juga mencetuskan semakan baki.
Anda kini selangkah lebih dekat untuk menguasai Web3! ?Projek ini bukan sahaja pencapaian teknikal tetapi juga satu langkah yang menarik ke dalam dunia pembangunan blockchain yang luas! ?
Kini, anda boleh menyambung dengan lancar ke dompet Yoroi, menyemak baki dan membawa kuasa blockchain ke hujung jari anda.
? Masa Menguji!
Projek ini adalah batu loncatan ke dalam dunia pembangunan blockchain. Berikut ialah beberapa idea untuk meneruskannya:
Projek ini adalah langkah pertama saya ke Web3, dan saya tidak sabar-sabar untuk belajar daripada yang terbaik. Pengalaman, cerapan dan cadangan anda boleh menjadikan projek ini lebih baik di samping membantu saya berkembang sebagai pembangun. Begini cara anda boleh menyumbang:
Mari terus membina dan berinovasi—sumbangan dan kreativiti anda boleh membentuk masa depan alat ini! ?
Terperangkap? Menemui pepijat? Ingin bersembang? Tinggalkan komen di bawah atau cari saya di Twitter!
Ingat, kita semua bermula di suatu tempat, dan satu-satunya soalan bodoh ialah soalan yang anda tidak tanya!
Selamat pengekodan, rakan-rakan peneroka blokchain! ?
Atas ialah kandungan terperinci Pengenalan. ke WebBuilding Cardano Wallet Checker dengan JavaScript.. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!