Skip to content
Closed
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
356 changes: 248 additions & 108 deletions apps/portal/src/app/vault/sdk/api-reference/page.mdx
Original file line number Diff line number Diff line change
@@ -1,130 +1,270 @@
# API Reference
import {
createVaultClient,
ping,
createEoa,
listEoas,
parseTransaction,
signTransaction,
createAccessToken,
} from "@thirdweb-dev/vault-sdk";
import "dotenv/config";
Comment on lines +1 to +10
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Do not import/execute SDK or dotenv in an MDX docs page (leaks secrets, breaks build).

Top-level imports will execute during build/SSR and attempt real network calls. Importing "dotenv/config" in the docs app is especially unsafe and will expose secrets if bundled. Move all runnable code into fenced code blocks; keep the page purely presentational.

Apply this diff to strip runtime imports and start an example section:

-import {
-  createVaultClient,
-  ping,
-  createEoa,
-  listEoas,
-  parseTransaction,
-  signTransaction,
-  createAccessToken,
-} from "@thirdweb-dev/vault-sdk";
-import "dotenv/config";
+{/* The runnable example is provided below as a fenced code block. */}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import {
createVaultClient,
ping,
createEoa,
listEoas,
parseTransaction,
signTransaction,
createAccessToken,
} from "@thirdweb-dev/vault-sdk";
import "dotenv/config";
{/* The runnable example is provided below as a fenced code block. */}
🧰 Tools
🪛 LanguageTool

[grammar] ~1-~1: There might be a mistake here.
Context: import { createVaultClient, ping, createEoa, ...

(QB_NEW_EN)


[grammar] ~8-~8: There might be a mistake here.
Context: ... signTransaction, createAccessToken, } from "@thirdweb-dev/vault-sdk"; import...

(QB_NEW_EN)


[grammar] ~9-~9: There might be a mistake here.
Context: ...Token, } from "@thirdweb-dev/vault-sdk"; import "dotenv/config"; // --- CONFIGUR...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In apps/portal/src/app/vault/sdk/api-reference/page.mdx around lines 1-10,
remove the top-level runtime imports (createVaultClient, ping, createEoa,
listEoas, parseTransaction, signTransaction, createAccessToken and especially
"dotenv/config") so nothing executes at build/SSR; instead add a presentational
"Example" section and place the shown imports and usage inside a fenced code
block (e.g., ```ts ... ```), so the MDX remains purely presentational and no
secrets or network calls occur during build.


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.
// --- CONFIGURACIÓN ---

---
const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
const BASE_TOKEN = process.env.VAULT_BASE_TOKEN!;
Comment on lines +14 to +16
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Secrets in client-visible context; remove BASE_TOKEN (unused).

Do not reference secrets from a docs page; ensure examples instruct running in Node with .env, not inside MDX. Also BASE_TOKEN is never used—drop it from code and docs to avoid confusion.

-const BASE_TOKEN = process.env.VAULT_BASE_TOKEN!;

And remove its mentions in the “.env example” below.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
const BASE_TOKEN = process.env.VAULT_BASE_TOKEN!;
const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
🧰 Tools
🪛 LanguageTool

[grammar] ~14-~14: There might be a mistake here.
Context: ...RET_KEY = process.env.VAULT_SECRET_KEY!; const SIG_TOKEN = process.env.VAULT_SIG_...

(QB_NEW_EN)


[grammar] ~15-~15: There might be a mistake here.
Context: ...IG_TOKEN = process.env.VAULT_SIG_TOKEN!; const BASE_TOKEN = process.env.VAULT_BAS...

(QB_NEW_EN)


## 1. Client utilities
const TARGET_ADDRESS = "0x6561fF4034De957fAFeA20b3aCC5E6E9FEb21aCE";

