Skip to content

windvex/windkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WindKit

npm version License: MIT

WindKit is a lightweight WebRTC protocol for connecting Vexanium DApps to Wind Wallet using PeerJS and WharfKit Signing Requests (VSR).

It enables secure cross-device login and transaction signing without requiring browser extensions.

Designed for production environments, including low-RAM mobile devices.


✨ Features

  • Cross-device login via VSR (Vexanium Signing Request)
  • Transaction signing (single action, multiple actions, or full transaction)
  • Optional broadcast control (sign-only or broadcast)
  • Message signing
  • Shared secret derivation (ECDH)
  • Session persistence via sessionStorage
  • Low-memory heartbeat strategy
  • Pure ESM module (JavaScript-only)

🧩 In-App Browser Injected Provider

WindKit now supports Wind Wallet's in-app DApp Browser provider, similar to MetaMask / Phantom / Rabby.

When a DApp is opened inside Wind Wallet Browser, Wind Wallet injects:

window.wind
window.windwallet
window.windWallet
window.vexanium
window.vex

Use the hybrid client to support both injected provider and QR/VSR fallback:

import { WindClient } from "windkit";

const wind = new WindClient();

const session = await wind.connect({
  name: "My Vexanium DApp",
  icon: "https://example.com/icon.png",

  // Called only when the DApp is opened outside Wind Wallet Browser.
  // Render this VSR as QR, or show your existing login modal.
  onLoginRequest(vsr) {
    console.log("Show QR:", vsr);
  }
});

console.log("Connected:", session.permissionLevel?.toString());

Direct injected request

import { InjectedWalletSession } from "windkit";

if (InjectedWalletSession.isAvailable()) {
  const session = await InjectedWalletSession.connect();

  await session.signMessage("Hello Wind!");
}

Provider API

Inside Wind Wallet Browser, DApps can also call the provider directly:

const accounts = await window.wind.request({
  method: "vex_requestAccounts"
});

const signature = await window.wind.request({
  method: "vex_signMessage",
  params: ["Hello Wind!"]
});

const result = await window.wind.request({
  method: "signRequest",
  params: ["vsr:..."]
});

Recommended DApp logic

1. Try injected provider first: window.wind / window.vexanium.
2. If not available, use QR/VSR + PeerJS fallback.
3. Keep signing approval inside Wind Wallet.

This keeps old QR pairing working while enabling MetaMask-style connect inside the Wind Wallet app.


πŸ“¦ Installation

npm install windkit

WindKit is ESM-only.

Your project must include:

{
  "type": "module"
}

πŸš€ Quick Start

Create Connector

import { WindConnector } from "windkit";

const connector = new WindConnector();

connector.on("session", (session, proof) => {
  console.log("Connected as:", session.permissionLevel?.toString());
});

await connector.connect();

By default, WindKit uses PeerJS default signaling.


🌐 Custom PeerJS Server (Optional)

connector.setServer("peer.yourdomain.com", 443, "/", true);

Signature:

setServer(host, port, path, secure);

Add custom ICE server:

connector.addIceServer({
  urls: "stun:stun.cloudflare.com:3478"
});

πŸ” Login Flow (VSR)

const vsr = connector.createLoginRequest(
  "My Vexanium DApp",
  "https://example.com/icon.png"
);

const payload = vsr.startsWith("vsr:") ? vsr.slice(4) : vsr;

window.open(
  `https://wallet.windcrypto.com/login?vsr=${encodeURIComponent(payload)}`,
  "Wind Wallet"
);

Wallet flow:

  1. Decode VSR
  2. Connect to embedded PeerID
  3. Send LOGIN_OK
  4. Emit session

πŸ”„ Session Handling

connector.on("session", (session, proof) => {
  session.onClose(() => {
    console.log("Wallet disconnected");
  });

  session.onError((error) => {
    console.error("Session error:", error);
  });

  window.appSession = session;
});

✍️ Send Transaction

With ABI Cache (Recommended)

import { Action } from "@wharfkit/antelope";
import { ABICache } from "@wharfkit/abicache";

const abiCache = new ABICache();
appSession.setABICache(abiCache);

const abi = await abiCache.getAbi("vex.token");

const action = Action.from(
  {
    account: "vex.token",
    name: "transfer",
    data: {
      from: "alice",
      to: "bob",
      quantity: "1.0000 VEX",
      memo: "WindKit test"
    },
    authorization: [appSession.permissionLevel]
  },
  abi
);

const result = await appSession.transact({ action });

console.log(result.transaction_id ?? result.id);

Sign Only (No Broadcast)

await appSession.transact(
  { action },
  { broadcast: false }
);

πŸ“ Sign Message

const signature = await appSession.signMessage("Hello Wind!");
console.log(signature.toString());

πŸ”‘ Shared Secret (ECDH)

import { PublicKey } from "@wharfkit/antelope";

const pub = PublicKey.from("PUB_K1_...");
const secret = await appSession.sharedSecret(pub);

console.log(secret.toString());

πŸ’Ύ Session Storage

WindKit stores session data in:

sessionStorage["vex-session"]

Example structure:

{
  "peerID": "VEX-xxxx",
  "permission": "account@active",
  "expiration": "2026-03-01T12:00:00",
  "auth": "base64u_identity_proof"
}

Clear session manually:

import { clearSession } from "windkit";

clearSession();

πŸ— Architecture

WindConnector

  • Creates VSR identity login
  • Hosts PeerJS PeerID (DApp-side)
  • Waits for wallet connection
  • Emits session

WalletSession

  • Sends:
    • signRequest
    • signMessage
    • sharedSecret
  • Routes replies via request IDs
  • Lightweight heartbeat ping
  • Handles account change events

πŸ”Ž Protocol Notes

Transaction signing method:

signRequest

Wallet push events handled:

LOGIN_OK
ACTIVE_ACCOUNT_CHANGED

All communication occurs over PeerJS DataConnection.


βš™ Technical Details

Chain ID is internally fixed via:

WalletSession.ChainID

Dependencies:

  • @wharfkit/signing-request
  • @wharfkit/antelope
  • peerjs
  • pako

Optimized for:

  • Low-RAM mobile devices
  • Background browser tabs
  • Unstable WebRTC networks

πŸ” Security Model

  • IdentityProof can be verified by the DApp (recommended).
  • Private keys never leave the wallet.
  • VSR ensures transaction integrity.
  • PeerID is embedded inside the VSR payload to prevent misrouting.

πŸ“„ License

MIT License
Β© Wind Stack

About

A protocol for connecting Vexanium DApps to the Wind wallet, enabling secure communication and transaction signing.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors