Skip to content

Commit 075899b

Browse files
authored
Merge pull request #39 from bandprotocol/refactor/add-oracleScriptDetailsPage
Refactor/add oracle script details page
2 parents 2099676 + 3174441 commit 075899b

36 files changed

+3487
-70
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
/.graphql_ppx_cache/
88
/lib/bs/
99
/coverage/
10-
.DS_Store
10+
.DS_Store

src/Index.res

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44
let make = () =>
55
<ApolloClient.React.ApolloProvider client=Apollo.client>
66
<GlobalContext>
7-
<TimeContext>
8-
<ThemeContext>
9-
<EmotionThemeContext>
10-
<ModalContext>
11-
<AccountContext>
12-
<App />
13-
<Modal />
14-
</AccountContext>
15-
</ModalContext>
16-
</EmotionThemeContext>
17-
</ThemeContext>
18-
</TimeContext>
7+
<ClientContext>
8+
<TimeContext>
9+
<ThemeContext>
10+
<EmotionThemeContext>
11+
<ModalContext>
12+
<AccountContext>
13+
<App />
14+
<Modal />
15+
</AccountContext>
16+
</ModalContext>
17+
</EmotionThemeContext>
18+
</ThemeContext>
19+
</TimeContext>
20+
</ClientContext>
1921
</GlobalContext>
2022
</ApolloClient.React.ApolloProvider>

