Skip to content

Commit 278ba38

Browse files
committed
Add contract templates
1 parent 3806ff1 commit 278ba38

File tree

9 files changed

+729
-8
lines changed

9 files changed

+729
-8
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { templates } from 'resources/subgraph-templates'
2+
import styled from 'styled-components'
3+
4+
interface ContractTemplateSelector {
5+
selected: string[]
6+
onChange: (templates: string[]) => void
7+
}
8+
9+
const List = styled.ul`
10+
margin: 0;
11+
padding: 0;
12+
display: flex;
13+
`
14+
15+
const Item = styled.li<{ selected: boolean }>`
16+
list-style: none;
17+
background: ${({ selected }) => (selected ? '#99999977' : 'transparent')};
18+
border: solid 1px #aaaaaa;
19+
border-radius: 8px;
20+
color: ${({ selected }) => (selected ? 'var(--color-white);' : '#aaaaaa')};
21+
padding: 4px 12px;
22+
margin: 2px;
23+
24+
&:hover {
25+
cursor: pointer;
26+
background: #44444477;
27+
}
28+
`
29+
30+
export default function ContractTemplateSelector({ selected, onChange }: ContractTemplateSelector) {
31+
return (
32+
<List>
33+
{templates.map(template => (
34+
<Item
35+
selected={selected.includes(template.id)}
36+
onClick={
37+
selected.includes(template.id)
38+
? () => onChange(selected.filter(item => item !== template.id))
39+
: () => onChange([...selected, template.id])
40+
}
41+
>
42+
{template.name || template.id}
43+
</Item>
44+
))}
45+
</List>
46+
)
47+
}

components/SubgraphEditor/SubgraphConfig/SubgraphConfig.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Dropdown } from '../../atoms'
1010
import { addImport } from 'utils/source-code-utils'
1111
import { generateLibrariesForSubgraph } from 'utils/graph-file-generator'
1212
import { compileAs } from 'utils/deploy-subgraph'
13+
import ContractTemplateSelector from './ContractTemplateSelector'
1314

1415
const Root = styled.div`
1516
min-height: 100vh;
@@ -28,9 +29,7 @@ const Title = styled.h3`
2829
font-size: 32px;
2930
font-weight: bold;
3031
color: #ffffff;
31-
max-width: 250px;
32-
margin: 0px;
33-
margin-bottom: 24px;
32+
margin: 8px 0 24px;
3433
`
3534

3635
const InfoMsg = styled.span`
@@ -174,6 +173,10 @@ export const SubgraphConfig = (props: SubgraphConfigProps) => {
174173
return null
175174
}
176175

