@hexora/core 1.0.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/dist/cache.d.ts +11 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +31 -0
- package/dist/cache.js.map +1 -0
- package/dist/history/fetcher.d.ts +12 -0
- package/dist/history/fetcher.d.ts.map +1 -0
- package/dist/history/fetcher.js +156 -0
- package/dist/history/fetcher.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/detector.d.ts +3 -0
- package/dist/providers/detector.d.ts.map +1 -0
- package/dist/providers/detector.js +79 -0
- package/dist/providers/detector.js.map +1 -0
- package/dist/similarity.d.ts +10 -0
- package/dist/similarity.d.ts.map +1 -0
- package/dist/similarity.js +88 -0
- package/dist/similarity.js.map +1 -0
- package/dist/types/index.d.ts +58 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/validator.d.ts +3 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +24 -0
- package/dist/validator.js.map +1 -0
- package/package.json +28 -0
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NormalizedTransaction, ChainId } from "./types/index.js";
|
|
2
|
+
declare class TransactionCache {
|
|
3
|
+
private store;
|
|
4
|
+
private key;
|
|
5
|
+
get(address: string, chain: ChainId): NormalizedTransaction[] | null;
|
|
6
|
+
set(address: string, chain: ChainId, txs: NormalizedTransaction[]): void;
|
|
7
|
+
clear(): void;
|
|
8
|
+
}
|
|
9
|
+
export declare const txCache: TransactionCache;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAUlE,cAAM,gBAAgB;IACpB,OAAO,CAAC,KAAK,CAAiC;IAE9C,OAAO,CAAC,GAAG;IAIX,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,qBAAqB,EAAE,GAAG,IAAI;IAUpE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAOxE,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,OAAO,kBAAyB,CAAC"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// In-memory session cache. Privacy-first — no persistence, clears on page unload.
|
|
2
|
+
const CACHE_TTL_MS = 5 * 60 * 1000;
|
|
3
|
+
class TransactionCache {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.store = new Map();
|
|
6
|
+
}
|
|
7
|
+
key(address, chain) {
|
|
8
|
+
return `${chain}:${address.toLowerCase()}`;
|
|
9
|
+
}
|
|
10
|
+
get(address, chain) {
|
|
11
|
+
const entry = this.store.get(this.key(address, chain));
|
|
12
|
+
if (!entry)
|
|
13
|
+
return null;
|
|
14
|
+
if (Date.now() - entry.fetchedAt > CACHE_TTL_MS) {
|
|
15
|
+
this.store.delete(this.key(address, chain));
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return entry.transactions;
|
|
19
|
+
}
|
|
20
|
+
set(address, chain, txs) {
|
|
21
|
+
this.store.set(this.key(address, chain), {
|
|
22
|
+
transactions: txs,
|
|
23
|
+
fetchedAt: Date.now(),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
clear() {
|
|
27
|
+
this.store.clear();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const txCache = new TransactionCache();
|
|
31
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAOnC,MAAM,gBAAgB;IAAtB;QACU,UAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IA0BhD,CAAC;IAxBS,GAAG,CAAC,OAAe,EAAE,KAAc;QACzC,OAAO,GAAG,KAAK,IAAI,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;IAC7C,CAAC;IAED,GAAG,CAAC,OAAe,EAAE,KAAc;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;YAChD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,YAAY,CAAC;IAC5B,CAAC;IAED,GAAG,CAAC,OAAe,EAAE,KAAc,EAAE,GAA4B;QAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YACvC,YAAY,EAAE,GAAG;YACjB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChainId, NormalizedTransaction, HistoryProvider } from "../types/index.js";
|
|
2
|
+
type ApiKeys = Record<string, string | undefined>;
|
|
3
|
+
export declare class DefaultHistoryProvider implements HistoryProvider {
|
|
4
|
+
private readonly apiKeys;
|
|
5
|
+
constructor(apiKeys?: ApiKeys);
|
|
6
|
+
getTransactions(address: string, chain: ChainId, limit: number): Promise<NormalizedTransaction[]>;
|
|
7
|
+
private getApiKey;
|
|
8
|
+
private fetchNormal;
|
|
9
|
+
private fetchToken;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/history/fetcher.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,qBAAqB,EACrB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAe3B,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAuBlD,qBAAa,sBAAuB,YAAW,eAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,OAAY;IAE5C,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAyBnC,OAAO,CAAC,SAAS;YASH,WAAW;YAyBX,UAAU;CAwBzB"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
const EXPLORER_CONFIG = {
|
|
2
|
+
ethereum: { baseUrl: "https://api.etherscan.io/api" },
|
|
3
|
+
bnb: { baseUrl: "https://api.bscscan.com/api" },
|
|
4
|
+
polygon: { baseUrl: "https://api.polygonscan.com/api" },
|
|
5
|
+
avalanche: { baseUrl: "https://api.snowtrace.io/api" },
|
|
6
|
+
arbitrum: { baseUrl: "https://api.arbiscan.io/api" },
|
|
7
|
+
optimism: { baseUrl: "https://api-optimistic.etherscan.io/api" },
|
|
8
|
+
};
|
|
9
|
+
// Works without API key (rate limited). Pass apiKeys for higher limits.
|
|
10
|
+
export class DefaultHistoryProvider {
|
|
11
|
+
constructor(apiKeys = {}) {
|
|
12
|
+
this.apiKeys = apiKeys;
|
|
13
|
+
}
|
|
14
|
+
async getTransactions(address, chain, limit) {
|
|
15
|
+
const config = EXPLORER_CONFIG[chain];
|
|
16
|
+
if (!config)
|
|
17
|
+
return [];
|
|
18
|
+
const key = this.getApiKey(chain);
|
|
19
|
+
const [normal, token] = await Promise.allSettled([
|
|
20
|
+
this.fetchNormal(config.baseUrl, address, limit, key),
|
|
21
|
+
this.fetchToken(config.baseUrl, address, limit, key),
|
|
22
|
+
]);
|
|
23
|
+
const results = [];
|
|
24
|
+
if (normal.status === "fulfilled")
|
|
25
|
+
results.push(...normal.value);
|
|
26
|
+
if (token.status === "fulfilled")
|
|
27
|
+
results.push(...token.value);
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
return results
|
|
30
|
+
.filter((tx) => {
|
|
31
|
+
if (seen.has(tx.hash))
|
|
32
|
+
return false;
|
|
33
|
+
seen.add(tx.hash);
|
|
34
|
+
return true;
|
|
35
|
+
})
|
|
36
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
37
|
+
.slice(0, limit);
|
|
38
|
+
}
|
|
39
|
+
getApiKey(chain) {
|
|
40
|
+
const map = {
|
|
41
|
+
ethereum: this.apiKeys["etherscan"],
|
|
42
|
+
bnb: this.apiKeys["bscscan"],
|
|
43
|
+
polygon: this.apiKeys["polygonscan"],
|
|
44
|
+
};
|
|
45
|
+
return map[chain] ?? "";
|
|
46
|
+
}
|
|
47
|
+
async fetchNormal(base, address, limit, key) {
|
|
48
|
+
const data = await fetchWithRetry(buildUrl(base, {
|
|
49
|
+
module: "account",
|
|
50
|
+
action: "txlist",
|
|
51
|
+
address,
|
|
52
|
+
startblock: "0",
|
|
53
|
+
endblock: "99999999",
|
|
54
|
+
page: "1",
|
|
55
|
+
offset: String(limit),
|
|
56
|
+
sort: "desc",
|
|
57
|
+
apikey: key,
|
|
58
|
+
}));
|
|
59
|
+
if (!data?.result || !Array.isArray(data.result))
|
|
60
|
+
return [];
|
|
61
|
+
return data.result.map((tx) => normalizeEVMTx(tx, address));
|
|
62
|
+
}
|
|
63
|
+
async fetchToken(base, address, limit, key) {
|
|
64
|
+
const data = await fetchWithRetry(buildUrl(base, {
|
|
65
|
+
module: "account",
|
|
66
|
+
action: "tokentx",
|
|
67
|
+
address,
|
|
68
|
+
startblock: "0",
|
|
69
|
+
endblock: "99999999",
|
|
70
|
+
page: "1",
|
|
71
|
+
offset: String(limit),
|
|
72
|
+
sort: "desc",
|
|
73
|
+
apikey: key,
|
|
74
|
+
}));
|
|
75
|
+
if (!data?.result || !Array.isArray(data.result))
|
|
76
|
+
return [];
|
|
77
|
+
return data.result.map((tx) => normalizeEVMTokenTx(tx, address));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 0xe19c2253 — batch transfer(address[],address[],address[],uint256[])
|
|
81
|
+
// Real attack tx: 0x05c6e673787275bdff029723492a07f4d9aad9b0e4fbfb7ff95bfb12e641bd48
|
|
82
|
+
const BATCH_POISON_IDS = new Set(["0xe19c2253"]);
|
|
83
|
+
function normalizeEVMTx(tx, userAddress) {
|
|
84
|
+
const value = BigInt(tx.value || "0");
|
|
85
|
+
const methodId = tx.input?.slice(0, 10) ?? "0x";
|
|
86
|
+
return {
|
|
87
|
+
hash: tx.hash,
|
|
88
|
+
from: tx.from.toLowerCase(),
|
|
89
|
+
to: (tx.to || "").toLowerCase(),
|
|
90
|
+
value,
|
|
91
|
+
timestamp: Number(tx.timeStamp),
|
|
92
|
+
blockNumber: Number(tx.blockNumber),
|
|
93
|
+
isIncoming: tx.to?.toLowerCase() === userAddress.toLowerCase(),
|
|
94
|
+
contractAddress: tx.contractAddress || undefined,
|
|
95
|
+
methodId: methodId || undefined,
|
|
96
|
+
isZeroValue: value === 0n,
|
|
97
|
+
isBatchPoison: value === 0n && BATCH_POISON_IDS.has(methodId),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function normalizeEVMTokenTx(tx, userAddress) {
|
|
101
|
+
const tokenValue = BigInt(tx.value || "0");
|
|
102
|
+
return {
|
|
103
|
+
hash: tx.hash,
|
|
104
|
+
from: tx.from.toLowerCase(),
|
|
105
|
+
to: tx.to.toLowerCase(),
|
|
106
|
+
value: 0n,
|
|
107
|
+
tokenValue,
|
|
108
|
+
timestamp: Number(tx.timeStamp),
|
|
109
|
+
blockNumber: Number(tx.blockNumber),
|
|
110
|
+
isIncoming: tx.to.toLowerCase() === userAddress.toLowerCase(),
|
|
111
|
+
contractAddress: tx.contractAddress,
|
|
112
|
+
isZeroValue: tokenValue === 0n,
|
|
113
|
+
isBatchPoison: tokenValue === 0n,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function buildUrl(base, params) {
|
|
117
|
+
return (base +
|
|
118
|
+
"?" +
|
|
119
|
+
Object.entries(params)
|
|
120
|
+
.filter(([, v]) => v !== "")
|
|
121
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
122
|
+
.join("&"));
|
|
123
|
+
}
|
|
124
|
+
async function fetchWithRetry(url, retries = 2, delay = 1000) {
|
|
125
|
+
for (let i = 0; i <= retries; i++) {
|
|
126
|
+
try {
|
|
127
|
+
const res = await fetch(url, {
|
|
128
|
+
headers: { Accept: "application/json" },
|
|
129
|
+
signal: AbortSignal.timeout(8000),
|
|
130
|
+
});
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
if (res.status === 429 && i < retries) {
|
|
133
|
+
await sleep(delay * (i + 1));
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const json = await res.json();
|
|
139
|
+
if (json?.status === "0" && json?.message !== "No transactions found")
|
|
140
|
+
return null;
|
|
141
|
+
return json;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
if (i < retries) {
|
|
145
|
+
await sleep(delay);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
function sleep(ms) {
|
|
154
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/history/fetcher.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { ChainId, RiskLevel, ScamReason, ErrorCode, NormalizedTransaction, CheckError, EIP1193Provider, PhantomProvider, RawProvider, HexoraProvider, ProviderType, HistoryProvider, } from "./types/index.js";
|
|
2
|
+
export { EVM_CHAIN_MAP } from "./types/index.js";
|
|
3
|
+
export { detectProvider } from "./providers/detector.js";
|
|
4
|
+
export { txCache } from "./cache.js";
|
|
5
|
+
export { validateAddress } from "./validator.js";
|
|
6
|
+
export { calculateSimilarity, findMostSimilar } from "./similarity.js";
|
|
7
|
+
export { DefaultHistoryProvider } from "./history/fetcher.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,OAAO,EACP,SAAS,EACT,UAAU,EACV,SAAS,EACT,qBAAqB,EACrB,UAAU,EACV,eAAe,EACf,eAAe,EACf,WAAW,EACX,cAAc,EACd,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { EVM_CHAIN_MAP } from "./types/index.js";
|
|
2
|
+
export { detectProvider } from "./providers/detector.js";
|
|
3
|
+
export { txCache } from "./cache.js";
|
|
4
|
+
export { validateAddress } from "./validator.js";
|
|
5
|
+
export { calculateSimilarity, findMostSimilar } from "./similarity.js";
|
|
6
|
+
export { DefaultHistoryProvider } from "./history/fetcher.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/providers/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGX,cAAc,EAKf,MAAM,mBAAmB,CAAC;AA6E3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc,CAO/D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { EVM_CHAIN_MAP, } from "../types/index.js";
|
|
2
|
+
function isEIP1193(p) {
|
|
3
|
+
return (typeof p === "object" &&
|
|
4
|
+
p !== null &&
|
|
5
|
+
"request" in p &&
|
|
6
|
+
typeof p.request === "function");
|
|
7
|
+
}
|
|
8
|
+
function isPhantom(p) {
|
|
9
|
+
return (typeof p === "object" &&
|
|
10
|
+
p !== null &&
|
|
11
|
+
("isPhantom" in p || "publicKey" in p));
|
|
12
|
+
}
|
|
13
|
+
class EVMAdapter {
|
|
14
|
+
constructor(provider) {
|
|
15
|
+
this.provider = provider;
|
|
16
|
+
}
|
|
17
|
+
isEVM() {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
getProviderType() {
|
|
21
|
+
return "eip1193";
|
|
22
|
+
}
|
|
23
|
+
async rawChainId() {
|
|
24
|
+
try {
|
|
25
|
+
const id = await this.provider.request({ method: "eth_chainId" });
|
|
26
|
+
return String(id);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
try {
|
|
30
|
+
const v = await this.provider.request({ method: "net_version" });
|
|
31
|
+
return "0x" + Number(v).toString(16);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw buildError("network_unavailable", "Failed to get chainId from provider");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async chainId() {
|
|
39
|
+
const raw = await this.rawChainId();
|
|
40
|
+
const hex = raw.startsWith("0x") ? raw : "0x" + Number(raw).toString(16);
|
|
41
|
+
const chain = EVM_CHAIN_MAP[hex];
|
|
42
|
+
if (!chain)
|
|
43
|
+
throw buildError("unsupported_chain", `Chain ${raw} is not supported yet`);
|
|
44
|
+
return chain;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
class SolanaAdapter {
|
|
48
|
+
constructor(_provider) {
|
|
49
|
+
this._provider = _provider;
|
|
50
|
+
}
|
|
51
|
+
isEVM() {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
getProviderType() {
|
|
55
|
+
return "phantom";
|
|
56
|
+
}
|
|
57
|
+
async rawChainId() {
|
|
58
|
+
return "solana-mainnet";
|
|
59
|
+
}
|
|
60
|
+
async chainId() {
|
|
61
|
+
return "solana";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Auto-detects provider type and wraps into unified HexoraProvider.
|
|
65
|
+
// Supports all EIP-1193 wallets + Phantom.
|
|
66
|
+
// New chains (Bitcoin, Tron) — add adapter here, nothing else changes.
|
|
67
|
+
export function detectProvider(raw) {
|
|
68
|
+
if (isEIP1193(raw))
|
|
69
|
+
return new EVMAdapter(raw);
|
|
70
|
+
if (isPhantom(raw))
|
|
71
|
+
return new SolanaAdapter(raw);
|
|
72
|
+
throw buildError("unknown_provider", "Unknown provider. Must implement EIP-1193 or be Phantom-compatible.");
|
|
73
|
+
}
|
|
74
|
+
function buildError(code, message) {
|
|
75
|
+
const err = new Error(message);
|
|
76
|
+
err.hexoraCode = code;
|
|
77
|
+
return err;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/providers/detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function normalizeAddress(address: string): string;
|
|
2
|
+
export declare function calculateSimilarity(a: string, b: string): number;
|
|
3
|
+
export interface SimilarityMatch {
|
|
4
|
+
address: string;
|
|
5
|
+
similarityScore: number;
|
|
6
|
+
prefixMatch: boolean;
|
|
7
|
+
suffixMatch: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function findMostSimilar(input: string, known: string[], threshold?: number): SimilarityMatch | null;
|
|
10
|
+
//# sourceMappingURL=similarity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.d.ts","sourceRoot":"","sources":["../src/similarity.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAWhE;AAoDD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,GAAE,MAAW,GACrB,eAAe,GAAG,IAAI,CAqBxB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Weighted similarity: prefix 40% + suffix 40% + levenshtein 20%
|
|
2
|
+
// Mirrors attacker strategy: same first/last chars, different middle.
|
|
3
|
+
export function normalizeAddress(address) {
|
|
4
|
+
return address.toLowerCase();
|
|
5
|
+
}
|
|
6
|
+
export function calculateSimilarity(a, b) {
|
|
7
|
+
const na = normalizeAddress(a);
|
|
8
|
+
const nb = normalizeAddress(b);
|
|
9
|
+
if (na === nb)
|
|
10
|
+
return 100;
|
|
11
|
+
const bodyA = na.startsWith("0x") ? na.slice(2) : na;
|
|
12
|
+
const bodyB = nb.startsWith("0x") ? nb.slice(2) : nb;
|
|
13
|
+
return Math.round(prefixSimilarity(bodyA, bodyB, 6) * 0.4 +
|
|
14
|
+
suffixSimilarity(bodyA, bodyB, 6) * 0.4 +
|
|
15
|
+
levenshteinSimilarity(bodyA, bodyB) * 0.2);
|
|
16
|
+
}
|
|
17
|
+
function prefixSimilarity(a, b, len) {
|
|
18
|
+
const pa = a.slice(0, len);
|
|
19
|
+
const pb = b.slice(0, len);
|
|
20
|
+
let m = 0;
|
|
21
|
+
for (let i = 0; i < Math.min(pa.length, pb.length); i++) {
|
|
22
|
+
const ca = pa[i];
|
|
23
|
+
const cb = pb[i];
|
|
24
|
+
if (ca !== undefined && cb !== undefined && ca === cb)
|
|
25
|
+
m++;
|
|
26
|
+
}
|
|
27
|
+
return (m / len) * 100;
|
|
28
|
+
}
|
|
29
|
+
function suffixSimilarity(a, b, len) {
|
|
30
|
+
const sa = a.slice(-len);
|
|
31
|
+
const sb = b.slice(-len);
|
|
32
|
+
let m = 0;
|
|
33
|
+
for (let i = 0; i < Math.min(sa.length, sb.length); i++) {
|
|
34
|
+
const ca = sa[i];
|
|
35
|
+
const cb = sb[i];
|
|
36
|
+
if (ca !== undefined && cb !== undefined && ca === cb)
|
|
37
|
+
m++;
|
|
38
|
+
}
|
|
39
|
+
return (m / len) * 100;
|
|
40
|
+
}
|
|
41
|
+
function levenshteinSimilarity(a, b) {
|
|
42
|
+
const maxLen = Math.max(a.length, b.length);
|
|
43
|
+
if (maxLen === 0)
|
|
44
|
+
return 100;
|
|
45
|
+
return Math.round((1 - levenshteinDistance(a, b) / maxLen) * 100);
|
|
46
|
+
}
|
|
47
|
+
function levenshteinDistance(a, b) {
|
|
48
|
+
const n = b.length;
|
|
49
|
+
const dp = Array.from({ length: n + 1 }, (_, i) => i);
|
|
50
|
+
for (let i = 1; i <= a.length; i++) {
|
|
51
|
+
let prev = dp[0] ?? 0;
|
|
52
|
+
dp[0] = i;
|
|
53
|
+
for (let j = 1; j <= n; j++) {
|
|
54
|
+
const temp = dp[j] ?? 0;
|
|
55
|
+
const ai = a[i - 1];
|
|
56
|
+
const bj = b[j - 1];
|
|
57
|
+
dp[j] =
|
|
58
|
+
ai !== undefined && bj !== undefined && ai === bj
|
|
59
|
+
? prev
|
|
60
|
+
: 1 + Math.min(prev, dp[j] ?? 0, dp[j - 1] ?? 0);
|
|
61
|
+
prev = temp;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return dp[n] ?? 0;
|
|
65
|
+
}
|
|
66
|
+
export function findMostSimilar(input, known, threshold = 85) {
|
|
67
|
+
const ni = normalizeAddress(input);
|
|
68
|
+
let best = null;
|
|
69
|
+
for (const addr of known) {
|
|
70
|
+
if (normalizeAddress(addr) === ni)
|
|
71
|
+
continue;
|
|
72
|
+
const score = calculateSimilarity(input, addr);
|
|
73
|
+
if (score >= threshold && (!best || score > best.similarityScore)) {
|
|
74
|
+
const bi = ni.startsWith("0x") ? ni.slice(2) : ni;
|
|
75
|
+
const ba = normalizeAddress(addr).startsWith("0x")
|
|
76
|
+
? normalizeAddress(addr).slice(2)
|
|
77
|
+
: normalizeAddress(addr);
|
|
78
|
+
best = {
|
|
79
|
+
address: addr,
|
|
80
|
+
similarityScore: score,
|
|
81
|
+
prefixMatch: bi.slice(0, 4) === ba.slice(0, 4),
|
|
82
|
+
suffixMatch: bi.slice(-4) === ba.slice(-4),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return best;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=similarity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"similarity.js","sourceRoot":"","sources":["../src/similarity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type ChainId = "ethereum" | "bnb" | "polygon" | "avalanche" | "arbitrum" | "optimism" | "solana" | "bitcoin" | "tron";
|
|
2
|
+
export declare const EVM_CHAIN_MAP: Record<string, ChainId>;
|
|
3
|
+
export type RiskLevel = "none" | "low" | "medium" | "high" | "critical";
|
|
4
|
+
export type ScamReason = "address_poisoning" | "zero_value_transfer" | "batch_poisoning" | "transferfrom_spoofing" | "dust_attack" | "new_suspicious_address" | "known_phishing" | "malicious_domain" | "phishing_domain" | "typosquat_domain";
|
|
5
|
+
export interface NormalizedTransaction {
|
|
6
|
+
hash: string;
|
|
7
|
+
from: string;
|
|
8
|
+
to: string;
|
|
9
|
+
value: bigint;
|
|
10
|
+
tokenValue?: bigint;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
blockNumber: number;
|
|
13
|
+
isIncoming: boolean;
|
|
14
|
+
contractAddress?: string | undefined;
|
|
15
|
+
methodId?: string | undefined;
|
|
16
|
+
isZeroValue: boolean;
|
|
17
|
+
isBatchPoison: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface CheckError {
|
|
20
|
+
code: ErrorCode;
|
|
21
|
+
message: string;
|
|
22
|
+
}
|
|
23
|
+
export type ErrorCode = "network_unavailable" | "history_fetch_failed" | "unsupported_chain" | "invalid_address" | "unknown_provider" | "rate_limited" | "unknown";
|
|
24
|
+
export interface EIP1193Provider {
|
|
25
|
+
request(args: {
|
|
26
|
+
method: string;
|
|
27
|
+
params?: unknown[];
|
|
28
|
+
}): Promise<unknown>;
|
|
29
|
+
on?(event: string, handler: (...args: unknown[]) => void): void;
|
|
30
|
+
removeListener?(event: string, handler: (...args: unknown[]) => void): void;
|
|
31
|
+
}
|
|
32
|
+
export interface PhantomProvider {
|
|
33
|
+
isPhantom: boolean;
|
|
34
|
+
publicKey?: {
|
|
35
|
+
toString(): string;
|
|
36
|
+
};
|
|
37
|
+
connect(): Promise<{
|
|
38
|
+
publicKey: {
|
|
39
|
+
toString(): string;
|
|
40
|
+
};
|
|
41
|
+
}>;
|
|
42
|
+
request?(args: {
|
|
43
|
+
method: string;
|
|
44
|
+
params?: unknown;
|
|
45
|
+
}): Promise<unknown>;
|
|
46
|
+
}
|
|
47
|
+
export type RawProvider = EIP1193Provider | PhantomProvider | Record<string, unknown>;
|
|
48
|
+
export interface HexoraProvider {
|
|
49
|
+
chainId(): Promise<ChainId>;
|
|
50
|
+
rawChainId(): Promise<string>;
|
|
51
|
+
isEVM(): boolean;
|
|
52
|
+
getProviderType(): ProviderType;
|
|
53
|
+
}
|
|
54
|
+
export type ProviderType = "eip1193" | "phantom" | "unknown";
|
|
55
|
+
export interface HistoryProvider {
|
|
56
|
+
getTransactions(address: string, chain: ChainId, limit: number): Promise<NormalizedTransaction[]>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAYA,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAA4B;IACpD,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,SAAS;IACjB,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,UAAU;CAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAW3C,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAYxE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const EVM_CHAINS = new Set([
|
|
2
|
+
"ethereum",
|
|
3
|
+
"bnb",
|
|
4
|
+
"polygon",
|
|
5
|
+
"avalanche",
|
|
6
|
+
"arbitrum",
|
|
7
|
+
"optimism",
|
|
8
|
+
]);
|
|
9
|
+
export function validateAddress(address, chain) {
|
|
10
|
+
if (!address || typeof address !== "string")
|
|
11
|
+
return false;
|
|
12
|
+
if (EVM_CHAINS.has(chain))
|
|
13
|
+
return /^0x[0-9a-fA-F]{40}$/.test(address);
|
|
14
|
+
if (chain === "solana")
|
|
15
|
+
return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
|
|
16
|
+
if (chain === "bitcoin")
|
|
17
|
+
return (/^1[a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address) ||
|
|
18
|
+
/^3[a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address) ||
|
|
19
|
+
/^bc1[a-z0-9]{6,87}$/.test(address));
|
|
20
|
+
if (chain === "tron")
|
|
21
|
+
return /^T[a-km-zA-HJ-NP-Z1-9]{33}$/.test(address);
|
|
22
|
+
return address.length > 0;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAU;IAClC,UAAU;IACV,KAAK;IACL,SAAS;IACT,WAAW;IACX,UAAU;IACV,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,KAAc;IAC7D,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,+BAA+B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7E,IAAI,KAAK,KAAK,SAAS;QACrB,OAAO,CACL,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9C,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9C,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CACpC,CAAC;IACJ,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzE,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hexora/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.5.4"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"lint": "eslint src",
|
|
26
|
+
"dev": "tsc --watch"
|
|
27
|
+
}
|
|
28
|
+
}
|