Pre-action security checks for blockchain addresses, URLs, and AIS-aligned agent submissions before irreversible crypto actions.
Greenlight now supports structured agent context with AIS-aligned identity, intent, and action fields — with tolerant optional field handling for gradual adoption.
/v1/pre-action-checks
RECOMMENDED
Submit AIS-aligned agent context, intent, and target data for pre-action security checks. Returns machine-readable security findings immediately. Supports gradual adoption — only 4 fields are required.
/v1/scans
Lightweight scan endpoint. Submit an address or URL for security analysis. Returns a signed findings payload.
/v1/scans/{scan_id}
Retrieve a previously completed findings payload by scan ID. Results expire after 24 hours.
/.well-known/agent-service.json
Agent discoverability manifest with endpoints, supported chains, submission requirements, and public keys.
# AIS-aligned pre-action check before a swap
curl -X POST https://greenlightagent.com/v1/pre-action-checks \
-H "Content-Type: application/json" \
-d '{
"agent_context": {
"agent_id": "trading-bot-01",
"operator_id": "fund-alpha"
},
"intent": {
"intent_type": "swap",
"chain": "ethereum",
"protocol": "uniswap_v3"
},
"action_context": {
"target_type": "address",
"target": "0xdef456...",
"target_role": "router"
},
"policy_context": {
"risk_profile": "standard",
"first_time_interaction": false
}
}'
{
"check_id": "pac_ece945d0562c",
"timestamp": 1712351235,
"deterministic_validation": {
"payload_valid": true,
"target_type_recognized": true,
"required_fields_present": true
},
"submitted_context": {
"agent_id": "trading-bot-01",
"intent_type": "swap",
"target_type": "address",
"target": "0xdef456..."
},
"findings_summary": {
"outcome": "no_issues_detected",
"level": "none",
"issues_count": 0,
"signal_weight": 0
},
"security_findings": [],
"signals": {
"contract_verified": true,
"known_malicious": false,
"first_time_interaction": false
},
"attestation": {
"type": "signed_findings_attestation",
"issuer": "Greenlight AgentAI",
"issued_at": 1712351235,
"expires_at": 1712352135,
"signature": "ed25519:f24e51a8...1a5d09"
},
"disclaimer": "Findings reflect checks and signals available at the time of evaluation. Absence of findings does not imply absence of risk and is not a guarantee of safety."
}
Greenlight returns findings — it does not make proceed/stop decisions. Your policy engine defines what each outcome means for your agent.
Greenlight now supports AIS-aligned pre-action submissions in which agents provide minimal identity, intent, and action context before execution. This enables richer security checks while allowing gradual adoption of structured agent identity standards.
| Field | Required | Description |
|---|---|---|
agent_context.agent_id | Required | Unique identifier of the acting agent |
intent.intent_type | Required | swap, transfer, approve, lend, add_liquidity, stake, bridge, withdraw, other |
action_context.target_type | Required | address, url, or tx |
action_context.target | Required | The address, URL, or transaction payload being evaluated |
agent_context.operator_id | Optional | Human, team, or organization operating the agent |
agent_context.wallet_address | Optional | Execution wallet when available |
agent_context.ais_ref | Optional | AIS or AID reference for the acting agent |
intent.chain / protocol / amount | Optional | Blockchain, protocol, and value context |
policy_context.* | Optional | risk_profile, max_value_usd, first_time_interaction |
Optional fields may be omitted, null, or set to "NA" — none will fail the request.
Every findings payload includes an Ed25519 signature over the canonical JSON of the signed payload fields. Use the public key from /.well-known/agent-service.json to verify.
Verify /v1/pre-action-checks responses using the check_id field. Verify /v1/scans responses using scan_id.
import nacl from 'tweetnacl';
const publicKey = '287cc8db0d0eae7d8bf0c14cb9e7ee647a047384c02ee85aea741c36a1bfabca';
function verify(result) {
// Reconstruct the signed payload (pre-action-checks response)
const payload = {
check_id: result.check_id,
agent_id: result.submitted_context.agent_id,
target: result.submitted_context.target,
target_type: result.submitted_context.target_type,
intent_type: result.submitted_context.intent_type,
outcome: result.findings_summary.outcome,
signal_weight: result.findings_summary.signal_weight,
findings_count: result.findings_summary.issues_count,
issued_at: result.attestation.issued_at,
expires_at: result.attestation.expires_at,
};
// Stable JSON: sort keys recursively
function stableStringify(obj) {
if (obj === null || obj === undefined) return 'null';
if (typeof obj !== 'object') return JSON.stringify(obj);
if (Array.isArray(obj))
return '[' + obj.map(stableStringify).join(',') + ']';
const keys = Object.keys(obj).sort();
return '{' + keys.map(k =>
JSON.stringify(k) + ':' + stableStringify(obj[k])
).join(',') + '}';
}
const message = new TextEncoder().encode(stableStringify(payload));
const sig = Buffer.from(scanResult.attestation.signature, 'hex');
const pub = Buffer.from(publicKey, 'hex');
return nacl.sign.detached.verify(message, sig, pub);
// true = authentic, untampered result from Greenlight
}
from nacl.signing import VerifyKey
import json
public_key = '287cc8db0d0eae7d8bf0c14cb9e7ee647a047384c02ee85aea741c36a1bfabca'
def verify(result):
# Reconstruct the signed payload (pre-action-checks response)
payload = {
"agent_id": result["submitted_context"]["agent_id"],
"check_id": result["check_id"],
"expires_at": result["attestation"]["expires_at"],
"findings_count": result["findings_summary"]["issues_count"],
"intent_type": result["submitted_context"]["intent_type"],
"issued_at": result["attestation"]["issued_at"],
"outcome": result["findings_summary"]["outcome"],
"signal_weight": result["findings_summary"]["signal_weight"],
"target": result["submitted_context"]["target"],
"target_type": result["submitted_context"]["target_type"],
}
# stableStringify: recursively sort keys
def stable(obj):
if isinstance(obj, dict):
return json.dumps({k: json.loads(stable(v)) for k in sorted(obj)}, separators=(",", ":"))
return json.dumps(obj, separators=(",", ":"))
message = stable(payload).encode()
sig_hex = result["attestation"]["signature"].replace("ed25519:", "")
sig = bytes.fromhex(sig_hex)
vk = VerifyKey(bytes.fromhex(public_key))
vk.verify(message, sig) # raises if invalid
return True
GoPlus Token Security, GoPlus Malicious Address, GoPlus Approval Security, GoPlus NFT Security, Chainabuse, Moralis Wallet Reputation, Phishing Database (53K+ domains), Etherscan, CoinGecko
GoPlus Phishing Detection, GoPlus dApp Security, Phishing Database, ScamSniffer, Chainabuse
30 requests/minute per IP. Free during beta. No API key required.