Node.js SDK
The official @guveno/wallet-sdk wraps the REST API and handles wallet key derivation, signing and encryption. It authenticates with an API key. Working in Python? The Python SDK offers the same features.
@guveno/wallet-sdkon npm→Install
npm install @guveno/wallet-sdkUsing an API key
Construct the client with your API key. The base URL defaults to the production API, so you only set it for a self-hosted server.
import { Guveno } from "@guveno/wallet-sdk";
const guveno = new Guveno({
apiKey: process.env.GUVENO_API_KEY, // gv_live_...
});
const wallets = await guveno.listWallets();Creating & deriving wallets
The server is the source of truth: a recovery phrase is generated locally, sealed to your encryption key, and stored on the server; the SDK re-fetches and unseals it on demand. Pass your encryption password (the one you set during dashboard onboarding) when you create or load a wallet; that's what unseals the phrase locally.
import { Guveno } from "@guveno/wallet-sdk";
const guveno = new Guveno({ apiKey: process.env.GUVENO_API_KEY });
// Generates a phrase, seals it to your encryption key, and stores it on the server.
const created = await guveno.createWallet({
name: "treasury-eth",
chain: "ethereum",
network: "mainnet",
encryptionPassword: process.env.GUVENO_ENCRYPTION_PASSWORD,
});
console.log(created.wallet.id, created.firstAddress.address);
console.log("Back up:", created.mnemonic);
// The returned wallet is already loaded — derive the next address (server index).
const next = await created.wallet.deriveAddress({ label: "deposits" });
created.wallet.lock();If key file protection is enabled, pass the original bytes when creating, importing, or loading:
import { readFile } from "node:fs/promises";
const keyFile = await readFile("/secure/original-photo.png");
const wallet = await guveno.loadWallet(10, {
encryptionPassword: process.env.GUVENO_ENCRYPTION_PASSWORD,
keyFile,
});
keyFile.fill(0);
// Use wallet, then wallet.lock() when finished.Vaults: one phrase, many chains
createWallet and importWallet create a vault for the phrase, or join the vault that already holds it when you have key access. addWalletToVault adds another chain wallet to an existing vault without generating anything new: it unseals the vault's phrase from one of its wallets and derives from it. Pass derivationPathPrefix to put a second wallet for the same chain in the same vault.
const [treasury] = await guveno.listVaults(); // metadata only, no password
const { wallet: eth } = await guveno.addWalletToVault({
vaultId: treasury.id,
name: "treasury-eth",
chain: "ethereum",
network: "mainnet",
encryptionPassword: process.env.GUVENO_ENCRYPTION_PASSWORD,
});
// A second Ethereum wallet in the same vault needs its own derivation path.
const { wallet: ops } = await guveno.addWalletToVault({
vaultId: treasury.id,
name: "ops-eth",
chain: "ethereum",
network: "mainnet",
derivationPathPrefix: "m/44'/60'/1'/0",
encryptionPassword: process.env.GUVENO_ENCRYPTION_PASSWORD,
});Reading balances
Balances need only the API key, no encryption password. A loaded wallet exposes getters, or call guveno.client directly with a wallet id. Amounts are decimal strings in the asset's main unit and carry the full asset metadata.
const wallet = await guveno.loadWallet(walletId, password);
const byAddress = await wallet.getBalances(); // per-address, per-asset
const totals = await wallet.getTotals(); // aggregated per asset
const stats = await wallet.getStats(); // holdings, flows, top addresses
// Or via the low-level client, by wallet id:
await guveno.client.getWalletBalanceTotals(walletId);
// Company-wide totals per asset (optionally scoped to a chain/network):
await guveno.client.getCompanyBalanceSummary({ chain: "ethereum", network: "mainnet" });Signing locally
Withdrawals follow prepare → sign → broadcast with signing in your process; see Hot wallets. The mnemonic is unsealed locally (or supplied by a key provider) and never leaves your environment. See the SDK README for the full method list and worked examples.