src/bindings/AxiosHooks.res

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
let setRpcUrl: string => unit = %raw(`
2-
function(rpcUrl) {
3-
const AxiosHooks = require("axios-hooks");
4-
const Axios = require("axios");
5-
AxiosHooks.configure({
6-
axios: Axios.create({
7-
baseURL: rpcUrl,
8-
}),
9-
});
10-
}
11-
`)
2+
function(rpcUrl) {
3+
const AxiosHooks = require("axios-hooks");
4+
const Axios = require("axios");
5+
AxiosHooks.configure({
6+
axios: Axios.create({
7+
baseURL: rpcUrl,
8+
}),
9+
});
10+
}
11+
`)
1212

1313
@deriving(abstract)
1414
type context_config_t = {useCache: bool}
@@ -27,6 +27,11 @@ let use = url => {
2727
Js.undefinedToOption(rawdata->dataGet)
2828
}
2929

30+
let useLoadable = url => {
31+
let (rawdata, _) = _context(url, context_config_t(~useCache=false));
32+
(Js.undefinedToOption(rawdata->dataGet), rawdata->loadingGet);
33+
};
34+
3035
let useWithReload = url => {
3136
let (rawdata, reload) = _context(url, context_config_t(~useCache=false))
3237
(Js.undefinedToOption(rawdata->dataGet), reload)

src/bindings/Obi.res

Lines changed: 127 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,16 +208,16 @@ let assignSolidity = ({name, varType}) => {
208208

209209
// TODO: abstract it out
210210
let optionsAll = options =>
211-
options |> Belt_Array.reduce(_, Some([]), (acc, obj) => {
211+
options -> Belt.Array.reduce(_, Some([]), (acc, obj) => {
212212
switch (acc, obj) {
213-
| (Some(acc'), Some(obj')) => Some(acc' |> Js.Array.concat([obj']))
213+
| (Some(acc'), Some(obj')) => Some(acc' -> Js.Array.concat([obj']))
214214
| (_, _) => None
215215
}
216216
})
217217

218218
let generateDecodeLibSolidity = (schema, dataType) => {
219-
let dataTypeString = dataType |> dataTypeToString
220-
let name = dataType |> dataTypeToSchemaField
219+
let dataTypeString = dataType -> dataTypeToString
220+
let name = dataType -> dataTypeToSchemaField
221221
let template = (structs, functions) =>
222222
`library ${dataTypeString}Decoder {
223223
using Obi for Obi.Data;
@@ -239,14 +239,14 @@ let generateDecodeLibSolidity = (schema, dataType) => {
239239
`
240240
let fieldPairsOpt = extractFields(schema, name)
241241
fieldPairsOpt->Belt.Option.flatMap(fieldsPairs => {
242-
let fieldsOpt = fieldsPairs |> Belt_Array.map(_, parse) |> optionsAll
242+
let fieldsOpt = fieldsPairs -> Belt.Array.map(parse) -> optionsAll
243243
fieldsOpt->Belt.Option.flatMap(fields => {
244244
let indent = "\n "
245245

246246
Some(
247247
template(
248-
fields |> Belt_Array.map(_, declareSolidity) |> Js.Array.joinWith(indent),
249-
fields |> Belt_Array.map(_, assignSolidity) |> Js.Array.joinWith(indent),
248+
fields -> Belt.Array.map(declareSolidity) -> Js.Array.joinWith(indent, _),
249+
fields -> Belt.Array.map(assignSolidity) -> Js.Array.joinWith(indent, _),
250250
),
251251
)
252252
})
@@ -267,4 +267,123 @@ import "./Obi.sol";
267267
})
268268
}
269269

270-
// TODO: implement GO generator later
270+
// TODO: revisit when using this.
271+
let declareGo = ({name, varType}) => {
272+
let capitalizedName = name -> ChangeCase.pascalCase;
273+
let type_ =
274+
switch varType {
275+
| Single(String) => "string"
276+
| Single(U64) => "uint64"
277+
| Single(U32) => "uint32"
278+
| Single(U8) => "uint8"
279+
| Array(String) => "[]string"
280+
| Array(U64) => "[]uint64"
281+
| Array(U32) => "[]uint32"
282+
| Array(U8) => "[]uint8"
283+
};
284+
j`$capitalizedName $type_`;
285+
};
286+
287+
let assignGo = ({name, varType}) => {
288+
switch (varType) {
289+
| Single(String) => j`$name, err := decoder.DecodeString()
290+
if err !== nil {
291+
return Result{}, err
292+
}`
293+
| Single(U64) => j`$name, err := decoder.DecodeU64()
294+
if err !== nil {
295+
return Result{}, err
296+
}`
297+
| Single(U32) => j`$name, err := decoder.DecodeU32()
298+
if err !== nil {
299+
return Result{}, err
300+
}`
301+
| Single(U8) => j`$name, err := decoder.DecodeU8()
302+
if err !== nil {
303+
return Result{}, err
304+
}`
305+
| _ => "// TODO: implement later"
306+
};
307+
};
308+
309+
let resultGo = ({name}) => {
310+
let capitalizedName = name -> ChangeCase.pascalCase;
311+
j`$capitalizedName: $name`;
312+
};
313+
314+
// TODO: Implement input/params decoding
315+
let generateDecoderGo = (packageName, schema, dataType) => {
316+
switch (dataType) {
317+
| Params => Some("Code is not available.")
318+
| Result =>
319+
let name = dataType -> dataTypeToSchemaField;
320+
let template = (structs, functions, results) => j`package $packageName
321+
322+
import "github.com/bandchain/chain/pkg/obi"
323+
324+
type Result struct {
325+
\t$structs
326+
}
327+
328+
func DecodeResult(data []byte) (Result, error) {
329+
\tdecoder := obi.NewObiDecoder(data)
330+
331+
\t$functions
332+
333+
\tif !decoder.Finished() {
334+
\t\treturn Result{}, errors.New("Obi: bytes left when decode result")
335+
\t}
336+
337+
\treturn Result{
338+
\t\t$results
339+
\t}, nil
340+
}`;
341+
342+
let fieldsPair = extractFields(schema, name) -> Belt.Option.getExn;
343+
let fields = fieldsPair -> Belt.Array.map(parse) -> optionsAll -> Belt.Option.getExn;
344+
Some(
345+
template(
346+
fields -> Belt.Array.map(declareGo) -> Js.Array.joinWith("\n\t", _),
347+
fields -> Belt.Array.map(assignGo) -> Js.Array.joinWith("\n\t", _),
348+
fields -> Belt.Array.map(resultGo) -> Js.Array.joinWith("\n\t\t", _),
349+
),
350+
);
351+
};
352+
};
353+
354+
let encodeStructGo = ({name, varType}) => {
355+
switch (varType) {
356+
| Single(U8) => j`encoder.EncodeU8(result.$name)`
357+
| Single(U32) => j`encoder.EncodeU32(result.$name)`
358+
| Single(U64) => j`encoder.EncodeU64(result.$name)`
359+
| Single(String) => j`encoder.EncodeString(result.$name)`
360+
| _ => "//TODO: implement later"
361+
};
362+
};
363+
364+
let generateEncodeGo = (packageName, schema, name) => {
365+
let template = (structs, functions) => j`package $packageName
366+
367+
import "github.com/bandchain/chain/pkg/obi"
368+
369+
type Result struct {
370+
\t$structs
371+
}
372+
373+
func(result *Result) EncodeResult() []byte {
374+
\tencoder := obi.NewObiEncoder()
375+
376+
\t$functions
377+
378+
\treturn encoder.GetEncodedData()
379+
}`;
380+
381+
let fieldsPair = extractFields(schema, name) -> Belt.Option.getExn;
382+
let fields = fieldsPair -> Belt.Array.map(parse) -> optionsAll -> Belt.Option.getExn;
383+
Some(
384+
template(
385+
fields -> Belt.Array.map(declareGo) -> Js.Array.joinWith("\n\t", _),
386+
fields -> Belt.Array.map(encodeStructGo) -> Js.Array.joinWith("\n\t", _),
387+
),
388+
);
389+
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
module Styles = {
2+
open CssJs;
3+
let reasonSection =
4+
style(. [
5+
padding2(~v=#px(24), ~h=#px(40)),
6+
important(border(#px(1), solid, Theme.failColor)),
7+
borderRadius(#px(12)),
8+
marginTop(#px(40)),
9+
display(#flex),
10+
alignItems(#center),
11+
]);
12+
let resultBox = style(. [padding(#px(20))]);
13+
let labelWrapper = style(. [flexShrink(0.), flexGrow(0.), flexBasis(#px(220))]);
14+
let resultWrapper =
15+
style(. [
16+
flexShrink(0.),
17+
flexGrow(0.),
18+
flexBasis(#calc((#sub, #percent(100.), #px(220)))),
19+
]);
20+
};
21+
22+
@react.component
23+
let make = (~id) => {
24+
let ({ThemeContext.theme}, _) = React.useContext(ThemeContext.context);
25+
let requestSub = RequestSub.get(id);
26+
<>
27+
<div className={Css.merge(list{CssHelper.flexBox(), Styles.resultBox})}>
28+
{switch (requestSub) {
29+
| Data({resolveStatus, resolveHeight}) =>
30+
<>
31+
<div className=Styles.labelWrapper>
32+
<Text value="Resolve Status" color={theme.textSecondary} weight=Text.Regular />
33+
</div>
34+
<div className={CssHelper.flexBox()}>
35+
<RequestStatus resolveStatus display=RequestStatus.Full size=Text.Md />
36+
{switch (resolveHeight) {
37+
| Some(height) =>
38+
<>
39+
<HSpacing size=Spacing.md />
40+
<Text value=" (" block=true color={theme.textPrimary} />
41+
<TypeID.Block id=height />
42+
<Text value=")" block=true color={theme.textPrimary} />
43+
</>
44+
| None => React.null
45+
}}
46+
</div>
47+
</>
48+
| _ => <LoadingCensorBar.CircleSpin height=90 />
49+
}}
50+
</div>
51+
{switch (requestSub) {
52+
| Data({reason}) =>
53+
switch (reason) {
54+
| Some(reason') when reason' !== "" =>
55+
<div className=Styles.reasonSection>
56+
<img alt="Fail Icon" src=Images.fail />
57+
<HSpacing size=Spacing.md />
58+
<Text value=reason' color={theme.textPrimary} />
59+
</div>
60+
| _ => React.null
61+
}
62+
| _ => React.null
63+
}}
64+
</>;
65+
};

src/components/RequestStatus.res

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
type display_t =
2+
| Full
3+
| Mini;
4+
5+
let toString = x =>
6+
switch x {
7+
| RequestSub.Success => "Success"
8+
| Failure => "Failure"
9+
| Pending => "Pending"
10+
| Expired => "Expired"
11+
| Unknown => "Unknown"
12+
}
13+
14+
@react.component
15+
let make = (~resolveStatus, ~display=Mini, ~style="", ~size=Text.Lg) => {
16+
<div className={CssHelper.flexBox(~align=#center, ())}>
17+
{switch (resolveStatus) {
18+
| RequestSub.Success => <img alt="Success Icon" src=Images.success className=style />
19+
| Failure => <img alt="Fail Icon" src=Images.fail className=style />
20+
| Pending => <img alt="Pending Icon" src=Images.pending className=style />
21+
| Expired => <img alt="Expired Icon" src=Images.expired className=style />
22+
| Unknown => <img alt="Unknown Icon" src=Images.unknown className=style />
23+
}}
24+
{display == Full
25+
? <> <HSpacing size=Spacing.sm /> <Text value={resolveStatus -> toString} size /> </>
26+
: React.null}
27+
</div>;
28+
};

0 commit comments

Comments
 (0)