Giter Site home page Giter Site logo

turbo-eth / buidl Goto Github PK

View Code? Open in Web Editor NEW
20.0 4.0 1.0 7.84 MB

Web3 Component Library using WAGMI, TailwindCSS and Radix

Home Page: https://buidl.turboeth.xyz/

License: MIT License

TypeScript 73.07% HTML 18.92% JavaScript 2.53% CSS 5.48%
components-react ethereum web3

buidl's Introduction

banner

โšก TurboETH

TS GPLv3 license

Turbo ETH is an Ethereum dApp Build System; designed to make building Web3 applications fast.

Deploy with Vercel

Installation & Usage

git clone [email protected]:turbo-eth/turbo-eth.git

Installation

pnpm is the recommended package manager.

pnpm install

Local Development

pnpm lab

Local Development w/ Blockchain Fork

pnpm lab:fork

Build

pnpm build

Tests

pnpm test

Modules

The monorepo includes 3 primary folders.

Each folder contains similar modules i.e. frontend applications go in the apps folder and the smart contracts go in the contracts folder; very straight-forward.

Environment Variables

Each module requires unique environment variables. Specifically the apps and contracts modules when preparing for deployment or forking a blockchain network.

The .env.example can be copied/pasted and updated to include the required variables deployment.

Task Pipelines

Builds, tests and deployments are handled via tasks pipelines. Task pipelines orchestrate build and dependency requirements between mono-repo packages.

Edit the turbo.json file in the root directory to add new pipelines and custom workflows.

Developer Experience

The TurboETH build system uses Turborepo and pNPM; a high-performance build system and a fast, disk space efficient package manager. Giving developers the best experience possible while minimizing demand on local compute resources.

Core Technologies


Copyright 2022 Kames Geraghty

buidl's People

Contributors

kamescg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

buidl's Issues

Bounty: Input field for Token address, name and symbol - 250 OP Reward

๐Ÿ‘จโ€๐Ÿ’ป User Story

As a developer I want to easily add Token input fields in my Web3 application.

More specifically I want an <InputToken /> component to handle input validation, fetching metadata and rendering details like a icon, name and symbol.

๐Ÿ“œ Disclaimer

To be eligible for the payout you must first get approval to work on the bounty.

It's recommended to share a link to your personal Github account.

๐Ÿงฑ Project

Create a Input component that accepts ERC20.address, ERC20.name and ERC20.symbol as inputs.

  • ERC.address: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
  • ERC20.name: USD Coin
  • ERC20.symbol: USDC

The input field should be able to resolve an ERC20 address using any of the inputs.

image

The Uniswap Token List standard will be used to manage lists of tokens.

Token lists contain metadata like name, symbol, decimals and logoURI.

Example of a Token interface in an exaple token list.

 {
  "chainId": 1,
  "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "symbol": "USDC.e",
  "name": "USD Coin",
  "decimals": 6,
  "logoURI": "ipfs://QmXfzKRvjZz3u5JRgC4v5mGVbm9ahrUiB4DgzHBsnWbTMM",
  "tags": [
	"stablecoin"
  ]
}

Field likes tags can also be used to provide additional sorting capabilities if necessary.

Mockups

Initial component designs are available in the BUIDL Figma document.

Technical Specifications

Required Functionality:

  1. Handle ERC20.address, ERC20.name and ERC20.symbols as input.
  2. Render metadata like name, symbol and icon.
  3. Dialog for expanded view and search.
  4. Dialog to update token lists.

Pseudo Code

Below is an example of how the component structure might start -- the final component structure will likely be much different.

// .input-token.tsx
import * as React from 'react'

import classNames from 'clsx'

import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog'

type Props = React.HTMLAttributes<HTMLElement> & {
  tokenList?: string
}

export const InputToken = ({ className, tokenList = 'tokenlist.turboeth.xyz' }: Props) => {
  const [address, setAddress] = React.useState<string>('')

  return (
    <Dialog>
      <DialogTrigger>
        <InputTokenRender className={className} address={address} />
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Token Search</DialogTitle>
        </DialogHeader>
        {/* Add Token List Search */}
      </DialogContent>
    </Dialog>
  )
}

