neo_solidity/cli/standard_json/
standard_json_abi.rs

1pub(crate) fn build_standard_abi(metadata: &ContractMetadata) -> Vec<Value> {
2    let mut abi_entries = Vec::new();
3
4    for method in &metadata.methods {
5        if matches!(method.kind, FunctionKind::Regular)
6            && !matches!(
7                method.visibility,
8                VisibilityKind::Public | VisibilityKind::External
9            )
10        {
11            continue;
12        }
13        let inputs: Vec<Value> = method
14            .parameters
15            .iter()
16            .enumerate()
17            .map(|(index, parameter)| {
18                json!({
19                    "name": parameter.name.clone().unwrap_or_else(|| format!("arg{index}")),
20                    "type": parameter.ty,
21                    "internalType": parameter.ty,
22                })
23            })
24            .collect();
25
26        let outputs: Vec<Value> = method
27            .return_parameters
28            .iter()
29            .enumerate()
30            .map(|(index, parameter)| {
31                json!({
32                    "name": parameter.name.clone().unwrap_or_else(|| format!("ret{index}")),
33                    "type": parameter.ty,
34                    "internalType": parameter.ty,
35                })
36            })
37            .collect();
38
39        match method.kind {
40            FunctionKind::Constructor => {
41                abi_entries.push(json!({
42                    "type": "constructor",
43                    "inputs": inputs,
44                    "stateMutability": state_mutability_label(method.state_mutability),
45                }));
46            }
47            FunctionKind::Regular => {
48                abi_entries.push(json!({
49                    "type": "function",
50                    "name": method.name,
51                    "inputs": inputs,
52                    "outputs": outputs,
53                    "stateMutability": state_mutability_label(method.state_mutability),
54                }));
55            }
56        }
57    }
58
59    for event in &metadata.events {
60        let inputs: Vec<Value> = event
61            .parameters
62            .iter()
63            .enumerate()
64            .map(|(index, parameter)| {
65                json!({
66                    "name": parameter.name.clone().unwrap_or_else(|| format!("param{index}")),
67                    "type": parameter.ty,
68                    "indexed": parameter.indexed,
69                })
70            })
71            .collect();
72
73        abi_entries.push(json!({
74            "type": "event",
75            "name": event.name,
76            "inputs": inputs,
77            "anonymous": false,
78        }));
79    }
80
81    abi_entries
82}
83
84pub(crate) fn build_method_identifiers(metadata: &ContractMetadata) -> Map<String, Value> {
85    let mut identifiers = Map::new();
86
87    for method in &metadata.methods {
88        if matches!(method.kind, FunctionKind::Constructor) {
89            continue;
90        }
91
92        if !matches!(
93            method.visibility,
94            VisibilityKind::Public | VisibilityKind::External
95        ) {
96            continue;
97        }
98
99        let param_signatures: Vec<String> = method
100            .parameters
101            .iter()
102            .map(|param| canonical_param_type(&param.ty))
103            .collect();
104        let signature = if param_signatures.is_empty() {
105            format!("{}()", method.name)
106        } else {
107            format!("{}({})", method.name, param_signatures.join(","))
108        };
109
110        identifiers.insert(
111            signature,
112            Value::String(hex_prefixed(&hex::encode(method.selector))),
113        );
114    }
115
116    identifiers
117}
118