Workshop: Monero-TS + t3-stack

alex

Created: 2024-06-06 Thu 12:41

About this workshop

Build real web3 applications

  • Web3 => integrating digital cash into digital apps
  • Benefit from trustless, open, permissionless ecosystem
  • Create awesome user experience

What we build today

A simple “web shop” with custom monero integration

  • The shop sells digital goods => i.e. ai generated imagefiles
  • The customer pays an invoice and receives a digital item on receive
  • unlocked images are visible to everybody on the site
  • 0-conf transactions

Being a web dev

Being a web dev in 2024

=> T3-Stack

Bringing monero to the web

  • monero-ts (previously monero-js)
    • allows for type-safe interaction with monero wallets
  • server side
    • in nodejs runtime
    • with monero-wallet-rpc
  • client side with WASM browser wallet

Architecture

Setting up the project

# clone the repo
git clone https://gitlab.com/monero-studio/xmr-t3-starter.git
cd xmr-t3-starter # cd into new directory
git checkout monerokon-2024-demo-store # switch branch
npm i # install node_modules
npx prisma migrate dev # migrate prisma schema

monero-wallet-rpc

  • Create a new server wallet with monero-wallet-cli
    • Pass the --stagenet option on wallet creation for stagenet
    • Write down the seed phrase
  • Start the rpc with: monero-wallet-rpc --config rpc.config

            rpc-bind-port=38083
            wallet-dir=./
            daemon-address=stagenet.community.rino.io:38081
            non-interactive=1
            trusted-daemon=1
            stagenet=1
            disable-rpc-login=1
            log-level=2
    

Creating the .env

  • Create the .env file from the example with
cp .env.example .env
  • Fill in the Monero wallet values from the previous step
  • On start, our NextJS app will connect to the wallet-rpc with these credentials

A glance at the schema

model Transaction {
  id             String  @id @default(uuid())
  transactionKey String? @unique
  amount         Float?  @default(0)
  isConfirmed    Boolean @default(false)
  isUnlocked     Boolean @default(false)
  item           Image?  @relation(fields: [itemId], references: [id])
  itemId         String?
}

model Image {
  id               String        @id @default(uuid())
  // Monero
  Transaction      Transaction[]
  moneroSubaddress String?       @unique
  payedAmount      Float?        @default(0)
  expectedAmount   Float?        @default(0)
  isPayed          Boolean?      @default(false)

  imagePath String @unique
}

Let’s jump into the code!