npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@opendatalabs/connect

v0.8.1

Published

SDK for integrating Vana Data Portability 'Connect data' flows

Readme

Vana Connect SDK

Let your users bring their own data to your app.

What problem this solves

Your users already have rich personal data — ChatGPT conversations, Instagram activity, Gmail, purchase history — but it's locked inside the platforms that collected it. As a builder, you can't easily use that data to personalize onboarding, tailor recommendations, or skip lengthy signup forms.

Data portability means users can export their data from these platforms and grant your app scoped access to it — with their explicit consent, cryptographic verification, and full control over what's shared and when to revoke it.

Today, getting access to user data means asking for manual file uploads (high friction), scraping on their behalf (fragile and legally risky), or negotiating enterprise API deals (slow and expensive). This SDK gives you a standardized way to request and receive personal data through Vana's Data Portability Protocol, handling session creation, grant verification, and data fetching in three function calls.

How it works

Your App                         Vana Protocol
──────────────────────────────   ──────────────────────────────

1. connect({ scopes })
   → creates session
   → returns deep link      ──▶  2. User opens DataConnect
                                    reviews scopes, exports data,
                                    approves grant

3. Poll resolves with grant  ◀──  Grant signed & registered

4. getData({ grant })        ──▶  5. Personal Server returns
   → structured JSON                 user data over TLS

The Data Portability Protocol defines how users collect data from platforms, store it under their control (on-device or hosted), and grant third-party apps scoped access. This SDK handles session creation, cryptographic request signing, polling, and data fetching. You write three function calls; the protocol handles the rest.

Getting started

The fastest way to get up and running is with the examples/nextjs-starter — a complete working app which uses the development environment and has full flow of data portability wired up:

git clone https://github.com/vana-com/vana-connect.git
cd vana-connect/examples/nextjs-starter
cp .env.local.example .env.local

Use the pre-registered dev key in .env.local. Note that this private key is ONLY for testing and works only with a testing Vana environment.

VANA_PRIVATE_KEY=0x3c05ac1a00546bc0b1b8d3a11fb908409005fac3f26d25f70711e4f632e720d3
APP_URL=http://localhost:3001

Install and run

pnpm install
pnpm dev

Note that while testing this example app, you should have a development version of the DataConnect app.

There is one caveat in development: the deep-link for DataConnect app doesn't open the dev version of the app. This means that when testing your app from the end user perspective, once you see this screen:

Instead of clicking the "Launch DataConnect" button, you should right-click on it and copy its address. The address will be something like vana://connect?sessionId=....

Then, in your dev version of DataConnect (likely built from the main branch) you will see a place to copy the link in the right-bottom corner of the app:


Manual integration

If you prefer to integrate the SDK into an existing project, follow the steps below.

Installation

pnpm add @opendatalabs/connect

Package manager

This repo is pnpm-only for local development and examples. Use pnpm commands, not npm.

Prerequisites

First, register your app in the Developer Portal. You will need to provide the URL where your app will be deployed, and then be given a private key after registration.

Quickstart

1. Create a session (server)

import { connect } from "@opendatalabs/connect/server";

const session = await connect({
  privateKey: process.env.VANA_APP_PRIVATE_KEY as `0x${string}`,
  scopes: ["chatgpt.conversations"],
  webhookUrl: "https://yourapp.com/api/webhook", // optional, data can be pushed to a web hook after a grant is approved
  appUserId: "yourapp-user-42", // optional: correlate your app user with the data they provided
});

// Return to your frontend:
// session.sessionId  — used for polling
// session.connectUrl — opens the Vana account page → launches DataConnect
// session.expiresAt  — ISO 8601 expiration

2. Poll for user approval (client)

import { useVanaConnect } from "@opendatalabs/connect/react";

