Skip to content

Commit 1f8e90e

Browse files
CoveMBericglau
andauthored
Plat 6356 refactor ai assistant code to prepare for adding other (#508)
Co-authored-by: Eric Lau <[email protected]>
1 parent 661ae07 commit 1f8e90e

File tree

13 files changed

+866
-605
lines changed

13 files changed

+866
-605
lines changed

.vscode/extensions.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"recommendations": [
33
"esbenp.prettier-vscode",
44
"dbaeumer.vscode-eslint",
5-
"denoland.vscode-deno",
6-
"ms-vscode.vscode-typescript-tslint-plugin",
5+
"denoland.vscode-deno"
76
]
87
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
const sharedFunctionDescription = {
2+
name: { type: 'string', description: 'The name of the contract' },
3+
4+
symbol: { type: 'string', description: 'The short symbol for the token' },
5+
6+
burnable: {
7+
type: 'boolean',
8+
description: 'Whether token holders will be able to destroy their tokens',
9+
},
10+
11+
pausable: {
12+
type: 'boolean',
13+
description:
14+
'Whether privileged accounts will be able to pause specifically marked functionality. Useful for emergency response.',
15+
},
16+
17+
mintable: {
18+
type: 'boolean',
19+
description: 'Whether privileged accounts will be able to create more supply or emit more tokens',
20+
},
21+
} as const;
22+
23+
export const addFunctionPropertiesFrom = <
24+
TCommonOptions extends Record<string, unknown>,
25+
TCommonOptionName extends keyof (typeof sharedFunctionDescription &
26+
TCommonOptions) = keyof (typeof sharedFunctionDescription & TCommonOptions),
27+
>(
28+
commonOptions: TCommonOptions,
29+
commonOptionNames: TCommonOptionName[],
30+
) =>
31+
commonOptionNames.reduce(
32+
(pickedCommonOptions, commonOptionName) => ({
33+
...pickedCommonOptions,
34+
[commonOptionName]: { ...commonOptions, ...sharedFunctionDescription }[commonOptionName],
35+
}),
36+
{} as Pick<typeof sharedFunctionDescription & TCommonOptions, TCommonOptionName>,
37+
);
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
const commonOptions = {
2-
// 'false' gets converted to false
1+
import type { AiFunctionDefinition, AiFunctionPropertyDefinition } from '../types/function-definition.ts';
2+
import { addFunctionPropertiesFrom } from './shared.ts';
3+
import type { SolidityCommonOptions } from '../types/languages.ts';
4+
5+
const commonFunctionDescription = {
36
access: {
4-
type: 'string',
5-
enum: ['false', 'ownable', 'roles', 'managed'],
7+
anyOf: [
8+
{ type: 'boolean', enum: [false] },
9+
{ type: 'string', enum: ['ownable', 'roles', 'managed'] },
10+
],
611
description:
712
'The type of access control to provision. Ownable is a simple mechanism with a single account authorized for all privileged actions. Roles is a flexible mechanism with a separate role for each privileged action. A role can have many authorized accounts. Managed enables a central contract to define a policy that allows certain callers to access certain functions.',
813
},
914

10-
// 'false' gets converted to false
1115
upgradeable: {
12-
type: 'string',
13-
enum: ['false', 'transparent', 'uups'],
16+
anyOf: [
17+
{ type: 'boolean', enum: [false] },
18+
{ type: 'string', enum: ['transparent', 'uups'] },
19+
],
1420
description:
1521
'Whether the smart contract is upgradeable. Transparent uses more complex proxy with higher overhead, requires less changes in your contract.Can also be used with beacons. UUPS uses simpler proxy with less overhead, requires including extra code in your contract. Allows flexibility for authorizing upgrades.',
1622
},
@@ -30,50 +36,38 @@ const commonOptions = {
3036
},
3137
},
3238
},
33-
};
34-
35-
const repeatedOptions = {
36-
name: { type: 'string', description: 'The name of the contract' },
37-
symbol: { type: 'string', description: 'The short symbol for the token' },
38-
burnable: {
39-
type: 'boolean',
40-
description: 'Whether token holders will be able to destroy their tokens',
41-
},
42-
pausable: {
43-
type: 'boolean',
44-
description:
45-
'Whether privileged accounts will be able to pause the functionality marked as whenNotPaused. Useful for emergency response.',
46-
},
47-
mintable: {
48-
type: 'boolean',
49-
description: 'Whether privileged accounts will be able to create more supply or emit more tokens',
50-
},
51-
};
39+
} as const satisfies AiFunctionPropertyDefinition<SolidityCommonOptions>['properties'];
5240

