@rlajous/sdk-threat 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.
Files changed (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +288 -0
  3. package/dist/cjs/client.js +165 -0
  4. package/dist/cjs/client.js.map +1 -0
  5. package/dist/cjs/index.js +33 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/package.json +1 -0
  8. package/dist/cjs/resources/account-trace.js +96 -0
  9. package/dist/cjs/resources/account-trace.js.map +1 -0
  10. package/dist/cjs/resources/addresses.js +189 -0
  11. package/dist/cjs/resources/addresses.js.map +1 -0
  12. package/dist/cjs/resources/contracts.js +216 -0
  13. package/dist/cjs/resources/contracts.js.map +1 -0
  14. package/dist/cjs/resources/index.js +18 -0
  15. package/dist/cjs/resources/index.js.map +1 -0
  16. package/dist/cjs/resources/ledger.js +123 -0
  17. package/dist/cjs/resources/ledger.js.map +1 -0
  18. package/dist/cjs/resources/url.js +85 -0
  19. package/dist/cjs/resources/url.js.map +1 -0
  20. package/dist/cjs/resources/usage.js +124 -0
  21. package/dist/cjs/resources/usage.js.map +1 -0
  22. package/dist/cjs/resources/wallets.js +149 -0
  23. package/dist/cjs/resources/wallets.js.map +1 -0
  24. package/dist/cjs/types/account-trace.js +3 -0
  25. package/dist/cjs/types/account-trace.js.map +1 -0
  26. package/dist/cjs/types/address.js +3 -0
  27. package/dist/cjs/types/address.js.map +1 -0
  28. package/dist/cjs/types/contract.js +3 -0
  29. package/dist/cjs/types/contract.js.map +1 -0
  30. package/dist/cjs/types/index.js +3 -0
  31. package/dist/cjs/types/index.js.map +1 -0
  32. package/dist/cjs/types/ledger.js +3 -0
  33. package/dist/cjs/types/ledger.js.map +1 -0
  34. package/dist/cjs/types/url.js +3 -0
  35. package/dist/cjs/types/url.js.map +1 -0
  36. package/dist/cjs/types/usage.js +3 -0
  37. package/dist/cjs/types/usage.js.map +1 -0
  38. package/dist/cjs/types/wallet.js +3 -0
  39. package/dist/cjs/types/wallet.js.map +1 -0
  40. package/dist/esm/client.js +161 -0
  41. package/dist/esm/client.js.map +1 -0
  42. package/dist/esm/index.js +7 -0
  43. package/dist/esm/index.js.map +1 -0
  44. package/dist/esm/package.json +1 -0
  45. package/dist/esm/resources/account-trace.js +92 -0
  46. package/dist/esm/resources/account-trace.js.map +1 -0
  47. package/dist/esm/resources/addresses.js +185 -0
  48. package/dist/esm/resources/addresses.js.map +1 -0
  49. package/dist/esm/resources/contracts.js +212 -0
  50. package/dist/esm/resources/contracts.js.map +1 -0
  51. package/dist/esm/resources/index.js +8 -0
  52. package/dist/esm/resources/index.js.map +1 -0
  53. package/dist/esm/resources/ledger.js +119 -0
  54. package/dist/esm/resources/ledger.js.map +1 -0
  55. package/dist/esm/resources/url.js +81 -0
  56. package/dist/esm/resources/url.js.map +1 -0
  57. package/dist/esm/resources/usage.js +120 -0
  58. package/dist/esm/resources/usage.js.map +1 -0
  59. package/dist/esm/resources/wallets.js +145 -0
  60. package/dist/esm/resources/wallets.js.map +1 -0
  61. package/dist/esm/types/account-trace.js +2 -0
  62. package/dist/esm/types/account-trace.js.map +1 -0
  63. package/dist/esm/types/address.js +2 -0
  64. package/dist/esm/types/address.js.map +1 -0
  65. package/dist/esm/types/contract.js +2 -0
  66. package/dist/esm/types/contract.js.map +1 -0
  67. package/dist/esm/types/index.js +2 -0
  68. package/dist/esm/types/index.js.map +1 -0
  69. package/dist/esm/types/ledger.js +2 -0
  70. package/dist/esm/types/ledger.js.map +1 -0
  71. package/dist/esm/types/url.js +2 -0
  72. package/dist/esm/types/url.js.map +1 -0
  73. package/dist/esm/types/usage.js +2 -0
  74. package/dist/esm/types/usage.js.map +1 -0
  75. package/dist/esm/types/wallet.js +2 -0
  76. package/dist/esm/types/wallet.js.map +1 -0
  77. package/dist/types/client.d.ts +145 -0
  78. package/dist/types/client.d.ts.map +1 -0
  79. package/dist/types/index.d.ts +5 -0
  80. package/dist/types/index.d.ts.map +1 -0
  81. package/dist/types/resources/account-trace.d.ts +67 -0
  82. package/dist/types/resources/account-trace.d.ts.map +1 -0
  83. package/dist/types/resources/addresses.d.ts +131 -0
  84. package/dist/types/resources/addresses.d.ts.map +1 -0
  85. package/dist/types/resources/contracts.d.ts +156 -0
  86. package/dist/types/resources/contracts.d.ts.map +1 -0
  87. package/dist/types/resources/index.d.ts +8 -0
  88. package/dist/types/resources/index.d.ts.map +1 -0
  89. package/dist/types/resources/ledger.d.ts +107 -0
  90. package/dist/types/resources/ledger.d.ts.map +1 -0
  91. package/dist/types/resources/url.d.ts +69 -0
  92. package/dist/types/resources/url.d.ts.map +1 -0
  93. package/dist/types/resources/usage.d.ts +99 -0
  94. package/dist/types/resources/usage.d.ts.map +1 -0
  95. package/dist/types/resources/wallets.d.ts +106 -0
  96. package/dist/types/resources/wallets.d.ts.map +1 -0
  97. package/dist/types/types/account-trace.d.ts +68 -0
  98. package/dist/types/types/account-trace.d.ts.map +1 -0
  99. package/dist/types/types/address.d.ts +266 -0
  100. package/dist/types/types/address.d.ts.map +1 -0
  101. package/dist/types/types/contract.d.ts +169 -0
  102. package/dist/types/types/contract.d.ts.map +1 -0
  103. package/dist/types/types/index.d.ts +8 -0
  104. package/dist/types/types/index.d.ts.map +1 -0
  105. package/dist/types/types/ledger.d.ts +106 -0
  106. package/dist/types/types/ledger.d.ts.map +1 -0
  107. package/dist/types/types/url.d.ts +39 -0
  108. package/dist/types/types/url.d.ts.map +1 -0
  109. package/dist/types/types/usage.d.ts +74 -0
  110. package/dist/types/types/usage.d.ts.map +1 -0
  111. package/dist/types/types/wallet.d.ts +129 -0
  112. package/dist/types/types/wallet.d.ts.map +1 -0
  113. package/package.json +74 -0
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AddressesResource = void 0;
4
+ const sdk_core_1 = require("@rlajous/sdk-core");
5
+ /**
6
+ * Resource for address risk analysis
7
+ *
8
+ * Provides comprehensive security analysis for blockchain addresses including:
9
+ * - Overall risk scoring
10
+ * - Risk categorization and tagging
11
+ * - Sanctions screening
12
+ * - Address poisoning detection
13
+ * - Fund flow analysis
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Analyze an address
18
+ * const risk = await client.addresses.analyze('0x...', { chain: Chain.ETH });
19
+ *
20
+ * // Check sanctions
21
+ * const sanctioned = await client.addresses.checkSanctioned('0x...', { chain: Chain.ETH });
22
+ *
23
+ * // With default chain configured, chain can be omitted
24
+ * const client = new ThreatClient({ apiKey: '...', defaultChain: Chain.ETH });
25
+ * const risk = await client.addresses.analyze('0x...'); // Uses ETH
26
+ * ```
27
+ */
28
+ class AddressesResource {
29
+ httpClient;
30
+ defaultChain;
31
+ constructor(httpClient, defaultChain) {
32
+ this.httpClient = httpClient;
33
+ this.defaultChain = defaultChain;
34
+ }
35
+ /**
36
+ * Resolve the chain to use for a request
37
+ * @throws ValidationError if no chain is specified and no default is set
38
+ */
39
+ resolveChain(options) {
40
+ const chain = options?.chain ?? this.defaultChain;
41
+ if (!chain) {
42
+ throw new sdk_core_1.ValidationError('Chain is required. Either specify chain in options or set defaultChain in client configuration.');
43
+ }
44
+ return chain;
45
+ }
46
+ /**
47
+ * Validate address format for the given chain
48
+ * @throws ValidationError if address format is invalid for the chain
49
+ */
50
+ validateAddress(address, chain) {
51
+ if (!(0, sdk_core_1.isValidAddress)(address, chain)) {
52
+ const chainName = sdk_core_1.CHAIN_NAMES[chain] || chain;
53
+ throw new sdk_core_1.ValidationError(`Invalid ${chainName} address: "${address}". Please provide a valid address format for the ${chainName} blockchain.`);
54
+ }
55
+ }
56
+ /**
57
+ * Analyze an address for security risks
58
+ *
59
+ * Returns comprehensive risk analysis including:
60
+ * - Overall risk score (0-100)
61
+ * - Risk tags and categories
62
+ * - Detailed analysis data (optional)
63
+ * - Deployer risk for contracts (optional)
64
+ *
65
+ * @param address - Address to analyze
66
+ * @param options - Analysis options (chain is optional if defaultChain is set)
67
+ * @returns Address risk analysis result
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * // Basic analysis
72
+ * const risk = await client.addresses.analyze('0x742d35Cc...', {
73
+ * chain: Chain.ETH,
74
+ * });
75
+ * console.log(`Risk score: ${risk.overallRisk}`);
76
+ *
77
+ * // With default chain, options can be omitted
78
+ * const risk = await client.addresses.analyze('0x742d35Cc...');
79
+ *
80
+ * // With specific modules
81
+ * const risk = await client.addresses.analyze('0x...', {
82
+ * chain: Chain.ETH,
83
+ * modules: [RiskModule.SANCTIONS_COMPLIANCE, RiskModule.FUND_FLOW_SCREENING],
84
+ * });
85
+ *
86
+ * // With detailed response and deployer risk
87
+ * const risk = await client.addresses.analyze('0x...', {
88
+ * chain: Chain.ETH,
89
+ * detailed: true,
90
+ * deployerRisk: true,
91
+ * });
92
+ * ```
93
+ */
94
+ async analyze(address, options = {}) {
95
+ const chain = this.resolveChain(options);
96
+ this.validateAddress(address, chain);
97
+ const queryParams = new URLSearchParams();
98
+ queryParams.append('chain', chain);
99
+ if (options.modules && options.modules.length > 0) {
100
+ for (const module of options.modules) {
101
+ queryParams.append('modules', module);
102
+ }
103
+ }
104
+ if (options.detailed !== undefined) {
105
+ queryParams.append('detailed', String(options.detailed));
106
+ }
107
+ if (options.deployerRisk !== undefined) {
108
+ queryParams.append('deployer_risk', String(options.deployerRisk));
109
+ }
110
+ const response = await this.httpClient.get(`/addresses/${encodeURIComponent(address)}?${queryParams.toString()}`, {
111
+ timeout: options.timeout,
112
+ signal: options.signal,
113
+ });
114
+ return response.data;
115
+ }
116
+ /**
117
+ * Check if an address is sanctioned
118
+ *
119
+ * Screens the address against known sanctions lists including OFAC.
120
+ *
121
+ * @param address - Address to check
122
+ * @param options - Request options (chain is optional if defaultChain is set)
123
+ * @returns Sanctions check result
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * const result = await client.addresses.checkSanctioned('0x...', {
128
+ * chain: Chain.ETH,
129
+ * });
130
+ *
131
+ * // With default chain configured
132
+ * const result = await client.addresses.checkSanctioned('0x...');
133
+ *
134
+ * if (result.is_sanctioned) {
135
+ * console.error('Address is sanctioned!');
136
+ * console.log('Details:', result.sanction_details);
137
+ * }
138
+ * ```
139
+ */
140
+ async checkSanctioned(address, options = {}) {
141
+ const chain = this.resolveChain(options);
142
+ this.validateAddress(address, chain);
143
+ const queryParams = new URLSearchParams();
144
+ queryParams.append('chain', chain);
145
+ const response = await this.httpClient.get(`/addresses/sanctioned/${encodeURIComponent(address)}?${queryParams.toString()}`, {
146
+ timeout: options.timeout,
147
+ signal: options.signal,
148
+ });
149
+ return response.data;
150
+ }
151
+ /**
152
+ * Check for address poisoning attacks
153
+ *
154
+ * Detects if an address has been targeted by address poisoning
155
+ * (dust attack) attempts.
156
+ *
157
+ * @param address - Address to check
158
+ * @param options - Request options (chain is optional if defaultChain is set)
159
+ * @returns Poisoning detection result
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * const result = await client.addresses.checkPoisoning('0x...', {
164
+ * chain: Chain.ETH,
165
+ * });
166
+ *
167
+ * // With default chain configured
168
+ * const result = await client.addresses.checkPoisoning('0x...');
169
+ *
170
+ * if (result.is_poisoned) {
171
+ * console.warn('Address poisoning detected!');
172
+ * console.log('Similar addresses:', result.poisoning_details?.similar_addresses);
173
+ * }
174
+ * ```
175
+ */
176
+ async checkPoisoning(address, options = {}) {
177
+ const chain = this.resolveChain(options);
178
+ this.validateAddress(address, chain);
179
+ const queryParams = new URLSearchParams();
180
+ queryParams.append('chain', chain);
181
+ const response = await this.httpClient.get(`/addresses/${encodeURIComponent(address)}/poisoning?${queryParams.toString()}`, {
182
+ timeout: options.timeout,
183
+ signal: options.signal,
184
+ });
185
+ return response.data;
186
+ }
187
+ }
188
+ exports.AddressesResource = AddressesResource;
189
+ //# sourceMappingURL=addresses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addresses.js","sourceRoot":"","sources":["../../../src/resources/addresses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractsResource = void 0;
4
+ const sdk_core_1 = require("@rlajous/sdk-core");
5
+ /**
6
+ * Resource for smart contract security analysis
7
+ *
8
+ * Provides comprehensive contract analysis including:
9
+ * - Static and dynamic code analysis
10
+ * - Vulnerability detection
11
+ * - Source code verification
12
+ * - Tax/fee detection
13
+ * - Deployer risk analysis
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Analyze a contract
18
+ * const risk = await client.contracts.analyze('0x...', { chain: Chain.ETH });
19
+ *
20
+ * // Get source code
21
+ * const source = await client.contracts.getSourceCode('0x...', { chain: Chain.ETH });
22
+ *
23
+ * // With default chain configured, chain can be omitted
24
+ * const client = new ThreatClient({ apiKey: '...', defaultChain: Chain.ETH });
25
+ * const risk = await client.contracts.analyze('0x...'); // Uses ETH
26
+ * ```
27
+ */
28
+ class ContractsResource {
29
+ httpClient;
30
+ defaultChain;
31
+ constructor(httpClient, defaultChain) {
32
+ this.httpClient = httpClient;
33
+ this.defaultChain = defaultChain;
34
+ }
35
+ /**
36
+ * Resolve the chain to use for a request
37
+ * @throws ValidationError if no chain is specified and no default is set
38
+ */
39
+ resolveChain(options) {
40
+ const chain = options?.chain ?? this.defaultChain;
41
+ if (!chain) {
42
+ throw new sdk_core_1.ValidationError('Chain is required. Either specify chain in options or set defaultChain in client configuration.');
43
+ }
44
+ return chain;
45
+ }
46
+ /**
47
+ * Analyze a smart contract for security risks
48
+ *
49
+ * Returns comprehensive analysis including:
50
+ * - Risk score and categorization
51
+ * - Vulnerability detection
52
+ * - Source code analysis (if verified)
53
+ * - Similar contracts
54
+ * - Deployer risk (optional)
55
+ *
56
+ * @param address - Contract address
57
+ * @param options - Analysis options (chain is optional if defaultChain is set)
58
+ * @returns Contract risk analysis result
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const result = await client.contracts.analyze('0xContract...', {
63
+ * chain: Chain.ETH,
64
+ * });
65
+ *
66
+ * // With default chain, options can be omitted
67
+ * const result = await client.contracts.analyze('0xContract...');
68
+ *
69
+ * console.log(`Risk score: ${result.score}`);
70
+ * console.log(`Tags: ${result.tags.map(t => t.name).join(', ')}`);
71
+ *
72
+ * // Check for vulnerabilities
73
+ * if (result.source_code_analysis && 'vulnerabilities' in result.source_code_analysis) {
74
+ * for (const vuln of result.source_code_analysis.vulnerabilities) {
75
+ * console.warn(`${vuln.severity}: ${vuln.title}`);
76
+ * }
77
+ * }
78
+ * ```
79
+ */
80
+ async analyze(address, options = {}) {
81
+ const chain = this.resolveChain(options);
82
+ // Validate contract address format before making API call
83
+ if (!(0, sdk_core_1.isValidAddress)(address, chain)) {
84
+ const chainName = sdk_core_1.CHAIN_NAMES[chain] || chain;
85
+ throw new sdk_core_1.ValidationError(`Invalid ${chainName} contract address: "${address}". Please provide a valid address format for the ${chainName} blockchain.`);
86
+ }
87
+ const queryParams = new URLSearchParams();
88
+ queryParams.append('chain', chain);
89
+ if (options.deployerRisk !== undefined) {
90
+ queryParams.append('deployer_risk', String(options.deployerRisk));
91
+ }
92
+ const response = await this.httpClient.get(`/contracts/${encodeURIComponent(address)}?${queryParams.toString()}`, {
93
+ timeout: options.timeout,
94
+ signal: options.signal,
95
+ });
96
+ return response.data;
97
+ }
98
+ /**
99
+ * Get contract source code
100
+ *
101
+ * Returns source code and metadata for verified contracts.
102
+ *
103
+ * @param address - Contract address
104
+ * @param options - Request options (chain is optional if defaultChain is set)
105
+ * @returns Contract source code and metadata
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const source = await client.contracts.getSourceCode('0x...', {
110
+ * chain: Chain.ETH,
111
+ * });
112
+ *
113
+ * // With default chain configured
114
+ * const source = await client.contracts.getSourceCode('0x...');
115
+ *
116
+ * if (source.is_verified) {
117
+ * console.log(`Contract: ${source.contract_name}`);
118
+ * console.log(`Compiler: ${source.compiler_version}`);
119
+ * } else {
120
+ * console.log('Contract source not verified');
121
+ * }
122
+ * ```
123
+ */
124
+ async getSourceCode(address, options = {}) {
125
+ const chain = this.resolveChain(options);
126
+ // Validate contract address format before making API call
127
+ if (!(0, sdk_core_1.isValidAddress)(address, chain)) {
128
+ const chainName = sdk_core_1.CHAIN_NAMES[chain] || chain;
129
+ throw new sdk_core_1.ValidationError(`Invalid ${chainName} contract address: "${address}". Please provide a valid address format for the ${chainName} blockchain.`);
130
+ }
131
+ const queryParams = new URLSearchParams();
132
+ queryParams.append('chain', chain);
133
+ const response = await this.httpClient.get(`/contracts/${encodeURIComponent(address)}/source-code?${queryParams.toString()}`, {
134
+ timeout: options.timeout,
135
+ signal: options.signal,
136
+ });
137
+ return response.data;
138
+ }
139
+ /**
140
+ * Get token buy/sell taxes
141
+ *
142
+ * Analyzes token contracts for buy and sell taxes.
143
+ *
144
+ * @param address - Token contract address
145
+ * @param options - Request options (chain is optional if defaultChain is set)
146
+ * @returns Tax information
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * const taxes = await client.contracts.getTaxes('0x...', {
151
+ * chain: Chain.ETH,
152
+ * });
153
+ *
154
+ * // With default chain configured
155
+ * const taxes = await client.contracts.getTaxes('0x...');
156
+ *
157
+ * if (taxes.buyTaxPercentage !== null || taxes.sellTaxPercentage !== null) {
158
+ * console.log(`Buy tax: ${taxes.buyTaxPercentage}%`);
159
+ * console.log(`Sell tax: ${taxes.sellTaxPercentage}%`);
160
+ * }
161
+ * ```
162
+ */
163
+ async getTaxes(address, options = {}) {
164
+ const chain = this.resolveChain(options);
165
+ // Validate token contract address format before making API call
166
+ if (!(0, sdk_core_1.isValidAddress)(address, chain)) {
167
+ const chainName = sdk_core_1.CHAIN_NAMES[chain] || chain;
168
+ throw new sdk_core_1.ValidationError(`Invalid ${chainName} token contract address: "${address}". Please provide a valid address format for the ${chainName} blockchain.`);
169
+ }
170
+ const queryParams = new URLSearchParams();
171
+ queryParams.append('chain', chain);
172
+ const response = await this.httpClient.get(`/contracts/taxes/${encodeURIComponent(address)}?${queryParams.toString()}`, {
173
+ timeout: options.timeout,
174
+ signal: options.signal,
175
+ });
176
+ return response.data;
177
+ }
178
+ /**
179
+ * Analyze Solidity source code
180
+ *
181
+ * Analyzes raw Solidity source code for vulnerabilities
182
+ * without requiring deployment.
183
+ *
184
+ * @param request - Analysis request with source code
185
+ * @returns Analysis results
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const result = await client.contracts.analyzeSolidity({
190
+ * source_code: `
191
+ * pragma solidity ^0.8.0;
192
+ * contract MyToken {
193
+ * // ...
194
+ * }
195
+ * `,
196
+ * compiler_version: '0.8.19',
197
+ * });
198
+ *
199
+ * if (result.success && result.results) {
200
+ * console.log(`Security score: ${result.results.security_score}`);
201
+ * for (const vuln of result.results.vulnerabilities) {
202
+ * console.warn(`${vuln.severity}: ${vuln.title}`);
203
+ * }
204
+ * }
205
+ * ```
206
+ */
207
+ async analyzeSolidity(request, options) {
208
+ const response = await this.httpClient.post('/contracts/solidity-detector', request, {
209
+ timeout: options?.timeout,
210
+ signal: options?.signal,
211
+ });
212
+ return response.data;
213
+ }
214
+ }
215
+ exports.ContractsResource = ContractsResource;
216
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/resources/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UsageResource = exports.AccountTraceResource = exports.LedgerResource = exports.WalletsResource = exports.UrlResource = exports.ContractsResource = exports.AddressesResource = void 0;
4
+ var addresses_1 = require("./addresses");
5
+ Object.defineProperty(exports, "AddressesResource", { enumerable: true, get: function () { return addresses_1.AddressesResource; } });
6
+ var contracts_1 = require("./contracts");
7
+ Object.defineProperty(exports, "ContractsResource", { enumerable: true, get: function () { return contracts_1.ContractsResource; } });
8
+ var url_1 = require("./url");
9
+ Object.defineProperty(exports, "UrlResource", { enumerable: true, get: function () { return url_1.UrlResource; } });
10
+ var wallets_1 = require("./wallets");
11
+ Object.defineProperty(exports, "WalletsResource", { enumerable: true, get: function () { return wallets_1.WalletsResource; } });
12
+ var ledger_1 = require("./ledger");
13
+ Object.defineProperty(exports, "LedgerResource", { enumerable: true, get: function () { return ledger_1.LedgerResource; } });
14
+ var account_trace_1 = require("./account-trace");
15
+ Object.defineProperty(exports, "AccountTraceResource", { enumerable: true, get: function () { return account_trace_1.AccountTraceResource; } });
16
+ var usage_1 = require("./usage");
17
+ Object.defineProperty(exports, "UsageResource", { enumerable: true, get: function () { return usage_1.UsageResource; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/resources/index.ts"],"names":[],"mappings":";;;AAAA,yCAAgD;AAAvC,8GAAA,iBAAiB,OAAA;AAC1B,yCAAgD;AAAvC,8GAAA,iBAAiB,OAAA;AAC1B,6BAAoC;AAA3B,kGAAA,WAAW,OAAA;AACpB,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AACxB,mCAA0C;AAAjC,wGAAA,cAAc,OAAA;AACvB,iDAAuD;AAA9C,qHAAA,oBAAoB,OAAA;AAC7B,iCAAwC;AAA/B,sGAAA,aAAa,OAAA"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LedgerResource = void 0;
4
+ /**
5
+ * Resource for hardware wallet transaction scanning
6
+ *
7
+ * Provides security analysis for transactions before signing on
8
+ * hardware wallets (Ledger devices).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Scan a transaction before signing
13
+ * const result = await client.ledger.scanTransaction('ethereum', {
14
+ * tx: { from: '0x...', raw: '0x...' },
15
+ * chain: 1,
16
+ * });
17
+ *
18
+ * if (!result.is_safe) {
19
+ * console.error('Transaction may be risky!');
20
+ * }
21
+ * ```
22
+ */
23
+ class LedgerResource {
24
+ httpClient;
25
+ constructor(httpClient) {
26
+ this.httpClient = httpClient;
27
+ }
28
+ /**
29
+ * Scan a transaction before signing
30
+ *
31
+ * Analyzes a transaction for security risks before signing
32
+ * on a hardware wallet.
33
+ *
34
+ * @param family - Ledger device family (ethereum, solana, bitcoin)
35
+ * @param request - Transaction scan request
36
+ * @param options - Request options
37
+ * @returns Security analysis result
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const result = await client.ledger.scanTransaction('ethereum', {
42
+ * tx: {
43
+ * from: '0xYourWallet...',
44
+ * raw: '0xEncodedTransaction...',
45
+ * },
46
+ * chain: 1, // Ethereum mainnet
47
+ * });
48
+ *
49
+ * if (!result.is_safe) {
50
+ * console.error(`Risk level: ${result.risk_level}`);
51
+ * for (const risk of result.risks) {
52
+ * console.warn(`${risk.level}: ${risk.description}`);
53
+ * }
54
+ * }
55
+ *
56
+ * // Check decoded data
57
+ * if (result.decoded?.function_name) {
58
+ * console.log(`Function: ${result.decoded.function_name}`);
59
+ * }
60
+ * ```
61
+ */
62
+ async scanTransaction(family, request, options) {
63
+ const response = await this.httpClient.post(`/ledger/${family}/scan/tx`, request, {
64
+ timeout: options?.timeout,
65
+ signal: options?.signal,
66
+ });
67
+ return response.data;
68
+ }
69
+ /**
70
+ * Scan EIP-712 typed data before signing
71
+ *
72
+ * Analyzes EIP-712 structured data for security risks
73
+ * before signing on a hardware wallet.
74
+ *
75
+ * @param family - Ledger device family
76
+ * @param request - EIP-712 scan request
77
+ * @param options - Request options
78
+ * @returns Security analysis result
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const result = await client.ledger.scanEip712('ethereum', {
83
+ * signer: '0xYourWallet...',
84
+ * typedData: {
85
+ * domain: {
86
+ * name: 'MyDApp',
87
+ * version: '1',
88
+ * chainId: 1,
89
+ * verifyingContract: '0x...',
90
+ * },
91
+ * message: {
92
+ * // Message content
93
+ * },
94
+ * primaryType: 'Order',
95
+ * types: {
96
+ * EIP712Domain: [
97
+ * { name: 'name', type: 'string' },
98
+ * // ...
99
+ * ],
100
+ * Order: [
101
+ * { name: 'maker', type: 'address' },
102
+ * // ...
103
+ * ],
104
+ * },
105
+ * },
106
+ * chain: 1,
107
+ * });
108
+ *
109
+ * if (!result.is_safe) {
110
+ * console.error('EIP-712 data may be risky!');
111
+ * }
112
+ * ```
113
+ */
114
+ async scanEip712(family, request, options) {
115
+ const response = await this.httpClient.post(`/ledger/${family}/scan/eip-712`, request, {
116
+ timeout: options?.timeout,
117
+ signal: options?.signal,
118
+ });
119
+ return response.data;
120
+ }
121
+ }
122
+ exports.LedgerResource = LedgerResource;
123
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../../src/resources/ledger.ts"],"names":[],"mappings":";;;AASA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAa,cAAc;IACI;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,KAAK,CAAC,eAAe,CACnB,MAAoB,EACpB,OAA0B,EAC1B,OAA2B;QAE3B,MAAM,QAAQ,GAAqC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAC3E,WAAW,MAAM,UAAU,EAC3B,OAAO,EACP;YACE,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4CG;IACH,KAAK,CAAC,UAAU,CACd,MAAoB,EACpB,OAA4B,EAC5B,OAA2B;QAE3B,MAAM,QAAQ,GAAqC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAC3E,WAAW,MAAM,eAAe,EAChC,OAAO,EACP;YACE,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF;AAnHD,wCAmHC"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UrlResource = void 0;
4
+ /**
5
+ * Resource for URL safety analysis
6
+ *
7
+ * Provides URL risk assessment to identify phishing sites,
8
+ * malicious domains, and other web-based threats.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const result = await client.url.check('https://suspicious-site.com');
13
+ * if (result.prediction === 'malicious') {
14
+ * console.warn('URL is malicious!');
15
+ * }
16
+ * ```
17
+ */
18
+ class UrlResource {
19
+ httpClient;
20
+ constructor(httpClient) {
21
+ this.httpClient = httpClient;
22
+ }
23
+ /**
24
+ * Check if a URL is safe
25
+ *
26
+ * Analyzes a URL for phishing, malware, and other threats.
27
+ *
28
+ * @param url - URL to check
29
+ * @param options - Request options
30
+ * @returns URL safety analysis result
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const result = await client.url.check('https://example.com');
35
+ *
36
+ * if (result.prediction === 'malicious') {
37
+ * console.error('URL is potentially dangerous!');
38
+ * console.log('Details:', result.details);
39
+ * } else if (result.prediction === 'benign') {
40
+ * console.log('URL appears safe');
41
+ * }
42
+ *
43
+ * // Check blacklist/whitelist status
44
+ * if (result.blacklist === 'true') {
45
+ * console.error('URL is blacklisted');
46
+ * }
47
+ * if (result.whitelist === 'true') {
48
+ * console.log('URL is whitelisted');
49
+ * }
50
+ * ```
51
+ */
52
+ async check(url, options) {
53
+ const response = await this.httpClient.post('/url', { url }, {
54
+ timeout: options?.timeout,
55
+ signal: options?.signal,
56
+ });
57
+ return response.data;
58
+ }
59
+ /**
60
+ * Add a URL to the database
61
+ *
62
+ * Report a URL to be analyzed and added to the threat database.
63
+ *
64
+ * @param url - URL to add
65
+ * @param options - Request options
66
+ * @returns Addition result
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const result = await client.url.add('https://phishing-site.com');
71
+ * if (result.success) {
72
+ * console.log('URL reported successfully');
73
+ * }
74
+ * ```
75
+ */
76
+ async add(url, options) {
77
+ const response = await this.httpClient.post('/url/add', { url }, {
78
+ timeout: options?.timeout,
79
+ signal: options?.signal,
80
+ });
81
+ return response.data;
82
+ }
83
+ }
84
+ exports.UrlResource = UrlResource;
85
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../../src/resources/url.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;GAaG;AACH,MAAa,WAAW;IACO;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,OAAyB;QAChD,MAAM,QAAQ,GAAkC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CACxE,MAAM,EACN,EAAE,GAAG,EAAE,EACP;YACE,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,OAAyB;QAC9C,MAAM,QAAQ,GAAiC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CACvE,UAAU,EACV,EAAE,GAAG,EAAE,EACP;YACE,OAAO,EAAE,OAAO,EAAE,OAAO;YACzB,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF;AA1ED,kCA0EC"}