open-index/open-npm huggingface dataset:
npm package: @relaycorp/awala-endpoint-internet
Description: JS library to make it easier for a server-side app to exchange messages with the Awala Internet Endpoint
Author: Relaycorp, Inc.
Latest version: 1.1.9

# `@relaycorp/awala-endpoint-internet`

High-level JS library to process [Awala Internet Endpoint](https://docs.relaycorp.tech/awala-endpoint-internet/)-compatible [CloudEvents](https://www.npmjs.com/package/cloudevents).

## Convert incoming CloudEvent to service message

To convert an incoming _service message_ wrapped in a `CloudEvent`, simply call `makeIncomingServiceMessage`.

For example, the following [Fastify](https://fastify.dev) route accepts CloudEvents in [binary mode](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/http-protocol-binding.md#31-binary-content-mode) and the converts them to service messages:

```typescript
import { CloudEventV1, HTTP } from 'cloudevents';
import type { FastifyInstance, FastifyPluginOptions } from 'fastify';

export async function registerEventReceiver(server: FastifyInstance): Promise<void> {
  // Accept any content type
  server.removeAllContentTypeParsers();
  server.addContentTypeParser('*', { parseAs: 'buffer' }, (_req, payload, next) => {
    next(null, payload);
  });

  server.post('/', async (request, reply) => {
    let event: CloudEventV1<Buffer>;
    try {
      event = HTTP.toEvent({ headers: request.headers, body: request.body });
    } catch (err) {
      // Malformed CloudEvent
      return reply.status(400).send({ reason: err.message });
    }

    const message = makeIncomingServiceMessage(event);
    request.log.info({ parcelId: message.parcelId }, 'Incoming service message');

    return reply.status(204).send();
  });
}
```

## Convert outgoing service message to CloudEvent

To convert an outgoing _service message_ to a `CloudEvent`, simply call `makeOutgoingCloudEvent`.

For example:

```typescript
import { makeOutgoingCloudEvent, OutgoingServiceMessage } from '@relaycorp/awala-endpoint-internet';

const outgoingServiceMessage: OutgoingServiceMessage = {
  recipientId: '<Insert Awala endpoint id of recipient>',
  contentType: 'application/vnd.your-company.your-service.Greeting',
  data: Buffer.from('Hello, world!'),
};
const outgoingEvent = makeOutgoingCloudEvent(outgoingServiceMessage);
```

Finally, send the `outgoingEvent` to the Awala Internet Endpoint using your [cloudevents](https://www.npmjs.com/package/cloudevents) emitter. For example:

```typescript
import { httpTransport, emitterFor } from 'cloudevents';

const emit = emitterFor(httpTransport('https://cloudevents-broker.com'));
emit(event);
```

## API documentation

See [API documentation](https://docs.relaycorp.tech/awala-endpoint-internet-js/).
npm package: @relaycorp/awala-keystore-mongodb
Description: MongoDB-based Certificate and Public Key Store for Awala
Author: Relaycorp, Inc.
Latest version: 1.1.45

# @relaycorp/awala-keystore-mongodb

MongoDB-based Certificate and Public Key Store for Awala in JavaScript.

## Install

This library is available on NPM and the latest version can be installed as follows:

```shell
npm i @relaycorp/awala-keystore-mongodb
```
npm package: @relaycorp/eslint-config
Description: ESLint configuration for all Relaycorp projects
Author: Relaycorp, Inc.
Latest version: 2.0.99

# `@relaycorp/eslint-config`

ESLint configuration for all Relaycorp JS projects.

It's utterly insane we have to create a repo and NPM package just for this, but ESLint requires a dedicated NPM module, so we couldn't just add the configuration to [`shared-config`](https://github.com/relaycorp/shared-config).
npm package: @relaycorp/keystore-db
Description: TypeORM-based Private and Public Key Store extension for Awala in JavaScript
Author: Relaycorp, Inc.
Latest version: 1.5.65

# @relaycorp/keystore-db

[TypeORM](https://typeorm.io)-based Private and Public Key Store extension for Node.js-based applications implementing Awala.

This library is meant for desktop apps as it doesn't do encryption at rest. Use [@relaycorp/keystore-vault](https://www.npmjs.com/package/@relaycorp/keystore-vault) for a Vault-backed keystore that can be used in server-side apps.

## Install

This library is available on NPM and the latest version can be installed as follows:

```shell
npm i @relaycorp/keystore-db
```
npm package: @relaycorp/keystore-vault
Description: Vault-based Private Key Store extension for server-side, Node.js-based applications implementing Relaynet
Author: Relaycorp, Inc.
Latest version: 2.0.27
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# keystore-vault-js

[Vault](https://www.vaultproject.io)-based Private Key Store extension for server-side, Node.js-based applications implementing Relaynet -- For example, public endpoints.

## Install

This library is available on NPM and the latest version can be installed as follows:

```shell
npm i @relaycorp/keystore-vault
```

## Usage

### Initialisation

Once you've configured Vault, you need to initialise `VaultPrivateKeyStore` with the following arguments:

- `vaultUrl`: The URL to Vault. For example, `https://vault.local:8200`.
- `vaultToken`: The auth token.
- `kvPath`: The path to the KV Secrets Engine. Only Version 2 of the engine is supported.

### Adding an identity key

To add an identity key for your own node, use `VaultPrivateKeyStore.saveNodeKey();`. For example:

```typescript
await keyStore.saveNodeKey(identityKeyPair.privateKey, identityCertificate);
```

**Make sure to store the output of `identityCertificate.getSerialNumber()`** because you'll need that identifier to retrieve the private key later.

### Adding an initial session key

To add an initial session key for your own node, use `VaultPrivateKeyStore.saveInitialSessionKey();`. For example:

```typescript
await keyStore.saveInitialSessionKey(sessionKeyPair.privateKey, sessionKeyId);
```

### Signing a RAMF message

To sign a RAMF message, such as a parcel, retrieve the identity key and pass it to the `RAMFMessage.serialize()` method. For example:

```typescript
const privateKey = await keyStore.fetchNodeKey(IDENTITY_KEY_ID);
const parcelSerialized = await parcel.serialize(privateKey);
```

### Decrypting a RAMF message payload

To decrypt the payload of a RAMF message -- for example, to extract the service message from a parcel -- you should simply pass the key store instance to `RAMFMessage.unwrapPayload()`. For example:

```typescript
const serviceMessage = await parcel.unwrapPayload(keyStore);
```

## API documentation

The API documentation can be found on [docs.relaycorp.tech](https://docs.relaycorp.tech/keystore-vault-js/).
npm package: @relaycorp/object-storage
Description: Node.js client for object stores like AWS S3, GCP GCS or Minio
Author: Relaycorp, Inc.
Latest version: 1.4.113

# @relaycorp/object-storage

This library allows you to interact with major object storage backends (e.g., Amazon S3) using a unified interface.

## Install

Releases are automatically pushed to [NPM](https://www.npmjs.com/package/@relaycorp/object-storage). For example, to get the latest release, run:

```
npm install @relaycorp/object-storage
```

## Supported backends

| Backend | Name | SDK used internally | Access/secret key support                                                                                                                                        |
| --- | --- | --- | --- |
| Amazon S3 | `s3` | AWS | Optional |
| Google Cloud Storage (GCS) | `gcs` | GCP | Unsupported. Use alternative authentication methods instead, like [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity). |
| Minio | `minio` | AWS | Required |

## Supported operations

- Get object (along with its metadata).
- Create/update object (along with its metadata).
- Delete object.
- List objects under a given prefix. Pagination is handled automatically: We return an iterable and retrieve the next page lazily.

We welcome PRs to support additional operations, as long as each new operation is supported across all backends in a normalised way, and has unit and functional tests.

## Example

```typescript
import { initObjectStoreClient } from '@relaycorp/object-storage';

async function main(): Promise<void> {
  const client = initObjectStoreClient(
    process.env.STORE_BACKEND,
    process.env.STORE_ENDPOINT,
    process.env.STORE_ACCESS_KEY,
    process.env.STORE_SECRET_KEY,
  );

  for await (const objectKey of client.listObjectKeys("prefix/", process.env.STORE_BUCKET)) {
    console.log("- ", objectKey)
  }
}
```

## API documentation

The API documentation can be found on [docs.relaycorp.tech](https://docs.relaycorp.tech/object-storage-js/).

## Contributing

We love contributions! If you haven't contributed to a Relaycorp project before, please take a minute to [read our guidelines](https://github.com/relaycorp/.github/blob/master/CONTRIBUTING.md) first.
npm package: @relaycorp/pino-cloud
Description: Pino integration for cloud logging services like Google Cloud Logging
Author: Relaycorp, Inc.
Latest version: 1.0.28

# @relaycorp/pino-cloud

This library generates [Pino](https://getpino.io) configuration to format log entries in such a way that they can be properly ingested by cloud logging services such as those on Google Cloud Platform (GCP).

At this point, only GCP's Cloud Logging and Error Reporting services are supported, but we'd welcome any PRs to support additional targets, such as Elastic Search or AWS CloudWatch Logs.

## Install

Releases are automatically pushed to [NPM](https://www.npmjs.com/package/@relaycorp/pino-cloud). For example, to get the latest release, run:

```shell
npm install @relaycorp/pino-cloud
```

## Usage

This library simply returns a configuration object for Pino, which you augment before passing to Pino. For example:

```typescript
import { getPinoOptions } from '@relaycorp/pino-cloud';

const LOGGER = pino({
  ...getPinoOptions(process.ENV.LOGGING_TARGET, {
    name: 'your-app-name',
    version: '1.0.2',
  }),
  level: 'debug',
});
```

If the environment variable `LOGGING_TARGET` is unset, an empty object is returned.

## Targets

### `gcp`

`error` and `fatal` logs are augmented to include Error Reporting fields, like the name and version of your app.

Additionally, if the log contains an `err` field that is an instance of `Error`, its stack trace will be added to the field `stack_trace` -- Where Error Reporting expects to find it.

## API documentation

The API documentation can be found on [docs.relaycorp.tech](https://docs.relaycorp.tech/pino-cloud-js/).

## Contributing

We love contributions! If you haven't contributed to a Relaycorp project before, please take a minute to [read our guidelines](https://github.com/relaycorp/.github/blob/master/CONTRIBUTING.md) first.
npm package: @relaycorp/relaynet-core
Description: Relaynet core library
Author: Relaycorp, Inc.
Latest version: 1.88.2

# relaynet-core-js

This library implements the core of [Awala](https://awala.network) and is meant to be used by anyone using the network from a Node.js application. [Read the docs online](https://docs.relaycorp.tech/relaynet-core-js/).

Please note that this documentation is mostly incomplete because the interface exposed by this library is changing rapidly as of this writing.

## Install

`@relaycorp/relaynet-core` requires Node.js v12 or newer, and the latest stable release can be installed as follows:

```
npm install --save @relaycorp/relaynet-core
```

## Specs supported

This library supports the following Awala specs:

- [RS-000 (Awala Core)](https://specs.awala.network/RS-000).
- [RS-001 (RAMF v1)](https://specs.awala.network/RS-001).
- [RS-002 (Awala PKI)](https://specs.awala.network/RS-002).
- [RS-003 (Awala Channel Session Protocol)](https://specs.awala.network/RS-003).
- [RS-018 (Awala Cryptographic Algorithms, Version 1)](https://specs.awala.network/RS-018). In addition to the required algorithms, the following are also supported:
  - Hashing functions: SHA-384 and SHA-512.
  - Ciphers: AES-192 and AES-256.
  - ECDH curves: P-384 and P-521.

## Updates

Releases are automatically published on GitHub and NPM, and the [changelog can be found on GitHub](https://github.com/relaycorp/relaynet-core-js/releases). This project uses [semantic versioning](https://semver.org/).
npm package: @relaycorp/relaynet-pohttp
Description: Relaynet PoHTTP binding
Author: Relaycorp, Inc.
Latest version: 1.7.87

# Node.js PoHTTP binding implementation

This is the client-side Node.js implementation of the Relaynet [Parcel Delivery over HTTP (PoHTTP) binding](https://specs.relaynet.link/RS-007).

Since PoHTTP establishes an [_external Parcel Delivery Connection (PDC)_](https://specs.relaynet.link/RS-000#external-pdc), this library is only relevant to developers implementing a gateway (like [Relaycorp's](https://github.com/relaycorp/relaynet-gateway-desktop)) or a [public endpoint](https://specs.relaynet.link/RS-000#addressing).

## Install

This library requires Node.js v10 or newer, and can be installed as follows:

```
npm install @relaycorp/relaynet-pohttp
```

## Use

As the client-side implementation of an external PDC, the only operation supported by this library is the delivery of parcels.

relaynet-pohttp-js is meant to be used with the [core library](https://www.npmjs.com/package/@relaycorp/relaynet-core). For example, this is how a relay would deliver a parcel to the public endpoint `rne+https://ping.relaycorp.tech`:

```javascript
import { deliverParcel } from '@relaycorp/relaynet-pohttp';

async function main() {
  // `parcelSerialized` is the ArrayBuffer representation of the parcel as a RAMF message
  const parcelSerialized = await yourFunctionToRetrieveTheParcel();

  await deliverParcel('ping.relaycorp.tech', parcelSerialized);
}
```

By default, a timeout of 3 seconds will be used and up to 3 consecutive redirects would be followed. `deliverParcel()` takes an optional `options` argument to customize these and other options.

TypeScript type declarations are included with this library.

## Use in integration or functional tests

Per the Relaynet specs, bindings like PoHTTP must be used over TLS, but this validation can be turned off in test suites that send requests to a mock HTTP server by passing the options `useTls=false` to `deliverParcel()`.
npm package: @relaycorp/relaynet-poweb
Description: Awala PoWeb binding
Author: Relaycorp, Inc.
Latest version: 1.6.35

# PoWeb JavaScript Client

Client-side JavaScript library for the [PoWeb binding](https://specs.awala.network/RS-016). This library will be used by:

- Desktop apps (to communicate with their local, private gateway). However, most app developers will want to use a higher-level library (yet to be built as of this writing).
- A desktop gateway like [the one by Relaycorp](https://github.com/relaycorp/relaynet-gateway-desktop) (to communicate with its public gateway over the Internet).
npm package: @relaycorp/shared-config
Description: Shared development and CI configuration across projects
Author: Relaycorp, Inc.
Latest version: 1.15.1

# shared-config

Shared development and CI configuration across projects.

This includes TSLint configuration. The configuration for ESLint, which supersedes TSLint, can be found in [`@relaycorp/eslint-config`](https://github.com/relaycorp/eslint-config).

See also: [shared-workflows](https://github.com/relaycorp/shared-workflows).
npm package: @relaycorp/ws-mock
Description: Mock client and server to unit test the NPM package 'ws'
Author: Relaycorp, Inc.
Latest version: 5.2.14

# @relaycorp/ws-mock

Mock client and server to unit test servers and clients powered by [`ws`](https://www.npmjs.com/package/ws).

## Install

```
npm install @relaycorp/ws-mock
```

## Using the mock client

You'd use a mock client when you need to test a server. You should initialise `MockClient` by passing the `ws` server to be tested and then call `client.connect()` to initiate the connection. From that point you can interact with the server. For example:

```typescript
test('Challenge should be sent as soon as client connects', async () => {
  const client = new MockClient(wsServer);
  await client.connect();

  const challengeSerialized = await client.receive();
  expect(challengeSerialized).toBeInstanceOf(ArrayBuffer);
});
```

You'll find real-world examples in [relaycorp/relaynet-internet-gateway](https://github.com/relaycorp/relaynet-internet-gateway/search?l=TypeScript&q=%22%40relaycorp%2Fws-mock%22) and [relaycorp/awala-gateway-desktop](https://github.com/relaycorp/awala-gateway-desktop/search?l=TypeScript&q=%22%40relaycorp%2Fws-mock%22).

## Using the mock server

You'd use a mock server when you need to test a client. You basically need to initialise `MockServer` and replace the default export from `ws` with a mock WebSocket. Here's an example with Jest:

```typescript
let mockServer: MockServer;
beforeEach(() => {
  mockServer = new MockServer();
});
jest.mock('ws', () => ({
  __esModule: true,
  default: jest.fn().mockImplementation(() => mockServer.client),
}));

test('Server message should be played back', async () => {
  const clientUnderTest = new ClientUnderTest();
  const messageToEcho = 'foo';

  await mockServer.use(
    clientUnderTest.connectToServerAndInteractWithIt(),
    async () => {
      await mockServer.send(messageToEcho);

      // Check that the client sent the message back to the server:
      const clientResponse = await mockServer.receive();
      expect(clientResponse).toEqual(messageToEcho);
    },
  );
});
```

You'll find [real-world examples in relaycorp/relaynet-poweb-js](https://github.com/relaycorp/relaynet-poweb-js/search?l=TypeScript&q=%22%40relaycorp%2Fws-mock%22).

## Using streams

When using streams in the unit under test, make sure to mock the `createWebSocketStream` function in `ws`. Here's an example with Jest:

```javascript
import { createMockWebSocketStream } from '@relaycorp/ws-mock';
import WebSocket from 'ws';

jest
  .spyOn(WebSocket, 'createWebSocketStream')
  .mockImplementation(createMockWebSocketStream);
```
npm package: @relayerfi/widget-kit-core
Description: Core logic for Relayer.fi widgets
Author: Relayer.fi
Latest version: 0.1.0

# @relayerfi/widget-kit-core

[![npm version](https://img.shields.io/npm/v/@relayerfi/widget-kit-core.svg)](https://www.npmjs.com/package/@relayerfi/widget-kit-core)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Framework-agnostic runtime for Relayer widgets. Handles widget directory management, metadata fetching, URL security classification, and proxy communication.

This package is used internally by `@relayerfi/widget-kit-react`. Most integrators should install that package instead.

## Install

```bash
pnpm add @relayerfi/widget-kit-core
```

## What It Does

- **WidgetDirectory** - Classifies widget URLs as trusted, malicious, or unknown
- **Metadata fetching** - Resolves action metadata from widget URLs via the Relayer proxy
- **Error types** - Structured `WidgetError` with factory methods
- **Utilities** - URL formatting, client-key management, proxy endpoint builders

## Key Exports

```typescript
import { WidgetDirectory, WidgetError, PROXY_URL } from '@relayerfi/widget-kit-core';

const directory = WidgetDirectory.getInstance();
await directory.init();
const state = directory.lookup('https://app.relayer.fi');
```

## Related Packages

| Package | Purpose |
|---------|---------|
| [`@relayerfi/action-kit`](https://www.npmjs.com/package/@relayerfi/action-kit) | Action type definitions, validators, executors |
| [`@relayerfi/widget-kit-react`](https://www.npmjs.com/package/@relayerfi/widget-kit-react) | React components for rendering widgets |

## License

MIT
npm package: @relayerfi/widget-kit-react
Description: [![npm version](https://img.shields.io/npm/v/@relayerfi/widget-kit-react.svg)](https://www.npmjs.com/package/@relayerfi/widget-kit-react) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
Author: Relayer.fi
Latest version: 0.1.0

# @relayerfi/widget-kit-react

[![npm version](https://img.shields.io/npm/v/@relayerfi/widget-kit-react.svg)](https://www.npmjs.com/package/@relayerfi/widget-kit-react)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

React components and hooks for rendering Relayer widgets. Embed on-chain actions (swaps, transfers, contract calls) into any React application.

## Install

```bash
pnpm add @relayerfi/widget-kit-react @relayerfi/action-kit @relayerfi/widget-kit-core wagmi viem @tanstack/react-query react react-dom
```

All listed packages are peer dependencies.

## Usage

```tsx
import { Widget, useWagmiAdapter } from '@relayerfi/widget-kit-react';
import { createMetadata } from '@relayerfi/action-kit';
import '@relayerfi/widget-kit-react/index.css';

const metadata = createMetadata({
  url: 'https://myapp.example',
  icon: 'https://example.com/icon.png',
  title: 'Send AVAX',
  description: 'Transfer 0.1 AVAX',
  actions: [
    {
      type: 'transfer',
      label: 'Send 0.1 AVAX',
      to: '0x1234...5678',
      amount: 0.1,
      chains: { source: 43114 },
    },
  ],
});

function MyWidget() {
  const adapter = useWagmiAdapter();

  return (
    <Widget
      metadata={metadata}
      adapter={adapter}
      securityState="trusted"
    />
  );
}
```

Wrap your app with `WagmiProvider` and `QueryClientProvider` before using the adapter.

## Exports

### Components

- `Widget` - Renders an interactive widget from validated action metadata
- `WalletButton` - Wallet connection button

### Hooks

- `useWagmiAdapter()` - Returns a `WidgetAdapter` wired to Wagmi for wallet interactions

### Adapters

- `WidgetAdapter` - Interface for wallet interactions (connect, sign, send)
- `WidgetExtensionAdapter` - Adapter for Chrome extension environments

### Extension Observers

Available via `@relayerfi/widget-kit-react/ext`:

- `setupWidgetObserverEVM` - Detect and render widgets on Twitter/X, YouTube, Twitch
- `setupTwitterObserverEVM`, `setupYoutubeObserverEVM`, `setupTwitchObserverEVM`

## CSS

Import the stylesheet in your entry point:

```typescript
import '@relayerfi/widget-kit-react/index.css';
```

## Related Packages

| Package | Purpose |
|---------|---------|
| [`@relayerfi/action-kit`](https://www.npmjs.com/package/@relayerfi/action-kit) | Action type definitions, validators, executors |
| [`@relayerfi/widget-kit-core`](https://www.npmjs.com/package/@relayerfi/widget-kit-core) | Framework-agnostic runtime (directory, security, proxy) |

## License

MIT
npm package: @relayerjs/core
Description: ORM-agnostic types and contracts for Relayer
Latest version: 0.4.1

# @relayerjs/core

ORM-agnostic types and contracts for [Relayer](../../README.md).

## What's inside

- **FieldType** enum (`Computed`, `Derived`)
- **Operator interfaces** — `StringOperators`, `NumberOperators`, `BooleanOperators`, `DateOperators`, `ArrayOperators`, `RelationOperators`
- **Field definitions** — `ScalarFieldDef`, `RelationFieldDef`, `ComputedFieldDef`, `DerivedFieldDef`
- **Entity registry** — `EntityRegistry`, `EntityMetadata`
- **Query option types** — `FindManyOptions`, `FindFirstOptions`, `CountOptions`, `CreateOptions`, `UpdateOptions`, `DeleteOptions`, `MutationResult`
- **Value types** — `ValueType`, `ScalarValueType`, `ObjectValueType`

## Usage

This package is typically not imported directly. The main adapter package (`@relayerjs/drizzle`) re-exports everything you need:

```ts
import { FieldType } from '@relayerjs/drizzle';
```

If you're building a custom adapter or need core types directly:

```ts
import { EntityRegistry, FieldType } from '@relayerjs/core';
import type { ComputedFieldDef, StringOperators } from '@relayerjs/core';
```

## License

[MIT](../../LICENSE)
npm package: @relayerjs/nestjs-common
Description: Shared NestJS utilities for Relayer — services, hooks, DI, and query primitives
Latest version: 0.0.2

# @relayerjs/nestjs-common

Shared utilities for Relayer's NestJS integrations.

This package contains the core building blocks that both `@relayerjs/nestjs-crud` (REST) and `@relayerjs/nestjs-graphql` (GraphQL) rely on.

Not meant to be used directly in most cases. Install the integration package you need (`nestjs-crud` or `nestjs-graphql`) and it will pull this in as a peer dependency.

## License

MIT
npm package: @relayfile/provider-clerk
Description: Clerk provider for Relayfile
Latest version: 0.1.0

# @relayfile/provider-clerk

Clerk provider for Relayfile with two layers:

- `IntegrationProvider` support for webhook ingestion into Relayfile
- `ConnectionProvider` support for OAuth token lookup and authenticated proxying

It also exposes Clerk-specific convenience methods for users, sessions, organizations, Svix webhook verification, and Clerk JWT/JWKS verification.

## Install

```bash
npm install @relayfile/provider-clerk @relayfile/sdk
```

## Usage

```ts
import { RelayFileClient } from "@relayfile/sdk";
import { ClerkProvider } from "@relayfile/provider-clerk";

const client = new RelayFileClient({
  apiKey: process.env.RELAYFILE_API_KEY!,
});

const clerk = new ClerkProvider(client, {
  secretKey: process.env.CLERK_SECRET_KEY!,
  webhookSecret: process.env.CLERK_WEBHOOK_SECRET,
});

const githubToken = await clerk.getAccessToken("user_123", "oauth_github");

const response = await clerk.proxy({
  method: "GET",
  baseUrl: "https://api.github.com",
  endpoint: "/user",
  connectionId: "user_123",
  headers: {
    "x-clerk-provider": "oauth_github",
  },
});

const users = await clerk.listUsers({ limit: 25, offset: 0 });
console.log(users.totalCount);
```

## Exposed methods

- `getAccessToken(userId, provider)`
- `proxy(request)`
- `ingestWebhook(workspaceId, rawInput)`
- `listUsers()`, `getUser()`, `updateUser()`, `deleteUser()`
- `getUserExternalAccounts()`, `getOAuthToken()`
- `listSessions()`, `getSession()`, `revokeSession()`, `verifySession()`
- `listOrganizations()`, `getOrganization()`, `listOrgMembers()`, `createOrgInvitation()`
- `verifyWebhook(payload, headers)`, `getJWKS()`, `verifyToken(token)`

## Notes

- Pass credentials from environment variables or your secret manager. The provider does not ship any hardcoded Clerk credentials.
- OAuth access tokens are read from `GET /v1/users/{userId}/oauth_access_tokens/{provider}` and the most recent token is used.
- Paginated Clerk list responses are normalized to expose `totalCount` even when Clerk returns `total_count`.
- Webhook verification uses Svix headers: `svix-id`, `svix-timestamp`, and `svix-signature`.
- JWT verification uses Clerk JWKS fetched from `/v1/jwks`.
npm package: @relayfile/provider-n8n
Description: Relayfile connection provider for self-hosted n8n instances.
Latest version: 0.1.0

# @relayfile/provider-n8n

Relayfile connection provider for self-hosted n8n instances.

This package wraps the n8n REST API with two layers:

- A Relayfile-compatible provider class that extends `IntegrationProvider`
- A convenience layer for credentials, workflows, executions, node discovery, and webhook ingestion

## Install

```bash
npm install @relayfile/provider-n8n @relayfile/sdk
```

## Configure n8n

This provider targets self-hosted n8n instances. Set `baseUrl` to your own deployment URL, for example `https://n8n.example.com` or `http://localhost:5678`.

### API key auth

1. Log in to your n8n instance.
2. Go to `Settings > n8n API`.
3. Enable the public API if it is not already enabled.
4. Create an API key and store it in an environment variable such as `N8N_API_KEY`.

### Basic auth

If your self-hosted deployment protects n8n with HTTP basic auth, pass `username` and `password` to the provider instead of an API key. A common local setup looks like:

```bash
export N8N_BASE_URL="http://localhost:5678"
export N8N_BASIC_AUTH_ACTIVE="true"
export N8N_BASIC_AUTH_USER="relay"
export N8N_BASIC_AUTH_PASSWORD="file"
```

## Usage

```ts
import { RelayFileClient } from "@relayfile/sdk";
import { createN8nProvider } from "@relayfile/provider-n8n";

const relayfile = new RelayFileClient({
  baseUrl: process.env.RELAYFILE_BASE_URL!,
  token: process.env.RELAYFILE_TOKEN!,
});

const provider = createN8nProvider(relayfile, {
  baseUrl: process.env.N8N_BASE_URL!,
  apiKey: process.env.N8N_API_KEY,
});

const credentials = await provider.listCredentials({ type: "githubApi" });
const workflow = await provider.activateWorkflow("workflow-123");
const proxyResponse = await provider.proxy({
  method: "GET",
  baseUrl: "https://api.github.com",
  endpoint: "/user",
  connectionId: "credential-123",
});
```

Basic-auth configuration:

```ts
const provider = createN8nProvider(relayfile, {
  baseUrl: process.env.N8N_BASE_URL!,
  username: process.env.N8N_BASIC_AUTH_USER!,
  password: process.env.N8N_BASIC_AUTH_PASSWORD!,
});
```

## Webhooks

n8n Webhook nodes expose both production and test URLs:

- Production: `{N8N_URL}/webhook/{path}`
- Test: `{N8N_URL}/webhook-test/{path}`

`N8nProvider.ingestWebhook()` normalizes the incoming webhook payload and forwards it to Relayfile using a canonical path derived from the normalized event.

## Scripts

```bash
npm run build
npm test
```
npm package: @relayfile/provider-supabase
Description: Relayfile provider for Supabase Auth and Admin API integrations
Latest version: 0.1.0

# @relayfile/provider-supabase

Relayfile provider package for Supabase Auth. It combines the SDK `IntegrationProvider`
contract with a convenience layer for Supabase Admin, token lookup, session refresh,
SSO, MFA, and webhook normalization.

## Install

```bash
npm install @relayfile/provider-supabase @relayfile/sdk
```

## Usage

```ts
import { RelayFileClient } from "@relayfile/sdk";
import { SupabaseProvider } from "@relayfile/provider-supabase";

const client = new RelayFileClient({
  baseUrl: process.env.RELAYFILE_URL!,
  token: process.env.RELAYFILE_TOKEN!,
});

const provider = new SupabaseProvider(client, {
  supabaseUrl: process.env.SUPABASE_URL!,
  serviceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY!,
  anonKey: process.env.SUPABASE_ANON_KEY,
  webhookSecret: process.env.SUPABASE_WEBHOOK_SECRET,
});
```

## Features

- `ingestWebhook(workspaceId, rawInput)`: normalize Supabase auth/database events into Relayfile.
- `proxy(request)`: resolve an OAuth provider token from `user.identities[]` and forward an authenticated API call.
- User management: `listUsers`, `getUser`, `createUser`, `updateUser`, `deleteUser`, `getUserIdentities`, `unlinkIdentity`.
- Token/session helpers: `getAccessToken`, `getProviderToken`, `refreshSession`, `generateLink`, `getSession`.
- Auth admin helpers: `listFactors`, `listSSO`, `createSSOProvider`.
- Webhook helpers: `normalizeSupabaseWebhook`, `verifyWebhook`.

## Security And Auth Modes

- Admin endpoints use `serviceRoleKey` for both `apikey` and `Authorization: Bearer ...`.
- Session refresh and JWT verification use `anonKey` when provided, otherwise they fall back to `serviceRoleKey`.
- The package does not embed credentials; configure `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, and optional keys via environment variables.

## Pagination

- `listUsers({ page, perPage, filter })` forwards Supabase's `page` and `per_page` query params and returns `{ users, page, perPage, total? }`.
- `listSSO({ page, perPage, filter })` forwards the same pagination params to the SSO admin endpoint.

## Proxy Provider Resolution

`ProxyRequest` does not carry a dedicated provider name, so this package resolves it in this order:

1. `x-supabase-provider` request header
2. `provider` query parameter
3. Base URL hostname mapping for common APIs such as GitHub, Slack, Google, Notion, Linear, and Discord

If none of those resolve, `proxy()` throws and asks for `x-supabase-provider`.

## Scripts

- `npm run build`
- `npm run test`
- `npm run typecheck`
npm package: @relayfile/sdk
Description: TypeScript SDK for relayfile — real-time filesystem for humans and agents
Latest version: 0.1.6

# @relayfile/sdk

TypeScript SDK for relayfile — real-time filesystem for humans and agents.

## Install

```bash
npm install @relayfile/sdk
```

## Quick Example

```ts
import { RelayFileClient } from "@relayfile/sdk";

const client = new RelayFileClient({
  baseUrl: "https://api.relayfile.com",
  token: process.env.RELAYFILE_TOKEN ?? ""
});

const workspaceId = "workspace_123";

const tree = await client.listTree(workspaceId, {
  path: "/",
  depth: 2
});

console.log(tree.entries.map((entry) => entry.path));

const file = await client.readFile(workspaceId, "/notes/todo.md");

console.log(file.content);

await client.writeFile({
  workspaceId,
  path: "/notes/todo.md",
  baseRevision: file.revision,
  content: `${file.content}\n- Follow up with SDK publish`,
  contentType: "text/markdown"
});
```

Use a relayfile JWT whose claims include `workspace_id`, `agent_name`, and `aud: ["relayfile"]`. The SDK adds `X-Correlation-Id` automatically for API calls.

## Full Docs

Full documentation is available in the [relayfile docs](https://github.com/AgentWorkforce/relayfile/tree/main/docs).
npm package: @relayfile/webhook-server
Description: Thin Hono webhook receiver for relayfile adapters
Latest version: 0.1.0

# @relayfile/webhook-server

Thin [Hono](https://hono.dev) server for receiving provider webhooks, verifying signatures, and persisting normalized events into relayfile via `RelayFileClient`.

## Install

```bash
npm install @relayfile/webhook-server hono
```

## Usage

```ts
import { GitHubAdapter } from "@relayfile/adapter-github";
import { RelayFileClient } from "@relayfile/sdk";
import { createWebhookServer } from "@relayfile/webhook-server";

const client = new RelayFileClient({ token: process.env.RELAYFILE_TOKEN! });
const provider = { name: "nango", proxy: async () => ({ status: 200, headers: {}, data: {} }), healthCheck: async () => true };
const github = new GitHubAdapter(provider);
const server = createWebhookServer({ client, port: 3456, secrets: { github: process.env.GITHUB_WEBHOOK_SECRET } });
server.register("github", github);
await server.start();
```

`POST /github/webhook` now verifies `x-hub-signature-256`, normalizes the event, computes a VFS path from the registered adapter, and calls `client.ingestWebhook(...)`.

## Supported built-ins

- `github`: HMAC-SHA256 verification via `x-hub-signature-256`
- `slack`: signing secret verification via `x-slack-signature` and `x-slack-request-timestamp`

Adapters can also provide their own `verifySignature` or `normalizeWebhook` hooks.

## API

### `createWebhookServer(options)`

- `client`: `RelayFileClient` used to persist webhook events
- `workspaceId`: relayfile workspace ID, defaults to `"default"`
- `port`: default port for `server.start()`, defaults to `3456`
- `hostname`: default hostname for `server.start()`, defaults to `"0.0.0.0"`
- `adapters`: optional initial adapter map
- `secrets`: provider-to-secret map for signature verification

### `server.register(name, adapter)`

Registers an adapter by provider name. The adapter may expose:

- `computePath(objectType, objectId, payload?)`
- `normalizeWebhook(payload, context)`
- `verifySignature(context)`
- `provider?: ConnectionProvider`

### Route

- `POST /:provider/webhook`

The route returns `404` for unknown providers, `401` for signature failures, `400` for invalid payloads, and `200` with the queued relayfile operation IDs when the webhook is accepted.