@kairoguard/sdk 0.0.12 → 0.0.13
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.bak +0 -0
- package/SKILL.md +28 -4
- package/dist/backend.d.ts +38 -1
- package/dist/backend.js +24 -3
- package/dist/cli.js +36 -3
- package/dist/client.d.ts +7 -0
- package/dist/client.js +85 -12
- package/dist/skill-templates.d.ts +3 -3
- package/dist/skill-templates.js +14 -14
- package/package.json +1 -1
package/README.md.bak
ADDED
|
Binary file
|
package/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kairo
|
|
3
|
-
description: Manage Kairo policy-enforced agent wallets. Use when creating wallets, setting transaction policies, checking vault status, minting policy receipts, or signing transactions through the Kairo API. Supports full wallet lifecycle: register API key → create wallet (DKG) → create policy → bind → vault provision → mint receipt → sign. Uses @
|
|
3
|
+
description: Manage Kairo policy-enforced agent wallets. Use when creating wallets, setting transaction policies, checking vault status, minting policy receipts, or signing transactions through the Kairo API. Supports full wallet lifecycle: register API key → create wallet (DKG) → create policy → bind → vault provision → mint receipt → sign. Uses @kairoguard/sdk for non-custodial wallet creation (agent keeps secret share locally).
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Kairo — Agent Wallet Management
|
|
@@ -44,6 +44,29 @@ console.log(`✅ Wallet created: ${wallet.address}`);
|
|
|
44
44
|
|
|
45
45
|
The wallet will be provisioned into the vault when the user connects their agent through the Kairo dashboard onboarding flow.
|
|
46
46
|
|
|
47
|
+
## API Key Scopes
|
|
48
|
+
|
|
49
|
+
Kairo uses scoped API keys to separate agent operations from dashboard administration:
|
|
50
|
+
|
|
51
|
+
- **Agent scope** (default for SDK/CLI): Can create wallets, sign transactions, and mint receipts. Cannot create/modify policies or governance.
|
|
52
|
+
- **Dashboard scope**: Can create policies, manage governance, and provision vaults. These are created through the Kairo dashboard.
|
|
53
|
+
|
|
54
|
+
When your agent registers an API key via `kairo.ps1 register` or the SDK, it receives an **agent-scoped key**. This is intentional — agents should focus on executing transactions, not managing policy rules. The user creates and binds policies through the dashboard.
|
|
55
|
+
|
|
56
|
+
**Agent-scoped keys CAN:**
|
|
57
|
+
- Create wallets via DKG
|
|
58
|
+
- Request signatures (with valid policy receipts)
|
|
59
|
+
- Mint policy receipts
|
|
60
|
+
- Query vault status and audit logs
|
|
61
|
+
|
|
62
|
+
**Agent-scoped keys CANNOT:**
|
|
63
|
+
- Create or modify policies
|
|
64
|
+
- Provision wallets into vaults
|
|
65
|
+
- Create or manage governance
|
|
66
|
+
- Approve policy changes
|
|
67
|
+
|
|
68
|
+
If your agent receives a **403 Forbidden** response with the message "This action is restricted to the dashboard", it means the operation requires dashboard scope. Guide the user to perform that action through the Kairo dashboard instead.
|
|
69
|
+
|
|
47
70
|
## Common Workflows
|
|
48
71
|
|
|
49
72
|
### Check API Health
|
|
@@ -69,7 +92,7 @@ powershell -File skills/kairo/scripts/kairo.ps1 policy-register -ApiKey $key -Po
|
|
|
69
92
|
### Create Wallet (via SDK)
|
|
70
93
|
For wallet creation, use the Node.js SDK (handles DKG client-side):
|
|
71
94
|
```typescript
|
|
72
|
-
import { KairoClient } from "@
|
|
95
|
+
import { KairoClient } from "@kairoguard/sdk";
|
|
73
96
|
const kairo = new KairoClient({ apiKey, backendUrl: "https://api.kairoguard.com" });
|
|
74
97
|
const wallet = await kairo.createWallet({ curve: "secp256k1" });
|
|
75
98
|
```
|
|
@@ -165,8 +188,9 @@ Before running a live demo, verify these in order:
|
|
|
165
188
|
2. **Backend key persistence is enabled**
|
|
166
189
|
- `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, `KAIRO_API_KEYS_TABLE=api_keys`
|
|
167
190
|
- Confirm key hash exists in Supabase `public.api_keys`
|
|
168
|
-
3. **Policy
|
|
169
|
-
-
|
|
191
|
+
3. **Policy and provisioning done through dashboard**
|
|
192
|
+
- User creates policy through dashboard (agents cannot)
|
|
193
|
+
- Wallet gets provisioned during dashboard onboarding
|
|
170
194
|
4. **Wallet ownership matches key**
|
|
171
195
|
- Wallet must be created/provisioned using the same API key
|
|
172
196
|
5. **Fund wallet before signing test**
|
package/dist/backend.d.ts
CHANGED
|
@@ -59,6 +59,8 @@ export interface ProvisionResponse {
|
|
|
59
59
|
export interface RegisterKeyRequest {
|
|
60
60
|
label: string;
|
|
61
61
|
email?: string;
|
|
62
|
+
userId?: string;
|
|
63
|
+
scope?: "dashboard" | "agent";
|
|
62
64
|
}
|
|
63
65
|
export interface RegisterKeyResponse {
|
|
64
66
|
success: boolean;
|
|
@@ -66,6 +68,8 @@ export interface RegisterKeyResponse {
|
|
|
66
68
|
label: string;
|
|
67
69
|
tier: string;
|
|
68
70
|
createdAt: number;
|
|
71
|
+
linkedUserId?: string | null;
|
|
72
|
+
linkedEmail?: string | null;
|
|
69
73
|
}
|
|
70
74
|
export type RequestStatus = "pending" | "processing" | "completed" | "failed";
|
|
71
75
|
export interface PresignRequestParams {
|
|
@@ -258,6 +262,29 @@ export interface SuiObjectResponse {
|
|
|
258
262
|
};
|
|
259
263
|
error?: string;
|
|
260
264
|
}
|
|
265
|
+
/** PolicyBinding info returned by /api/policies/user */
|
|
266
|
+
export interface UserBinding {
|
|
267
|
+
bindingId: string;
|
|
268
|
+
dWalletId: string;
|
|
269
|
+
stableId: string;
|
|
270
|
+
activeVersionId: string | null;
|
|
271
|
+
governanceId: string | null;
|
|
272
|
+
governanceMode: number | null;
|
|
273
|
+
isGoverned: boolean;
|
|
274
|
+
}
|
|
275
|
+
export interface UserBindingsResponse {
|
|
276
|
+
success?: boolean;
|
|
277
|
+
policies: UserBinding[];
|
|
278
|
+
_debug?: Record<string, unknown>;
|
|
279
|
+
error?: string;
|
|
280
|
+
}
|
|
281
|
+
/** Response from /api/policy/binding/:id/policy */
|
|
282
|
+
export interface BindingPolicyResponse {
|
|
283
|
+
success: boolean;
|
|
284
|
+
bindingId?: string;
|
|
285
|
+
policyObjectId?: string;
|
|
286
|
+
error?: string;
|
|
287
|
+
}
|
|
261
288
|
export declare class BackendClient {
|
|
262
289
|
private baseUrl;
|
|
263
290
|
private apiKey;
|
|
@@ -266,7 +293,17 @@ export declare class BackendClient {
|
|
|
266
293
|
getBaseUrl(): string;
|
|
267
294
|
private request;
|
|
268
295
|
getHealth(): Promise<HealthResponse>;
|
|
269
|
-
register(
|
|
296
|
+
register(params: {
|
|
297
|
+
label: string;
|
|
298
|
+
email?: string;
|
|
299
|
+
userId?: string;
|
|
300
|
+
scope?: "dashboard" | "agent";
|
|
301
|
+
authToken?: string;
|
|
302
|
+
}): Promise<RegisterKeyResponse>;
|
|
303
|
+
/** List policy bindings for the current API key (with wallet ownership). */
|
|
304
|
+
listUserBindings(): Promise<UserBindingsResponse>;
|
|
305
|
+
/** Resolve policyObjectId from a bindingObjectId. */
|
|
306
|
+
getPolicyFromBinding(bindingObjectId: string): Promise<BindingPolicyResponse>;
|
|
270
307
|
submitDKG(data: DKGSubmitRequest): Promise<DKGSubmitResponse>;
|
|
271
308
|
getDKGStatus(requestId: string): Promise<DKGStatusResponse>;
|
|
272
309
|
provision(params: ProvisionRequest): Promise<ProvisionResponse>;
|
package/dist/backend.js
CHANGED
|
@@ -18,11 +18,14 @@ export class BackendClient {
|
|
|
18
18
|
getBaseUrl() {
|
|
19
19
|
return this.baseUrl;
|
|
20
20
|
}
|
|
21
|
-
async request(method, path, body) {
|
|
21
|
+
async request(method, path, body, extraHeaders) {
|
|
22
22
|
const headers = { "Content-Type": "application/json" };
|
|
23
23
|
if (this.apiKey) {
|
|
24
24
|
headers["X-Kairo-Api-Key"] = this.apiKey;
|
|
25
25
|
}
|
|
26
|
+
if (extraHeaders) {
|
|
27
|
+
Object.assign(headers, extraHeaders);
|
|
28
|
+
}
|
|
26
29
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
27
30
|
method,
|
|
28
31
|
headers,
|
|
@@ -38,8 +41,26 @@ export class BackendClient {
|
|
|
38
41
|
async getHealth() {
|
|
39
42
|
return this.request("GET", "/health");
|
|
40
43
|
}
|
|
41
|
-
async register(
|
|
42
|
-
|
|
44
|
+
async register(params) {
|
|
45
|
+
const headers = {};
|
|
46
|
+
if (params.authToken) {
|
|
47
|
+
headers.Authorization = `Bearer ${params.authToken}`;
|
|
48
|
+
}
|
|
49
|
+
const body = {
|
|
50
|
+
label: params.label,
|
|
51
|
+
email: params.email,
|
|
52
|
+
userId: params.userId,
|
|
53
|
+
scope: params.scope,
|
|
54
|
+
};
|
|
55
|
+
return this.request("POST", "/api/keys/register", body, headers);
|
|
56
|
+
}
|
|
57
|
+
/** List policy bindings for the current API key (with wallet ownership). */
|
|
58
|
+
async listUserBindings() {
|
|
59
|
+
return this.request("GET", "/api/policies/user");
|
|
60
|
+
}
|
|
61
|
+
/** Resolve policyObjectId from a bindingObjectId. */
|
|
62
|
+
async getPolicyFromBinding(bindingObjectId) {
|
|
63
|
+
return this.request("GET", `/api/policy/binding/${bindingObjectId}/policy`);
|
|
43
64
|
}
|
|
44
65
|
async submitDKG(data) {
|
|
45
66
|
return this.request("POST", "/api/dkg/submit", data);
|
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ function loadConfig() {
|
|
|
24
24
|
function requireConfig() {
|
|
25
25
|
const cfg = loadConfig();
|
|
26
26
|
if (!cfg) {
|
|
27
|
-
console.error("No Kairo config found. Run: npx @
|
|
27
|
+
console.error("No Kairo config found. Run: npx @kairoguard/sdk init <YOUR_KEY>");
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
30
|
return cfg;
|
|
@@ -150,9 +150,22 @@ async function cmdWalletCreate(args) {
|
|
|
150
150
|
}
|
|
151
151
|
async function cmdRegister(args) {
|
|
152
152
|
const label = requireFlag(args, "--label", "name");
|
|
153
|
+
const userId = flag(args, "--user-id") ?? process.env.KAIRO_USER_ID;
|
|
154
|
+
const email = flag(args, "--email");
|
|
155
|
+
const authToken = flag(args, "--auth-token") ?? process.env.KAIRO_AUTH_TOKEN;
|
|
153
156
|
const client = getClient();
|
|
154
|
-
const res = await client.register(
|
|
157
|
+
const res = await client.register({
|
|
158
|
+
label,
|
|
159
|
+
email,
|
|
160
|
+
userId,
|
|
161
|
+
scope: "agent",
|
|
162
|
+
authToken,
|
|
163
|
+
});
|
|
155
164
|
console.log(JSON.stringify(res, null, 2));
|
|
165
|
+
if (!res.linkedUserId) {
|
|
166
|
+
console.log("Note: key created without user linkage (headless mode). " +
|
|
167
|
+
"Set --user-id (or KAIRO_USER_ID) or --auth-token (or KAIRO_AUTH_TOKEN) to link this key to a user.");
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
async function cmdPolicyCreate(args) {
|
|
158
171
|
const stableId = requireFlag(args, "--stable-id", "id");
|
|
@@ -256,6 +269,19 @@ async function cmdAuditVerify(args) {
|
|
|
256
269
|
}
|
|
257
270
|
console.log("OK");
|
|
258
271
|
}
|
|
272
|
+
async function cmdSync() {
|
|
273
|
+
const cfg = requireConfig();
|
|
274
|
+
const kairo = new KairoClient({
|
|
275
|
+
apiKey: cfg.apiKey,
|
|
276
|
+
backendUrl: cfg.backendUrl,
|
|
277
|
+
});
|
|
278
|
+
const updated = await kairo.syncWallets();
|
|
279
|
+
console.log(`Synced local wallet records: ${updated} updated`);
|
|
280
|
+
const wallets = kairo.listWallets();
|
|
281
|
+
for (const w of wallets) {
|
|
282
|
+
console.log(` ${w.walletId} binding=${w.bindingObjectId ?? "(none)"}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
259
285
|
function printUsage() {
|
|
260
286
|
console.log(`Kairo CLI — Agent Wallet Operations
|
|
261
287
|
|
|
@@ -268,7 +294,9 @@ Wallet & Policy:
|
|
|
268
294
|
health Server health check
|
|
269
295
|
wallet-create [--curve secp256k1|ed25519] [--policy-id <id>] [--stable-id <id>] [--auto-provision]
|
|
270
296
|
Create a new dWallet via SDK DKG flow
|
|
271
|
-
register --label <name>
|
|
297
|
+
register --label <name> [--user-id <uuid>] [--email <email>] [--auth-token <jwt>]
|
|
298
|
+
Register new API key (agent scope). Prefer linking with user id/jwt.
|
|
299
|
+
sync Sync local wallet metadata from backend (binding/policy IDs)
|
|
272
300
|
policy-create --stable-id <id> --allow <addrs> Create policy
|
|
273
301
|
policy-register --policy-id <id> Register policy version
|
|
274
302
|
policy-details --policy-id <id> Get policy details
|
|
@@ -276,6 +304,7 @@ Wallet & Policy:
|
|
|
276
304
|
vault-provision --wallet-id <id> --policy-id <id> [--stable-id <id>]
|
|
277
305
|
reaffirm --wallet-id <id> Reaffirm a wallet's current policy binding
|
|
278
306
|
receipt-mint --policy-id <id> --binding-id <id> --destination <hex> --intent-hash <hex>
|
|
307
|
+
sync Sync local wallet records with backend binding metadata
|
|
279
308
|
|
|
280
309
|
Utility:
|
|
281
310
|
audit --limit <n> List audit events
|
|
@@ -309,10 +338,14 @@ async function main() {
|
|
|
309
338
|
return cmdReaffirm(rest);
|
|
310
339
|
case "receipt-mint":
|
|
311
340
|
return cmdReceiptMint(rest);
|
|
341
|
+
case "sync":
|
|
342
|
+
return cmdSync();
|
|
312
343
|
case "audit":
|
|
313
344
|
if (rest[0] === "verify")
|
|
314
345
|
return cmdAuditVerify(rest.slice(1));
|
|
315
346
|
return cmdAudit(rest);
|
|
347
|
+
case "sync":
|
|
348
|
+
return cmdSync();
|
|
316
349
|
case "--help":
|
|
317
350
|
case "-h":
|
|
318
351
|
case undefined:
|
package/dist/client.d.ts
CHANGED
|
@@ -153,6 +153,13 @@ export declare class KairoClient {
|
|
|
153
153
|
listWallets(): WalletInfo[];
|
|
154
154
|
/** Get a wallet from local key store by ID. */
|
|
155
155
|
getWallet(walletId: string): WalletInfo | null;
|
|
156
|
+
/**
|
|
157
|
+
* Sync local wallet metadata from the backend.
|
|
158
|
+
* Queries /api/policies/user for bindings and updates local records
|
|
159
|
+
* with bindingObjectId and policyObjectId where available.
|
|
160
|
+
* Returns count of wallets updated.
|
|
161
|
+
*/
|
|
162
|
+
syncWallets(): Promise<number>;
|
|
156
163
|
/**
|
|
157
164
|
* Provision an existing local wallet into the policy vault.
|
|
158
165
|
* Persists binding/policy metadata to local keystore.
|
package/dist/client.js
CHANGED
|
@@ -207,6 +207,61 @@ export class KairoClient {
|
|
|
207
207
|
createdAt: r.createdAt,
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Sync local wallet metadata from the backend.
|
|
212
|
+
* Queries /api/policies/user for bindings and updates local records
|
|
213
|
+
* with bindingObjectId and policyObjectId where available.
|
|
214
|
+
* Returns count of wallets updated.
|
|
215
|
+
*/
|
|
216
|
+
async syncWallets() {
|
|
217
|
+
const response = await this.backend.listUserBindings();
|
|
218
|
+
if (!response.policies?.length)
|
|
219
|
+
return 0;
|
|
220
|
+
// Build lookup map by dWalletId (case-insensitive)
|
|
221
|
+
const bindingsByWallet = new Map();
|
|
222
|
+
for (const binding of response.policies) {
|
|
223
|
+
const wid = binding.dWalletId?.toLowerCase();
|
|
224
|
+
if (!wid)
|
|
225
|
+
continue;
|
|
226
|
+
if (!bindingsByWallet.has(wid)) {
|
|
227
|
+
bindingsByWallet.set(wid, {
|
|
228
|
+
bindingId: binding.bindingId,
|
|
229
|
+
stableId: binding.stableId,
|
|
230
|
+
activeVersionId: binding.activeVersionId,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let updated = 0;
|
|
235
|
+
for (const record of this.store.list()) {
|
|
236
|
+
const remote = bindingsByWallet.get(record.walletId.toLowerCase());
|
|
237
|
+
if (!remote)
|
|
238
|
+
continue;
|
|
239
|
+
const needsBindingUpdate = !record.bindingObjectId && remote.bindingId?.startsWith("0x");
|
|
240
|
+
const needsPolicyUpdate = !record.policyObjectId && remote.activeVersionId?.startsWith("0x");
|
|
241
|
+
if (needsBindingUpdate || needsPolicyUpdate) {
|
|
242
|
+
let policyObjectId = record.policyObjectId;
|
|
243
|
+
// If we have activeVersionId but no policyObjectId, resolve it from the binding
|
|
244
|
+
if (!policyObjectId && remote.activeVersionId) {
|
|
245
|
+
try {
|
|
246
|
+
const policyRes = await this.backend.getPolicyFromBinding(remote.bindingId);
|
|
247
|
+
if (policyRes.success && policyRes.policyObjectId?.startsWith("0x")) {
|
|
248
|
+
policyObjectId = policyRes.policyObjectId;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Resolution failed, will remain undefined; caller may need to handle
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
this.store.save({
|
|
256
|
+
...record,
|
|
257
|
+
bindingObjectId: record.bindingObjectId ?? remote.bindingId,
|
|
258
|
+
policyObjectId,
|
|
259
|
+
});
|
|
260
|
+
updated++;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return updated;
|
|
264
|
+
}
|
|
210
265
|
/**
|
|
211
266
|
* Provision an existing local wallet into the policy vault.
|
|
212
267
|
* Persists binding/policy metadata to local keystore.
|
|
@@ -686,11 +741,19 @@ export class KairoClient {
|
|
|
686
741
|
throw new Error(`Sign timed out after ${SIGN_POLL_TIMEOUT_MS / 1000}s (requestId: ${requestId})`);
|
|
687
742
|
}
|
|
688
743
|
async mintPolicyReceipt(wallet, ctx) {
|
|
744
|
+
// If binding metadata is missing, attempt to sync from backend before failing
|
|
689
745
|
if (!wallet.policyObjectId || !wallet.bindingObjectId) {
|
|
690
|
-
|
|
746
|
+
await this.syncWallets();
|
|
747
|
+
const refreshed = this.store.load(wallet.walletId);
|
|
748
|
+
if (refreshed) {
|
|
749
|
+
wallet = refreshed;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (!wallet.policyObjectId || !wallet.bindingObjectId) {
|
|
753
|
+
throw new Error("Wallet is missing policy binding metadata. Provision the wallet via dashboard or SDK before signing.");
|
|
691
754
|
}
|
|
692
755
|
const mintOnce = () => this.backend.mintReceipt({
|
|
693
|
-
policyObjectId: wallet.policyObjectId,
|
|
756
|
+
policyObjectId: wallet.policyObjectId ?? undefined,
|
|
694
757
|
bindingObjectId: wallet.bindingObjectId,
|
|
695
758
|
namespace: ctx.namespace,
|
|
696
759
|
// chainId is encoded as u64 bytes (16 hex chars)
|
|
@@ -722,18 +785,28 @@ export class KairoClient {
|
|
|
722
785
|
const explicit = String(override ?? "").trim();
|
|
723
786
|
if (explicit)
|
|
724
787
|
return explicit;
|
|
725
|
-
if (
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
788
|
+
if (wallet.policyObjectId?.startsWith("0x")) {
|
|
789
|
+
const response = await this.backend.getPolicy(wallet.policyObjectId);
|
|
790
|
+
if (response.success && response.policy) {
|
|
791
|
+
const version = decodeMoveString(response.policy.version).trim();
|
|
792
|
+
if (version)
|
|
793
|
+
return version;
|
|
794
|
+
}
|
|
731
795
|
}
|
|
732
|
-
|
|
733
|
-
if (
|
|
734
|
-
|
|
796
|
+
// policyObjectId unknown (e.g. provisioned via dashboard); resolve from binding metadata
|
|
797
|
+
if (wallet.bindingObjectId?.startsWith("0x")) {
|
|
798
|
+
const bindings = await this.backend.listUserBindings();
|
|
799
|
+
const match = bindings.policies?.find((b) => b.bindingId?.toLowerCase() === wallet.bindingObjectId.toLowerCase());
|
|
800
|
+
if (match?.activeVersionId?.startsWith("0x")) {
|
|
801
|
+
const versionDetails = await this.backend.getPolicy(match.activeVersionId);
|
|
802
|
+
if (versionDetails.success && versionDetails.policy) {
|
|
803
|
+
const version = decodeMoveString(versionDetails.policy.version).trim();
|
|
804
|
+
if (version)
|
|
805
|
+
return version;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
735
808
|
}
|
|
736
|
-
|
|
809
|
+
throw new Error("Could not resolve policy version. Pass policyVersion explicitly or provision via SDK.");
|
|
737
810
|
}
|
|
738
811
|
isReaffirmRequiredError(err) {
|
|
739
812
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* All backend URLs are intentionally omitted -- the SDK and CLI
|
|
5
5
|
* resolve the endpoint internally.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SKILL_MD = "---\nname: kairo\ndescription: Manage Kairo policy-enforced agent wallets. Use when creating wallets, checking vault status, minting policy receipts, or signing transactions through the Kairo SDK/CLI. Default onboarding is dashboard-first: register API key -> create wallet (DKG) in agent -> dashboard auto-binds/provisions policy. Uses @
|
|
8
|
-
export declare const API_REFERENCE_MD = "# Kairo API Reference\n\n## Authentication\nAll write endpoints require `X-Kairo-Api-Key` header.\nThe CLI reads the key from `~/.kairo/config.json` automatically.\nOpen endpoints: `/health`, `/api/vault/info`, `/api/vault/status/:id`, `/api/audit/events`\n\n## Key Registration\n```bash\nnpx kairo register --label \"my-agent\"\n```\n\n## Wallet Creation (via SDK)\nThe SDK handles DKG client-side. Agent keeps their secret share locally.\n```typescript\nimport { KairoClient } from \"@
|
|
9
|
-
export declare const SDK_REFERENCE_MD = "# Kairo SDK Reference\n\n## Installation\n```bash\nnpm install @
|
|
7
|
+
export declare const SKILL_MD = "---\nname: kairo\ndescription: Manage Kairo policy-enforced agent wallets. Use when creating wallets, checking vault status, minting policy receipts, or signing transactions through the Kairo SDK/CLI. Default onboarding is dashboard-first: register API key -> create wallet (DKG) in agent -> dashboard auto-binds/provisions policy. Uses @kairoguard/sdk for non-custodial wallet creation (agent keeps secret share locally).\n---\n\n# Kairo \u2014 Agent Wallet Management\n\n## Quick Reference\n\nCLI: `npx kairo <command>`\nSDK reference: `.cursor/skills/kairo/references/sdk.md`\nAPI reference: `.cursor/skills/kairo/references/api.md`\n\n## Setup\n\nRun the one-line installer (already done if you see this file):\n```bash\nnpx @kairoguard/sdk init <YOUR_KEY>\n```\n\nThe API key is stored in `~/.kairo/config.json`. All CLI commands read it automatically.\n\n## Common Workflows\n\n### Check API Health\n```bash\nnpx kairo health\n```\n\n### Dashboard-First Onboarding (Recommended)\n1. In dashboard onboarding, create/select policy + governance.\n2. In your agent:\n```bash\nnpx @kairoguard/sdk init <YOUR_KEY>\n```\n```typescript\nimport { KairoClient } from \"@kairoguard/sdk\";\nconst kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });\nconst wallet = await kairo.createWallet({ curve: \"secp256k1\" });\n```\n3. Return to dashboard \"Verify Connection\". Dashboard auto-provisions wallet policy binding + vault registration.\n\n### Create a Policy (Advanced / Self-Managed)\n```bash\nnpx kairo policy-create --stable-id \"my-policy\" --allow \"0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18\"\n```\nThen register the version:\n```bash\nnpx kairo policy-register --policy-id \"0x...\"\n```\n\n### Create Wallet (via SDK)\nFor wallet creation, use the Node.js SDK (handles DKG client-side):\n```typescript\nimport { KairoClient } from \"@kairoguard/sdk\";\nconst kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });\nconst wallet = await kairo.createWallet({ curve: \"secp256k1\" });\n```\nSee `.cursor/skills/kairo/references/sdk.md` for full SDK docs.\n\n### Provision Wallet into Vault\nRequires: policy version registered first.\n```bash\nnpx kairo vault-provision --wallet-id \"0x...\" --policy-id \"0x...\" --stable-id \"my-policy\"\n```\n\n### Mint Policy Receipt\n```bash\nnpx kairo receipt-mint --policy-id \"0x...\" --binding-id \"0x...\" --destination \"0x742d35Cc...\" --intent-hash \"0xabab...\"\n```\n\n### Check Vault Status\n```bash\nnpx kairo vault-status --wallet-id \"0x...\"\n```\n\n### View Audit Events\n```bash\nnpx kairo audit --limit 20\n```\n\n## Full Agent Flow (Dashboard-First)\n\n1. `npx @kairoguard/sdk init <YOUR_KEY>` \u2014 store API key, install skill\n2. Create/select policy in dashboard onboarding\n3. Configure governance approvers in dashboard onboarding (optional)\n4. Create wallet via SDK `createWallet()` \u2014 runs DKG locally, secret share stays on agent\n5. Dashboard Verify step auto-provisions wallet with selected policy\n6. `npx kairo receipt-mint` \u2014 request policy check for a transaction\n7. Sign via SDK \u2014 both shares combine, only if policy allows\n\n## Advanced: Self-Managed Flow (CLI Heavy)\n\n1. `npx @kairoguard/sdk init <YOUR_KEY>`\n2. `npx kairo policy-create`\n3. `npx kairo policy-register`\n4. SDK `createWallet()`\n5. `npx kairo vault-provision`\n\n## Trust Model\n\n- Agent's key share stays local (`~/.kairo/keys/`)\n- Server's key share stays on Kairo backend\n- Neither party can sign alone\n- Policy engine gates every transaction before server releases its share\n- All policy decisions are on-chain (Sui) and verifiable\n\n## Troubleshooting\n\n- **401 Unauthorized**: API key missing/invalid or not registered in backend key store. Re-run `npx @kairoguard/sdk init <YOUR_KEY>` with a valid key.\n- **403 Forbidden: key does not own wallet**: Wallet wasn't created/provisioned with this API key (ownership mismatch).\n- **429 Rate limit**: Public Sui RPC throttled \u2014 use Shinami or own RPC provider.\n- **MoveAbort code 102**: Policy version not registered \u2014 call `npx kairo policy-register` before `vault-provision`.\n- **`nonce too low` / `already known`**: Rapid reruns or duplicate raw tx; wait for pending tx, then re-sign and rebroadcast.\n- **AwaitingKeyHolderSignature**: Wallet needs activation after DKG \u2014 SDK activation flow required.\n";
|
|
8
|
+
export declare const API_REFERENCE_MD = "# Kairo API Reference\n\n## Authentication\nAll write endpoints require `X-Kairo-Api-Key` header.\nThe CLI reads the key from `~/.kairo/config.json` automatically.\nOpen endpoints: `/health`, `/api/vault/info`, `/api/vault/status/:id`, `/api/audit/events`\n\n## Key Registration\n```bash\nnpx kairo register --label \"my-agent\"\n```\n\n## Wallet Creation (via SDK)\nThe SDK handles DKG client-side. Agent keeps their secret share locally.\n```typescript\nimport { KairoClient } from \"@kairoguard/sdk\";\nconst kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });\nconst wallet = await kairo.createWallet({ curve: \"secp256k1\" });\n// wallet.walletId, wallet.address\n```\n\n## Policy Management\n\n### Create Policy\n```bash\nnpx kairo policy-create --stable-id \"my-policy\" --version \"1.0.0\" --allow \"0x<address>\"\n```\n\nRule types:\n- `1` = MaxNativeValue (max single transaction value)\n- `10` = PeriodLimit (cumulative spend limit per time window)\n\n### Register Policy Version\n```bash\nnpx kairo policy-register --policy-id \"0x...\"\n```\n\n### Get Policy Details\n```bash\nnpx kairo policy-details --policy-id \"0x...\"\n```\n\n## Vault\n\n### Provision (atomic binding + vault registration)\n```bash\nnpx kairo vault-provision --wallet-id \"0x...\" --policy-id \"0x...\" --stable-id \"my-policy\"\n```\nNote: Register policy version BEFORE calling provision.\n\n### Check Status\n```bash\nnpx kairo vault-status --wallet-id \"0x...\"\n```\n\n## Receipt Minting\n```bash\nnpx kairo receipt-mint --policy-id \"0x...\" --binding-id \"0x...\" --destination \"0x...\" --intent-hash \"0x...\"\n```\nNamespace: 1=EVM, 2=Bitcoin, 3=Solana\n\n## Utility\n```bash\nnpx kairo health # Server health\nnpx kairo audit --limit 20 # Recent audit events\n```\n";
|
|
9
|
+
export declare const SDK_REFERENCE_MD = "# Kairo SDK Reference\n\n## Installation\n```bash\nnpm install @kairoguard/sdk\n```\n\nRequires: `@ika.xyz/sdk`, `@mysten/sui`\n\n## KairoClient\n\n```typescript\nimport { KairoClient } from \"@kairoguard/sdk\";\n\nconst kairo = new KairoClient({\n apiKey: process.env.KAIRO_API_KEY!,\n storePath: \"~/.kairo/keys\", // local secret share storage (default)\n network: \"testnet\", // or \"mainnet\"\n suiRpcUrl: \"https://...\", // optional, defaults to public testnet\n});\n```\n\n### createWallet(opts?)\nCreates a dWallet via client-side DKG. Secret share stays local.\n\n```typescript\nconst wallet = await kairo.createWallet({\n curve: \"secp256k1\", // or \"ed25519\" for Solana\n});\n// Returns: { walletId, address, curve, bindingObjectId?, createdAt }\n```\n\nDashboard-first default: create wallet in agent and let dashboard onboarding handle policy provisioning.\n\nAdvanced optional params are still supported:\n```typescript\nconst wallet = await kairo.createWallet({\n curve: \"secp256k1\",\n policyObjectId: \"0x...\",\n stableId: \"my-policy\",\n});\n```\n\n### listWallets()\nLists all wallets in local key store.\n```typescript\nconst wallets = kairo.listWallets();\n```\n\n### getWallet(walletId)\nGets a specific wallet from local store.\n```typescript\nconst w = kairo.getWallet(\"0x...\");\n```\n\n## BackendClient (HTTP wrapper)\nLower-level HTTP client for direct API calls.\n\n```typescript\nimport { BackendClient } from \"@kairoguard/sdk\";\n\nconst client = new BackendClient({ apiKey: \"your-key\" });\n\nawait client.register({ label: \"my-agent\", scope: \"agent\" });\nawait client.getHealth();\nawait client.submitDKG({...});\nawait client.getDKGStatus(requestId);\nawait client.provision({...});\nawait client.mintReceipt({...});\n```\n\n## KeyStore (local storage)\nFile-based secret share storage at `~/.kairo/keys/`.\n\n```typescript\nimport { KeyStore } from \"@kairoguard/sdk\";\n\nconst store = new KeyStore(\"~/.kairo/keys\");\nstore.save(record);\nstore.load(\"0x...\");\nstore.list();\nstore.delete(\"0x...\");\n```\n\n## Trust Model\n- Agent's secret share -> stored locally (KeyStore), never sent to server\n- Server's share -> held by Kairo backend\n- Full signing -> requires BOTH shares + policy approval\n- Kairo alone cannot sign (missing agent share)\n- Agent alone cannot sign (missing server share)\n";
|
package/dist/skill-templates.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export const SKILL_MD = `---
|
|
8
8
|
name: kairo
|
|
9
|
-
description: Manage Kairo policy-enforced agent wallets. Use when creating wallets, checking vault status, minting policy receipts, or signing transactions through the Kairo SDK/CLI. Default onboarding is dashboard-first: register API key -> create wallet (DKG) in agent -> dashboard auto-binds/provisions policy. Uses @
|
|
9
|
+
description: Manage Kairo policy-enforced agent wallets. Use when creating wallets, checking vault status, minting policy receipts, or signing transactions through the Kairo SDK/CLI. Default onboarding is dashboard-first: register API key -> create wallet (DKG) in agent -> dashboard auto-binds/provisions policy. Uses @kairoguard/sdk for non-custodial wallet creation (agent keeps secret share locally).
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Kairo — Agent Wallet Management
|
|
@@ -21,7 +21,7 @@ API reference: \`.cursor/skills/kairo/references/api.md\`
|
|
|
21
21
|
|
|
22
22
|
Run the one-line installer (already done if you see this file):
|
|
23
23
|
\`\`\`bash
|
|
24
|
-
npx @
|
|
24
|
+
npx @kairoguard/sdk init <YOUR_KEY>
|
|
25
25
|
\`\`\`
|
|
26
26
|
|
|
27
27
|
The API key is stored in \`~/.kairo/config.json\`. All CLI commands read it automatically.
|
|
@@ -37,10 +37,10 @@ npx kairo health
|
|
|
37
37
|
1. In dashboard onboarding, create/select policy + governance.
|
|
38
38
|
2. In your agent:
|
|
39
39
|
\`\`\`bash
|
|
40
|
-
npx @
|
|
40
|
+
npx @kairoguard/sdk init <YOUR_KEY>
|
|
41
41
|
\`\`\`
|
|
42
42
|
\`\`\`typescript
|
|
43
|
-
import { KairoClient } from "@
|
|
43
|
+
import { KairoClient } from "@kairoguard/sdk";
|
|
44
44
|
const kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });
|
|
45
45
|
const wallet = await kairo.createWallet({ curve: "secp256k1" });
|
|
46
46
|
\`\`\`
|
|
@@ -58,7 +58,7 @@ npx kairo policy-register --policy-id "0x..."
|
|
|
58
58
|
### Create Wallet (via SDK)
|
|
59
59
|
For wallet creation, use the Node.js SDK (handles DKG client-side):
|
|
60
60
|
\`\`\`typescript
|
|
61
|
-
import { KairoClient } from "@
|
|
61
|
+
import { KairoClient } from "@kairoguard/sdk";
|
|
62
62
|
const kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });
|
|
63
63
|
const wallet = await kairo.createWallet({ curve: "secp256k1" });
|
|
64
64
|
\`\`\`
|
|
@@ -87,7 +87,7 @@ npx kairo audit --limit 20
|
|
|
87
87
|
|
|
88
88
|
## Full Agent Flow (Dashboard-First)
|
|
89
89
|
|
|
90
|
-
1. \`npx @
|
|
90
|
+
1. \`npx @kairoguard/sdk init <YOUR_KEY>\` — store API key, install skill
|
|
91
91
|
2. Create/select policy in dashboard onboarding
|
|
92
92
|
3. Configure governance approvers in dashboard onboarding (optional)
|
|
93
93
|
4. Create wallet via SDK \`createWallet()\` — runs DKG locally, secret share stays on agent
|
|
@@ -97,7 +97,7 @@ npx kairo audit --limit 20
|
|
|
97
97
|
|
|
98
98
|
## Advanced: Self-Managed Flow (CLI Heavy)
|
|
99
99
|
|
|
100
|
-
1. \`npx @
|
|
100
|
+
1. \`npx @kairoguard/sdk init <YOUR_KEY>\`
|
|
101
101
|
2. \`npx kairo policy-create\`
|
|
102
102
|
3. \`npx kairo policy-register\`
|
|
103
103
|
4. SDK \`createWallet()\`
|
|
@@ -113,7 +113,7 @@ npx kairo audit --limit 20
|
|
|
113
113
|
|
|
114
114
|
## Troubleshooting
|
|
115
115
|
|
|
116
|
-
- **401 Unauthorized**: API key missing/invalid or not registered in backend key store. Re-run \`npx @
|
|
116
|
+
- **401 Unauthorized**: API key missing/invalid or not registered in backend key store. Re-run \`npx @kairoguard/sdk init <YOUR_KEY>\` with a valid key.
|
|
117
117
|
- **403 Forbidden: key does not own wallet**: Wallet wasn't created/provisioned with this API key (ownership mismatch).
|
|
118
118
|
- **429 Rate limit**: Public Sui RPC throttled — use Shinami or own RPC provider.
|
|
119
119
|
- **MoveAbort code 102**: Policy version not registered — call \`npx kairo policy-register\` before \`vault-provision\`.
|
|
@@ -135,7 +135,7 @@ npx kairo register --label "my-agent"
|
|
|
135
135
|
## Wallet Creation (via SDK)
|
|
136
136
|
The SDK handles DKG client-side. Agent keeps their secret share locally.
|
|
137
137
|
\`\`\`typescript
|
|
138
|
-
import { KairoClient } from "@
|
|
138
|
+
import { KairoClient } from "@kairoguard/sdk";
|
|
139
139
|
const kairo = new KairoClient({ apiKey: process.env.KAIRO_API_KEY! });
|
|
140
140
|
const wallet = await kairo.createWallet({ curve: "secp256k1" });
|
|
141
141
|
// wallet.walletId, wallet.address
|
|
@@ -191,7 +191,7 @@ export const SDK_REFERENCE_MD = `# Kairo SDK Reference
|
|
|
191
191
|
|
|
192
192
|
## Installation
|
|
193
193
|
\`\`\`bash
|
|
194
|
-
npm install @
|
|
194
|
+
npm install @kairoguard/sdk
|
|
195
195
|
\`\`\`
|
|
196
196
|
|
|
197
197
|
Requires: \`@ika.xyz/sdk\`, \`@mysten/sui\`
|
|
@@ -199,7 +199,7 @@ Requires: \`@ika.xyz/sdk\`, \`@mysten/sui\`
|
|
|
199
199
|
## KairoClient
|
|
200
200
|
|
|
201
201
|
\`\`\`typescript
|
|
202
|
-
import { KairoClient } from "@
|
|
202
|
+
import { KairoClient } from "@kairoguard/sdk";
|
|
203
203
|
|
|
204
204
|
const kairo = new KairoClient({
|
|
205
205
|
apiKey: process.env.KAIRO_API_KEY!,
|
|
@@ -246,11 +246,11 @@ const w = kairo.getWallet("0x...");
|
|
|
246
246
|
Lower-level HTTP client for direct API calls.
|
|
247
247
|
|
|
248
248
|
\`\`\`typescript
|
|
249
|
-
import { BackendClient } from "@
|
|
249
|
+
import { BackendClient } from "@kairoguard/sdk";
|
|
250
250
|
|
|
251
251
|
const client = new BackendClient({ apiKey: "your-key" });
|
|
252
252
|
|
|
253
|
-
await client.register("my-agent");
|
|
253
|
+
await client.register({ label: "my-agent", scope: "agent" });
|
|
254
254
|
await client.getHealth();
|
|
255
255
|
await client.submitDKG({...});
|
|
256
256
|
await client.getDKGStatus(requestId);
|
|
@@ -262,7 +262,7 @@ await client.mintReceipt({...});
|
|
|
262
262
|
File-based secret share storage at \`~/.kairo/keys/\`.
|
|
263
263
|
|
|
264
264
|
\`\`\`typescript
|
|
265
|
-
import { KeyStore } from "@
|
|
265
|
+
import { KeyStore } from "@kairoguard/sdk";
|
|
266
266
|
|
|
267
267
|
const store = new KeyStore("~/.kairo/keys");
|
|
268
268
|
store.save(record);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kairoguard/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "Kairo SDK for multi-chain policy-based transaction signing with dWallet support (EVM, Bitcoin, Solana, Sui)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kairo <mehraab@thewidercollective.com>",
|