JavaScript SDK
У репозиторії є дві клієнтські бібліотеки:
| Бібліотека | Де | Коли використовувати |
|---|---|---|
dApp SDK (NeuroChain) | neurochain-web/src/sdk/neurochain.js | Ваша сторінка тримає ключ користувача (або скрипт працює з вашим власним гаманцем) |
Signer SDK (NeuroSigner) | packages/neurochain-signer-sdk | Ваш dApp працює на іншому сайті, а користувач підписує у своєму гаманці NeuroChain у спливному вікні |
Жодна з них ще не опублікована в npm; скопіюйте модуль або зберіть пакет з репозиторію.
dApp SDK
Один ES-модуль без залежностей. Читання — звичайний fetch (браузер або Node 18+); запис підписується ML-DSA-65 тим самим криптомодулем WASM, що й гаманець, тож нода приймає підписи.
import { NeuroChain, OP_TARGETS, toRaw } from './neurochain.js'
const nc = new NeuroChain({ gateway: 'http://localhost:3000' })| Опція | За замовчуванням | Значення |
|---|---|---|
gateway | http://localhost:3000 | Базова адреса gateway |
crypto | — | Уже ініціалізований криптомодуль WASM |
cryptoLoader | завантажує ../wasm/neuro_wasm_crypto.js | Асинхронна функція, що повертає ініціалізований модуль |
Суми
Кожне value і amount, які ви передаєте, — це людські NRO ('1.5', 2, '0.000021'). SDK переводить їх у ціле число uNRO через toRaw(), тож підписана й надіслана суми завжди однакові. Для показу використовуйте поля *_human з відповідей API.
Читання
| Метод | Звертається до | Повертає |
|---|---|---|
networkStatus() | GET /api/v1/network/status | Висоту, шарди, валідаторів |
shards() | GET /api/v1/shards | Висоти шардів |
account(addr) | GET /api/v1/accounts/:addr | balance, balance_human, nonce, … |
balance(addr) | через account | { raw, human, nonce } |
nextNonce(addr) | через account | Підтверджений nonce + 1 |
validators() | GET /api/v1/validators | Валідаторів зі стейком і метриками |
blocks({ limit, offset }) | GET /api/v1/blocks | Останні блоки |
block(height) | GET /api/v1/blocks/:height | Один блок |
tx(hash) | GET /api/v1/transactions/:hash | Одну транзакцію |
contract(addr) / contracts({ limit, offset }) | GET /api/v1/contracts… | Метадані контрактів |
gasEstimate() | GET /api/v1/gas/estimate | base_fee і оцінки |
contractQuery(addr, fn, args) | POST /api/v1/contracts/:addr/call з dry_run: true | Розібраний результат; без транзакції і без газу |
Гаманець
const wallet = await nc.walletFromMnemonic('<24 слова>')
wallet.address // neuro:<15 hex>.human
wallet.publicKey // публічний ключ ML-DSA-65, hexПриватний seed лишається всередині об'єкта гаманця й ніколи не доступний як властивість.
Запис
// Переказ
await nc.transfer({ wallet, to: 'neuro:<адреса>.human', value: '1.5', gasPrice })
// Будь-яка транзакція, за потреби з даними виклику
await nc.sendTransaction({ wallet, to, value, data, gasPrice })
// Виклик контракту — дані виклику JSON { function, args }
await nc.contractCall({ wallet, address: 'neuro:<10 hex>.app', fn: 'transfer', args: { … }, value, gasPrice })
// Розгортання — транзакція на neuro:system.deploy
await nc.deployContract({ wallet, bytecodeHex, name, description, template, initArgs, gasPrice })Кожен запис читає наступний nonce, підписує nc-tx-v2|from|to|value|nonce і надсилає на POST /api/v1/transactions.
Задавайте ціну газу
За замовчуванням SDK ставить gasPrice: 1 (для розгортання — 5). Нода відхиляє транзакцію з ціною нижче поточної базової комісії, а вона під навантаженням зростає. Спершу прочитайте її й передайте gasPrice явно:
const { base_fee } = await nc.gasEstimate()
const gasPrice = Math.ceil(base_fee * 1.5)Підписані операції
Стейкінг, реєстрація імені та інші системні операції підписуються на системну ціль з nonce — позначкою часу в мілісекундах (див. Гаманець → Підписані операції):
const op = nc.signOp(wallet, OP_TARGETS.name, 0) // { signature, public_key, nonce }
// додайте op до тіла запиту ендпоінтаOP_TARGETS містить stake (neuro:system.stake) і name (neuro:system.name).
Відомі проблеми
Відомі проблеми поточного SDK
- Перекази з ненульовою сумою не проходять.
sendTransaction/transferнадсилаютьvalueрядком JSON; нода читає лише число й відхиляє запит зMissing from/to/value. Виклики й розгортання з сумою 0 це не зачіпає. Обхід — підписати й надіслати числове значення:jsconst nonce = await nc.nextNonce(wallet.address) const value = Number(toRaw('1.5')) // uNRO числом const sig = wallet.sign(to, value, nonce) await fetch(GATEWAY + '/api/v1/transactions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ from: wallet.address, to, value, nonce, gas_price, ...sig }) }) contractQueryповертає сирий рядок, якщо відповідь контракту — не чистий JSON. Відповіді NRC-20 закінчуються нульовим байтом, тож ви отримаєте рядок'{"ok":true,"value":…}'; приберіть\u0000і розберіть.stake()двічі переводить суму в uNRO перед підписом, тож нода відхиляє підпис. Доки не виправлено, складайте запит самі:{ address, amount: toRaw(amount), ...nc.signOp(wallet, OP_TARGETS.stake, amount) }на/api/v1/staking/stake.staking(addr)звертається до/api/v1/staking/:addr, якого gateway не обслуговує; використовуйтеGET /api/v1/staking/info/:address.contractCallдодає до JSON виклику полеcaller. Контракти його ігнорують — ідентичність дає хост, — тож це нешкідливо.
Криптомодуль
Для підпису потрібен neuro_wasm_crypto — WASM-збірка гаманця (neurochain-web/src/wasm/neuro_wasm_crypto.js і neuro_wasm_crypto_bg.wasm). Він має експортувати nc_keypair_from_words, nc_tx_message і nc_sign. Якщо ваша сторінка віддає його з іншого місця, передайте завантажувач:
const nc = new NeuroChain({
gateway: 'http://localhost:3000',
cryptoLoader: async () => {
const mod = await import('/wasm/neuro_wasm_crypto.js')
await mod.default()
return mod
},
})Без модуля читання працює, а кожен запис кидає помилку.
Signer SDK
Для dApp на іншому домені (біржа, гра), який не повинен бачити фразу користувача. Вебзастосунок NeuroChain користувача відкривається у спливному вікні, користувач підтверджує, і підпис повертається через postMessage.
import { NeuroSigner } from 'neurochain-signer-sdk'
const signer = new NeuroSigner({
signerUrl: 'http://localhost:8080/signer', // сторінка /signer вебгаманця
allowedOrigins: ['http://localhost:8080'],
})
// Має виконуватися безпосередньо в обробнику кліку, інакше браузер заблокує вікно
button.onclick = async () => {
const { address, publicKey } = await signer.connect()
const { signature, nonce } = await signer.signOperation({
to: 'neuro:system.dex',
value: 1000000, // uNRO
})
}| Метод | Повертає |
|---|---|
connect() | { address, publicKey } |
signOperation({ to, value, actor? }) | { signature, publicKey, nonce } — підписана операція для actor (за замовчуванням — підключена адреса) |
isConnected(), getAddress(), getPublicKey() | Стан підключення |
close() | Закриває вікно і від'єднується |
Помилки мають code: POPUP_BLOCKED, CONNECTION_TIMEOUT, SIGNATURE_REJECTED, INVALID_ORIGIN, NOT_CONNECTED. При POPUP_BLOCKED покажіть користувачу пряме посилання на сторінку підпису.
Повідомлення приймаються лише з allowedOrigins; вкажіть там домен свого вебгаманця.