Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
961fb314
Commit
961fb314
authored
Jan 06, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
write contract and refactoring
parent
62afe258
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
237 additions
and
129 deletions
+237
-129
resources.ts
lib/api/resources.ts
+5
-1
contract.ts
types/api/contract.ts
+19
-4
ContractMethodCallable.tsx
ui/address/contract/ContractMethodCallable.tsx
+36
-44
ContractMethodConstant.tsx
ui/address/contract/ContractMethodConstant.tsx
+7
-3
ContractMethodField.tsx
ui/address/contract/ContractMethodField.tsx
+6
-6
ContractMethodsAccordion.tsx
ui/address/contract/ContractMethodsAccordion.tsx
+63
-0
ContractRead.tsx
ui/address/contract/ContractRead.tsx
+39
-69
ContractWrite.tsx
ui/address/contract/ContractWrite.tsx
+59
-0
types.ts
ui/address/contract/types.ts
+1
-1
Address.tsx
ui/pages/Address.tsx
+2
-1
No files found.
lib/api/resources.ts
View file @
961fb314
...
@@ -14,7 +14,7 @@ import type {
...
@@ -14,7 +14,7 @@ import type {
}
from
'
types/api/address
'
;
}
from
'
types/api/address
'
;
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
Block
,
BlockFilters
}
from
'
types/api/block
'
;
import
type
{
BlocksResponse
,
BlockTransactionsResponse
,
Block
,
BlockFilters
}
from
'
types/api/block
'
;
import
type
{
ChartMarketResponse
,
ChartTransactionResponse
}
from
'
types/api/charts
'
;
import
type
{
ChartMarketResponse
,
ChartTransactionResponse
}
from
'
types/api/charts
'
;
import
type
{
SmartContract
,
SmartContractReadMethod
}
from
'
types/api/contract
'
;
import
type
{
SmartContract
,
SmartContractReadMethod
,
SmartContractWriteMethod
}
from
'
types/api/contract
'
;
import
type
{
IndexingStatus
}
from
'
types/api/indexingStatus
'
;
import
type
{
IndexingStatus
}
from
'
types/api/indexingStatus
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
import
type
{
InternalTransactionsResponse
}
from
'
types/api/internalTransaction
'
;
import
type
{
JsonRpcUrlResponse
}
from
'
types/api/jsonRpcUrl
'
;
import
type
{
JsonRpcUrlResponse
}
from
'
types/api/jsonRpcUrl
'
;
...
@@ -174,6 +174,9 @@ export const RESOURCES = {
...
@@ -174,6 +174,9 @@ export const RESOURCES = {
contract_method_query
:
{
contract_method_query
:
{
path
:
'
/api/v2/smart-contracts/:id/query-read-method
'
,
path
:
'
/api/v2/smart-contracts/:id/query-read-method
'
,
},
},
contract_methods_write
:
{
path
:
'
/api/v2/smart-contracts/:id/methods-write
'
,
},
// TOKEN
// TOKEN
token
:
{
token
:
{
...
@@ -284,6 +287,7 @@ Q extends 'token_counters' ? TokenCounters :
...
@@ -284,6 +287,7 @@ Q extends 'token_counters' ? TokenCounters :
Q
extends
'
config_json_rpc
'
?
JsonRpcUrlResponse
:
Q
extends
'
config_json_rpc
'
?
JsonRpcUrlResponse
:
Q
extends
'
contract
'
?
SmartContract
:
Q
extends
'
contract
'
?
SmartContract
:
Q
extends
'
contract_methods_read
'
?
Array
<
SmartContractReadMethod
>
:
Q
extends
'
contract_methods_read
'
?
Array
<
SmartContractReadMethod
>
:
Q
extends
'
contract_methods_write
'
?
Array
<
SmartContractWriteMethod
>
:
never
;
never
;
/* eslint-enable @typescript-eslint/indent */
/* eslint-enable @typescript-eslint/indent */
...
...
types/api/contract.ts
View file @
961fb314
...
@@ -14,15 +14,30 @@ export interface SmartContract {
...
@@ -14,15 +14,30 @@ export interface SmartContract {
can_be_visualized_via_sol2uml
:
boolean
|
null
;
can_be_visualized_via_sol2uml
:
boolean
|
null
;
}
}
export
interface
SmartContract
ReadMethod
{
export
interface
SmartContract
MethodBase
{
inputs
:
Array
<
SmartContractMethodInput
>
;
inputs
:
Array
<
SmartContractMethodInput
>
;
outputs
:
Array
<
SmartContractMethodOutput
>
;
outputs
:
Array
<
SmartContractMethodOutput
>
;
method_id
:
string
;
constant
:
boolean
;
name
:
string
;
name
:
string
;
stateMutability
:
string
;
stateMutability
:
string
;
type
:
string
;
type
:
'
function
'
;
payable
:
boolean
;
}
export
interface
SmartContractReadMethod
extends
SmartContractMethodBase
{
method_id
:
string
;
}
}
export
interface
SmartContractWriteFallback
{
payable
:
true
;
stateMutability
:
'
payable
'
;
type
:
'
fallback
'
;
}
export
type
SmartContractWriteMethod
=
SmartContractMethodBase
|
SmartContractWriteFallback
;
export
type
SmartContractMethod
=
SmartContractReadMethod
|
SmartContractWriteMethod
;
export
interface
SmartContractMethodInput
{
export
interface
SmartContractMethodInput
{
internalType
:
string
;
internalType
:
string
;
name
:
string
;
name
:
string
;
...
@@ -30,5 +45,5 @@ export interface SmartContractMethodInput {
...
@@ -30,5 +45,5 @@ export interface SmartContractMethodInput {
}
}
export
interface
SmartContractMethodOutput
extends
SmartContractMethodInput
{
export
interface
SmartContractMethodOutput
extends
SmartContractMethodInput
{
value
:
string
;
value
?
:
string
;
}
}
ui/address/contract/Contract
ReadItemInput
.tsx
→
ui/address/contract/Contract
MethodCallable
.tsx
View file @
961fb314
...
@@ -4,21 +4,17 @@ import React from 'react';
...
@@ -4,21 +4,17 @@ import React from 'react';
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
{
useForm
}
from
'
react-hook-form
'
;
import
{
useForm
}
from
'
react-hook-form
'
;
import
type
{
Method
Input
Fields
}
from
'
./types
'
;
import
type
{
Method
Form
Fields
}
from
'
./types
'
;
import
type
{
SmartContract
,
SmartContractMethodInput
,
SmartContractMethodOutput
}
from
'
types/api/contract
'
;
import
type
{
SmartContract
MethodInput
,
SmartContractMethod
}
from
'
types/api/contract
'
;
import
appConfig
from
'
configs/app/config
'
;
import
arrowIcon
from
'
icons/arrows/down-right.svg
'
;
import
arrowIcon
from
'
icons/arrows/down-right.svg
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
Contract
ReadItemInputField
from
'
./ContractReadItemInput
Field
'
;
import
Contract
MethodField
from
'
./ContractMethod
Field
'
;
interface
Props
{
interface
Props
<
T
extends
SmartContractMethod
>
{
data
:
Array
<
SmartContractMethodInput
>
;
data
:
T
;
address
?:
string
;
caller
:
(
data
:
T
,
args
:
Array
<
string
>
)
=>
Promise
<
Array
<
Array
<
string
>>>
;
abi
?:
SmartContract
[
'
abi
'
];
methodName
:
string
;
methodId
:
string
;
outputs
:
Array
<
SmartContractMethodOutput
>
;
}
}
const
getFieldName
=
(
name
:
string
,
index
:
number
):
string
=>
name
||
String
(
index
);
const
getFieldName
=
(
name
:
string
,
index
:
number
):
string
=>
name
||
String
(
index
);
...
@@ -39,36 +35,30 @@ const sortFields = (data: Array<SmartContractMethodInput>) => ([ a ]: [string, s
...
@@ -39,36 +35,30 @@ const sortFields = (data: Array<SmartContractMethodInput>) => ([ a ]: [string, s
return
0
;
return
0
;
};
};
const
ContractReadItemInput
=
({
data
,
address
,
methodId
,
methodName
,
outputs
}:
Props
)
=>
{
const
ContractMethodCallable
=
<
T
extends
SmartContractMethod
>
(
{
data
,
caller
}
: Props
<
T
>
) =
>
{
const
{
control
,
handleSubmit
,
setValue
}
=
useForm
<
MethodInputFields
>
({
defaultValues
:
_fromPairs
(
data
.
map
(({
name
},
index
)
=>
[
getFieldName
(
name
,
index
),
''
])),
const
inputs
=
React
.
useMemo
(()
=>
{
});
return
data
.
payable
&&
(
!
(
'
inputs
'
in
data
)
||
data
.
inputs
.
length
===
0
)
?
[
{
const
apiFetch
=
useApiFetch
();
name
:
'
value
'
,
const
[
result
,
setResult
]
=
React
.
useState
<
Array
<
[
string
,
string
]
>>
([
]);
type
:
appConfig
.
network
.
currency
.
symbol
,
internalType
:
appConfig
.
network
.
currency
.
symbol
,
}
as
SmartContractMethodInput
]
:
data
.
inputs
;
},
[
data
]);
const
onSubmit
:
SubmitHandler
<
MethodInputFields
>
=
React
.
useCallback
(
async
(
formData
)
=>
{
const
{
control
,
handleSubmit
,
setValue
}
=
useForm
<
MethodFormFields
>
(
{
if
(
!
address
)
{
defaultValues
:
_fromPairs
(
inputs
.
map
(({
name
},
index
)
=>
[
getFieldName
(
name
,
index
),
''
])),
return
;
})
;
}
const
[
result
,
setResult
]
=
React
.
useState
<
Array
<
Array
<
string
>>>
([
]);
const
onSubmit
:
SubmitHandler
<
MethodFormFields
>
=
React
.
useCallback
(
async
(
formData
)
=>
{
const
args
=
Object
.
entries
(
formData
)
const
args
=
Object
.
entries
(
formData
)
.
sort
(
sortFields
(
data
))
.
sort
(
sortFields
(
inputs
))
.
map
(([
,
value
])
=>
value
);
.
map
(([
,
value
])
=>
value
);
// todo_tom delete mock
const
result
=
await
caller
(
data
,
args
);
setResult
(
outputs
.
map
(({
type
},
index
)
=>
([
type
,
args
[
index
]
])));
setResult
(
result
);
await
apiFetch
(
'
contract_method_query
'
,
{
},
[
caller
,
data
,
inputs
]);
pathParams
:
{
id
:
address
},
fetchParams
:
{
method
:
'
POST
'
,
body
:
{
args
,
method_id
:
methodId
,
},
},
});
},
[
address
,
apiFetch
,
data
,
methodId
,
outputs
]);
const
resultBgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
resultBgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
...
@@ -84,10 +74,10 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
...
@@ -84,10 +74,10 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
onSubmit=
{
handleSubmit
(
onSubmit
)
}
onSubmit=
{
handleSubmit
(
onSubmit
)
}
flexWrap=
"wrap"
flexWrap=
"wrap"
>
>
{
data
.
map
(({
type
,
name
},
index
)
=>
{
{
inputs
.
map
(({
type
,
name
},
index
)
=>
{
const
fieldName
=
getFieldName
(
name
,
index
);
const
fieldName
=
getFieldName
(
name
,
index
);
return
(
return
(
<
Contract
ReadItemInput
Field
<
Contract
Method
Field
key=
{
fieldName
}
key=
{
fieldName
}
name=
{
fieldName
}
name=
{
fieldName
}
placeholder=
{
`${ name }(${ type })`
}
placeholder=
{
`${ name }(${ type })`
}
...
@@ -105,14 +95,16 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
...
@@ -105,14 +95,16 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
Query
Query
</
Button
>
</
Button
>
</
chakra
.
form
>
</
chakra
.
form
>
<
Flex
mt=
{
3
}
>
{
'
outputs
'
in
data
&&
data
.
outputs
.
length
>
0
&&
(
<
Icon
as=
{
arrowIcon
}
boxSize=
{
5
}
mr=
{
1
}
/>
<
Flex
mt=
{
3
}
>
<
Text
>
{
outputs
.
map
(({
type
})
=>
type
).
join
(
'
,
'
)
}
</
Text
>
<
Icon
as=
{
arrowIcon
}
boxSize=
{
5
}
mr=
{
1
}
/>
</
Flex
>
<
Text
>
{
data
.
outputs
.
map
(({
type
})
=>
type
).
join
(
'
,
'
)
}
</
Text
>
</
Flex
>
)
}
{
result
.
length
>
0
&&
(
{
result
.
length
>
0
&&
(
<
Box
mt=
{
3
}
p=
{
4
}
borderRadius=
"md"
bgColor=
{
resultBgColor
}
fontSize=
"sm"
>
<
Box
mt=
{
3
}
p=
{
4
}
borderRadius=
"md"
bgColor=
{
resultBgColor
}
fontSize=
"sm"
>
<
p
>
<
p
>
[
<
chakra
.
span
fontWeight=
{
600
}
>
{
methodName
}
</
chakra
.
span
>
method R
esponse ]
[
<
chakra
.
span
fontWeight=
{
600
}
>
{
'
name
'
in
data
?
data
.
name
:
''
}
</
chakra
.
span
>
method r
esponse ]
</
p
>
</
p
>
<
p
>
[
</
p
>
<
p
>
[
</
p
>
{
result
.
map
(([
key
,
value
],
index
)
=>
(
{
result
.
map
(([
key
,
value
],
index
)
=>
(
...
@@ -125,4 +117,4 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
...
@@ -125,4 +117,4 @@ const ContractReadItemInput = ({ data, address, methodId, methodName, outputs }:
);
);
}
;
}
;
export
default
ContractReadItemInput
;
export default
React.memo(ContractMethodCallable) as typeof ContractMethodCallable
;
ui/address/contract/Contract
ReadItemOutpu
t.tsx
→
ui/address/contract/Contract
MethodConstan
t.tsx
View file @
961fb314
...
@@ -12,12 +12,16 @@ interface Props {
...
@@ -12,12 +12,16 @@ interface Props {
data
:
SmartContractMethodOutput
;
data
:
SmartContractMethodOutput
;
}
}
const
Contract
ReadItemOutput
=
({
data
}:
Props
)
=>
{
const
Contract
MethodStatic
=
({
data
}:
Props
)
=>
{
const
isBigInt
=
data
.
type
.
includes
(
'
int256
'
)
||
data
.
type
.
includes
(
'
int128
'
);
const
isBigInt
=
data
.
type
.
includes
(
'
int256
'
)
||
data
.
type
.
includes
(
'
int128
'
);
const
[
value
,
setValue
]
=
React
.
useState
(
isBigInt
?
BigNumber
(
data
.
value
).
toFixed
()
:
data
.
value
);
const
[
value
,
setValue
]
=
React
.
useState
(
isBigInt
&&
data
.
value
?
BigNumber
(
data
.
value
).
toFixed
()
:
data
.
value
);
const
[
label
,
setLabel
]
=
React
.
useState
(
'
WEI
'
);
const
[
label
,
setLabel
]
=
React
.
useState
(
'
WEI
'
);
const
handleCheckboxChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleCheckboxChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
if
(
!
data
.
value
)
{
return
;
}
if
(
event
.
target
.
checked
)
{
if
(
event
.
target
.
checked
)
{
setValue
(
BigNumber
(
data
.
value
).
div
(
WEI
).
toFixed
());
setValue
(
BigNumber
(
data
.
value
).
div
(
WEI
).
toFixed
());
setLabel
(
appConfig
.
network
.
currency
.
symbol
||
'
ETH
'
);
setLabel
(
appConfig
.
network
.
currency
.
symbol
||
'
ETH
'
);
...
@@ -35,4 +39,4 @@ const ContractReadItemOutput = ({ data }: Props) => {
...
@@ -35,4 +39,4 @@ const ContractReadItemOutput = ({ data }: Props) => {
);
);
};
};
export
default
Contract
ReadItemOutput
;
export
default
Contract
MethodStatic
;
ui/address/contract/Contract
ReadItemInput
Field.tsx
→
ui/address/contract/Contract
Method
Field.tsx
View file @
961fb314
...
@@ -3,18 +3,18 @@ import React from 'react';
...
@@ -3,18 +3,18 @@ import React from 'react';
import
type
{
Control
,
ControllerRenderProps
,
UseFormSetValue
}
from
'
react-hook-form
'
;
import
type
{
Control
,
ControllerRenderProps
,
UseFormSetValue
}
from
'
react-hook-form
'
;
import
{
Controller
}
from
'
react-hook-form
'
;
import
{
Controller
}
from
'
react-hook-form
'
;
import
type
{
Method
Input
Fields
}
from
'
./types
'
;
import
type
{
Method
Form
Fields
}
from
'
./types
'
;
import
InputClearButton
from
'
ui/shared/InputClearButton
'
;
import
InputClearButton
from
'
ui/shared/InputClearButton
'
;
interface
Props
{
interface
Props
{
control
:
Control
<
Method
Input
Fields
>
;
control
:
Control
<
Method
Form
Fields
>
;
setValue
:
UseFormSetValue
<
Method
Input
Fields
>
;
setValue
:
UseFormSetValue
<
Method
Form
Fields
>
;
placeholder
:
string
;
placeholder
:
string
;
name
:
string
;
name
:
string
;
}
}
const
Contract
ReadItemInput
Field
=
({
control
,
name
,
placeholder
,
setValue
}:
Props
)
=>
{
const
Contract
Method
Field
=
({
control
,
name
,
placeholder
,
setValue
}:
Props
)
=>
{
const
ref
=
React
.
useRef
<
HTMLInputElement
>
(
null
);
const
ref
=
React
.
useRef
<
HTMLInputElement
>
(
null
);
const
handleClear
=
React
.
useCallback
(()
=>
{
const
handleClear
=
React
.
useCallback
(()
=>
{
...
@@ -22,7 +22,7 @@ const ContractReadItemInputField = ({ control, name, placeholder, setValue }: Pr
...
@@ -22,7 +22,7 @@ const ContractReadItemInputField = ({ control, name, placeholder, setValue }: Pr
ref
.
current
?.
focus
();
ref
.
current
?.
focus
();
},
[
name
,
setValue
]);
},
[
name
,
setValue
]);
const
renderInput
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Method
Input
Fields
>
})
=>
{
const
renderInput
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Method
Form
Fields
>
})
=>
{
return
(
return
(
<
FormControl
id=
{
name
}
maxW=
{
{
base
:
'
100%
'
,
lg
:
'
calc((100% - 24px) / 3)
'
}
}
>
<
FormControl
id=
{
name
}
maxW=
{
{
base
:
'
100%
'
,
lg
:
'
calc((100% - 24px) / 3)
'
}
}
>
<
InputGroup
size=
"xs"
>
<
InputGroup
size=
"xs"
>
...
@@ -51,4 +51,4 @@ const ContractReadItemInputField = ({ control, name, placeholder, setValue }: Pr
...
@@ -51,4 +51,4 @@ const ContractReadItemInputField = ({ control, name, placeholder, setValue }: Pr
);
);
};
};
export
default
ContractReadItemInputField
;
export
default
React
.
memo
(
ContractMethodField
)
;
ui/address/contract/ContractMethodsAccordion.tsx
0 → 100644
View file @
961fb314
import
{
Accordion
,
AccordionButton
,
AccordionIcon
,
AccordionItem
,
AccordionPanel
,
Box
,
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
_range
from
'
lodash/range
'
;
import
React
from
'
react
'
;
import
type
{
SmartContractMethod
}
from
'
types/api/contract
'
;
interface
Props
<
T
extends
SmartContractMethod
>
{
data
:
Array
<
T
>
;
renderContent
:
(
item
:
T
,
index
:
number
,
id
:
number
)
=>
React
.
ReactNode
;
}
const
ContractMethodsAccordion
=
<
T
extends
SmartContractMethod
>
(
{
data
,
renderContent
}
: Props
<
T
>
) =
>
{
const
[
expandedSections
,
setExpandedSections
]
=
React
.
useState
<
Array
<
number
>>
([]);
const
[
id
,
setId
]
=
React
.
useState
(
0
);
const
handleAccordionStateChange
=
React
.
useCallback
((
newValue
:
Array
<
number
>
)
=>
{
setExpandedSections
(
newValue
);
},
[]);
const
handleExpandAll
=
React
.
useCallback
(()
=>
{
if
(
!
data
)
{
return
;
}
if
(
expandedSections
.
length
<
data
.
length
)
{
setExpandedSections
(
_range
(
0
,
data
.
length
));
}
else
{
setExpandedSections
([]);
}
},
[
data
,
expandedSections
.
length
]);
const
handleReset
=
React
.
useCallback
(()
=>
{
setId
((
id
)
=>
id
+
1
);
},
[]);
return
(
<
Accordion
allowMultiple
position=
"relative"
onChange=
{
handleAccordionStateChange
}
index=
{
expandedSections
}
>
{
data
.
map
((
item
,
index
)
=>
{
return
(
<
AccordionItem
key=
{
index
}
as=
"section"
>
<
h2
>
<
AccordionButton
px=
{
0
}
py=
{
3
}
_hover=
{
{
bgColor
:
'
inherit
'
}
}
>
<
Box
as=
"span"
fontFamily=
"heading"
fontWeight=
{
500
}
fontSize=
"lg"
mr=
{
1
}
>
{
index
+
1
}
.
{
item
.
type
===
'
fallback
'
?
'
fallback
'
:
item
.
name
}
</
Box
>
<
AccordionIcon
/>
</
AccordionButton
>
</
h2
>
<
AccordionPanel
pb=
{
4
}
px=
{
0
}
>
{
renderContent
(
item
,
index
,
id
)
}
</
AccordionPanel
>
</
AccordionItem
>
);
})
}
<
Flex
columnGap=
{
3
}
position=
"absolute"
top=
{
0
}
right=
{
0
}
py=
{
3
}
lineHeight=
"27px"
>
<
Link
onClick=
{
handleExpandAll
}
>
{
expandedSections
.
length
===
data
.
length
?
'
Collapse
'
:
'
Expand
'
}
all
</
Link
>
<
Link
onClick=
{
handleReset
}
>
Reset
</
Link
>
</
Flex
>
</
Accordion
>
);
}
;
export default React.memo(ContractMethodsAccordion) as typeof ContractMethodsAccordion;
ui/address/contract/ContractRead.tsx
View file @
961fb314
import
{
Accordion
,
AccordionButton
,
AccordionIcon
,
AccordionItem
,
AccordionPanel
,
Box
,
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
_range
from
'
lodash/range
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SmartContractReadMethod
}
from
'
types/api/contract
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
ContractMethodsAccordion
from
'
ui/address/contract/ContractMethodsAccordion
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
Contract
ReadItemInput
from
'
./ContractReadItemInput
'
;
import
Contract
MethodCallable
from
'
./ContractMethodCallable
'
;
import
Contract
ReadItemOutput
from
'
./ContractReadItemOutpu
t
'
;
import
Contract
MethodConstant
from
'
./ContractMethodConstan
t
'
;
const
ContractRead
=
()
=>
{
const
ContractRead
=
()
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
apiFetch
=
useApiFetch
();
const
[
expandedSections
,
setExpandedSections
]
=
React
.
useState
<
Array
<
number
>>
([]);
const
[
id
,
setId
]
=
React
.
useState
(
0
);
const
addressHash
=
router
.
query
.
id
?.
toString
();
const
addressHash
=
router
.
query
.
id
?.
toString
();
...
@@ -24,80 +26,48 @@ const ContractRead = () => {
...
@@ -24,80 +26,48 @@ const ContractRead = () => {
},
},
});
});
const
contractInfo
=
useApiQuery
(
'
contract
'
,
{
const
contractCaller
=
React
.
useCallback
(
async
(
item
:
SmartContractReadMethod
,
args
:
Array
<
string
>
)
=>
{
pathParams
:
{
id
:
addressHash
},
await
apiFetch
(
'
contract_method_query
'
,
{
queryOptions
:
{
pathParams
:
{
id
:
addressHash
},
enabled
:
Boolean
(
router
.
query
.
id
),
fetchParams
:
{
},
method
:
'
POST
'
,
});
body
:
{
args
,
method_id
:
item
.
method_id
,
},
},
});
const
handleAccordionStateChange
=
React
.
useCallback
((
newValue
:
Array
<
number
>
)
=>
{
return
[
[
'
string
'
,
'
this is mock
'
]
];
setExpandedSections
(
newValue
);
},
[
addressHash
,
apiFetch
]);
},
[]);
const
handleExpandAll
=
React
.
useCallback
(()
=>
{
if
(
!
data
)
{
return
;
}
if
(
expandedSections
.
length
<
data
.
length
)
{
const
renderContent
=
React
.
useCallback
((
item
:
SmartContractReadMethod
,
index
:
number
,
id
:
number
)
=>
{
setExpandedSections
(
_range
(
0
,
data
.
length
));
if
(
item
.
inputs
.
length
===
0
)
{
}
else
{
return
(
setExpandedSections
([]);
<
Flex
flexDir=
"column"
rowGap=
{
1
}
>
{
item
.
outputs
.
map
((
output
,
index
)
=>
<
ContractMethodConstant
key=
{
index
}
data=
{
output
}
/>)
}
</
Flex
>
);
}
}
},
[
data
,
expandedSections
.
length
]);
const
handleReset
=
React
.
useCallback
(()
=>
{
return
(
setId
((
id
)
=>
id
+
1
);
<
ContractMethodCallable
},
[]);
key=
{
id
+
'
_
'
+
index
}
data=
{
item
}
caller=
{
contractCaller
}
/>
);
},
[
contractCaller
]);
if
(
isError
)
{
if
(
isError
)
{
return
<
DataFetchAlert
/>;
return
<
DataFetchAlert
/>;
}
}
if
(
isLoading
)
{
if
(
isLoading
)
{
return
<
span
>
loading...
</
span
>;
return
<
ContentLoader
/
>;
}
}
return
(
return
<
ContractMethodsAccordion
data=
{
data
}
renderContent=
{
renderContent
}
/>;
<
Accordion
allowMultiple
position=
"relative"
onChange=
{
handleAccordionStateChange
}
index=
{
expandedSections
}
>
{
data
.
map
((
item
,
index
)
=>
{
return
(
<
AccordionItem
key=
{
item
.
name
+
'
_
'
+
item
.
method_id
}
as=
"section"
>
<
h2
>
<
AccordionButton
px=
{
0
}
py=
{
3
}
_hover=
{
{
bgColor
:
'
inherit
'
}
}
>
<
Box
as=
"span"
fontFamily=
"heading"
fontWeight=
{
500
}
fontSize=
"lg"
mr=
{
1
}
>
{
index
+
1
}
.
{
item
.
name
}
</
Box
>
<
AccordionIcon
/>
</
AccordionButton
>
</
h2
>
<
AccordionPanel
pb=
{
4
}
px=
{
0
}
>
{
item
.
inputs
.
length
===
0
?
(
<
Flex
flexDir=
"column"
rowGap=
{
1
}
>
{
item
.
outputs
.
map
((
output
,
index
)
=>
<
ContractReadItemOutput
key=
{
index
}
data=
{
output
}
/>)
}
</
Flex
>
)
:
(
<
ContractReadItemInput
key=
{
id
+
'
_
'
+
index
}
data=
{
item
.
inputs
}
address=
{
addressHash
}
abi=
{
contractInfo
.
data
?.
abi
}
methodName=
{
item
.
name
}
methodId=
{
item
.
method_id
}
outputs=
{
item
.
outputs
}
/>
)
}
</
AccordionPanel
>
</
AccordionItem
>
);
})
}
<
Flex
columnGap=
{
3
}
position=
"absolute"
top=
{
0
}
right=
{
0
}
py=
{
3
}
lineHeight=
"27px"
>
<
Link
onClick=
{
handleExpandAll
}
>
{
expandedSections
.
length
===
data
.
length
?
'
Collapse
'
:
'
Expand
'
}
all
</
Link
>
<
Link
onClick=
{
handleReset
}
>
Reset
</
Link
>
</
Flex
>
</
Accordion
>
);
};
};
export
default
ContractRead
;
export
default
ContractRead
;
ui/address/contract/ContractWrite.tsx
0 → 100644
View file @
961fb314
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
type
{
SmartContractWriteMethod
}
from
'
types/api/contract
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
ContractMethodsAccordion
from
'
ui/address/contract/ContractMethodsAccordion
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
ContractMethodCallable
from
'
./ContractMethodCallable
'
;
const
ContractWrite
=
()
=>
{
const
router
=
useRouter
();
const
addressHash
=
router
.
query
.
id
?.
toString
();
const
{
data
,
isLoading
,
isError
}
=
useApiQuery
(
'
contract_methods_write
'
,
{
pathParams
:
{
id
:
addressHash
},
queryOptions
:
{
enabled
:
Boolean
(
router
.
query
.
id
),
},
});
const
contractInfo
=
useApiQuery
(
'
contract
'
,
{
pathParams
:
{
id
:
addressHash
},
queryOptions
:
{
enabled
:
Boolean
(
router
.
query
.
id
),
},
});
const
contractCaller
=
React
.
useCallback
(
async
()
=>
{
// eslint-disable-next-line no-console
console
.
log
(
'
__>__
'
,
contractInfo
);
return
[
[
'
string
'
,
'
this is mock
'
]
];
},
[
contractInfo
]);
const
renderContent
=
React
.
useCallback
((
item
:
SmartContractWriteMethod
,
index
:
number
,
id
:
number
)
=>
{
return
(
<
ContractMethodCallable
key=
{
id
+
'
_
'
+
index
}
data=
{
item
}
caller=
{
contractCaller
}
/>
);
},
[
contractCaller
]);
if
(
isError
)
{
return
<
DataFetchAlert
/>;
}
if
(
isLoading
)
{
return
<
ContentLoader
/>;
}
return
<
ContractMethodsAccordion
data=
{
data
}
renderContent=
{
renderContent
}
/>;
};
export
default
ContractWrite
;
ui/address/contract/types.ts
View file @
961fb314
export
type
Method
Input
Fields
=
Record
<
string
,
string
>
;
export
type
Method
Form
Fields
=
Record
<
string
,
string
>
;
ui/pages/Address.tsx
View file @
961fb314
...
@@ -16,6 +16,7 @@ import AddressTokenTransfers from 'ui/address/AddressTokenTransfers';
...
@@ -16,6 +16,7 @@ import AddressTokenTransfers from 'ui/address/AddressTokenTransfers';
import
AddressTxs
from
'
ui/address/AddressTxs
'
;
import
AddressTxs
from
'
ui/address/AddressTxs
'
;
import
ContractCode
from
'
ui/address/contract/ContractCode
'
;
import
ContractCode
from
'
ui/address/contract/ContractCode
'
;
import
ContractRead
from
'
ui/address/contract/ContractRead
'
;
import
ContractRead
from
'
ui/address/contract/ContractRead
'
;
import
ContractWrite
from
'
ui/address/contract/ContractWrite
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
...
@@ -27,7 +28,7 @@ const CONTRACT_TABS = [
...
@@ -27,7 +28,7 @@ const CONTRACT_TABS = [
{
id
:
'
contact_decompiled_code
'
,
title
:
'
Decompiled code
'
,
component
:
<
div
>
Decompiled code
</
div
>
},
{
id
:
'
contact_decompiled_code
'
,
title
:
'
Decompiled code
'
,
component
:
<
div
>
Decompiled code
</
div
>
},
{
id
:
'
read_contract
'
,
title
:
'
Read contract
'
,
component
:
<
ContractRead
/>
},
{
id
:
'
read_contract
'
,
title
:
'
Read contract
'
,
component
:
<
ContractRead
/>
},
{
id
:
'
read_proxy
'
,
title
:
'
Read proxy
'
,
component
:
<
div
>
Read proxy
</
div
>
},
{
id
:
'
read_proxy
'
,
title
:
'
Read proxy
'
,
component
:
<
div
>
Read proxy
</
div
>
},
{
id
:
'
write_contract
'
,
title
:
'
Write contract
'
,
component
:
<
div
>
Write contract
</
div
>
},
{
id
:
'
write_contract
'
,
title
:
'
Write contract
'
,
component
:
<
ContractWrite
/
>
},
{
id
:
'
write_proxy
'
,
title
:
'
Write proxy
'
,
component
:
<
div
>
Write proxy
</
div
>
},
{
id
:
'
write_proxy
'
,
title
:
'
Write proxy
'
,
component
:
<
div
>
Write proxy
</
div
>
},
];
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment