solvoid 1.1.7 → 1.3.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/LICENSE +21 -0
- package/README.md +110 -90
- package/SECURITY.md +42 -0
- package/bin/solvoid-scan +2 -0
- package/dist/cli/commands/ghost.d.ts +11 -0
- package/dist/cli/commands/ghost.d.ts.map +1 -0
- package/dist/cli/commands/ghost.js +161 -0
- package/dist/cli/commands/ghost.js.map +1 -0
- package/dist/cli/commands/rescue.d.ts +7 -0
- package/dist/cli/commands/rescue.d.ts.map +1 -0
- package/dist/cli/commands/rescue.js +203 -0
- package/dist/cli/commands/rescue.js.map +1 -0
- package/dist/cli/comprehensive-rpc-list.d.ts +31 -0
- package/dist/cli/comprehensive-rpc-list.d.ts.map +1 -0
- package/dist/cli/comprehensive-rpc-list.js +341 -0
- package/dist/cli/comprehensive-rpc-list.js.map +1 -0
- package/dist/cli/demo-scan.d.ts +6 -0
- package/dist/cli/demo-scan.d.ts.map +1 -0
- package/dist/cli/demo-scan.js +178 -0
- package/dist/cli/demo-scan.js.map +1 -0
- package/dist/cli/enhanced-privacy-scan.d.ts +46 -0
- package/dist/cli/enhanced-privacy-scan.d.ts.map +1 -0
- package/dist/cli/enhanced-privacy-scan.js +422 -0
- package/dist/cli/enhanced-privacy-scan.js.map +1 -0
- package/dist/cli/ghost-test.d.ts +7 -0
- package/dist/cli/ghost-test.d.ts.map +1 -0
- package/dist/cli/ghost-test.js +192 -0
- package/dist/cli/ghost-test.js.map +1 -0
- package/dist/cli/simple-scan.d.ts +6 -0
- package/dist/cli/simple-scan.d.ts.map +1 -0
- package/dist/cli/simple-scan.js +250 -0
- package/dist/cli/simple-scan.js.map +1 -0
- package/dist/cli/solvoid-scan.d.ts +7 -0
- package/dist/cli/solvoid-scan.d.ts.map +1 -0
- package/dist/cli/solvoid-scan.js +263 -0
- package/dist/cli/solvoid-scan.js.map +1 -0
- package/dist/cli/ultimate-privacy-scan.d.ts +54 -0
- package/dist/cli/ultimate-privacy-scan.d.ts.map +1 -0
- package/dist/cli/ultimate-privacy-scan.js +543 -0
- package/dist/cli/ultimate-privacy-scan.js.map +1 -0
- package/dist/cli/utils/asset-scanner.d.ts +76 -0
- package/dist/cli/utils/asset-scanner.d.ts.map +1 -0
- package/dist/cli/utils/asset-scanner.js +224 -0
- package/dist/cli/utils/asset-scanner.js.map +1 -0
- package/dist/cli/utils/badge-generator.d.ts +33 -0
- package/dist/cli/utils/badge-generator.d.ts.map +1 -0
- package/dist/cli/utils/badge-generator.js +263 -0
- package/dist/cli/utils/badge-generator.js.map +1 -0
- package/dist/cli/utils/enhanced-monitoring.d.ts +13 -0
- package/dist/cli/utils/enhanced-monitoring.d.ts.map +1 -0
- package/dist/cli/utils/enhanced-monitoring.js +46 -0
- package/dist/cli/utils/enhanced-monitoring.js.map +1 -0
- package/dist/cli/utils/enhanced-pyth-feed.d.ts +20 -0
- package/dist/cli/utils/enhanced-pyth-feed.d.ts.map +1 -0
- package/dist/cli/utils/enhanced-pyth-feed.js +64 -0
- package/dist/cli/utils/enhanced-pyth-feed.js.map +1 -0
- package/dist/cli/utils/enhanced-threat-intel.d.ts +20 -0
- package/dist/cli/utils/enhanced-threat-intel.d.ts.map +1 -0
- package/dist/cli/utils/enhanced-threat-intel.js +57 -0
- package/dist/cli/utils/enhanced-threat-intel.js.map +1 -0
- package/dist/cli/utils/env-validator.d.ts +17 -0
- package/dist/cli/utils/env-validator.d.ts.map +1 -0
- package/dist/cli/utils/env-validator.js +257 -0
- package/dist/cli/utils/env-validator.js.map +1 -0
- package/dist/cli/utils/ghost-art.d.ts +14 -0
- package/dist/cli/utils/ghost-art.d.ts.map +1 -0
- package/dist/cli/utils/ghost-art.js +285 -0
- package/dist/cli/utils/ghost-art.js.map +1 -0
- package/dist/cli/utils/ghost-calculator.d.ts +52 -0
- package/dist/cli/utils/ghost-calculator.d.ts.map +1 -0
- package/dist/cli/utils/ghost-calculator.js +207 -0
- package/dist/cli/utils/ghost-calculator.js.map +1 -0
- package/dist/cli/utils/jito-mev-bundle.d.ts +9 -0
- package/dist/cli/utils/jito-mev-bundle.d.ts.map +1 -0
- package/dist/cli/utils/jito-mev-bundle.js +40 -0
- package/dist/cli/utils/jito-mev-bundle.js.map +1 -0
- package/dist/cli/utils/rescue-engine.d.ts +57 -0
- package/dist/cli/utils/rescue-engine.d.ts.map +1 -0
- package/dist/cli/utils/rescue-engine.js +192 -0
- package/dist/cli/utils/rescue-engine.js.map +1 -0
- package/dist/cli/utils/shadow-bridge.d.ts +20 -0
- package/dist/cli/utils/shadow-bridge.d.ts.map +1 -0
- package/dist/cli/utils/shadow-bridge.js +33 -0
- package/dist/cli/utils/shadow-bridge.js.map +1 -0
- package/dist/cli/utils/threat-detector.d.ts +48 -0
- package/dist/cli/utils/threat-detector.d.ts.map +1 -0
- package/dist/cli/utils/threat-detector.js +304 -0
- package/dist/cli/utils/threat-detector.js.map +1 -0
- package/dist/relayer/key-manager.d.ts +52 -0
- package/dist/relayer/key-manager.d.ts.map +1 -0
- package/dist/relayer/key-manager.js +356 -0
- package/dist/relayer/key-manager.js.map +1 -0
- package/dist/relayer/replay-protection.d.ts +94 -0
- package/dist/relayer/replay-protection.d.ts.map +1 -0
- package/dist/relayer/replay-protection.js +189 -0
- package/dist/relayer/replay-protection.js.map +1 -0
- package/dist/relayer/secure-service.d.ts +46 -0
- package/dist/relayer/secure-service.d.ts.map +1 -0
- package/dist/relayer/secure-service.js +538 -0
- package/dist/relayer/secure-service.js.map +1 -0
- package/dist/relayer/service.d.ts +25 -0
- package/dist/relayer/service.d.ts.map +1 -0
- package/dist/relayer/service.js +380 -0
- package/dist/relayer/service.js.map +1 -0
- package/dist/{client.d.ts → sdk/client.d.ts} +17 -0
- package/dist/sdk/client.d.ts.map +1 -0
- package/dist/{client.js → sdk/client.js} +69 -2
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/crypto/poseidon.d.ts.map +1 -0
- package/dist/sdk/crypto/poseidon.js.map +1 -0
- package/dist/sdk/events/bus.d.ts.map +1 -0
- package/dist/sdk/events/bus.js.map +1 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/integrity.d.ts.map +1 -0
- package/dist/sdk/integrity.js.map +1 -0
- package/dist/sdk/network/shadow-rpc.d.ts.map +1 -0
- package/dist/sdk/network/shadow-rpc.js.map +1 -0
- package/dist/sdk/passport/manager.d.ts.map +1 -0
- package/dist/sdk/passport/manager.js.map +1 -0
- package/dist/sdk/pipeline.d.ts.map +1 -0
- package/dist/{pipeline.js → sdk/pipeline.js} +69 -12
- package/dist/sdk/pipeline.js.map +1 -0
- package/dist/sdk/polyfill.d.ts +8 -0
- package/dist/sdk/polyfill.d.ts.map +1 -0
- package/dist/sdk/polyfill.js +21 -0
- package/dist/sdk/polyfill.js.map +1 -0
- package/dist/sdk/privacy/relayer.d.ts.map +1 -0
- package/dist/sdk/privacy/relayer.js.map +1 -0
- package/dist/sdk/privacy/shield.d.ts.map +1 -0
- package/dist/sdk/privacy/shield.js.map +1 -0
- package/dist/sdk/privacy-engine.d.ts.map +1 -0
- package/dist/sdk/privacy-engine.js.map +1 -0
- package/dist/sdk/registry/idl-fetcher.d.ts.map +1 -0
- package/dist/sdk/registry/idl-fetcher.js.map +1 -0
- package/dist/sdk/registry/programs.d.ts.map +1 -0
- package/dist/sdk/registry/programs.js.map +1 -0
- package/dist/sdk/rescue/analyzer.d.ts.map +1 -0
- package/dist/sdk/rescue/analyzer.js.map +1 -0
- package/dist/sdk/rescue/builder.d.ts.map +1 -0
- package/dist/sdk/rescue/builder.js.map +1 -0
- package/dist/sdk/security/key-rotation.d.ts.map +1 -0
- package/dist/sdk/security/key-rotation.js.map +1 -0
- package/dist/{semantics → sdk/semantics}/analyzer.d.ts.map +1 -1
- package/dist/{semantics → sdk/semantics}/analyzer.js.map +1 -1
- package/dist/sdk/semantics/decoder.d.ts.map +1 -0
- package/dist/sdk/semantics/decoder.js.map +1 -0
- package/dist/{semantics → sdk/semantics}/graph.d.ts.map +1 -1
- package/dist/{semantics → sdk/semantics}/graph.js.map +1 -1
- package/dist/sdk/semantics/idl-registry.d.ts.map +1 -0
- package/dist/sdk/semantics/idl-registry.js.map +1 -0
- package/dist/sdk/semantics/types.d.ts.map +1 -0
- package/dist/sdk/semantics/types.js.map +1 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/{semantics → sdk}/types.js.map +1 -1
- package/dist/sdk/utils/address.d.ts.map +1 -0
- package/dist/sdk/utils/address.js.map +1 -0
- package/dist/sdk/utils/config.d.ts.map +1 -0
- package/dist/sdk/utils/config.js.map +1 -0
- package/dist/sdk/utils/logger.d.ts.map +1 -0
- package/dist/sdk/utils/logger.js.map +1 -0
- package/dist/simple-scan.js +249 -0
- package/package.json +103 -36
- package/CHANGELOG.md +0 -33
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/crypto/poseidon.d.ts.map +0 -1
- package/dist/crypto/poseidon.js.map +0 -1
- package/dist/events/bus.d.ts.map +0 -1
- package/dist/events/bus.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/integrity.d.ts.map +0 -1
- package/dist/integrity.js.map +0 -1
- package/dist/network/shadow-rpc.d.ts.map +0 -1
- package/dist/network/shadow-rpc.js.map +0 -1
- package/dist/passport/manager.d.ts.map +0 -1
- package/dist/passport/manager.js.map +0 -1
- package/dist/pipeline.d.ts.map +0 -1
- package/dist/pipeline.js.map +0 -1
- package/dist/privacy/relayer.d.ts.map +0 -1
- package/dist/privacy/relayer.js.map +0 -1
- package/dist/privacy/shield.d.ts.map +0 -1
- package/dist/privacy/shield.js.map +0 -1
- package/dist/privacy-engine.d.ts.map +0 -1
- package/dist/privacy-engine.js.map +0 -1
- package/dist/registry/idl-fetcher.d.ts.map +0 -1
- package/dist/registry/idl-fetcher.js.map +0 -1
- package/dist/registry/programs.d.ts.map +0 -1
- package/dist/registry/programs.js.map +0 -1
- package/dist/rescue/analyzer.d.ts.map +0 -1
- package/dist/rescue/analyzer.js.map +0 -1
- package/dist/rescue/builder.d.ts.map +0 -1
- package/dist/rescue/builder.js.map +0 -1
- package/dist/security/key-rotation.d.ts.map +0 -1
- package/dist/security/key-rotation.js.map +0 -1
- package/dist/semantics/decoder.d.ts.map +0 -1
- package/dist/semantics/decoder.js.map +0 -1
- package/dist/semantics/idl-registry.d.ts.map +0 -1
- package/dist/semantics/idl-registry.js.map +0 -1
- package/dist/semantics/types.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/address.d.ts.map +0 -1
- package/dist/utils/address.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- /package/dist/{crypto → sdk/crypto}/poseidon.d.ts +0 -0
- /package/dist/{crypto → sdk/crypto}/poseidon.js +0 -0
- /package/dist/{events → sdk/events}/bus.d.ts +0 -0
- /package/dist/{events → sdk/events}/bus.js +0 -0
- /package/dist/{index.d.ts → sdk/index.d.ts} +0 -0
- /package/dist/{index.js → sdk/index.js} +0 -0
- /package/dist/{integrity.d.ts → sdk/integrity.d.ts} +0 -0
- /package/dist/{integrity.js → sdk/integrity.js} +0 -0
- /package/dist/{network → sdk/network}/shadow-rpc.d.ts +0 -0
- /package/dist/{network → sdk/network}/shadow-rpc.js +0 -0
- /package/dist/{passport → sdk/passport}/manager.d.ts +0 -0
- /package/dist/{passport → sdk/passport}/manager.js +0 -0
- /package/dist/{pipeline.d.ts → sdk/pipeline.d.ts} +0 -0
- /package/dist/{privacy → sdk/privacy}/relayer.d.ts +0 -0
- /package/dist/{privacy → sdk/privacy}/relayer.js +0 -0
- /package/dist/{privacy → sdk/privacy}/shield.d.ts +0 -0
- /package/dist/{privacy → sdk/privacy}/shield.js +0 -0
- /package/dist/{privacy-engine.d.ts → sdk/privacy-engine.d.ts} +0 -0
- /package/dist/{privacy-engine.js → sdk/privacy-engine.js} +0 -0
- /package/dist/{registry → sdk/registry}/idl-fetcher.d.ts +0 -0
- /package/dist/{registry → sdk/registry}/idl-fetcher.js +0 -0
- /package/dist/{registry → sdk/registry}/programs.d.ts +0 -0
- /package/dist/{registry → sdk/registry}/programs.js +0 -0
- /package/dist/{rescue → sdk/rescue}/analyzer.d.ts +0 -0
- /package/dist/{rescue → sdk/rescue}/analyzer.js +0 -0
- /package/dist/{rescue → sdk/rescue}/builder.d.ts +0 -0
- /package/dist/{rescue → sdk/rescue}/builder.js +0 -0
- /package/dist/{security → sdk/security}/key-rotation.d.ts +0 -0
- /package/dist/{security → sdk/security}/key-rotation.js +0 -0
- /package/dist/{semantics → sdk/semantics}/analyzer.d.ts +0 -0
- /package/dist/{semantics → sdk/semantics}/analyzer.js +0 -0
- /package/dist/{semantics → sdk/semantics}/decoder.d.ts +0 -0
- /package/dist/{semantics → sdk/semantics}/decoder.js +0 -0
- /package/dist/{semantics → sdk/semantics}/graph.d.ts +0 -0
- /package/dist/{semantics → sdk/semantics}/graph.js +0 -0
- /package/dist/{semantics → sdk/semantics}/idl-registry.d.ts +0 -0
- /package/dist/{semantics → sdk/semantics}/idl-registry.js +0 -0
- /package/dist/{semantics → sdk/semantics}/types.d.ts +0 -0
- /package/dist/{semantics → sdk/semantics}/types.js +0 -0
- /package/dist/{types.d.ts → sdk/types.d.ts} +0 -0
- /package/dist/{types.js → sdk/types.js} +0 -0
- /package/dist/{utils → sdk/utils}/address.d.ts +0 -0
- /package/dist/{utils → sdk/utils}/address.js +0 -0
- /package/dist/{utils → sdk/utils}/config.d.ts +0 -0
- /package/dist/{utils → sdk/utils}/config.js +0 -0
- /package/dist/{utils → sdk/utils}/logger.d.ts +0 -0
- /package/dist/{utils → sdk/utils}/logger.js +0 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.KeyManager = void 0;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
43
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
44
|
+
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
45
|
+
class KeyManager {
|
|
46
|
+
constructor(storageType = 'file') {
|
|
47
|
+
this.storageType = storageType;
|
|
48
|
+
this.keyFilePath = path.join(process.cwd(), '.relayer-keys.json');
|
|
49
|
+
this.encryptionKey = process.env.RELAYER_KEY_ENCRYPTION_KEY || 'default-encryption-key-change-in-production';
|
|
50
|
+
this.keypair = this.loadOrGenerateKeysSync();
|
|
51
|
+
}
|
|
52
|
+
loadOrGenerateKeysSync() {
|
|
53
|
+
try {
|
|
54
|
+
switch (this.storageType) {
|
|
55
|
+
case 'file':
|
|
56
|
+
return this.loadFromFileSync();
|
|
57
|
+
case 'env':
|
|
58
|
+
return this.loadFromEnvSync();
|
|
59
|
+
case 'aws':
|
|
60
|
+
// AWS and GCP require async, fallback to file for now
|
|
61
|
+
console.log('AWS/GCP storage requires async initialization, using file storage');
|
|
62
|
+
return this.loadFromFileSync();
|
|
63
|
+
case 'gcp':
|
|
64
|
+
console.log('AWS/GCP storage requires async initialization, using file storage');
|
|
65
|
+
return this.loadFromFileSync();
|
|
66
|
+
case 'hsm':
|
|
67
|
+
console.log('HSM storage requires async initialization, using file storage');
|
|
68
|
+
return this.loadFromFileSync();
|
|
69
|
+
default:
|
|
70
|
+
throw new Error(`Unsupported storage type: ${this.storageType}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.log('Failed to load existing keys, generating new ones:', error);
|
|
75
|
+
return this.generateNewKeysSync();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
loadFromFileSync() {
|
|
79
|
+
if (!fs.existsSync(this.keyFilePath)) {
|
|
80
|
+
throw new Error('Key file does not exist');
|
|
81
|
+
}
|
|
82
|
+
const encryptedData = fs.readFileSync(this.keyFilePath, 'utf8');
|
|
83
|
+
const decryptedData = this.decryptData(encryptedData);
|
|
84
|
+
return JSON.parse(decryptedData);
|
|
85
|
+
}
|
|
86
|
+
loadFromEnvSync() {
|
|
87
|
+
const privateKey = process.env.RELAYER_PRIVATE_KEY;
|
|
88
|
+
const publicKey = process.env.RELAYER_PUBLIC_KEY;
|
|
89
|
+
if (!privateKey || !publicKey) {
|
|
90
|
+
throw new Error('Relayer keys not found in environment variables');
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
publicKey,
|
|
94
|
+
privateKey,
|
|
95
|
+
createdAt: Date.now()
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
generateNewKeysSync() {
|
|
99
|
+
const keypair = web3_js_1.Keypair.generate();
|
|
100
|
+
const keyData = {
|
|
101
|
+
publicKey: keypair.publicKey.toBase58(),
|
|
102
|
+
privateKey: Buffer.from(keypair.secretKey).toString('hex'),
|
|
103
|
+
createdAt: Date.now()
|
|
104
|
+
};
|
|
105
|
+
this.saveKeysSync(keyData);
|
|
106
|
+
return keyData;
|
|
107
|
+
}
|
|
108
|
+
saveKeysSync(keyData) {
|
|
109
|
+
switch (this.storageType) {
|
|
110
|
+
case 'file':
|
|
111
|
+
this.saveToFileSync(keyData);
|
|
112
|
+
break;
|
|
113
|
+
case 'env':
|
|
114
|
+
this.saveToEnvSync(keyData);
|
|
115
|
+
break;
|
|
116
|
+
case 'aws':
|
|
117
|
+
case 'gcp':
|
|
118
|
+
case 'hsm':
|
|
119
|
+
console.log('Async storage types require manual setup');
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
saveToFileSync(keyData) {
|
|
124
|
+
const encryptedData = this.encryptData(JSON.stringify(keyData));
|
|
125
|
+
fs.writeFileSync(this.keyFilePath, encryptedData, 'utf8');
|
|
126
|
+
console.log('Keys saved to encrypted file:', this.keyFilePath);
|
|
127
|
+
}
|
|
128
|
+
saveToEnvSync(keyData) {
|
|
129
|
+
console.log('Keys should be set in environment variables:');
|
|
130
|
+
console.log(`RELAYER_PRIVATE_KEY=${keyData.privateKey}`);
|
|
131
|
+
console.log(`RELAYER_PUBLIC_KEY=${keyData.publicKey}`);
|
|
132
|
+
}
|
|
133
|
+
async loadFromFile() {
|
|
134
|
+
if (!fs.existsSync(this.keyFilePath)) {
|
|
135
|
+
throw new Error('Key file does not exist');
|
|
136
|
+
}
|
|
137
|
+
const encryptedData = fs.readFileSync(this.keyFilePath, 'utf8');
|
|
138
|
+
const decryptedData = this.decryptData(encryptedData);
|
|
139
|
+
return JSON.parse(decryptedData);
|
|
140
|
+
}
|
|
141
|
+
async loadFromEnv() {
|
|
142
|
+
const privateKey = process.env.RELAYER_PRIVATE_KEY;
|
|
143
|
+
const publicKey = process.env.RELAYER_PUBLIC_KEY;
|
|
144
|
+
if (!privateKey || !publicKey) {
|
|
145
|
+
throw new Error('Relayer keys not found in environment variables');
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
publicKey,
|
|
149
|
+
privateKey,
|
|
150
|
+
createdAt: Date.now()
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async loadFromAWS() {
|
|
154
|
+
// Implementation for AWS Secrets Manager
|
|
155
|
+
const AWS = require('aws-sdk');
|
|
156
|
+
const secretsManager = new AWS.SecretsManager();
|
|
157
|
+
try {
|
|
158
|
+
const secretValue = await secretsManager.getSecretValue({
|
|
159
|
+
SecretId: process.env.AWS_RELAYER_KEY_SECRET_NAME || 'relayer-keys'
|
|
160
|
+
}).promise();
|
|
161
|
+
const decryptedData = this.decryptData(secretValue.SecretString);
|
|
162
|
+
return JSON.parse(decryptedData);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
throw new Error(`Failed to load keys from AWS Secrets Manager: ${error}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async loadFromGCP() {
|
|
169
|
+
// Implementation for GCP Secret Manager
|
|
170
|
+
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');
|
|
171
|
+
const client = new SecretManagerServiceClient();
|
|
172
|
+
try {
|
|
173
|
+
const [version] = await client.accessSecretVersion({
|
|
174
|
+
name: `projects/${process.env.GCP_PROJECT_ID}/secrets/${process.env.GCP_RELAYER_KEY_SECRET_NAME || 'relayer-keys'}/versions/latest`
|
|
175
|
+
});
|
|
176
|
+
const decryptedData = this.decryptData(version.payload.data.toString());
|
|
177
|
+
return JSON.parse(decryptedData);
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
throw new Error(`Failed to load keys from GCP Secret Manager: ${error}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async loadFromHSM() {
|
|
184
|
+
// Implementation for Hardware Security Module
|
|
185
|
+
// This would integrate with HSM providers like AWS CloudHSM, Azure Key Vault, etc.
|
|
186
|
+
throw new Error('HSM integration not implemented yet');
|
|
187
|
+
}
|
|
188
|
+
async generateNewKeys() {
|
|
189
|
+
const keypair = web3_js_1.Keypair.generate();
|
|
190
|
+
const keyData = {
|
|
191
|
+
publicKey: keypair.publicKey.toBase58(),
|
|
192
|
+
privateKey: Buffer.from(keypair.secretKey).toString('hex'),
|
|
193
|
+
createdAt: Date.now()
|
|
194
|
+
};
|
|
195
|
+
await this.saveKeys(keyData);
|
|
196
|
+
return keyData;
|
|
197
|
+
}
|
|
198
|
+
async saveKeys(keyData) {
|
|
199
|
+
switch (this.storageType) {
|
|
200
|
+
case 'file':
|
|
201
|
+
await this.saveToFile(keyData);
|
|
202
|
+
break;
|
|
203
|
+
case 'env':
|
|
204
|
+
await this.saveToEnv(keyData);
|
|
205
|
+
break;
|
|
206
|
+
case 'aws':
|
|
207
|
+
await this.saveToAWS(keyData);
|
|
208
|
+
break;
|
|
209
|
+
case 'gcp':
|
|
210
|
+
await this.saveToGCP(keyData);
|
|
211
|
+
break;
|
|
212
|
+
case 'hsm':
|
|
213
|
+
await this.saveToHSM(keyData);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async saveToFile(keyData) {
|
|
218
|
+
const encryptedData = this.encryptData(JSON.stringify(keyData));
|
|
219
|
+
fs.writeFileSync(this.keyFilePath, encryptedData, 'utf8');
|
|
220
|
+
console.log('Keys saved to encrypted file:', this.keyFilePath);
|
|
221
|
+
}
|
|
222
|
+
async saveToEnv(keyData) {
|
|
223
|
+
console.log('Keys should be set in environment variables:');
|
|
224
|
+
console.log(`RELAYER_PRIVATE_KEY=${keyData.privateKey}`);
|
|
225
|
+
console.log(`RELAYER_PUBLIC_KEY=${keyData.publicKey}`);
|
|
226
|
+
}
|
|
227
|
+
async saveToAWS(keyData) {
|
|
228
|
+
const AWS = require('aws-sdk');
|
|
229
|
+
const secretsManager = new AWS.SecretsManager();
|
|
230
|
+
const encryptedData = this.encryptData(JSON.stringify(keyData));
|
|
231
|
+
await secretsManager.createSecret({
|
|
232
|
+
Name: process.env.AWS_RELAYER_KEY_SECRET_NAME || 'relayer-keys',
|
|
233
|
+
SecretString: encryptedData
|
|
234
|
+
}).promise();
|
|
235
|
+
console.log('Keys saved to AWS Secrets Manager');
|
|
236
|
+
}
|
|
237
|
+
async saveToGCP(keyData) {
|
|
238
|
+
const { SecretManagerServiceClient } = require('@google-cloud/secret-manager');
|
|
239
|
+
const client = new SecretManagerServiceClient();
|
|
240
|
+
const encryptedData = this.encryptData(JSON.stringify(keyData));
|
|
241
|
+
await client.createSecret({
|
|
242
|
+
parent: `projects/${process.env.GCP_PROJECT_ID}`,
|
|
243
|
+
secretId: process.env.GCP_RELAYER_KEY_SECRET_NAME || 'relayer-keys',
|
|
244
|
+
replication: {
|
|
245
|
+
automatic: true
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
await client.addSecretVersion({
|
|
249
|
+
parent: `projects/${process.env.GCP_PROJECT_ID}/secrets/${process.env.GCP_RELAYER_KEY_SECRET_NAME || 'relayer-keys'}`,
|
|
250
|
+
payload: {
|
|
251
|
+
data: Buffer.from(encryptedData)
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
console.log('Keys saved to GCP Secret Manager');
|
|
255
|
+
}
|
|
256
|
+
async saveToHSM(keyData) {
|
|
257
|
+
throw new Error('HSM integration not implemented yet');
|
|
258
|
+
}
|
|
259
|
+
encryptData(data) {
|
|
260
|
+
const algorithm = 'aes-256-gcm';
|
|
261
|
+
const key = crypto_1.default.scryptSync(this.encryptionKey, 'salt', 32);
|
|
262
|
+
const iv = crypto_1.default.randomBytes(16);
|
|
263
|
+
const cipher = crypto_1.default.createCipheriv(algorithm, key, iv);
|
|
264
|
+
let encrypted = cipher.update(data, 'utf8', 'hex');
|
|
265
|
+
encrypted += cipher.final('hex');
|
|
266
|
+
const authTag = cipher.getAuthTag();
|
|
267
|
+
return iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted;
|
|
268
|
+
}
|
|
269
|
+
decryptData(encryptedData) {
|
|
270
|
+
const algorithm = 'aes-256-gcm';
|
|
271
|
+
const key = crypto_1.default.scryptSync(this.encryptionKey, 'salt', 32);
|
|
272
|
+
const parts = encryptedData.split(':');
|
|
273
|
+
const iv = Buffer.from(parts[0], 'hex');
|
|
274
|
+
const authTag = Buffer.from(parts[1], 'hex');
|
|
275
|
+
const encrypted = parts[2];
|
|
276
|
+
const decipher = crypto_1.default.createDecipheriv(algorithm, key, iv);
|
|
277
|
+
decipher.setAuthTag(authTag);
|
|
278
|
+
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
279
|
+
decrypted += decipher.final('utf8');
|
|
280
|
+
return decrypted;
|
|
281
|
+
}
|
|
282
|
+
async rotateKeys() {
|
|
283
|
+
const oldKeyData = { ...this.keypair };
|
|
284
|
+
const newKeyData = await this.generateNewKeys();
|
|
285
|
+
// Create rotation message
|
|
286
|
+
const rotationMessage = JSON.stringify({
|
|
287
|
+
oldPublicKey: oldKeyData.publicKey,
|
|
288
|
+
newPublicKey: newKeyData.publicKey,
|
|
289
|
+
timestamp: Date.now(),
|
|
290
|
+
transitionPeriod: 300 // 5 minutes transition period
|
|
291
|
+
});
|
|
292
|
+
// Sign rotation message with old key
|
|
293
|
+
const rotationSignature = this.signMessage(rotationMessage, oldKeyData.privateKey);
|
|
294
|
+
// Update key data with rotation info
|
|
295
|
+
newKeyData.previousPublicKey = oldKeyData.publicKey;
|
|
296
|
+
newKeyData.lastRotated = Date.now();
|
|
297
|
+
newKeyData.rotationSignature = rotationSignature;
|
|
298
|
+
await this.saveKeys(newKeyData);
|
|
299
|
+
this.keypair = newKeyData;
|
|
300
|
+
const rotationData = {
|
|
301
|
+
oldPublicKey: oldKeyData.publicKey,
|
|
302
|
+
newPublicKey: newKeyData.publicKey,
|
|
303
|
+
rotationSignature,
|
|
304
|
+
timestamp: Date.now(),
|
|
305
|
+
transitionPeriod: 300
|
|
306
|
+
};
|
|
307
|
+
console.log('Key rotation completed');
|
|
308
|
+
return rotationData;
|
|
309
|
+
}
|
|
310
|
+
signMessage(message, privateKey) {
|
|
311
|
+
const keypair = web3_js_1.Keypair.fromSecretKey(Buffer.from(privateKey, 'hex'));
|
|
312
|
+
const messageBuffer = Buffer.from(message, 'utf8');
|
|
313
|
+
const signature = tweetnacl_1.default.sign.detached(messageBuffer, keypair.secretKey);
|
|
314
|
+
return Buffer.from(signature).toString('hex');
|
|
315
|
+
}
|
|
316
|
+
verifyRotationSignature(rotationData) {
|
|
317
|
+
try {
|
|
318
|
+
const rotationMessage = JSON.stringify({
|
|
319
|
+
oldPublicKey: rotationData.oldPublicKey,
|
|
320
|
+
newPublicKey: rotationData.newPublicKey,
|
|
321
|
+
timestamp: rotationData.timestamp,
|
|
322
|
+
transitionPeriod: rotationData.transitionPeriod
|
|
323
|
+
});
|
|
324
|
+
const messageBuffer = Buffer.from(rotationMessage, 'utf8');
|
|
325
|
+
const signatureBuffer = Buffer.from(rotationData.rotationSignature, 'hex');
|
|
326
|
+
const publicKeyBuffer = Buffer.from(rotationData.oldPublicKey, 'hex');
|
|
327
|
+
return tweetnacl_1.default.sign.detached.verify(messageBuffer, signatureBuffer, publicKeyBuffer);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
console.error('Failed to verify rotation signature:', error);
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
getCurrentKeys() {
|
|
335
|
+
return { ...this.keypair };
|
|
336
|
+
}
|
|
337
|
+
getPublicKey() {
|
|
338
|
+
return this.keypair.publicKey;
|
|
339
|
+
}
|
|
340
|
+
getPrivateKey() {
|
|
341
|
+
return this.keypair.privateKey;
|
|
342
|
+
}
|
|
343
|
+
isKeyInTransitionPeriod() {
|
|
344
|
+
if (!this.keypair.lastRotated) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
const transitionPeriod = 300; // 5 minutes
|
|
348
|
+
const timeSinceRotation = Date.now() - this.keypair.lastRotated;
|
|
349
|
+
return timeSinceRotation < (transitionPeriod * 1000);
|
|
350
|
+
}
|
|
351
|
+
getPreviousPublicKey() {
|
|
352
|
+
return this.keypair.previousPublicKey || null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
exports.KeyManager = KeyManager;
|
|
356
|
+
//# sourceMappingURL=key-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-manager.js","sourceRoot":"","sources":["../../relayer/key-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export interface NonceEntry {
|
|
2
|
+
publicKey: string;
|
|
3
|
+
nonce: number;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
txHash: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TransactionData {
|
|
8
|
+
publicKey: string;
|
|
9
|
+
nonce: number;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
txHash: string;
|
|
12
|
+
signature: string;
|
|
13
|
+
instructions: any[];
|
|
14
|
+
}
|
|
15
|
+
export interface ReplayCacheEntry {
|
|
16
|
+
publicKey: string;
|
|
17
|
+
nonce: number;
|
|
18
|
+
txHash: string;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class ReplayProtection {
|
|
22
|
+
private nonceCache;
|
|
23
|
+
private replayCache;
|
|
24
|
+
private expirationWindow;
|
|
25
|
+
private cleanupInterval;
|
|
26
|
+
constructor();
|
|
27
|
+
/**
|
|
28
|
+
* Initialize nonce for a user (called during registration)
|
|
29
|
+
*/
|
|
30
|
+
initializeNonce(publicKey: string): number;
|
|
31
|
+
/**
|
|
32
|
+
* Get current nonce for a user
|
|
33
|
+
*/
|
|
34
|
+
getCurrentNonce(publicKey: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* Validate and increment nonce for transaction
|
|
37
|
+
*/
|
|
38
|
+
validateAndIncrementNonce(publicKey: string, expectedNonce: number): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if transaction is expired
|
|
41
|
+
*/
|
|
42
|
+
isTransactionExpired(timestamp: number): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Create cache key for replay protection
|
|
45
|
+
*/
|
|
46
|
+
private createCacheKey;
|
|
47
|
+
/**
|
|
48
|
+
* Check if transaction is in replay cache
|
|
49
|
+
*/
|
|
50
|
+
isTransactionReplayed(publicKey: string, nonce: number, txHash: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Add transaction to replay cache
|
|
53
|
+
*/
|
|
54
|
+
addTransactionToCache(publicKey: string, nonce: number, txHash: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Validate complete transaction data
|
|
57
|
+
*/
|
|
58
|
+
validateTransaction(txData: TransactionData): {
|
|
59
|
+
isValid: boolean;
|
|
60
|
+
error: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Get nonce statistics for a user
|
|
64
|
+
*/
|
|
65
|
+
getNonceStats(publicKey: string): {
|
|
66
|
+
currentNonce: number;
|
|
67
|
+
totalTransactions: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Clean up old entries from replay cache
|
|
71
|
+
*/
|
|
72
|
+
private cleanupExpiredEntries;
|
|
73
|
+
/**
|
|
74
|
+
* Start cleanup task
|
|
75
|
+
*/
|
|
76
|
+
private startCleanupTask;
|
|
77
|
+
/**
|
|
78
|
+
* Stop cleanup task
|
|
79
|
+
*/
|
|
80
|
+
stopCleanupTask(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Get cache statistics
|
|
83
|
+
*/
|
|
84
|
+
getCacheStats(): {
|
|
85
|
+
totalEntries: number;
|
|
86
|
+
nonceCacheSize: number;
|
|
87
|
+
expirationWindow: number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Clear all cache data (for testing)
|
|
91
|
+
*/
|
|
92
|
+
clearCache(): void;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=replay-protection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-protection.d.ts","sourceRoot":"","sources":["../../relayer/replay-protection.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,GAAG,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,WAAW,CAA4C;IAC/D,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,eAAe,CAA+B;;IAMtD;;OAEG;IACI,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOjD;;OAEG;IACI,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAIjD;;OAEG;IACI,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO;IAanF;;OAEG;IACI,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAMvD;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACI,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAiBvF;;OAEG;IACI,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAapF;;OAEG;IACI,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAkCxF;;OAEG;IACI,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE;IAiB5F;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAmB7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACI,eAAe,IAAI,IAAI;IAO9B;;OAEG;IACI,aAAa;;;;;IAQpB;;OAEG;IACI,UAAU,IAAI,IAAI;CAK5B"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReplayProtection = void 0;
|
|
4
|
+
class ReplayProtection {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.nonceCache = new Map(); // publicKey -> current nonce
|
|
7
|
+
this.replayCache = new Map(); // (publicKey:nonce:txHash) -> entry
|
|
8
|
+
this.expirationWindow = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
9
|
+
this.cleanupInterval = null;
|
|
10
|
+
this.startCleanupTask();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Initialize nonce for a user (called during registration)
|
|
14
|
+
*/
|
|
15
|
+
initializeNonce(publicKey) {
|
|
16
|
+
const nonce = 1;
|
|
17
|
+
this.nonceCache.set(publicKey, nonce);
|
|
18
|
+
console.log(`Initialized nonce ${nonce} for user ${publicKey}`);
|
|
19
|
+
return nonce;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get current nonce for a user
|
|
23
|
+
*/
|
|
24
|
+
getCurrentNonce(publicKey) {
|
|
25
|
+
return this.nonceCache.get(publicKey) || 0;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate and increment nonce for transaction
|
|
29
|
+
*/
|
|
30
|
+
validateAndIncrementNonce(publicKey, expectedNonce) {
|
|
31
|
+
const currentNonce = this.nonceCache.get(publicKey) || 0;
|
|
32
|
+
if (expectedNonce !== currentNonce + 1) {
|
|
33
|
+
console.log(`Invalid nonce for user ${publicKey}: expected ${currentNonce + 1}, got ${expectedNonce}`);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
this.nonceCache.set(publicKey, expectedNonce);
|
|
37
|
+
console.log(`Incremented nonce to ${expectedNonce} for user ${publicKey}`);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if transaction is expired
|
|
42
|
+
*/
|
|
43
|
+
isTransactionExpired(timestamp) {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
const age = now - timestamp;
|
|
46
|
+
return age > this.expirationWindow;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create cache key for replay protection
|
|
50
|
+
*/
|
|
51
|
+
createCacheKey(publicKey, nonce, txHash) {
|
|
52
|
+
return `${publicKey}:${nonce}:${txHash}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Check if transaction is in replay cache
|
|
56
|
+
*/
|
|
57
|
+
isTransactionReplayed(publicKey, nonce, txHash) {
|
|
58
|
+
const cacheKey = this.createCacheKey(publicKey, nonce, txHash);
|
|
59
|
+
const entry = this.replayCache.get(cacheKey);
|
|
60
|
+
if (!entry) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// Check if transaction is expired
|
|
64
|
+
if (this.isTransactionExpired(entry.timestamp)) {
|
|
65
|
+
this.replayCache.delete(cacheKey);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Add transaction to replay cache
|
|
72
|
+
*/
|
|
73
|
+
addTransactionToCache(publicKey, nonce, txHash) {
|
|
74
|
+
const cacheKey = this.createCacheKey(publicKey, nonce, txHash);
|
|
75
|
+
const entry = {
|
|
76
|
+
publicKey,
|
|
77
|
+
nonce,
|
|
78
|
+
txHash,
|
|
79
|
+
timestamp: Date.now()
|
|
80
|
+
};
|
|
81
|
+
this.replayCache.set(cacheKey, entry);
|
|
82
|
+
console.log(`Added transaction to replay cache: ${cacheKey}`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validate complete transaction data
|
|
86
|
+
*/
|
|
87
|
+
validateTransaction(txData) {
|
|
88
|
+
// Check timestamp expiration
|
|
89
|
+
if (this.isTransactionExpired(txData.timestamp)) {
|
|
90
|
+
return {
|
|
91
|
+
isValid: false,
|
|
92
|
+
error: 'Transaction has expired'
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Check nonce sequence
|
|
96
|
+
if (!this.validateAndIncrementNonce(txData.publicKey, txData.nonce)) {
|
|
97
|
+
return {
|
|
98
|
+
isValid: false,
|
|
99
|
+
error: `Invalid nonce sequence. Expected ${this.getCurrentNonce(txData.publicKey) + 1}, got ${txData.nonce}`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Check replay cache
|
|
103
|
+
if (this.isTransactionReplayed(txData.publicKey, txData.nonce, txData.txHash)) {
|
|
104
|
+
return {
|
|
105
|
+
isValid: false,
|
|
106
|
+
error: 'Transaction has already been processed'
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// Add to replay cache
|
|
110
|
+
this.addTransactionToCache(txData.publicKey, txData.nonce, txData.txHash);
|
|
111
|
+
return {
|
|
112
|
+
isValid: true,
|
|
113
|
+
error: ''
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get nonce statistics for a user
|
|
118
|
+
*/
|
|
119
|
+
getNonceStats(publicKey) {
|
|
120
|
+
const currentNonce = this.getCurrentNonce(publicKey);
|
|
121
|
+
let totalTransactions = 0;
|
|
122
|
+
// Count transactions in cache for this user
|
|
123
|
+
for (const [key, entry] of this.replayCache.entries()) {
|
|
124
|
+
if (key.startsWith(`${publicKey}:`)) {
|
|
125
|
+
totalTransactions++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
currentNonce,
|
|
130
|
+
totalTransactions
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Clean up old entries from replay cache
|
|
135
|
+
*/
|
|
136
|
+
cleanupExpiredEntries() {
|
|
137
|
+
const now = Date.now();
|
|
138
|
+
const expiredKeys = [];
|
|
139
|
+
for (const [key, entry] of this.replayCache.entries()) {
|
|
140
|
+
if (this.isTransactionExpired(entry.timestamp)) {
|
|
141
|
+
expiredKeys.push(key);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const key of expiredKeys) {
|
|
145
|
+
this.replayCache.delete(key);
|
|
146
|
+
}
|
|
147
|
+
if (expiredKeys.length > 0) {
|
|
148
|
+
console.log(`Cleaned up ${expiredKeys.length} expired replay cache entries`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Start cleanup task
|
|
153
|
+
*/
|
|
154
|
+
startCleanupTask() {
|
|
155
|
+
// Run cleanup every 5 minutes
|
|
156
|
+
this.cleanupInterval = setInterval(() => {
|
|
157
|
+
this.cleanupExpiredEntries();
|
|
158
|
+
}, 5 * 60 * 1000);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Stop cleanup task
|
|
162
|
+
*/
|
|
163
|
+
stopCleanupTask() {
|
|
164
|
+
if (this.cleanupInterval) {
|
|
165
|
+
clearInterval(this.cleanupInterval);
|
|
166
|
+
this.cleanupInterval = null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get cache statistics
|
|
171
|
+
*/
|
|
172
|
+
getCacheStats() {
|
|
173
|
+
return {
|
|
174
|
+
totalEntries: this.replayCache.size,
|
|
175
|
+
nonceCacheSize: this.nonceCache.size,
|
|
176
|
+
expirationWindow: this.expirationWindow
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Clear all cache data (for testing)
|
|
181
|
+
*/
|
|
182
|
+
clearCache() {
|
|
183
|
+
this.nonceCache.clear();
|
|
184
|
+
this.replayCache.clear();
|
|
185
|
+
console.log('Cleared all replay protection cache data');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.ReplayProtection = ReplayProtection;
|
|
189
|
+
//# sourceMappingURL=replay-protection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-protection.js","sourceRoot":"","sources":["../../relayer/replay-protection.ts"],"names":[],"mappings":"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"}
|