Skip to content

[Docs] Add Vault SDK documentation and guides #7054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions apps/portal/src/app/vault/sdk/api-reference/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# API Reference

This section lists every exported function from **@thirdweb-dev/vault-sdk** grouped by broad capability. All functions are fully typed – hover in your editor for exact type information.

---

## 1. Client utilities

| Function | Description |
| --- | --- |
| `createVaultClient({ secretKey })` | Uses your project secret key to establish a connection to your Vault instance and returns a `VaultClient`. Create **one** client per Vault instance and reuse it. |
| `ping({ client, request })` | Health-check endpoint mainly used in examples and tests. Returns the current server time. |

```ts
const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });
await ping({ client, request: { message: "pong?" } });
```

---

## 2. Service Accounts

| Function | When to use |
| --- | --- |
| `createServiceAccount({ request })` | Bootstrap a brand-new Vault. Returns the **admin key** and **rotation code**. _Run once during provisioning_. |
| `getServiceAccount({ request })` | Retrieve metadata for the current service account. Requires **admin key** or a token with `serviceAccount:read` policy. |
| `rotateServiceAccount({ request })` | Rotate (invalidate) the admin key **and** all existing access tokens in a single atomic operation. Authenticate with the **rotation code**. |

Comment on lines +24 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix function signature documentation in Service Accounts section.
The table lists createServiceAccount({ request }), getServiceAccount({ request }), and rotateServiceAccount({ request }), but the example and actual SDK require passing { client, request }. Update the table entries to reflect the correct signature including client.

🤖 Prompt for AI Agents
In apps/portal/src/app/vault/sdk/api-reference/page.mdx around lines 24 to 28,
the function signatures in the Service Accounts section incorrectly list only `{
request }` as parameters. Update each function signature in the table to include
both `{ client, request }` to match the actual SDK usage and examples.

Example – rotate an account after a key leak:

```ts
await rotateServiceAccount({
client,
request: {
auth: { rotationCode: process.env.VAULT_ROTATION_CODE! },
},
});
```

---

## 3. EOAs (Wallets)