| 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. |
async function main() {
// 1. Crear cliente del Vault
const client = await createVaultClient({ secretKey: SECRET_KEY });

```ts
const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });
await ping({ client, request: { message: "pong?" } });
```
// 2. Hacer ping al Vault (opcional)
const pingResult = await ping({ client, request: { message: "pong?" } });
console.log("Ping response:", pingResult);

---
// 3. Crear un EOA con metadata que incluya la dirección
const eoa = await createEoa({
client,
request: {
metadata: {
label: "Wallet externa",
externalAddress: TARGET_ADDRESS,
},
},
});
console.log("Nuevo EOA creado (metadatos):", eoa);

## 2. Service Accounts
// 4. Crear una transacción ficticia desde la dirección
const tx = parseTransaction({
to: "0xAbC123456789abcdef123456789abcdef1234567", // dirección de destino ficticia
value: 0n,
chainId: 1,
maxFeePerGas: 30n * 10n ** 9n,
maxPriorityFeePerGas: 1n * 10n ** 9n,
gasLimit: 21_000,
});

| 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**. |
// 5. Firmar transacción (usando la dirección como `from`)
const signedTx = await signTransaction({
client,
request: {
auth: { accessToken: SIG_TOKEN },
options: {
from: TARGET_ADDRESS,
transaction: tx,
},
},
});
console.log("Transacción firmada:", signedTx);

Example – rotate an account after a key leak:
// 6. Crear un access token vinculado a la dirección
const token = await createAccessToken({
client,
request: {
metadata: {
name: "Token para wallet específica",
wallet: TARGET_ADDRESS,
},
policies: [
{
type: "eoa:signMessage",
chainId: 1,
eoa: TARGET_ADDRESS,
},
],
},
});
console.log("Access token creado:", token);

```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. |
| `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,
// 7. Listar EOAs que tengan la dirección como metadato
const matchingEoas = await listEoas({
client,
request: {
metadata: {
externalAddress: TARGET_ADDRESS,
},
},
});
console.log("EOAs encontrados con esa dirección:", matchingEoas);
}

// Ejecutar
main().catch((err) => {
console.error("Error durante la ejecución:", err);
});
Comment on lines +12 to 97
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Remove executable script from the page; render as a code sample instead.

The main() flow will run at build/SSR time and requires secrets. Convert it to a fenced TypeScript snippet so readers can copy-paste into a Node script.

Proposed replacement:

-// --- CONFIGURACIÓN ---
-const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
-const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
-const BASE_TOKEN = process.env.VAULT_BASE_TOKEN!;
-const TARGET_ADDRESS = "0x6561fF4034De957fAFeA20b3aCC5E6E9FEb21aCE";
-async function main() {
-  const client = await createVaultClient({ secretKey: SECRET_KEY });
-  const pingResult = await ping({ client, request: { message: "pong?" } });
-  console.log("Ping response:", pingResult);
-  const eoa = await createEoa({
-    client,
-    request: {
-      metadata: { label: "Wallet externa", externalAddress: TARGET_ADDRESS },
-    },
-  });
-  console.log("Nuevo EOA creado (metadatos):", eoa);
-  const tx = parseTransaction({
-    to: "0xAbC123456789abcdef123456789abcdef1234567",
-    value: 0n,
-    chainId: 1,
-    maxFeePerGas: 30n * 10n ** 9n,
-    maxPriorityFeePerGas: 1n * 10n ** 9n,
-    gasLimit: 21_000,
-  });
-  const signedTx = await signTransaction({
-    client,
-    request: {
-      auth: { accessToken: SIG_TOKEN },
-      options: { from: TARGET_ADDRESS, transaction: tx },
-    },
-  });
-  console.log("Transacción firmada:", signedTx);
-  const token = await createAccessToken({
-    client,
-    request: {
-      metadata: { name: "Token para wallet específica", wallet: TARGET_ADDRESS },
-      policies: [{ type: "eoa:signMessage", chainId: 1, eoa: TARGET_ADDRESS }],
-    },
-  });
-  console.log("Access token creado:", token);
-  const matchingEoas = await listEoas({
-    client,
-    request: { metadata: { externalAddress: TARGET_ADDRESS } },
-  });
-  console.log("EOAs encontrados con esa dirección:", matchingEoas);
-}
-// Ejecutar
-main().catch((err) => {
-  console.error("Error durante la ejecución:", err);
-});
+```ts
+// vault-integration.ts (Node/TS script - do not run in the browser)
+import "dotenv/config";
+import {
+  createVaultClient,
+  ping,
+  createEoa,
+  listEoas,
+  parseTransaction,
+  signTransaction,
+  createAccessToken,
+} from "@thirdweb-dev/vault-sdk";
+
+const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
+const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
+const TARGET_ADDRESS = process.env.TARGET_ADDRESS ?? "0xYourAddress";
+
+async function main() {
+  const client = await createVaultClient({ secretKey: SECRET_KEY });
+  const pingResult = await ping({ client, request: { message: "pong?" } });
+  console.log("Ping response:", pingResult);
+
+  const eoa = await createEoa({
+    client,
+    request: { metadata: { label: "Wallet externa", externalAddress: TARGET_ADDRESS } },
+  });
+  console.log("Nuevo EOA creado (metadatos):", eoa);
+
+  const tx = parseTransaction({
+    to: "0xAbC123456789abcdef123456789abcdef1234567",
+    value: 0n,
+    chainId: 1,
+    maxFeePerGas: 30n * 10n ** 9n,
+    maxPriorityFeePerGas: 1n * 10n ** 9n,
+    gasLimit: 21_000,
+  });
+
+  const signedTx = await signTransaction({
+    client,
+    request: { auth: { accessToken: SIG_TOKEN }, options: { from: TARGET_ADDRESS, transaction: tx } },
+  });
+  console.log("Transacción firmada:", signedTx);
+
+  const token = await createAccessToken({
+    client,
+    request: {
+      metadata: { name: "Token para wallet específica", wallet: TARGET_ADDRESS },
+      policies: [{ type: "eoa:signMessage", chainId: 1, eoa: TARGET_ADDRESS }],
+    },
+  });
+  console.log("Access token creado:", token);
+
+  const matchingEoas = await listEoas({ client, request: { metadata: { externalAddress: TARGET_ADDRESS } } });
+  console.log("EOAs encontrados con esa dirección:", matchingEoas);
+}
+
+main().catch((err) => {
+  console.error("Error durante la ejecución:", err);
+});
+```
🧰 Tools
🪛 LanguageTool

