Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e1bb90f
Initial Polkadot section in UI
ericglau Aug 25, 2025
bb7801e
Omit Account and Superchain
ericglau Aug 25, 2025
542def8
Use Polkadot colors for tabs
ericglau Aug 25, 2025
c8452d4
Add Remix overrides
ericglau Aug 25, 2025
56b1a65
Refactor overrides
ericglau Aug 25, 2025
eeda293
Refactor Overrides interface
ericglau Aug 25, 2025
52170fe
Hide Foundry, add todos
ericglau Aug 25, 2025
f061d6e
Refactor get button visibilities
ericglau Aug 25, 2025
2d3ba5c
Simplify polkadot switch, remove version selector for now
ericglau Aug 25, 2025
8ccf673
Add todo
ericglau Aug 25, 2025
07b493b
Additional omits for governor, votes, permit
ericglau Aug 26, 2025
337b003
Refactor default overrides
ericglau Aug 26, 2025
c2a1078
Comments
ericglau Aug 26, 2025
b59f9e0
Fix undefined
ericglau Aug 26, 2025
6e3fcb8
Remove omitted features from selected options
ericglau Aug 26, 2025
aaa55be
Handle undefined omitfeatures
ericglau Aug 26, 2025
e97acdc
Add override for AI assistant
ericglau Aug 26, 2025
492eba1
Update prompt
ericglau Aug 26, 2025
e3989fa
Restore Governor, votes, permit
ericglau Sep 10, 2025
ca745e2
Merge remote-tracking branch 'upstream/master' into polkadotsolidity
ericglau Sep 10, 2025
579986e
Disable download Hardhat for Polkadot for now
ericglau Sep 10, 2025
5cbf528
Restore Governor for AI assistant
ericglau Sep 10, 2025
068f52c
Remove todo
ericglau Sep 10, 2025
4a95d90
Fix AI function defs
ericglau Sep 10, 2025
d5458bb
Remove sample messages override
ericglau Sep 10, 2025
cb34293
Avoid circular type
ericglau Sep 10, 2025
55a1019
Fix lint
ericglau Sep 10, 2025
97f0af4
Update post config language
ericglau Sep 11, 2025
0ba7914
Merge branch 'master' into polkadotsolidity
ericglau Sep 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/ui/api/ai-assistant/function-definitions/polkadot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
solidityERC20AIFunctionDefinition,
solidityERC721AIFunctionDefinition,
solidityERC1155AIFunctionDefinition,
solidityStablecoinAIFunctionDefinition,
solidityRealWorldAssetAIFunctionDefinition,
solidityGovernorAIFunctionDefinition,
solidityCustomAIFunctionDefinition,
} from './solidity.ts';

export const polkadotERC20AIFunctionDefinition = solidityERC20AIFunctionDefinition;
export const polkadotERC721AIFunctionDefinition = solidityERC721AIFunctionDefinition;
export const polkadotERC1155AIFunctionDefinition = solidityERC1155AIFunctionDefinition;
export const polkadotStablecoinAIFunctionDefinition = solidityStablecoinAIFunctionDefinition;
export const polkadotRealWorldAssetAIFunctionDefinition = solidityRealWorldAssetAIFunctionDefinition;
export const polkadotGovernorAIFunctionDefinition = solidityGovernorAIFunctionDefinition;
export const polkadotCustomAIFunctionDefinition = solidityCustomAIFunctionDefinition;
19 changes: 13 additions & 6 deletions packages/ui/api/ai-assistant/types/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@ import type { KindedOptions as StylusKindedOptions } from '../../../../core/styl
import type { CommonContractOptions as StylusCommonContractOptionsBase } from '../../../../core/stylus/dist/common-options';
export type StylusCommonContractOptions = Omit<StylusCommonContractOptionsBase, 'access'> & { access?: false };

type SolidityContractsOptions = Omit<
SolidityKindedOptions,
'Stablecoin' | 'RealWorldAsset' | 'Account' | 'Governor'
> & {
Stablecoin: Omit<SolidityKindedOptions['Stablecoin'], 'upgradeable'> & { upgradeable?: false };
RealWorldAsset: Omit<SolidityKindedOptions['RealWorldAsset'], 'upgradeable'> & { upgradeable?: false };
Account: Omit<SolidityKindedOptions['Account'], 'upgradeable' | 'access'> & { upgradeable?: false; access?: false };
Governor: Omit<SolidityKindedOptions['Governor'], 'access'> & { access?: false };
};