176+
if (!subgraph) {
177+
return <div>Error: Subgraph not found</div>
178+
}
179+
177180
const updateSelectedContract = (address: string, newProps: Partial<Contract>) => {
178181
if (!subgraph) {
179182
throw new Error('No subgraph')
@@ -236,6 +239,14 @@ export const SubgraphConfig = (props: SubgraphConfigProps) => {
236239
/>
237240
{errorState.version ? <ErrorState>{errorState.version}</ErrorState> : null}
238241

242+
<Title>Contract Templates</Title>
243+
<ContractTemplateSelector
244+
selected={subgraph.templates || []}
245+
onChange={newTemplates =>
246+
update(_subgraph => ({ ..._subgraph, templates: newTemplates }))
247+
}
248+
/>
249+
239250
<Title>Contracts</Title>
240251
<InputLabel>Add contract</InputLabel>
241252
<ContractInput

hooks/local-subgraphs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const storageKey = 'localSubgraphs'
55

66
export const DEFAULT_MAPPING = 'mapping.ts'
77

8+
const DEFAULT_TEMPLATES = ['ERC20', 'ERC721']
9+
810
interface Publication {
911
cid: string
1012
version: string
@@ -34,6 +36,7 @@ export interface SubgraphData {
3436
schema: string
3537
version: string
3638
contracts: Contract[]
39+
templates: string[]
3740
publications: Publication[]
3841
publishConfig: PublishConfig | null
3942
}
@@ -81,6 +84,7 @@ export const newSubgraph = ({
8184
schema,
8285
name: 'Untitled subgraph',
8386
contracts,
87+
templates: DEFAULT_TEMPLATES,
8488
publications,
8589
version: '0.0.1',
8690
publishConfig: DEFAULT_PUBLISH_CONFIG,

hooks/useGeneratedFiles.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { SubgraphData } from './local-subgraphs'
88
// @ts-ignore
99
import assemblyscriptGlobals from '!raw-loader!assemblyscript/std/assembly/index.d.ts'
10+
import { templates } from 'resources/subgraph-templates'
1011

1112
export const useGeneratedFiles = (subgraph: SubgraphData | null) => {
1213
const [files, setFiles] = useState<{ content: string; filePath: string }[]>([])
@@ -32,6 +33,19 @@ export const useGeneratedFiles = (subgraph: SubgraphData | null) => {
3233
console.error(`Error generating file for ${contract.name}: ${e.message}`)
3334
}
3435
}
36+
37+
for (const templateId of subgraph.templates || []) {
38+
const template = templates.find(template => template.id === templateId)
39+
if (!template) {
40+
console.warn(`Contract template ${templateId} not found`)
41+
continue
42+
}
43+
const code = await generateContractFile(template.id, template.abi)
44+
_files.push({ filePath: `file:///contracts/${template.id}.ts`, content: code })
45+
const templateCode = await generateTemplateFile(template.id)
46+
_files.push({ filePath: `file:///templates/${template.id}.ts`, content: templateCode })
47+
}
48+
3549
setFiles(_files)
3650
}
3751

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
[
2+
{
3+
"constant": true,
4+
"inputs": [],
5+
"name": "name",
6+
"outputs": [
7+
{
8+
"name": "",
9+
"type": "string"
10+
}
11+
],
12+
"payable": false,
13+
"stateMutability": "view",
14+
"type": "function"
15+
},
16+
{
17+
"constant": false,
18+
"inputs": [
19+
{
20+
"name": "_spender",
21+
"type": "address"
22+
},
23+
{
24+
"name": "_value",
25+
"type": "uint256"
26+
}
27+
],
28+
"name": "approve",
29+
"outputs": [
30+
{
31+
"name": "",
32+
"type": "bool"
33+
}
34+
],
35+
"payable": false,
36+
"stateMutability": "nonpayable",
37+
"type": "function"
38+
},
39+
{
40+
"constant": true,
41+
"inputs": [],
42+
"name": "totalSupply",
43+
"outputs": [
44+
{
45+
"name": "",
46+
"type": "uint256"
47+
}
48+
],
49+
"payable": false,
50+
"stateMutability": "view",
51+
"type": "function"
52+
},
53+
{
54+
"constant": false,
55+
"inputs": [
56+
{
57+
"name": "_from",
58+
"type": "address"
59+
},
60+
{
61+
"name": "_to",
62+
"type": "address"
63+
},
64+
{
65+
"name": "_value",
66+
"type": "uint256"
67+
}
68+
],
69+
"name": "transferFrom",
70+
"outputs": [
71+
{
72+
"name": "",
73+
"type": "bool"
74+
}
75+
],
76+
"payable": false,
77+
"stateMutability": "nonpayable",
78+
"type": "function"
79+
},
80+
{
81+
"constant": true,
82+
"inputs": [],
83+
"name": "decimals",
84+
"outputs": [
85+
{
86+
"name": "",
87+
"type": "uint8"
88+
}
89+
],
90+
"payable": false,
91+
"stateMutability": "view",
92+
"type": "function"
93+
},
94+
{
95+
"constant": true,
96+
"inputs": [
97+
{
98+
"name": "_owner",
99+
"type": "address"
100+
}
101+
],
102+
"name": "balanceOf",
103+
"outputs": [
104+
{
105+
"name": "balance",
106+
"type": "uint256"
107+
}
108+
],
109+
"payable": false,
110+
"stateMutability": "view",
111+
"type": "function"
112+
},
113+
{
114+
"constant": true,
115+
"inputs": [],
116+
"name": "symbol",
117+
"outputs": [
118+
{
119+
"name": "",
120+
"type": "string"
121+
}
122+
],
123+
"payable": false,
124+
"stateMutability": "view",
125+
"type": "function"
126+
},
127+
{
128+
"constant": false,
129+
"inputs": [
130+
{
131+
"name": "_to",
132+
"type": "address"
133+
},
134+
{
135+
"name": "_value",
136+
"type": "uint256"
137+
}
138+
],
139+
"name": "transfer",
140+
"outputs": [
141+
{
142+
"name": "",
143+
"type": "bool"
144+
}
145+
],
146+
"payable": false,
147+
"stateMutability": "nonpayable",
148+
"type": "function"
149+
},
150+
{
151+
"constant": true,
152+
"inputs": [
153+
{
154+
"name": "_owner",
155+
"type": "address"
156+
},
157+
{
158+
"name": "_spender",
159+
"type": "address"
160+
}
161+
],
162+
"name": "allowance",
163+
"outputs": [
164+
{
165+
"name": "",
166+
"type": "uint256"
167+
}
168+
],
169+
"payable": false,
170+
"stateMutability": "view",
171+
"type": "function"
172+
},
173+
{
174+
"payable": true,
175+
"stateMutability": "payable",
176+
"type": "fallback"
177+
},
178+
{
179+
"anonymous": false,
180+
"inputs": [
181+
{
182+
"indexed": true,
183+
"name": "owner",
184+
"type": "address"
185+
},
186+
{
187+
"indexed": true,
188+
"name": "spender",
189+
"type": "address"
190+
},
191+
{
192+
"indexed": false,
193+
"name": "value",
194+
"type": "uint256"
195+
}
196+
],
197+
"name": "Approval",
198+
"type": "event"
199+
},
200+
{
201+
"anonymous": false,
202+
"inputs": [
203+
{
204+
"indexed": true,
205+
"name": "from",
206+
"type": "address"
207+
},
208+
{
209+
"indexed": true,
210+
"name": "to",
211+
"type": "address"
212+
},
213+
{
214+
"indexed": false,
215+
"name": "value",
216+
"type": "uint256"
217+
}
218+
],
219+
"name": "Transfer",
220+
"type": "event"
221+
}
222+
]

0 commit comments

Comments
 (0)