@m2msentinel/sdk 1.2.1 → 1.2.3

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 CHANGED
@@ -40,13 +40,13 @@ Autonomous agents handling value must never rely on a single oracle or heuristic
40
40
  npm install @m2msentinel/sdk
41
41
 
42
42
  # Or unscoped package
43
- npm install m2m-sentinel-sdk@1.2.1
43
+ npm install m2m-sentinel-sdk@1.2.3
44
44
  ```
45
45
 
46
46
  ### Python (PyPI)
47
47
 
48
48
  ```bash
49
- pip install m2m-sentinel==1.2.1
49
+ pip install m2m-sentinel==1.2.3
50
50
  ```
51
51
 
52
52
  ### MCP Server (Model Context Protocol)
@@ -77,6 +77,17 @@ console.log('Capability evidence:', audit.audit.dissection.capabilities);
77
77
  console.log('Proxy Target:', audit.audit.proxyResolution.targetAddress);
78
78
  console.log('Reachability:', audit.audit.reachability || 'NOT_ESTABLISHED');
79
79
 
80
+ // Transaction-specific observation before a caller-owned signing decision.
81
+ const preflight = await client.preflightTransaction({
82
+ chainId: 8453,
83
+ to: '0x1111111111111111111111111111111111111111',
84
+ data: '0x40c10f19'
85
+ });
86
+ console.log('Selector:', preflight.selectorHex);
87
+ console.log('Executing target:', preflight.resolvedExecutionTarget);
88
+ console.log('Observation block:', preflight.observationBlock.blockNumber);
89
+ // The caller must apply its own policy; M2M Sentinel does not return a safety verdict.
90
+
80
91
  // 2. Autonomous Headless x402 Micropayments (EIP-3009 Local Signing)
81
92
  const x402Client = new X402SignerClient({
82
93
  walletSigner: myAgentWallet, // ethers / viem signer
@@ -115,7 +126,7 @@ const signer = new X402SignerClient({
115
126
 
116
127
  ## Authentication and x402
117
128
 
118
- Send API keys only in `x-api-key` (or `Authorization: Bearer`). Query-string credentials are rejected with HTTP 401. Payable routes also support x402 v2 on Base USDC. An unpaid call returns a base64 `PAYMENT-REQUIRED` challenge; a successful settlement returns `PAYMENT-RESPONSE`.
129
+ Send API keys only in `x-api-key` (or `Authorization: Bearer`). Query-string credentials are rejected with HTTP 401. Payable routes also support x402 v2 on Base USDC. An unpaid call returns a base64 `PAYMENT-REQUIRED` challenge; a successful settlement returns `PAYMENT-RESPONSE`. `POST /v1/transaction/preflight` is API-key/RapidAPI metered and is deliberately not in the x402 catalog; it has no x402 price.
119
130
 
120
131
  ---
121
132
 
@@ -126,6 +137,7 @@ Send API keys only in `x-api-key` (or `Authorization: Bearer`). Query-string cre
126
137
  - `GET /v1/plans`
127
138
  - `GET /v1/demo/audit/:address` for the published sample allowlist
128
139
  - `GET /v1/audit/:address` (requires API key or x402 payment)
140
+ - `POST /v1/transaction/preflight` (requires an API key or verified RapidAPI proxy authentication; not x402-payable)
129
141
 
130
142
  The JavaScript, TypeScript, and Python clients expose multi-period purchase/renewal and wallet recovery without requiring callers to hand-build requests:
131
143
 
package/agent_adapter.js CHANGED
@@ -67,7 +67,7 @@ class M2MSentinelActionProvider {
67
67
 
68
68
  const headers = {
69
69
  Accept: 'application/json',
70
- 'User-Agent': 'M2MSentinel-AgentKit/1.2.1',
70
+ 'User-Agent': 'M2MSentinel-AgentKit/1.2.3',
71
71
  ...options.headers
72
72
  };
73
73
  if (this.apiKey && !headers['x-api-key']) {
package/index.d.ts CHANGED
@@ -14,6 +14,15 @@ export interface RecoveryChallengeOptions {
14
14
  txHash?: string;
15
15
  }
16
16
 
17
+ export interface TransactionPreflightRequest {
18
+ chainId: number | string;
19
+ to: string;
20
+ data: string;
21
+ from?: string;
22
+ value?: number | string;
23
+ blockNumber?: number | string;
24
+ }
25
+
17
26
  export interface M2MSentinelErrorOptions {
18
27
  status?: number;
19
28
  body?: unknown;
@@ -56,6 +65,7 @@ export class M2MSentinelClient {
56
65
  getCapabilityScore(address: string, options?: M2MSentinelClientOptions): Promise<any>;
57
66
  /** Legacy alias. The response is a capability coverage index, not a safety score. */
58
67
  getSecurityScore(address: string, options?: M2MSentinelClientOptions): Promise<any>;
68
+ preflightTransaction(transaction: TransactionPreflightRequest, options?: M2MSentinelClientOptions): Promise<any>;
59
69
  getGasFees(options?: M2MSentinelClientOptions): Promise<any>;
60
70
  getDexMetrics(options?: M2MSentinelClientOptions): Promise<any>;
61
71
  getTokenPrice(symbol: string, options?: M2MSentinelClientOptions): Promise<any>;
package/index.js CHANGED
@@ -128,6 +128,9 @@ class M2MSentinelClient {
128
128
  getCapabilityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
129
129
  // Legacy method name; the response is a capability coverage index, not a safety score.
130
130
  getSecurityScore(address, options) { return this.request('GET', '/v1/security/score/' + encodeURIComponent(address), undefined, options); }
131
+ preflightTransaction(transaction, options) {
132
+ return this.request('POST', '/v1/transaction/preflight', transaction, options);
133
+ }
131
134
  getGasFees(options) { return this.request('GET', '/v1/gas/fees', undefined, options); }
132
135
  getDexMetrics(options) { return this.request('GET', '/v1/dex/metrics', undefined, options); }
133
136
  getTokenPrice(symbol, options) { return this.request('GET', '/v1/token/price/' + encodeURIComponent(symbol), undefined, options); }
package/mcp_server.js CHANGED
@@ -8,7 +8,7 @@ const readline = require('readline');
8
8
  let BASE_URL = process.env.M2M_SENTINEL_BASE_URL || 'https://api.m2msentinel.com';
9
9
  let API_KEY = process.env.M2M_SENTINEL_API_KEY || '';
10
10
  const TIMEOUT_MS = Number(process.env.M2M_SENTINEL_TIMEOUT_MS || 30000);
11
- const VERSION = '1.2.1';
11
+ const VERSION = '1.2.3';
12
12
 
13
13
  const TOOLS = [
14
14
  {
@@ -387,7 +387,7 @@ async function runCli(args) {
387
387
  console.log(`Network: Base Mainnet (8453)`);
388
388
  console.log(`Latency: ${res.latencyMs}ms`);
389
389
  console.log('================================================================');
390
-
390
+
391
391
  const proxy = auditObj.proxyResolution || auditObj.proxy || {};
392
392
  const isProxy = !!proxy.isProxy;
393
393
  if (isProxy) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m2msentinel/sdk",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "mcpName": "io.github.M2M-Sentinel/m2m-sentinel-sdk",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,6 +18,15 @@ export interface RecoveryChallengeOptions {
18
18
  txHash?: string;
19
19
  }
20
20
 
21
+ export interface TransactionPreflightRequest {
22
+ chainId: number | string;
23
+ to: string;
24
+ data: string;
25
+ from?: string;
26
+ value?: number | string;
27
+ blockNumber?: number | string;
28
+ }
29
+
21
30
  export interface M2MSentinelErrorOptions {
22
31
  status?: number;
23
32
  body?: any;
@@ -155,6 +164,7 @@ export class M2MSentinelClient {
155
164
  public getCapabilityScore(address: string, options?: M2MSentinelClientOptions) { return this.request<any>('GET', `/v1/security/score/${encodeURIComponent(address)}`, undefined, options); }
156
165
  /** Legacy name. The response is a capability coverage index, not a safety score. */
157
166
  public getSecurityScore(address: string, options?: M2MSentinelClientOptions) { return this.request<any>('GET', `/v1/security/score/${encodeURIComponent(address)}`, undefined, options); }
167
+ public preflightTransaction(transaction: TransactionPreflightRequest, options?: M2MSentinelClientOptions) { return this.request<any>('POST', '/v1/transaction/preflight', transaction, options); }
158
168
  public getGasFees(options?: M2MSentinelClientOptions) { return this.request<any>('GET', '/v1/gas/fees', undefined, options); }
159
169
  public getDexMetrics(options?: M2MSentinelClientOptions) { return this.request<any>('GET', '/v1/dex/metrics', undefined, options); }
160
170
  public getTokenPrice(symbol: string, options?: M2MSentinelClientOptions) { return this.request<any>('GET', `/v1/token/price/${encodeURIComponent(symbol)}`, undefined, options); }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "m2m-sentinel-sdk",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Source-distributed TypeScript client for M2M Sentinel Base capability intelligence API",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",
@@ -39,6 +39,9 @@ export interface X402PaymentChallenge {
39
39
  export interface X402SignedAuthorizationV2 {
40
40
  x402Version: 2;
41
41
  resource?: any;
42
+ /** The server's advertised extensions, echoed back. The CDP Bazaar indexes a
43
+ * resource from the bazaar extension carried by the settlement. */
44
+ extensions?: any;
42
45
  /** The chosen offer echoed back verbatim. The server deep-equality matches
43
46
  * this against its own requirements to learn which offer is being paid. */
44
47
  accepted: any;
@@ -271,6 +274,12 @@ export class X402SignerClient {
271
274
  x402Version: 2,
272
275
  resource: challenge.resource,
273
276
  accepted: offer,
277
+ // Echo the server's advertised extensions back. The canonical client
278
+ // merges paymentRequired.extensions into the payload; omitting the
279
+ // field still settles the payment, so this failed silently -- but the
280
+ // CDP Bazaar indexes a resource from the bazaar extension carried by
281
+ // the settlement, so a payment without it is invisible to discovery.
282
+ extensions: challenge.extensions,
274
283
  payload: {
275
284
  authorization: {
276
285
  from: fromAddress,
@@ -309,7 +318,7 @@ export class X402SignerClient {
309
318
 
310
319
  async fetchWithAutoPayment(path: string, options: any = {}): Promise<any> {
311
320
  const url = path.startsWith('http') ? path : `${this.baseUrl}/${path.replace(/^\/+/, '')}`;
312
- const headers = { 'Accept': 'application/json', 'User-Agent': '@m2msentinel/sdk-ts/1.2.1', ...(options.headers || {}) };
321
+ const headers = { 'Accept': 'application/json', 'User-Agent': '@m2msentinel/sdk-ts/1.2.3', ...(options.headers || {}) };
313
322
 
314
323
  let res = await fetch(url, { method: options.method || 'GET', headers, body: options.body });
315
324
  if (res.status !== 402) {
package/x402_signer.js CHANGED
@@ -189,6 +189,12 @@ class X402SignerClient {
189
189
  x402Version: 2,
190
190
  resource: challenge.resource,
191
191
  accepted: offer,
192
+ // Echo the server's advertised extensions back. The canonical client
193
+ // merges paymentRequired.extensions into the payload; omitting the
194
+ // field still settles the payment, so this failed silently -- but the
195
+ // CDP Bazaar indexes a resource from the bazaar extension carried by
196
+ // the settlement, so a payment without it is invisible to discovery.
197
+ extensions: challenge.extensions,
192
198
  payload: {
193
199
  authorization: {
194
200
  from: message.from,
@@ -265,7 +271,7 @@ class X402SignerClient {
265
271
  path: url.pathname + url.search,
266
272
  method: options.method || 'GET',
267
273
  headers: {
268
- 'User-Agent': 'M2M-Sentinel-X402Signer/1.2.1',
274
+ 'User-Agent': 'M2M-Sentinel-X402Signer/1.2.3',
269
275
  'Accept': 'application/json',
270
276
  ...(options.headers || {})
271
277
  },