5341
export const erc20Function = {
54-
name: 'erc20',
42+
name: 'ERC20',
5543
description: 'Make a fungible token per the ERC-20 standard',
5644
parameters: {
5745
type: 'object',
5846
properties: {
59-
name: repeatedOptions.name,
60-
symbol: repeatedOptions.symbol,
61-
burnable: repeatedOptions.burnable,
62-
pausable: repeatedOptions.pausable,
47+
...addFunctionPropertiesFrom(commonFunctionDescription, [
48+
'name',
49+
'symbol',
50+
'burnable',
51+
'pausable',
52+
'mintable',
53+
'access',
54+
'upgradeable',
55+
'info',
56+
]),
6357
premint: {
64-
type: 'number',
58+
type: 'string',
6559
description: 'The number of tokens to premint for the deployer.',
6660
},
67-
mintable: repeatedOptions.mintable,
6861
permit: {
6962
type: 'boolean',
7063
description:
7164
'Whether without paying gas, token holders will be able to allow third parties to transfer from their account.',
7265
},
73-
// 'false' gets converted to false
7466
votes: {
75-
type: 'string',
76-
enum: ['false', 'blocknumber', 'timestamp'],
67+
anyOf: [
68+
{ type: 'boolean', enum: [false] },
69+
{ type: 'string', enum: ['blocknumber', 'timestamp'] },
70+
],
7771
description:
7872
'Whether to keep track of historical balances for voting in on-chain governance. Voting durations can be expressed as block numbers or timestamps.',
7973
},
@@ -83,25 +77,44 @@ export const erc20Function = {
8377
"Whether to include built-in flash loans to allow lending tokens without requiring collateral as long as they're returned in the same transaction.",
8478
},
8579
crossChainBridging: {
86-
type: 'string',
87-
enum: ['false', 'custom', 'superchain'],
80+
anyOf: [
81+
{ type: 'boolean', enum: [false] },
82+
{ type: 'string', enum: ['custom', 'superchain'] },
83+
],
8884
description:
8985
'Whether to allow authorized bridge contracts to mint and burn tokens for cross-chain transfers. Options are to use custom bridges on any chain, or the SuperchainERC20 standard with the predeployed SuperchainTokenBridge. Emphasize that these features are experimental, not audited and are subject to change. The SuperchainERC20 feature is only available on chains in the Superchain, and requires deploying your contract to the same address on every chain in the Superchain.',
9086
},
91-
...commonOptions,
87+
premintChainId: {
88+
type: 'string',
89+
description: 'The chain ID of the network on which to premint tokens.',
90+
},
91+
callback: {
92+
type: 'boolean',
93+
description:
94+
'Whether to includes supports for code execution after transfers and approvals on recipient contracts in a single transaction.',
95+
},
9296
},
9397
required: ['name', 'symbol'],
98+
additionalProperties: false,
9499
},
95-
};
100+
} as const satisfies AiFunctionDefinition<'solidity', 'ERC20'>;
96101

