@dev.sail.money/sailor 1.3.0-225 → 1.3.0-227
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 +16 -0
- package/examples/custom-mandate/.sail/contracts/interfaces/IPermission.sol +4 -0
- package/examples/custom-mandate/README.md +4 -1
- package/examples/permissions/interfaces/IBatchPermission.sol +2 -0
- package/examples/permissions/interfaces/IPermission.sol +4 -0
- package/package.json +7 -1
- package/packages/cli/dist/index.cjs +58 -10
- package/packages/cli/dist/server.cjs +105 -23
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/packages/ui/dist/assets/{add-QIu9SGBU.js → add-DoHGZfJI.js} +2 -2
- package/packages/ui/dist/assets/{all-wallets-2auxp9E5.js → all-wallets-CUKVFyT3.js} +2 -2
- package/packages/ui/dist/assets/{app-store-BVtVvk-F.js → app-store-DyQ4PZOs.js} +1 -1
- package/packages/ui/dist/assets/{apple-Dq7Ppvqv.js → apple-Dc-GOiDW.js} +2 -2
- package/packages/ui/dist/assets/arrow-bottom-C-dI8Oh_.js +8 -0
- package/packages/ui/dist/assets/{arrow-bottom-circle-hkf9bWhW.js → arrow-bottom-circle-BH2LebvP.js} +2 -2
- package/packages/ui/dist/assets/arrow-left-CUIn5NsD.js +8 -0
- package/packages/ui/dist/assets/arrow-right-B-X57DDF.js +8 -0
- package/packages/ui/dist/assets/arrow-top-BNOmzVbg.js +8 -0
- package/packages/ui/dist/assets/{bank-CkRSSgJy.js → bank-Dqcy3Map.js} +2 -2
- package/packages/ui/dist/assets/{basic-D9puI79I.js → basic-CN95kOlB.js} +177 -177
- package/packages/ui/dist/assets/{browser-BC8qo0Bh.js → browser-v-WzD6Au.js} +2 -2
- package/packages/ui/dist/assets/{card-BYuGTxNc.js → card-DJmQXuOi.js} +2 -2
- package/packages/ui/dist/assets/ccip-8oS512uk.js +1 -0
- package/packages/ui/dist/assets/{checkmark-C-MZeapS.js → checkmark-6Rvy6Al7.js} +2 -2
- package/packages/ui/dist/assets/{checkmark-bold-Bs3hadsW.js → checkmark-bold-GYXSMFUr.js} +2 -2
- package/packages/ui/dist/assets/chevron-bottom-BF1Fa2NO.js +8 -0
- package/packages/ui/dist/assets/chevron-left-kj9KjPLp.js +8 -0
- package/packages/ui/dist/assets/chevron-right-CHH0lg7_.js +8 -0
- package/packages/ui/dist/assets/chevron-top-DjHmnG32.js +8 -0
- package/packages/ui/dist/assets/{chrome-store-sDKm_6es.js → chrome-store-KzNe4H9H.js} +2 -2
- package/packages/ui/dist/assets/{clock-BwfFymxk.js → clock-xHvMNQNx.js} +2 -2
- package/packages/ui/dist/assets/{close-BewD5_E0.js → close-nKtgX0WM.js} +2 -2
- package/packages/ui/dist/assets/{coinPlaceholder-DRPvf0NA.js → coinPlaceholder-gnwD3g4G.js} +2 -2
- package/packages/ui/dist/assets/{compass-BHPvd2dw.js → compass-wnLBxh3w.js} +2 -2
- package/packages/ui/dist/assets/{copy-BMv4Y3KF.js → copy-CmLisiOG.js} +2 -2
- package/packages/ui/dist/assets/core-BLOM5s8O.js +907 -0
- package/packages/ui/dist/assets/cursor-DgwjrlpZ.js +3 -0
- package/packages/ui/dist/assets/{cursor-transparent-DT8YBqHU.js → cursor-transparent-CjVDknUI.js} +2 -2
- package/packages/ui/dist/assets/{desktop-BeePUUqi.js → desktop-BSGjR5fT.js} +2 -2
- package/packages/ui/dist/assets/{disconnect-C2qT29qY.js → disconnect-DkOQ_j9U.js} +2 -2
- package/packages/ui/dist/assets/{discord-I4ToELfU.js → discord-DtvZ281_.js} +2 -2
- package/packages/ui/dist/assets/{etherscan-3psXC5Ef.js → etherscan-BB3baLbR.js} +2 -2
- package/packages/ui/dist/assets/events-DQ172AOg.js +1 -0
- package/packages/ui/dist/assets/{exclamation-triangle-BCaWksGJ.js → exclamation-triangle-BrR8a-pR.js} +2 -2
- package/packages/ui/dist/assets/{extension-DfYavvbY.js → extension-BiGAMg97.js} +2 -2
- package/packages/ui/dist/assets/external-link-qUc7QuKA.js +8 -0
- package/packages/ui/dist/assets/{facebook-BSvrXy3w.js → facebook-BuXatc22.js} +2 -2
- package/packages/ui/dist/assets/{farcaster-CcAuzEDi.js → farcaster-USwPlLU8.js} +2 -2
- package/packages/ui/dist/assets/{filters-umCx-UFU.js → filters-BWx3pZxN.js} +2 -2
- package/packages/ui/dist/assets/{github-CBNoBl67.js → github-CUSWD7ff.js} +2 -2
- package/packages/ui/dist/assets/{google-yyR1jNOC.js → google-CxJSLEaz.js} +2 -2
- package/packages/ui/dist/assets/{help-circle-C0WjKnIM.js → help-circle-_8isjSO0.js} +1 -1
- package/packages/ui/dist/assets/{id-BwIK6e_N.js → id-DJCzMfx_.js} +2 -2
- package/packages/ui/dist/assets/{image-D5oAo1Te.js → image-CmG69MZj.js} +2 -2
- package/packages/ui/dist/assets/{index-DMNSiu42.js → index-3YqzzyrK.js} +3 -3
- package/packages/ui/dist/assets/index-B07bCKJ8.css +1 -0
- package/packages/ui/dist/assets/index-BIqjq0q5.js +1 -0
- package/packages/ui/dist/assets/index-BV8s6ez1.js +1 -0
- package/packages/ui/dist/assets/index-D8zwDy7d.js +1780 -0
- package/packages/ui/dist/assets/index-DHVwxjrm.js +47 -0
- package/packages/ui/dist/assets/index-DsxB7ORb.js +16 -0
- package/packages/ui/dist/assets/index.es-Hqwz_Ukd.js +26 -0
- package/packages/ui/dist/assets/{info-CtcvKk8x.js → info-XYctdUoY.js} +2 -2
- package/packages/ui/dist/assets/{info-circle-BIm6XYyt.js → info-circle-D_fYZUhv.js} +2 -2
- package/packages/ui/dist/assets/{lightbulb-CMj21RIi.js → lightbulb-BqKkDThe.js} +2 -2
- package/packages/ui/dist/assets/{mail-C805tcaU.js → mail-CM4laVWT.js} +2 -2
- package/packages/ui/dist/assets/metamask-sdk-8TvB8vxr.js +542 -0
- package/packages/ui/dist/assets/{mobile-BEii3NyZ.js → mobile-C2cl_MIN.js} +2 -2
- package/packages/ui/dist/assets/{more-RSnRt81X.js → more-DOik7ytj.js} +2 -2
- package/packages/ui/dist/assets/{network-placeholder-s9JaqzCQ.js → network-placeholder-CC9Cg0q_.js} +2 -2
- package/packages/ui/dist/assets/{nftPlaceholder-Ccur2yVc.js → nftPlaceholder-Oe_bTYkM.js} +2 -2
- package/packages/ui/dist/assets/{off-DUtG4rlI.js → off-ao0Rdo1E.js} +2 -2
- package/packages/ui/dist/assets/{play-store-Bt2HvO3e.js → play-store-BcQlROdR.js} +2 -2
- package/packages/ui/dist/assets/{plus-BtEzQu0h.js → plus-DSOprccT.js} +2 -2
- package/packages/ui/dist/assets/{qr-code-xbQZ-Nio.js → qr-code-B64-C9CJ.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-d9pzE6vq.js → recycle-horizontal-BJg7qNO9.js} +2 -2
- package/packages/ui/dist/assets/{refresh-B3-2Sch0.js → refresh-Dexg1q9p.js} +2 -2
- package/packages/ui/dist/assets/{reown-logo-DBkmQAX8.js → reown-logo-D8KP4d24.js} +2 -2
- package/packages/ui/dist/assets/{search-dgDA8Ou5.js → search-CBfhIhB0.js} +2 -2
- package/packages/ui/dist/assets/{secp256k1-C4g4FCze.js → secp256k1-BOKPNuRR.js} +1 -1
- package/packages/ui/dist/assets/{send-CEDXr4l7.js → send-DpJV-P0b.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontal-Co6_f8oH.js → swapHorizontal-DC-Elc2j.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalBold-k4d22FNy.js → swapHorizontalBold-Unn8xI55.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalMedium-Des6w_mz.js → swapHorizontalMedium-B58RR8wP.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-CVd4538j.js → swapHorizontalRoundedBold-UTrbE6zM.js} +2 -2
- package/packages/ui/dist/assets/{swapVertical-Cn_eRfv8.js → swapVertical-CLBtBVG1.js} +2 -2
- package/packages/ui/dist/assets/{telegram-BE46RC0s.js → telegram-C_tvCVU8.js} +2 -2
- package/packages/ui/dist/assets/{three-dots-CvqWsUWa.js → three-dots-BIn_IFa0.js} +2 -2
- package/packages/ui/dist/assets/{twitch-9V7YXB0X.js → twitch-BqiEXRul.js} +2 -2
- package/packages/ui/dist/assets/{twitterIcon-DbUxk6yk.js → twitterIcon-CquA5TCG.js} +2 -2
- package/packages/ui/dist/assets/{verify-CQSnwVrh.js → verify-DOUX5_SE.js} +2 -2
- package/packages/ui/dist/assets/{verify-filled-DG_hDTr8.js → verify-filled-nMk53S_a.js} +2 -2
- package/packages/ui/dist/assets/{w3m-modal-BsHGIrg7.js → w3m-modal-B-JVYtbP.js} +1 -1
- package/packages/ui/dist/assets/{wallet-lbVIReb_.js → wallet-BjbzMOXA.js} +2 -2
- package/packages/ui/dist/assets/{wallet-placeholder-C_ndmKAs.js → wallet-placeholder-DPidGoJt.js} +2 -2
- package/packages/ui/dist/assets/{walletconnect-ByDpG-E0.js → walletconnect-Dw14KwDj.js} +3 -3
- package/packages/ui/dist/assets/{warning-circle-hrS3II0d.js → warning-circle-Ewxxj9bx.js} +2 -2
- package/packages/ui/dist/assets/{x-BPMn3x5J.js → x-B5Li_yME.js} +2 -2
- package/packages/ui/dist/index.html +2 -2
- package/templates/default/.agents/skills/sail-mandates/references/examples-index.md +2 -2
- package/templates/default/.agents/skills/sail-servers/SKILL.md +1 -0
- package/templates/default/.env.example +9 -0
- package/templates/default/test/BoundedCallPermission.t.sol +2 -1
- package/packages/ui/dist/assets/arrow-bottom-DpT3R4Rr.js +0 -8
- package/packages/ui/dist/assets/arrow-left-3PhiE4SD.js +0 -8
- package/packages/ui/dist/assets/arrow-right-DUIXJHib.js +0 -8
- package/packages/ui/dist/assets/arrow-top-Cf--02la.js +0 -8
- package/packages/ui/dist/assets/ccip-BS_rjbk9.js +0 -1
- package/packages/ui/dist/assets/chevron-bottom-C8mqtkD4.js +0 -8
- package/packages/ui/dist/assets/chevron-left-Dxj-vVDJ.js +0 -8
- package/packages/ui/dist/assets/chevron-right-BoIrOTtL.js +0 -8
- package/packages/ui/dist/assets/chevron-top-BlgziB_P.js +0 -8
- package/packages/ui/dist/assets/core-BMNH6XFj.js +0 -907
- package/packages/ui/dist/assets/cursor-ir0cjMUl.js +0 -3
- package/packages/ui/dist/assets/events-Cdt6abbf.js +0 -1
- package/packages/ui/dist/assets/external-link-B8uBskz7.js +0 -8
- package/packages/ui/dist/assets/fallback-BSMYROva.js +0 -1
- package/packages/ui/dist/assets/index-B_Gc8xPp.js +0 -1
- package/packages/ui/dist/assets/index-BaEe036r.js +0 -1
- package/packages/ui/dist/assets/index-BuqyrXYX.js +0 -16
- package/packages/ui/dist/assets/index-CKoOBsKn.css +0 -1
- package/packages/ui/dist/assets/index-CPrhuDfP.js +0 -1782
- package/packages/ui/dist/assets/index-DCWU1RuS.js +0 -1
- package/packages/ui/dist/assets/index.es-DImsg59a.js +0 -26
- package/packages/ui/dist/assets/metamask-sdk-DDk4vkrl.js +0 -542
- package/packages/ui/dist/assets/native-CJ5et6AR.js +0 -1
- package/packages/ui/dist/assets/parseSignature-BbS8pxpB.js +0 -1
package/README.md
CHANGED
|
@@ -295,6 +295,22 @@ the station), set a comma-separated list — the local origin is always allowed:
|
|
|
295
295
|
SAILOR_CORS_ORIGINS=https://hermes.example.ts.net,https://another.host
|
|
296
296
|
```
|
|
297
297
|
|
|
298
|
+
By default the UI server binds `127.0.0.1` (local only). To reach it from another
|
|
299
|
+
device **without** Tailscale — e.g. behind your own reverse proxy on a domain — bind
|
|
300
|
+
all interfaces and throttle the key-management endpoints:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
SAILOR_HOST=0.0.0.0 # bind all interfaces (default 127.0.0.1)
|
|
304
|
+
SAILOR_TRUST_PROXY=1 # hops to your proxy (or an IP allowlist), so rate limits key on the real client IP
|
|
305
|
+
SAILOR_RATE_LIMIT_PER_MIN=100 # cap /api/signer + /api/onboard/generate-key (default 100)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Behind a reverse proxy, set `SAILOR_TRUST_PROXY` (usually `1`) — otherwise the rate
|
|
309
|
+
limiter sees only the proxy's IP and applies one shared bucket to all clients.
|
|
310
|
+
|
|
311
|
+
The key-management endpoints are **unauthenticated** — only expose them behind your
|
|
312
|
+
own auth (reverse-proxy basic-auth, or a private tailnet), never the open internet.
|
|
313
|
+
|
|
298
314
|
---
|
|
299
315
|
|
|
300
316
|
## Agent-driven onboarding & custom mandates
|
|
@@ -10,6 +10,10 @@ struct Context {
|
|
|
10
10
|
uint256 value;
|
|
11
11
|
uint256 blockTimestamp;
|
|
12
12
|
uint256 blockNumber;
|
|
13
|
+
/// @dev Kernel registrationEpoch(account, permission) at dispatch. Configurable
|
|
14
|
+
/// permissions fail closed on a mismatch with the epoch stamped at configure()
|
|
15
|
+
/// time; permissions without post-deploy configuration can ignore it.
|
|
16
|
+
uint256 configEpoch;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
interface IPermission {
|
|
@@ -36,11 +36,14 @@ struct Context {
|
|
|
36
36
|
uint256 value; // msg.value (native asset) sent with the call
|
|
37
37
|
uint256 blockTimestamp; // block.timestamp at evaluation
|
|
38
38
|
uint256 blockNumber; // block.number at evaluation
|
|
39
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch;
|
|
40
|
+
// ignore it unless your permission takes post-deploy configuration
|
|
39
41
|
}
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
- `evaluate` — your policy. Return `true` to permit the call, `false` to block it. Runs under a
|
|
43
|
-
|
|
45
|
+
150,000-gas `staticcall` (`SailKernel.PERMISSION_GAS_CAP`); a revert or gas overage is treated
|
|
46
|
+
as `false`.
|
|
44
47
|
- `discriminator` — a stable `bytes32` name for your permission (e.g. `keccak256("MyMandate")`).
|
|
45
48
|
|
|
46
49
|
Keep all policy parameters constructor-configured so each deployment is a complete, reviewable
|
|
@@ -26,6 +26,8 @@ struct BatchContext {
|
|
|
26
26
|
bytes32 batchHash; // keccak256(abi.encode(calls)) — stable id for the exact sequence
|
|
27
27
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
28
28
|
uint256 blockNumber; // block.number at dispatch
|
|
29
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch —
|
|
30
|
+
// same fail-closed freshness check as Context.configEpoch
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
interface IBatchPermission {
|
|
@@ -10,6 +10,10 @@ struct Context {
|
|
|
10
10
|
uint256 value;
|
|
11
11
|
uint256 blockTimestamp;
|
|
12
12
|
uint256 blockNumber;
|
|
13
|
+
/// @dev Kernel registrationEpoch(account, permission) at dispatch. Configurable
|
|
14
|
+
/// permissions fail closed on a mismatch with the epoch stamped at configure()
|
|
15
|
+
/// time; permissions without post-deploy configuration can ignore it.
|
|
16
|
+
uint256 configEpoch;
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
interface IPermission {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev.sail.money/sailor",
|
|
3
|
-
"version": "1.3.0-
|
|
3
|
+
"version": "1.3.0-227",
|
|
4
4
|
"description": "Operator toolkit for Sail Protocol",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sailor": "packages/cli/dist/index.cjs"
|
|
@@ -42,5 +42,11 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"tsx": "^4.22.4"
|
|
45
|
+
},
|
|
46
|
+
"pnpm": {
|
|
47
|
+
"overrides": {
|
|
48
|
+
"form-data@<4.0.6": ">=4.0.6",
|
|
49
|
+
"hono@<4.12.25": ">=4.12.25"
|
|
50
|
+
}
|
|
45
51
|
}
|
|
46
52
|
}
|
|
@@ -39629,8 +39629,9 @@ var SigningServer = class {
|
|
|
39629
39629
|
}
|
|
39630
39630
|
}
|
|
39631
39631
|
if (!(0, import_node_fs6.existsSync)(this.runtimeDir)) (0, import_node_fs6.mkdirSync)(this.runtimeDir, { recursive: true });
|
|
39632
|
+
const serverStatePath = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
39632
39633
|
(0, import_node_fs6.writeFileSync)(
|
|
39633
|
-
|
|
39634
|
+
serverStatePath,
|
|
39634
39635
|
JSON.stringify(
|
|
39635
39636
|
{
|
|
39636
39637
|
url: this._url,
|
|
@@ -39642,8 +39643,10 @@ var SigningServer = class {
|
|
|
39642
39643
|
},
|
|
39643
39644
|
null,
|
|
39644
39645
|
2
|
|
39645
|
-
)
|
|
39646
|
+
),
|
|
39647
|
+
{ mode: 384 }
|
|
39646
39648
|
);
|
|
39649
|
+
(0, import_node_fs6.chmodSync)(serverStatePath, 384);
|
|
39647
39650
|
}
|
|
39648
39651
|
removeRuntimeState() {
|
|
39649
39652
|
const path11 = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
@@ -40542,15 +40545,36 @@ var IPERMISSION_ABI = [
|
|
|
40542
40545
|
{ name: "selector", type: "bytes4" },
|
|
40543
40546
|
{ name: "value", type: "uint256" },
|
|
40544
40547
|
{ name: "blockTimestamp", type: "uint256" },
|
|
40545
|
-
{ name: "blockNumber", type: "uint256" }
|
|
40548
|
+
{ name: "blockNumber", type: "uint256" },
|
|
40549
|
+
{ name: "configEpoch", type: "uint256" }
|
|
40546
40550
|
]
|
|
40547
40551
|
}
|
|
40548
40552
|
],
|
|
40549
40553
|
outputs: [{ type: "bool" }]
|
|
40550
40554
|
}
|
|
40551
40555
|
];
|
|
40556
|
+
var REGISTRATION_EPOCH_ABI2 = [
|
|
40557
|
+
{
|
|
40558
|
+
type: "function",
|
|
40559
|
+
name: "registrationEpoch",
|
|
40560
|
+
stateMutability: "view",
|
|
40561
|
+
inputs: [
|
|
40562
|
+
{ name: "account", type: "address" },
|
|
40563
|
+
{ name: "permission", type: "address" }
|
|
40564
|
+
],
|
|
40565
|
+
outputs: [{ type: "uint256" }]
|
|
40566
|
+
}
|
|
40567
|
+
];
|
|
40568
|
+
async function readRegistrationEpoch(publicClient, kernel, account2, permission) {
|
|
40569
|
+
return await publicClient.readContract({
|
|
40570
|
+
address: kernel,
|
|
40571
|
+
abi: REGISTRATION_EPOCH_ABI2,
|
|
40572
|
+
functionName: "registrationEpoch",
|
|
40573
|
+
args: [account2, permission]
|
|
40574
|
+
});
|
|
40575
|
+
}
|
|
40552
40576
|
function buildPermissionContext(params) {
|
|
40553
|
-
const { account: account2, manager, call: call2, blockInfo } = params;
|
|
40577
|
+
const { account: account2, manager, call: call2, blockInfo, configEpoch } = params;
|
|
40554
40578
|
const selector = call2.data.length >= 10 ? call2.data.slice(0, 10) : "0x00000000";
|
|
40555
40579
|
return {
|
|
40556
40580
|
account: account2,
|
|
@@ -40561,12 +40585,23 @@ function buildPermissionContext(params) {
|
|
|
40561
40585
|
selector,
|
|
40562
40586
|
value: call2.value,
|
|
40563
40587
|
blockTimestamp: blockInfo.timestamp,
|
|
40564
|
-
blockNumber: blockInfo.number
|
|
40588
|
+
blockNumber: blockInfo.number,
|
|
40589
|
+
configEpoch
|
|
40565
40590
|
};
|
|
40566
40591
|
}
|
|
40567
40592
|
async function probePermissionForCall(params) {
|
|
40568
|
-
const { publicClient, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40569
|
-
|
|
40593
|
+
const { publicClient, kernel, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40594
|
+
let configEpoch;
|
|
40595
|
+
try {
|
|
40596
|
+
configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40597
|
+
} catch (err) {
|
|
40598
|
+
return {
|
|
40599
|
+
accepted: false,
|
|
40600
|
+
reverted: true,
|
|
40601
|
+
error: `could not read registrationEpoch from kernel ${kernel} (${err.message.split("\n")[0]})`
|
|
40602
|
+
};
|
|
40603
|
+
}
|
|
40604
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40570
40605
|
try {
|
|
40571
40606
|
const accepted = await publicClient.readContract({
|
|
40572
40607
|
address: permission,
|
|
@@ -40580,10 +40615,11 @@ async function probePermissionForCall(params) {
|
|
|
40580
40615
|
}
|
|
40581
40616
|
}
|
|
40582
40617
|
async function resolvePermissionForCall(params) {
|
|
40583
|
-
const { publicClient, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40584
|
-
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo });
|
|
40618
|
+
const { publicClient, kernel, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40585
40619
|
for (const permission of registeredPermissions) {
|
|
40586
40620
|
try {
|
|
40621
|
+
const configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40622
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40587
40623
|
const accepted = await publicClient.readContract({
|
|
40588
40624
|
address: permission,
|
|
40589
40625
|
abi: IPERMISSION_ABI,
|
|
@@ -40653,7 +40689,10 @@ async function probePassThrough(pc, permission, account2) {
|
|
|
40653
40689
|
selector: PROBE_SELECTOR,
|
|
40654
40690
|
value: 0n,
|
|
40655
40691
|
blockTimestamp: 0n,
|
|
40656
|
-
blockNumber: 0n
|
|
40692
|
+
blockNumber: 0n,
|
|
40693
|
+
// Pass-through probes only run on conjunctive kernels, which predate
|
|
40694
|
+
// registrationEpoch — there is no live epoch to read, so probe with 0.
|
|
40695
|
+
configEpoch: 0n
|
|
40657
40696
|
}
|
|
40658
40697
|
]
|
|
40659
40698
|
});
|
|
@@ -40949,6 +40988,10 @@ struct Context {
|
|
|
40949
40988
|
uint256 value; // native ETH forwarded (wei)
|
|
40950
40989
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40951
40990
|
uint256 blockNumber; // block.number at dispatch
|
|
40991
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch;
|
|
40992
|
+
// configurable permissions fail closed on a mismatch with the
|
|
40993
|
+
// epoch stamped at configure() time. Custom permissions that
|
|
40994
|
+
// take no post-deploy configuration can ignore it.
|
|
40952
40995
|
}
|
|
40953
40996
|
|
|
40954
40997
|
/// @title IPermission
|
|
@@ -40984,6 +41027,8 @@ struct BatchContext {
|
|
|
40984
41027
|
bytes32 batchHash; // keccak256(abi.encode(calls)) \u2014 stable id for the exact sequence
|
|
40985
41028
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40986
41029
|
uint256 blockNumber; // block.number at dispatch
|
|
41030
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch \u2014
|
|
41031
|
+
// same fail-closed freshness check as Context.configEpoch
|
|
40987
41032
|
}
|
|
40988
41033
|
|
|
40989
41034
|
/// @title IBatchPermission
|
|
@@ -44361,6 +44406,7 @@ async function mandateSimulate(options) {
|
|
|
44361
44406
|
const [probe, codeCheck] = await Promise.all([
|
|
44362
44407
|
probePermissionForCall({
|
|
44363
44408
|
publicClient: pc,
|
|
44409
|
+
kernel: project.contracts.kernel,
|
|
44364
44410
|
permission,
|
|
44365
44411
|
account: account2,
|
|
44366
44412
|
manager,
|
|
@@ -45320,6 +45366,8 @@ Configure the chain in the SDK chain registry or set KERNEL_ADDRESS in .sail/.en
|
|
|
45320
45366
|
} else {
|
|
45321
45367
|
permission = await resolvePermissionForCall({
|
|
45322
45368
|
publicClient,
|
|
45369
|
+
kernel,
|
|
45370
|
+
// narrowed: runCommand validates kernel before runTick runs
|
|
45323
45371
|
account: accountAddr,
|
|
45324
45372
|
manager: agentManager.address,
|
|
45325
45373
|
call: firstCall,
|
|
@@ -46377,6 +46377,8 @@ var init_esm = __esm({
|
|
|
46377
46377
|
// ../ui/server.js
|
|
46378
46378
|
var server_exports = {};
|
|
46379
46379
|
__export(server_exports, {
|
|
46380
|
+
isHttpUrl: () => isHttpUrl,
|
|
46381
|
+
isSafeEnvValue: () => isSafeEnvValue,
|
|
46380
46382
|
startServer: () => startServer
|
|
46381
46383
|
});
|
|
46382
46384
|
module.exports = __toCommonJS(server_exports);
|
|
@@ -47879,6 +47881,41 @@ function persistPassphrase(envPath, passphrase) {
|
|
|
47879
47881
|
import_node_fs2.default.writeFileSync(envPath, content, { mode: 384 });
|
|
47880
47882
|
import_node_fs2.default.chmodSync(envPath, 384);
|
|
47881
47883
|
}
|
|
47884
|
+
function isSafeEnvValue(v) {
|
|
47885
|
+
return typeof v === "string" && !/[\n\r]/.test(v);
|
|
47886
|
+
}
|
|
47887
|
+
function isHttpUrl(v) {
|
|
47888
|
+
try {
|
|
47889
|
+
const u = new URL(v);
|
|
47890
|
+
return u.protocol === "http:" || u.protocol === "https:";
|
|
47891
|
+
} catch {
|
|
47892
|
+
return false;
|
|
47893
|
+
}
|
|
47894
|
+
}
|
|
47895
|
+
function serverError(res, err) {
|
|
47896
|
+
console.error(err);
|
|
47897
|
+
res.status(500).json({ error: "internal server error" });
|
|
47898
|
+
}
|
|
47899
|
+
function rateLimit({ windowMs, max }) {
|
|
47900
|
+
const hits = /* @__PURE__ */ new Map();
|
|
47901
|
+
let lastSweep = 0;
|
|
47902
|
+
return (req, res, next) => {
|
|
47903
|
+
const now = Date.now();
|
|
47904
|
+
if (now - lastSweep > windowMs) {
|
|
47905
|
+
for (const [k, v] of hits) if (now > v.resetAt) hits.delete(k);
|
|
47906
|
+
lastSweep = now;
|
|
47907
|
+
}
|
|
47908
|
+
const ip = req.ip || req.socket?.remoteAddress || "local";
|
|
47909
|
+
const rec = hits.get(ip);
|
|
47910
|
+
if (!rec || now > rec.resetAt) {
|
|
47911
|
+
hits.set(ip, { count: 1, resetAt: now + windowMs });
|
|
47912
|
+
return next();
|
|
47913
|
+
}
|
|
47914
|
+
if (rec.count >= max) return res.status(429).json({ error: "too many requests" });
|
|
47915
|
+
rec.count += 1;
|
|
47916
|
+
next();
|
|
47917
|
+
};
|
|
47918
|
+
}
|
|
47882
47919
|
var CHAIN_NAMES = {
|
|
47883
47920
|
1: "ethereum",
|
|
47884
47921
|
8453: "base",
|
|
@@ -47983,8 +48020,27 @@ function addManagerToList(existing, current, next) {
|
|
|
47983
48020
|
var OVERVIEW_TTL_MS = 1e4;
|
|
47984
48021
|
function startServer(sailDir, { port = PORT } = {}) {
|
|
47985
48022
|
const app = (0, import_express.default)();
|
|
48023
|
+
const trustProxy = process.env.SAILOR_TRUST_PROXY;
|
|
48024
|
+
if (trustProxy && trustProxy !== "false" && trustProxy !== "0") {
|
|
48025
|
+
const hops = Number(trustProxy);
|
|
48026
|
+
app.set("trust proxy", Number.isFinite(hops) ? hops : trustProxy === "true" ? true : trustProxy);
|
|
48027
|
+
}
|
|
47986
48028
|
app.use((0, import_cors.default)({ origin: CORS_ORIGINS }));
|
|
47987
48029
|
app.use(import_express.default.json());
|
|
48030
|
+
const rateLimitPerMin = (() => {
|
|
48031
|
+
const fromEnv = Number(process.env.SAILOR_RATE_LIMIT_PER_MIN);
|
|
48032
|
+
if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
|
|
48033
|
+
try {
|
|
48034
|
+
const cfg = JSON.parse(import_node_fs2.default.readFileSync(import_node_path.default.join(sailDir, "config.json"), "utf-8"));
|
|
48035
|
+
const fromCfg = Number(cfg?.rateLimitPerMin);
|
|
48036
|
+
if (Number.isFinite(fromCfg) && fromCfg > 0) return fromCfg;
|
|
48037
|
+
} catch {
|
|
48038
|
+
}
|
|
48039
|
+
return 100;
|
|
48040
|
+
})();
|
|
48041
|
+
const keyEndpointLimiter = rateLimit({ windowMs: 6e4, max: rateLimitPerMin });
|
|
48042
|
+
app.use("/api/signer", keyEndpointLimiter);
|
|
48043
|
+
app.use("/api/onboard/generate-key", keyEndpointLimiter);
|
|
47988
48044
|
const at = (name) => import_node_path.default.join(sailDir, name);
|
|
47989
48045
|
const syncConfigChainId = (chainId) => {
|
|
47990
48046
|
if (chainId == null) return;
|
|
@@ -48113,7 +48169,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48113
48169
|
overviewCacheByAccount.clear();
|
|
48114
48170
|
res.json({ ok: true });
|
|
48115
48171
|
} catch (err) {
|
|
48116
|
-
res
|
|
48172
|
+
serverError(res, err);
|
|
48117
48173
|
}
|
|
48118
48174
|
});
|
|
48119
48175
|
app.post("/api/account", async (req, res) => {
|
|
@@ -48156,7 +48212,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48156
48212
|
syncConfigChainId(chainId);
|
|
48157
48213
|
res.json({ ok: true });
|
|
48158
48214
|
} catch (err) {
|
|
48159
|
-
res
|
|
48215
|
+
serverError(res, err);
|
|
48160
48216
|
}
|
|
48161
48217
|
});
|
|
48162
48218
|
app.get("/api/accounts", (_req, res) => {
|
|
@@ -48195,7 +48251,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48195
48251
|
syncConfigChainId(target.chainId);
|
|
48196
48252
|
res.json({ ok: true, active: target });
|
|
48197
48253
|
} catch (err) {
|
|
48198
|
-
res
|
|
48254
|
+
serverError(res, err);
|
|
48199
48255
|
}
|
|
48200
48256
|
});
|
|
48201
48257
|
app.post("/api/account/rename", (req, res) => {
|
|
@@ -48204,6 +48260,11 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48204
48260
|
res.status(400).json({ error: "safe and name are required" });
|
|
48205
48261
|
return;
|
|
48206
48262
|
}
|
|
48263
|
+
const cleanName = typeof name === "string" ? name.replace(/\p{Cc}/gu, "").trim() : "";
|
|
48264
|
+
if (!cleanName || cleanName.length > 100) {
|
|
48265
|
+
res.status(400).json({ error: "name must be 1\u2013100 characters" });
|
|
48266
|
+
return;
|
|
48267
|
+
}
|
|
48207
48268
|
try {
|
|
48208
48269
|
const accountsPath = at("state/accounts.json");
|
|
48209
48270
|
const accounts = JSON.parse(import_node_fs2.default.readFileSync(accountsPath, "utf-8"));
|
|
@@ -48212,12 +48273,12 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48212
48273
|
res.status(404).json({ error: "SMA not found" });
|
|
48213
48274
|
return;
|
|
48214
48275
|
}
|
|
48215
|
-
accounts[idx] = { ...accounts[idx], name };
|
|
48276
|
+
accounts[idx] = { ...accounts[idx], name: cleanName };
|
|
48216
48277
|
import_node_fs2.default.writeFileSync(accountsPath, `${JSON.stringify(accounts, null, 2)}
|
|
48217
48278
|
`);
|
|
48218
48279
|
res.json({ ok: true });
|
|
48219
48280
|
} catch (err) {
|
|
48220
|
-
res
|
|
48281
|
+
serverError(res, err);
|
|
48221
48282
|
}
|
|
48222
48283
|
});
|
|
48223
48284
|
const readActiveSafe = () => {
|
|
@@ -48286,7 +48347,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48286
48347
|
`);
|
|
48287
48348
|
res.json({ ok: true, event });
|
|
48288
48349
|
} catch (err) {
|
|
48289
|
-
res
|
|
48350
|
+
serverError(res, err);
|
|
48290
48351
|
}
|
|
48291
48352
|
});
|
|
48292
48353
|
const managerKeyPath = (safe) => at(`keys/manager-${safe.toLowerCase()}.json`);
|
|
@@ -48345,7 +48406,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48345
48406
|
invalidateOverviewCache(safe);
|
|
48346
48407
|
res.json({ ok: true, address: keyring.address, revealed });
|
|
48347
48408
|
} catch (err) {
|
|
48348
|
-
res
|
|
48409
|
+
serverError(res, err);
|
|
48349
48410
|
}
|
|
48350
48411
|
});
|
|
48351
48412
|
app.post("/api/manager/complete", (req, res) => {
|
|
@@ -48392,7 +48453,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48392
48453
|
invalidateOverviewCache(safe);
|
|
48393
48454
|
res.json({ ok: true, manager });
|
|
48394
48455
|
} catch (err) {
|
|
48395
|
-
res
|
|
48456
|
+
serverError(res, err);
|
|
48396
48457
|
}
|
|
48397
48458
|
});
|
|
48398
48459
|
const isManagerKeyFile = (file) => file === "manager.json" || file.startsWith("manager-") && file.endsWith(".json") || file.startsWith("managers/") && file.endsWith(".json");
|
|
@@ -48445,7 +48506,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48445
48506
|
}
|
|
48446
48507
|
res.json({ signers: [...byAddress.values()] });
|
|
48447
48508
|
} catch (err) {
|
|
48448
|
-
res
|
|
48509
|
+
serverError(res, err);
|
|
48449
48510
|
}
|
|
48450
48511
|
});
|
|
48451
48512
|
app.post("/api/signer/activate", (req, res) => {
|
|
@@ -48476,7 +48537,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48476
48537
|
invalidateOverviewCache(safe);
|
|
48477
48538
|
res.json({ ok: true, address: getAddress(address), file: match });
|
|
48478
48539
|
} catch (err) {
|
|
48479
|
-
res
|
|
48540
|
+
serverError(res, err);
|
|
48480
48541
|
}
|
|
48481
48542
|
});
|
|
48482
48543
|
app.get("/api/mandate", (_req, res) => {
|
|
@@ -48575,7 +48636,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48575
48636
|
}
|
|
48576
48637
|
}
|
|
48577
48638
|
} catch (err) {
|
|
48578
|
-
res.status(500).json({ error: `On-chain registration failed: ${err?.message ?? String(err)}` });
|
|
48639
|
+
res.status(500).json({ error: `On-chain registration failed: ${(err?.message ?? String(err)).split("\n")[0]}` });
|
|
48579
48640
|
return;
|
|
48580
48641
|
}
|
|
48581
48642
|
const mandate = {
|
|
@@ -48606,7 +48667,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48606
48667
|
}
|
|
48607
48668
|
res.json(mandate);
|
|
48608
48669
|
} catch (err) {
|
|
48609
|
-
res
|
|
48670
|
+
serverError(res, err);
|
|
48610
48671
|
}
|
|
48611
48672
|
});
|
|
48612
48673
|
const readPidFile = (filePath) => {
|
|
@@ -48822,6 +48883,19 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48822
48883
|
});
|
|
48823
48884
|
app.post("/api/onboard/save-config", (req, res) => {
|
|
48824
48885
|
const { rpcUrl, sailApiKey, chainId } = req.body ?? {};
|
|
48886
|
+
const cid = Number(chainId);
|
|
48887
|
+
if (chainId !== void 0 && !CHAIN_RPC_ENV_KEYS[cid]) {
|
|
48888
|
+
res.status(400).json({ error: "unsupported chainId" });
|
|
48889
|
+
return;
|
|
48890
|
+
}
|
|
48891
|
+
if (rpcUrl !== void 0 && (!isSafeEnvValue(rpcUrl) || !isHttpUrl(rpcUrl))) {
|
|
48892
|
+
res.status(400).json({ error: "invalid rpcUrl" });
|
|
48893
|
+
return;
|
|
48894
|
+
}
|
|
48895
|
+
if (sailApiKey !== void 0 && !isSafeEnvValue(sailApiKey)) {
|
|
48896
|
+
res.status(400).json({ error: "invalid sailApiKey" });
|
|
48897
|
+
return;
|
|
48898
|
+
}
|
|
48825
48899
|
try {
|
|
48826
48900
|
const config = (() => {
|
|
48827
48901
|
try {
|
|
@@ -48834,20 +48908,20 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48834
48908
|
const envPath = at(".env.local");
|
|
48835
48909
|
const existing = parseEnvFile(envPath);
|
|
48836
48910
|
if (rpcUrl && chainId) {
|
|
48837
|
-
existing[`RPC_URL_${
|
|
48838
|
-
if (
|
|
48911
|
+
existing[`RPC_URL_${cid}`] = rpcUrl;
|
|
48912
|
+
if (cid === Number(activeChainId)) existing.RPC_URL = rpcUrl;
|
|
48839
48913
|
} else if (rpcUrl) {
|
|
48840
48914
|
existing.RPC_URL = rpcUrl;
|
|
48841
48915
|
}
|
|
48842
48916
|
if (sailApiKey) existing.SAIL_API_KEY = sailApiKey;
|
|
48843
|
-
if (chainId) existing.CHAIN_ID = String(
|
|
48917
|
+
if (chainId) existing.CHAIN_ID = String(cid);
|
|
48844
48918
|
const content = Object.entries(existing).map(([k, v]) => `${k}=${v}`).join("\n") + "\n";
|
|
48845
48919
|
import_node_fs2.default.mkdirSync(sailDir, { recursive: true });
|
|
48846
48920
|
import_node_fs2.default.writeFileSync(envPath, content, { mode: 384 });
|
|
48847
48921
|
import_node_fs2.default.chmodSync(envPath, 384);
|
|
48848
48922
|
res.json({ ok: true });
|
|
48849
48923
|
} catch (err) {
|
|
48850
|
-
res
|
|
48924
|
+
serverError(res, err);
|
|
48851
48925
|
}
|
|
48852
48926
|
});
|
|
48853
48927
|
app.post("/api/onboard/generate-key", async (req, res) => {
|
|
@@ -48876,7 +48950,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48876
48950
|
persistPassphrase(at(".env.local"), passphrase);
|
|
48877
48951
|
res.json({ address: keyring.address, existed: false });
|
|
48878
48952
|
} catch (err) {
|
|
48879
|
-
res
|
|
48953
|
+
serverError(res, err);
|
|
48880
48954
|
}
|
|
48881
48955
|
});
|
|
48882
48956
|
app.post("/api/onboard/build-create-tx", (req, res) => {
|
|
@@ -48928,7 +49002,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48928
49002
|
});
|
|
48929
49003
|
res.json({ to: kernel, data, chainId, saltNonce: saltNonce.toString() });
|
|
48930
49004
|
} catch (err) {
|
|
48931
|
-
res
|
|
49005
|
+
serverError(res, err);
|
|
48932
49006
|
}
|
|
48933
49007
|
});
|
|
48934
49008
|
app.post("/api/onboard/build-register-path", (req, res) => {
|
|
@@ -48982,7 +49056,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
48982
49056
|
saltNonce: saltNonce.toString()
|
|
48983
49057
|
});
|
|
48984
49058
|
} catch (err) {
|
|
48985
|
-
res
|
|
49059
|
+
serverError(res, err);
|
|
48986
49060
|
}
|
|
48987
49061
|
});
|
|
48988
49062
|
app.post("/api/onboard/complete", async (req, res) => {
|
|
@@ -49050,7 +49124,7 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
49050
49124
|
syncConfigChainId(chainId);
|
|
49051
49125
|
res.json({ ok: true, account: record });
|
|
49052
49126
|
} catch (err) {
|
|
49053
|
-
res
|
|
49127
|
+
serverError(res, err);
|
|
49054
49128
|
}
|
|
49055
49129
|
});
|
|
49056
49130
|
app.get("/api/wizard-state", (_req, res) => {
|
|
@@ -49062,13 +49136,18 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
49062
49136
|
}
|
|
49063
49137
|
});
|
|
49064
49138
|
app.post("/api/wizard-state", (req, res) => {
|
|
49139
|
+
const body = req.body;
|
|
49140
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) {
|
|
49141
|
+
res.status(400).json({ error: "wizard state must be an object" });
|
|
49142
|
+
return;
|
|
49143
|
+
}
|
|
49065
49144
|
try {
|
|
49066
49145
|
import_node_fs2.default.mkdirSync(sailDir, { recursive: true });
|
|
49067
|
-
import_node_fs2.default.writeFileSync(at(".wizard-state.json"), `${JSON.stringify(
|
|
49146
|
+
import_node_fs2.default.writeFileSync(at(".wizard-state.json"), `${JSON.stringify(body, null, 2)}
|
|
49068
49147
|
`);
|
|
49069
49148
|
res.json({ ok: true });
|
|
49070
49149
|
} catch (err) {
|
|
49071
|
-
res
|
|
49150
|
+
serverError(res, err);
|
|
49072
49151
|
}
|
|
49073
49152
|
});
|
|
49074
49153
|
app.get("/api/positions", (_req, res) => {
|
|
@@ -49348,7 +49427,8 @@ function startServer(sailDir, { port = PORT } = {}) {
|
|
|
49348
49427
|
res.sendFile(import_node_path.default.join(distDir, "index.html"));
|
|
49349
49428
|
});
|
|
49350
49429
|
}
|
|
49351
|
-
const
|
|
49430
|
+
const bindHost = process.env.SAILOR_HOST ?? "127.0.0.1";
|
|
49431
|
+
const httpServer = app.listen(port, bindHost, () => {
|
|
49352
49432
|
console.log(`Sailor UI running at http://localhost:${port} (reading ${sailDir})`);
|
|
49353
49433
|
});
|
|
49354
49434
|
const wss = new import_websocket_server.default({ noServer: true });
|
|
@@ -49427,6 +49507,8 @@ if (isMain) {
|
|
|
49427
49507
|
}
|
|
49428
49508
|
// Annotate the CommonJS export names for ESM import in node:
|
|
49429
49509
|
0 && (module.exports = {
|
|
49510
|
+
isHttpUrl,
|
|
49511
|
+
isSafeEnvValue,
|
|
49430
49512
|
startServer
|
|
49431
49513
|
});
|
|
49432
49514
|
/*! Bundled license information:
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Do not edit manually — run `pnpm build` to regenerate.
|
|
6
6
|
*
|
|
7
7
|
* Spec version : 1.2.1
|
|
8
|
-
* Generated at : 2026-07-
|
|
8
|
+
* Generated at : 2026-07-02T16:26:37.498Z
|
|
9
9
|
*/
|
|
10
10
|
export declare const SAIL_INTELLIGENCE_BASE_URL = "https://api.sail.money";
|
|
11
11
|
export declare const SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Do not edit manually — run `pnpm build` to regenerate.
|
|
6
6
|
*
|
|
7
7
|
* Spec version : 1.2.1
|
|
8
|
-
* Generated at : 2026-07-
|
|
8
|
+
* Generated at : 2026-07-02T16:26:37.498Z
|
|
9
9
|
*/
|
|
10
10
|
export const SAIL_INTELLIGENCE_BASE_URL = "https://api.sail.money";
|
|
11
11
|
export const SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F as o}from"./core-
|
|
1
|
+
import{F as o}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const e=o`<svg
|
|
2
2
|
width="14"
|
|
3
3
|
height="14"
|
|
4
4
|
viewBox="0 0 14 14"
|
|
@@ -12,4 +12,4 @@ import{F as o}from"./core-BMNH6XFj.js";import"./index-CPrhuDfP.js";import"./even
|
|
|
12
12
|
d="M7.0023 0.875C7.48571 0.875 7.8776 1.26675 7.8776 1.75V6.125H12.2541C12.7375 6.125 13.1294 6.51675 13.1294 7C13.1294 7.48325 12.7375 7.875 12.2541 7.875H7.8776V12.25C7.8776 12.7332 7.48571 13.125 7.0023 13.125C6.51889 13.125 6.12701 12.7332 6.12701 12.25V7.875H1.75054C1.26713 7.875 0.875244 7.48325 0.875244 7C0.875244 6.51675 1.26713 6.125 1.75054 6.125H6.12701V1.75C6.12701 1.26675 6.51889 0.875 7.0023 0.875Z"
|
|
13
13
|
fill="#667dff"
|
|
14
14
|
/></svg
|
|
15
|
-
>`;export{
|
|
15
|
+
>`;export{e as addSvg};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{F as o}from"./core-
|
|
1
|
+
import{F as o}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const r=o`<svg fill="none" viewBox="0 0 24 24">
|
|
2
2
|
<path
|
|
3
3
|
style="fill: var(--wui-color-accent-100);"
|
|
4
4
|
d="M10.2 6.6a3.6 3.6 0 1 1-7.2 0 3.6 3.6 0 0 1 7.2 0ZM21 6.6a3.6 3.6 0 1 1-7.2 0 3.6 3.6 0 0 1 7.2 0ZM10.2 17.4a3.6 3.6 0 1 1-7.2 0 3.6 3.6 0 0 1 7.2 0ZM21 17.4a3.6 3.6 0 1 1-7.2 0 3.6 3.6 0 0 1 7.2 0Z"
|
|
5
5
|
/>
|
|
6
|
-
</svg>`;export{
|
|
6
|
+
</svg>`;export{r as allWalletsSvg};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F as t}from"./core-
|
|
1
|
+
import{F as t}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const e=t`
|
|
2
2
|
<svg width="36" height="36">
|
|
3
3
|
<path
|
|
4
4
|
d="M28.724 0H7.271A7.269 7.269 0 0 0 0 7.272v21.46A7.268 7.268 0 0 0 7.271 36H28.73A7.272 7.272 0 0 0 36 28.728V7.272A7.275 7.275 0 0 0 28.724 0Z"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F as i}from"./core-
|
|
1
|
+
import{F as i}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const c=i`<svg fill="none" viewBox="0 0 40 40">
|
|
2
2
|
<g clip-path="url(#a)">
|
|
3
3
|
<g clip-path="url(#b)">
|
|
4
4
|
<circle cx="20" cy="19.89" r="20" fill="#000" />
|
|
@@ -15,4 +15,4 @@ import{F as i}from"./core-BMNH6XFj.js";import"./index-CPrhuDfP.js";import"./even
|
|
|
15
15
|
<clipPath id="b"><path fill="#fff" d="M0 0h40v40H0z" /></clipPath>
|
|
16
16
|
<clipPath id="c"><path fill="#fff" d="M8 7.89h24v24H8z" /></clipPath>
|
|
17
17
|
</defs>
|
|
18
|
-
</svg>`;export{
|
|
18
|
+
</svg>`;export{c as appleSvg};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{F as o}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const i=o`<svg fill="none" viewBox="0 0 14 15">
|
|
2
|
+
<path
|
|
3
|
+
fill="currentColor"
|
|
4
|
+
fill-rule="evenodd"
|
|
5
|
+
d="M7 1.99a1 1 0 0 1 1 1v7.58l2.46-2.46a1 1 0 0 1 1.41 1.42L7.7 13.69a1 1 0 0 1-1.41 0L2.12 9.53A1 1 0 0 1 3.54 8.1L6 10.57V3a1 1 0 0 1 1-1Z"
|
|
6
|
+
clip-rule="evenodd"
|
|
7
|
+
/>
|
|
8
|
+
</svg>`;export{i as arrowBottomSvg};
|
package/packages/ui/dist/assets/{arrow-bottom-circle-hkf9bWhW.js → arrow-bottom-circle-BH2LebvP.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F as
|
|
1
|
+
import{F as C}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const i=C`<svg
|
|
2
2
|
fill="none"
|
|
3
3
|
viewBox="0 0 21 20"
|
|
4
4
|
>
|
|
@@ -8,4 +8,4 @@ import{F as o}from"./core-BMNH6XFj.js";import"./index-CPrhuDfP.js";import"./even
|
|
|
8
8
|
d="M10.5 2.42908C6.31875 2.42908 2.92859 5.81989 2.92859 10.0034C2.92859 14.1869 6.31875 17.5777 10.5 17.5777C14.6813 17.5777 18.0714 14.1869 18.0714 10.0034C18.0714 5.81989 14.6813 2.42908 10.5 2.42908ZM0.928589 10.0034C0.928589 4.71596 5.21355 0.429077 10.5 0.429077C15.7865 0.429077 20.0714 4.71596 20.0714 10.0034C20.0714 15.2908 15.7865 19.5777 10.5 19.5777C5.21355 19.5777 0.928589 15.2908 0.928589 10.0034ZM10.5 5.75003C11.0523 5.75003 11.5 6.19774 11.5 6.75003L11.5 10.8343L12.7929 9.54137C13.1834 9.15085 13.8166 9.15085 14.2071 9.54137C14.5976 9.9319 14.5976 10.5651 14.2071 10.9556L11.2071 13.9556C10.8166 14.3461 10.1834 14.3461 9.79291 13.9556L6.79291 10.9556C6.40239 10.5651 6.40239 9.9319 6.79291 9.54137C7.18343 9.15085 7.8166 9.15085 8.20712 9.54137L9.50002 10.8343L9.50002 6.75003C9.50002 6.19774 9.94773 5.75003 10.5 5.75003Z"
|
|
9
9
|
clip-rule="evenodd"
|
|
10
10
|
/></svg
|
|
11
|
-
>`;export{
|
|
11
|
+
>`;export{i as arrowBottomCircleSvg};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{F as o}from"./core-BLOM5s8O.js";import"./index-D8zwDy7d.js";import"./index.es-Hqwz_Ukd.js";import"./events-DQ172AOg.js";const t=o`<svg fill="none" viewBox="0 0 14 15">
|
|
2
|
+
<path
|
|
3
|
+
fill="currentColor"
|
|
4
|
+
fill-rule="evenodd"
|
|
5
|
+
d="M13 7.99a1 1 0 0 1-1 1H4.4l2.46 2.46a1 1 0 1 1-1.41 1.41L1.29 8.7a1 1 0 0 1 0-1.41L5.46 3.1a1 1 0 0 1 1.41 1.42L4.41 6.99H12a1 1 0 0 1 1 1Z"
|
|
6
|
+
clip-rule="evenodd"
|
|
7
|
+
/>
|
|
8
|
+
</svg>`;export{t as arrowLeftSvg};
|