@m2msentinel/sdk 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -9
- package/agent_adapter.js +31 -3
- package/eliza_plugin.js +7 -2
- package/index.d.ts +113 -94
- package/index.js +192 -187
- package/m2m_sentinel_sdk.js +1 -1
- package/mcp_server.js +492 -223
- package/package.json +6 -3
- package/typescript/index.ts +218 -204
- package/typescript/package.json +2 -2
- package/typescript/x402.ts +265 -0
- package/x402_signer.js +243 -0
package/index.js
CHANGED
|
@@ -1,187 +1,192 @@
|
|
|
1
|
-
const DEFAULT_BASE_URL = 'https://api.m2msentinel.com';
|
|
2
|
-
const DEFAULT_TIMEOUT_MS = 30000;
|
|
3
|
-
|
|
4
|
-
class M2MSentinelError extends Error {
|
|
5
|
-
constructor(message, options = {}) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.name = this.constructor.name;
|
|
8
|
-
this.status = options.status;
|
|
9
|
-
this.body = options.body;
|
|
10
|
-
this.retryAfter = options.retryAfter || null;
|
|
11
|
-
this.paymentRequired = options.paymentRequired || null;
|
|
12
|
-
this.paymentResponse = options.paymentResponse || null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
class PaymentRequiredError extends M2MSentinelError {}
|
|
17
|
-
class RateLimitedError extends M2MSentinelError {}
|
|
18
|
-
class DataSourceUnavailableError extends M2MSentinelError {}
|
|
19
|
-
|
|
20
|
-
function parseX402Header(value) {
|
|
21
|
-
if (!value) return null;
|
|
22
|
-
// x402 v2 transports protocol objects as base64 JSON. Retain raw-JSON
|
|
23
|
-
// compatibility for older M2M Sentinel deployments during upgrades.
|
|
24
|
-
try { return JSON.parse(value); } catch (_) { /* try v2 encoding */ }
|
|
25
|
-
try {
|
|
26
|
-
const normalized = String(value).replace(/-/g, '+').replace(/_/g, '/');
|
|
27
|
-
const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);
|
|
28
|
-
return JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));
|
|
29
|
-
} catch (_) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function normalizeOptions(optionsOrApiKey, baseUrl) {
|
|
35
|
-
if (optionsOrApiKey && typeof optionsOrApiKey === 'object') return { ...optionsOrApiKey };
|
|
36
|
-
return { apiKey: optionsOrApiKey || undefined, baseUrl: baseUrl || DEFAULT_BASE_URL };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
class M2MSentinelClient {
|
|
40
|
-
constructor(optionsOrApiKey, baseUrl) {
|
|
41
|
-
const options = normalizeOptions(optionsOrApiKey, baseUrl);
|
|
42
|
-
this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
43
|
-
this.apiKey = options.apiKey || undefined;
|
|
44
|
-
this.timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS;
|
|
45
|
-
this.paymentSignature = options.paymentSignature || undefined;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async request(method, path, body, options = {}) {
|
|
49
|
-
const headers = {
|
|
50
|
-
'Accept': 'application/json'
|
|
51
|
-
};
|
|
52
|
-
if (body !== undefined) headers['Content-Type'] = 'application/json';
|
|
53
|
-
const apiKey = options.apiKey || this.apiKey;
|
|
54
|
-
if (apiKey) headers['x-api-key'] = apiKey;
|
|
55
|
-
if (options.operatorToken) headers.Authorization = 'Bearer ' + options.operatorToken;
|
|
56
|
-
const paymentSignature = options.paymentSignature || this.paymentSignature;
|
|
57
|
-
if (paymentSignature) headers['PAYMENT-SIGNATURE'] = paymentSignature;
|
|
58
|
-
|
|
59
|
-
const controller = new AbortController();
|
|
60
|
-
const timeout = setTimeout(() => controller.abort(), options.timeoutMs || this.timeoutMs);
|
|
61
|
-
let response;
|
|
62
|
-
try {
|
|
63
|
-
response = await fetch(this.baseUrl + path, {
|
|
64
|
-
method,
|
|
65
|
-
headers,
|
|
66
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
67
|
-
signal: controller.signal
|
|
68
|
-
});
|
|
69
|
-
} catch (err) {
|
|
70
|
-
if (err && err.name === 'AbortError') throw new M2MSentinelError('M2M Sentinel request timed out', { status: 0 });
|
|
71
|
-
throw err;
|
|
72
|
-
} finally {
|
|
73
|
-
clearTimeout(timeout);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const text = await response.text();
|
|
77
|
-
let data = null;
|
|
78
|
-
if (text) {
|
|
79
|
-
try { data = JSON.parse(text); } catch (_) { data = { raw: text }; }
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const paymentRequired = parseX402Header(response.headers.get('PAYMENT-REQUIRED'));
|
|
83
|
-
const paymentResponse = parseX402Header(response.headers.get('PAYMENT-RESPONSE')) || response.headers.get('PAYMENT-RESPONSE');
|
|
84
|
-
if (response.ok) return data;
|
|
85
|
-
|
|
86
|
-
const details = {
|
|
87
|
-
status: response.status,
|
|
88
|
-
body: data,
|
|
89
|
-
retryAfter: response.headers.get('Retry-After'),
|
|
90
|
-
paymentRequired,
|
|
91
|
-
paymentResponse
|
|
92
|
-
};
|
|
93
|
-
const message = data && data.message ? data.message : 'M2M Sentinel HTTP ' + response.status;
|
|
94
|
-
if (response.status === 402) throw new PaymentRequiredError(message, details);
|
|
95
|
-
if (response.status === 429) throw new RateLimitedError(message, details);
|
|
96
|
-
if (response.status === 503 && data && data.error === 'DATA_SOURCE_UNAVAILABLE') throw new DataSourceUnavailableError(message, details);
|
|
97
|
-
throw new M2MSentinelError(message, details);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
getStatus() { return this.request('GET', '/v1/status'); }
|
|
101
|
-
getPublicStats(days = 30) { return this.request('GET', '/v1/stats?days=' + encodeURIComponent(days)); }
|
|
102
|
-
// Backward-compatible alias. Ordinary/customer credentials still receive
|
|
103
|
-
// only the counter-free public privacy envelope.
|
|
104
|
-
getAggregateStats(days = 30) { return this.getPublicStats(days); }
|
|
105
|
-
getOperatorAggregateStats(days, operatorToken) {
|
|
106
|
-
return this.request('GET', '/v1/stats?days=' + encodeURIComponent(days || 30), undefined, { operatorToken });
|
|
107
|
-
}
|
|
108
|
-
getPlans() { return this.request('GET', '/v1/plans'); }
|
|
109
|
-
demoAudit(address) { return this.request('GET', '/v1/demo/audit/' + encodeURIComponent(address)); }
|
|
110
|
-
createFreeChallenge(userWallet) { return this.request('POST', '/v1/subscribe/free/challenge', { userWallet }); }
|
|
111
|
-
claimFreeTier(intentId, signature) { return this.request('POST', '/v1/subscribe/free/claim', { intentId, signature }); }
|
|
112
|
-
createSubscriptionIntent(tier, userWallet, options = {}) {
|
|
113
|
-
const body = { tier, userWallet };
|
|
114
|
-
if (options.durationDays !== undefined) body.durationDays = options.durationDays;
|
|
115
|
-
if (options.renewExistingKey !== undefined) body.renewExistingKey = options.renewExistingKey;
|
|
116
|
-
return this.request('POST', '/v1/subscribe/intents', body, options);
|
|
117
|
-
}
|
|
118
|
-
claimSubscription(intentId, signature, txHash) { return this.request('POST', '/v1/subscribe/crypto', { intentId, signature, txHash }); }
|
|
119
|
-
createRecoveryChallenge(userWallet, options = {}) {
|
|
120
|
-
const body = { userWallet };
|
|
121
|
-
if (options.txHash !== undefined) body.txHash = options.txHash;
|
|
122
|
-
return this.request('POST', '/v1/keys/recovery/challenge', body);
|
|
123
|
-
}
|
|
124
|
-
claimRecoveredKey(intentId, signature) {
|
|
125
|
-
return this.request('POST', '/v1/keys/recovery/claim', { intentId, signature });
|
|
126
|
-
}
|
|
127
|
-
auditContract(address, options) { return this.request('GET', '/v1/audit/' + encodeURIComponent(address), undefined, options); }
|
|
128
|
-
getCapabilityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
|
|
129
|
-
// Legacy method name; the response is a capability coverage index, not a safety score.
|
|
130
|
-
getSecurityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
|
|
131
|
-
getGasFees(options) { return this.request('GET', '/v1/gas/fees', undefined, options); }
|
|
132
|
-
getDexMetrics(options) { return this.request('GET', '/v1/dex/metrics', undefined, options); }
|
|
133
|
-
getTokenPrice(symbol, options) { return this.request('GET', '/v1/token/price/' + encodeURIComponent(symbol), undefined, options); }
|
|
134
|
-
getWhaleSignals(options) { return this.request('GET', '/v1/whales/signals', undefined, options); }
|
|
135
|
-
getKeySelf() { return this.request('GET', '/v1/keys/self'); }
|
|
136
|
-
revokeKey(confirm = true) { return this.request('POST', '/v1/keys/revoke', { confirm }); }
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async function enforceCallerPolicy(policy, analysis, context) {
|
|
140
|
-
if (typeof policy !== 'function') {
|
|
141
|
-
throw new Error('[M2M Sentinel] A caller-defined policy function is required. Static capability observations are not a safety decision.');
|
|
142
|
-
}
|
|
143
|
-
const result = await policy(analysis, context);
|
|
144
|
-
if (result === false || (result && result.allow === false)) {
|
|
145
|
-
const reason = result && result.reason ? result.reason : 'caller-defined policy rejected the transaction';
|
|
146
|
-
throw new Error('[M2M Sentinel] Transaction blocked: ' + reason + '.');
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function createEthersSentinelMiddleware(apiKey, baseUrl, policy) {
|
|
151
|
-
const client = new M2MSentinelClient({ apiKey, baseUrl });
|
|
152
|
-
return {
|
|
153
|
-
client,
|
|
154
|
-
verifyContractBeforeTx: async (targetAddress, policyOverride) => {
|
|
155
|
-
const audit = await client.auditContract(targetAddress);
|
|
156
|
-
await enforceCallerPolicy(policyOverride || policy, audit, { targetAddress, integration: 'ethers' });
|
|
157
|
-
return audit;
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function createViemSentinelInterceptor(apiKey, baseUrl, policy) {
|
|
163
|
-
const client = new M2MSentinelClient({ apiKey, baseUrl });
|
|
164
|
-
return {
|
|
165
|
-
client,
|
|
166
|
-
inspectSwapTarget: async (address, policyOverride) => {
|
|
167
|
-
const analysis = await client.getCapabilityScore(address);
|
|
168
|
-
await enforceCallerPolicy(policyOverride || policy, analysis, { targetAddress: address, integration: 'viem' });
|
|
169
|
-
return analysis;
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const { M2MSentinelActionProvider, m2mSentinelActionProvider } = require('./agent_adapter.js');
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
1
|
+
const DEFAULT_BASE_URL = 'https://api.m2msentinel.com';
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
3
|
+
|
|
4
|
+
class M2MSentinelError extends Error {
|
|
5
|
+
constructor(message, options = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = this.constructor.name;
|
|
8
|
+
this.status = options.status;
|
|
9
|
+
this.body = options.body;
|
|
10
|
+
this.retryAfter = options.retryAfter || null;
|
|
11
|
+
this.paymentRequired = options.paymentRequired || null;
|
|
12
|
+
this.paymentResponse = options.paymentResponse || null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
class PaymentRequiredError extends M2MSentinelError {}
|
|
17
|
+
class RateLimitedError extends M2MSentinelError {}
|
|
18
|
+
class DataSourceUnavailableError extends M2MSentinelError {}
|
|
19
|
+
|
|
20
|
+
function parseX402Header(value) {
|
|
21
|
+
if (!value) return null;
|
|
22
|
+
// x402 v2 transports protocol objects as base64 JSON. Retain raw-JSON
|
|
23
|
+
// compatibility for older M2M Sentinel deployments during upgrades.
|
|
24
|
+
try { return JSON.parse(value); } catch (_) { /* try v2 encoding */ }
|
|
25
|
+
try {
|
|
26
|
+
const normalized = String(value).replace(/-/g, '+').replace(/_/g, '/');
|
|
27
|
+
const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);
|
|
28
|
+
return JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));
|
|
29
|
+
} catch (_) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeOptions(optionsOrApiKey, baseUrl) {
|
|
35
|
+
if (optionsOrApiKey && typeof optionsOrApiKey === 'object') return { ...optionsOrApiKey };
|
|
36
|
+
return { apiKey: optionsOrApiKey || undefined, baseUrl: baseUrl || DEFAULT_BASE_URL };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class M2MSentinelClient {
|
|
40
|
+
constructor(optionsOrApiKey, baseUrl) {
|
|
41
|
+
const options = normalizeOptions(optionsOrApiKey, baseUrl);
|
|
42
|
+
this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
43
|
+
this.apiKey = options.apiKey || undefined;
|
|
44
|
+
this.timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS;
|
|
45
|
+
this.paymentSignature = options.paymentSignature || undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async request(method, path, body, options = {}) {
|
|
49
|
+
const headers = {
|
|
50
|
+
'Accept': 'application/json'
|
|
51
|
+
};
|
|
52
|
+
if (body !== undefined) headers['Content-Type'] = 'application/json';
|
|
53
|
+
const apiKey = options.apiKey || this.apiKey;
|
|
54
|
+
if (apiKey) headers['x-api-key'] = apiKey;
|
|
55
|
+
if (options.operatorToken) headers.Authorization = 'Bearer ' + options.operatorToken;
|
|
56
|
+
const paymentSignature = options.paymentSignature || this.paymentSignature;
|
|
57
|
+
if (paymentSignature) headers['PAYMENT-SIGNATURE'] = paymentSignature;
|
|
58
|
+
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timeout = setTimeout(() => controller.abort(), options.timeoutMs || this.timeoutMs);
|
|
61
|
+
let response;
|
|
62
|
+
try {
|
|
63
|
+
response = await fetch(this.baseUrl + path, {
|
|
64
|
+
method,
|
|
65
|
+
headers,
|
|
66
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
67
|
+
signal: controller.signal
|
|
68
|
+
});
|
|
69
|
+
} catch (err) {
|
|
70
|
+
if (err && err.name === 'AbortError') throw new M2MSentinelError('M2M Sentinel request timed out', { status: 0 });
|
|
71
|
+
throw err;
|
|
72
|
+
} finally {
|
|
73
|
+
clearTimeout(timeout);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const text = await response.text();
|
|
77
|
+
let data = null;
|
|
78
|
+
if (text) {
|
|
79
|
+
try { data = JSON.parse(text); } catch (_) { data = { raw: text }; }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const paymentRequired = parseX402Header(response.headers.get('PAYMENT-REQUIRED'));
|
|
83
|
+
const paymentResponse = parseX402Header(response.headers.get('PAYMENT-RESPONSE')) || response.headers.get('PAYMENT-RESPONSE');
|
|
84
|
+
if (response.ok) return data;
|
|
85
|
+
|
|
86
|
+
const details = {
|
|
87
|
+
status: response.status,
|
|
88
|
+
body: data,
|
|
89
|
+
retryAfter: response.headers.get('Retry-After'),
|
|
90
|
+
paymentRequired,
|
|
91
|
+
paymentResponse
|
|
92
|
+
};
|
|
93
|
+
const message = data && data.message ? data.message : 'M2M Sentinel HTTP ' + response.status;
|
|
94
|
+
if (response.status === 402) throw new PaymentRequiredError(message, details);
|
|
95
|
+
if (response.status === 429) throw new RateLimitedError(message, details);
|
|
96
|
+
if (response.status === 503 && data && data.error === 'DATA_SOURCE_UNAVAILABLE') throw new DataSourceUnavailableError(message, details);
|
|
97
|
+
throw new M2MSentinelError(message, details);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
getStatus() { return this.request('GET', '/v1/status'); }
|
|
101
|
+
getPublicStats(days = 30) { return this.request('GET', '/v1/stats?days=' + encodeURIComponent(days)); }
|
|
102
|
+
// Backward-compatible alias. Ordinary/customer credentials still receive
|
|
103
|
+
// only the counter-free public privacy envelope.
|
|
104
|
+
getAggregateStats(days = 30) { return this.getPublicStats(days); }
|
|
105
|
+
getOperatorAggregateStats(days, operatorToken) {
|
|
106
|
+
return this.request('GET', '/v1/stats?days=' + encodeURIComponent(days || 30), undefined, { operatorToken });
|
|
107
|
+
}
|
|
108
|
+
getPlans() { return this.request('GET', '/v1/plans'); }
|
|
109
|
+
demoAudit(address) { return this.request('GET', '/v1/demo/audit/' + encodeURIComponent(address)); }
|
|
110
|
+
createFreeChallenge(userWallet) { return this.request('POST', '/v1/subscribe/free/challenge', { userWallet }); }
|
|
111
|
+
claimFreeTier(intentId, signature) { return this.request('POST', '/v1/subscribe/free/claim', { intentId, signature }); }
|
|
112
|
+
createSubscriptionIntent(tier, userWallet, options = {}) {
|
|
113
|
+
const body = { tier, userWallet };
|
|
114
|
+
if (options.durationDays !== undefined) body.durationDays = options.durationDays;
|
|
115
|
+
if (options.renewExistingKey !== undefined) body.renewExistingKey = options.renewExistingKey;
|
|
116
|
+
return this.request('POST', '/v1/subscribe/intents', body, options);
|
|
117
|
+
}
|
|
118
|
+
claimSubscription(intentId, signature, txHash) { return this.request('POST', '/v1/subscribe/crypto', { intentId, signature, txHash }); }
|
|
119
|
+
createRecoveryChallenge(userWallet, options = {}) {
|
|
120
|
+
const body = { userWallet };
|
|
121
|
+
if (options.txHash !== undefined) body.txHash = options.txHash;
|
|
122
|
+
return this.request('POST', '/v1/keys/recovery/challenge', body);
|
|
123
|
+
}
|
|
124
|
+
claimRecoveredKey(intentId, signature) {
|
|
125
|
+
return this.request('POST', '/v1/keys/recovery/claim', { intentId, signature });
|
|
126
|
+
}
|
|
127
|
+
auditContract(address, options) { return this.request('GET', '/v1/audit/' + encodeURIComponent(address), undefined, options); }
|
|
128
|
+
getCapabilityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
|
|
129
|
+
// Legacy method name; the response is a capability coverage index, not a safety score.
|
|
130
|
+
getSecurityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
|
|
131
|
+
getGasFees(options) { return this.request('GET', '/v1/gas/fees', undefined, options); }
|
|
132
|
+
getDexMetrics(options) { return this.request('GET', '/v1/dex/metrics', undefined, options); }
|
|
133
|
+
getTokenPrice(symbol, options) { return this.request('GET', '/v1/token/price/' + encodeURIComponent(symbol), undefined, options); }
|
|
134
|
+
getWhaleSignals(options) { return this.request('GET', '/v1/whales/signals', undefined, options); }
|
|
135
|
+
getKeySelf() { return this.request('GET', '/v1/keys/self'); }
|
|
136
|
+
revokeKey(confirm = true) { return this.request('POST', '/v1/keys/revoke', { confirm }); }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function enforceCallerPolicy(policy, analysis, context) {
|
|
140
|
+
if (typeof policy !== 'function') {
|
|
141
|
+
throw new Error('[M2M Sentinel] A caller-defined policy function is required. Static capability observations are not a safety decision.');
|
|
142
|
+
}
|
|
143
|
+
const result = await policy(analysis, context);
|
|
144
|
+
if (result === false || (result && result.allow === false)) {
|
|
145
|
+
const reason = result && result.reason ? result.reason : 'caller-defined policy rejected the transaction';
|
|
146
|
+
throw new Error('[M2M Sentinel] Transaction blocked: ' + reason + '.');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function createEthersSentinelMiddleware(apiKey, baseUrl, policy) {
|
|
151
|
+
const client = new M2MSentinelClient({ apiKey, baseUrl });
|
|
152
|
+
return {
|
|
153
|
+
client,
|
|
154
|
+
verifyContractBeforeTx: async (targetAddress, policyOverride) => {
|
|
155
|
+
const audit = await client.auditContract(targetAddress);
|
|
156
|
+
await enforceCallerPolicy(policyOverride || policy, audit, { targetAddress, integration: 'ethers' });
|
|
157
|
+
return audit;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function createViemSentinelInterceptor(apiKey, baseUrl, policy) {
|
|
163
|
+
const client = new M2MSentinelClient({ apiKey, baseUrl });
|
|
164
|
+
return {
|
|
165
|
+
client,
|
|
166
|
+
inspectSwapTarget: async (address, policyOverride) => {
|
|
167
|
+
const analysis = await client.getCapabilityScore(address);
|
|
168
|
+
await enforceCallerPolicy(policyOverride || policy, analysis, { targetAddress: address, integration: 'viem' });
|
|
169
|
+
return analysis;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const { M2MSentinelActionProvider, m2mSentinelActionProvider } = require('./agent_adapter.js');
|
|
175
|
+
const { X402SignerClient, x402SignerClient, parsePaymentHeader, parsePriceToUnits } = require('./x402_signer.js');
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
M2MSentinelClient,
|
|
179
|
+
M2MSentinelError,
|
|
180
|
+
PaymentRequiredError,
|
|
181
|
+
RateLimitedError,
|
|
182
|
+
DataSourceUnavailableError,
|
|
183
|
+
enforceCallerPolicy,
|
|
184
|
+
createEthersSentinelMiddleware,
|
|
185
|
+
createViemSentinelInterceptor,
|
|
186
|
+
M2MSentinelActionProvider,
|
|
187
|
+
m2mSentinelActionProvider,
|
|
188
|
+
X402SignerClient,
|
|
189
|
+
x402SignerClient,
|
|
190
|
+
parsePaymentHeader,
|
|
191
|
+
parsePriceToUnits
|
|
192
|
+
};
|
package/m2m_sentinel_sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require('./index.js');
|
|
1
|
+
module.exports = require('./index.js');
|