97102
export const erc721Function = {
98-
name: 'erc721',
103+
name: 'ERC721',
99104
description: 'Make a non-fungible token per the ERC-721 standard',
100105
parameters: {
101106
type: 'object',
102107
properties: {
103-
name: repeatedOptions.name,
104-
symbol: repeatedOptions.symbol,
108+
...addFunctionPropertiesFrom(commonFunctionDescription, [
109+
'name',
110+
'symbol',
111+
'burnable',
112+
'pausable',
113+
'mintable',
114+
'access',
115+
'upgradeable',
116+
'info',
117+
]),
105118
baseUri: { type: 'string', description: 'A base uri for the token' },
106119
enumerable: {
107120
type: 'boolean',
@@ -112,41 +125,44 @@ export const erc721Function = {
112125
type: 'boolean',
113126
description: 'Allows updating token URIs for individual token IDs',
114127
},
115-
burnable: repeatedOptions.burnable,
116-
pausable: repeatedOptions.pausable,
117-
mintable: repeatedOptions.mintable,
118128
incremental: {
119129
type: 'boolean',
120130
description: 'Whether new tokens will be automatically assigned an incremental id',
121131
},
122-
// 'false' gets converted to false
123132
votes: {
124-
type: 'string',
125-
enum: ['false', 'blocknumber', 'timestamp'],
133+
anyOf: [
134+
{ type: 'boolean', enum: [false] },
135+
{ type: 'string', enum: ['blocknumber', 'timestamp'] },
136+
],
126137
description:
127138
'Whether to keep track of individual units for voting in on-chain governance. Voting durations can be expressed as block numbers or timestamps.',
128139
},
129-
...commonOptions,
130140
},
131141
required: ['name', 'symbol'],
142+
additionalProperties: false,
132143
},
133-
};
144+
} as const satisfies AiFunctionDefinition<'solidity', 'ERC721'>;
134145

135146
export const erc1155Function = {
136-
name: 'erc1155',
147+
name: 'ERC1155',
137148
description: 'Make a non-fungible token per the ERC-1155 standard',
138149
parameters: {
139150
type: 'object',
140151
properties: {
141-
name: repeatedOptions.name,
152+
...addFunctionPropertiesFrom(commonFunctionDescription, [
153+
'name',
154+
'burnable',
155+
'pausable',
156+
'mintable',
157+
'access',
158+
'upgradeable',
159+
'info',
160+
]),
142161
uri: {
143162
type: 'string',
144163
description:
145164
'The Location of the metadata for the token. Clients will replace any instance of {id} in this string with the tokenId.',
146165
},
147-
burnable: repeatedOptions.burnable,
148-
pausable: repeatedOptions.pausable,
149-
mintable: repeatedOptions.mintable,
150166
supply: {
151167
type: 'boolean',
152168
description: 'Whether to keep track of total supply of tokens',
@@ -155,14 +171,14 @@ export const erc1155Function = {
155171
type: 'boolean',
156172
description: 'Whether privileged accounts will be able to set a new URI for all token types',
157173
},
158-
...commonOptions,
159174
},
160175
required: ['name', 'uri'],
176+
additionalProperties: false,
161177
},
162-
};
178+
} as const satisfies AiFunctionDefinition<'solidity', 'ERC1155'>;
163179

164180
export const stablecoinFunction = {
165-
name: 'stablecoin',
181+
name: 'Stablecoin',
166182
description:
167183
'Make a stablecoin token that uses the ERC-20 standard. Emphasize that this is experimental, and some features are not audited and subject to change.',
168184
parameters: {
@@ -174,37 +190,39 @@ export const stablecoinFunction = {
174190
description:
175191
'Whether authorized accounts can freeze and unfreeze accounts for regulatory or security purposes. This feature is experimental, not audited and is subject to change.',
176192
},
177-
// 'false' gets converted to false
178193
limitations: {
179-
type: 'string',
180-
enum: ['false', 'allowlist', 'blocklist'],
194+
anyOf: [
195+
{ type: 'boolean', enum: [false] },
196+
{ type: 'string', enum: ['allowlist', 'blocklist'] },
197+
],
181198
description:
182199
'Whether to restrict certain users from transferring tokens, either via allowing or blocking them. This feature is experimental, not audited and is subject to change.',
183200
},
184201
upgradeable: {
185202
type: 'string',
186-
enum: ['false'],
203+
enum: [false],
187204
description: 'Upgradeability is not yet available for features that use @openzeppelin/community-contracts',
188205
},
189206
},
190207
required: ['name', 'symbol'],
208+
additionalProperties: false,
191209
},
192-
};
210+
} as const satisfies AiFunctionDefinition<'solidity', 'Stablecoin'>;
193211

