@kairoguard/sdk 0.0.3 → 0.0.5
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/dist/auditBundle.d.ts +1 -1
- package/dist/auditBundle.js +1 -1
- package/dist/backend.d.ts +1 -0
- package/dist/backend.js +3 -0
- package/dist/cli.js +25 -0
- package/dist/client.d.ts +5 -1
- package/dist/client.js +90 -5
- package/dist/ika-protocol.js +29 -10
- package/dist/index.d.ts +13 -13
- package/dist/index.js +13 -13
- package/package.json +1 -1
package/dist/auditBundle.d.ts
CHANGED
package/dist/auditBundle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { fetchAndValidatePolicyReceipt } from "./suiReceipts";
|
|
1
|
+
import { fetchAndValidatePolicyReceipt } from "./suiReceipts.js";
|
|
2
2
|
/**
|
|
3
3
|
* Minimal verifier for an audit bundle (v1).
|
|
4
4
|
* This intentionally verifies only receipt commitments using on-chain receipt contents.
|
package/dist/backend.d.ts
CHANGED
|
@@ -253,6 +253,7 @@ export declare class BackendClient {
|
|
|
253
253
|
private apiKey;
|
|
254
254
|
constructor(opts: BackendClientOpts);
|
|
255
255
|
setApiKey(key: string): void;
|
|
256
|
+
getBaseUrl(): string;
|
|
256
257
|
private request;
|
|
257
258
|
getHealth(): Promise<HealthResponse>;
|
|
258
259
|
register(label: string, email?: string): Promise<RegisterKeyResponse>;
|
package/dist/backend.js
CHANGED
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { join } from "node:path";
|
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { verifyAuditBundle } from "./auditBundle.js";
|
|
6
6
|
import { BackendClient } from "./backend.js";
|
|
7
|
+
import { KairoClient } from "./client.js";
|
|
7
8
|
import { SKILL_MD, API_REFERENCE_MD, SDK_REFERENCE_MD } from "./skill-templates.js";
|
|
8
9
|
const CONFIG_DIR = join(homedir(), ".kairo");
|
|
9
10
|
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
@@ -80,6 +81,26 @@ async function cmdHealth() {
|
|
|
80
81
|
const res = await client.getHealth();
|
|
81
82
|
console.log(JSON.stringify(res, null, 2));
|
|
82
83
|
}
|
|
84
|
+
async function cmdWalletCreate(args) {
|
|
85
|
+
const curveRaw = flag(args, "--curve") ?? "secp256k1";
|
|
86
|
+
if (curveRaw !== "secp256k1" && curveRaw !== "ed25519") {
|
|
87
|
+
console.error('Invalid --curve value. Use "secp256k1" or "ed25519".');
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const policyId = flag(args, "--policy-id");
|
|
91
|
+
const stableId = flag(args, "--stable-id");
|
|
92
|
+
const cfg = requireConfig();
|
|
93
|
+
const kairo = new KairoClient({
|
|
94
|
+
apiKey: cfg.apiKey,
|
|
95
|
+
backendUrl: cfg.backendUrl,
|
|
96
|
+
});
|
|
97
|
+
const wallet = await kairo.createWallet({
|
|
98
|
+
curve: curveRaw,
|
|
99
|
+
policyObjectId: policyId,
|
|
100
|
+
stableId,
|
|
101
|
+
});
|
|
102
|
+
console.log(JSON.stringify(wallet, null, 2));
|
|
103
|
+
}
|
|
83
104
|
async function cmdRegister(args) {
|
|
84
105
|
const label = requireFlag(args, "--label", "name");
|
|
85
106
|
const client = getClient();
|
|
@@ -184,6 +205,8 @@ Setup:
|
|
|
184
205
|
|
|
185
206
|
Wallet & Policy:
|
|
186
207
|
health Server health check
|
|
208
|
+
wallet-create [--curve secp256k1|ed25519] [--policy-id <id>] [--stable-id <id>]
|
|
209
|
+
Create a new dWallet via SDK DKG flow
|
|
187
210
|
register --label <name> Register new API key
|
|
188
211
|
policy-create --stable-id <id> --allow <addrs> Create policy
|
|
189
212
|
policy-register --policy-id <id> Register policy version
|
|
@@ -206,6 +229,8 @@ async function main() {
|
|
|
206
229
|
return cmdInit(rest);
|
|
207
230
|
case "health":
|
|
208
231
|
return cmdHealth();
|
|
232
|
+
case "wallet-create":
|
|
233
|
+
return cmdWalletCreate(rest);
|
|
209
234
|
case "register":
|
|
210
235
|
return cmdRegister(rest);
|
|
211
236
|
case "policy-create":
|
package/dist/client.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface KairoClientOpts {
|
|
|
17
17
|
backendUrl?: string;
|
|
18
18
|
/** Local directory for secret share storage. Defaults to ~/.kairo/keys */
|
|
19
19
|
storePath?: string;
|
|
20
|
-
/** Sui RPC URL for fetching Ika protocol params. Defaults to public testnet. */
|
|
20
|
+
/** Sui RPC URL for fetching Ika protocol params. Defaults to backend's proxy, then SUI_RPC_URL env, then public testnet. */
|
|
21
21
|
suiRpcUrl?: string;
|
|
22
22
|
/** Sui network. Defaults to "testnet". */
|
|
23
23
|
network?: "testnet" | "mainnet";
|
|
@@ -138,6 +138,10 @@ export declare class KairoClient {
|
|
|
138
138
|
private network;
|
|
139
139
|
private evmRpcUrls;
|
|
140
140
|
constructor(opts: KairoClientOpts);
|
|
141
|
+
/**
|
|
142
|
+
* Resolve Sui RPC URL, testing backend proxy first and falling back to public RPC.
|
|
143
|
+
*/
|
|
144
|
+
private resolveSuiRpcUrl;
|
|
141
145
|
/**
|
|
142
146
|
* Create a new dWallet. Runs DKG on the agent's machine, submits to backend,
|
|
143
147
|
* and optionally provisions the wallet in the vault.
|
package/dist/client.js
CHANGED
|
@@ -14,7 +14,43 @@ import { Curve, fetchProtocolParams, deriveEncryptionKeys, generateSeed, generat
|
|
|
14
14
|
import { Hash, SignatureAlgorithm, createUserSignMessageWithPublicOutput } from "@ika.xyz/sdk";
|
|
15
15
|
import { computeEvmIntentFromUnsignedTxBytes } from "./evmIntent.js";
|
|
16
16
|
import { keccak256, recoverTransactionAddress, serializeTransaction, } from "viem";
|
|
17
|
-
const
|
|
17
|
+
const FALLBACK_SUI_RPC = "https://fullnode.testnet.sui.io:443";
|
|
18
|
+
async function testRpcEndpoint(url) {
|
|
19
|
+
try {
|
|
20
|
+
const res = await fetch(url, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: { "Content-Type": "application/json" },
|
|
23
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "suix_getLatestSuiSystemState", params: [] }),
|
|
24
|
+
});
|
|
25
|
+
return res.ok;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function isRateLimitError(err) {
|
|
32
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
33
|
+
return message.includes("429") || message.includes("Too Many Requests");
|
|
34
|
+
}
|
|
35
|
+
async function withRetry(fn, opts) {
|
|
36
|
+
const maxRetries = opts?.maxRetries ?? 3;
|
|
37
|
+
const baseDelayMs = opts?.baseDelayMs ?? 2000;
|
|
38
|
+
const label = opts?.label ?? "operation";
|
|
39
|
+
for (let attempt = 0;; attempt++) {
|
|
40
|
+
try {
|
|
41
|
+
return await fn();
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
const lastAttempt = attempt >= maxRetries;
|
|
45
|
+
if (lastAttempt || !isRateLimitError(err)) {
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
const delayMs = baseDelayMs * 2 ** attempt;
|
|
49
|
+
console.warn(`[KairoSDK] ${label} rate-limited (attempt ${attempt + 1}/${maxRetries + 1}); retrying in ${delayMs / 1000}s...`);
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
18
54
|
const DEFAULT_EVM_RPC_URLS = {
|
|
19
55
|
1: "https://rpc.ankr.com/eth",
|
|
20
56
|
11155111: "https://rpc.ankr.com/eth_sepolia",
|
|
@@ -37,9 +73,30 @@ export class KairoClient {
|
|
|
37
73
|
constructor(opts) {
|
|
38
74
|
this.backend = new BackendClient({ backendUrl: opts.backendUrl, apiKey: opts.apiKey });
|
|
39
75
|
this.store = new KeyStore(opts.storePath);
|
|
40
|
-
this.suiRpcUrl = opts.suiRpcUrl ?? DEFAULT_SUI_RPC;
|
|
41
76
|
this.network = opts.network ?? "testnet";
|
|
42
77
|
this.evmRpcUrls = { ...DEFAULT_EVM_RPC_URLS, ...(opts.evmRpcUrls ?? {}) };
|
|
78
|
+
// Sui RPC priority: explicit option > env var > will resolve lazily (proxy or fallback)
|
|
79
|
+
this.suiRpcUrl =
|
|
80
|
+
opts.suiRpcUrl ??
|
|
81
|
+
process.env.SUI_RPC_URL?.trim() ??
|
|
82
|
+
""; // Empty means we'll resolve lazily
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Resolve Sui RPC URL, testing backend proxy first and falling back to public RPC.
|
|
86
|
+
*/
|
|
87
|
+
async resolveSuiRpcUrl() {
|
|
88
|
+
if (this.suiRpcUrl)
|
|
89
|
+
return this.suiRpcUrl;
|
|
90
|
+
// Try backend proxy first (uses Shinami)
|
|
91
|
+
const backendProxy = `${this.backend.getBaseUrl()}/api/sui-rpc`;
|
|
92
|
+
if (await testRpcEndpoint(backendProxy)) {
|
|
93
|
+
this.suiRpcUrl = backendProxy;
|
|
94
|
+
return this.suiRpcUrl;
|
|
95
|
+
}
|
|
96
|
+
// Fall back to public RPC
|
|
97
|
+
console.warn("[KairoSDK] Backend RPC proxy not available, falling back to public Sui RPC");
|
|
98
|
+
this.suiRpcUrl = FALLBACK_SUI_RPC;
|
|
99
|
+
return this.suiRpcUrl;
|
|
43
100
|
}
|
|
44
101
|
/**
|
|
45
102
|
* Create a new dWallet. Runs DKG on the agent's machine, submits to backend,
|
|
@@ -53,7 +110,8 @@ export class KairoClient {
|
|
|
53
110
|
const seed = generateSeed();
|
|
54
111
|
const encryptionKeys = await deriveEncryptionKeys(seed, curve);
|
|
55
112
|
// 2. Fetch protocol params from Ika network (runs locally, avoids backend memory limit)
|
|
56
|
-
const
|
|
113
|
+
const rpcUrl = await this.resolveSuiRpcUrl();
|
|
114
|
+
const protocolParams = await withRetry(() => fetchProtocolParams(curve, rpcUrl, this.network), { label: "fetchProtocolParams" });
|
|
57
115
|
// 3. Generate session identifier
|
|
58
116
|
const sessionIdentifier = generateSessionIdentifier();
|
|
59
117
|
// 4. Get backend admin address (DKG must target the admin signer)
|
|
@@ -323,7 +381,8 @@ export class KairoClient {
|
|
|
323
381
|
presignId = presign.presignId;
|
|
324
382
|
presignBytes = presign.presignBytes;
|
|
325
383
|
}
|
|
326
|
-
const
|
|
384
|
+
const rpcUrlForSign = await this.resolveSuiRpcUrl();
|
|
385
|
+
const protocolParams = await withRetry(() => fetchProtocolParams("secp256k1", rpcUrlForSign, this.network), { label: "fetchProtocolParams(sign)" });
|
|
327
386
|
const messageBytes = new Uint8Array(Buffer.from(messageHexNoPrefix, "hex"));
|
|
328
387
|
const userSignMessage = await this.computeUserSignMessageWithExtensionFallback(wallet, protocolParams, presignBytes, messageBytes);
|
|
329
388
|
const policyContext = opts?.policyContext ?? {
|
|
@@ -474,7 +533,33 @@ export class KairoClient {
|
|
|
474
533
|
async activateWallet(walletId, encryptedShareId, encryptionKeys, userPublicOutput) {
|
|
475
534
|
// Wait a moment for the dWallet state to propagate
|
|
476
535
|
await new Promise((r) => setTimeout(r, 2000));
|
|
477
|
-
const
|
|
536
|
+
const rpcUrlForActivation = await this.resolveSuiRpcUrl();
|
|
537
|
+
const dWallet = await withRetry(() => fetchDWallet(rpcUrlForActivation, this.network, walletId), { label: "fetchDWallet(activate)" });
|
|
538
|
+
// Check dWallet state - skip activation if already active
|
|
539
|
+
const state = dWallet?.state;
|
|
540
|
+
const isActive = Boolean(state?.Active) || state?.$kind === "Active";
|
|
541
|
+
if (isActive) {
|
|
542
|
+
// Already activated, nothing to do
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const isAwaitingSignature = Boolean(state?.AwaitingKeyHolderSignature) ||
|
|
546
|
+
state?.$kind === "AwaitingKeyHolderSignature";
|
|
547
|
+
if (!isAwaitingSignature) {
|
|
548
|
+
// Unknown state - wait and retry once
|
|
549
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
550
|
+
const dWallet2 = await withRetry(() => fetchDWallet(rpcUrlForActivation, this.network, walletId), { label: "fetchDWallet(activate-recheck)" });
|
|
551
|
+
const state2 = dWallet2?.state;
|
|
552
|
+
const isActive2 = Boolean(state2?.Active) || state2?.$kind === "Active";
|
|
553
|
+
if (isActive2)
|
|
554
|
+
return;
|
|
555
|
+
const isAwaiting2 = Boolean(state2?.AwaitingKeyHolderSignature) ||
|
|
556
|
+
state2?.$kind === "AwaitingKeyHolderSignature";
|
|
557
|
+
if (!isAwaiting2) {
|
|
558
|
+
const stateKind = state2?.$kind ?? Object.keys(state2 ?? {})[0] ?? "Unknown";
|
|
559
|
+
throw new Error(`dWallet is not ready for activation (state=${stateKind}). ` +
|
|
560
|
+
`This can happen if the DKG is still processing. Wait a few seconds and retry.`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
478
563
|
const signature = await computeUserOutputSignature({
|
|
479
564
|
encryptionKeys,
|
|
480
565
|
dWallet,
|
package/dist/ika-protocol.js
CHANGED
|
@@ -12,22 +12,43 @@ function resolveCurve(curve) {
|
|
|
12
12
|
}
|
|
13
13
|
// Protocol params are large (~MB). Cache per curve to avoid refetching.
|
|
14
14
|
const paramsCache = new Map();
|
|
15
|
+
// Reuse a single initialized Ika client per (network + RPC URL) to avoid
|
|
16
|
+
// repeated initialize() bursts that can trigger upstream rate limits.
|
|
17
|
+
const clientCache = new Map();
|
|
18
|
+
function getClientCacheKey(network, suiRpcUrl) {
|
|
19
|
+
return `${network}:${suiRpcUrl}`;
|
|
20
|
+
}
|
|
21
|
+
function getOrCreateIkaClient(network, suiRpcUrl) {
|
|
22
|
+
const key = getClientCacheKey(network, suiRpcUrl);
|
|
23
|
+
const cached = clientCache.get(key);
|
|
24
|
+
if (cached)
|
|
25
|
+
return cached;
|
|
26
|
+
const suiClient = new SuiClient({ url: suiRpcUrl });
|
|
27
|
+
const ikaConfig = getNetworkConfig(network);
|
|
28
|
+
const ikaClient = new IkaClient({ suiClient, config: ikaConfig });
|
|
29
|
+
const ready = ikaClient.initialize().catch((err) => {
|
|
30
|
+
clientCache.delete(key);
|
|
31
|
+
throw err;
|
|
32
|
+
});
|
|
33
|
+
const created = { ikaClient, ready };
|
|
34
|
+
clientCache.set(key, created);
|
|
35
|
+
return created;
|
|
36
|
+
}
|
|
15
37
|
/**
|
|
16
38
|
* Fetch Ika protocol public parameters for a given curve.
|
|
17
39
|
* Uses the IkaClient which reads from the Ika coordinator on Sui.
|
|
18
40
|
*/
|
|
19
41
|
export async function fetchProtocolParams(curve, suiRpcUrl, network = "testnet") {
|
|
20
42
|
const ikaCurve = resolveCurve(curve);
|
|
21
|
-
const
|
|
43
|
+
const paramsCacheKey = `${getClientCacheKey(network, suiRpcUrl)}:${ikaCurve}`;
|
|
44
|
+
const cached = paramsCache.get(paramsCacheKey);
|
|
22
45
|
if (cached)
|
|
23
46
|
return cached;
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const ikaClient = new IkaClient({ suiClient, config: ikaConfig });
|
|
27
|
-
await ikaClient.initialize();
|
|
47
|
+
const { ikaClient, ready } = getOrCreateIkaClient(network, suiRpcUrl);
|
|
48
|
+
await ready;
|
|
28
49
|
// First arg is dWallet (undefined for new wallets), second is curve
|
|
29
50
|
const params = await ikaClient.getProtocolPublicParameters(undefined, ikaCurve);
|
|
30
|
-
paramsCache.set(
|
|
51
|
+
paramsCache.set(paramsCacheKey, params);
|
|
31
52
|
return params;
|
|
32
53
|
}
|
|
33
54
|
/**
|
|
@@ -73,10 +94,8 @@ export async function computeUserOutputSignature(params) {
|
|
|
73
94
|
* Fetch the dWallet object from Ika network for activation.
|
|
74
95
|
*/
|
|
75
96
|
export async function fetchDWallet(suiRpcUrl, network, dwalletId) {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
const ikaClient = new IkaClient({ suiClient, config: ikaConfig });
|
|
79
|
-
await ikaClient.initialize();
|
|
97
|
+
const { ikaClient, ready } = getOrCreateIkaClient(network, suiRpcUrl);
|
|
98
|
+
await ready;
|
|
80
99
|
return ikaClient.getDWallet(dwalletId);
|
|
81
100
|
}
|
|
82
101
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * from "./types";
|
|
2
|
-
export * from "./evmIntent";
|
|
3
|
-
export * from "./evm";
|
|
4
|
-
export * from "./bitcoinIntent";
|
|
5
|
-
export { type SolanaCluster, LAMPORTS_PER_SOL, type ParsedInstruction, type ParsedSolanaTransaction, type SolanaIntent, PROGRAM_IDS, SystemInstructionType, base58Decode, base58Encode, validateSolanaAddress, computeSolanaIntentHash, isKnownSafeProgram, isTokenProgram, getProgramName, lamportsToSOL, solToLamports, extractSystemTransfers, } from "./solanaIntent";
|
|
6
|
-
export * from "./suiReceipts";
|
|
7
|
-
export * from "./suiResult";
|
|
8
|
-
export * from "./suiTxBuilders";
|
|
9
|
-
export * from "./auditBundle";
|
|
10
|
-
export * from "./suiCustody";
|
|
11
|
-
export { KairoClient, type KairoClientOpts, type CreateWalletOpts, type WalletInfo, type ProposePolicyUpdateParams, type PolicyUpdateProposalResult, type ApprovePolicyUpdateParams, type ExecutePolicyUpdateParams, type PolicyUpdateStatus, } from "./client";
|
|
12
|
-
export { KeyStore, type WalletRecord } from "./keystore";
|
|
13
|
-
export { BackendClient, DEFAULT_BACKEND_URL, type BackendClientOpts } from "./backend";
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./evmIntent.js";
|
|
3
|
+
export * from "./evm.js";
|
|
4
|
+
export * from "./bitcoinIntent.js";
|
|
5
|
+
export { type SolanaCluster, LAMPORTS_PER_SOL, type ParsedInstruction, type ParsedSolanaTransaction, type SolanaIntent, PROGRAM_IDS, SystemInstructionType, base58Decode, base58Encode, validateSolanaAddress, computeSolanaIntentHash, isKnownSafeProgram, isTokenProgram, getProgramName, lamportsToSOL, solToLamports, extractSystemTransfers, } from "./solanaIntent.js";
|
|
6
|
+
export * from "./suiReceipts.js";
|
|
7
|
+
export * from "./suiResult.js";
|
|
8
|
+
export * from "./suiTxBuilders.js";
|
|
9
|
+
export * from "./auditBundle.js";
|
|
10
|
+
export * from "./suiCustody.js";
|
|
11
|
+
export { KairoClient, type KairoClientOpts, type CreateWalletOpts, type WalletInfo, type ProposePolicyUpdateParams, type PolicyUpdateProposalResult, type ApprovePolicyUpdateParams, type ExecutePolicyUpdateParams, type PolicyUpdateStatus, } from "./client.js";
|
|
12
|
+
export { KeyStore, type WalletRecord } from "./keystore.js";
|
|
13
|
+
export { BackendClient, DEFAULT_BACKEND_URL, type BackendClientOpts } from "./backend.js";
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export * from "./types";
|
|
2
|
-
export * from "./evmIntent";
|
|
3
|
-
export * from "./evm";
|
|
4
|
-
export * from "./bitcoinIntent";
|
|
5
|
-
export { LAMPORTS_PER_SOL, PROGRAM_IDS, SystemInstructionType, base58Decode, base58Encode, validateSolanaAddress, computeSolanaIntentHash, isKnownSafeProgram, isTokenProgram, getProgramName, lamportsToSOL, solToLamports, extractSystemTransfers, } from "./solanaIntent";
|
|
6
|
-
export * from "./suiReceipts";
|
|
7
|
-
export * from "./suiResult";
|
|
8
|
-
export * from "./suiTxBuilders";
|
|
9
|
-
export * from "./auditBundle";
|
|
10
|
-
export * from "./suiCustody";
|
|
11
|
-
export { KairoClient, } from "./client";
|
|
12
|
-
export { KeyStore } from "./keystore";
|
|
13
|
-
export { BackendClient, DEFAULT_BACKEND_URL } from "./backend";
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./evmIntent.js";
|
|
3
|
+
export * from "./evm.js";
|
|
4
|
+
export * from "./bitcoinIntent.js";
|
|
5
|
+
export { LAMPORTS_PER_SOL, PROGRAM_IDS, SystemInstructionType, base58Decode, base58Encode, validateSolanaAddress, computeSolanaIntentHash, isKnownSafeProgram, isTokenProgram, getProgramName, lamportsToSOL, solToLamports, extractSystemTransfers, } from "./solanaIntent.js";
|
|
6
|
+
export * from "./suiReceipts.js";
|
|
7
|
+
export * from "./suiResult.js";
|
|
8
|
+
export * from "./suiTxBuilders.js";
|
|
9
|
+
export * from "./auditBundle.js";
|
|
10
|
+
export * from "./suiCustody.js";
|
|
11
|
+
export { KairoClient, } from "./client.js";
|
|
12
|
+
export { KeyStore } from "./keystore.js";
|
|
13
|
+
export { BackendClient, DEFAULT_BACKEND_URL } from "./backend.js";
|