Skip to content

Commit 4c3453b

Browse files
saleelPhilWindlealexghrThunkar
authored
chore: playground improvements (#13588)
- Add profiler to playground - Upload your own contract: - show which version of `aztec-up` - link to tutorial to push before to write their own contract - make instructions less transparent - Contract Interaction - show parameter type in the text box - authwit move description up and explain caller - Add tool tip for simulate, send, authwit, profiler - Connect to Sandbox - show what version to deploy on - Register contract - When selecting contract, load AbI per usual and then automatically load deploy pop up - register/deploy button - Rename button to - “click here to load this pre deployed contract” - rename to “deploy/load contract” - Select Contract/Account - when deployed, the menu item should show “Contract: TST (0x123…) - Add Account: - Add “recommended” next to r1 - Add contact - show that contact is of aztec address type - Make log button is more obvious (it is a red button now like a chat) - Inspiration button“start building” - Set tx timeout to 2 mins --------- Co-authored-by: PhilWindle <[email protected]> Co-authored-by: Alex Gherghisan <[email protected]> Co-authored-by: thunkar <[email protected]>
1 parent 3976e8e commit 4c3453b

22 files changed

+880
-436
lines changed

playground/src/components/common/FnParameter.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,34 @@ export function FunctionParameter({ parameter, required, onParameterChange }: Fu
6565
}
6666
};
6767

