seal-wallet-agent-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # @seal-wallet/agent-sdk
2
+
3
+ Lightweight SDK for AI agents and bots to authenticate with [Seal](https://github.com/seal-wallet) smart wallets on Solana via the Sigil pairing token flow.
4
+
5
+ ## Overview
6
+
7
+ Seal wallets are on-chain smart wallets with **session-based authorization**, **spending limits**, and **allowed-program enforcement**. The Sigil system provides a secure pairing flow where wallet owners grant agents ephemeral sessions via **pairing tokens**.
8
+
9
+ This SDK handles the entire agent-side flow:
10
+ - **Authenticate** with a pairing token (no private keys needed)
11
+ - **Obtain ephemeral sessions** with on-chain spending limits
12
+ - **Wrap instructions** through Seal's `ExecuteViaSession` CPI
13
+ - **Auto-renew** sessions before they expire
14
+ - **Heartbeat** to report agent status
15
+
16
+ ```mermaid
17
+ sequenceDiagram
18
+ participant App as Sigil App (Wallet Owner)
19
+ participant Backend as Sigil Backend (Session Broker)
20
+ participant Chain as Solana (Seal Program)
21
+ participant Agent as Your Agent (SigilAgent)
22
+
23
+ App->>Backend: Pairing token (sgil_xxx)
24
+ Agent->>Backend: Request session (Bearer sgil_xxx)
25
+ Backend->>Chain: CreateSession TX (on-chain)
26
+ Chain-->>Backend: Session PDA created
27
+ Backend-->>Agent: Session credentials (keypair + limits)
28
+ Agent->>Chain: ExecuteViaSession TX (signed by session key)
29
+ Chain-->>Agent: TX confirmed
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ npm install @seal-wallet/agent-sdk @solana/web3.js
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```typescript
41
+ import { SigilAgent } from "@seal-wallet/agent-sdk";
42
+ import { Connection, Transaction, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js";
43
+
44
+ // 1. Initialize with pairing token from Sigil app
45
+ const agent = new SigilAgent({
46
+ pairingToken: process.env.PAIRING_TOKEN!, // sgil_xxx format
47
+ apiUrl: "http://localhost:3003", // Sigil backend URL
48
+ });
49
+
50
+ // 2. Get a session (auto-creates on-chain session key)
51
+ const session = await agent.getSession({
52
+ durationSecs: 3600, // 1 hour
53
+ maxAmountSol: 5.0, // 5 SOL daily limit
54
+ maxPerTxSol: 1.0, // 1 SOL per transaction limit
55
+ });
56
+
57
+ // 3. Build your instruction (e.g., SOL transfer, DLMM addLiquidity)
58
+ const transferIx = SystemProgram.transfer({
59
+ fromPubkey: session.walletPda, // Seal wallet PDA is the authority
60
+ toPubkey: recipientAddress,
61
+ lamports: 0.1 * LAMPORTS_PER_SOL,
62
+ });
63
+
64
+ // 4. Wrap it through Seal's ExecuteViaSession
65
+ const wrappedIx = agent.wrapInstruction(transferIx, BigInt(0.1 * LAMPORTS_PER_SOL));
66
+
67
+ // 5. Sign with session keypair and submit
68
+ const tx = new Transaction().add(wrappedIx);
69
+ tx.feePayer = session.sessionKeypair.publicKey;
70
+ const connection = new Connection("https://api.devnet.solana.com");
71
+ await connection.sendTransaction(tx, [session.sessionKeypair]);
72
+ ```
73
+
74
+ ## API Reference
75
+
76
+ ### `new SigilAgent(config)`
77
+
78
+ | Parameter | Type | Default | Description |
79
+ |-----------|------|---------|-------------|
80
+ | `pairingToken` | `string` | *required* | Pairing token from Sigil app (`sgil_xxx` format) |
81
+ | `apiUrl` | `string` | `http://localhost:3003` | Sigil backend URL |
82
+ | `autoRefresh` | `boolean` | `true` | Auto-renew session before expiry |
83
+ | `refreshThresholdSecs` | `number` | `300` | Seconds before expiry to trigger renewal |
84
+
85
+ ### `agent.getSession(options?)`
86
+
87
+ Requests or returns a cached ephemeral session. If the current session is within `refreshThresholdSecs` of expiry, a new one is created automatically.
88
+
89
+ **Options:**
90
+
91
+ | Parameter | Type | Default | Description |
92
+ |-----------|------|---------|-------------|
93
+ | `durationSecs` | `number` | `86400` | Session duration (60s – 7 days) |
94
+ | `maxAmountSol` | `number` | `5.0` | Max total SOL for this session |
95
+ | `maxPerTxSol` | `number` | `1.0` | Max SOL per single transaction |
96
+
97
+ **Returns:**
98
+ ```typescript
99
+ {
100
+ credentials: SessionCredentials; // Full session metadata
101
+ sessionKeypair: Keypair; // For signing transactions
102
+ walletPda: PublicKey; // Seal wallet PDA (use as authority)
103
+ agentConfigPda: PublicKey; // Agent config PDA
104
+ }
105
+ ```
106
+
107
+ **Throws:**
108
+ - `Error("Session request pending manual approval...")` if the agent's `autoApprove` is `false` — the wallet owner must approve in the Sigil app.
109
+ - `Error("Session request failed: ...")` on backend/network errors (automatically retried up to 3 times with exponential backoff).
110
+
111
+ ### `agent.wrapInstruction(innerIx, amountLamports?)`
112
+
113
+ Wraps a `TransactionInstruction` inside Seal's `ExecuteViaSession` CPI envelope. The Seal program verifies:
114
+ - Session key is valid and not expired
115
+ - Amount is within per-TX and daily limits
116
+ - Target program is in the agent's `allowed_programs` list
117
+
118
+ | Parameter | Type | Default | Description |
119
+ |-----------|------|---------|-------------|
120
+ | `innerIx` | `TransactionInstruction` | *required* | The instruction to execute |
121
+ | `amountLamports` | `bigint` | `0n` | Amount of lamports being spent |
122
+
123
+ ### `agent.heartbeat(status?, metadata?)`
124
+
125
+ Sends a keepalive to the Sigil backend. Shows up in the wallet owner's activity feed.
126
+
127
+ | Parameter | Type | Default | Description |
128
+ |-----------|------|---------|-------------|
129
+ | `status` | `"active" \| "idle" \| "trading"` | `"active"` | Agent status |
130
+ | `metadata` | `Record<string, unknown>` | — | Custom metadata (pool name, action, etc.) |
131
+
132
+ ### `agent.isSessionValid()`
133
+
134
+ Returns `true` if the cached session has not expired.
135
+
136
+ ### `agent.getSessionKeypair()`
137
+
138
+ Returns the current session `Keypair`. Throws if no session is active.
139
+
140
+ ### `agent.getWalletPda()`
141
+
142
+ Returns the Seal wallet `PublicKey`. Throws if no session is active.
143
+
144
+ ## Meteora DLMM Integration
145
+
146
+ The primary use case is autonomous LP trading on Meteora DLMM pools:
147
+
148
+ ```typescript
149
+ import DLMM from "@meteora-ag/dlmm";
150
+ import { SigilAgent } from "@seal-wallet/agent-sdk";
151
+ import { Connection, Keypair, Transaction } from "@solana/web3.js";
152
+ import BN from "bn.js";
153
+
154
+ const agent = new SigilAgent({ pairingToken: process.env.PAIRING_TOKEN! });
155
+ const session = await agent.getSession({ maxAmountSol: 2.0 });
156
+ const connection = new Connection("https://api.devnet.solana.com");
157
+
158
+ // Load DLMM pool
159
+ const poolAddress = new PublicKey("POOL_ADDRESS_HERE");
160
+ const dlmm = await DLMM.create(connection, poolAddress);
161
+
162
+ // Build add-liquidity instructions with Seal wallet PDA as user
163
+ const positionKeypair = Keypair.generate();
164
+ const { instructions } = await dlmm.initializePositionAndAddLiquidityByStrategy({
165
+ positionPubKey: positionKeypair.publicKey,
166
+ user: session.walletPda, // Seal wallet PDA is the authority
167
+ totalXAmount: new BN(0.5 * 1e9), // 0.5 SOL
168
+ totalYAmount: new BN(0),
169
+ strategy: {
170
+ maxBinId: activeBin.binId + 10,
171
+ minBinId: activeBin.binId - 10,
172
+ strategyType: StrategyType.SpotBalanced,
173
+ },
174
+ });
175
+
176
+ // Wrap EACH instruction through Seal's ExecuteViaSession
177
+ const wrappedInstructions = instructions.map((ix) =>
178
+ agent.wrapInstruction(ix, 500_000_000n) // 0.5 SOL
179
+ );
180
+
181
+ const tx = new Transaction().add(...wrappedInstructions);
182
+ tx.feePayer = session.sessionKeypair.publicKey;
183
+
184
+ await connection.sendTransaction(tx, [session.sessionKeypair, positionKeypair]);
185
+ ```
186
+
187
+ ## Session Auto-Renewal
188
+
189
+ Sessions are ephemeral and have an expiry time. The SDK automatically renews them:
190
+
191
+ ```typescript
192
+ const agent = new SigilAgent({
193
+ pairingToken: "sgil_xxx",
194
+ autoRefresh: true, // default
195
+ refreshThresholdSecs: 300, // renew 5 min before expiry (default)
196
+ });
197
+
198
+ // First call creates a session
199
+ const s1 = await agent.getSession();
200
+
201
+ // Subsequent calls return cached session
202
+ const s2 = await agent.getSession(); // same session (if still valid)
203
+
204
+ // When session nears expiry, a new one is automatically created
205
+ // No manual session management needed
206
+ ```
207
+
208
+ ## Error Handling & Retry
209
+
210
+ The SDK includes built-in retry with exponential backoff for transient failures:
211
+ - **Network errors**: Retried up to 3 times (1s → 2s → 4s backoff)
212
+ - **5xx server errors**: Retried with backoff
213
+ - **4xx client errors**: NOT retried (invalid token, locked wallet, etc.)
214
+
215
+ ```typescript
216
+ try {
217
+ const session = await agent.getSession();
218
+ } catch (err) {
219
+ if (err.message.includes("pending manual approval")) {
220
+ // Agent's autoApprove is false — owner must approve in Sigil app
221
+ } else if (err.message.includes("Wallet is locked")) {
222
+ // Owner locked the wallet — agent cannot create sessions
223
+ } else {
224
+ // Network/server error after 3 retries
225
+ }
226
+ }
227
+ ```
228
+
229
+ ## Security Model
230
+
231
+ | Feature | Protection |
232
+ |---------|------------|
233
+ | Pairing tokens | Bcrypt-hashed, never stored in plaintext |
234
+ | Session keys | AES-256-GCM encrypted at rest on backend |
235
+ | Session secret delivery | Transmitted once over HTTPS, never logged |
236
+ | Spending limits | Enforced on-chain by Seal program (tamper-proof) |
237
+ | Allowed programs | On-chain whitelist — agent can only call approved programs |
238
+ | Wallet lock | Owner can instantly lock wallet, blocking all new sessions |
239
+ | Session revocation | Owner can revoke individual or all sessions instantly |
240
+
241
+ ## Examples
242
+
243
+ See the [examples/](./examples/) directory:
244
+ - [`demo.ts`](./examples/demo.ts) — Full SDK lifecycle demo
245
+ - [`meteora-integration.ts`](./examples/meteora-integration.ts) — Meteora DLMM integration pattern
246
+
247
+ ```bash
248
+ # Run the demo
249
+ PAIRING_TOKEN=sgil_xxx npx tsx examples/demo.ts
250
+
251
+ # Run with on-chain transaction
252
+ PAIRING_TOKEN=sgil_xxx npx tsx examples/demo.ts --send
253
+ ```
254
+
255
+ ## License
256
+
257
+ MIT
@@ -0,0 +1,64 @@
1
+ import { Keypair, PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import type { SigilAgentConfig, SessionCredentials, SessionRequestOptions } from "./types.js";
3
+ /**
4
+ * SigilAgent — the primary class for agents to interact with Seal wallets.
5
+ *
6
+ * Usage:
7
+ * ```ts
8
+ * const agent = new SigilAgent({ pairingToken: "sgil_abc123..." });
9
+ * const session = await agent.getSession();
10
+ *
11
+ * // Use session.sessionKeypair to sign transactions
12
+ * // Use session.walletPda as the wallet authority in DLMM instructions
13
+ * // Wrap instructions with agent.wrapInstruction(innerIx, amountLamports)
14
+ * ```
15
+ */
16
+ export declare class SigilAgent {
17
+ private readonly pairingToken;
18
+ private readonly apiUrl;
19
+ private readonly autoRefresh;
20
+ private readonly refreshThresholdSecs;
21
+ private credentials;
22
+ private sessionKeypair;
23
+ constructor(config: SigilAgentConfig);
24
+ /**
25
+ * Get or create a session. Returns cached session if still valid.
26
+ * Automatically requests a new session if expired or about to expire.
27
+ */
28
+ getSession(options?: SessionRequestOptions): Promise<{
29
+ credentials: SessionCredentials;
30
+ sessionKeypair: Keypair;
31
+ walletPda: PublicKey;
32
+ agentConfigPda: PublicKey;
33
+ }>;
34
+ /**
35
+ * Build an ExecuteViaSession wrapper instruction.
36
+ * This wraps an inner instruction (e.g., DLMM addLiquidity) with Seal's
37
+ * session-based authorization.
38
+ */
39
+ wrapInstruction(innerIx: TransactionInstruction, amountLamports?: bigint): TransactionInstruction;
40
+ /**
41
+ * Send a heartbeat to the Sigil backend.
42
+ */
43
+ heartbeat(status?: "active" | "idle" | "trading", metadata?: Record<string, unknown>): Promise<void>;
44
+ /**
45
+ * Get the current session keypair (for signing transactions).
46
+ */
47
+ getSessionKeypair(): Keypair;
48
+ /**
49
+ * Get the wallet PDA (for use as authority in DLMM and other instructions).
50
+ */
51
+ getWalletPda(): PublicKey;
52
+ /**
53
+ * Check if the current session is still valid.
54
+ */
55
+ isSessionValid(): boolean;
56
+ private requestSession;
57
+ /**
58
+ * Make an API request with exponential backoff retry for transient failures.
59
+ * Retries on network errors and 5xx responses. Does NOT retry 4xx.
60
+ */
61
+ private apiRequestWithRetry;
62
+ private apiRequest;
63
+ private sleep;
64
+ }
package/dist/agent.js ADDED
@@ -0,0 +1,217 @@
1
+ import { Keypair, PublicKey, TransactionInstruction, } from "@solana/web3.js";
2
+ const DEFAULT_API_URL = "http://localhost:3003";
3
+ const DEFAULT_REFRESH_THRESHOLD = 300; // 5 minutes
4
+ const MAX_RETRIES = 3;
5
+ const INITIAL_BACKOFF_MS = 1000;
6
+ /**
7
+ * SigilAgent — the primary class for agents to interact with Seal wallets.
8
+ *
9
+ * Usage:
10
+ * ```ts
11
+ * const agent = new SigilAgent({ pairingToken: "sgil_abc123..." });
12
+ * const session = await agent.getSession();
13
+ *
14
+ * // Use session.sessionKeypair to sign transactions
15
+ * // Use session.walletPda as the wallet authority in DLMM instructions
16
+ * // Wrap instructions with agent.wrapInstruction(innerIx, amountLamports)
17
+ * ```
18
+ */
19
+ export class SigilAgent {
20
+ pairingToken;
21
+ apiUrl;
22
+ autoRefresh;
23
+ refreshThresholdSecs;
24
+ credentials = null;
25
+ sessionKeypair = null;
26
+ constructor(config) {
27
+ if (!config.pairingToken.startsWith("sgil_")) {
28
+ throw new Error("Invalid pairing token format. Expected: sgil_<token>");
29
+ }
30
+ this.pairingToken = config.pairingToken;
31
+ this.apiUrl = config.apiUrl ?? DEFAULT_API_URL;
32
+ this.autoRefresh = config.autoRefresh ?? true;
33
+ this.refreshThresholdSecs =
34
+ config.refreshThresholdSecs ?? DEFAULT_REFRESH_THRESHOLD;
35
+ }
36
+ /**
37
+ * Get or create a session. Returns cached session if still valid.
38
+ * Automatically requests a new session if expired or about to expire.
39
+ */
40
+ async getSession(options) {
41
+ // Check if we have a valid, non-expiring session
42
+ if (this.credentials && this.sessionKeypair) {
43
+ const expiresAt = new Date(this.credentials.expiresAt).getTime();
44
+ const remaining = (expiresAt - Date.now()) / 1000;
45
+ if (remaining > this.refreshThresholdSecs) {
46
+ return {
47
+ credentials: this.credentials,
48
+ sessionKeypair: this.sessionKeypair,
49
+ walletPda: new PublicKey(this.credentials.walletPda),
50
+ agentConfigPda: new PublicKey(this.credentials.agentConfigPda),
51
+ };
52
+ }
53
+ }
54
+ // Request new session
55
+ const creds = await this.requestSession(options);
56
+ this.credentials = creds;
57
+ this.sessionKeypair = Keypair.fromSecretKey(Buffer.from(creds.sessionSecretKey, "base64"));
58
+ return {
59
+ credentials: creds,
60
+ sessionKeypair: this.sessionKeypair,
61
+ walletPda: new PublicKey(creds.walletPda),
62
+ agentConfigPda: new PublicKey(creds.agentConfigPda),
63
+ };
64
+ }
65
+ /**
66
+ * Build an ExecuteViaSession wrapper instruction.
67
+ * This wraps an inner instruction (e.g., DLMM addLiquidity) with Seal's
68
+ * session-based authorization.
69
+ */
70
+ wrapInstruction(innerIx, amountLamports = 0n) {
71
+ if (!this.credentials || !this.sessionKeypair) {
72
+ throw new Error("No active session. Call getSession() first.");
73
+ }
74
+ const walletPda = new PublicKey(this.credentials.walletPda);
75
+ const agentPda = new PublicKey(this.credentials.agentConfigPda);
76
+ const sessionPda = new PublicKey(this.credentials.sessionPda);
77
+ const sealProgramId = new PublicKey("EV3TKRVz7pTHpAqBTjP8jmwuvoRBRCpjmVSPHhcMnXqb");
78
+ // Build remaining accounts from inner instruction
79
+ const remainingAccounts = innerIx.keys.map((key) => ({
80
+ pubkey: key.pubkey,
81
+ isSigner: key.pubkey.equals(walletPda) ? false : key.isSigner,
82
+ isWritable: key.isWritable,
83
+ }));
84
+ // Instruction data: [disc(1)] + [amount(8)] + [inner_data(N)]
85
+ const amountBuf = Buffer.alloc(8);
86
+ amountBuf.writeBigUInt64LE(amountLamports);
87
+ const data = Buffer.concat([
88
+ Buffer.from([3]), // ExecuteViaSession discriminant
89
+ amountBuf,
90
+ innerIx.data,
91
+ ]);
92
+ return new TransactionInstruction({
93
+ programId: sealProgramId,
94
+ keys: [
95
+ {
96
+ pubkey: this.sessionKeypair.publicKey,
97
+ isSigner: true,
98
+ isWritable: false,
99
+ },
100
+ { pubkey: walletPda, isSigner: false, isWritable: true },
101
+ { pubkey: agentPda, isSigner: false, isWritable: true },
102
+ { pubkey: sessionPda, isSigner: false, isWritable: true },
103
+ { pubkey: innerIx.programId, isSigner: false, isWritable: false },
104
+ ...remainingAccounts,
105
+ ],
106
+ data,
107
+ });
108
+ }
109
+ /**
110
+ * Send a heartbeat to the Sigil backend.
111
+ */
112
+ async heartbeat(status = "active", metadata) {
113
+ if (!this.credentials)
114
+ return;
115
+ await this.apiRequestWithRetry("/api/agent/session/heartbeat", {
116
+ method: "POST",
117
+ body: JSON.stringify({
118
+ sessionPda: this.credentials.sessionPda,
119
+ status,
120
+ metadata,
121
+ }),
122
+ });
123
+ }
124
+ /**
125
+ * Get the current session keypair (for signing transactions).
126
+ */
127
+ getSessionKeypair() {
128
+ if (!this.sessionKeypair) {
129
+ throw new Error("No active session. Call getSession() first.");
130
+ }
131
+ return this.sessionKeypair;
132
+ }
133
+ /**
134
+ * Get the wallet PDA (for use as authority in DLMM and other instructions).
135
+ */
136
+ getWalletPda() {
137
+ if (!this.credentials) {
138
+ throw new Error("No active session. Call getSession() first.");
139
+ }
140
+ return new PublicKey(this.credentials.walletPda);
141
+ }
142
+ /**
143
+ * Check if the current session is still valid.
144
+ */
145
+ isSessionValid() {
146
+ if (!this.credentials)
147
+ return false;
148
+ const expiresAt = new Date(this.credentials.expiresAt).getTime();
149
+ return Date.now() < expiresAt;
150
+ }
151
+ // ═══════════════════════════════════════════════════════════
152
+ // Private
153
+ // ═══════════════════════════════════════════════════════════
154
+ async requestSession(options) {
155
+ const response = await this.apiRequestWithRetry("/api/agent/session/request", {
156
+ method: "POST",
157
+ body: JSON.stringify({
158
+ durationSecs: options?.durationSecs,
159
+ maxAmountSol: options?.maxAmountSol,
160
+ maxPerTxSol: options?.maxPerTxSol,
161
+ }),
162
+ });
163
+ if (response.status === 202) {
164
+ throw new Error("Session request pending manual approval. Check the Sigil app to approve.");
165
+ }
166
+ if (!response.ok) {
167
+ const error = await response.json().catch(() => ({ error: "Unknown" }));
168
+ throw new Error(`Session request failed: ${error.error ?? response.statusText}`);
169
+ }
170
+ return response.json();
171
+ }
172
+ /**
173
+ * Make an API request with exponential backoff retry for transient failures.
174
+ * Retries on network errors and 5xx responses. Does NOT retry 4xx.
175
+ */
176
+ async apiRequestWithRetry(path, init = {}, retries = MAX_RETRIES) {
177
+ let lastError;
178
+ for (let attempt = 0; attempt <= retries; attempt++) {
179
+ try {
180
+ const response = await this.apiRequest(path, init);
181
+ // Don't retry client errors (4xx) — they won't change
182
+ if (response.status >= 400 && response.status < 500) {
183
+ return response;
184
+ }
185
+ // Retry server errors (5xx)
186
+ if (response.status >= 500 && attempt < retries) {
187
+ const delay = INITIAL_BACKOFF_MS * Math.pow(2, attempt);
188
+ await this.sleep(delay);
189
+ continue;
190
+ }
191
+ return response;
192
+ }
193
+ catch (error) {
194
+ lastError = error instanceof Error ? error : new Error(String(error));
195
+ if (attempt < retries) {
196
+ const delay = INITIAL_BACKOFF_MS * Math.pow(2, attempt);
197
+ await this.sleep(delay);
198
+ }
199
+ }
200
+ }
201
+ throw lastError ?? new Error(`Request to ${path} failed after ${retries + 1} attempts`);
202
+ }
203
+ async apiRequest(path, init = {}) {
204
+ return fetch(`${this.apiUrl}${path}`, {
205
+ ...init,
206
+ headers: {
207
+ "Content-Type": "application/json",
208
+ Authorization: `Bearer ${this.pairingToken}`,
209
+ ...(init.headers ?? {}),
210
+ },
211
+ });
212
+ }
213
+ sleep(ms) {
214
+ return new Promise((resolve) => setTimeout(resolve, ms));
215
+ }
216
+ }
217
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { SigilAgent } from "./agent.js";
2
+ export type { SigilAgentConfig, SessionCredentials, SessionRequestOptions, } from "./types.js";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { SigilAgent } from "./agent.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface SigilAgentConfig {
2
+ /** The pairing token obtained from the Sigil app (format: sgil_xxx) */
3
+ pairingToken: string;
4
+ /** Sigil backend URL (default: http://localhost:3003) */
5
+ apiUrl?: string;
6
+ /** Auto-refresh session before expiry (default: true) */
7
+ autoRefresh?: boolean;
8
+ /** Minimum remaining session time before refresh, in seconds (default: 300 = 5min) */
9
+ refreshThresholdSecs?: number;
10
+ }
11
+ export interface SessionCredentials {
12
+ sessionPubkey: string;
13
+ sessionSecretKey: string;
14
+ sessionPda: string;
15
+ walletPda: string;
16
+ agentConfigPda: string;
17
+ agentPubkey: string;
18
+ expiresAt: string;
19
+ maxAmountLamports: string;
20
+ maxPerTxLamports: string;
21
+ txSignature: string;
22
+ }
23
+ export interface SessionRequestOptions {
24
+ durationSecs?: number;
25
+ maxAmountSol?: number;
26
+ maxPerTxSol?: number;
27
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "seal-wallet-agent-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Lightweight SDK for AI agents to authenticate with Seal smart wallets on Solana via Sigil pairing tokens",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": ["dist", "README.md"],
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc --watch",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "dependencies": {
15
+ "@solana/web3.js": "^1.98.0"
16
+ },
17
+ "peerDependencies": {
18
+ "@solana/web3.js": "^1.90.0"
19
+ },
20
+ "peerDependenciesMeta": {
21
+ "@solana/web3.js": {
22
+ "optional": false
23
+ }
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^22.0.0",
27
+ "typescript": "^5.7.0"
28
+ },
29
+ "keywords": ["solana", "seal", "agent", "wallet", "sigil", "dlmm", "meteora", "smart-wallet", "session-key", "autonomous"],
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/seal-wallet/agent-sdk"
34
+ },
35
+ "homepage": "https://github.com/seal-wallet/agent-sdk#readme",
36
+ "bugs": {
37
+ "url": "https://github.com/seal-wallet/agent-sdk/issues"
38
+ },
39
+ "engines": {
40
+ "node": ">=18"
41
+ }
42
+ }