Our PDK generators will accept a properly typed Patchwork project configuration file as input and will generate the same name solidity contract as output in the current working directory.

Here’s an example Patchwork project configuration:

import { Feature, type ProjectConfig } from '@patchworkdev/common/types';
import { anvil, base, baseSepolia } from 'viem/chains';

export default {
    name: 'My Patchwork App',
    contracts: {
        MyFirstContract: {
            scopeName: 'myapp',
            name: 'My First Contract',
            symbol: 'FIRST',
            baseURI: 'https://www.example.com/',
            schemaURI: 'https://www.example.com/schemas/myfirstcontract.json',
            imageURI: 'https://www.example.com/assets/myfirstcontract/{tokenID}',
            fields: [
                {
                    id: 0,
                    key: 'myfield',
                    type: 'char32',
                    description: 'My Field',
                },
                {
                    id: 1,
                    key: 'myarray',
                    type: 'char8',
                    description: 'My Array',
                    arrayLength: 4,
                },
            ],
            features: [Feature.MINTABLE],
        },
        MySecondContract: {
            scopeName: 'myapp',
            name: 'My Second Contract',
            symbol: 'SECOND',
            baseURI: 'https://www.example.com/',
            schemaURI: 'https://www.example.com/schemas/mysecondcontract.json',
            imageURI: 'https://www.example.com/assets/mysecondcontract/{tokenID}',
            fields: [
                {
                    id: 0,
                    key: 'examplefield',
                    type: 'char32',
                    description: 'My Example Field',
                },
            ],
            features: [Feature.MINTABLE],
        },
    },
    contractRelations: {
        MyFirstContract: {
            fragments: ['MySecondContract'],
        }
    },
    scopes: [
        {
            name: 'myapp',
        },
    ],
    networks: {
        local: {
            chain: anvil,
            rpc: 'http://127.0.0.1:8545',
        },
        testnet: {
            chain: baseSepolia,
            rpc: 'http://127.0.0.1:8545',
        },
        mainnet: {
            chain: base,
            rpc: 'http://127.0.0.1:8545',
        },
    },
} as projectConfig;

From this file, we can generate Solidity boilerplate, indexer schemas, React hooks and more.

Project configuration

NameDescription
nameThe name of your app
scopesScope configuration records
contractsContract configuration records
contractRelationsContract relations records
networksNetwork configuration records

Contract configuration

NameDescription
scopeNameThe scope name of the contract
nameThe ERC-721 Name of the contract
symbolThe ERC-721 symbol of the contract
baseURIThe base URI
schemaURIThe schema URI
imageURIThe image URI
featuresList of features
fieldsList of fields

Contract fields

NameDescription
idThe field ID (must be unique)
keyThe field key (must be unique)
typeThe field Type (Must be in field type enum)
arrayLengthThe array length (1 is default, 0 is dynamic and >1 is a static array)
descriptionThe field description

Contract field types

NameDescription
booleanA boolean type (true or false)
int8An 8-bit signed integer.
int16A 16-bit signed integer.
int32A 32-bit signed integer.
int64A 64-bit signed integer.
int128A 128-bit signed integer.
int256A 256-bit signed integer.
uint8An 8-bit unsigned integer.
uint16A 16-bit unsigned integer.
uint32A 32-bit unsigned integer.
uint64A 64-bit unsigned integer.
uint128A 128-bit unsigned integer.
uint256A 256-bit unsigned integer.
char8An 8-character string (64 bits).
char16A 16-character string (128 bits).
char32A 32-character string (256 bits).
char64A 64-character string (512 bits).
literefA 64-bit Literef reference to a patchwork fragment.
addressA 160-bit address.
stringA dynamically-sized string.

Contract features

NameDescription
FRAGMENTMULTIA multi-assignable fragment
FRAGMENTSINGLEA single-assignable fragment
PATCHA 721 patch
PATCHACCOUNTAn account patch
PATCH1155An 1155 patch
MINTABLEMintable
REVERSIBLEReversible (patch)

If you’re using Typescript, you’ll need to import the Feature enum from @patchworkdev/common/types.