68+
function getParameterType(type: AbiType) {
69+
switch (type.kind) {
70+
case 'field':
71+
return 'number';
72+
case 'integer':
73+
return 'number';
74+
case 'string':
75+
return 'text';
76+
default:
77+
return 'text';
78+
}
79+
}
80+
81+
function getParameterLabel(type: AbiType) {
82+
switch (type.kind) {
83+
case 'field':
84+
return 'number';
85+
case 'integer':
86+
return 'int';
87+
case 'string':
88+
return 'string';
89+
case 'boolean':
90+
return 'bool';
91+
default:
92+
return '';
93+
}
94+
}
95+
6896
return (
6997
<div css={container}>
7098
{isAddressStruct(parameter.type) && !manualInput ? (
@@ -112,8 +140,8 @@ export function FunctionParameter({ parameter, required, onParameterChange }: Fu
112140
variant="outlined"
113141
disabled={['array', 'struct', 'tuple'].includes(parameter.type.kind) && !isAddressStruct(parameter.type)}
114142
key={parameter.name}
115-
type="text"
116-
label={capitalize(parameter.name)}
143+
type={getParameterType(parameter.type)}
144+
label={`${capitalize(parameter.name)} (${getParameterLabel(parameter.type)})`}
117145
onChange={e => handleParameterChange(e.target.value, parameter.type)}
118146
/>
119147
)}

playground/src/components/common/LoadingModal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,15 @@ const funFacts = [
165165
'The Aztec protocol was founded in 2017',
166166
"We're almost there...",
167167
'Aztec Connect was the first private DeFi application',
168-
'Aztec invented PLONK which is really cool',
168+
'Aztec invented PLONK which is really cool and underpins all modern zkVMs',
169169
'Aztec supports private, public, and hybrid smart contract execution',
170-
'Aztec enables privacy and full composability',
170+
'Aztec enables privacy and full composability across private and public calls',
171+
'All transactions on Aztec start off private (since all accounts and transaction entrypoints are private)',
172+
'Aztec is the first L2 to launch a decentralized testnet on day 1',
173+
'While you wait for this proof, check out somethinghappened.wtf',
171174
];
172175

176+
173177
export function LoadingModal() {
174178
const { currentTx, setCurrentTx, logs } = useContext(AztecContext);
175179
const [currentFunFact, setCurrentFunFact] = useState(0);

playground/src/components/contract/Contract.tsx

Lines changed: 96 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ import { formatFrAsString } from '../../utils/conversion';
1919
import { CreateContractDialog } from './components/CreateContractDialog';
2020
import ClearIcon from '@mui/icons-material/Clear';
2121
import { CopyToClipboardButton } from '../common/CopyToClipboardButton';
22+
2223
import { ContractUpload } from './components/ContractUpload';
2324
import { ContractFilter } from './components/ContractFilter';
2425
import { FunctionCard } from './components/FunctionCard';
2526
import { useTransaction } from '../../hooks/useTransaction';
27+
import { ContractDescriptions, ContractDocumentationLinks, ContractMethodOrder } from '../../utils/constants';
28+
import Box from '@mui/material/Box';
29+
import CardContent from '@mui/material/CardContent';
30+
import Card from '@mui/material/Card';
2631

2732
const container = css({
2833
display: 'flex',
@@ -55,15 +60,39 @@ const headerContainer = css({
5560

5661
const header = css({
5762
display: 'flex',
63+
flexDirection: 'column',
5864
width: '100%',
65+
alignItems: 'flex-start',
66+
justifyContent: 'space-between',
67+
});
68+
69+
const titleContainer = css({
70+
display: 'flex',
71+
flexDirection: 'row',
5972
alignItems: 'center',
6073
justifyContent: 'space-between',
74+
width: '100%',
75+
marginBottom: '1rem',
6176
});
6277

6378
const contractActions = css({
6479
display: 'flex',
6580
flexDirection: 'row',
6681
alignItems: 'center',
82+
minWidth: '150px',
83+
});
84+
85+
const deployButton = css({
86+
background: '#8C7EFF',
87+
height: '30px',
88+
fontSize: '14px',
89+
fontWeight: 600,
90+
padding: '20px 16px',
91+
borderRadius: '6px',
92+
'@media (max-width: 900px)': {
93+
padding: '4px',
94+
height: 'auto',
95+
},
6796
});
6897

6998
const loadingArtifactContainer = css({
@@ -137,6 +166,12 @@ export function ContractComponent() {
137166
}
138167
}, [currentContractArtifact, currentContractAddress, wallet]);
139168

169+
useEffect(() => {
170+
if (!currentContractAddress) {
171+
setOpenCreateContractDialog(true);
172+
}
173+
}, [currentContractAddress]);
174+
140175
const handleContractCreation = async (
141176
contract?: ContractInstanceWithAddress,
142177
publiclyDeploy?: boolean,
@@ -173,39 +208,51 @@ export function ContractComponent() {
173208
<div css={contractFnContainer}>
174209
<div css={headerContainer}>
175210
<div css={header}>
176-
<Typography variant="h3" css={contractName}>
177-
{currentContractArtifact.name}
178-
</Typography>
179-
{!currentContractAddress && wallet && (
180-
<div css={contractActions}>
181-
<Button size="small" variant="contained" onClick={() => setOpenCreateContractDialog(true)}>
182-
Register/Deploy
183-
</Button>
184-
{openCreateContractDialog && (
185-
<CreateContractDialog
186-
contractArtifact={currentContractArtifact}
187-
open={openCreateContractDialog}
188-
onClose={handleContractCreation}
189-
/>
190-
)}
191-
</div>
192-
)}
193-
{currentContractAddress && (
194-
<div css={contractActions}>
195-
<Typography color="text.secondary">{formatFrAsString(currentContractAddress.toString())}</Typography>
196-
<CopyToClipboardButton disabled={false} data={currentContractAddress.toString()} />
197-
<IconButton
198-
onClick={() => {
199-
setCurrentContractAddress(null);
200-
setCurrentContract(null);
201-
setCurrentContractArtifact(null);
202-
}}
203-
>
204-
<ClearIcon />
205-
</IconButton>
206-
</div>
211+
<Box sx={titleContainer}>
212+
<Typography variant="h3" css={contractName}>
213+
{currentContractArtifact.name}
214+
</Typography>
215+
216+
{!currentContractAddress && wallet && (
217+
<div css={contractActions}>
218+
<Button size="small" variant="contained" css={deployButton} onClick={() => setOpenCreateContractDialog(true)}>
219+
Deploy / Load Contract
220+
</Button>
221+
{openCreateContractDialog && (
222+
<CreateContractDialog
223+
contractArtifact={currentContractArtifact}
224+
open={openCreateContractDialog}
225+
onClose={handleContractCreation}
226+
/>
227+
)}
228+
</div>
229+
)}
230+
231+
{currentContractAddress && (
232+
<div css={contractActions}>
233+
<Typography color="text.secondary">{formatFrAsString(currentContractAddress.toString())}</Typography>
234+
<CopyToClipboardButton disabled={false} data={currentContractAddress.toString()} />
235+
<IconButton
236+
onClick={() => {
237+
setCurrentContractAddress(null);
238+
setCurrentContract(null);
239+
setCurrentContractArtifact(null);
240+
}}
241+
>
242+
<ClearIcon />
243+
</IconButton>
244+
</div>
245+
)}
246+
247+
</Box>
248+
249+
{!!ContractDescriptions[currentContractArtifact.name] && (
250+
<Typography variant="body1" css={{ marginBottom: '2rem' }}>
251+
{ContractDescriptions[currentContractArtifact.name]}
252+
</Typography>
207253
)}
208254
</div>
255+
209256
<ContractFilter filters={filters} onFilterChange={setFilters} />
210257
</div>
211258
{functionAbis
@@ -218,9 +265,26 @@ export function ContractComponent() {
218265
(filters.utility && fn.functionType === FunctionType.UTILITY)) &&
219266
(filters.searchTerm === '' || fn.name.includes(filters.searchTerm)),
220267
)
268+
.sort((a, b) => {
269+
if (ContractMethodOrder[currentContractArtifact.name]) {
270+
return ContractMethodOrder[currentContractArtifact.name]?.indexOf(a.name) - ContractMethodOrder[currentContractArtifact.name]?.indexOf(b.name)
271+
}
272+
return 0;
273+
})
221274
.map(fn => (
222-
<FunctionCard fn={fn} key={fn.name} contract={currentContract} onSendTxRequested={sendTx} />
275+
<FunctionCard fn={fn} key={fn.name} contract={currentContract} contractArtifact={currentContractArtifact} onSendTxRequested={sendTx} />
223276
))}
277+
278+
{!!ContractDocumentationLinks[currentContractArtifact.name] && (
279+
<Card sx={{ margin: '3rem 0.5rem' }}>
280+
<CardContent>
281+
<Typography variant="body1">
282+
<span>Find the in-depth tutorial for {currentContractArtifact.name} </span>
283+
<a href={ContractDocumentationLinks[currentContractArtifact.name]} target="_blank" rel="noopener noreferrer">here</a>
284+
</Typography>
285+
</CardContent>
286+
</Card>
287+
)}
224288
</div>
225289
)}
226290
</div>

playground/src/components/contract/components/ContractFilter.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const search = css({
1616
'@media (width > 800px)': {
1717
maxWidth: '500px',
1818
},
19+
marginBottom: '1rem',
1920
});
2021

2122
const checkBoxLabel = css({
@@ -58,7 +59,7 @@ export function ContractFilter({ filters, onFilterChange }: ContractFilterProps)
5859
}}
5960
>
6061
<Tooltip
61-
title="These functions are simulated locally and only proofs are sent to Aztec"
62+
title="Function signature and execution are kept private by executing locally and generating a zk proof of correct execution. The proof is sent to Aztec."
6263
arrow
6364
slotProps={{
6465
tooltip: {
@@ -112,7 +113,7 @@ export function ContractFilter({ filters, onFilterChange }: ContractFilterProps)
112113
</Tooltip>
113114

114115
<Tooltip
115-
title="Only invoked by applications that interact with contracts to perform state queries from an off-chain client. They are unconstrained, meaning no proofs are generated"
116+
title="These are off-chain getters (for you to query the state) without generating any proofs. They are unconstrained, so no proof is generated and data is fetched locally."
116117
arrow
117118
slotProps={{
118119
tooltip: {

playground/src/components/contract/components/ContractUpload.tsx

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import Typography from '@mui/material/Typography';
77
import UploadFileIcon from '@mui/icons-material/UploadFile';
88
import { useContext } from 'react';
99
import { AztecContext } from '../../../aztecEnv';
10+
import Box from '@mui/material/Box';
11+
import { VERSION } from '../../../utils/constants';
1012

1113
const dropZoneContainer = css({
1214
display: 'flex',
@@ -29,7 +31,7 @@ const uploadIcon = css({
2931
export function ContractUpload() {
3032
const { setCurrentContractArtifact } = useContext(AztecContext);
3133

32-
const { getRootProps, getInputProps } = useDropzone({
34+
const { getRootProps, getInputProps, } = useDropzone({
3335
onDrop: async files => {
3436
const file = files[0];
3537
const reader = new FileReader();
@@ -43,6 +45,7 @@ export function ContractUpload() {
4345
'application/json': ['.json'],
4446
},
4547
multiple: false,
48+
noDragEventsBubbling: true,
4649
});
4750

4851
return (
@@ -54,9 +57,31 @@ export function ContractUpload() {
5457
Upload Contract JSON Artifact
5558
</Typography>
5659
<Typography>Drag and drop a contract JSON file here, or click to select a file</Typography>
57-
<Typography variant="caption" color="text.secondary" sx={{ mt: 1, mb: 3, display: 'block' }}>
58-
The contract artifact should be a JSON file exported from your Noir/Aztec project
59-
</Typography>
60+
61+
62+
<Box sx={{ textAlign: 'left', backgroundColor: 'var(--mui-palette-grey-A200)', p: 2, borderRadius: '5px', my: 3 }}>
63+
<Box>
64+
<a href="https://docs.aztec.network/developers/tutorials/codealong/contract_tutorials/counter_contract" target="_blank" rel="noopener noreferrer">Learn</a>
65+
<span> to write your own Aztec smart contracts and upload them here when ready.</span>
66+
</Box>
67+
68+
<Box sx={{ mt: 2 }}>
69+
<Typography
70+
variant="body2"
71+
color="text.secondary"
72+
onClick={(e) => {
73+
e.stopPropagation();
74+
}}
75+
>
76+
1. Install Aztec CLI by running `aztec-up {VERSION}`
77+
<br />
78+
2. Run `aztec-nargo compile` in your project directory
79+
<br />
80+
3. Look for `{'<your-project-name>'}.json` file in the ./target directory
81+
</Typography>
82+
</Box>
83+
</Box>
84+
6085
<Button
6186
variant="contained"
6287
color="primary"

0 commit comments

Comments
 (0)