Skip to content

Frontend integration

For most apps, prefer the hosted HTTP API at https://ebg-tokenizer.u3dev.deno.net/ so clients send JSON only and do not hold minter keys.

You can also call the factory directly from a web app (e.g. with wagmi) if the connected wallet has the right onchain roles. This page mirrors the shapes used onchain and in the HTTP API; the full tuple includes image_url and certificate_url (see Certificate data model).

wagmi — create collection

typescript
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
import { factoryAbi } from './abis/factory'

const FACTORY_ADDRESS = '0x...' as const

function CreateCertificate() {
  const { writeContract, data: hash, isPending } = useWriteContract()
  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
    hash,
  })

  const createCertificate = async () => {
    try {
      await writeContract({
        address: FACTORY_ADDRESS,
        abi: factoryAbi,
        functionName: 'create_certificate',
        args: [
          'EBG Cert', // name_ (max 25 chars)
          'EBG', // symbol_ (max 5 chars)
          'https://api.example.com/metadata/', // base_uri_ (max 80 chars)
        ],
      })
    } catch (error) {
      console.error('Failed to create certificate:', error)
    }
  }

  return (
    <div>
      <button
        onClick={createCertificate}
        disabled={isPending || isConfirming}
      >
        {isPending ? 'Creating...' : isConfirming ? 'Confirming...' : 'Create certificate'}
      </button>
      {isSuccess && <p>Certificate collection created.</p>}
    </div>
  )
}

wagmi — mint through factory

mint_certificate takes the collection address, the certificate struct as a tuple, and the recipient address. All ten struct fields must be provided in order.

typescript
function MintCertificate() {
  const { writeContract, data: hash, isPending } = useWriteContract()
  const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
    hash,
  })

  const mintCertificate = async () => {
    const certificateData = [
      1734567890n, // registration_date
      'DLV-001', // delivery_correlative
      'John', // participant_names
      'Doe', // participant_last_names
      'EBG Course', // course_name
      40n, // hours_number
      10n, // sessions_number
      'EBG Academy', // issuing_institution
      'https://example.com/img.png', // image_url
      'https://example.com/cert.pdf', // certificate_url
    ] as const

    try {
      await writeContract({
        address: FACTORY_ADDRESS,
        abi: factoryAbi,
        functionName: 'mint_certificate',
        args: ['0x...', certificateData, '0x...'], // certificate_, data_, to_
      })
    } catch (error) {
      console.error('Failed to mint certificate:', error)
    }
  }

  return (
    <div>
      <button
        onClick={mintCertificate}
        disabled={isPending || isConfirming}
      >
        {isPending ? 'Minting...' : isConfirming ? 'Confirming...' : 'Mint certificate'}
      </button>
      {isSuccess && <p>Certificate minted.</p>}
    </div>
  )
}

ABI snippets

Use the full factory ABI from your block explorer, RPC provider, or contract publisher. Minimal create_certificate and mint_certificate entries for the flows above:

typescript
export const factoryAbi = [
  {
    inputs: [
      { name: 'name_', type: 'string' },
      { name: 'symbol_', type: 'string' },
      { name: 'base_uri_', type: 'string' },
    ],
    name: 'create_certificate',
    outputs: [{ name: '', type: 'address' }],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [
      { name: 'certificate_', type: 'address' },
      {
        name: 'data_',
        type: 'tuple',
        components: [
          { name: 'registration_date', type: 'uint256' },
          { name: 'delivery_correlative', type: 'string' },
          { name: 'participant_names', type: 'string' },
          { name: 'participant_last_names', type: 'string' },
          { name: 'course_name', type: 'string' },
          { name: 'hours_number', type: 'uint256' },
          { name: 'sessions_number', type: 'uint256' },
          { name: 'issuing_institution', type: 'string' },
          { name: 'image_url', type: 'string' },
          { name: 'certificate_url', type: 'string' },
        ],
      },
      { name: 'to_', type: 'address' },
    ],
    name: 'mint_certificate',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
] as const

For tuple field order when encoding mint_certificate, see Certificate data model.

Released under License.