function ConnectData({ sessionId }: { sessionId: string }) {
  const { connect, status, grant, connectUrl } = useVanaConnect();

  useEffect(() => {
    connect({ sessionId });
  }, [sessionId]);

  if (status === "waiting" && connectUrl) {
    return <a href={connectUrl}>Connect your data</a>;
  }
  if (status === "approved" && grant) {
    // grant.grantId, grant.userAddress, grant.scopes are available
    return <p>Connected.</p>;
  }
  return <p>{status}</p>;
}

Or use the pre-built button:

import { ConnectButton } from "@opendatalabs/connect/react";

<ConnectButton
  sessionId={sessionId}
  onComplete={(grant) => saveGrant(grant)}
  onError={(err) => console.error(err)}
/>;

3. Fetch user data (server)

import { getData } from "@opendatalabs/connect/server";

const data = await getData({
  privateKey: process.env.VANA_APP_PRIVATE_KEY as `0x${string}`,
  grant, // GrantPayload from step 2
});

// Record<string, unknown> keyed by scope
const conversations = data["chatgpt.conversations"];

Web App Manifest

The DataConnect App verifies your identity by fetching your manifest. Use signVanaManifest() to generate it:

import { signVanaManifest } from "@opendatalabs/connect/server";

// In your manifest route handler (e.g. Next.js /manifest.json/route.ts):
const vanaBlock = await signVanaManifest({
  privateKey: process.env.VANA_APP_PRIVATE_KEY as `0x${string}`,
  appUrl: "https://yourapp.com",
  privacyPolicyUrl: "https://yourapp.com/privacy",
  termsUrl: "https://yourapp.com/terms",
  supportUrl: "https://yourapp.com/support",
  webhookUrl: "https://yourapp.com/api/webhook",
});

const manifest = {
  name: "Your App",
  short_name: "YourApp",
  start_url: "/",
  display: "standalone",
  vana: vanaBlock, // signed identity block
};

Make sure your HTML includes <link rel="manifest" href="/manifest.json">.

Connectors

Available data connectors and their scopes (schema definitions): vana-com/data-connectors/schemas

API Reference

Entrypoints

| Import | Environment | Exports | | ------------------------------ | ----------- | ----------------------------------------------------------------- | | @opendatalabs/connect/server | Node.js | connect(), getData(), signVanaManifest(), low-level clients | | @opendatalabs/connect/react | Browser | useVanaConnect(), useVanaData(), ConnectButton | | @opendatalabs/connect/core | Universal | Types, ConnectError, constants |

connect(config): Promise<SessionInitResult>

Creates a session on the Session Relay. Returns sessionId, connectUrl, and expiresAt.

| Param | Type | Required | Description | | ------------ | ------------------- | -------- | ---------------------------------------------------------------------- | | privateKey | `0x${string}` | Yes | Builder private key | | scopes | string[] | Yes | Data scopes to request | | webhookUrl | string | No | Public HTTPS URL for grant event notifications (localhost is rejected) | | appUserId | string | No | Your app's user ID for correlation |

getData(config): Promise<Record<string, unknown>>

Fetches user data from their Personal Server using a signed grant.

| Param | Type | Required | Description | | ------------ | ------------------- | -------- | ---------------------------- | | privateKey | `0x${string}` | Yes | Builder private key | | grant | GrantPayload | Yes | Grant from the approval step |

useVanaConnect(config?): UseVanaConnectResult

React hook that polls the Session Relay and manages connection state.

const { connect, status, grant, error, connectUrl, reset } = useVanaConnect();

status transitions: idleconnectingwaitingapproved | denied | expired | error

GrantPayload

Returned when a user approves access:

interface GrantPayload {
  grantId: string; // on-chain permission ID
  userAddress: string; // user's wallet address
  builderAddress: string; // your registered address
  scopes: string[]; // approved data scopes
  serverAddress?: string; // user's Personal Server
  appUserId?: string; // your app's user ID (if provided)
}

Low-level clients

For full control over individual protocol interactions:

import {
  createRequestSigner, // Web3Signed header generation
  createSessionRelay, // Session Relay HTTP client
  createDataClient, // Data Gateway HTTP client
} from "@opendatalabs/connect/server";

License

MIT