@kairoguard/sdk 0.0.8 → 0.0.10
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/backend.d.ts +11 -0
- package/dist/backend.js +3 -0
- package/dist/cli.js +71 -6
- package/dist/client.d.ts +14 -0
- package/dist/client.js +141 -32
- package/dist/policy-templates.d.ts +16 -0
- package/dist/policy-templates.js +56 -0
- package/package.json +1 -1
package/dist/backend.d.ts
CHANGED
|
@@ -232,6 +232,16 @@ export interface PolicyDetailsResponse {
|
|
|
232
232
|
policy?: Record<string, unknown>;
|
|
233
233
|
error?: string;
|
|
234
234
|
}
|
|
235
|
+
export interface ReaffirmPolicyBindingParams {
|
|
236
|
+
bindingObjectId: string;
|
|
237
|
+
registryObjectId?: string;
|
|
238
|
+
}
|
|
239
|
+
export interface ReaffirmPolicyBindingResponse {
|
|
240
|
+
success: boolean;
|
|
241
|
+
digest: string;
|
|
242
|
+
activeVersionObjectId?: string;
|
|
243
|
+
error?: string;
|
|
244
|
+
}
|
|
235
245
|
export interface DWalletFullResponse {
|
|
236
246
|
success: boolean;
|
|
237
247
|
dWallet?: unknown;
|
|
@@ -273,6 +283,7 @@ export declare class BackendClient {
|
|
|
273
283
|
getGovernance(governanceId: string): Promise<GovernanceGetResponse>;
|
|
274
284
|
getGovernanceProposal(proposalId: string): Promise<GovernanceProposalGetResponse>;
|
|
275
285
|
getPolicy(policyObjectId: string): Promise<PolicyDetailsResponse>;
|
|
286
|
+
reaffirmPolicyBinding(params: ReaffirmPolicyBindingParams): Promise<ReaffirmPolicyBindingResponse>;
|
|
276
287
|
getDWalletFull(dWalletId: string): Promise<DWalletFullResponse>;
|
|
277
288
|
getSuiObject(objectId: string): Promise<SuiObjectResponse>;
|
|
278
289
|
policySign(params: Record<string, unknown>): Promise<Record<string, unknown>>;
|
package/dist/backend.js
CHANGED
|
@@ -89,6 +89,9 @@ export class BackendClient {
|
|
|
89
89
|
async getPolicy(policyObjectId) {
|
|
90
90
|
return this.request("GET", `/api/policies/${policyObjectId}`);
|
|
91
91
|
}
|
|
92
|
+
async reaffirmPolicyBinding(params) {
|
|
93
|
+
return this.request("POST", "/api/policy/binding/reaffirm", params);
|
|
94
|
+
}
|
|
92
95
|
async getDWalletFull(dWalletId) {
|
|
93
96
|
return this.request("GET", `/api/dwallet/full/${dWalletId}`);
|
|
94
97
|
}
|
package/dist/cli.js
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
+
import { createInterface } from "node:readline/promises";
|
|
6
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
5
7
|
import { verifyAuditBundle } from "./auditBundle.js";
|
|
6
8
|
import { BackendClient, DEFAULT_BACKEND_URL } from "./backend.js";
|
|
7
9
|
import { KairoClient } from "./client.js";
|
|
10
|
+
import { POLICY_TEMPLATE_PRESETS, buildPolicyTemplatePayload } from "./policy-templates.js";
|
|
8
11
|
import { SKILL_MD, API_REFERENCE_MD, SDK_REFERENCE_MD } from "./skill-templates.js";
|
|
9
12
|
const CONFIG_DIR = join(homedir(), ".kairo");
|
|
10
13
|
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
@@ -39,6 +42,9 @@ function flag(args, name) {
|
|
|
39
42
|
return undefined;
|
|
40
43
|
return args[idx + 1];
|
|
41
44
|
}
|
|
45
|
+
function hasFlag(args, name) {
|
|
46
|
+
return args.includes(name);
|
|
47
|
+
}
|
|
42
48
|
function requireFlag(args, name, label) {
|
|
43
49
|
const v = flag(args, name);
|
|
44
50
|
if (!v) {
|
|
@@ -47,6 +53,24 @@ function requireFlag(args, name, label) {
|
|
|
47
53
|
}
|
|
48
54
|
return v;
|
|
49
55
|
}
|
|
56
|
+
async function promptPolicyTemplateId() {
|
|
57
|
+
const rl = createInterface({ input, output });
|
|
58
|
+
try {
|
|
59
|
+
console.log("Choose a default policy template:");
|
|
60
|
+
console.log(` 1) ${POLICY_TEMPLATE_PRESETS["tpl-1"].label}`);
|
|
61
|
+
console.log(` 2) ${POLICY_TEMPLATE_PRESETS["tpl-2"].label}`);
|
|
62
|
+
console.log(` 3) ${POLICY_TEMPLATE_PRESETS["tpl-3"].label}`);
|
|
63
|
+
const answer = (await rl.question("Template [1/2/3] (default 2): ")).trim();
|
|
64
|
+
if (answer === "1")
|
|
65
|
+
return "tpl-1";
|
|
66
|
+
if (answer === "3")
|
|
67
|
+
return "tpl-3";
|
|
68
|
+
return "tpl-2";
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
rl.close();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
50
74
|
// ── Commands ────────────────────────────────────────────────────────────────
|
|
51
75
|
async function cmdInit(args) {
|
|
52
76
|
const apiKey = args[0];
|
|
@@ -88,17 +112,41 @@ async function cmdWalletCreate(args) {
|
|
|
88
112
|
}
|
|
89
113
|
const policyId = flag(args, "--policy-id");
|
|
90
114
|
const stableId = flag(args, "--stable-id");
|
|
115
|
+
const autoProvision = hasFlag(args, "--auto-provision");
|
|
91
116
|
const cfg = requireConfig();
|
|
117
|
+
let resolvedPolicyId = policyId;
|
|
118
|
+
if (autoProvision && !resolvedPolicyId) {
|
|
119
|
+
const templateId = await promptPolicyTemplateId();
|
|
120
|
+
const templatePayload = buildPolicyTemplatePayload(templateId);
|
|
121
|
+
const stable = stableId ?? `agent-policy-${Date.now()}`;
|
|
122
|
+
const client = getClient();
|
|
123
|
+
const created = await client.createPolicyV4({
|
|
124
|
+
stableId: stable,
|
|
125
|
+
version: "1.0.0",
|
|
126
|
+
allowNamespaces: templatePayload.allowNamespaces,
|
|
127
|
+
rules: templatePayload.rules,
|
|
128
|
+
});
|
|
129
|
+
if (!created.success || !created.policyObjectId?.startsWith("0x")) {
|
|
130
|
+
throw new Error(created.error ?? "Failed to create default policy from template");
|
|
131
|
+
}
|
|
132
|
+
await client.registerPolicyVersionFromPolicy({ policyObjectId: created.policyObjectId });
|
|
133
|
+
resolvedPolicyId = created.policyObjectId;
|
|
134
|
+
console.log(`Created + registered policy ${resolvedPolicyId} using ${templatePayload.template.id}.`);
|
|
135
|
+
}
|
|
92
136
|
const kairo = new KairoClient({
|
|
93
137
|
apiKey: cfg.apiKey,
|
|
94
138
|
backendUrl: cfg.backendUrl,
|
|
95
139
|
});
|
|
96
140
|
const wallet = await kairo.createWallet({
|
|
97
141
|
curve: curveRaw,
|
|
98
|
-
policyObjectId:
|
|
142
|
+
policyObjectId: resolvedPolicyId,
|
|
99
143
|
stableId,
|
|
100
144
|
});
|
|
101
145
|
console.log(JSON.stringify(wallet, null, 2));
|
|
146
|
+
if (!resolvedPolicyId) {
|
|
147
|
+
console.log("Wallet created but not provisioned. To show it in dashboard policies, run: " +
|
|
148
|
+
`kairo vault-provision --wallet-id ${wallet.walletId} --policy-id <policyObjectId> [--stable-id <id>]`);
|
|
149
|
+
}
|
|
102
150
|
}
|
|
103
151
|
async function cmdRegister(args) {
|
|
104
152
|
const label = requireFlag(args, "--label", "name");
|
|
@@ -141,9 +189,23 @@ async function cmdVaultStatus(args) {
|
|
|
141
189
|
async function cmdVaultProvision(args) {
|
|
142
190
|
const walletId = requireFlag(args, "--wallet-id", "dwalletId");
|
|
143
191
|
const policyId = requireFlag(args, "--policy-id", "objectId");
|
|
144
|
-
const stableId =
|
|
145
|
-
const
|
|
146
|
-
const
|
|
192
|
+
const stableId = flag(args, "--stable-id");
|
|
193
|
+
const cfg = requireConfig();
|
|
194
|
+
const kairo = new KairoClient({
|
|
195
|
+
apiKey: cfg.apiKey,
|
|
196
|
+
backendUrl: cfg.backendUrl,
|
|
197
|
+
});
|
|
198
|
+
const res = await kairo.provision(walletId, policyId, stableId);
|
|
199
|
+
console.log(JSON.stringify(res, null, 2));
|
|
200
|
+
}
|
|
201
|
+
async function cmdReaffirm(args) {
|
|
202
|
+
const walletId = requireFlag(args, "--wallet-id", "dwalletId");
|
|
203
|
+
const cfg = requireConfig();
|
|
204
|
+
const kairo = new KairoClient({
|
|
205
|
+
apiKey: cfg.apiKey,
|
|
206
|
+
backendUrl: cfg.backendUrl,
|
|
207
|
+
});
|
|
208
|
+
const res = await kairo.reaffirmBinding(walletId);
|
|
147
209
|
console.log(JSON.stringify(res, null, 2));
|
|
148
210
|
}
|
|
149
211
|
async function cmdReceiptMint(args) {
|
|
@@ -204,14 +266,15 @@ Setup:
|
|
|
204
266
|
|
|
205
267
|
Wallet & Policy:
|
|
206
268
|
health Server health check
|
|
207
|
-
wallet-create [--curve secp256k1|ed25519] [--policy-id <id>] [--stable-id <id>]
|
|
269
|
+
wallet-create [--curve secp256k1|ed25519] [--policy-id <id>] [--stable-id <id>] [--auto-provision]
|
|
208
270
|
Create a new dWallet via SDK DKG flow
|
|
209
271
|
register --label <name> Register new API key
|
|
210
272
|
policy-create --stable-id <id> --allow <addrs> Create policy
|
|
211
273
|
policy-register --policy-id <id> Register policy version
|
|
212
274
|
policy-details --policy-id <id> Get policy details
|
|
213
275
|
vault-status --wallet-id <id> Check vault registration
|
|
214
|
-
vault-provision --wallet-id <id> --policy-id <id> --stable-id <id>
|
|
276
|
+
vault-provision --wallet-id <id> --policy-id <id> [--stable-id <id>]
|
|
277
|
+
reaffirm --wallet-id <id> Reaffirm a wallet's current policy binding
|
|
215
278
|
receipt-mint --policy-id <id> --binding-id <id> --destination <hex> --intent-hash <hex>
|
|
216
279
|
|
|
217
280
|
Utility:
|
|
@@ -242,6 +305,8 @@ async function main() {
|
|
|
242
305
|
return cmdVaultStatus(rest);
|
|
243
306
|
case "vault-provision":
|
|
244
307
|
return cmdVaultProvision(rest);
|
|
308
|
+
case "reaffirm":
|
|
309
|
+
return cmdReaffirm(rest);
|
|
245
310
|
case "receipt-mint":
|
|
246
311
|
return cmdReceiptMint(rest);
|
|
247
312
|
case "audit":
|
package/dist/client.d.ts
CHANGED
|
@@ -153,6 +153,18 @@ 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
|
+
* Provision an existing local wallet into the policy vault.
|
|
158
|
+
* Persists binding/policy metadata to local keystore.
|
|
159
|
+
*/
|
|
160
|
+
provision(walletId: string, policyObjectId: string, stableId?: string): Promise<{
|
|
161
|
+
bindingObjectId: string;
|
|
162
|
+
digest: string;
|
|
163
|
+
}>;
|
|
164
|
+
reaffirmBinding(walletId: string): Promise<{
|
|
165
|
+
digest: string;
|
|
166
|
+
activeVersionObjectId?: string;
|
|
167
|
+
}>;
|
|
156
168
|
/**
|
|
157
169
|
* Governance-first policy update: creates a new policy + version, then proposes
|
|
158
170
|
* a change for approvers. This method does NOT execute/reaffirm directly.
|
|
@@ -182,6 +194,8 @@ export declare class KairoClient {
|
|
|
182
194
|
private pollPresignStatus;
|
|
183
195
|
private pollSignStatus;
|
|
184
196
|
private mintPolicyReceipt;
|
|
197
|
+
private resolvePolicyVersion;
|
|
198
|
+
private isReaffirmRequiredError;
|
|
185
199
|
private computeUserSignMessageWithExtensionFallback;
|
|
186
200
|
private rebuildSigningMaterialFromChain;
|
|
187
201
|
private resolveEvmRpcUrl;
|
package/dist/client.js
CHANGED
|
@@ -173,13 +173,8 @@ export class KairoClient {
|
|
|
173
173
|
// 10. Provision into vault (binding + registration) if policy is provided
|
|
174
174
|
let bindingObjectId;
|
|
175
175
|
if (opts?.policyObjectId) {
|
|
176
|
-
const provisionResult = await this.
|
|
177
|
-
|
|
178
|
-
policyObjectId: opts.policyObjectId,
|
|
179
|
-
stableId: opts.stableId ?? `agent-wallet-${walletId.slice(0, 8)}`,
|
|
180
|
-
});
|
|
181
|
-
bindingObjectId = provisionResult.bindingObjectId ?? undefined;
|
|
182
|
-
this.store.save({ ...record, bindingObjectId });
|
|
176
|
+
const provisionResult = await this.provision(walletId, opts.policyObjectId, opts.stableId);
|
|
177
|
+
bindingObjectId = provisionResult.bindingObjectId;
|
|
183
178
|
}
|
|
184
179
|
return {
|
|
185
180
|
walletId,
|
|
@@ -212,6 +207,56 @@ export class KairoClient {
|
|
|
212
207
|
createdAt: r.createdAt,
|
|
213
208
|
};
|
|
214
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Provision an existing local wallet into the policy vault.
|
|
212
|
+
* Persists binding/policy metadata to local keystore.
|
|
213
|
+
*/
|
|
214
|
+
async provision(walletId, policyObjectId, stableId) {
|
|
215
|
+
const wallet = this.requireWalletRecord(walletId);
|
|
216
|
+
if (!policyObjectId?.startsWith("0x")) {
|
|
217
|
+
throw new Error("policyObjectId must be a valid 0x object id");
|
|
218
|
+
}
|
|
219
|
+
const result = await this.backend.provision({
|
|
220
|
+
dwalletObjectId: walletId,
|
|
221
|
+
policyObjectId,
|
|
222
|
+
stableId: stableId ?? `agent-wallet-${walletId.slice(0, 8)}`,
|
|
223
|
+
});
|
|
224
|
+
const bindingObjectId = String(result.bindingObjectId ?? "");
|
|
225
|
+
if (!bindingObjectId.startsWith("0x")) {
|
|
226
|
+
throw new Error("Provision succeeded but no bindingObjectId was returned");
|
|
227
|
+
}
|
|
228
|
+
this.store.save({
|
|
229
|
+
...wallet,
|
|
230
|
+
bindingObjectId,
|
|
231
|
+
policyObjectId,
|
|
232
|
+
});
|
|
233
|
+
return { bindingObjectId, digest: result.digest };
|
|
234
|
+
}
|
|
235
|
+
async reaffirmBinding(walletId) {
|
|
236
|
+
const wallet = this.requireWalletRecord(walletId);
|
|
237
|
+
if (!wallet.bindingObjectId?.startsWith("0x")) {
|
|
238
|
+
throw new Error("Wallet is missing bindingObjectId. Provision the wallet before reaffirming.");
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
const result = await this.backend.reaffirmPolicyBinding({
|
|
242
|
+
bindingObjectId: wallet.bindingObjectId,
|
|
243
|
+
});
|
|
244
|
+
return {
|
|
245
|
+
digest: result.digest,
|
|
246
|
+
activeVersionObjectId: result.activeVersionObjectId,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
251
|
+
const governedGuardTriggered = /binding is governed/i.test(message) ||
|
|
252
|
+
/requires governance receipt flow/i.test(message) ||
|
|
253
|
+
/execute-and-reaffirm/i.test(message);
|
|
254
|
+
if (governedGuardTriggered) {
|
|
255
|
+
throw new Error("Binding is governed and cannot be directly reaffirmed. Complete governance execute-and-reaffirm first, then retry signing.");
|
|
256
|
+
}
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
215
260
|
/**
|
|
216
261
|
* Governance-first policy update: creates a new policy + version, then proposes
|
|
217
262
|
* a change for approvers. This method does NOT execute/reaffirm directly.
|
|
@@ -398,35 +443,52 @@ export class KairoClient {
|
|
|
398
443
|
destinationHex: "0x0000000000000000000000000000000000000000",
|
|
399
444
|
nativeValue: 0n,
|
|
400
445
|
};
|
|
401
|
-
const
|
|
446
|
+
const initialPolicyReceiptId = await this.mintPolicyReceipt(wallet, policyContext);
|
|
402
447
|
const dWalletCapId = wallet.dWalletCapId;
|
|
403
448
|
if (!dWalletCapId) {
|
|
404
449
|
throw new Error("Wallet record is missing dWalletCapId. Recreate/provision this wallet before signing.");
|
|
405
450
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
451
|
+
if (!presignId) {
|
|
452
|
+
throw new Error("Missing presignId after presign creation.");
|
|
453
|
+
}
|
|
454
|
+
const resolvedPolicyVersion = await this.resolvePolicyVersion(wallet, opts?.policyVersion);
|
|
455
|
+
const submitAndPoll = async (policyReceiptId) => {
|
|
456
|
+
const req = await this.backend.requestSign({
|
|
457
|
+
dWalletId: wallet.walletId,
|
|
458
|
+
dWalletCapId,
|
|
459
|
+
encryptedUserSecretKeyShareId: wallet.encryptedUserSecretKeyShareId ?? "",
|
|
460
|
+
userOutputSignature: [],
|
|
461
|
+
presignId,
|
|
462
|
+
messageHex: messageHexNoPrefix,
|
|
463
|
+
userSignMessage: Array.from(userSignMessage),
|
|
464
|
+
policyReceiptId,
|
|
465
|
+
policyBindingObjectId: wallet.bindingObjectId,
|
|
466
|
+
policyObjectId: wallet.policyObjectId,
|
|
467
|
+
policyVersion: resolvedPolicyVersion,
|
|
468
|
+
ethTx: opts?.ethTx,
|
|
469
|
+
});
|
|
470
|
+
if (!req.success) {
|
|
471
|
+
throw new Error(`Failed to request sign for wallet ${walletId}`);
|
|
472
|
+
}
|
|
473
|
+
const signStatus = await this.pollSignStatus(req.requestId);
|
|
474
|
+
return {
|
|
475
|
+
requestId: req.requestId,
|
|
476
|
+
signId: signStatus.signId,
|
|
477
|
+
presignId,
|
|
478
|
+
signatureHex: ensureHexPrefix(signStatus.signatureHex),
|
|
479
|
+
};
|
|
429
480
|
};
|
|
481
|
+
try {
|
|
482
|
+
return await submitAndPoll(initialPolicyReceiptId);
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
if (!this.isReaffirmRequiredError(error))
|
|
486
|
+
throw error;
|
|
487
|
+
await this.reaffirmBinding(wallet.walletId);
|
|
488
|
+
// Reaffirm changes active binding version; mint a fresh receipt bound to the new version.
|
|
489
|
+
const retriedPolicyReceiptId = await this.mintPolicyReceipt(wallet, policyContext);
|
|
490
|
+
return submitAndPoll(retriedPolicyReceiptId);
|
|
491
|
+
}
|
|
430
492
|
}
|
|
431
493
|
async signEvm(params) {
|
|
432
494
|
const wallet = this.requireWalletRecord(params.walletId);
|
|
@@ -627,7 +689,7 @@ export class KairoClient {
|
|
|
627
689
|
if (!wallet.policyObjectId || !wallet.bindingObjectId) {
|
|
628
690
|
throw new Error("Wallet is missing policy binding metadata. Ensure it is provisioned with policyObjectId and bindingObjectId.");
|
|
629
691
|
}
|
|
630
|
-
const
|
|
692
|
+
const mintOnce = () => this.backend.mintReceipt({
|
|
631
693
|
policyObjectId: wallet.policyObjectId,
|
|
632
694
|
bindingObjectId: wallet.bindingObjectId,
|
|
633
695
|
namespace: ctx.namespace,
|
|
@@ -638,6 +700,12 @@ export class KairoClient {
|
|
|
638
700
|
nativeValueHex: ctx.nativeValue.toString(16).padStart(64, "0"),
|
|
639
701
|
contextDataHex: ctx.contextDataHex ? stripHexPrefix(ctx.contextDataHex) : undefined,
|
|
640
702
|
});
|
|
703
|
+
let response = await mintOnce();
|
|
704
|
+
const initialError = String(response?.error ?? "");
|
|
705
|
+
if (response.success === false && this.isReaffirmRequiredError(initialError)) {
|
|
706
|
+
await this.reaffirmBinding(wallet.walletId);
|
|
707
|
+
response = await mintOnce();
|
|
708
|
+
}
|
|
641
709
|
if (response.success === false) {
|
|
642
710
|
throw new Error(String(response.error ?? "Failed to mint policy receipt"));
|
|
643
711
|
}
|
|
@@ -650,6 +718,27 @@ export class KairoClient {
|
|
|
650
718
|
}
|
|
651
719
|
return receiptId;
|
|
652
720
|
}
|
|
721
|
+
async resolvePolicyVersion(wallet, override) {
|
|
722
|
+
const explicit = String(override ?? "").trim();
|
|
723
|
+
if (explicit)
|
|
724
|
+
return explicit;
|
|
725
|
+
if (!wallet.policyObjectId?.startsWith("0x")) {
|
|
726
|
+
throw new Error("Wallet is missing policyObjectId. Provision the wallet before signing.");
|
|
727
|
+
}
|
|
728
|
+
const response = await this.backend.getPolicy(wallet.policyObjectId);
|
|
729
|
+
if (!response.success || !response.policy) {
|
|
730
|
+
throw new Error(response.error ?? "Failed to resolve policy details for signing");
|
|
731
|
+
}
|
|
732
|
+
const version = decodeMoveString(response.policy.version).trim();
|
|
733
|
+
if (!version) {
|
|
734
|
+
throw new Error("Policy version is missing on-chain. Pass policyVersion explicitly.");
|
|
735
|
+
}
|
|
736
|
+
return version;
|
|
737
|
+
}
|
|
738
|
+
isReaffirmRequiredError(err) {
|
|
739
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
740
|
+
return /requires confirmation/i.test(message) || /reaffirm/i.test(message);
|
|
741
|
+
}
|
|
653
742
|
async computeUserSignMessageWithExtensionFallback(wallet, protocolParams, presignBytes, messageBytes) {
|
|
654
743
|
try {
|
|
655
744
|
return await createUserSignMessageWithPublicOutput(protocolParams, new Uint8Array(wallet.userPublicOutput), new Uint8Array(wallet.userSecretKeyShare), presignBytes, messageBytes, Hash.KECCAK256, SignatureAlgorithm.ECDSASecp256k1, Curve.SECP256K1);
|
|
@@ -733,6 +822,26 @@ function toBigInt(value) {
|
|
|
733
822
|
return BigInt(value);
|
|
734
823
|
return value.startsWith("0x") ? BigInt(value) : BigInt(value);
|
|
735
824
|
}
|
|
825
|
+
function decodeMoveString(value) {
|
|
826
|
+
if (typeof value === "string")
|
|
827
|
+
return value;
|
|
828
|
+
if (Array.isArray(value) && value.every((x) => Number.isInteger(x) && x >= 0 && x <= 255)) {
|
|
829
|
+
try {
|
|
830
|
+
return new TextDecoder().decode(Uint8Array.from(value));
|
|
831
|
+
}
|
|
832
|
+
catch {
|
|
833
|
+
return "";
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
if (value && typeof value === "object") {
|
|
837
|
+
const obj = value;
|
|
838
|
+
return (decodeMoveString(obj.bytes) ||
|
|
839
|
+
decodeMoveString(obj.data) ||
|
|
840
|
+
decodeMoveString(obj.value) ||
|
|
841
|
+
decodeMoveString(obj.fields));
|
|
842
|
+
}
|
|
843
|
+
return "";
|
|
844
|
+
}
|
|
736
845
|
function buildNormalizedEncryptedShare(fields) {
|
|
737
846
|
const { state } = normalizeMoveEnumState(fields.state);
|
|
738
847
|
const candidate = {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface PolicyTemplatePreset {
|
|
2
|
+
id: "tpl-1" | "tpl-2" | "tpl-3";
|
|
3
|
+
label: string;
|
|
4
|
+
singleTxUsd: number;
|
|
5
|
+
dailyLimitUsd: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const POLICY_TEMPLATE_PRESETS: Record<PolicyTemplatePreset["id"], PolicyTemplatePreset>;
|
|
8
|
+
export declare function buildPolicyTemplatePayload(templateId: string): {
|
|
9
|
+
template: PolicyTemplatePreset;
|
|
10
|
+
allowNamespaces: number[];
|
|
11
|
+
rules: Array<{
|
|
12
|
+
ruleType: number;
|
|
13
|
+
namespace?: number;
|
|
14
|
+
params: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export const POLICY_TEMPLATE_PRESETS = {
|
|
2
|
+
"tpl-1": {
|
|
3
|
+
id: "tpl-1",
|
|
4
|
+
label: "Conservative ($200/tx, $1k/day)",
|
|
5
|
+
singleTxUsd: 200,
|
|
6
|
+
dailyLimitUsd: 1_000,
|
|
7
|
+
},
|
|
8
|
+
"tpl-2": {
|
|
9
|
+
id: "tpl-2",
|
|
10
|
+
label: "Standard ($2k/tx, $10k/day)",
|
|
11
|
+
singleTxUsd: 2_000,
|
|
12
|
+
dailyLimitUsd: 10_000,
|
|
13
|
+
},
|
|
14
|
+
"tpl-3": {
|
|
15
|
+
id: "tpl-3",
|
|
16
|
+
label: "High-limit ($10k/tx, $50k/day)",
|
|
17
|
+
singleTxUsd: 10_000,
|
|
18
|
+
dailyLimitUsd: 50_000,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
function stripHexPrefix(value) {
|
|
22
|
+
return value.startsWith("0x") ? value.slice(2) : value;
|
|
23
|
+
}
|
|
24
|
+
function encodeU256(value) {
|
|
25
|
+
const big = typeof value === "bigint" ? value : BigInt(value);
|
|
26
|
+
return `0x${big.toString(16).padStart(64, "0")}`;
|
|
27
|
+
}
|
|
28
|
+
function encodeMaxNativeRule(maxNativeBaseUnits) {
|
|
29
|
+
return encodeU256(maxNativeBaseUnits);
|
|
30
|
+
}
|
|
31
|
+
function encodeDailyPeriodLimitRule(maxDailyBaseUnits) {
|
|
32
|
+
const periodTypeDaily = 1;
|
|
33
|
+
return `0x${periodTypeDaily.toString(16).padStart(2, "0")}${stripHexPrefix(encodeU256(maxDailyBaseUnits))}`;
|
|
34
|
+
}
|
|
35
|
+
export function buildPolicyTemplatePayload(templateId) {
|
|
36
|
+
const template = POLICY_TEMPLATE_PRESETS[templateId] ?? POLICY_TEMPLATE_PRESETS["tpl-2"];
|
|
37
|
+
const maxNativeBaseUnits = BigInt(Math.round(template.singleTxUsd * 1_000_000));
|
|
38
|
+
const dailyLimitBaseUnits = BigInt(Math.round(template.dailyLimitUsd * 1_000_000));
|
|
39
|
+
return {
|
|
40
|
+
template,
|
|
41
|
+
// Default to EVM namespace so newly onboarded users can sign EVM txs immediately.
|
|
42
|
+
allowNamespaces: [1],
|
|
43
|
+
rules: [
|
|
44
|
+
{
|
|
45
|
+
ruleType: 1,
|
|
46
|
+
namespace: 0,
|
|
47
|
+
params: encodeMaxNativeRule(maxNativeBaseUnits),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
ruleType: 10,
|
|
51
|
+
namespace: 0,
|
|
52
|
+
params: encodeDailyPeriodLimitRule(dailyLimitBaseUnits),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|