// Add supported language here
export type LanguagesContractsOptions = {
solidity: Omit<SolidityKindedOptions, 'Stablecoin' | 'RealWorldAsset' | 'Account' | 'Governor'> & {
Stablecoin: Omit<SolidityKindedOptions['Stablecoin'], 'upgradeable'> & { upgradeable?: false };
RealWorldAsset: Omit<SolidityKindedOptions['RealWorldAsset'], 'upgradeable'> & { upgradeable?: false };
Account: Omit<SolidityKindedOptions['Account'], 'upgradeable' | 'access'> & { upgradeable?: false; access?: false };
Governor: Omit<SolidityKindedOptions['Governor'], 'access'> & { access?: false };
};
solidity: SolidityContractsOptions;
cairo: CairoKindedOptions;
cairoAlpha: CairoAlphaKindedOptions;
polkadot: Omit<SolidityContractsOptions, 'Account'>;
stellar: Omit<StellarKindedOptions, 'Fungible' | 'NonFungible' | 'Stablecoin'> & {
Fungible: StellarKindedOptions['Fungible'] & StellarCommonContractOptions;
NonFungible: StellarKindedOptions['NonFungible'] & StellarCommonContractOptions;
Expand All @@ -45,6 +51,7 @@ export type LanguagesContractsOptions = {
export type AllLanguagesContractsOptions = LanguagesContractsOptions['solidity'] &
LanguagesContractsOptions['cairo'] &
LanguagesContractsOptions['cairoAlpha'] &
LanguagesContractsOptions['polkadot'] &
LanguagesContractsOptions['stellar'] &
LanguagesContractsOptions['stylus'];
//
Expand Down
4 changes: 3 additions & 1 deletion packages/ui/api/ai.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { OpenAIStream } from 'ai';
import * as solidityFunctions from './ai-assistant/function-definitions/solidity.ts';
import * as polkadotFunctions from './ai-assistant/function-definitions/polkadot.ts';
import * as cairoFunctions from './ai-assistant/function-definitions/cairo.ts';
import * as cairoAlphaFunctions from './ai-assistant/function-definitions/cairo-alpha.ts';
import * as stellarFunctions from './ai-assistant/function-definitions/stellar.ts';
Expand All @@ -21,6 +22,7 @@ const getFunctionsContext = <TLanguage extends SupportedLanguage = SupportedLang
solidity: solidityFunctions,
cairo: cairoFunctions,
cairoAlpha: cairoAlphaFunctions,
polkadot: polkadotFunctions,
stellar: stellarFunctions,
stylus: stylusFunctions,
};
Expand All @@ -39,7 +41,7 @@ const buildAiChatMessages = (request: AiChatBodyRequest): Chat[] => {
content: `
You are a smart contract assistant built by OpenZeppelin to help users using OpenZeppelin Contracts Wizard.
The current options are ${JSON.stringify(request.currentOpts)}.
The current contract code is ${request.currentCode}, written in ${request.language}
The current contract code is ${request.currentCode}, written for the ${request.language} ecosystem.
Please be kind and concise. Keep responses to <100 words.
`.trim(),
},
Expand Down
1 change: 1 addition & 0 deletions packages/ui/public/cairo.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<option value="alpha" />
</select>
</div>
<a class="switch switch-polkadot" href="/polkadot"><img src="/icons/polkadot.svg" alt="polkadot">Polkadot</a>
<a class="switch switch-stellar" href="/stellar"><img src="/icons/stellar.svg" alt="stellar">Stellar</a>
<a class="switch switch-stylus" href="/stylus"><img src="/icons/stylus.svg" alt="stylus">Stylus</a>
</div>
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/public/icons/polkadot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions packages/ui/public/icons/polkadot_active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
<div class="nav nav-switches flex flex-row">
<a class="switch switch-solidity active" href="/"><img src="/icons/solidity.svg" alt="solidity">Solidity</a>
<a class="switch switch-cairo" href="/cairo"><img src="/icons/cairo.svg" alt="cairo">Cairo</a>
<a class="switch switch-polkadot" href="/polkadot"><img src="/icons/polkadot.svg" alt="polkadot">Polkadot</a>
<a class="switch switch-stellar" href="/stellar"><img src="/icons/stellar.svg" alt="stellar">Stellar</a>
<a class="switch switch-stylus" href="/stylus"><img src="/icons/stylus.svg" alt="stylus">Stylus</a>
</div>
Expand Down
100 changes: 100 additions & 0 deletions packages/ui/public/polkadot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>OpenZeppelin Contracts Wizard</title>

<!-- Twitter card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:creator" content="@OpenZeppelin">
<meta name="twitter:title" content="OpenZeppelin Contracts Wizard">
<meta name="twitter:description" content="An interactive smart contract generator based on OpenZeppelin Contracts.">
<meta name="twitter:image" content="https://wizard.openzeppelin.com/tw-card.png">

<!-- Favicons -->
<link rel='icon' type='image/png' href='/favicons/favicon.ico'>
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-icon-180x180.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/favicon-192x192.png" />
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">

<!-- Scripts and CSS -->
<link rel="preload" href="/fonts/Inter-VariableFont_opsz,wght.ttf" as="font" type="font/woff2" crossorigin>
<link rel='stylesheet' href='/build/standalone.css'>
<script async src='/build/embed.js'></script>
<script src="/build/versions.js"></script>
</head>
<body>

<div class="header container flex flex-row justify-between items-center overflow-auto">
<div class="flex flex-row items-center">
<a href="https://www.openzeppelin.com/" target="_blank" rel="noopener noreferrer"><img src="/logo.svg" alt="OpenZeppelin" class="logo" width="160"></a>
</div>
<div class="flex flex-row items-center">
<a class="link" href="https://forum.openzeppelin.com/" target="_blank" rel="noopener noreferrer">Forum</a>
<a class="link" href="https://docs.openzeppelin.com/" target="_blank" rel="noopener noreferrer">Docs</a>
<a class="link" href="https://github.com/OpenZeppelin/" target="_blank" rel="noopener noreferrer"><img src="/icons/github-mark.svg" width="20" alt="GitHub OpenZeppelin"></a>
<a class="link" href="https://x.com/OpenZeppelin" target="_blank" rel="noopener noreferrer"><img src="/icons/x-logo.svg" width="20" alt="Twitter/X"></a>
</div>
</div>
<div class="banner flex w-full gap-2">
<div class="bg-blue-100 text-blue-600 px-2 py-0.5 rounded-md text-sm font-medium">New</div>
<div>
Build secure, OpenZeppelin-standard smart contracts with your favorite AI using the
<a
href="https://mcp.openzeppelin.com/"
target="_blank"
rel="noopener noreferrer"
class="text-gray-600 hover:underline">Contracts MCP</a
>.
</div>
</div>
<div class="nav-row flex flex-row items-center justify-between">
<div class="nav">
<a class="switch switch-solidity" href="/"><img src="/icons/solidity.svg" alt="solidity">Solidity</a>
<a class="switch switch-cairo" href="/cairo"><img src="/icons/cairo.svg" alt="cairo">Cairo</a>
<a class="switch switch-polkadot active" href="#"><img src="/icons/polkadot_active.svg" alt="polkadot">Polkadot</a>
<a class="switch switch-stellar" href="/stellar"><img src="/icons/stellar.svg" alt="stellar">Stellar</a>
<a class="switch switch-stylus" href="/stylus"><img src="/icons/stylus.svg" alt="stylus">Stylus</a>
</div>
</div>
<div class="wizard-container">
<oz-wizard class="wizard" data-sync-url="fragment" data-lang="polkadot"></oz-wizard>
</div>

<footer>
<p>© <a href="https://openzeppelin.com" target="_blank" rel="noopener noreferrer">OpenZeppelin</a> 2017-<span id="copyright-date"></span> |&nbsp;<a href="https://openzeppelin.com/privacy" target="_blank" rel="noopener noreferrer">Privacy</a> |&nbsp;<a href="https://openzeppelin.com/tos" target="_blank" rel="noopener noreferrer">Terms of Service</a></p>
</footer>

<!-- Set current year -->
<script>document.getElementById('copyright-date').innerHTML = new Date().getFullYear();</script>

<!-- Start of HubSpot Embed Code -->
<script type="text/javascript" id="hs-script-loader" async defer src="//js.hs-scripts.com/7795250.js"></script>
<!-- End of HubSpot Embed Code -->
<!-- Hotjar Tracking Code for OpenZeppelinWizard -->
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:5302135,hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
</script>
</body>
</html>
1 change: 1 addition & 0 deletions packages/ui/public/stellar.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<div class="nav">
<a class="switch switch-solidity" href="/"><img src="/icons/solidity.svg" alt="solidity">Solidity</a>
<a class="switch switch-cairo" href="/cairo"><img src="/icons/cairo.svg" alt="cairo">Cairo</a>
<a class="switch switch-polkadot" href="/polkadot"><img src="/icons/polkadot.svg" alt="polkadot">Polkadot</a>
<a class="switch switch-stellar active" href="#"><img src="/icons/stellar.svg" alt="stellar">Stellar</a>
<a class="switch switch-stylus" href="/stylus"><img src="/icons/stylus.svg" alt="stylus">Stylus</a>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/ui/public/stylus.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<div class="nav">
<a class="switch switch-solidity" href="/"><img src="/icons/solidity.svg" alt="solidity">Solidity</a>
<a class="switch switch-cairo" href="/cairo"><img src="/icons/cairo.svg" alt="cairo">Cairo</a>
<a class="switch switch-polkadot" href="/polkadot"><img src="/icons/polkadot.svg" alt="polkadot">Polkadot</a>
<a class="switch switch-stellar" href="/stellar"><img src="/icons/stellar.svg" alt="stellar">Stellar</a>
<a class="switch switch-stylus active" href="#"><img src="/icons/stylus_active.svg" alt="stylus">Stylus</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/common/languages-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ export type LanguagesOptions =
| Required<StellarOptions>
| Required<StylusOptions>;

export type Language = 'solidity' | 'cairo' | 'stylus' | 'stellar';
export type Language = 'solidity' | 'cairo' | 'polkadot-solidity' | 'stylus' | 'stellar';
2 changes: 2 additions & 0 deletions packages/ui/src/common/styles/vars.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

--cairo-orange: #fe4a3c;

--polkadot-pink: #ff2670;

--stylus-pink: #e3066e;

--stellar-black: #0f0f0f;
Expand Down
14 changes: 13 additions & 1 deletion packages/ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './common/styles/global.css';
import SolidityApp from './solidity/App.svelte';
import CairoApp from './cairo/App.svelte';
import CairoAlphaApp from './cairo_alpha/App.svelte';
import PolkadotApp from './polkadot/App.svelte';
import StellarApp from './stellar/App.svelte';
import StylusApp from './stylus/App.svelte';
import VersionedApp from './common/VersionedApp.svelte';
Expand Down Expand Up @@ -43,7 +44,7 @@ const initialOpts: InitialOptions = {

interface CompatibleSelection {
compatible: true;
appType: 'solidity' | 'cairo' | 'cairo_alpha' | 'stellar' | 'stylus';
appType: 'solidity' | 'cairo' | 'cairo_alpha' | 'polkadot' | 'stellar' | 'stylus';
}

interface IncompatibleSelection {
Expand Down Expand Up @@ -79,6 +80,14 @@ function evaluateSelection(
return { compatible: false, compatibleVersionsSemver: `${cairoAlphaSemver} || ${cairoSemver}` };
}
}
case 'polkadot': {
// Use Solidity Contracts semver
if (requestedVersion === undefined || semver.satisfies(requestedVersion, soliditySemver)) {
return { compatible: true, appType: 'polkadot' };
} else {
return { compatible: false, compatibleVersionsSemver: soliditySemver };
}
}
case 'stellar': {
if (requestedVersion === undefined || semver.satisfies(requestedVersion, stellarSemver)) {
return { compatible: true, appType: 'stellar' };
Expand Down Expand Up @@ -145,6 +154,9 @@ if (!selection.compatible) {
},
});
break;
case 'polkadot':
app = new PolkadotApp({ target: document.body, props: { initialTab, initialOpts } });
break;
case 'stellar':
app = new StellarApp({ target: document.body, props: { initialTab, initialOpts } });
break;
Expand Down
38 changes: 38 additions & 0 deletions packages/ui/src/polkadot/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script lang="ts">
import SolidityApp from '../solidity/App.svelte';
import type { InitialOptions } from '../common/initial-options';
import type { Overrides } from '../solidity/overrides';
import { defineOmitFeatures, sanitizeOmittedFeatures } from './handle-unsupported-features';
import { createWiz } from '../common/Wiz.svelte';

export let initialTab: string | undefined = 'ERC20';
export let initialOpts: InitialOptions = {};

let overrides: Overrides = {
omitTabs: ['Account'],
omitFeatures: defineOmitFeatures(),
omitZipFoundry: true,
omitZipHardhat: true, // Disabled until Polkadot-specific config is added for the download package
remix: {
label: 'Open in Polkadot Remix',
url: 'https://remix.polkadot.io',
},
sanitizeOmittedFeatures,
aiAssistant: {
svelteComponent: createWiz<'polkadot'>(),
language: 'polkadot',
},
};
</script>

<div class="polkadot-app">
<SolidityApp {initialTab} {initialOpts} {overrides} />
</div>

<style lang="postcss">
.polkadot-app :global(.tab button.selected) {
background-color: var(--polkadot-pink) !important;
color: white;
order: -1;
}
</style>
18 changes: 18 additions & 0 deletions packages/ui/src/polkadot/handle-unsupported-features.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { GenericOptions, Kind } from '@openzeppelin/wizard';

export function defineOmitFeatures(): Map<Kind, string[]> {
const omitFeatures: Map<Kind, string[]> = new Map();
omitFeatures.set('ERC20', ['superchain']);
omitFeatures.set('Stablecoin', ['superchain']);
omitFeatures.set('RealWorldAsset', ['superchain']);
return omitFeatures;
}

export function sanitizeOmittedFeatures(opts: GenericOptions): GenericOptions {
if (opts.kind === 'ERC20' || opts.kind === 'Stablecoin' || opts.kind === 'RealWorldAsset') {
if (opts.crossChainBridging === 'superchain') {
opts.crossChainBridging = 'custom';
}
}
return opts;
}
Loading
Loading