@kairoguard/sdk 0.0.1
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 +92 -0
- package/dist/auditBundle.d.ts +28 -0
- package/dist/auditBundle.js +20 -0
- package/dist/backend.d.ts +288 -0
- package/dist/backend.js +107 -0
- package/dist/bitcoinIntent.d.ts +104 -0
- package/dist/bitcoinIntent.js +126 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +237 -0
- package/dist/client.d.ts +186 -0
- package/dist/client.js +767 -0
- package/dist/evm.d.ts +19 -0
- package/dist/evm.js +53 -0
- package/dist/evmIntent.d.ts +11 -0
- package/dist/evmIntent.js +12 -0
- package/dist/ika-protocol.d.ts +85 -0
- package/dist/ika-protocol.js +156 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/keystore.d.ts +29 -0
- package/dist/keystore.js +53 -0
- package/dist/skill-templates.d.ts +9 -0
- package/dist/skill-templates.js +252 -0
- package/dist/solanaIntent.d.ts +128 -0
- package/dist/solanaIntent.js +214 -0
- package/dist/suiCustody.d.ts +14 -0
- package/dist/suiCustody.js +183 -0
- package/dist/suiReceipts.d.ts +27 -0
- package/dist/suiReceipts.js +203 -0
- package/dist/suiResult.d.ts +8 -0
- package/dist/suiResult.js +12 -0
- package/dist/suiTxBuilders.d.ts +15 -0
- package/dist/suiTxBuilders.js +38 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +1 -0
- package/package.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# `@kairo/sdk` (MVP)
|
|
2
|
+
|
|
3
|
+
MVP helpers for:
|
|
4
|
+
|
|
5
|
+
- computing an **EVM intent hash** (Keccak256 over serialized unsigned tx bytes)
|
|
6
|
+
- building a Sui transaction to mint a **hard-gate** `PolicyReceipt`
|
|
7
|
+
- fetching + validating a `PolicyReceipt` / `PolicyReceiptV2` object for gating
|
|
8
|
+
- verifying a Sui custody `CustodyEvent` hash (v2/v3 canonical BCS hashing)
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
From repo root:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## DApp flow (user mints receipt with their Sui wallet)
|
|
19
|
+
|
|
20
|
+
1) Your app computes the EVM unsigned tx bytes and intent hash:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { computeEvmIntentFromUnsignedTxBytes } from "@kairo/sdk";
|
|
24
|
+
|
|
25
|
+
const { intentHash } = computeEvmIntentFromUnsignedTxBytes({
|
|
26
|
+
chainId: 84532, // Base Sepolia (example)
|
|
27
|
+
unsignedTxBytesHex, // 0x... serialized unsigned EIP-1559 tx bytes
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2) Build a Sui tx that mints a receipt:
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { buildMintEvmReceiptTx } from "@kairo/sdk";
|
|
35
|
+
|
|
36
|
+
const tx = buildMintEvmReceiptTx({
|
|
37
|
+
packageId,
|
|
38
|
+
policyObjectId,
|
|
39
|
+
evmChainId: 84532,
|
|
40
|
+
intentHash,
|
|
41
|
+
toEvm,
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
3) Have the user sign+execute the Sui tx with their wallet (example using Sui dApp kit):
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// Pseudocode: your wallet adapter will differ depending on your stack.
|
|
49
|
+
const result = await wallet.signAndExecuteTransaction({
|
|
50
|
+
transaction: tx,
|
|
51
|
+
chain: "sui:testnet",
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
4) Extract the created receipt object id from the execution result, then hard-gate EVM signing:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// We’ll add a helper for extracting created receipt IDs once we standardize receipt type strings.
|
|
59
|
+
// For now, you can scan result.effects.created for the created object id of PolicyReceipt.
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Demo/extension flow (backend mints receipt)
|
|
63
|
+
|
|
64
|
+
In this repo’s Key‑Spring demo, the backend mints the receipt (so the extension UX stays “approve action” instead of “approve Sui tx”).
|
|
65
|
+
The verifier helper `fetchAndValidatePolicyReceipt` supports both receipt types:
|
|
66
|
+
|
|
67
|
+
- legacy `PolicyReceipt` (MVP)
|
|
68
|
+
- `PolicyReceiptV2` (includes `policy_root` + `policy_version_id` + optional selector/amount)
|
|
69
|
+
|
|
70
|
+
If you also log to the custody ledger, you can verify a specific custody event hash:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { fetchAndVerifyCustodyEvent } from "@kairo/sdk";
|
|
74
|
+
|
|
75
|
+
const res = await fetchAndVerifyCustodyEvent({
|
|
76
|
+
suiRpcUrl,
|
|
77
|
+
custodyEventObjectId: "0x...",
|
|
78
|
+
});
|
|
79
|
+
if (!res.ok) throw new Error(res.error);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Hex } from "./types";
|
|
2
|
+
export type AuditBundle = {
|
|
3
|
+
v: 1;
|
|
4
|
+
network: "testnet" | "mainnet";
|
|
5
|
+
receipts: Array<{
|
|
6
|
+
receiptObjectId: string;
|
|
7
|
+
expected: {
|
|
8
|
+
policyId: string;
|
|
9
|
+
policyVersion: string;
|
|
10
|
+
evmChainId: number;
|
|
11
|
+
intentHash: Hex;
|
|
12
|
+
toEvm: Hex;
|
|
13
|
+
};
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Minimal verifier for an audit bundle (v1).
|
|
18
|
+
* This intentionally verifies only receipt commitments using on-chain receipt contents.
|
|
19
|
+
*/
|
|
20
|
+
export declare function verifyAuditBundle(args: {
|
|
21
|
+
suiRpcUrl: string;
|
|
22
|
+
bundle: AuditBundle;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
ok: true;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
error: string;
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fetchAndValidatePolicyReceipt } from "./suiReceipts";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal verifier for an audit bundle (v1).
|
|
4
|
+
* This intentionally verifies only receipt commitments using on-chain receipt contents.
|
|
5
|
+
*/
|
|
6
|
+
export async function verifyAuditBundle(args) {
|
|
7
|
+
try {
|
|
8
|
+
for (const r of args.bundle.receipts) {
|
|
9
|
+
await fetchAndValidatePolicyReceipt({
|
|
10
|
+
suiRpcUrl: args.suiRpcUrl,
|
|
11
|
+
receiptObjectId: r.receiptObjectId,
|
|
12
|
+
expected: r.expected,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return { ok: true };
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Kairo backend API.
|
|
3
|
+
*
|
|
4
|
+
* Handles authentication, request formatting, and response parsing.
|
|
5
|
+
* All methods automatically attach the X-Kairo-Api-Key header.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_BACKEND_URL = "https://api.kairoguard.com";
|
|
8
|
+
export interface BackendClientOpts {
|
|
9
|
+
backendUrl?: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface HealthResponse {
|
|
13
|
+
status: string;
|
|
14
|
+
adminAddress: string;
|
|
15
|
+
suiNetwork: string;
|
|
16
|
+
timestamp: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DKGSubmitRequest {
|
|
19
|
+
userPublicOutput: number[];
|
|
20
|
+
userDkgMessage: number[];
|
|
21
|
+
encryptedUserShareAndProof: number[];
|
|
22
|
+
sessionIdentifier: number[];
|
|
23
|
+
signerPublicKey: number[];
|
|
24
|
+
encryptionKeyAddress: string;
|
|
25
|
+
encryptionKey: number[];
|
|
26
|
+
encryptionKeySignature: number[];
|
|
27
|
+
curve?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface DKGSubmitResponse {
|
|
30
|
+
success: boolean;
|
|
31
|
+
requestId: string;
|
|
32
|
+
status: string;
|
|
33
|
+
}
|
|
34
|
+
export interface DKGStatusResponse {
|
|
35
|
+
success: boolean;
|
|
36
|
+
requestId: string;
|
|
37
|
+
status: "pending" | "processing" | "completed" | "failed";
|
|
38
|
+
dWalletCapObjectId?: string;
|
|
39
|
+
dWalletObjectId?: string;
|
|
40
|
+
encryptedUserSecretKeyShareId?: string;
|
|
41
|
+
ethereumAddress?: string;
|
|
42
|
+
solanaAddress?: string;
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ProvisionRequest {
|
|
46
|
+
dwalletObjectId: string;
|
|
47
|
+
policyObjectId: string;
|
|
48
|
+
stableId: string;
|
|
49
|
+
isImportedKey?: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface ProvisionResponse {
|
|
52
|
+
success: boolean;
|
|
53
|
+
digest: string;
|
|
54
|
+
bindingObjectId: string | null;
|
|
55
|
+
vaultObjectId: string;
|
|
56
|
+
dwalletObjectId: string;
|
|
57
|
+
walletState: string;
|
|
58
|
+
}
|
|
59
|
+
export interface RegisterKeyRequest {
|
|
60
|
+
label: string;
|
|
61
|
+
email?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface RegisterKeyResponse {
|
|
64
|
+
success: boolean;
|
|
65
|
+
apiKey: string;
|
|
66
|
+
label: string;
|
|
67
|
+
tier: string;
|
|
68
|
+
createdAt: number;
|
|
69
|
+
}
|
|
70
|
+
export type RequestStatus = "pending" | "processing" | "completed" | "failed";
|
|
71
|
+
export interface PresignRequestParams {
|
|
72
|
+
dWalletId: string;
|
|
73
|
+
dWalletCapId?: string;
|
|
74
|
+
curve?: number;
|
|
75
|
+
signatureAlgorithm?: number;
|
|
76
|
+
encryptedUserSecretKeyShareId?: string;
|
|
77
|
+
userOutputSignature?: number[];
|
|
78
|
+
}
|
|
79
|
+
export interface PresignRequestResponse {
|
|
80
|
+
success: boolean;
|
|
81
|
+
requestId: string;
|
|
82
|
+
status: RequestStatus;
|
|
83
|
+
}
|
|
84
|
+
export interface PresignStatusResponse {
|
|
85
|
+
success: boolean;
|
|
86
|
+
requestId: string;
|
|
87
|
+
status: RequestStatus;
|
|
88
|
+
presignId?: string;
|
|
89
|
+
presignBytes?: number[];
|
|
90
|
+
error?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface EthTxParams {
|
|
93
|
+
to: string;
|
|
94
|
+
value: string;
|
|
95
|
+
nonce: number;
|
|
96
|
+
gasLimit: string;
|
|
97
|
+
maxFeePerGas: string;
|
|
98
|
+
maxPriorityFeePerGas: string;
|
|
99
|
+
chainId: number;
|
|
100
|
+
from: string;
|
|
101
|
+
}
|
|
102
|
+
export interface SignRequestParams {
|
|
103
|
+
dWalletId: string;
|
|
104
|
+
dWalletCapId: string;
|
|
105
|
+
encryptedUserSecretKeyShareId: string;
|
|
106
|
+
userOutputSignature: number[];
|
|
107
|
+
presignId: string;
|
|
108
|
+
messageHex: string;
|
|
109
|
+
userSignMessage: number[];
|
|
110
|
+
policyReceiptId: string;
|
|
111
|
+
policyBindingObjectId?: string;
|
|
112
|
+
policyObjectId?: string;
|
|
113
|
+
policyVersion?: string;
|
|
114
|
+
custodyChainObjectId?: string;
|
|
115
|
+
custodyPackageId?: string;
|
|
116
|
+
ethTx?: EthTxParams;
|
|
117
|
+
}
|
|
118
|
+
export interface SignRequestResponse {
|
|
119
|
+
success: boolean;
|
|
120
|
+
requestId: string;
|
|
121
|
+
status: RequestStatus;
|
|
122
|
+
}
|
|
123
|
+
export interface SignStatusResponse {
|
|
124
|
+
success: boolean;
|
|
125
|
+
requestId: string;
|
|
126
|
+
status: RequestStatus;
|
|
127
|
+
digest?: string;
|
|
128
|
+
signatureHex?: string;
|
|
129
|
+
signId?: string;
|
|
130
|
+
ethTxHash?: string;
|
|
131
|
+
ethBlockNumber?: number;
|
|
132
|
+
error?: string;
|
|
133
|
+
}
|
|
134
|
+
export interface CreatePolicyV4Rule {
|
|
135
|
+
ruleType: number;
|
|
136
|
+
namespace?: number;
|
|
137
|
+
params: string;
|
|
138
|
+
}
|
|
139
|
+
export interface CreatePolicyV4Params {
|
|
140
|
+
stableId: string;
|
|
141
|
+
version: string;
|
|
142
|
+
expiresAtMs?: number;
|
|
143
|
+
allowNamespaces?: number[];
|
|
144
|
+
allowChainIds?: Array<{
|
|
145
|
+
namespace: number;
|
|
146
|
+
chainId: string;
|
|
147
|
+
}>;
|
|
148
|
+
allowDestinations?: string[];
|
|
149
|
+
denyDestinations?: string[];
|
|
150
|
+
rules: CreatePolicyV4Rule[];
|
|
151
|
+
}
|
|
152
|
+
export interface CreatePolicyV4Response {
|
|
153
|
+
success: boolean;
|
|
154
|
+
policyObjectId: string;
|
|
155
|
+
digest: string;
|
|
156
|
+
error?: string;
|
|
157
|
+
}
|
|
158
|
+
export interface RegisterFromPolicyParams {
|
|
159
|
+
policyObjectId: string;
|
|
160
|
+
note?: string;
|
|
161
|
+
registryObjectId?: string;
|
|
162
|
+
}
|
|
163
|
+
export interface RegisterFromPolicyResponse {
|
|
164
|
+
success: boolean;
|
|
165
|
+
policyVersionObjectId: string;
|
|
166
|
+
digest: string;
|
|
167
|
+
error?: string;
|
|
168
|
+
}
|
|
169
|
+
export interface GovernanceProposeParams {
|
|
170
|
+
governanceId: string;
|
|
171
|
+
bindingId: string;
|
|
172
|
+
targetVersionId: string;
|
|
173
|
+
}
|
|
174
|
+
export interface GovernanceProposeResponse {
|
|
175
|
+
success: boolean;
|
|
176
|
+
proposalId: string;
|
|
177
|
+
digest: string;
|
|
178
|
+
error?: string;
|
|
179
|
+
}
|
|
180
|
+
export interface GovernanceApproveParams {
|
|
181
|
+
governanceId: string;
|
|
182
|
+
proposalId: string;
|
|
183
|
+
}
|
|
184
|
+
export interface GovernanceApproveResponse {
|
|
185
|
+
success: boolean;
|
|
186
|
+
digest: string;
|
|
187
|
+
error?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface GovernanceExecuteAndReaffirmParams {
|
|
190
|
+
governanceId: string;
|
|
191
|
+
proposalId: string;
|
|
192
|
+
bindingObjectId: string;
|
|
193
|
+
}
|
|
194
|
+
export interface GovernanceExecuteAndReaffirmResponse {
|
|
195
|
+
success: boolean;
|
|
196
|
+
digest: string;
|
|
197
|
+
error?: string;
|
|
198
|
+
}
|
|
199
|
+
export interface GovernanceInfo {
|
|
200
|
+
id: string;
|
|
201
|
+
stableId: string;
|
|
202
|
+
approvers: string[];
|
|
203
|
+
threshold: number;
|
|
204
|
+
timelockDurationMs: number;
|
|
205
|
+
proposalCount: number;
|
|
206
|
+
admin: string;
|
|
207
|
+
}
|
|
208
|
+
export interface GovernanceGetResponse {
|
|
209
|
+
success: boolean;
|
|
210
|
+
governance?: GovernanceInfo;
|
|
211
|
+
error?: string;
|
|
212
|
+
}
|
|
213
|
+
export interface GovernanceProposalInfo {
|
|
214
|
+
id: string;
|
|
215
|
+
governanceId: string;
|
|
216
|
+
bindingId: string;
|
|
217
|
+
targetVersionId: string;
|
|
218
|
+
proposer: string;
|
|
219
|
+
approvals: string[];
|
|
220
|
+
createdAtMs: number;
|
|
221
|
+
thresholdMetAtMs: number;
|
|
222
|
+
executed: boolean;
|
|
223
|
+
cancelled: boolean;
|
|
224
|
+
}
|
|
225
|
+
export interface GovernanceProposalGetResponse {
|
|
226
|
+
success: boolean;
|
|
227
|
+
proposal?: GovernanceProposalInfo;
|
|
228
|
+
error?: string;
|
|
229
|
+
}
|
|
230
|
+
export interface PolicyDetailsResponse {
|
|
231
|
+
success: boolean;
|
|
232
|
+
policy?: Record<string, unknown>;
|
|
233
|
+
error?: string;
|
|
234
|
+
}
|
|
235
|
+
export interface DWalletFullResponse {
|
|
236
|
+
success: boolean;
|
|
237
|
+
dWallet?: unknown;
|
|
238
|
+
error?: string;
|
|
239
|
+
}
|
|
240
|
+
export interface SuiObjectResponse {
|
|
241
|
+
success: boolean;
|
|
242
|
+
object?: {
|
|
243
|
+
data?: {
|
|
244
|
+
content?: {
|
|
245
|
+
fields?: Record<string, unknown>;
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
error?: string;
|
|
250
|
+
}
|
|
251
|
+
export declare class BackendClient {
|
|
252
|
+
private baseUrl;
|
|
253
|
+
private apiKey;
|
|
254
|
+
constructor(opts: BackendClientOpts);
|
|
255
|
+
setApiKey(key: string): void;
|
|
256
|
+
private request;
|
|
257
|
+
getHealth(): Promise<HealthResponse>;
|
|
258
|
+
register(label: string, email?: string): Promise<RegisterKeyResponse>;
|
|
259
|
+
submitDKG(data: DKGSubmitRequest): Promise<DKGSubmitResponse>;
|
|
260
|
+
getDKGStatus(requestId: string): Promise<DKGStatusResponse>;
|
|
261
|
+
provision(params: ProvisionRequest): Promise<ProvisionResponse>;
|
|
262
|
+
mintReceipt(params: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
263
|
+
requestPresign(params: PresignRequestParams): Promise<PresignRequestResponse>;
|
|
264
|
+
getPresignStatus(requestId: string): Promise<PresignStatusResponse>;
|
|
265
|
+
requestSign(params: SignRequestParams): Promise<SignRequestResponse>;
|
|
266
|
+
getSignStatus(requestId: string): Promise<SignStatusResponse>;
|
|
267
|
+
createPolicyV4(params: CreatePolicyV4Params): Promise<CreatePolicyV4Response>;
|
|
268
|
+
registerPolicyVersionFromPolicy(params: RegisterFromPolicyParams): Promise<RegisterFromPolicyResponse>;
|
|
269
|
+
proposeGovernancePolicyChange(params: GovernanceProposeParams): Promise<GovernanceProposeResponse>;
|
|
270
|
+
approveGovernancePolicyChange(params: GovernanceApproveParams): Promise<GovernanceApproveResponse>;
|
|
271
|
+
executeAndReaffirmGovernancePolicyChange(params: GovernanceExecuteAndReaffirmParams): Promise<GovernanceExecuteAndReaffirmResponse>;
|
|
272
|
+
getGovernance(governanceId: string): Promise<GovernanceGetResponse>;
|
|
273
|
+
getGovernanceProposal(proposalId: string): Promise<GovernanceProposalGetResponse>;
|
|
274
|
+
getPolicy(policyObjectId: string): Promise<PolicyDetailsResponse>;
|
|
275
|
+
getDWalletFull(dWalletId: string): Promise<DWalletFullResponse>;
|
|
276
|
+
getSuiObject(objectId: string): Promise<SuiObjectResponse>;
|
|
277
|
+
policySign(params: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
278
|
+
activateDWallet(params: {
|
|
279
|
+
dWalletId: string;
|
|
280
|
+
encryptedUserSecretKeyShareId: string;
|
|
281
|
+
userOutputSignature: number[];
|
|
282
|
+
}): Promise<{
|
|
283
|
+
success: boolean;
|
|
284
|
+
digest: string;
|
|
285
|
+
}>;
|
|
286
|
+
getVaultStatus(dWalletId: string): Promise<Record<string, unknown>>;
|
|
287
|
+
getAuditEvents(limit?: number): Promise<Record<string, unknown>>;
|
|
288
|
+
}
|
package/dist/backend.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the Kairo backend API.
|
|
3
|
+
*
|
|
4
|
+
* Handles authentication, request formatting, and response parsing.
|
|
5
|
+
* All methods automatically attach the X-Kairo-Api-Key header.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_BACKEND_URL = "https://api.kairoguard.com";
|
|
8
|
+
export class BackendClient {
|
|
9
|
+
baseUrl;
|
|
10
|
+
apiKey;
|
|
11
|
+
constructor(opts) {
|
|
12
|
+
this.baseUrl = (opts.backendUrl ?? DEFAULT_BACKEND_URL).replace(/\/+$/, "");
|
|
13
|
+
this.apiKey = opts.apiKey;
|
|
14
|
+
}
|
|
15
|
+
setApiKey(key) {
|
|
16
|
+
this.apiKey = key;
|
|
17
|
+
}
|
|
18
|
+
async request(method, path, body) {
|
|
19
|
+
const headers = { "Content-Type": "application/json" };
|
|
20
|
+
if (this.apiKey) {
|
|
21
|
+
headers["X-Kairo-Api-Key"] = this.apiKey;
|
|
22
|
+
}
|
|
23
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
24
|
+
method,
|
|
25
|
+
headers,
|
|
26
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
27
|
+
});
|
|
28
|
+
const json = await res.json();
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
const msg = json.error || json.message || `HTTP ${res.status}`;
|
|
31
|
+
throw new Error(`Kairo API error (${path}): ${msg}`);
|
|
32
|
+
}
|
|
33
|
+
return json;
|
|
34
|
+
}
|
|
35
|
+
async getHealth() {
|
|
36
|
+
return this.request("GET", "/health");
|
|
37
|
+
}
|
|
38
|
+
async register(label, email) {
|
|
39
|
+
return this.request("POST", "/api/keys/register", { label, email });
|
|
40
|
+
}
|
|
41
|
+
async submitDKG(data) {
|
|
42
|
+
return this.request("POST", "/api/dkg/submit", data);
|
|
43
|
+
}
|
|
44
|
+
async getDKGStatus(requestId) {
|
|
45
|
+
return this.request("GET", `/api/dkg/status/${requestId}`);
|
|
46
|
+
}
|
|
47
|
+
async provision(params) {
|
|
48
|
+
return this.request("POST", "/api/vault/provision", params);
|
|
49
|
+
}
|
|
50
|
+
async mintReceipt(params) {
|
|
51
|
+
return this.request("POST", "/api/policy/receipt/mint", params);
|
|
52
|
+
}
|
|
53
|
+
async requestPresign(params) {
|
|
54
|
+
return this.request("POST", "/api/presign/request", params);
|
|
55
|
+
}
|
|
56
|
+
async getPresignStatus(requestId) {
|
|
57
|
+
return this.request("GET", `/api/presign/status/${requestId}`);
|
|
58
|
+
}
|
|
59
|
+
async requestSign(params) {
|
|
60
|
+
return this.request("POST", "/api/sign/request", params);
|
|
61
|
+
}
|
|
62
|
+
async getSignStatus(requestId) {
|
|
63
|
+
return this.request("GET", `/api/sign/status/${requestId}`);
|
|
64
|
+
}
|
|
65
|
+
async createPolicyV4(params) {
|
|
66
|
+
return this.request("POST", "/api/policy/create", params);
|
|
67
|
+
}
|
|
68
|
+
async registerPolicyVersionFromPolicy(params) {
|
|
69
|
+
return this.request("POST", "/api/policy/registry/register-from-policy", params);
|
|
70
|
+
}
|
|
71
|
+
async proposeGovernancePolicyChange(params) {
|
|
72
|
+
return this.request("POST", "/api/policy/governance/propose", params);
|
|
73
|
+
}
|
|
74
|
+
async approveGovernancePolicyChange(params) {
|
|
75
|
+
return this.request("POST", "/api/policy/governance/approve", params);
|
|
76
|
+
}
|
|
77
|
+
async executeAndReaffirmGovernancePolicyChange(params) {
|
|
78
|
+
return this.request("POST", "/api/policy/governance/execute-and-reaffirm", params);
|
|
79
|
+
}
|
|
80
|
+
async getGovernance(governanceId) {
|
|
81
|
+
return this.request("GET", `/api/policy/governance/${governanceId}`);
|
|
82
|
+
}
|
|
83
|
+
async getGovernanceProposal(proposalId) {
|
|
84
|
+
return this.request("GET", `/api/policy/governance/proposal/${proposalId}`);
|
|
85
|
+
}
|
|
86
|
+
async getPolicy(policyObjectId) {
|
|
87
|
+
return this.request("GET", `/api/policies/${policyObjectId}`);
|
|
88
|
+
}
|
|
89
|
+
async getDWalletFull(dWalletId) {
|
|
90
|
+
return this.request("GET", `/api/dwallet/full/${dWalletId}`);
|
|
91
|
+
}
|
|
92
|
+
async getSuiObject(objectId) {
|
|
93
|
+
return this.request("GET", `/api/sui/object/${objectId}`);
|
|
94
|
+
}
|
|
95
|
+
async policySign(params) {
|
|
96
|
+
return this.request("POST", "/api/policy/sign", params);
|
|
97
|
+
}
|
|
98
|
+
async activateDWallet(params) {
|
|
99
|
+
return this.request("POST", "/api/dwallet/activate", params);
|
|
100
|
+
}
|
|
101
|
+
async getVaultStatus(dWalletId) {
|
|
102
|
+
return this.request("GET", `/api/vault/status/${dWalletId}`);
|
|
103
|
+
}
|
|
104
|
+
async getAuditEvents(limit = 10) {
|
|
105
|
+
return this.request("GET", `/api/audit/events?limit=${limit}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bitcoin Intent Utilities
|
|
3
|
+
*
|
|
4
|
+
* Client-side helpers for Bitcoin transaction intent hashing and validation.
|
|
5
|
+
*/
|
|
6
|
+
import type { Hex } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Bitcoin script types.
|
|
9
|
+
*/
|
|
10
|
+
export declare enum BitcoinScriptType {
|
|
11
|
+
P2PKH = 0,
|
|
12
|
+
P2WPKH = 1,
|
|
13
|
+
P2TR = 2
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Bitcoin network types.
|
|
17
|
+
*/
|
|
18
|
+
export type BitcoinNetwork = "mainnet" | "testnet" | "signet";
|
|
19
|
+
/**
|
|
20
|
+
* Parsed PSBT output.
|
|
21
|
+
*/
|
|
22
|
+
export interface PSBTOutput {
|
|
23
|
+
address: string;
|
|
24
|
+
value: bigint;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parsed PSBT input (UTXO).
|
|
28
|
+
*/
|
|
29
|
+
export interface PSBTInput {
|
|
30
|
+
txid: string;
|
|
31
|
+
vout: number;
|
|
32
|
+
value: bigint;
|
|
33
|
+
scriptType?: BitcoinScriptType;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Parsed PSBT structure.
|
|
37
|
+
*/
|
|
38
|
+
export interface ParsedPSBT {
|
|
39
|
+
inputs: PSBTInput[];
|
|
40
|
+
outputs: PSBTOutput[];
|
|
41
|
+
fee: bigint;
|
|
42
|
+
scriptType: BitcoinScriptType;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Bitcoin intent for policy verification.
|
|
46
|
+
*/
|
|
47
|
+
export interface BitcoinIntent {
|
|
48
|
+
network: BitcoinNetwork;
|
|
49
|
+
/** 32-byte intent hash (sighash) */
|
|
50
|
+
intentHash: Hex;
|
|
51
|
+
/** Destination addresses */
|
|
52
|
+
destinations: string[];
|
|
53
|
+
/** Amounts in satoshis */
|
|
54
|
+
amounts: bigint[];
|
|
55
|
+
/** Script type */
|
|
56
|
+
scriptType: BitcoinScriptType;
|
|
57
|
+
/** Raw PSBT hex */
|
|
58
|
+
psbtHex: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Compute double SHA256 (hash256).
|
|
62
|
+
*/
|
|
63
|
+
export declare function hash256(data: Uint8Array): Uint8Array;
|
|
64
|
+
/**
|
|
65
|
+
* Compute BIP340 tagged hash for Taproot.
|
|
66
|
+
*/
|
|
67
|
+
export declare function taggedHash(tag: string, data: Uint8Array): Uint8Array;
|
|
68
|
+
/**
|
|
69
|
+
* Convert hex string to bytes.
|
|
70
|
+
*/
|
|
71
|
+
export declare function hexToBytes(hex: string): Uint8Array;
|
|
72
|
+
/**
|
|
73
|
+
* Convert bytes to hex string.
|
|
74
|
+
*/
|
|
75
|
+
export declare function bytesToHex(bytes: Uint8Array): Hex;
|
|
76
|
+
/**
|
|
77
|
+
* Validate a Bitcoin address format.
|
|
78
|
+
* This is a basic check - full validation requires network context.
|
|
79
|
+
*/
|
|
80
|
+
export declare function validateBitcoinAddress(address: string, network?: BitcoinNetwork): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Detect script type from address format.
|
|
83
|
+
*/
|
|
84
|
+
export declare function detectScriptTypeFromAddress(address: string): BitcoinScriptType;
|
|
85
|
+
/**
|
|
86
|
+
* Compute total input value from parsed PSBT.
|
|
87
|
+
*/
|
|
88
|
+
export declare function computeTotalInputValue(psbt: ParsedPSBT): bigint;
|
|
89
|
+
/**
|
|
90
|
+
* Compute total output value from parsed PSBT.
|
|
91
|
+
*/
|
|
92
|
+
export declare function computeTotalOutputValue(psbt: ParsedPSBT): bigint;
|
|
93
|
+
/**
|
|
94
|
+
* Compute fee from parsed PSBT.
|
|
95
|
+
*/
|
|
96
|
+
export declare function computeFee(psbt: ParsedPSBT): bigint;
|
|
97
|
+
/**
|
|
98
|
+
* Format satoshis as BTC string.
|
|
99
|
+
*/
|
|
100
|
+
export declare function satoshisToBTC(satoshis: bigint): string;
|
|
101
|
+
/**
|
|
102
|
+
* Parse BTC string to satoshis.
|
|
103
|
+
*/
|
|
104
|
+
export declare function btcToSatoshis(btc: string | number): bigint;
|