@saviours/check 0.1.0
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 +53 -0
- package/dist/castCommand.d.ts +9 -0
- package/dist/castCommand.d.ts.map +1 -0
- package/dist/castCommand.js +16 -0
- package/dist/castCommand.js.map +1 -0
- package/dist/check.d.ts +10 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +18 -0
- package/dist/check.js.map +1 -0
- package/dist/ens.d.ts +7 -0
- package/dist/ens.d.ts.map +1 -0
- package/dist/ens.js +89 -0
- package/dist/ens.js.map +1 -0
- package/dist/gateway.d.ts +4 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +110 -0
- package/dist/gateway.js.map +1 -0
- package/dist/guard.d.ts +11 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +22 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +7 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +6 -0
- package/dist/react.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/examples/basic.ts +15 -0
- package/examples/viem-hook.ts +21 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# `@saviours/check`
|
|
2
|
+
|
|
3
|
+
Two-line counterparty check. Default path talks to Sepolia ENS only — **zero** `@saviours/core`, **$0**, no our server.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { check } from "@saviours/check";
|
|
7
|
+
|
|
8
|
+
const r = await check("0x935bfb495e33f74d2e9735df1da66ace442ede48");
|
|
9
|
+
if (r.decision === "BLOCK") throw new Error("counterparty is named TAINTED");
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Mode | Path | Cost | Our server? |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| `ens` (default) | PermissionedResolver.text | $0 | No |
|
|
15
|
+
| `shield` | `POST /api/shield/check` | $0 | Gateway |
|
|
16
|
+
| `full` | `POST /api/investigate` | ~USDC on miss | Gateway |
|
|
17
|
+
|
|
18
|
+
Also: `guard(address)`, `castCommand(address)`.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
### From git (works today)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add github:devhb1/Saviour#path:packages/check
|
|
26
|
+
# or
|
|
27
|
+
npm install github:devhb1/Saviour#path:packages/check
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`prepare` runs `tsc` on install so `dist/` is built (it is gitignored in the monorepo).
|
|
31
|
+
|
|
32
|
+
### From npm (after publish)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @saviours/check
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Requires the npm org `@saviours` and:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cd packages/check
|
|
42
|
+
npm login
|
|
43
|
+
npm publish --access public
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Smoke
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
node --input-type=module -e "
|
|
50
|
+
import { check } from '@saviours/check';
|
|
51
|
+
console.log(await check('0x935bfb495e33f74d2e9735df1da66ace442ede48'));
|
|
52
|
+
"
|
|
53
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verifiable one-liner — same path as Identity / live-agent (no our server).
|
|
3
|
+
*/
|
|
4
|
+
export declare function castCommand(address: string, opts?: {
|
|
5
|
+
resolver?: string;
|
|
6
|
+
parent?: string;
|
|
7
|
+
key?: string;
|
|
8
|
+
}): string;
|
|
9
|
+
//# sourceMappingURL=castCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"castCommand.d.ts","sourceRoot":"","sources":["../src/castCommand.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,MAAM,CAUR"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const DEFAULT_RESOLVER = "0xF479306621F718F7d76875f67506ceD33717751c";
|
|
2
|
+
/**
|
|
3
|
+
* Verifiable one-liner — same path as Identity / live-agent (no our server).
|
|
4
|
+
*/
|
|
5
|
+
export function castCommand(address, opts) {
|
|
6
|
+
const a = address.trim().toLowerCase();
|
|
7
|
+
if (!/^0x[a-f0-9]{40}$/.test(a)) {
|
|
8
|
+
throw new Error(`Invalid address: ${address}`);
|
|
9
|
+
}
|
|
10
|
+
const parent = opts?.parent ?? "saviours.eth";
|
|
11
|
+
const resolver = opts?.resolver ?? DEFAULT_RESOLVER;
|
|
12
|
+
const key = opts?.key ?? "saviours.status";
|
|
13
|
+
const ens = `${a}.${parent}`;
|
|
14
|
+
return `cast call ${resolver} "text(bytes32,string)(string)" $(cast namehash ${ens}) "${key}"`;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=castCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"castCommand.js","sourceRoot":"","sources":["../src/castCommand.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GACpB,4CAAqD,CAAC;AAExD;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,IAA2D;IAE3D,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,cAAc,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,gBAAgB,CAAC;IACpD,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,iBAAiB,CAAC;IAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;IAC7B,OAAO,aAAa,QAAQ,mDAAmD,GAAG,MAAM,GAAG,GAAG,CAAC;AACjG,CAAC"}
|
package/dist/check.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CheckOptions, CheckResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Counterparty check.
|
|
4
|
+
*
|
|
5
|
+
* - `ens` (default): Sepolia PermissionedResolver · $0 · no our server
|
|
6
|
+
* - `shield`: POST /api/shield/check · $0 · gateway
|
|
7
|
+
* - `full`: POST /api/investigate · ~$0.01 on miss · gateway
|
|
8
|
+
*/
|
|
9
|
+
export declare function check(address: string, opts?: CheckOptions): Promise<CheckResult>;
|
|
10
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;GAMG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CAKtB"}
|
package/dist/check.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { checkEns } from "./ens.js";
|
|
2
|
+
import { checkFull, checkShield } from "./gateway.js";
|
|
3
|
+
/**
|
|
4
|
+
* Counterparty check.
|
|
5
|
+
*
|
|
6
|
+
* - `ens` (default): Sepolia PermissionedResolver · $0 · no our server
|
|
7
|
+
* - `shield`: POST /api/shield/check · $0 · gateway
|
|
8
|
+
* - `full`: POST /api/investigate · ~$0.01 on miss · gateway
|
|
9
|
+
*/
|
|
10
|
+
export async function check(address, opts = {}) {
|
|
11
|
+
const mode = opts.mode ?? "ens";
|
|
12
|
+
if (mode === "shield")
|
|
13
|
+
return checkShield(address, opts);
|
|
14
|
+
if (mode === "full")
|
|
15
|
+
return checkFull(address, opts);
|
|
16
|
+
return checkEns(address, opts);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGtD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAe,EACf,OAAqB,EAAE;IAEvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;IAChC,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
package/dist/ens.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ENS-only check — imports nothing from @saviours/core.
|
|
3
|
+
* Mirror of consumers/live-agent/src/ensShield.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { CheckOptions, CheckResult } from "./types.js";
|
|
6
|
+
export declare function checkEns(address: string, opts?: CheckOptions): Promise<CheckResult>;
|
|
7
|
+
//# sourceMappingURL=ens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ens.d.ts","sourceRoot":"","sources":["../src/ens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAY,MAAM,YAAY,CAAC;AAkCtE,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CAyDtB"}
|
package/dist/ens.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ENS-only check — imports nothing from @saviours/core.
|
|
3
|
+
* Mirror of consumers/live-agent/src/ensShield.ts.
|
|
4
|
+
*/
|
|
5
|
+
import { createPublicClient, http } from "viem";
|
|
6
|
+
import { namehash } from "viem/ens";
|
|
7
|
+
import { sepolia } from "viem/chains";
|
|
8
|
+
const DEFAULT_RESOLVER = "0xF479306621F718F7d76875f67506ceD33717751c";
|
|
9
|
+
const textAbi = [
|
|
10
|
+
{
|
|
11
|
+
name: "text",
|
|
12
|
+
type: "function",
|
|
13
|
+
stateMutability: "view",
|
|
14
|
+
inputs: [
|
|
15
|
+
{ name: "node", type: "bytes32" },
|
|
16
|
+
{ name: "key", type: "string" },
|
|
17
|
+
],
|
|
18
|
+
outputs: [{ name: "", type: "string" }],
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
function requireAddress(address) {
|
|
22
|
+
const a = address.trim().toLowerCase();
|
|
23
|
+
if (!/^0x[a-f0-9]{40}$/.test(a)) {
|
|
24
|
+
throw new Error(`Invalid address: ${address}`);
|
|
25
|
+
}
|
|
26
|
+
return a;
|
|
27
|
+
}
|
|
28
|
+
function decisionFromStatus(status) {
|
|
29
|
+
const s = status.toUpperCase();
|
|
30
|
+
if (s === "TAINTED")
|
|
31
|
+
return "BLOCK";
|
|
32
|
+
if (s === "WATCH")
|
|
33
|
+
return "WARN";
|
|
34
|
+
if (s === "SAFE")
|
|
35
|
+
return "ALLOW";
|
|
36
|
+
return "ESCALATE";
|
|
37
|
+
}
|
|
38
|
+
export async function checkEns(address, opts = {}) {
|
|
39
|
+
const addr = requireAddress(address);
|
|
40
|
+
const parent = opts.parent ?? "saviours.eth";
|
|
41
|
+
const resolver = (opts.resolver ?? DEFAULT_RESOLVER);
|
|
42
|
+
const rpcUrl = opts.rpcUrl ??
|
|
43
|
+
process.env.SEPOLIA_RPC_URL ??
|
|
44
|
+
"https://ethereum-sepolia-rpc.publicnode.com";
|
|
45
|
+
const ensName = `${addr}.${parent}`;
|
|
46
|
+
const t0 = Date.now();
|
|
47
|
+
const client = createPublicClient({
|
|
48
|
+
chain: sepolia,
|
|
49
|
+
transport: http(rpcUrl),
|
|
50
|
+
});
|
|
51
|
+
const node = namehash(ensName);
|
|
52
|
+
const readText = (key) => client.readContract({
|
|
53
|
+
address: resolver,
|
|
54
|
+
abi: textAbi,
|
|
55
|
+
functionName: "text",
|
|
56
|
+
args: [node, key],
|
|
57
|
+
});
|
|
58
|
+
const status = (await readText("saviours.status")).trim();
|
|
59
|
+
if (!status) {
|
|
60
|
+
return {
|
|
61
|
+
decision: "ESCALATE",
|
|
62
|
+
status: "UNKNOWN",
|
|
63
|
+
ensName,
|
|
64
|
+
source: "none",
|
|
65
|
+
reason: "No saviours.status on ENS",
|
|
66
|
+
latencyMs: Date.now() - t0,
|
|
67
|
+
cost: { graph: 0, ai: 0, usd: 0 },
|
|
68
|
+
mode: "ens",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const [threat, evidenceHash, atomicTx] = await Promise.all([
|
|
72
|
+
readText("saviours.threat"),
|
|
73
|
+
readText("saviours.evidenceHash"),
|
|
74
|
+
readText("saviours.atomicTx"),
|
|
75
|
+
]);
|
|
76
|
+
return {
|
|
77
|
+
decision: decisionFromStatus(status),
|
|
78
|
+
status,
|
|
79
|
+
ensName,
|
|
80
|
+
source: "ens",
|
|
81
|
+
threat: threat || undefined,
|
|
82
|
+
evidenceHash: evidenceHash || undefined,
|
|
83
|
+
atomicTx: atomicTx || undefined,
|
|
84
|
+
latencyMs: Date.now() - t0,
|
|
85
|
+
cost: { graph: 0, ai: 0, usd: 0 },
|
|
86
|
+
mode: "ens",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=ens.js.map
|
package/dist/ens.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ens.js","sourceRoot":"","sources":["../src/ens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CheckOptions, CheckResult } from "./types.js";
|
|
2
|
+
export declare function checkShield(address: string, opts?: CheckOptions): Promise<CheckResult>;
|
|
3
|
+
export declare function checkFull(address: string, opts?: CheckOptions): Promise<CheckResult>;
|
|
4
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAY,MAAM,YAAY,CAAC;AAqBtE,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CA4DtB;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CA0DtB"}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const DEFAULT_BASE = "https://www.saviours.xyz";
|
|
2
|
+
function requireAddress(address) {
|
|
3
|
+
const a = address.trim().toLowerCase();
|
|
4
|
+
if (!/^0x[a-f0-9]{40}$/.test(a)) {
|
|
5
|
+
throw new Error(`Invalid address: ${address}`);
|
|
6
|
+
}
|
|
7
|
+
return a;
|
|
8
|
+
}
|
|
9
|
+
function baseUrl(opts) {
|
|
10
|
+
return (opts.baseUrl ??
|
|
11
|
+
process.env.SAVIOURS_BASE_URL ??
|
|
12
|
+
process.env.PUBLIC_APP_URL ??
|
|
13
|
+
DEFAULT_BASE).replace(/\/$/, "");
|
|
14
|
+
}
|
|
15
|
+
export async function checkShield(address, opts = {}) {
|
|
16
|
+
const addr = requireAddress(address);
|
|
17
|
+
const t0 = Date.now();
|
|
18
|
+
const res = await fetch(`${baseUrl(opts)}/api/shield/check`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: { "content-type": "application/json" },
|
|
21
|
+
body: JSON.stringify({
|
|
22
|
+
chainId: opts.chainId ?? 1,
|
|
23
|
+
address: addr,
|
|
24
|
+
registryNetwork: opts.registryNetwork ?? "sepolia",
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
const json = (await res.json());
|
|
28
|
+
if (!res.ok || !json.check?.decision) {
|
|
29
|
+
throw new Error(json.error || `shield/check HTTP ${res.status}`);
|
|
30
|
+
}
|
|
31
|
+
const sourceRaw = (json.check.source ?? "none").toLowerCase();
|
|
32
|
+
const source = sourceRaw === "ens" || sourceRaw === "registry"
|
|
33
|
+
? sourceRaw === "ens"
|
|
34
|
+
? "ens"
|
|
35
|
+
: "shield"
|
|
36
|
+
: "none";
|
|
37
|
+
return {
|
|
38
|
+
decision: json.check.decision,
|
|
39
|
+
status: json.check.decision === "BLOCK"
|
|
40
|
+
? "TAINTED"
|
|
41
|
+
: json.check.decision === "WARN"
|
|
42
|
+
? "WATCH"
|
|
43
|
+
: json.check.decision === "ALLOW"
|
|
44
|
+
? "SAFE"
|
|
45
|
+
: "UNKNOWN",
|
|
46
|
+
ensName: json.check.ensName ??
|
|
47
|
+
`${addr}.saviours.eth`,
|
|
48
|
+
source: source === "none" && json.check.decision === "ESCALATE" ? "none" : source === "ens" ? "ens" : "shield",
|
|
49
|
+
reason: json.check.reason,
|
|
50
|
+
latencyMs: typeof json.check.latencyMs === "number"
|
|
51
|
+
? json.check.latencyMs
|
|
52
|
+
: Date.now() - t0,
|
|
53
|
+
cost: {
|
|
54
|
+
graph: json.memoryHit?.graphQueries ?? 0,
|
|
55
|
+
ai: json.memoryHit?.aiCalls ?? 0,
|
|
56
|
+
usd: 0,
|
|
57
|
+
},
|
|
58
|
+
mode: "shield",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export async function checkFull(address, opts = {}) {
|
|
62
|
+
const addr = requireAddress(address);
|
|
63
|
+
const t0 = Date.now();
|
|
64
|
+
const res = await fetch(`${baseUrl(opts)}/api/investigate`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
headers: { "content-type": "application/json" },
|
|
67
|
+
body: JSON.stringify({
|
|
68
|
+
chainId: opts.chainId ?? 1,
|
|
69
|
+
address: addr,
|
|
70
|
+
persist: opts.persist ?? false,
|
|
71
|
+
forceFresh: opts.forceFresh ?? false,
|
|
72
|
+
registryNetwork: opts.registryNetwork ?? "sepolia",
|
|
73
|
+
}),
|
|
74
|
+
});
|
|
75
|
+
const json = (await res.json());
|
|
76
|
+
if (!res.ok) {
|
|
77
|
+
throw new Error(json.error || `investigate HTTP ${res.status}`);
|
|
78
|
+
}
|
|
79
|
+
const status = (json.assessment?.status ?? "UNKNOWN").toUpperCase();
|
|
80
|
+
let decision = "ESCALATE";
|
|
81
|
+
if (status === "TAINTED")
|
|
82
|
+
decision = "BLOCK";
|
|
83
|
+
else if (status === "WATCH")
|
|
84
|
+
decision = "WARN";
|
|
85
|
+
else if (status === "SAFE")
|
|
86
|
+
decision = "ALLOW";
|
|
87
|
+
else if (json.shield?.decision)
|
|
88
|
+
decision = json.shield.decision;
|
|
89
|
+
const graph = json.cost?.graphQueries ?? 0;
|
|
90
|
+
const ai = json.cost?.aiCalls ?? 0;
|
|
91
|
+
const hit = Boolean(json.memoryHit ?? json.cost?.memoryHit);
|
|
92
|
+
return {
|
|
93
|
+
decision,
|
|
94
|
+
status,
|
|
95
|
+
ensName: `${addr}.saviours.eth`,
|
|
96
|
+
source: hit ? "shield" : "investigate",
|
|
97
|
+
threat: json.assessment?.threatTypes?.join(" ∧ "),
|
|
98
|
+
latencyMs: json.cost?.latencyMs ?? Date.now() - t0,
|
|
99
|
+
cost: {
|
|
100
|
+
graph,
|
|
101
|
+
ai,
|
|
102
|
+
usd: hit ? 0 : 0.01,
|
|
103
|
+
},
|
|
104
|
+
mode: "full",
|
|
105
|
+
reason: hit
|
|
106
|
+
? "MEMORY HIT short-circuit"
|
|
107
|
+
: "Fresh investigation (Graph + AI cite + validator)",
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CheckOptions, CheckResult } from "./types.js";
|
|
2
|
+
export declare class SavioursBlockedError extends Error {
|
|
3
|
+
readonly result: CheckResult;
|
|
4
|
+
constructor(result: CheckResult);
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Drop-in for signer middleware: throws on BLOCK, returns result on WARN/ALLOW/ESCALATE.
|
|
8
|
+
* WARN is returned (not thrown) so callers can reduce size — never silent.
|
|
9
|
+
*/
|
|
10
|
+
export declare function guard(address: string, opts?: CheckOptions): Promise<CheckResult>;
|
|
11
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;gBACjB,MAAM,EAAE,WAAW;CAQhC;AAED;;;GAGG;AACH,wBAAsB,KAAK,CACzB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,WAAW,CAAC,CAMtB"}
|
package/dist/guard.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { check } from "./check.js";
|
|
2
|
+
export class SavioursBlockedError extends Error {
|
|
3
|
+
result;
|
|
4
|
+
constructor(result) {
|
|
5
|
+
super(`SAVIOURS BLOCK: ${result.ensName} status=${result.status}` +
|
|
6
|
+
(result.threat ? ` threat=${result.threat}` : ""));
|
|
7
|
+
this.name = "SavioursBlockedError";
|
|
8
|
+
this.result = result;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Drop-in for signer middleware: throws on BLOCK, returns result on WARN/ALLOW/ESCALATE.
|
|
13
|
+
* WARN is returned (not thrown) so callers can reduce size — never silent.
|
|
14
|
+
*/
|
|
15
|
+
export async function guard(address, opts = {}) {
|
|
16
|
+
const result = await check(address, opts);
|
|
17
|
+
if (result.decision === "BLOCK") {
|
|
18
|
+
throw new SavioursBlockedError(result);
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,MAAM,CAAc;IAC7B,YAAY,MAAmB;QAC7B,KAAK,CACH,mBAAmB,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC,MAAM,EAAE;YACzD,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACpD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,OAAe,EACf,OAAqB,EAAE;IAEvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { check } from "./check.js";
|
|
2
|
+
export { guard, SavioursBlockedError } from "./guard.js";
|
|
3
|
+
export { castCommand } from "./castCommand.js";
|
|
4
|
+
export { checkEns } from "./ens.js";
|
|
5
|
+
export { checkShield, checkFull } from "./gateway.js";
|
|
6
|
+
export type { CheckCost, CheckMode, CheckOptions, CheckResult, Decision, } from "./types.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EACV,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { check } from "./check.js";
|
|
2
|
+
export { guard, SavioursBlockedError } from "./guard.js";
|
|
3
|
+
export { castCommand } from "./castCommand.js";
|
|
4
|
+
export { checkEns } from "./ens.js";
|
|
5
|
+
export { checkShield, checkFull } from "./gateway.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional React entry — peer-free types; apps re-export a fetch-based hook.
|
|
3
|
+
* Node agents should use `check()` / `guard()` from the main entry (viem ENS).
|
|
4
|
+
*/
|
|
5
|
+
export { check, guard, castCommand } from "./index.js";
|
|
6
|
+
export type { CheckResult, CheckOptions, Decision } from "./types.js";
|
|
7
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/react.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type Decision = "BLOCK" | "WARN" | "ALLOW" | "ESCALATE";
|
|
2
|
+
export type CheckMode = "ens" | "shield" | "full";
|
|
3
|
+
export type CheckCost = {
|
|
4
|
+
graph: number;
|
|
5
|
+
ai: number;
|
|
6
|
+
usd: number;
|
|
7
|
+
};
|
|
8
|
+
export type CheckResult = {
|
|
9
|
+
decision: Decision;
|
|
10
|
+
status: string;
|
|
11
|
+
ensName: string;
|
|
12
|
+
source: "ens" | "shield" | "investigate" | "none";
|
|
13
|
+
threat?: string;
|
|
14
|
+
evidenceHash?: string;
|
|
15
|
+
atomicTx?: string;
|
|
16
|
+
reason?: string;
|
|
17
|
+
latencyMs: number;
|
|
18
|
+
cost: CheckCost;
|
|
19
|
+
mode: CheckMode;
|
|
20
|
+
};
|
|
21
|
+
export type CheckOptions = {
|
|
22
|
+
/** ens (default) | shield | full */
|
|
23
|
+
mode?: CheckMode;
|
|
24
|
+
/** Sepolia RPC for mode=ens. Defaults to publicnode. */
|
|
25
|
+
rpcUrl?: string;
|
|
26
|
+
/** PermissionedResolver proxy. */
|
|
27
|
+
resolver?: `0x${string}`;
|
|
28
|
+
/** Parent name, default saviours.eth */
|
|
29
|
+
parent?: string;
|
|
30
|
+
/** Gateway / app origin for shield + full. */
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
chainId?: number;
|
|
33
|
+
registryNetwork?: "sepolia" | "anvil";
|
|
34
|
+
/** full mode only — force Graph path */
|
|
35
|
+
forceFresh?: boolean;
|
|
36
|
+
/** full mode only — attempt Remember (usually false on public) */
|
|
37
|
+
persist?: boolean;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE/D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,oCAAoC;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IACtC,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { check, castCommand, guard } from "@saviours/check";
|
|
2
|
+
|
|
3
|
+
const ATTACK_1 = "0x935bfb495e33f74d2e9735df1da66ace442ede48";
|
|
4
|
+
|
|
5
|
+
const r = await check(ATTACK_1);
|
|
6
|
+
console.log(r);
|
|
7
|
+
// { decision: "BLOCK", status: "TAINTED", source: "ens", cost: { graph: 0, ai: 0, usd: 0 }, … }
|
|
8
|
+
|
|
9
|
+
console.log(castCommand(ATTACK_1));
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await guard(ATTACK_1);
|
|
13
|
+
} catch (e) {
|
|
14
|
+
console.error(String(e));
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example — wrap a viem wallet client sendTransaction with guard().
|
|
3
|
+
* Not shipped as a dependency; copy into your agent.
|
|
4
|
+
*/
|
|
5
|
+
import { guard, SavioursBlockedError } from "@saviours/check";
|
|
6
|
+
|
|
7
|
+
export async function sendWithSavioursGuard(
|
|
8
|
+
to: `0x${string}`,
|
|
9
|
+
send: () => Promise<`0x${string}`>,
|
|
10
|
+
): Promise<`0x${string}`> {
|
|
11
|
+
const r = await guard(to, { mode: "ens" });
|
|
12
|
+
if (r.decision === "WARN") {
|
|
13
|
+
console.warn(`[saviours] WARN ${r.ensName} — reduce size`);
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
return await send();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
if (e instanceof SavioursBlockedError) throw e;
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@saviours/check",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Two-line counterparty check — ENS first, optional Shield/investigate gateway",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "SAVIOURS",
|
|
8
|
+
"homepage": "https://www.saviours.xyz",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/devhb1/Saviour.git",
|
|
12
|
+
"directory": "packages/check"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/devhb1/Saviour/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"ethereum",
|
|
19
|
+
"ens",
|
|
20
|
+
"security",
|
|
21
|
+
"wallet",
|
|
22
|
+
"agent",
|
|
23
|
+
"saviours"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./react": {
|
|
34
|
+
"types": "./dist/react.d.ts",
|
|
35
|
+
"import": "./dist/react.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"examples",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.json",
|
|
45
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
46
|
+
"prepare": "tsc -p tsconfig.json",
|
|
47
|
+
"prepublishOnly": "tsc -p tsconfig.json"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"react": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"react": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"viem": "^2.56.3"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"typescript": "^5.7.2"
|
|
62
|
+
},
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=20"
|
|
65
|
+
}
|
|
66
|
+
}
|