type RenderProps = React.HTMLAttributes<HTMLElement> & {
  address?: string
  isAddressFetching?: boolean
}

export const InputTokenRender = ({ className, ...props }: RenderProps) => {
  const classes = classNames(className, 'InputToken')
  return <input className={classes} {...props} />
}
State Management

To manage the persistence of the user's token list selection we can use jotai to manage the application state and persist the value in localStorage.

// .input-token-state.ts
import { WritableAtom, atom, useAtom } from 'jotai'

let strAtom: WritableAtom<string, string>
if (typeof window !== 'undefined') {
  strAtom = atom(window?.localStorage.getItem('tokenlist') || 'tokenlist.turboeth.xyz')
} else {
  strAtom = atom('tokenlist.turboeth.xyz')
}

export const tokenList = atom(
  (get) => get(strAtom),
  (get, set, newList: string) => {
    set(strAtom, newList)
    localStorage.setItem('tokenlist', newList)
  }
)

export const useTokenList = () => {
  const [list, setTokenList] = useAtom(tokenList)
  return [list, setTokenList] as const
}
Example using InputToken and useTokenList

Below is an example of how the InputToken component and useTokenList state can be used together inside a Form.

import * as React from 'react'

import classNames from 'clsx'

import { InputToken } from './input-token'
import { useTokenList } from './input-token-state'

type Props = React.HTMLAttributes<HTMLElement>
export const FormUsingInputToken = ({ children, className }: Props) => {
  const [tokenList] = useTokenList()

  return (
    <form>
      <InputToken tokenList={tokenList} />
    </form>
  )
}

๐Ÿ’ฐ Bounty Reward

The bounty reward is 250 OP tokens and TurboETH DevPass digital collectible.

TurboETH is the recipient of 18,271.88 OP Tokens from Optimism Retroactive Public Goods Funding. OP tokens earned from RPGF are helping fund TurboETH bounties.

Disclaimer

The final integration may not resemble the proposed integration - that's O.K - a natural part of software development.

During development you might discover an original hypothesis doesn't make sense. No problem. Make a comment and clearly explain why a new approach is better than old one. Get rewarded for thinking out of the box.

The final bounty reward can be increased to match new bounty tasks.

Resources

Bounty: Input field for Account, Domain and Identifiers - 250 OP Reward

๐Ÿ‘จโ€๐Ÿ’ป User Story

As a developer I want to easily add Account input fields in my Web3 application.

More specifically I want an <InputAccount /> component to handle validation, fetching metadata and rendering details like a profile picture (PFP) using an address, domain or identifier as the input.

๐Ÿ“œ Disclaimer

To be eligible for the payout you must first get approval to work on the bounty.

It's recommended to share a link to your personal Github account.

๐Ÿงฑ Project

Create a Input component that accepts account, domain and identifiers as inputs.

  • Account: Ethereum address i.e. 0x121...212
  • Domain: Web3 domains i.e. Ethereum Name System
  • Identifiers: Decentralized identifiers (DIDs) and related linkages.

The input field should be able to accept any account, domain or identifier data and output (resolve) a valid address.

For example:

  • Input is 0x121...212 the output should be 0x121...212
  • Input is kames.eth the output should be 0x121...212
  • Input is did:3:ky92v...19al the output should be 0x121...212
  • Input is twitter:kamesgeraghty the output should be 0x121...212
  • Input is discord:metasudo#4209 the output should be 0x121...212

image

Accepting all these data types in a single Input field component will require data fetching from multiple external sources. Reasonable defaults will be included, but we want to give developers the ability to override DID resolver APIs and caching services.

For example to resolve did:3 and linkage tokens like twitter:kamesgeraghty will use as the default Disco API service. But developers should be able to easily override the default by passing in a new DID and DIDLinkage resolver service.

In addition to resolving the address for the multiple Input data types: account, domain and identifier, the component should also resolve a profile picture (PFP) when possible.