194212
export const realWorldAssetFunction = {
195-
name: 'realworldasset',
213+
name: 'RealWorldAsset',
196214
description:
197215
'Make a real-world asset token that uses the ERC-20 standard. Emphasize that this is experimental, and some features are not audited and subject to change.',
198216
parameters: stablecoinFunction.parameters,
199-
};
217+
} as const satisfies AiFunctionDefinition<'solidity', 'RealWorldAsset'>;
200218

201219
export const governorFunction = {
202-
name: 'governor',
220+
name: 'Governor',
203221
description: 'Make a contract to implement governance, such as for a DAO',
204222
parameters: {
205223
type: 'object',
206224
properties: {
207-
name: repeatedOptions.name,
225+
...addFunctionPropertiesFrom(commonFunctionDescription, ['name', 'access', 'upgradeable', 'info']),
208226
delay: {
209227
type: 'string',
210228
description: 'The delay since proposal is created until voting starts, default is "1 day"',
@@ -217,9 +235,8 @@ export const governorFunction = {
217235
type: 'number',
218236
description: 'The number of seconds assumed for a block, default is 12',
219237
},
220-
// gets converted to a string to follow the API
221238
proposalThreshold: {
222-
type: 'number',
239+
type: 'string',
223240
description: 'Minimum number of votes an account must have to create a proposal, default is 0.',
224241
},
225242
decimals: {
@@ -236,9 +253,8 @@ export const governorFunction = {
236253
type: 'number',
237254
description: 'The percent required, in cases of quorumMode equals percent',
238255
},
239-
// gets converted to a string to follow the API
240256
quorumAbsolute: {
241-
type: 'number',
257+
type: 'string',
242258
description: 'The absolute quorum required, in cases of quorumMode equals absolute',
243259
},
244260
votes: {
@@ -252,10 +268,11 @@ export const governorFunction = {
252268
description:
253269
'The clock mode used by the voting token. For Governor, this must be chosen to match what the ERC20 or ERC721 voting token uses.',
254270
},
255-
// 'false' gets converted to false
256271
timelock: {
257-
type: 'string',
258-
enum: ['false', 'openzeppelin', 'compound'],
272+
anyOf: [
273+
{ type: 'boolean', enum: [false] },
274+
{ type: 'string', enum: ['openzeppelin', 'compound'] },
275+
],
259276
description: 'The type of timelock to use',
260277
},
261278
storage: {
@@ -266,22 +283,25 @@ export const governorFunction = {
266283
type: 'boolean',
267284
description: 'Allow governance to update voting settings (delay, period, proposal threshold)',
268285
},
269-
...commonOptions,
270286
},
271287
required: ['name', 'delay', 'period'],
288+
additionalProperties: false,
272289
},
273-
};
290+
} as const satisfies AiFunctionDefinition<'solidity', 'Governor'>;
274291

275292
export const customFunction = {
276-
name: 'custom',
293+
name: 'Custom',
277294
description: 'Make a custom smart contract',
278295
parameters: {
279296
type: 'object',
280-
properties: {
281-
name: repeatedOptions.name,
282-
pausable: repeatedOptions.pausable,
283-
...commonOptions,
284-
},
297+
properties: addFunctionPropertiesFrom(commonFunctionDescription, [
298+
'name',
299+
'pausable',
300+
'access',
301+
'upgradeable',
302+
'info',
303+
]),
285304
required: ['name'],
305+
additionalProperties: false,
286306
},
287-
};
307+
} as const satisfies AiFunctionDefinition<'solidity', 'Custom'>;

0 commit comments

Comments
 (0)