Skip to content
Draft
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
8 changes: 6 additions & 2 deletions apps/sdp-docs/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ import { DocsPage, DocsTitle, DocsDescription, DocsBody } from "@/components/doc

| Class | Element |
|---|---|
| `.launch-docs-title` | H1, ABC Diatype, clamp(36px, 6vw, 56px), weight 700 |
| `.launch-docs-title` | H1, ABC Diatype, clamp(32px, 4.5vw, 40px), weight 700 |
| `.launch-docs-description` | Subtitle `<p>`, ABC Diatype 18px, max-width 720px, margin-bottom 36px |
| `.launch-docs-body` | Content wrapper, Inter, `--launch-text` color |
| `.launch-mdx-heading` | Base heading style (ABC Diatype, bold, ink color) |
Expand All @@ -123,7 +123,11 @@ import { DocsPage, DocsTitle, DocsDescription, DocsBody } from "@/components/doc

### Navigation node icons (`navigation-node.tsx`)

The current sidebar does not render per-page icons. Page and folder links are text-only; only the folder expand/collapse chevron uses an icon (`ChevronDown` / `ChevronRight` from Lucide). If you want to reintroduce keyword-based icon mapping, add it to `NavigationNode` in `src/components/docs-shell/navigation-node.tsx`.
Sidebar icons are optional and opt-in per page/folder. Set `icon: <LucideName>` (e.g. `icon: BookOpen`) in a page's MDX frontmatter or a folder's `meta.json`; the loader in `src/lib/source.ts` resolves the name against `lucide-react` exports (unknown names throw at build time) and `NavigationNode` renders it before the label via `.launch-docs-nav-icon`. Pages without an `icon` stay text-only. The folder expand/collapse chevron (`ChevronDown` / `ChevronRight`) is unrelated and always shown.

### Search

⌘K search works out of the box: `RootProvider` (root `layout.tsx`) provides the Fumadocs search dialog + hotkey, backed by the Orama route at `src/app/api/search/route.ts` (`createFromSource(source)`). The sidebar header has a "Search docs" trigger button (`.launch-docs-sidebar-search`). Only `content/docs/` MDX is indexed — JSX-rendered content like `DocsHome` is not.

---

Expand Down
15 changes: 15 additions & 0 deletions apps/sdp-docs/content/docs/developing-with-sdp/authentication.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Authentication
description: Authenticate API requests with project-scoped API keys.
---

Every API request carries an API key in the `Authorization` header:

```bash title="Terminal"
curl https://api.solana.com/v1/wallets \
-H "Authorization: Bearer sk_test_..."
```

Key prefixes tell you which environment a key belongs to: `sk_test_` keys are sandbox, `sk_live_` keys are production.

Keys are project-scoped — a key can only reach the wallets, tokens, and payments of the project it was issued for. See [Manage API Keys](/docs/developing-with-sdp/manage-api-keys) for creating, rotating, and revoking keys.
16 changes: 16 additions & 0 deletions apps/sdp-docs/content/docs/developing-with-sdp/idempotency.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: Idempotency
description: Prevent duplicate operations by sending an Idempotency-Key header on mutation requests.
---

Include an `Idempotency-Key` header on mutation requests to prevent duplicates. If a request times out or your client retries, replaying the same key returns the original result instead of performing the operation twice.

```bash title="Terminal"
curl -X POST https://api.solana.com/v1/payments/transfers \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: 8a2f6c1e-9d4b-4f3a-b7e5-2c8d9f0a1b3c" \
-H "Content-Type: application/json" \
-d '{ ... }'
```

Use a unique key per logical operation (a UUID works well) and reuse the same key for retries of that operation.
24 changes: 24 additions & 0 deletions apps/sdp-docs/content/docs/developing-with-sdp/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
title: Overview
description: The interfaces, environments, and conventions you build against.
---

SDP exposes two interfaces that connect to the same backend:

- **Dashboard** — browser-based UI for setup, token management, and compliance operations. Sign in with email, Google, or GitHub.
- **REST API** — programmatic access for backend integrations. Authenticate with an API key in the `Authorization` header.

Everything the dashboard does is available through the API. Build against the API for automation and integrations; use the dashboard to set up your organization, inspect state, and perform one-off operations.

## Environments

| Environment | Network | API key prefix |
| ------------ | ------------ | -------------- |
| `sandbox` | devnet | `sk_test_` |
| `production` | mainnet-beta | `sk_live_` |

Both environments expose identical APIs. Develop and test against sandbox, then switch to production by swapping your API key.

## Signing modes