[grammar] ~14-~14: There might be a mistake here.
Context: ...RET_KEY = process.env.VAULT_SECRET_KEY!; const SIG_TOKEN = process.env.VAULT_SIG_...

(QB_NEW_EN)


[grammar] ~15-~15: There might be a mistake here.
Context: ...IG_TOKEN = process.env.VAULT_SIG_TOKEN!; const BASE_TOKEN = process.env.VAULT_BAS...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...acción (usando la dirección como from) const signedTx = await signTransaction({...

(QB_NEW_EN)


[grammar] ~94-~94: There might be a mistake here.
Context: ...rección:", matchingEoas); } // Ejecutar main().catch((err) => { console.error(...

(QB_NEW_EN)


[grammar] ~95-~95: There might be a mistake here.
Context: ...; } // Ejecutar main().catch((err) => { console.error("Error durante la ejecució...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...ror("Error durante la ejecución:", err); }); ✅ Requisitos Instala las dependencia...

(QB_NEW_EN)


[grammar] ~97-~97: There might be a mistake here.
Context: ..."Error durante la ejecución:", err); }); ✅ Requisitos Instala las dependencias si...

(QB_NEW_EN)

🤖 Prompt for AI Agents
apps/portal/src/app/vault/sdk/api-reference/page.mdx lines 12-97: the file
contains an executable top-level main() script that will run at build/SSR time
and requires secrets; replace the runnable code with a fenced TypeScript code
sample (triple backticks with "ts") that demonstrates usage but does not execute
during rendering — include suggested changes: move dotenv import and example
imports into the snippet, read secrets from process.env (e.g., TARGET_ADDRESS
fallback), keep all async logic inside an exported or example main() function
but do not call main() in the MDX page, and add a short comment line that this
is a Node/TS script (do not run in the browser).

✅ Requisitos
Instala las dependencias si aún no las tienes:
npm install @thirdweb-dev/vault-sdk dotenv
Crea un archivo .env en la raíz del proyecto con tus claves:
VAULT_SECRET_KEY=tu_clave_secreta_del_vault
VAULT_SIG_TOKEN=tu_access_token_para_firmar
VAULT_BASE_TOKEN=tu_access_token_base
Ejecuta el script:
ts-node vault-integration.ts

