This repository has been archived by the owner on Jun 14, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathwrapper.js
138 lines (115 loc) · 3.86 KB
/
wrapper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
var ProviderError = require('./error');
module.exports = {
/*
* Web3.js Transport Wrapper
*
* Wraps an underlying web3 provider's RPC transport methods (send/sendAsync)
* for Truffle-specific purposes, mainly for logging / request verbosity.
*/
wrap: function(provider, options) {
/* wrapping should be idempotent */
if (provider._alreadyWrapped) return provider;
/* setup options defaults */
options = options || {};
// custom logger
options.logger = options.logger || console;
// to see what web3 is sending and receiving.
options.verbose = options.verbose || options.verboseRpc || false;
/* create wrapper functions for before/after send */
var preHook = this.preHook(options);
var postHook = this.postHook(options);
var originalSend = provider.send.bind(provider);
var originalSendAsync = provider.sendAsync.bind(provider);
/* overwrite methods */
provider.send = this.send(originalSend, preHook, postHook);
provider.sendAsync = this.sendAsync(originalSendAsync, preHook, postHook);
/* mark as wrapped */
provider._alreadyWrapped = true;
return provider;
},
/*
* Transport Hook Generators
*
* Used to wrap underlying web3.js behavior before/after sending request
* payloads to the RPC.
*
* Transport hooks may be used to perform additional operations before/after
* sending, and/or to modify request/response data.
*
* Each generator accepts an `options` argument and uses it to construct
* and return a function.
*
* Returned functions accept relevant arguments and return potentially new
* versions of those arguments (for payload/result/error overrides)
*/
// before send/sendAsync
preHook: function(options) {
return function(payload) {
if (options.verbose) {
// for request payload debugging
options.logger.log(" > " + JSON.stringify(payload, null, 2).split("\n").join("\n > "));
}
return payload;
};
},
// after send/sendAsync
postHook: function(options) {
return function(payload, error, result) {
if (error != null) {
// wrap errors in internal error class
error = new ProviderError(error.message, error);
return [payload, error, result];
}
if (options.verbose) {
options.logger.log(" < " + JSON.stringify(result, null, 2).split("\n").join("\n < "));
}
return [payload, error, result];
};
},
/*
* Transport Method Generators
*
* Generate wrapped versions of `send`/`sendAsync`, given original method and
* transport hooks.
*
* Pre-condition: originals are bound correctly (`send.bind(provider)`)
*
* Return the wrapped function matching the original function's signature.
*/
// wrap a `provider.send` function with behavior hooks
// returns a function(payload) to replace `provider.send`
send: function(originalSend, preHook, postHook) {
return function(payload) {
var result = null;
var error = null;
payload = preHook(payload);
try {
result = originalSend(payload);
} catch (e) {
error = e;
}
var modified = postHook(payload, error, result);
payload = modified[0];
error = modified[1];
result = modified[2];
if (error != null) {
throw error;
}
return result;
}
},
// wrap a `provider.sendAsync` function with behavior hooks
// returns a function(payload, callback) to replace `provider.sendAsync`
sendAsync: function(originalSendAsync, preHook, postHook) {
return function(payload, callback) {
payload = preHook(payload);
originalSendAsync(payload, function(error, result) {
var modified = postHook(payload, error, result);
payload = modified[0];
error = modified[1];
result = modified[2];
callback(error, result);
});
};
}
}