@dev.sail.money/sailor 1.3.0-208 → 1.3.0-210
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/package.json +1 -1
- package/packages/cli/dist/index.cjs +166 -100
- package/packages/cli/dist/server.cjs +1256 -48
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/packages/sdk/dist/signing.d.ts +29 -0
- package/packages/sdk/dist/signing.d.ts.map +1 -1
- package/packages/ui/dist/assets/{add-CfTRVkh-.js → add-CLs0-B0p.js} +1 -1
- package/packages/ui/dist/assets/{all-wallets-VZChJwJf.js → all-wallets-CDOk28sj.js} +1 -1
- package/packages/ui/dist/assets/{app-store-CuFK1xBJ.js → app-store-DVzpi1qN.js} +1 -1
- package/packages/ui/dist/assets/{apple-DETqVk_I.js → apple-C9U9iH1l.js} +1 -1
- package/packages/ui/dist/assets/{arrow-bottom-CnNYsZfo.js → arrow-bottom-DjQ4jGMe.js} +1 -1
- package/packages/ui/dist/assets/{arrow-bottom-circle-DZwJF3UO.js → arrow-bottom-circle-jxial9Si.js} +1 -1
- package/packages/ui/dist/assets/{arrow-left-CBnisTAa.js → arrow-left-BjAyI8D1.js} +1 -1
- package/packages/ui/dist/assets/{arrow-right-DA3Y1Yzf.js → arrow-right-BlFO4Tcx.js} +1 -1
- package/packages/ui/dist/assets/{arrow-top-e8-FE_fo.js → arrow-top-DJ3oh3DH.js} +1 -1
- package/packages/ui/dist/assets/{bank-DdwromQn.js → bank-B98it1qN.js} +1 -1
- package/packages/ui/dist/assets/{basic-DLYER2un.js → basic-DsgeyPNu.js} +1 -1
- package/packages/ui/dist/assets/{browser-BJNrv4Zj.js → browser-j4vCeHwE.js} +1 -1
- package/packages/ui/dist/assets/{card-DB6j4DSk.js → card-CzxbMvEd.js} +1 -1
- package/packages/ui/dist/assets/{ccip-Dy_s323Y.js → ccip-U9yiu_EK.js} +1 -1
- package/packages/ui/dist/assets/{checkmark-Db9oicko.js → checkmark-D5sWBbk3.js} +1 -1
- package/packages/ui/dist/assets/{checkmark-bold-D9MgGHxv.js → checkmark-bold-BW6w3KCC.js} +1 -1
- package/packages/ui/dist/assets/{chevron-bottom-IGUDJRKN.js → chevron-bottom-BbHhmTQq.js} +1 -1
- package/packages/ui/dist/assets/{chevron-left-CWpfP-rw.js → chevron-left-D8BDH4Wo.js} +1 -1
- package/packages/ui/dist/assets/{chevron-right-BejY0vtE.js → chevron-right-BQuQk5zc.js} +1 -1
- package/packages/ui/dist/assets/{chevron-top-BaUN0LGF.js → chevron-top-1oeSXkx4.js} +1 -1
- package/packages/ui/dist/assets/{chrome-store-fox1tIqs.js → chrome-store-B1OMtzC-.js} +1 -1
- package/packages/ui/dist/assets/{clock-DlqB4Ehi.js → clock-e0HueehS.js} +1 -1
- package/packages/ui/dist/assets/{close-03e52feP.js → close-Cy1ytr26.js} +1 -1
- package/packages/ui/dist/assets/{coinPlaceholder-BO3nv4hx.js → coinPlaceholder-DqJu3ZPV.js} +1 -1
- package/packages/ui/dist/assets/{compass-CIqPRE0k.js → compass-XDz_N2Hg.js} +1 -1
- package/packages/ui/dist/assets/{copy-D5cJBwZq.js → copy-DmDo3Nob.js} +1 -1
- package/packages/ui/dist/assets/{core-COelOg3-.js → core-DbkMGSYW.js} +3 -3
- package/packages/ui/dist/assets/cursor-DRFqL8nZ.js +3 -0
- package/packages/ui/dist/assets/{cursor-transparent-Cvbiq9Br.js → cursor-transparent-DF2aA10D.js} +1 -1
- package/packages/ui/dist/assets/{desktop-Dp2wtF3n.js → desktop-CVydOWLn.js} +1 -1
- package/packages/ui/dist/assets/{disconnect-Dx_IGM73.js → disconnect-BuN2Whnz.js} +1 -1
- package/packages/ui/dist/assets/{discord-Cxryn14a.js → discord-DMNPvTB2.js} +1 -1
- package/packages/ui/dist/assets/{etherscan-D8aNXWCx.js → etherscan-CacW-93f.js} +1 -1
- package/packages/ui/dist/assets/{events-DR6OOHz2.js → events-CZkVDFih.js} +1 -1
- package/packages/ui/dist/assets/{exclamation-triangle-BBCaPLj1.js → exclamation-triangle-B26hIvqO.js} +1 -1
- package/packages/ui/dist/assets/{extension-bACRNBl5.js → extension-B7rI0gv7.js} +1 -1
- package/packages/ui/dist/assets/{external-link-BZRqHo3q.js → external-link-CX8skCbH.js} +1 -1
- package/packages/ui/dist/assets/{facebook-TAdUitg4.js → facebook-BDqbE6kl.js} +1 -1
- package/packages/ui/dist/assets/{fallback-DGiwrboN.js → fallback-DWQYKf3l.js} +1 -1
- package/packages/ui/dist/assets/{farcaster-YzdobBfR.js → farcaster-zQ3oQzZ8.js} +1 -1
- package/packages/ui/dist/assets/{filters-CT-xLEoI.js → filters-DCglZYsM.js} +1 -1
- package/packages/ui/dist/assets/{github-DxPBbmEL.js → github-BH-BYjss.js} +1 -1
- package/packages/ui/dist/assets/{google-B0TMgFhK.js → google-DYFWxZbC.js} +1 -1
- package/packages/ui/dist/assets/{help-circle-Be6sRPTw.js → help-circle-BXH_DtZ_.js} +1 -1
- package/packages/ui/dist/assets/{id-Dem_akbE.js → id-Dr2yTeX1.js} +1 -1
- package/packages/ui/dist/assets/{image-CszBzFVG.js → image-DeJey1Eg.js} +1 -1
- package/packages/ui/dist/assets/{index-DXqj6oYp.js → index-BP-UuQ8g.js} +1 -1
- package/packages/ui/dist/assets/{index-DAawBKd2.js → index-BksbyFjf.js} +1 -1
- package/packages/ui/dist/assets/{index-homh6mWC.js → index-C55-Ne92.js} +1 -1
- package/packages/ui/dist/assets/{index-Cb5eBfrN.js → index-D6_Zei-R.js} +71 -71
- package/packages/ui/dist/assets/{index-C2n9XvGG.js → index-DVjAiPHI.js} +3 -3
- package/packages/ui/dist/assets/{index-B0FDHAiK.js → index-uSdXE5b_.js} +1 -1
- package/packages/ui/dist/assets/{index.es-DJgl78dj.js → index.es-dZlNPpfR.js} +4 -4
- package/packages/ui/dist/assets/{info-BimGN4NK.js → info-B91pD5Rw.js} +1 -1
- package/packages/ui/dist/assets/{info-circle-lnKEJu2R.js → info-circle-CySl3_on.js} +1 -1
- package/packages/ui/dist/assets/{lightbulb-DS1vEMce.js → lightbulb-wwG8LQLo.js} +1 -1
- package/packages/ui/dist/assets/{mail-DoS3Wibk.js → mail-D617YZ8y.js} +1 -1
- package/packages/ui/dist/assets/{metamask-sdk-CMIU3BwW.js → metamask-sdk-RbLbxUgF.js} +1 -1
- package/packages/ui/dist/assets/{mobile-B09Cs95_.js → mobile-CD9KlA0m.js} +1 -1
- package/packages/ui/dist/assets/{more-CLBZT8WI.js → more-BQ_rpPXo.js} +1 -1
- package/packages/ui/dist/assets/{network-placeholder-C45Cp8rY.js → network-placeholder-BA7nl9e6.js} +1 -1
- package/packages/ui/dist/assets/{nftPlaceholder-CAVclL3u.js → nftPlaceholder-D1EaaeDn.js} +1 -1
- package/packages/ui/dist/assets/{off-CwE8HoZ0.js → off-DnGG35_w.js} +1 -1
- package/packages/ui/dist/assets/{parseSignature-kmMNHYjl.js → parseSignature-E29x8poM.js} +1 -1
- package/packages/ui/dist/assets/{play-store-DiFF_6n4.js → play-store-C5u2FvYB.js} +1 -1
- package/packages/ui/dist/assets/{plus-aygpl_pZ.js → plus-CM4xJkvI.js} +1 -1
- package/packages/ui/dist/assets/{qr-code-DpIS4fFK.js → qr-code-kM3FUIdR.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-Qk2N74JE.js → recycle-horizontal-DWrRWIBM.js} +1 -1
- package/packages/ui/dist/assets/{refresh-sWRq9Vnt.js → refresh-CztbjK2d.js} +1 -1
- package/packages/ui/dist/assets/{reown-logo-YQxBa9i9.js → reown-logo-DUHEIodF.js} +1 -1
- package/packages/ui/dist/assets/{search-Bt6BSPcC.js → search-BJtb4mn1.js} +1 -1
- package/packages/ui/dist/assets/{secp256k1-BUh3OoFd.js → secp256k1-BjrTZpQx.js} +1 -1
- package/packages/ui/dist/assets/{send-ym-Fn17O.js → send-B3_kavG1.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontal-fBE2gnqc.js → swapHorizontal-BrF9POiv.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalBold-CekQ22FJ.js → swapHorizontalBold-Dgf8OjXj.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalMedium-B9BI9ovU.js → swapHorizontalMedium-C6wX0JZj.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-DOC75mBH.js → swapHorizontalRoundedBold-DTAVw6oF.js} +1 -1
- package/packages/ui/dist/assets/{swapVertical-CSQAPH0z.js → swapVertical-KGlTFNoi.js} +1 -1
- package/packages/ui/dist/assets/{telegram-BPjzFxKU.js → telegram-DnLrK-4y.js} +1 -1
- package/packages/ui/dist/assets/{three-dots-DP6hdXH8.js → three-dots-C6_oMJfw.js} +1 -1
- package/packages/ui/dist/assets/{twitch-CgHMd-f3.js → twitch-DvPqPD4f.js} +1 -1
- package/packages/ui/dist/assets/{twitterIcon-BrR8ynXm.js → twitterIcon-BZdk82Am.js} +1 -1
- package/packages/ui/dist/assets/{verify-D35D7Wtv.js → verify-CbESD5G0.js} +1 -1
- package/packages/ui/dist/assets/{verify-filled-DCP5CT59.js → verify-filled-BRjTrLxw.js} +1 -1
- package/packages/ui/dist/assets/{w3m-modal-B-ZptWk0.js → w3m-modal-D9b2TGHc.js} +1 -1
- package/packages/ui/dist/assets/{wallet-Cnb4dkr3.js → wallet-B87E5UId.js} +1 -1
- package/packages/ui/dist/assets/{wallet-placeholder-CCzk0PqU.js → wallet-placeholder-DmssSbYf.js} +1 -1
- package/packages/ui/dist/assets/{walletconnect-f6tQZYRi.js → walletconnect-CZkLKWMZ.js} +1 -1
- package/packages/ui/dist/assets/{warning-circle-zxMagvfx.js → warning-circle-BPTpHB1P.js} +1 -1
- package/packages/ui/dist/assets/{x-D0nEGO1G.js → x-D_dEtEDU.js} +1 -1
- package/packages/ui/dist/index.html +1 -1
- package/packages/ui/dist/assets/cursor-CRb7R3u1.js +0 -3
package/package.json
CHANGED
|
@@ -41240,9 +41240,124 @@ async function keysShow() {
|
|
|
41240
41240
|
|
|
41241
41241
|
// src/commands/mandate-contracts.ts
|
|
41242
41242
|
var import_node_child_process = require("node:child_process");
|
|
41243
|
+
var import_node_fs14 = require("node:fs");
|
|
41244
|
+
var import_node_path12 = require("node:path");
|
|
41245
|
+
init_esm2();
|
|
41246
|
+
|
|
41247
|
+
// src/lib/permission-explainer.ts
|
|
41243
41248
|
var import_node_fs13 = require("node:fs");
|
|
41244
41249
|
var import_node_path11 = require("node:path");
|
|
41245
|
-
|
|
41250
|
+
function explainPermission(name, sourcePath) {
|
|
41251
|
+
const resolved = sourcePath ?? (0, import_node_path11.join)(process.cwd(), "mandates", `${name}.sol`);
|
|
41252
|
+
let src;
|
|
41253
|
+
try {
|
|
41254
|
+
src = (0, import_node_fs13.readFileSync)(resolved, "utf8");
|
|
41255
|
+
} catch {
|
|
41256
|
+
return null;
|
|
41257
|
+
}
|
|
41258
|
+
return parseStructured(src) ?? parseNatSpec(src) ?? parseRequires(src);
|
|
41259
|
+
}
|
|
41260
|
+
var ENFORCED_HEADER = /ENFORCE[SD]\s+ON-CHAIN/i;
|
|
41261
|
+
var NOT_ENFORCED_HEADER = /NOT\s+(ENFORCED|BOUNDED)/i;
|
|
41262
|
+
function parseStructured(src) {
|
|
41263
|
+
if (!ENFORCED_HEADER.test(src)) return null;
|
|
41264
|
+
const lines = src.split("\n");
|
|
41265
|
+
const result = {
|
|
41266
|
+
source: "structured",
|
|
41267
|
+
enforced: [],
|
|
41268
|
+
notEnforced: []
|
|
41269
|
+
};
|
|
41270
|
+
const headerLines = [];
|
|
41271
|
+
for (const line of lines) {
|
|
41272
|
+
const t = line.trim();
|
|
41273
|
+
if (t.startsWith("import ") || t.startsWith("contract ") || t.startsWith("abstract contract ")) break;
|
|
41274
|
+
if (t.startsWith("//")) headerLines.push(t.slice(2));
|
|
41275
|
+
}
|
|
41276
|
+
let section = null;
|
|
41277
|
+
for (const raw of headerLines) {
|
|
41278
|
+
const trimmed = raw.trim();
|
|
41279
|
+
if (/^─+$/.test(trimmed)) continue;
|
|
41280
|
+
if (NOT_ENFORCED_HEADER.test(trimmed)) {
|
|
41281
|
+
section = "notEnforced";
|
|
41282
|
+
continue;
|
|
41283
|
+
}
|
|
41284
|
+
if (ENFORCED_HEADER.test(trimmed)) {
|
|
41285
|
+
section = "enforced";
|
|
41286
|
+
continue;
|
|
41287
|
+
}
|
|
41288
|
+
if (trimmed.includes("VERIFY BEFORE USE")) {
|
|
41289
|
+
section = null;
|
|
41290
|
+
continue;
|
|
41291
|
+
}
|
|
41292
|
+
if (section === null) {
|
|
41293
|
+
const kv = trimmed.match(/^(Protocol|Version|Chain|Target)\s*:\s*(.+)$/i);
|
|
41294
|
+
if (kv) {
|
|
41295
|
+
const key = kv[1].toLowerCase();
|
|
41296
|
+
result[key] = kv[2].trim();
|
|
41297
|
+
}
|
|
41298
|
+
}
|
|
41299
|
+
if (section && trimmed.startsWith("\u2022")) {
|
|
41300
|
+
const bullet = trimmed.slice(1).trim();
|
|
41301
|
+
if (bullet) result[section].push(bullet);
|
|
41302
|
+
}
|
|
41303
|
+
}
|
|
41304
|
+
if (result.enforced.length === 0 && !result.protocol) return null;
|
|
41305
|
+
return result;
|
|
41306
|
+
}
|
|
41307
|
+
function parseNatSpec(src) {
|
|
41308
|
+
const enforced = [];
|
|
41309
|
+
const notEnforced = [];
|
|
41310
|
+
let current = null;
|
|
41311
|
+
let buf = [];
|
|
41312
|
+
const flush = () => {
|
|
41313
|
+
if (current && buf.length) {
|
|
41314
|
+
const text = buf.join(" ").replace(/\s+/g, " ").trim();
|
|
41315
|
+
if (text) (current === "enforced" ? enforced : notEnforced).push(text);
|
|
41316
|
+
}
|
|
41317
|
+
buf = [];
|
|
41318
|
+
};
|
|
41319
|
+
for (const line of src.split("\n")) {
|
|
41320
|
+
const t = line.trim();
|
|
41321
|
+
const tagged = t.match(/^\/\/\/\s*@(\w+)\s+(.+)$/);
|
|
41322
|
+
if (tagged) {
|
|
41323
|
+
const [, tag, text] = tagged;
|
|
41324
|
+
if (tag === "notice") {
|
|
41325
|
+
flush();
|
|
41326
|
+
current = "enforced";
|
|
41327
|
+
buf.push(text.trim());
|
|
41328
|
+
} else if (tag === "dev") {
|
|
41329
|
+
flush();
|
|
41330
|
+
current = "notEnforced";
|
|
41331
|
+
buf.push(text.trim());
|
|
41332
|
+
} else {
|
|
41333
|
+
flush();
|
|
41334
|
+
current = null;
|
|
41335
|
+
}
|
|
41336
|
+
continue;
|
|
41337
|
+
}
|
|
41338
|
+
const cont = t.match(/^\/\/\/\s?(.*)$/);
|
|
41339
|
+
if (cont && current) {
|
|
41340
|
+
const text = cont[1].trim();
|
|
41341
|
+
if (text) buf.push(text);
|
|
41342
|
+
continue;
|
|
41343
|
+
}
|
|
41344
|
+
if (!t.startsWith("///")) {
|
|
41345
|
+
flush();
|
|
41346
|
+
current = null;
|
|
41347
|
+
}
|
|
41348
|
+
}
|
|
41349
|
+
flush();
|
|
41350
|
+
if (enforced.length === 0 && notEnforced.length === 0) return null;
|
|
41351
|
+
return { source: "natspec", enforced, notEnforced };
|
|
41352
|
+
}
|
|
41353
|
+
function parseRequires(src) {
|
|
41354
|
+
const enforced = [];
|
|
41355
|
+
const re = /require\s*\([^,)]+,\s*["']([^"']+)["']\)/g;
|
|
41356
|
+
let m;
|
|
41357
|
+
while ((m = re.exec(src)) !== null) enforced.push(m[1]);
|
|
41358
|
+
if (enforced.length === 0) return null;
|
|
41359
|
+
return { source: "require-only", enforced, notEnforced: [] };
|
|
41360
|
+
}
|
|
41246
41361
|
|
|
41247
41362
|
// src/lib/mandates.ts
|
|
41248
41363
|
var MandateStore = class {
|
|
@@ -41708,6 +41823,8 @@ Pushing signing request for "${template.label}" permission\u2026`));
|
|
|
41708
41823
|
` The mandate signer (${permissionSigner}) must sign in the browser \u2014 not the agent wallet.`
|
|
41709
41824
|
)
|
|
41710
41825
|
);
|
|
41826
|
+
const permRecord = new MandateStore().find(templateAddress);
|
|
41827
|
+
const permExplanation = (permRecord ? explainPermission(permRecord.name, permRecord.sourcePath) : explainPermission(template.label)) ?? void 0;
|
|
41711
41828
|
const response = await channel.requestSignature({
|
|
41712
41829
|
type: "typed-data",
|
|
41713
41830
|
kind: "register-permission",
|
|
@@ -41720,6 +41837,7 @@ Pushing signing request for "${template.label}" permission\u2026`));
|
|
|
41720
41837
|
{ label: "Permission", value: template.label },
|
|
41721
41838
|
{ label: "Mandate signer", value: permissionSigner }
|
|
41722
41839
|
],
|
|
41840
|
+
explanation: permExplanation,
|
|
41723
41841
|
typedData
|
|
41724
41842
|
});
|
|
41725
41843
|
if (response.status === "rejected") {
|
|
@@ -41934,12 +42052,12 @@ async function runDeploy(project, channel, options) {
|
|
|
41934
42052
|
)
|
|
41935
42053
|
);
|
|
41936
42054
|
}
|
|
41937
|
-
const { abi: abi2, bytecode, contractName, artifactPath } = resolveArtifact(options);
|
|
42055
|
+
const { abi: abi2, bytecode, contractName, artifactPath, sourcePath } = resolveArtifact(options);
|
|
41938
42056
|
let argsJson;
|
|
41939
42057
|
if (options.argsFile) {
|
|
41940
|
-
const argsFilePath = (0,
|
|
42058
|
+
const argsFilePath = (0, import_node_path12.resolve)(options.argsFile);
|
|
41941
42059
|
try {
|
|
41942
|
-
argsJson = (0,
|
|
42060
|
+
argsJson = (0, import_node_fs14.readFileSync)(argsFilePath, "utf8").trim();
|
|
41943
42061
|
} catch {
|
|
41944
42062
|
throw new Error(`Cannot read --args-file: ${argsFilePath}`);
|
|
41945
42063
|
}
|
|
@@ -41952,6 +42070,7 @@ async function runDeploy(project, channel, options) {
|
|
|
41952
42070
|
const publicClient = publicClientFor(project);
|
|
41953
42071
|
announceSigningUrl(json);
|
|
41954
42072
|
say(() => console.log(`Pushing deploy request for "${contractName}"\u2026`));
|
|
42073
|
+
const explanation = explainPermission(contractName, sourcePath) ?? void 0;
|
|
41955
42074
|
const response = await channel.requestSignature({
|
|
41956
42075
|
type: "transaction",
|
|
41957
42076
|
kind: "deploy-mandate",
|
|
@@ -41966,7 +42085,8 @@ async function runDeploy(project, channel, options) {
|
|
|
41966
42085
|
label: options.argsFile ? "Constructor args (from file)" : "Constructor args",
|
|
41967
42086
|
value: argsJson ? argsJson : "(none)"
|
|
41968
42087
|
}
|
|
41969
|
-
]
|
|
42088
|
+
],
|
|
42089
|
+
explanation
|
|
41970
42090
|
});
|
|
41971
42091
|
if (response.status === "rejected") {
|
|
41972
42092
|
throw new Error(`User rejected permission deployment: ${response.reason ?? "no reason given"}`);
|
|
@@ -41986,6 +42106,7 @@ async function runDeploy(project, channel, options) {
|
|
|
41986
42106
|
address: deployed,
|
|
41987
42107
|
txHash: response.txHash,
|
|
41988
42108
|
chainId,
|
|
42109
|
+
sourcePath,
|
|
41989
42110
|
artifactPath,
|
|
41990
42111
|
constructorArgs: parseArgsRaw(options.args),
|
|
41991
42112
|
deployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -42079,9 +42200,12 @@ var CLONE_TEMPLATES = {
|
|
|
42079
42200
|
]
|
|
42080
42201
|
}
|
|
42081
42202
|
};
|
|
42082
|
-
function predictCloneAddress(impl, factory, submitter, salt) {
|
|
42203
|
+
function predictCloneAddress(impl, factory, submitter, account2, salt) {
|
|
42083
42204
|
const namespacedSalt = keccak256(
|
|
42084
|
-
encodeAbiParameters(
|
|
42205
|
+
encodeAbiParameters(
|
|
42206
|
+
[{ type: "address" }, { type: "address" }, { type: "bytes32" }],
|
|
42207
|
+
[submitter, account2, salt]
|
|
42208
|
+
)
|
|
42085
42209
|
);
|
|
42086
42210
|
const initCode = concatHex([CLONE_INIT_PREFIX, impl, CLONE_INIT_SUFFIX]);
|
|
42087
42211
|
return getCreate2Address({
|
|
@@ -42178,7 +42302,7 @@ async function runDeployClone(project, channel, options) {
|
|
|
42178
42302
|
[sma, impl, BigInt(Math.floor(Date.now() / 1e3))]
|
|
42179
42303
|
)
|
|
42180
42304
|
);
|
|
42181
|
-
const clone = predictCloneAddress(impl, project.contracts.mandateFactory, submitter, salt);
|
|
42305
|
+
const clone = predictCloneAddress(impl, project.contracts.mandateFactory, submitter, sma, salt);
|
|
42182
42306
|
say(() => {
|
|
42183
42307
|
console.log(`
|
|
42184
42308
|
${spec.label} clone (${options.template})`);
|
|
@@ -42620,6 +42744,15 @@ async function attachBatchToSma(project, channel, publicClient, sma, permissions
|
|
|
42620
42744
|
Attaching ${permissions.length} permissions in one signature \u2014 the mandate signer (${permissionSigner}) signs in the browser\u2026`
|
|
42621
42745
|
)
|
|
42622
42746
|
);
|
|
42747
|
+
const permStore = new MandateStore();
|
|
42748
|
+
const permExplanations = permissions.map((addr) => {
|
|
42749
|
+
const rec = permStore.find(addr);
|
|
42750
|
+
return {
|
|
42751
|
+
label: rec?.name ?? addr,
|
|
42752
|
+
address: addr,
|
|
42753
|
+
explanation: (rec ? explainPermission(rec.name, rec.sourcePath) : null) ?? void 0
|
|
42754
|
+
};
|
|
42755
|
+
});
|
|
42623
42756
|
const response = await channel.requestSignature({
|
|
42624
42757
|
type: "typed-data",
|
|
42625
42758
|
kind: "register-permission",
|
|
@@ -42631,6 +42764,7 @@ Attaching ${permissions.length} permissions in one signature \u2014 the mandate
|
|
|
42631
42764
|
{ label: "Permissions", value: String(permissions.length) },
|
|
42632
42765
|
{ label: "Mandate signer", value: permissionSigner }
|
|
42633
42766
|
],
|
|
42767
|
+
permissions: permExplanations,
|
|
42634
42768
|
typedData
|
|
42635
42769
|
});
|
|
42636
42770
|
if (response.status === "rejected") {
|
|
@@ -42778,11 +42912,11 @@ function resolveArtifact(options) {
|
|
|
42778
42912
|
let contractName = options.contract ?? options.name ?? "";
|
|
42779
42913
|
if (!artifactPath) {
|
|
42780
42914
|
if (!options.contract) throw new Error("Provide --artifact <path> or --contract <name>");
|
|
42781
|
-
artifactPath = (0,
|
|
42915
|
+
artifactPath = (0, import_node_path12.join)(options.out, `${options.contract}.sol`, `${options.contract}.json`);
|
|
42782
42916
|
}
|
|
42783
|
-
const resolved = (0,
|
|
42784
|
-
const projectRoot = (0,
|
|
42785
|
-
if (!resolved.startsWith(projectRoot +
|
|
42917
|
+
const resolved = (0, import_node_path12.resolve)(artifactPath);
|
|
42918
|
+
const projectRoot = (0, import_node_path12.resolve)(process.cwd());
|
|
42919
|
+
if (!resolved.startsWith(projectRoot + import_node_path12.sep) && resolved !== projectRoot) {
|
|
42786
42920
|
throw new Error(
|
|
42787
42921
|
`Artifact path must be inside the project directory.
|
|
42788
42922
|
Resolved: ${resolved}`
|
|
@@ -42790,14 +42924,14 @@ Resolved: ${resolved}`
|
|
|
42790
42924
|
}
|
|
42791
42925
|
artifactPath = resolved;
|
|
42792
42926
|
if (options.build) runForgeBuild();
|
|
42793
|
-
if (!(0,
|
|
42927
|
+
if (!(0, import_node_fs14.existsSync)(artifactPath)) {
|
|
42794
42928
|
ensureForgeHint();
|
|
42795
42929
|
throw new Error(
|
|
42796
42930
|
`Artifact not found: ${artifactPath}
|
|
42797
42931
|
Compile your mandate first (e.g. \`forge build\`), or pass --build.`
|
|
42798
42932
|
);
|
|
42799
42933
|
}
|
|
42800
|
-
const artifact = JSON.parse((0,
|
|
42934
|
+
const artifact = JSON.parse((0, import_node_fs14.readFileSync)(artifactPath, "utf8"));
|
|
42801
42935
|
const abi2 = artifact.abi;
|
|
42802
42936
|
const bytecodeRaw = artifact.bytecode?.object ?? artifact.bytecode;
|
|
42803
42937
|
if (!bytecodeRaw || typeof bytecodeRaw !== "string") {
|
|
@@ -42808,7 +42942,16 @@ Compile your mandate first (e.g. \`forge build\`), or pass --build.`
|
|
|
42808
42942
|
const m = artifactPath.match(/([^/\\]+)\.json$/);
|
|
42809
42943
|
contractName = m ? m[1] : "Mandate";
|
|
42810
42944
|
}
|
|
42811
|
-
|
|
42945
|
+
let sourcePath;
|
|
42946
|
+
const compilationTarget = artifact.metadata?.settings?.compilationTarget;
|
|
42947
|
+
if (compilationTarget && typeof compilationTarget === "object") {
|
|
42948
|
+
sourcePath = Object.keys(compilationTarget)[0];
|
|
42949
|
+
}
|
|
42950
|
+
sourcePath = sourcePath ?? artifact.ast?.absolutePath;
|
|
42951
|
+
if (sourcePath && !sourcePath.startsWith("/")) {
|
|
42952
|
+
sourcePath = (0, import_node_path12.resolve)(projectRoot, sourcePath);
|
|
42953
|
+
}
|
|
42954
|
+
return { abi: abi2, bytecode, contractName, artifactPath, sourcePath };
|
|
42812
42955
|
}
|
|
42813
42956
|
function parseArgsRaw(argsJson) {
|
|
42814
42957
|
if (!argsJson) return void 0;
|
|
@@ -42878,88 +43021,6 @@ function runForgeBuild() {
|
|
|
42878
43021
|
|
|
42879
43022
|
// src/commands/mandate.ts
|
|
42880
43023
|
init_esm2();
|
|
42881
|
-
|
|
42882
|
-
// src/lib/permission-explainer.ts
|
|
42883
|
-
var import_node_fs14 = require("node:fs");
|
|
42884
|
-
var import_node_path12 = require("node:path");
|
|
42885
|
-
function explainPermission(name, sourcePath) {
|
|
42886
|
-
const resolved = sourcePath ?? (0, import_node_path12.join)(process.cwd(), "mandates", `${name}.sol`);
|
|
42887
|
-
let src;
|
|
42888
|
-
try {
|
|
42889
|
-
src = (0, import_node_fs14.readFileSync)(resolved, "utf8");
|
|
42890
|
-
} catch {
|
|
42891
|
-
return null;
|
|
42892
|
-
}
|
|
42893
|
-
return parseStructured(src) ?? parseNatSpec(src) ?? parseRequires(src);
|
|
42894
|
-
}
|
|
42895
|
-
function parseStructured(src) {
|
|
42896
|
-
if (!src.includes("ENFORCED ON-CHAIN")) return null;
|
|
42897
|
-
const lines = src.split("\n");
|
|
42898
|
-
const result = {
|
|
42899
|
-
source: "structured",
|
|
42900
|
-
enforced: [],
|
|
42901
|
-
notEnforced: []
|
|
42902
|
-
};
|
|
42903
|
-
const headerLines = [];
|
|
42904
|
-
for (const line of lines) {
|
|
42905
|
-
const t = line.trim();
|
|
42906
|
-
if (t.startsWith("import ") || t.startsWith("contract ") || t.startsWith("abstract contract ")) break;
|
|
42907
|
-
if (t.startsWith("//")) headerLines.push(t.slice(2));
|
|
42908
|
-
}
|
|
42909
|
-
let section = null;
|
|
42910
|
-
for (const raw of headerLines) {
|
|
42911
|
-
const trimmed = raw.trim();
|
|
42912
|
-
if (/^─+$/.test(trimmed)) continue;
|
|
42913
|
-
if (trimmed.includes("ENFORCED ON-CHAIN")) {
|
|
42914
|
-
section = "enforced";
|
|
42915
|
-
continue;
|
|
42916
|
-
}
|
|
42917
|
-
if (trimmed.includes("NOT ENFORCED")) {
|
|
42918
|
-
section = "notEnforced";
|
|
42919
|
-
continue;
|
|
42920
|
-
}
|
|
42921
|
-
if (trimmed.includes("VERIFY BEFORE USE")) {
|
|
42922
|
-
section = null;
|
|
42923
|
-
continue;
|
|
42924
|
-
}
|
|
42925
|
-
if (section === null) {
|
|
42926
|
-
const kv = trimmed.match(/^(Protocol|Version|Chain|Target)\s*:\s*(.+)$/i);
|
|
42927
|
-
if (kv) {
|
|
42928
|
-
const key = kv[1].toLowerCase();
|
|
42929
|
-
result[key] = kv[2].trim();
|
|
42930
|
-
}
|
|
42931
|
-
}
|
|
42932
|
-
if (section && trimmed.startsWith("\u2022")) {
|
|
42933
|
-
const bullet = trimmed.slice(1).trim();
|
|
42934
|
-
if (bullet) result[section].push(bullet);
|
|
42935
|
-
}
|
|
42936
|
-
}
|
|
42937
|
-
if (result.enforced.length === 0 && !result.protocol) return null;
|
|
42938
|
-
return result;
|
|
42939
|
-
}
|
|
42940
|
-
function parseNatSpec(src) {
|
|
42941
|
-
const enforced = [];
|
|
42942
|
-
const notEnforced = [];
|
|
42943
|
-
for (const line of src.split("\n")) {
|
|
42944
|
-
const t = line.trim();
|
|
42945
|
-
const notice = t.match(/^\/\/\/\s*@notice\s+(.+)$/);
|
|
42946
|
-
if (notice) enforced.push(notice[1].trim());
|
|
42947
|
-
const dev = t.match(/^\/\/\/\s*@dev\s+(.+)$/);
|
|
42948
|
-
if (dev) notEnforced.push(dev[1].trim());
|
|
42949
|
-
}
|
|
42950
|
-
if (enforced.length === 0 && notEnforced.length === 0) return null;
|
|
42951
|
-
return { source: "natspec", enforced, notEnforced };
|
|
42952
|
-
}
|
|
42953
|
-
function parseRequires(src) {
|
|
42954
|
-
const enforced = [];
|
|
42955
|
-
const re = /require\s*\([^,)]+,\s*["']([^"']+)["']\)/g;
|
|
42956
|
-
let m;
|
|
42957
|
-
while ((m = re.exec(src)) !== null) enforced.push(m[1]);
|
|
42958
|
-
if (enforced.length === 0) return null;
|
|
42959
|
-
return { source: "require-only", enforced, notEnforced: [] };
|
|
42960
|
-
}
|
|
42961
|
-
|
|
42962
|
-
// src/commands/mandate.ts
|
|
42963
43024
|
function resolveActiveChain(account2) {
|
|
42964
43025
|
try {
|
|
42965
43026
|
const project = new ProjectContext();
|
|
@@ -43035,7 +43096,9 @@ ${permissions.length} permission(s) tracked for SMA ${account2.safe}:
|
|
|
43035
43096
|
const draft = {
|
|
43036
43097
|
account: account2.safe,
|
|
43037
43098
|
chainId,
|
|
43038
|
-
|
|
43099
|
+
// Only permissions not already registered on this SMA belong in the signing
|
|
43100
|
+
// draft — re-registering an already-registered permission reverts on-chain.
|
|
43101
|
+
permissions: permissions.filter((p) => !p.revokedOnChain && !p.registeredOnSma).map((p) => {
|
|
43039
43102
|
const mandate2 = store.find(p.address);
|
|
43040
43103
|
const explanation = explainPermission(p.label, mandate2?.sourcePath) ?? void 0;
|
|
43041
43104
|
return { address: p.address, label: p.label, explanation };
|
|
@@ -45170,9 +45233,12 @@ function tailscaleServeUp(port) {
|
|
|
45170
45233
|
["serve", "--bg", "--https=443", `http://127.0.0.1:${port}`],
|
|
45171
45234
|
{ encoding: "utf-8" }
|
|
45172
45235
|
);
|
|
45236
|
+
const out = `${r.stdout ?? ""}${r.stderr ?? ""}`;
|
|
45173
45237
|
if (r.status !== 0) {
|
|
45174
|
-
|
|
45175
|
-
|
|
45238
|
+
throw new Error(out.trim() || `exit ${r.status ?? "?"}`);
|
|
45239
|
+
}
|
|
45240
|
+
if (/serve is not enabled/i.test(out)) {
|
|
45241
|
+
throw new Error(out.trim());
|
|
45176
45242
|
}
|
|
45177
45243
|
}
|
|
45178
45244
|
function tailscaleServeDown() {
|