# Quickstart (/docs/builders/shreds/quickstart)

import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import { Steps, Step } from 'fumadocs-ui/components/steps';

# Quickstart

Build a realtime payment application using RISE's Shred API in under 15 minutes. This tutorial will demonstrate instant transaction confirmations and realtime balance updates.

## What We'll Build

A simple payment application that:

* Sends instant payments with immediate confirmation
* Displays realtime balance updates
* Shows live transaction history
* Demonstrates shred subscriptions

## Prerequisites

* Node.js 16+ installed
* Basic TypeScript/JavaScript knowledge
* A code editor (VS Code recommended)

## Project Setup

<Steps>
  <Step>
    ### Create a New Project

    ```bash
    mkdir rise-quickstart
    cd rise-quickstart
    npm init -y
    ```
  </Step>

  <Step>
    ### Install Dependencies

    <Tabs items={['npm', 'pnpm', 'yarn', 'bun']}>
      <Tab value="npm">
        ```bash
        npm install shreds viem dotenv
        npm install -D typescript tsx @types/node
        ```
      </Tab>

      <Tab value="pnpm">
        ```bash
        pnpm add shreds viem dotenv
        pnpm add -D typescript tsx @types/node
        ```
      </Tab>

      <Tab value="yarn">
        ```bash
        yarn add shreds viem dotenv
        yarn add -D typescript tsx @types/node
        ```
      </Tab>

      <Tab value="bun">
        ```bash
        bun add shreds viem dotenv
        bun add -D typescript tsx @types/node
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step>
    ### Configure TypeScript

    Create `tsconfig.json`:

    ```json title="tsconfig.json"
    {
      "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "moduleResolution": "bundler",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "resolveJsonModule": true
      }
    }
    ```
  </Step>

  <Step>
    ### Set Up Environment

    Create `.env`:

    ```bash title=".env"
    # RISE Testnet RPC endpoints
    RISE_RPC_URL=https://testnet.riselabs.xyz
    RISE_WS_URL=wss://testnet.riselabs.xyz/ws

    # Test wallet (has testnet tokens)
    PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
    ```

    <Callout type="warn">
      This is a well-known test private key. Never use it for real funds!
    </Callout>
  </Step>
</Steps>

## Build the Application

Create `quickstart.ts`:

```typescript title="quickstart.ts"
import 'dotenv/config'
import { createWalletClient, createPublicClient, http, webSocket, parseEther, formatEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { riseTestnet } from 'viem/chains'
import { shredActions } from 'shreds/viem'

// Setup account from private key
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
console.log('Wallet address:', account.address)

// Create client and extend with shred actions
const client = createWalletClient({
  account,
  chain: riseTestnet,
  transport: http(process.env.RISE_RPC_URL)
}).extend(shredActions)

// Recipient address
const recipient = '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'

async function main() {
  console.log('[START] RISE Quickstart\n')

  // Step 1: Check initial balances
  console.log('[INFO] Checking initial balances...')
  const senderBalance = await client.getBalance({ address: account.address })
  const recipientBalance = await client.getBalance({ address: recipient })

  console.log(`Sender: ${formatEther(senderBalance)} ETH`)
  console.log(`Recipient: ${formatEther(recipientBalance)} ETH\n`)

  // Step 2: Subscribe to shreds for realtime updates
  console.log('[SUBSCRIBE] Subscribing to realtime updates...\n')

  const wsClient = createPublicClient({
    chain: riseTestnet,
    transport: webSocket(process.env.RISE_WS_URL)
  }).extend(shredActions)

  const unwatch = wsClient.watchShreds({
    onShred: (shred) => {
      console.log(`[SHRED] New shred detected!`)
      console.log(`   Index: ${shred.shredIndex}`)
      console.log(`   Transactions: ${shred.transactions.length}`)
      console.log(`   Timestamp: ${new Date(Number(shred.blockTimestamp) * 1000).toLocaleTimeString()}\n`)
    }
  })

  // Step 3: Send instant transaction
  console.log('[SEND] Sending 0.1 ETH with instant confirmation...')
  const startTime = Date.now()

  try {
    const hash = await client.sendTransactionSync({
      to: recipient,
      value: parseEther('0.1'),
    })

    const confirmTime = Date.now() - startTime
    console.log(`[SUCCESS] Transaction confirmed in ${confirmTime}ms!`)
    console.log(`[HASH] ${hash}\n`)

    // Step 4: Check updated balances immediately
    console.log('[INFO] Checking updated balances...')
    const newSenderBalance = await client.getBalance({ address: account.address })
    const newRecipientBalance = await client.getBalance({ address: recipient })

    console.log(`Sender: ${formatEther(newSenderBalance)} ETH`)
    console.log(`Recipient: ${formatEther(newRecipientBalance)} ETH`)

  } catch (error) {
    console.error('[ERROR] Transaction failed:', error.message)
  }

  // Keep watching for a few seconds
  console.log('\n[WATCH] Watching for more shreds (10 seconds)...')

  setTimeout(() => {
    unwatch()
    console.log('\n[COMPLETE] Quickstart complete!')
    process.exit(0)
  }, 10000)
}

// Run the quickstart
main().catch(console.error)
```

## Run the Application

Execute the quickstart:

```bash
npx tsx quickstart.ts
```

You should see output like:

```
[START] RISE Quickstart

[INFO] Checking initial balances...
Sender: 10000.0 ETH
Recipient: 10000.0 ETH

[SUBSCRIBE] Subscribing to realtime updates...

[SEND] Sending 0.1 ETH with instant confirmation...
[SHRED] New shred detected!
   Index: 1234
   Transactions: 1
   Timestamp: 2:34:56 PM

[SUCCESS] Transaction confirmed in 4ms!
[HASH] 0x...

[INFO] Checking updated balances...
Sender: 9999.899... ETH
Recipient: 10000.1 ETH

[WATCH] Watching for more shreds (10 seconds)...
```

## What Just Happened?

1. **Instant Confirmation**: The transaction confirmed in \~4ms, not minutes
2. **Realtime Updates**: Balances reflected the change immediately
3. **Shred Subscription**: We received the shred notification in realtime
4. **Full Compatibility**: Standard viem methods worked seamlessly

## Next Steps

### Enhance the Application

Try these modifications:

1. **Batch Transactions**: Send multiple transactions rapidly
2. **Event Monitoring**: Watch for specific smart contract events
3. **Balance Streaming**: Display continuously updating balances
4. **Error Recovery**: Add retry logic for failed transactions

### Learn More

* [API Methods](/docs/builders/shreds/api-methods) - Core Shred API methods
* [Watching Events](/docs/builders/shreds/watching-events) - Realtime subscriptions