await signTransaction({
client,
request: {
auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
options: { from: "0xEoaAddress", transaction: tx },
Estructura del Proyecto
vault-project/
├── .env.example
├── .gitignore
├── package.json
├── tsconfig.json
├── vault-integration.ts
1. 📦 package.json
{
"name": "vault-project",
"version": "1.0.0",
"type": "module",
"main": "vault-integration.ts",
"scripts": {
"start": "ts-node vault-integration.ts"
},
});
```

> **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
});
```
"dependencies": {
"@thirdweb-dev/vault-sdk": "^0.9.0",
"dotenv": "^16.3.1"
},
"devDependencies": {
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
}
}
Comment on lines +117 to +133
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Dependency versions: confirm current releases.

The example pins versions (^0.9.0, ^16.3.1, ts-node ^10.9.1, TS ^5.2.2). Please verify these are still current or adjust to known-good ranges.


🌐 Web query:

What is the latest stable version of @thirdweb-dev/vault-sdk, dotenv, ts-node, and typescript?

💡 Result:

As of Sep 3, 2025:

  • @thirdweb-dev/vault-sdk — 0.0.3. [1]
  • dotenv — 17.2.2. [2]
  • ts-node — 10.9.2. [3]
  • typescript — 5.8.3. [4]

Sources:
[1] @thirdweb-dev/vault-sdk (Libraries.io).
[2] dotenv (npm).
[3] ts-node (npm).
[4] typescript (npm).


Update dependency versions in example: bump @thirdweb-dev/vault-sdk to ^0.0.3, dotenv to ^17.2.2, ts-node to ^10.9.2, and typescript to ^5.8.3 to match the latest stable releases.

🤖 Prompt for AI Agents
In apps/portal/src/app/vault/sdk/api-reference/page.mdx around lines 117 to 133,
the example package.json uses outdated dependency versions; update the
dependency entries to bump "@thirdweb-dev/vault-sdk" to "^0.0.3", "dotenv" to
"^17.2.2", "ts-node" to "^10.9.2", and "typescript" to "^5.8.3" (leave other
fields unchanged) so the example reflects the requested newer stable releases.

2. ⚙️ tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"strict": true
},
"include": ["vault-integration.ts"]
}
3. 🗂 .env.example
# Reemplaza estos valores en tu archivo .env
VAULT_SECRET_KEY=tu_clave_secreta_del_vault
VAULT_SIG_TOKEN=tu_access_token_para_firmar
VAULT_BASE_TOKEN=tu_access_token_base
4. 📄 .gitignore
.env
node_modules/
dist/

---
vault-integration.ts
Este es el archivo que ya construimos antes. Puedes copiarlo directamente desde aquí arriba o te lo dejo resumido aquí de nuevo:
<details> <summary>Ver el código</summary>
import {
createVaultClient,
ping,
createEoa,
listEoas,
parseTransaction,
signTransaction,
createAccessToken,
} from "@thirdweb-dev/vault-sdk";
import {
createVaultClient,
ping,
createEoa,
listEoas,
parseTransaction,
signTransaction,
createAccessToken,
} from "@thirdweb-dev/vault-sdk";
import "dotenv/config";

## 5. Utilities
// --- CONFIGURACIÓN ---
const SECRET_KEY = process.env.VAULT_SECRET_KEY!;
const SIG_TOKEN = process.env.VAULT_SIG_TOKEN!;
const BASE_TOKEN = process.env.VAULT_BASE_TOKEN!;

| 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. |
const TARGET_ADDRESS = "0x6561fF4034De957fAFeA20b3aCC5E6E9FEb21aCE";

```ts
try {
parseTransaction({ gas: 100_000 });
} catch (err) {
if (err instanceof ParseTransactionError) {
console.error(err.message);
}
}
```
async function main() {
const client = await createVaultClient({ secretKey: SECRET_KEY });

const pingResult = await ping({ client, request: { message: "pong?" } });
console.log("Ping response:", pingResult);

---
const eoa = await createEoa({
client,
request: {
metadata: {
label: "Wallet externa",
externalAddress: TARGET_ADDRESS,
},
},
});
console.log("Nuevo EOA creado:", eoa);

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

All request & response shapes are exported as TypeScript types so you can easily model higher-level abstractions:
const signedTx = await signTransaction({
client,
request: {
auth: { accessToken: SIG_TOKEN },
options: {
from: TARGET_ADDRESS,
transaction: tx,
},
},
});
console.log("Transacción firmada:", signedTx);

```ts
import type { CreateEoaPayload, SignMessagePayload, PolicyComponent } from "@thirdweb-dev/vault-sdk";
```
const token = await createAccessToken({
client,
request: {
metadata: {
name: "Token para wallet específica",
wallet: TARGET_ADDRESS,
},
policies: [
{
type: "eoa:signMessage",
chainId: 1,
eoa: TARGET_ADDRESS,
},
],
},
});
console.log("Access token creado:", token);

const matchingEoas = await listEoas({
client,
request: {
metadata: {
externalAddress: TARGET_ADDRESS,
},
},
});
console.log("EOAs encontrados:", matchingEoas);
}

main().catch((err) => {
console.error("Error:", err);
});
</details>

Refer to the generated `.d.ts` files for the complete list.
Instrucciones para Ejecutar
Clona o crea el proyecto:
mkdir vault-project
cd vault-project
Copia los archivos arriba o usa npm init y crea el package.json manualmente.
Instala dependencias:
npm install
Crea tu archivo .env desde el ejemplo:
cp .env.example .env
Edita .env con tus claves reales.
Ejecuta el script:
npm start