Most transaction endpoints support Execute (SDP signs and submits) or Prepare (SDP builds the transaction, you sign). See [Prepare vs Execute](/docs/guides/prepare-vs-execute).
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ After dismissing, the key appears in the table with its prefix, role, environmen

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/api-keys \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
Expand All @@ -70,7 +70,7 @@ curl -X POST https://api.solana.com/v1/api-keys \
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="create-api-key.ts"
const response = await fetch("https://api.solana.com/v1/api-keys", {
method: "POST",
headers: {
Expand All @@ -90,7 +90,7 @@ const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="CreateApiKey.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/api-keys"))
.header("Authorization", "Bearer sk_test_...")
Expand Down Expand Up @@ -131,15 +131,15 @@ During the grace period both the old and new key are valid. The new key value ap

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/api-keys/key_abc123/rotate \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{ "gracePeriodHours": 24 }'
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="rotate-api-key.ts"
const response = await fetch(
"https://api.solana.com/v1/api-keys/key_abc123/rotate",
{
Expand All @@ -156,7 +156,7 @@ const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="RotateApiKey.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/api-keys/key_abc123/rotate"))
.header("Authorization", "Bearer sk_test_...")
Expand Down Expand Up @@ -185,15 +185,15 @@ Open the **Actions** dropdown next to the key and click **Delete key**. The key

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X DELETE https://api.solana.com/v1/api-keys/key_abc123 \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{ "confirmation": "CI deploy key" }'
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="revoke-api-key.ts"
await fetch("https://api.solana.com/v1/api-keys/key_abc123", {
method: "DELETE",
headers: {
Expand All @@ -205,7 +205,7 @@ await fetch("https://api.solana.com/v1/api-keys/key_abc123", {
```
</Tab>
<Tab value="Java">
```java
```java title="RevokeApiKey.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/api-keys/key_abc123"))
.header("Authorization", "Bearer sk_test_...")
Expand Down
4 changes: 4 additions & 0 deletions apps/sdp-docs/content/docs/developing-with-sdp/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"title": "Developing with SDP",
"pages": ["index", "idempotency", "authentication", "manage-api-keys"]
}
18 changes: 9 additions & 9 deletions apps/sdp-docs/content/docs/guides/create-a-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,21 @@ A success toast confirms creation. The token is now in `pending` status, ready t

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl https://api.solana.com/v1/issuance/templates \
-H "Authorization: Bearer sk_test_..."
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="list-templates.ts"
const response = await fetch("https://api.solana.com/v1/issuance/templates", {
headers: { "Authorization": "Bearer sk_test_..." },
});
const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="ListTemplates.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/issuance/templates"))
.header("Authorization", "Bearer sk_test_...")
Expand All @@ -91,7 +91,7 @@ HttpRequest request = HttpRequest.newBuilder()

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/issuance/tokens \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
Expand All @@ -108,7 +108,7 @@ curl -X POST https://api.solana.com/v1/issuance/tokens \
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="create-token.ts"
const response = await fetch("https://api.solana.com/v1/issuance/tokens", {
method: "POST",
headers: {
Expand All @@ -131,7 +131,7 @@ const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="CreateToken.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/issuance/tokens"))
.header("Authorization", "Bearer sk_test_...")
Expand Down Expand Up @@ -160,7 +160,7 @@ Omit the `template` field or set it to `"custom"` and configure extensions via `

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/issuance/tokens \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
Expand All @@ -184,7 +184,7 @@ curl -X POST https://api.solana.com/v1/issuance/tokens \
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="create-custom-token.ts"
const response = await fetch("https://api.solana.com/v1/issuance/tokens", {
method: "POST",
headers: {
Expand All @@ -209,7 +209,7 @@ const response = await fetch("https://api.solana.com/v1/issuance/tokens", {
```
</Tab>
<Tab value="Java">
```java
```java title="CreateCustomToken.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/issuance/tokens"))
.header("Authorization", "Bearer sk_test_...")
Expand Down
12 changes: 6 additions & 6 deletions apps/sdp-docs/content/docs/guides/deploy-a-token.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ You can deploy from the dashboard or through the API. In the dashboard, open the

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: deploy-acme-001"
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="deploy-token.ts"
const response = await fetch(
"https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy",
{
Expand All @@ -39,7 +39,7 @@ const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="DeployToken.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy"))
.header("Authorization", "Bearer sk_test_...")
Expand All @@ -56,13 +56,13 @@ The token status changes from `pending` to `active`, and `mintAddress` is popula

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
```bash title="Terminal"
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy/prepare \
-H "Authorization: Bearer sk_test_..."
```
</Tab>
<Tab value="TypeScript">
```typescript
```typescript title="prepare-deploy-token.ts"
const response = await fetch(
"https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy/prepare",
{
Expand All @@ -75,7 +75,7 @@ const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
```java title="PrepareDeployToken.java"
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/deploy/prepare"))
.header("Authorization", "Bearer sk_test_...")
Expand Down
Loading
Loading