Кошельки и биржи
Эта страница для тех, кто интегрирует Velum: кошельков, бирж, платёжных шлюзов и приложений. Velum не совместим с EVM: у него свой формат адресов, транзакций и подписи. Всё необходимое собрано здесь.
Технические параметры
| Параметр | Значение |
|---|---|
| Сеть | {{chain}} (поле chain каждой транзакции) |
| Нативная монета | VEL, 6 знаков (1 VEL = 1 000 000 µVEL) |
| Суммы | Целые числа в минимальной единице токена |
| Время блока | Цель 2 с (реальный темп измеряется в обозревателе) · эпоха: 1 800 блоков (≈ 1 ч)30 блоков (≈ 60 с) |
| Кривая и подпись | ed25519 над каноническим JSON |
| Адрес | vel + base58(открытый ключ ed25519, 32 Б) |
| Вывод ключей кошелька | BIP-39 (24 слова) + SLIP-10 ed25519 по пути m/44'/7420'/аккаунт'/0'/индекс' |
| Комиссия за платёж | 0 при стоимости меньше 1 000 € (с доказательством работы); 0,01 % от 1 000 € |
| Цена | Собственный оракул: TWAP за 1 ч по {{pair}} |
| Порядок транзакций | nonce кошелька, начинается с 0 |
| ID транзакции | Первые 48 hex-символов SHA-256(канонический JSON с sig) |
| Рекомендуемые подтверждения | 6 (платежи), 30 (депозиты на биржах) |
| Узел | JSON-RPC поверх WebSocket |
| Обозреватель | REST API только для чтения по адресу /api |
Адреса {#direcciones}
Адрес — это префикс vel и открытый ключ ed25519 (32 байта) в base58 (алфавит Bitcoin). Длина 46–47 символов.
import { ed25519 } from "@noble/curves/ed25519.js";
import { base58 } from "@scure/base";
// A Velum address is "vel" + base58(32-byte ed25519 public key). No checksum byte:
// validate by decoding and checking the length is exactly 32.
const address = (pub: Uint8Array) => "vel" + base58.encode(pub);
const isAddress = (a: string) =>
a.startsWith("vel") && !a.startsWith("vel_") && (() => {
try { return base58.decode(a.slice(3)).length === 32; } catch { return false; }
})();
- Контрольной суммы нет. Всегда проверяй адрес декодированием: должно получиться ровно 32 байта. Для адресов, вводимых вручную, советуй копирование или сканирование QR-кода.
- Адреса, начинающиеся с
vel_, — служебные счета без ключа (vel_pool,vel_reserve,vel_escrow). Не принимай выводы на них. - Пользователи могут делиться псевдонимом (
@lucia) вместо адреса. Всегда разрешай его по блокчейну и показывай полученный адрес перед отправкой.
Вывод ключей {#claves}
Фраза BIP-39 из 24 слов порождает кошельки через SLIP-10 ed25519, все уровни усиленные (hardened):
| Параметр | Значение |
|---|---|
| Путь | m/44'/7420'/аккаунт'/0'/индекс' |
| Кошелёк официального приложения | m/44'/7420'/0'/0'/0' |
| Монета SLIP-44 | 7420 (ожидает регистрации) |
Ключи личности и ящика для переписки выводятся из того же семени через HKDF-SHA512 (velum/v2/identity, velum/v2/mailbox) и не являются ключами кошелька: бирже или кошельку они не нужны.
import { mnemonicToSeedSync } from "@scure/bip39";
import { hkdf } from "@noble/hashes/hkdf.js";
import { sha512 } from "@noble/hashes/sha2.js";
import { walletFromPhrase, walletPath } from "@velum/sdk";
// Wallet keys: SLIP-10 ed25519, every level hardened: m/44'/7420'/account'/0'/index'
const hot = walletFromPhrase(phrase, 0, 0); // m/44'/7420'/0'/0'/0' (the official app's wallet)
const user42 = walletFromPhrase(phrase, 0, 42); // one deposit address per customer
walletPath(0, 42); // "m/44'/7420'/0'/0'/42'"
// Messaging keys are NOT wallet keys: they come from the same seed with HKDF-SHA512.
const seed = mnemonicToSeedSync(phrase);
const identity = hkdf(sha512, seed, undefined, new TextEncoder().encode("velum/v2/identity"), 32);
Через SDK:
import { walletFromPhrase, isAddress } from "@velum/sdk";
const { address, secret } = walletFromPhrase(phrase, 0, 0);
isAddress(address); // true: "vel" + base58(32-byte ed25519 public key)
Это тот же путь, что используют SDK
@velum/sdk, аппаратные кошельки (Trezor, Ledger) и Snap для MetaMask. См. Экосистема.
Транзакции {#transacciones}
У всех транзакций есть общие поля:
| Поле | Тип | Значение |
|---|---|---|
type |
string | Тип транзакции |
chain |
string | {{chain}}. При несовпадении транзакция отклоняется. |
from |
адрес | Подписывающий кошелёк |
nonce |
целое | Число предыдущих транзакций from (0, 1, 2…) |
ts |
целое (мс) | Время клиента. Справочное: блокчейн использует время блока. |
sig |
hex (128) | Подпись ed25519 кошелька |
Подпись и канонический JSON
// Canonical JSON: keys sorted, no whitespace, undefined fields dropped. This is what gets signed and hashed.
export function canonical(v: unknown): string {
if (v === null || typeof v !== "object") return JSON.stringify(v);
if (Array.isArray(v)) return "[" + v.map(canonical).join(",") + "]";
const o = v as Record<string, unknown>;
return "{" + Object.keys(o).filter((k) => o[k] !== undefined).sort()
.map((k) => JSON.stringify(k) + ":" + canonical(o[k])).join(",") + "}";
}
// sig = hex(ed25519.sign(utf8(canonical(tx without "sig")), walletSecret))
// txId = hex(sha256(utf8(canonical(tx with "sig")))).slice(0, 48)
- Собери объект без
sig. Неиспользуемые необязательные поля пропусти (не ставьnull). - Сериализуй в канонический JSON: ключи отсортированы, без пробелов.
- Подпиши байты UTF-8 ключом кошелька.
sig— подпись в hex. - ID — это
sha256(канонический JSON с sig)в hex, обрезанный до 48 символов.
Платёж (transfer)
{
"type": "transfer",
"chain": "{{chain}}",
"from": "vel8Kx3vQ…",
"to": "vel4Jt9mR…",
"amount": 12500000,
"fee": 0,
"token": "tEUR",
"memo": "inv-20481",
"nonce": 17,
"ts": 1793577600000,
"sig": "9f2c…(128 hex)"
}
amountв минимальных единицах токена (µVEL, еслиtokenнет). Больше 0.feeподчиняется правилу v3: 0, если стоимость платежа по цене оракула сети меньше 1 000 €; иначе 0,01 % суммы. Платежи сfee, равным 0, содержат печать работыpow(SHA-512, около 50 мс на телефоне), которая входит в подписываемые данные; её вычисляетbuildTransferиз@velum/sdk. Точный формат описан вPROTOCOL.mdи вspec/vectors/.tokenнеобязателен: символ токена. Без него отправляется VEL.memoнеобязательно, до 128 символов. Оно публично: используй его для ссылок на платёж, но никогда для персональных данных.
Регистрация узла (register)
{
"type": "register", "chain": "{{chain}}", "from": "vel…node", "nonce": 0, "ts": 1793577600000,
"name": "atico-madrid", "payout": "vel…wallet", "version": "2.0.0",
"kind": "full", "endpoint": "wss://node.example.org:7420/ws",
"sig": "…"
}
Бесплатно. kind — full (компьютер, создаёт блоки) или light (телефон). payout — кошелёк для выплат.
Токены (token.create, token.mint, pool.fund)
{ "type": "token.create", "chain": "{{chain}}", "from": "vel…", "nonce": 3, "ts": 1793577600000,
"symbol": "CAFE", "name": "Café de barrio", "decimals": 2,
"maxSupply": 100000000, "initial": 2500000, "mintable": true, "fee": 100000000, "sig": "…" }
{ "type": "token.mint", "chain": "{{chain}}", "from": "vel…issuer", "nonce": 4, "ts": 1793577660000,
"symbol": "CAFE", "to": "vel…", "amount": 50000, "fee": 0, "sig": "…" }
{ "type": "pool.fund", "chain": "{{chain}}", "from": "vel…issuer", "nonce": 5, "ts": 1793577720000,
"token": "CAFE", "amount": 1440000, "epochs": 1440, "fee": 0, "sig": "…" }
Правила для каждого поля — в разделе Свои токены.
Биржа (order.place, order.cancel)
{ "type": "order.place", "chain": "{{chain}}", "from": "vel…", "nonce": 9, "ts": 1793577600000,
"pair": "VEL/tEUR", "side": "buy", "price": 12500, "amount": 250000000, "ttl": 1440, "sig": "…" }
{ "type": "order.cancel", "chain": "{{chain}}", "from": "vel…", "nonce": 10, "ts": 1793577660000,
"id": "4c1f0a…", "sig": "…" }
price в минимальных единицах токена за 1 VEL; amount в µVEL (минимум 1 VEL). См. Биржа.
Аттестация устройства (device.attest)
{ "type": "device.attest", "chain": "{{chain}}", "from": "vel…", "nonce": 0, "ts": 1793577600000,
"device": "e3b0c442…(64 hex = sha256 of the device public key)",
"keyId": "base64…", "attestation": "base64 CBOR…", "sig": "…" }
Её отправляет приложение для iOS, чтобы зафиксировать, что это оригинальное приложение на настоящем iPhone. Интеграторам отправлять её не нужно.
Nonce
- Первый
nonceкошелька — 0; каждая принятая транзакция увеличивает его на 1. - Для следующего используй
account.get→nonce + pending(pending— транзакции этого кошелька, ждущие в мемпуле узла). - Транзакция с уже использованным
nonceотклоняется. Повторная отправка той же самой подписанной транзакции безопасна: дважды она не спишется.
Частые ошибки
| Ошибка | Причина |
|---|---|
Cadena incorrecta |
chain не равно {{chain}} |
Firma no válida |
Подписан неканонический JSON или JSON с sig внутри |
Comisión incorrecta |
fee не соответствует правилу 1 000 € и цене оракула |
Nonce no válido |
Отрицательный, нецелый или повторный |
Nota demasiado larga |
memo длиннее 128 символов |
Финальность и подтверждения {#finalidad}
Финальность пока вероятностная (см. Консенсус). Реорганизации короткие, обычно на один-два блока.
| Сценарий | Подтверждения | Время |
|---|---|---|
| Чат, чаевые | 1 | Один блок |
| Магазин, платёжный шлюз | 6 | Несколько секунд |
| Депозит на бирже | 30 | ≈ 1 мин при целевом темпе |
| Крупный депозит | Одна эпоха | ≈ 1 ч≈ 1 мин |
У транзакции n подтверждений, когда её блок находится на высоте h, а вершина цепочки на h + n − 1.
RPC узла (WebSocket) {#rpc}
Приложения и сервисы общаются с узлами JSON-кадрами поверх WebSocket:
- Через публичный шлюз:
wss://velum.consultorabim.com/hub?role=client(резервный:wss://velum.consultora-bim.workers.dev/hub). - Напрямую с узлом:
ws://<host>:7420/ws?role=client. Бирже лучше держать собственный узел.
// Client → gateway (wss://velum.consultorabim.com/hub?role=client) or a node (ws://host:7420/ws?role=client)
type ClientToHub =
| { t: "rpc"; node?: string; id: string; method: RpcMethod; params: any }
| { t: "ping" };
type HubToClient =
| { t: "welcome"; client: string; nodes: PeerInfo[] }
| { t: "nodes"; nodes: PeerInfo[] }
| { t: "rpc_res"; id: string; result?: any; error?: string; node?: string }
| { t: "push"; node: string; event: "shard" | "head"; data: any }
| { t: "pong" };
// Read-only live feed for explorers (wss://…/hub?role=watch)
type HubToWatch =
| { t: "snapshot"; head: { height: number; hash: string } | null; nodes: PeerInfo[]; stats: Record<string, number> }
| { t: "block"; block: Block }
| { t: "nodes"; nodes: PeerInfo[] }
| { t: "flow"; kind: "shard" | "receipt" | "tx"; id: string; from?: string; to?: string; ts: number };
При работе через шлюз node необязателен: если его не указать, шлюз сам выберет узел и сообщит какой в ответе.
Методы
| Метод | Параметры | Результат |
|---|---|---|
chain.head |
{} |
{ height, hash, ts, node } |
chain.block |
{ height? , hash? } |
Block или null |
chain.blocks |
{ from, to } |
Block[] |
account.get |
{ address } |
{ balance, nonce, pending } (VEL в µVEL) |
account.history |
{ address, limit? } |
[{ height, ts, tx }] |
tx.submit |
{ tx } |
{ id } |
| shard.put | { shard } | { ok, carrier } |
| mailbox.open | { mailboxes: MailboxOpen[] } | { shards, courier }, затем события push |
| receipt.submit | { receipts } | { accepted } |
| node.info | {} | Данные узла |
| node.list | {} | Известные узлы |
| stats | {} | Счётчики узла |
Пример без SDK:
const ws = new WebSocket("wss://velum.consultorabim.com/hub?role=client");
let seq = 0;
const pending = new Map<string, (r: any) => void>();
const rpc = (method: string, params: object) =>
new Promise((resolve, reject) => {
const id = String(++seq);
pending.set(id, (m) => (m.error ? reject(new Error(m.error)) : resolve(m.result)));
ws.send(JSON.stringify({ t: "rpc", id, method, params }));
});
ws.onmessage = (e) => {
const m = JSON.parse(e.data);
if (m.t === "rpc_res") pending.get(m.id)?.(m), pending.delete(m.id);
};
ws.onopen = async () => {
const head = await rpc("chain.head", {}); // { height, hash, ts, node }
const acc = await rpc("account.get", { address: "vel…" }); // { balance, nonce, pending }
};
REST API обозревателя {#rest}
Обозреватель публикует API только для чтения с открытым CORS по адресу https://velum.consultorabim.com/api. Ответы в JSON; ошибки — { "error": "…" } с соответствующим HTTP-кодом.
| Маршрут | Возвращает |
|---|---|
GET /api/stats |
Высота, хеш, эмиссия, Резерв, предложение, узлы, уровни и параметры |
GET /api/oracle |
Цена сети: { eur, usd, usdt, ts, source } (если цены нет, значения null) |
GET /api/blocks?limit=&before= |
Канонические блоки от новых к старым (макс. 100) |
GET /api/block/:высота-или-хеш |
Подробности блока: платежи, баллы, награды |
GET /api/block/:id?raw=1 |
Полный подписанный блок (последние 5 000) |
GET /api/tx/:id |
Транзакция, подтверждения и подписанный JSON |
GET /api/txs?type=transfer|register|all&limit=&before= |
Последние транзакции |
GET /api/fragments?limit=&before= |
Квитанции о доставке по блокам |
GET /api/nodes |
Узлы с уровнем, доставками, заработком и статусом |
GET /api/address/:адрес |
Баланс, nonce, операции и награды |
GET /api/node/:адрес |
То же самое для узлов |
GET /api/search?q= |
Поиск по высоте, хешу, транзакции, адресу или имени узла |
curl -s https://velum.consultorabim.com/api/stats
curl -s "https://velum.consultorabim.com/api/blocks?limit=25&before=120000"
curl -s https://velum.consultorabim.com/api/block/118204
curl -s "https://velum.consultorabim.com/api/block/118204?raw=1" # signed block JSON
curl -s https://velum.consultorabim.com/api/tx/4c1f0a9e…
curl -s "https://velum.consultorabim.com/api/txs?type=all&limit=50"
curl -s https://velum.consultorabim.com/api/address/vel8Kx3vQ…
curl -s "https://velum.consultorabim.com/api/search?q=118204"
Для живой ленты подключись к wss://velum.consultorabim.com/hub?role=watch: придут snapshot, каждый новый block и список nodes.
API обозревателя удобен для запросов, но не является источником истины для движения средств. Бирже нужно проверять всё на собственном узле.
Депозиты и выводы на биржах {#exchanges}
Модель счетов
Два варианта, как и в других блокчейнах со счетами:
- Отдельный адрес для каждого пользователя (рекомендуется). Выводи
m/44'/7420'/0'/0'/N'для каждого клиента из холодной фразы. Не зависит от того, правильно ли пользователь ввёл memo. - Общий адрес + memo. Один адрес для депозитов и
memoкак идентификатор клиента. Если memo нет или оно неверное, депозит уходит на ручную проверку.
Отслеживание депозитов
import { CHAIN_ID } from "@velum/core";
const CONFIRMATIONS = 6; // ≈ 12 s; see "Finality" above
let next = loadCursor(); // last processed height + 1
async function poll() {
const head = (await rpc("chain.head", {})) as { height: number };
while (next <= head.height - CONFIRMATIONS) {
const block = (await rpc("chain.block", { height: next })) as Block;
if (block.header.chain !== CHAIN_ID) throw new Error("wrong chain");
for (const tx of block.txs) {
if (tx.type !== "transfer" || !isOurDepositAddress(tx.to)) continue;
const asset = tx.token ?? "VEL";
credit({ txid: txId(tx), to: tx.to, asset, amount: tx.amount, memo: tx.memo, height: next });
}
saveCursor(++next);
}
}
// Re-check the hash of the last credited blocks on every poll: if it changed, a short reorg happened.
- Следи за цепочкой блок за блоком через
chain.headиchain.blockна собственном узле. - Обрабатывай только транзакции
transferна свои адреса. Актив —token, а если его нет, VEL. - Зачисляй, когда у блока 30 подтверждений.
- Сохраняй хеш каждого обработанного блока. Если при следующем проходе он изменился, произошла реорганизация: откати и обработай заново с этого блока.
- Переводи средства в холодный кошелёк, когда удобно. Перемещения меньше 1 000 € идут без комиссии; более крупные стоят 0,01 %.
Выводы
import { makeTransfer, txId } from "@velum/core";
const acc = (await rpc("account.get", { address: hot.address })) as { nonce: number; pending: number };
const tx = makeTransfer(hot.secret, hot.address, userAddress, amountMicro, acc.nonce + acc.pending, { memo: withdrawalId });
const { id } = (await rpc("tx.submit", { tx })) as { id: string }; // id === txId(tx)
// Track id until it is CONFIRMATIONS blocks deep. Re-broadcasting the same signed tx is safe (same nonce).
- Подписывай в изолированном сервисе; узел получает только уже подписанные транзакции.
- Получай
nonceчерезaccount.get(nonce + pending) и веди собственный счётчик, если отправляешь много транзакций подряд. - Проверяй, что адрес назначения корректен и не является служебным счётом
vel_…. - Если вывод не попал в блок за несколько блоков, отправь ту же самую подписанную транзакцию ещё раз. Не подписывай новую с другим
nonce, пока не убедишься, что первая не прошла.
MetaMask Snaps {#snaps}
MetaMask работает с Ethereum, но Snaps позволяют добавлять сети, не совместимые с EVM. Snap для Velum должен:
- Вывести ключ ed25519. Через
snap_getBip32Entropyсcurve: "ed25519"(SLIP-10) по путиm/44'/7420'/0'/0'/0', тот же путь, что и в SDK. Число 7420 ожидает регистрации в SLIP-44. - Сформировать адрес
vel+ base58 открытого ключа. - Подписать канонический JSON транзакции ключом ed25519, предварительно запросив подтверждение пользователя через
snap_dialog. - Отправить транзакцию на узел по WebSocket (
endowment:network-access) или вернуть её подписанной dapp.
{
"version": "0.1.0",
"proposedName": "Velum",
"source": { "shasum": "…", "location": { "npm": { "filePath": "dist/bundle.js", "packageName": "velum-snap", "registry": "https://registry.npmjs.org/" } } },
"initialPermissions": {
"snap_getBip32Entropy": [{ "path": ["m", "44'", "7420'"], "curve": "ed25519" }],
"endowment:rpc": { "dapps": true, "snaps": false },
"snap_dialog": {},
"endowment:network-access": {}
},
"manifestVersion": "0.1"
}
import type { OnRpcRequestHandler } from "@metamask/snaps-sdk";
import { confirmUi } from "./ui"; // renders the transfer for the user
import { ed25519 } from "@noble/curves/ed25519.js";
import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js";
import { base58 } from "@scure/base";
import { canonical, CHAIN_ID } from "@velum/core";
// SLIP-10 ed25519 at m/44'/7420'/0'/0'/0' — the same path the Velum SDK and hardware wallets use.
async function walletKey() {
const node = await snap.request({
method: "snap_getBip32Entropy",
params: { path: ["m", "44'", "7420'", "0'", "0'", "0'"], curve: "ed25519" },
});
const secret = hexToBytes(node.privateKey!.slice(2)); // SLIP-10 ed25519 key, "0x…"
const pub = ed25519.getPublicKey(secret);
return { secret, address: "vel" + base58.encode(pub) };
}
export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
const k = await walletKey();
if (request.method === "velum_getAddress") return k.address;
if (request.method === "velum_signTransfer") {
const { to, amount, nonce, token, memo, fee } = request.params as any;
// fee: 0 below 1,000 € at the network oracle price (plus a small proof of work, see PROTOCOL.md), else 0.01 %
const body = { type: "transfer", chain: CHAIN_ID, from: k.address, to, amount, fee, nonce, ts: Date.now(), token, memo };
const ok = await snap.request({ method: "snap_dialog", params: { type: "confirmation", content: confirmUi(body) } });
if (!ok) throw new Error("rejected");
const sig = bytesToHex(ed25519.sign(new TextEncoder().encode(canonical(body)), k.secret));
return { ...body, sig };
}
throw new Error("method not found");
};
Важно:
- Путь тот же, но фраза — от MetaMask: аккаунт в Snap не совпадает с аккаунтом в приложении Velum, если только ты не используешь одну и ту же фразу в обоих местах.
- Перед публикацией Snap должен пройти аудит и процедуру включения в каталог MetaMask.
Что нужно для листинга VEL на бирже {#listado}
Что обычно требует крупная биржа (Binance, Kraken, Coinbase…) для интеграции нового блокчейна и где это найти:
| Требование | Состояние |
|---|---|
| Узел, который биржа может запустить | Запусти узел: бинарный файл без зависимостей, Linux x64/arm64 |
| Стабильный и документированный RPC | RPC узла |
| Публичный обозреватель | Обозреватель и REST API |
| Спецификация формата транзакций и подписи | Транзакции |
| Правило финальности | Финальность |
| Открытый код узла | Публичный репозиторий velum-node (готовится) |
| Внешний аудит безопасности | Запланирован до запуска основной сети |
| Основная сеть | velum-mainnet-1, без крана и тестовых токенов |
| Правовая база (MiCA в ЕС) | Прорабатывается с юристами |
Платёжные шлюзы {#pasarelas}
Velum подходит для приёма платежей в реальном времени: блоки за секунды и нулевая комиссия для платежей меньше 1 000 €. Всегда показывай стоимость в EUR, USD или USDT по цене оракула сети и сумму, которую получит магазин.
- Создавай отдельный адрес для каждого заказа (выводя
m/44'/7420'/0'/0'/N') или используй постоянный адрес с ID заказа вmemo. - Показывай QR-код с адресом, суммой и токеном (например,
{{quote}}). - Следи за блоками через
hub?role=watchили свой узел и отмечай заказ оплаченным после 6 подтверждений. - Если принимаешь оплату в токене и хочешь рассчитываться в VEL (или наоборот), используй биржу.
SDK @velum/core {#sdk}
То же ядро, на котором работают приложение, узел и этот сайт. TypeScript без нативных зависимостей: работает в Bun, Node, браузерах, Workers и React Native.
Подключение
import { VelumClient, keysFromPhrase, generatePhrase, createDevice, createAccount } from "@velum/core";
const phrase = generatePhrase("en"); // 24 words — store it offline
const keys = keysFromPhrase(phrase);
const account = createAccount(keys, createDevice("server-1"));
const client = new VelumClient({ account }); // defaults to the public gateways
client.on("status", (s) => console.log("network:", s));
client.connect();
await client.faucet(); // testnet only: 25 VEL
Отправка сообщения
client.on("message", (m) => console.log(m.payload.from, m.payload.body));
client.setContact(theirDeviceList); // signed DeviceList received out of band / via QR
const progress = await client.send(theirIdentity, { kind: "text", body: "Hola" });
client.on("progress", (p) => console.log(`${p.accepted}/${p.total} shards accepted`));
Платёж
import { parseAmount } from "@velum/core";
const { id } = await client.pay("vel4Jt9mR…", parseAmount("12,5")!); // VEL (µVEL integer)
await client.pay("vel4Jt9mR…", 2_000_000, { token: "tEUR", memo: "order-981" }); // 2 tEUR, fee in VEL
const { balance, nonce } = await client.balance();
Выставление заявки
// Buy 250 VEL at 0.0125 tEUR each. price = smallest token units per 1 VEL (tEUR has 6 decimals).
await client.placeOrder({ token: "tEUR", side: "buy", price: 12_500, amount: 250_000_000, ttl: 1_440 });
Создание токена
await client.createToken({ symbol: "CAFE", name: "Café de barrio", decimals: 2, maxSupply: 100_000_000, initial: 2_500_000, mintable: true });
// Costs 100 VEL. Then reward nodes in CAFE for a day:
// makePoolFund(wallet.secret, wallet.address, nonce, "CAFE", 1_440_000, 1_440)
SDK также экспортирует конструкторы транзакций (makeTransfer, makeRegister, makeTokenCreate, makeTokenMint, makePoolFund, makeOrder, makeCancel), функции чтения состояния (supplyInfo, difficulty, bookOf, tradesOf) и форматирование сумм (formatAmount, parseAmount).