m2m-sentinel-sdk 1.2.3 → 1.2.7
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 +106 -112
- package/agent_adapter.js +11 -23
- package/base_account_paymaster_guard.js +921 -0
- package/eliza_plugin.js +1 -1
- package/index.d.ts +244 -1
- package/index.js +3 -1
- package/langchain_tool.js +93 -0
- package/mcp_server.js +176 -84
- package/package.json +19 -3
- package/smithery.yaml +2 -2
- package/typescript/base_account_paymaster_guard.ts +284 -0
- package/typescript/index.ts +2 -0
- package/typescript/package-lock.json +50 -0
- package/typescript/package.json +6 -2
- package/typescript/tsconfig.json +13 -0
- package/typescript/x402.ts +1 -1
- package/x402_signer.js +1 -1
package/eliza_plugin.js
CHANGED
|
@@ -69,7 +69,7 @@ const m2mSentinelPlugin = {
|
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
name: 'GET_GAS_FEES',
|
|
72
|
-
description: 'Fetches
|
|
72
|
+
description: 'Fetches current Base gas-price telemetry with upstream provenance.',
|
|
73
73
|
handler: async (runtime) => {
|
|
74
74
|
try { return { text: JSON.stringify(await clientFor(runtime).getGasFees()) }; }
|
|
75
75
|
catch (err) { return { text: errorText(err) }; }
|
package/index.d.ts
CHANGED
|
@@ -23,6 +23,192 @@ export interface TransactionPreflightRequest {
|
|
|
23
23
|
blockNumber?: number | string;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/** A top-level call in the documented EIP-5792 wallet_sendCalls envelope. */
|
|
27
|
+
export interface WalletSendCallsCall {
|
|
28
|
+
to: string;
|
|
29
|
+
data: string;
|
|
30
|
+
/** Base Account uses canonical 0x quantities for call value. */
|
|
31
|
+
value?: string;
|
|
32
|
+
capabilities?: Record<string, Record<string, unknown>>;
|
|
33
|
+
flowControl?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WalletSendCallsParams {
|
|
37
|
+
version: '1.0';
|
|
38
|
+
id?: string;
|
|
39
|
+
from: string;
|
|
40
|
+
/** Deliberately restricted to Base's canonical wallet_sendCalls value. */
|
|
41
|
+
chainId: '0x2105';
|
|
42
|
+
atomicRequired?: boolean;
|
|
43
|
+
calls: WalletSendCallsCall[];
|
|
44
|
+
capabilities?: Record<string, Record<string, unknown>>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface WalletSendCallsRequest {
|
|
48
|
+
method: 'wallet_sendCalls';
|
|
49
|
+
params: [WalletSendCallsParams];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface Eip1193Provider {
|
|
53
|
+
request(request: WalletSendCallsRequest): Promise<unknown>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type BaseTrustLevel = 'HIGH_TRUST_PRIMARY' | 'QUORUM_PUBLIC';
|
|
57
|
+
|
|
58
|
+
export interface BaseObservationBlock {
|
|
59
|
+
status: 'PINNED';
|
|
60
|
+
chainId: number | string;
|
|
61
|
+
network: 'eip155:8453';
|
|
62
|
+
blockNumber: number | string;
|
|
63
|
+
blockHash: string;
|
|
64
|
+
blockTag: string;
|
|
65
|
+
trustLevel: BaseTrustLevel;
|
|
66
|
+
[key: string]: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface BaseSimulationObservation {
|
|
70
|
+
attempted: true;
|
|
71
|
+
trusted: true;
|
|
72
|
+
outcome: 'NOT_ATTEMPTED' | 'SUCCEEDED' | 'REVERTED' | 'UNAVAILABLE' | 'MALFORMED';
|
|
73
|
+
blockTag: string;
|
|
74
|
+
evidenceOnly: true;
|
|
75
|
+
[key: string]: unknown;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface BaseRpcObservation {
|
|
79
|
+
pinnedBlockTag: string;
|
|
80
|
+
stateBearingCallCount: number;
|
|
81
|
+
failedReadCount: 0;
|
|
82
|
+
failures: unknown[];
|
|
83
|
+
calls: BaseRpcObservationCall[];
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface BaseRpcObservationCall {
|
|
88
|
+
method?: string;
|
|
89
|
+
params?: unknown[];
|
|
90
|
+
blockTag?: string | null;
|
|
91
|
+
status?: 'OK' | 'UNSUPPORTED_OPTIONAL_METHOD' | 'EXECUTION_ERROR' | string;
|
|
92
|
+
trustLevel?: BaseTrustLevel | 'DEGRADED_LOW_TRUST';
|
|
93
|
+
[key: string]: unknown;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface BaseCapabilityEvidence {
|
|
97
|
+
sourceAddress: string;
|
|
98
|
+
executionRole: 'RESOLVED_EXECUTING_CODE' | 'SELECTED_DIAMOND_FACET';
|
|
99
|
+
transactionSelector: string | null;
|
|
100
|
+
dissection: BaseDissection;
|
|
101
|
+
notASafetyGuarantee: true;
|
|
102
|
+
reachability: 'NOT_ESTABLISHED';
|
|
103
|
+
[key: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface BaseDissectionCapability {
|
|
107
|
+
type: string;
|
|
108
|
+
[key: string]: unknown;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface BaseDissection {
|
|
112
|
+
isValidContract: true;
|
|
113
|
+
bytecodeSizeBytes: number;
|
|
114
|
+
targetBytecodeHash: string;
|
|
115
|
+
capabilities: BaseDissectionCapability[];
|
|
116
|
+
detectedCapabilities: string[];
|
|
117
|
+
[key: string]: unknown;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface BaseBytecodeHashes {
|
|
121
|
+
runtimeBytecodeHash: string | null;
|
|
122
|
+
finalTargetBytecodeHash: string;
|
|
123
|
+
facetBytecodeHash: string | null;
|
|
124
|
+
facetBytecodeHashes: unknown[];
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface BaseAccountPreflightObservation {
|
|
129
|
+
status: 'SUCCESS';
|
|
130
|
+
operation: 'TRANSACTION_PREFLIGHT_OBSERVATION';
|
|
131
|
+
request: TransactionPreflightRequest;
|
|
132
|
+
selectorHex: string | null;
|
|
133
|
+
surfaceTarget: string;
|
|
134
|
+
resolvedExecutionTarget: string;
|
|
135
|
+
resolution: Record<string, unknown> & { status: 'COMPLETE'; resolutionComplete: true };
|
|
136
|
+
evidenceGrade: true;
|
|
137
|
+
evidenceStatus: 'VERIFIED';
|
|
138
|
+
effectiveTrust: BaseTrustLevel;
|
|
139
|
+
observationBlock: BaseObservationBlock;
|
|
140
|
+
simulationObservation: BaseSimulationObservation;
|
|
141
|
+
rpcObservation: BaseRpcObservation;
|
|
142
|
+
capabilityEvidence: BaseCapabilityEvidence;
|
|
143
|
+
bytecodeHashes: BaseBytecodeHashes;
|
|
144
|
+
notASafetyGuarantee: true;
|
|
145
|
+
reachability: 'NOT_ESTABLISHED';
|
|
146
|
+
limitations: string[];
|
|
147
|
+
conclusion: null;
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface BaseAccountObservationIdentity {
|
|
152
|
+
blockNumber: bigint;
|
|
153
|
+
blockTag: string;
|
|
154
|
+
blockHash: string;
|
|
155
|
+
effectiveTrust: BaseTrustLevel;
|
|
156
|
+
blockTrustLevel: BaseTrustLevel;
|
|
157
|
+
finalTargetBytecodeHash: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface BaseAccountGuardContext {
|
|
161
|
+
callIndex: number;
|
|
162
|
+
index: number;
|
|
163
|
+
call: WalletSendCallsCall;
|
|
164
|
+
transaction: TransactionPreflightRequest;
|
|
165
|
+
request: WalletSendCallsRequest;
|
|
166
|
+
params: WalletSendCallsParams;
|
|
167
|
+
[key: string]: unknown;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type BaseAccountCallerPolicyResult =
|
|
171
|
+
| true
|
|
172
|
+
| false
|
|
173
|
+
| null
|
|
174
|
+
| undefined
|
|
175
|
+
| { allow: true; reason?: string }
|
|
176
|
+
| { allow: false; reason?: string };
|
|
177
|
+
|
|
178
|
+
export type BaseAccountCallerPolicy = (
|
|
179
|
+
observation: BaseAccountPreflightObservation,
|
|
180
|
+
context: BaseAccountGuardContext
|
|
181
|
+
) => BaseAccountCallerPolicyResult | Promise<BaseAccountCallerPolicyResult>;
|
|
182
|
+
|
|
183
|
+
export interface GuardWalletSendCallsOptions {
|
|
184
|
+
client: Pick<M2MSentinelClient, 'preflightTransaction'>;
|
|
185
|
+
provider: Eip1193Provider;
|
|
186
|
+
request: WalletSendCallsRequest;
|
|
187
|
+
policy: BaseAccountCallerPolicy;
|
|
188
|
+
context?: Record<string, unknown>;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface BaseAccountPaymasterGuardOptions {
|
|
192
|
+
client: Pick<M2MSentinelClient, 'preflightTransaction'>;
|
|
193
|
+
policy: BaseAccountCallerPolicy;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface BaseAccountGuardCallOptions {
|
|
197
|
+
policy?: BaseAccountCallerPolicy;
|
|
198
|
+
context?: Record<string, unknown>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface PreflightBeforeSigningOptions {
|
|
202
|
+
client: Pick<M2MSentinelClient, 'preflightTransaction'>;
|
|
203
|
+
transaction: TransactionPreflightRequest;
|
|
204
|
+
policy: (
|
|
205
|
+
observation: BaseAccountPreflightObservation,
|
|
206
|
+
context: { transaction: TransactionPreflightRequest; [key: string]: unknown }
|
|
207
|
+
) => BaseAccountCallerPolicyResult | Promise<BaseAccountCallerPolicyResult>;
|
|
208
|
+
signAndSend: (transaction: TransactionPreflightRequest, observation: BaseAccountPreflightObservation) => Promise<unknown>;
|
|
209
|
+
context?: Record<string, unknown>;
|
|
210
|
+
}
|
|
211
|
+
|
|
26
212
|
export interface M2MSentinelErrorOptions {
|
|
27
213
|
status?: number;
|
|
28
214
|
body?: unknown;
|
|
@@ -74,6 +260,64 @@ export class M2MSentinelClient {
|
|
|
74
260
|
revokeKey(confirm?: boolean): Promise<any>;
|
|
75
261
|
}
|
|
76
262
|
|
|
263
|
+
export class WalletSendCallsInputError extends TypeError {
|
|
264
|
+
readonly code: 'INVALID_WALLET_SEND_CALLS_INPUT';
|
|
265
|
+
readonly field: string;
|
|
266
|
+
constructor(field: string, message: string);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export class ExecutionIdentityBlockedError extends Error {
|
|
270
|
+
readonly code: string;
|
|
271
|
+
constructor(code: string, message: string);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export const PreflightInputError: typeof WalletSendCallsInputError;
|
|
275
|
+
export const PreflightBlockedError: typeof ExecutionIdentityBlockedError;
|
|
276
|
+
|
|
277
|
+
export const BASE_CHAIN_ID: 8453;
|
|
278
|
+
export const BASE_CHAIN_HEX: '0x2105';
|
|
279
|
+
export const BASE_NETWORK: 'eip155:8453';
|
|
280
|
+
export const MAX_CALLS: number;
|
|
281
|
+
export const MAX_PREFLIGHT_CONCURRENCY: number;
|
|
282
|
+
export const MAX_RPC_OBSERVATION_CALLS: number;
|
|
283
|
+
export const MAX_DATA_BYTES: number;
|
|
284
|
+
|
|
285
|
+
export function isAffirmativePolicyResult(value: unknown): value is true | { allow: true; reason?: string };
|
|
286
|
+
export function validateWalletSendCallsRequest(request: unknown): WalletSendCallsRequest;
|
|
287
|
+
export const normalizeWalletSendCallsRequest: typeof validateWalletSendCallsRequest;
|
|
288
|
+
export function transactionFromCall(params: WalletSendCallsParams, call: WalletSendCallsCall, index?: number): TransactionPreflightRequest;
|
|
289
|
+
export function toPreflightTransaction(params: WalletSendCallsParams, call: WalletSendCallsCall, index?: number): TransactionPreflightRequest;
|
|
290
|
+
export function assertObservationReady(
|
|
291
|
+
observation: unknown,
|
|
292
|
+
transaction: TransactionPreflightRequest
|
|
293
|
+
): BaseAccountObservationIdentity;
|
|
294
|
+
export function guardWalletSendCalls(options: GuardWalletSendCallsOptions): Promise<unknown>;
|
|
295
|
+
export const preflightWalletSendCalls: typeof guardWalletSendCalls;
|
|
296
|
+
export const sendCallsWithPreflight: typeof guardWalletSendCalls;
|
|
297
|
+
export const executeWalletSendCalls: typeof guardWalletSendCalls;
|
|
298
|
+
|
|
299
|
+
export function preflightBeforeSigning(options: PreflightBeforeSigningOptions): Promise<unknown>;
|
|
300
|
+
export const guardTransaction: typeof preflightBeforeSigning;
|
|
301
|
+
export const preflightTransactionBeforeSigning: typeof preflightBeforeSigning;
|
|
302
|
+
|
|
303
|
+
export class BaseAccountPaymasterGuard {
|
|
304
|
+
constructor(options: BaseAccountPaymasterGuardOptions);
|
|
305
|
+
request(provider: Eip1193Provider, request: WalletSendCallsRequest, options?: BaseAccountGuardCallOptions): Promise<unknown>;
|
|
306
|
+
sendCalls(provider: Eip1193Provider, request: WalletSendCallsRequest, options?: BaseAccountGuardCallOptions): Promise<unknown>;
|
|
307
|
+
preflightTransaction(transaction: TransactionPreflightRequest, options?: { policy?: BaseAccountCallerPolicy; signAndSend: (tx: any, obs: any) => Promise<unknown>; context?: Record<string, unknown> }): Promise<unknown>;
|
|
308
|
+
guardTransaction(transaction: TransactionPreflightRequest, options?: { policy?: BaseAccountCallerPolicy; signAndSend: (tx: any, obs: any) => Promise<unknown>; context?: Record<string, unknown> }): Promise<unknown>;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export const BaseAccountExecutionGuard: typeof BaseAccountPaymasterGuard;
|
|
312
|
+
export function createBaseAccountPaymasterGuard(options: BaseAccountPaymasterGuardOptions): BaseAccountPaymasterGuard;
|
|
313
|
+
export function createExecutionIdentityGuard(options: BaseAccountPaymasterGuardOptions): BaseAccountPaymasterGuard;
|
|
314
|
+
export function createPublicClient(options: {
|
|
315
|
+
apiKey: string;
|
|
316
|
+
baseUrl?: string;
|
|
317
|
+
timeoutMs?: number;
|
|
318
|
+
sdk?: { M2MSentinelClient: typeof M2MSentinelClient };
|
|
319
|
+
}): M2MSentinelClient;
|
|
320
|
+
|
|
77
321
|
export type SentinelPolicy = (
|
|
78
322
|
analysis: any,
|
|
79
323
|
context: { targetAddress: string; integration: string }
|
|
@@ -120,4 +364,3 @@ export class X402SignerClient {
|
|
|
120
364
|
export function x402SignerClient(options?: X402SignerClientOptions): X402SignerClient;
|
|
121
365
|
export function parsePaymentHeader(value: string | object | null): any;
|
|
122
366
|
export function parsePriceToUnits(priceStr: string | number, decimals?: number): bigint;
|
|
123
|
-
|
package/index.js
CHANGED
|
@@ -176,6 +176,7 @@ function createViemSentinelInterceptor(apiKey, baseUrl, policy) {
|
|
|
176
176
|
|
|
177
177
|
const { M2MSentinelActionProvider, m2mSentinelActionProvider } = require('./agent_adapter.js');
|
|
178
178
|
const { X402SignerClient, x402SignerClient, parsePaymentHeader, parsePriceToUnits } = require('./x402_signer.js');
|
|
179
|
+
const baseAccountPaymasterGuard = require('./base_account_paymaster_guard.js');
|
|
179
180
|
|
|
180
181
|
module.exports = {
|
|
181
182
|
M2MSentinelClient,
|
|
@@ -191,5 +192,6 @@ module.exports = {
|
|
|
191
192
|
X402SignerClient,
|
|
192
193
|
x402SignerClient,
|
|
193
194
|
parsePaymentHeader,
|
|
194
|
-
parsePriceToUnits
|
|
195
|
+
parsePriceToUnits,
|
|
196
|
+
...baseAccountPaymasterGuard
|
|
195
197
|
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LangChain & LangGraph Tool Provider for M2M Sentinel.
|
|
5
|
+
*
|
|
6
|
+
* Compatible with @langchain/core/tools StructuredTool and DynamicStructuredTool.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { M2MSentinelClient } = require('./index.js');
|
|
10
|
+
|
|
11
|
+
class M2MSentinelLangChainTools {
|
|
12
|
+
/**
|
|
13
|
+
* @param {Object} [options]
|
|
14
|
+
* @param {string} [options.apiKey] M2M Sentinel API Key
|
|
15
|
+
* @param {string} [options.baseUrl] M2M Sentinel Base URL
|
|
16
|
+
*/
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.client = new M2MSentinelClient(options);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Return a list of tool definitions compatible with LangChain agents.
|
|
23
|
+
* Can be passed directly to `createOpenAIToolsAgent({ tools })` or `AgentExecutor`.
|
|
24
|
+
*/
|
|
25
|
+
getTools() {
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
name: 'm2m_audit_contract',
|
|
29
|
+
description: 'Deterministic EVM bytecode capability analysis and proxy resolution for Base contracts. Run before signing or sending transactions to unverified contracts.',
|
|
30
|
+
schema: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
address: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'The 0x-prefixed 40-hex Ethereum address on Base (Chain ID 8453) to inspect.'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
required: ['address']
|
|
39
|
+
},
|
|
40
|
+
func: async ({ address }) => {
|
|
41
|
+
try {
|
|
42
|
+
const res = await this.client.auditContract(address);
|
|
43
|
+
return JSON.stringify(res);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return JSON.stringify({ error: err.message, status: err.status || 500 });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'm2m_get_gas_metrics',
|
|
51
|
+
description: 'Fetch current Base gas price in wei/gwei with RPC provenance. Read-only telemetry; does not authorize or submit transactions.',
|
|
52
|
+
schema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {}
|
|
55
|
+
},
|
|
56
|
+
func: async () => {
|
|
57
|
+
try {
|
|
58
|
+
const res = await this.client.getGasFees();
|
|
59
|
+
return JSON.stringify(res);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
return JSON.stringify({ error: err.message, status: err.status || 500 });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'm2m_get_token_price',
|
|
67
|
+
description: 'Fetch sourced Base DEX spot price for one allowlisted token symbol (e.g. USDC, WETH), with pool provenance and no historical price series.',
|
|
68
|
+
schema: {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
symbol: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'The asset symbol (e.g., USDC, WETH).'
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
required: ['symbol']
|
|
77
|
+
},
|
|
78
|
+
func: async ({ symbol }) => {
|
|
79
|
+
try {
|
|
80
|
+
const res = await this.client.getTokenPrice(symbol);
|
|
81
|
+
return JSON.stringify(res);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
return JSON.stringify({ error: err.message, status: err.status || 500 });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
M2MSentinelLangChainTools
|
|
93
|
+
};
|