Protocols like ENS are already supported in libraries like wagmi/viem.

But a standard pattern for fetching profile pictures from DID providers like Disco and Orbis is an unsolved problem. Resolving decentralized identifiers is generally also more complicated than resolving ENS txt records.

Mockups

Initial designs are available in the BUIDL Figma document.

Technical Specifications

Required Functionality:

  1. Handle address, domain and identifiers as input.
  2. Fetch account metadata like name and pfp.
  3. Render profile picture and/or identicon.
  4. Dialog for expanded view and search
  5. Configurable domain and identifier API services.

Component Views

  • Input
  • Dialog with Input and Search
  • Dialog with domain (i.e. ENS) API configuration
  • Dialog with DID Resolver API configuration

Figma Component View Mockups

Input types

  • address - Standard Ethereum address
  • domain - Ethereum Name System domain
  • identifier - Decentralized Identifier
  • linkage - Verifiable Credential URN(Uniform Resource Name)
    • twitter:[username]
    • github:[username]
    • discord:[username]

The Input field should accept and validate all of the above input types.

Input Examples

  • 0x761d584f1C2d43cBc3F42ECd739701a36dFFAa31
  • kames.eth
  • did:pkh:0x761d584f1C2d43cBc3F42ECd739701a36dFFAa31
  • did:3:kjzl6cwe1jw149ofmn3uw261yxv5eio39po2auvgdjxyidmxvqufpnsxrgmo2oa
  • did:web3:districtlabs.com
  • twitter:kamesgeraghty
  • github:kamescg
  • discord:MetaSudo#5364

Linkages like twitter:kamesgeraghty should be powered by DID resolver services like Disco account linkage service which consumes social aliases and returns decentralized identity documents and an associated Ethereum address.

Example of searching for addresses by using a linkage.

https://api.disco.xyz/v1/search/?handle=provenauthority

Below is an example of how the component structure might start. The final component structure will likely be much different.

import React, * as React from 'react'

import classNames from 'clsx'

type AddressError = {
  code: number
  message: string
}

type PfpError = {
  code: number
  message: string
}

type Props = React.HTMLAttributes<HTMLElement> & {
  didResolver?: string
  ensResolver?: string
  pfpEnabled?: boolean
  onAddressResolved?: () => `0x${string}`
  onAddressError?: () => AddressError
  onPfpResolved?: () => void
  onPfpfError?: () => PfpError
}

export const InputAccount = ({
  className,
  didResolver = 'api.disco.xyz/resolver',
  ensResolver = 'api.ens.app/resolver',
  onAddressResolved,
  onAddressError,
  onPfpResolved,
  onPfpfError,
}: Props) => {
  const [address, setAddress] = React.useState<string>('')
  const [pfp, setPfp] = React.useState<string>('')

  /**
   * TODO: Add domain resolver i.e. kames.eth
   * TODO: Add identifier (DID) resolver i.e. did:3 or did:web3
   */

  return <InputAccountRender className={className} address={address} pfp={pfp} />
}

type RenderProps = React.HTMLAttributes<HTMLElement> & {
  address?: string
  pfp?: string
  isAddressFetching?: boolean
  isPfpFetching?: boolean
}

export const InputAccountRender = ({ children, className }: RenderProps) => {
  const classes = classNames(className, 'InputAccount')
  return <div className={classes}>{children}</div>
}

๐Ÿ’ฐ Bounty Reward

The bounty reward is 250 tokens and TurboETH DevPass digital collectible.

TurboETH is the recipient of 18,271.88 OP Tokens from Optimism Retroactive Public Goods Funding. OP tokens earned from RPGF are helping fund TurboETH bounties.

Disclaimer

The final integration may not resemble the proposed integration - that's O.K - a natural part of software development.

During development you might discover an original hypothesis doesn't make sense. No problem. Make a comment and clearly explain why a new approach is better than old one. Get rewarded for thinking out of the box.

The final bounty reward can be increased to match new bounty tasks.

Resources

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.