| Function | Purpose |
| --- | --- |
| `createEoa` | Create a new EOA (wallet) inside the Vault. Optionally attach arbitrary `metadata` for later querying. |
| `listEoas` | Pagination-aware listing with optional metadata filters. |
| `signTransaction` | Ask the Vault to sign an EVM transaction (legacy, 2930, 1559, 4844 or 7702). |
| `signMessage` | Sign a plain string / hex message. |
| `signTypedData` | Sign EIP-712 typed data with full generic type safety. |
| `signAuthorization` | Sign an [`Authorization`](#authorization) struct used by some L2s / account-abstraction schemes. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #authorization anchor link doesn't have a corresponding target in the document. Either add a section explaining the Authorization struct with the proper anchor ID, or remove the link formatting from the reference. This will prevent users from encountering a broken link when they click on it.

Suggested change
| `signAuthorization` | Sign an [`Authorization`](#authorization) struct used by some L2s / account-abstraction schemes. |
| `signAuthorization` | Sign an `Authorization` struct used by some L2s / account-abstraction schemes. |

Spotted by Diamond

Is this helpful? React 👍 or 👎 to let us know.

| `signStructuredMessage` | Sign EIP-4337 user-operations (v0.6 & v0.7). |

```ts
// sign a 1559 tx
import { parseTransaction, signTransaction } from "@thirdweb-dev/vault-sdk";

const tx = parseTransaction({
to: "0x...",
value: 0n,
chainId: 1,
maxFeePerGas: 30n * 10n ** 9n,
maxPriorityFeePerGas: 1n * 10n ** 9n,
gasLimit: 21_000,
});

await signTransaction({
client,
request: {
auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
options: { from: "0xEoaAddress", transaction: tx },
},
});
```

> **Note**: `parseTransaction` is a convenience helper that normalises user-supplied objects – you can also build the canonical tx object yourself.

---

## 4. Access Tokens

| Function | Purpose |
| --- | --- |
| `createAccessToken` | Mint a **base token** scoped by policies & metadata. Requires **admin key**. |
| `createSignedAccessToken` | Pure-client helper that turns a *base* token into a short-lived, signed JWT (prefixed with `vt_sat_`). No server round-trip required. |
| `listAccessTokens` | List existing tokens with pagination and optional metadata filters. |
| `revokeAccessToken` | Immediately invalidate a token (or all derived signed tokens) by `id`. |

```ts
// Derive a time-boxed signed token for a serverless function
const sat = await createSignedAccessToken({
vaultClient: client,
baseAccessToken: process.env.VAULT_BASE_TOKEN!,
additionalPolicies: [
{ type: "eoa:signMessage", chainId: 1, messagePattern: "^0x.*" },
],
expiryTimestamp: Math.floor(Date.now() / 1000) + 60 * 5, // 5 min
});
```

---

## 5. Utilities

| Function | Notes |
| --- | --- |
| `parseTransaction` | Normalises user input into a canonical `EthereumTypedTransaction` (supports Legacy, 2930, 1559, 4844, 7702). Throws `ParseTransactionError` on invalid input. |
| `ParseTransactionError` | Custom error class thrown by the above helper. |

```ts
try {
parseTransaction({ gas: 100_000 });
} catch (err) {
if (err instanceof ParseTransactionError) {
console.error(err.message);
}
}
```

---

### Types

All request & response shapes are exported as TypeScript types so you can easily model higher-level abstractions:

```ts
import type { CreateEoaPayload, SignMessagePayload, PolicyComponent } from "@thirdweb-dev/vault-sdk";
```

Refer to the generated `.d.ts` files for the complete list.
105 changes: 105 additions & 0 deletions apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Guide – Managing Access Tokens

Access tokens let you delegate finely-scoped permissions to services, cron jobs or external partners without sharing the admin key.

This guide covers:

1. Creating a **base** access token (server-side)
2. Deriving short-lived **signed** tokens client-side
3. Listing and revoking tokens

---

## 1. Create a base token

Base tokens are created **once** and stored securely (e.g. in your secrets manager). They cannot be scoped by expiry – instead you define *policies* that control which operations are allowed.

```ts
import { createVaultClient, createAccessToken } from "@thirdweb-dev/vault-sdk";

const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });

const res = await createAccessToken({
client,
request: {
auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
options: {
policies: [
{
type: "eoa:signMessage",
allowlist: ["0xEoaAddress"],
messagePattern: "^0x.*", // only allow hex messages
},
],
expiresAt: new Date("2030-01-01").toISOString(),
metadata: { env: "prod", owner: "backend" },
},
},
});

console.log("base token", res.data.accessToken);
```
Comment on lines +17 to +41
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Close the code fence for the base token example
The opening ```ts block at line 17 is not closed, which will break MDX parsing. Add a closing fence after the console.log call.

   console.log("base token", res.data.accessToken);
+  ```
🤖 Prompt for AI Agents
In apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx between lines 17
and 41, the TypeScript code block starting with ```ts is not closed, causing MDX
parsing errors. Add a closing code fence ``` immediately after the console.log
statement to properly close the code block.


---

## 2. Create a signed access token (JWT)

A **signed access token (SAT)** is a JWT created entirely on the client side. You derive it from a base token, embed additional policies and set a short expiry.

```ts
import { createSignedAccessToken } from "@thirdweb-dev/vault-sdk";


const sat = await createSignedAccessToken({
vaultClient: client,
baseAccessToken: process.env.BASE_ACCESS_TOKEN,

additionalPolicies: [
{ type: "eoa:signMessage", chainId: 1 },
],
expiryTimestamp: Math.floor(Date.now() / 1000) + 300, // 5 minutes
});

// Prefix: vt_sat_<JWT>
console.log(sat);
Comment on lines +49 to +64
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Close the code fence for the signed access token (SAT) example
The SAT snippet starts with ts but lacks a closing fence. Add it right after the console.log(sat); to ensure proper rendering.

   console.log(sat);
+  ```
🤖 Prompt for AI Agents
In apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx around lines 49
to 64, the TypeScript code block for the signed access token example starts with
a ```ts fence but is missing the closing ``` fence. Add the closing ``` fence
immediately after the line containing console.log(sat); to properly close the
code block and ensure correct markdown rendering.

```

Send SATs to un-trusted environments (browser, serverless) – they only work until the expiry timestamp and can be revoked centrally by revoking their base token.

---

## 3. List & revoke

```ts
import { listAccessTokens, revokeAccessToken } from "@thirdweb-dev/vault-sdk";

// List the first 10 tokens created by "backend"
const list = await listAccessTokens({
client,
request: {
auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
options: { page: 1, pageSize: 10 },
},
});

const tokenId = list.data.items[0].id;

// Revoke it
await revokeAccessToken({
client,
request: {
auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
options: { id: tokenId },
},
});
```

Once revoked, **all signed tokens derived** from the base are automatically invalidated.

---

### Best practices

1. **Never ship base tokens to browsers** – always derive SATs.
2. **Keep expiries short** (minutes) for web-apps and serverless functions.
3. **Scope by metadata** to share the same policies across many EOAs.
75 changes: 75 additions & 0 deletions apps/portal/src/app/vault/sdk/guides/creating-eoas/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Guide – Creating & Managing EOAs

This guide walks you through creating your first Externally Owned Account (EOA) inside the Vault and querying it later.

## Prerequisites

- A running Vault instance.
- The **admin key** or a token with the `eoa:create` / `eoa:read` policies.
- The Vault SDK installed (see Installation).

---

## 1. Create a new EOA

```ts
import { createVaultClient, createEoa } from "@thirdweb-dev/vault-sdk";

const client = await createVaultClient({
secretKey: "PROJECT_SECRET_KEY",
});

const res = await createEoa({
client,
request: {
auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
options: {
metadata: {
team: "treasury",
purpose: "eth-cold-storage",
},
},
},
});

if (!res.success) throw new Error(res.error.message);

console.log("EOA address", res.data.address);
```

### Metadata

`metadata` accepts arbitrary key-value pairs that can later be used for filtering (`listEoas`) or for access-token policies.

---

## 2. Listing EOAs

```ts
import { listEoas } from "@thirdweb-dev/vault-sdk";

const list = await listEoas({
client,
request: {
auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
options: {
page: 1,
pageSize: 20,
},
},
});

for (const eoa of list.data.items) {
console.log(eoa.address, "metadata:", eoa.metadata);
}
```

You can build richer UIs by using the pagination data (`page`, `pageSize`, `totalRecords`).

---

## 3. Best practices

1. **Group wallets via metadata** – e.g. `{ env: "prod" }`, `{ team: "ops" }`.
2. **Use access tokens for app-specific actions** – never ship the admin key to client-side code.
3. **Rotate when you onboard/offboard admins** – see the rotation guide.
Loading
Loading