Sign & submit transfer
Cum să iei OMBRA de la user-ul tău (cu confirmation explicit) și să o trimiți programatic dintr-un dApp.
One-shot: ombra_submitTransfer
Cea mai simplă metodă — semnează ȘI broadcast într-un singur call:
const { txHash } = await window.ombra.request({
method: "ombra_submitTransfer",
params: {
to: "5bb5c50f185363cf913f93a18c6837c20d720a69",
amount: "1000000", // 1 OMBRA în micro
fee: "10000", // 0.01 OMBRA fee minim
memo: "Tip pentru articolul X" // opțional, max 256 chars
}
});
console.log("TX hash:", txHash);
Wallet-ul deschide popup → user confirmă → tx semnată + broadcast. Returnează txHash imediat.
Two-step: separat semnătură + broadcast
Util dacă vrei să semnezi în extensie dar broadcast-uiești prin propriul backend (ex: pentru pre-validation custom):
Step 1: Sign
const signed = await window.ombra.request({
method: "ombra_signTransfer",
params: {
to: "5bb...",
amount: "1000000",
fee: "10000"
}
});
// signed = {
// tx: {
// type: "TRANSFER",
// from: "...",
// to: "5bb...",
// amount: "1000000",
// fee: "10000",
// nonce: 42,
// timestamp: 1715990000,
// publicKey: "..."
// },
// signature: "..."
// }
Step 2: Broadcast manual
const response = await fetch("https://api.ombra-net.com/api/chain/tx", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(signed)
});
const { txHash } = await response.json();
Bulk transfers (airdrop)
Pentru a trimite OMBRA la N destinatari, fă N transferuri separate (nu există tx batch în v2):
const recipients = [
{ addr: "5bb...", amount: "1000000" },
{ addr: "abc...", amount: "2000000" },
{ addr: "def...", amount: "500000" }
];
const txHashes = [];
for (const r of recipients) {
const { txHash } = await window.ombra.request({
method: "ombra_submitTransfer",
params: { to: r.addr, amount: r.amount, fee: "10000" }
});
txHashes.push(txHash);
// Wait ~15s între tx-uri pentru a evita nonce conflict
await new Promise(r => setTimeout(r, 16000));
}
ATENȚIE: Wallet-ul va deschide popup pentru FIECARE tx. Pentru airdrop la sute de adrese, e mai practic să rulezi un script Node.js cu cheie privată directă (nu prin extensie).
Verifică confirmation
După submitTransfer, tx-ul e în mempool. Verifică inclusion în bloc:
async function waitForConfirmation(txHash: string, timeoutMs = 60000) {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const res = await fetch(`https://api.ombra-net.com/api/chain/tx/${txHash}`);
if (res.ok) {
const { blockIndex, status } = await res.json();
if (status === "confirmed") return blockIndex;
}
await new Promise(r => setTimeout(r, 5000));
}
throw new Error("Timeout așteptând confirmation");
}
const blockIndex = await waitForConfirmation(txHash);
console.log(`Confirmat în blocul #${blockIndex}`);
Validare pre-submit (UX)
Înainte de a deschide popup-ul de confirmation, validează local:
function validateTransfer(to: string, amount: string, fee: string) {
if (!/^[0-9a-f]{40}$/.test(to)) throw new Error("Adresă invalidă");
const amountBig = BigInt(amount);
const feeBig = BigInt(fee);
if (amountBig <= 0n) throw new Error("Amount > 0");
if (feeBig < 10_000n) throw new Error("Fee minim 0.01 OMBRA");
return true;
}
Memo field
Optional memo (max 256 bytes UTF-8) — pentru tag-uri, invoice ID, etc.:
await window.ombra.request({
method: "ombra_submitTransfer",
params: {
to: "...",
amount: "1000000",
fee: "10000",
memo: "invoice:#12345"
}
});
Memo apare pe explorer și e indexabil. NU folosi pentru secrete — e public on-chain.