UNPKG

5.4 kBJavaScriptView Raw
1var sha3 = require("crypto-js/sha3");
2var schema_version = require("./package.json").version;
3
4var TruffleSchema = {
5 // Normalize options passed in to be the exact options required
6 // for truffle-contract.
7 //
8 // options can be three things:
9 // - normal object
10 // - contract object
11 // - solc output
12 //
13 // TODO: Is extra_options still necessary?
14 normalizeOptions: function(options, extra_options) {
15 extra_options = extra_options || {};
16 var normalized = {};
17 var expected_keys = [
18 "contract_name",
19 "abi",
20 "binary",
21 "unlinked_binary",
22 "address",
23 "networks",
24 "links",
25 "events",
26 "network_id",
27 "default_network",
28 "updated_at"
29 ];
30
31 // Merge options/contract object first, then extra_options
32 expected_keys.forEach(function(key) {
33 var value;
34
35 try {
36 // Will throw an error if key == address and address doesn't exist.
37 value = options[key];
38
39 if (value != undefined) {
40 normalized[key] = value;
41 }
42 } catch (e) {
43 // Do nothing.
44 }
45
46 try {
47 // Will throw an error if key == address and address doesn't exist.
48 value = extra_options[key];
49
50 if (value != undefined) {
51 normalized[key] = value;
52 }
53 } catch (e) {
54 // Do nothing.
55 }
56 });
57
58 // Now look for solc specific items.
59 if (options.interface != null) {
60 normalized.abi = JSON.parse(options.interface);
61 }
62
63 if (options.bytecode != null) {
64 normalized.unlinked_binary = options.bytecode
65 }
66
67 // Assume any binary passed is the unlinked binary
68 if (normalized.unlinked_binary == null && normalized.binary) {
69 normalized.unlinked_binary = normalized.binary;
70 }
71
72 delete normalized.binary;
73
74 this.copyCustomOptions(options, normalized);
75
76 return normalized;
77 },
78
79 // Generate a proper binary from normalized options, and optionally
80 // merge it with an existing binary.
81 generateBinary: function(options, existing_binary, extra_options) {
82 extra_options = extra_options || {};
83
84 existing_binary = existing_binary || {};
85
86 if (options.overwrite == true) {
87 existing_binary = {};
88 }
89
90 existing_binary.contract_name = options.contract_name || existing_binary.contract_name || "Contract";
91 existing_binary.default_network = options.default_network || existing_binary.default_network;
92
93 existing_binary.abi = options.abi || existing_binary.abi;
94 existing_binary.unlinked_binary = options.unlinked_binary || existing_binary.unlinked_binary;
95
96 // Ensure unlinked binary starts with a 0x
97 if (existing_binary.unlinked_binary && existing_binary.unlinked_binary.indexOf("0x") < 0) {
98 existing_binary.unlinked_binary = "0x" + existing_binary.unlinked_binary;
99 }
100
101 // Merge existing networks with any passed in networks.
102 existing_binary.networks = existing_binary.networks || {};
103 options.networks = options.networks || {};
104 Object.keys(options.networks).forEach(function(network_id) {
105 existing_binary.networks[network_id] = options.networks[network_id];
106 });
107
108 var updated_at = new Date().getTime();
109
110 if (options.network_id) {
111 // Ensure an object exists for this network.
112 existing_binary.networks[options.network_id] = existing_binary.networks[options.network_id] || {};
113
114 var network = existing_binary.networks[options.network_id];
115
116 // Override specific keys
117 network.address = options.address || network.address;
118 network.links = options.links;
119
120 // merge events with any that previously existed
121 network.events = network.events || {};
122 options.events = options.events || {};
123 Object.keys(options.events).forEach(function(event_id) {
124 options.events[event_id] = options.events[event_id];
125 });
126
127 // Now overwrite any events with the most recent data from the ABI.
128 existing_binary.abi.forEach(function(item) {
129 if (item.type != "event") return;
130
131 var signature = item.name + "(" + item.inputs.map(function(param) {return param.type;}).join(",") + ")";
132 network.events["0x" + sha3(signature, {outputLength: 256})] = item;
133 });
134
135 if (extra_options.dirty !== false) {
136 network.updated_at = updated_at;
137 }
138 } else {
139 if (options.address) {
140 throw new Error("Cannot set address without network id");
141 }
142 }
143
144 // Ensure all networks have a `links` object.
145 Object.keys(existing_binary.networks).forEach(function(network_id) {
146 var network = existing_binary.networks[network_id];
147 network.links = network.links || {};
148 });
149
150 existing_binary.schema_version = schema_version;
151
152 if (extra_options.dirty !== false) {
153 existing_binary.updated_at = updated_at;
154 } else {
155 existing_binary.updated_at = options.updated_at || existing_binary.updated_at || updated_at;
156 }
157
158 this.copyCustomOptions(options, existing_binary);
159
160 return existing_binary;
161 },
162
163 copyCustomOptions: function(from, to) {
164 // Now let all x- options through.
165 Object.keys(from).forEach(function(key) {
166 if (key.indexOf("x-") != 0) return;
167
168 try {
169 value = from[key];
170
171 if (value != undefined) {
172 to[key] = value;
173 }
174 } catch (e) {
175 // Do nothing.
176 }
177 });
178 }
179};
180
181module.exports = TruffleSchema;