Skip to content

VRChat API package focused on abstracting session management.

License

Notifications You must be signed in to change notification settings

enterverse/vrchat

Repository files navigation

vrchat

VRChat API package focused on abstracting session management.

Installation

yarn add @enterlink/vrchat

Usage

Accounts with no totp key must define a ClientOptions#onRequestOtpKey for fetching the relevant otp.

import { Client, CurrentUser, Routes, World } from "@enterlink/vrchat";

const client = new Client({
  email: '[email protected]',
  password: 'some-secret-password',
  totpKey: 'totp-private-key'
});

;(async () => {
  const user = await client.get<CurrentUser>(Routes.currentUser());
  console.log("Logged in as", user.displayName);

  const world = await client.get<World>(Routes.world("wrld_2851d12c-57d0-4754-84cf-aa494ce7a03a"));
  console.log("Found World:", world.name);

  await client.put(Routes.logout());
  console.log("Logged out!");
})().catch(console.error);

Pooled Usage Example

Our specfic scenario demands us having a pool of accounts. You can achieve this with using the pooler. The pooler expects a constructed implementation of StorageAdapter. In this example we will use the Memory Adapter.

It is highly recommended to use an adapter that will persist session states across restarts. VRChat has a limit to how many active sessions an account can have.

import { CurrentUser, Pooler, Routes } from "@enterlink/vrchat";
import { MemoryStorageAdapter } from '@enterlink/vrchat/adapter/memory';

const adapter = new MemoryStorageAdapter([
  {
    email: '[email protected]',
    password: 'some-secret-password',
    totpKey: 'totp-private-key'
  },
  {
    email: '[email protected]',
    password: 'some-secret-password',
    totpKey: 'totp-private-key'
  },
  {
    email: '[email protected]',
    password: 'some-secret-password',
    totpKey: 'totp-private-key'
  }
]);

const pooler = new Pooler(adapter);

;(async () => {
  const users = await pooler.getAll<CurrentUser>(Routes.currentUser());

  for (const user of users) {
    console.log("Logged in as:", user.displayName);
  }

  await pooler.putAll(Routes.logout());
  console.log("Logged out all users");
})().catch(console.error);

Notes

We use otplib internally for generating TOTP codes. I've noticed that on Node.js versions 20 and 21, authentication failures occur because one of otplib's dependencies, thirty-two, uses new Buffer() internally. This results in a Node.js error: TypeError: Cannot read properties of undefined (reading '0'). Since there isn't a straightforward fix for this issue, we are running Node.js v22+ to avoid the problem.

Backlog

  • Implement Prisma adapter for our use case.
  • Prisma adapter optional encryption.
  • Way to select an account to use in pooler.
  • Way to request on all accounts in pooler.
  • Support for accounts all 2fa types (see src/client.ts).
  • Implement all API endpoints (see src/api.ts).
  • Support setting ratelimits.
  • Pooler single account transactions.

About

VRChat API package focused on abstracting session management.

Resources

License

Stars

Watchers

Forks

Packages

No packages published