# Project export: Project DropKit

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: DropKit is a Sui-native ticketing app: create events in one atomic PTB, sell via Kiosk, enforce royalties via Transfer Policy. One-click purchase; check-in prevents reuse; posters on Walrus.
- Devpost: https://devpost.com/software/project-dropkit
- GitHub: https://github.com/sulaymanbowles-hash/SUI_CalHacks
- Video: https://www.youtube.com/embed/v-djL7SPw4c?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — SulaymanB2024 (25 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# DropKit – Ticketmaster on Sui

**Core promise:** Sell & resell event tickets where the artist *always* gets paid—enforced on-chain via Kiosk + Transfer Policy, executed via Programmable Transaction Blocks (PTBs) in one click.

- **Pricing:** All listings priced in **SUI** (mist). USD is display-only.
- **Network:** Sui **testnet** for MVP.
- **On-chain enforcement:** Kiosk + Transfer Policy ensures royalties on every resale.
- **Assets:** Walrus for posters/event images.
- **Secrets:** Seal (DSM) for sensitive data.
- **Fiat onramp:** MoonPay/Transak UI is visual-only on testnet; rely on faucets and gas sponsorship.
- **Auth:** zkLogin planned for later milestones; local keypairs for M0–M2.

## Quick Start

```bash
# 1) Verify tools and testnet
bash scripts/check_env.sh

# 2) Add SELLER/BUYER addresses to scripts/env.sh (see docs/TESTNET_BOOTSTRAP.md)

# 3) Proceed to M1 (Move modules + tests)
```

## What to Do First

1. Read [docs/TESTNET_BOOTSTRAP.md](docs/TESTNET_BOOTSTRAP.md) to install tools, switch to testnet, create addresses, and fund via faucets.
2. Populate `scripts/env.sh` with your addresses (never commit secrets).
3. Run `bash scripts/check_env.sh` to confirm setup.
4. Review [docs/CLAUDE_RULES.md](docs/CLAUDE_RULES.md) for development workflow.
5. Move on to **M1** (Move package), **M2** (PTBs), **M3** (zkLogin/Sponsorship), **M4** (Walrus/Seal), **M5** (Frontend), **M6** (Polish).

## Why GraphQL is Stretch

The MVP relies on PTBs for all mutations and direct RPC queries for reads (balances, objects, events). GraphQL indexing adds complexity and latency; we defer it to post-MVP to stay focused on core flows: **Mint&List**, **Buy&Approve**, and **Check-in**. If demand for rich queries grows, we'll add a GraphQL layer in a later phase.

## Project Context

See [docs/PROJECT_CONTEXT.md](docs/PROJECT_CONTEXT.md) for product vision, constraints, and core flows.

## Development Rules

All code contributions must follow [docs/CLAUDE_RULES.md](docs/CLAUDE_RULES.md):
- One artifact per turn.
- IDs/addresses from `scripts/env.sh` only.
- Include "Run" steps and "Expected output" in every deliverable.

## Milestones

- **M0** (this): Project skeleton, docs, testnet bootstrap scripts.
- **M1**: Move package (Ticket, Kiosk setup, Transfer Policy).
- **M2**: PTBs for Mint&List, Buy&Approve, mark_used.
- **M3**: zkLogin + gas sponsorship.
- **M4**: Walrus (assets) + Seal (secrets).
- **M5**: Frontend (React/Next.js, wallet adapter, PTB execution).
- **M6**: Polish (error handling, rate limits, UX).

---

**License:** MIT  
**Maintainer:** DropKit Team

## Detected evidence (automated analysis)

Indexed codebase: 114 recognized source files, 779 KB.
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (120 of 148)

```
.gitignore
.nvmrc
.vercelignore
docs/AUTOMATION_AND_WALLETS.md
docs/CLAUDE_RULES.md
docs/DEPENDENCY_PINS.md
docs/DESIGN_SYSTEM_IMPLEMENTATION.md
docs/FIXES_APPLIED.md
docs/FRONTEND_AUDIT.md
docs/FRONTEND_BUILD_PLAN.md
docs/FRONTEND_DESIGN_BRIEF.md
docs/FRONTEND_PROMPT_FOR_CLAUDE.md
docs/M1_MOVE_SPEC.md
docs/ORGANIZER_WIZARD_INTEGRATION.md
docs/PROJECT_CONTEXT.md
docs/TESTNET_BOOTSTRAP.md
FUNDING_STATUS.md
packages/move/ticket/Move.lock
packages/move/ticket/Move.toml
packages/move/ticket/sources/channel.move
packages/move/ticket/sources/class.move
packages/move/ticket/sources/event.move
packages/move/ticket/sources/payouts.move
packages/move/ticket/sources/policy_admin.move
packages/move/ticket/sources/ticket.move
packages/move/ticket/tests/policy_tests.move
packages/move/ticket/tests/ticket_tests.move
README.md
scripts/.last_mint.sh
scripts/check_env.sh
scripts/check_seller_address.ts
scripts/check_seller_coins.ts
scripts/ci_smoke.sh
scripts/create_policy.sh
scripts/create_proper_wallet.ts
scripts/demo_flow.sh
scripts/deploy_package.sh
scripts/env.example.sh
scripts/faucet_rotate.sh
scripts/faucet_sui.sh
scripts/faucet_usdc.ts
scripts/gen_wallet.ts
scripts/package.json
scripts/ptb_buy_and_approve.ts
scripts/ptb_checkin_seller.ts
scripts/ptb_checkin.ts
scripts/ptb_mint_and_list.ts
scripts/test_event_creation.ts
scripts/test_kiosk.ts
scripts/transfer_funds.ts
scripts/transfer_to_dev_local.ts
scripts/tsconfig.json
scripts/verify_payouts.ts
scripts/verify_seller.ts
scripts/walrus_check.ts
VERCEL_DEPLOYMENT.md
vercel.json
web/.env.example
web/get_dev_wallet.html
web/index.html
web/package.json
web/postcss.config.js
web/src/App.tsx
web/src/components/AmbientBackground.tsx
web/src/components/BadgeViewer.tsx
web/src/components/Button.tsx
web/src/components/Card.tsx
web/src/components/Chip.tsx
web/src/components/DevWalletBadge.tsx
web/src/components/DisplayWallet.tsx
web/src/components/FadeRise.tsx
web/src/components/Header.tsx
web/src/components/hero/__MACOSX/Sui Logo Ocean/._Sui_Logo_Ocean.eps
web/src/components/hero/__MACOSX/Sui Logo Sea/._Sui_Symbol_Sea.eps
web/src/components/hero/__MACOSX/Sui Logo White/._Sui_Logo_White.eps
web/src/components/hero/__MACOSX/Sui Symbol Ocean/._Sui_Symbol_Ocean.eps
web/src/components/hero/__MACOSX/Sui Symbol Sea/._Sui_Symbol_Sea.eps
web/src/components/hero/__MACOSX/Sui Symbol White/._Sui_Symbol_White.eps
web/src/components/hero/BrandWatermark.tsx
web/src/components/hero/BuiltOnSuiChip.tsx
web/src/components/hero/FlowingWaterBackground.tsx
web/src/components/hero/Hero.tsx
web/src/components/hero/Sui Logo Ocean/Sui_Logo_Ocean.eps
web/src/components/hero/Sui Logo Sea/Sui_Symbol_Sea.eps
web/src/components/hero/Sui Logo White/Sui_Logo_White.eps
web/src/components/hero/Sui Symbol Ocean/Sui_Symbol_Ocean.eps
web/src/components/hero/Sui Symbol Sea/Sui_Symbol_Sea.eps
web/src/components/hero/Sui Symbol White/Sui_Symbol_White.eps
web/src/components/hero/SuiHeroBackdrop.tsx
web/src/components/hero/TypedHeadline.tsx
web/src/components/Input.tsx
web/src/components/ListModal.tsx
web/src/components/motion/HeroParallax.tsx
web/src/components/motion/Reveals.tsx
web/src/components/motion/ScrollProgress.tsx
web/src/components/PosterUpload.tsx
web/src/components/QRDrawer.tsx
web/src/components/RoyaltyBreakdown.tsx
web/src/components/Scanner.tsx
web/src/components/StepHeader.tsx
web/src/components/TestnetPill.tsx
web/src/components/TicketCard.tsx
web/src/components/Tooltip.tsx
web/src/components/TransferModal.tsx
web/src/components/TweenNumber.tsx
web/src/components/TxStatus.tsx
web/src/components/TxTimeline.tsx
web/src/components/ZkLoginButton.tsx
web/src/design-tokens.ts
web/src/lib/channels.ts
web/src/lib/demoTickets.ts
web/src/lib/dev-wallet.ts
web/src/lib/displayWallet.ts
web/src/lib/effects.ts
web/src/lib/env.ts
web/src/lib/explorer.ts
web/src/lib/policy.ts
web/src/lib/ptb.ts
web/src/lib/rpc.ts
web/src/lib/signer.ts
[28 more files omitted for size]
```

### Dependencies

- scripts/package.json: @mysten/sui@^1.0.0, @types/node@^20.11.0, node-fetch@^3.3.2, open@^10.0.0, tsx@^4.7.0, typescript@^5.6.3
- web/package.json: @mysten/dapp-kit@^0.19.6, @mysten/enoki@^0.12.8, @mysten/sui@^1.43.1, @tanstack/react-query@^5.90.5, @types/react@^18.2.55, @types/react-dom@^18.2.19, @typescript-eslint/eslint-plugin@^6.21.0, @typescript-eslint/parser@^6.21.0, @vitejs/plugin-react@^4.2.1, autoprefixer@^10.4.17, eslint@^8.56.0, eslint-plugin-react-hooks@^4.6.0, eslint-plugin-react-refresh@^0.4.5, framer-motion@^11.18.2, lucide-react@^0.344.0, postcss@^8.4.35, qrcode.react@^4.2.0, react@^18.2.0, react-dom@^18.2.0, react-router-dom@^6.22.0, tailwindcss@^3.4.1, typescript@^5.3.3, vite@^5.1.0

### Recent commits (newest first)

- feat: Add CreateEvent page and update routing in App component
- feat: Refactor build scripts and improve TypeScript configuration for better linting and error handling
- feat: Implement kiosk creation and ticket class setup in atomicGoLive function
- feat: Set demo mode to true by default and streamline ticket loading for demonstration
- feat: Enhance BuyerApp with advanced filtering, sorting, and event details
- feat: add Collections page for artist-specific soulbound NFT collections with attendance tracking
- feat: Add BadgeViewer component for displaying attendance badges
- feat: Refactor event and ticket creation to use separate transactions for improved clarity and error handling
- feat: Add TypedHeadline component for animated text display
- Refactor code structure for improved readability and maintainability
- feat: Implement Events Marketplace with QR Code Generation Utilities
- feat: add comprehensive design system implementation with tokens, typography, and responsive guidelines
- feat: implement Events Marketplace page with search, filters, and event details
- Pusha
- feat: Enhance Scanner and CheckIn components with improved QR code handling and state management
- feat: Implement Scanner component for QR code scanning functionality
- feat: Update Button component props and enhance Landing page styling for improved UI/UX
- feat: Refactor Button component with new variants and sizes, update Header navigation, enhance TicketCard styling, and improve ZkLoginButton accessibility
- feat: Implement zkLogin functionality with Google OAuth integration
- feat: Add Poster Upload component for image uploads to Walrus

## Key source files (fetched from GitHub, selected and truncated for size)

### FUNDING_STATUS.md

```markdown
# Testnet Funding Status

## Addresses to Fund

### 1. CLI Publisher (for package deployment)
- **Address**: `0x44e2baf0ceafa68fc742412676245e451fd2327438a9dd3c9f6e824b5fb9dd06`
- **Status**: ❌ No gas
- **Usage**: Publishing Move package, creating transfer policy
- **Web Faucet**: https://faucet.sui.io/?address=0x44e2baf0ceafa68fc742412676245e451fd2327438a9dd3c9f6e824b5fb9dd06

### 2. SELLER (for PTB mint & list)
- **Address**: `0x17d071be65e54fa6252be15699462d5c4f98b25680f7ff0ca3d2a4b33f6d3950`
- **Status**: ✅ Has 1 SUI
- **Usage**: Minting tickets and listing in kiosk
- **File**: `.secrets/SELLER.json`

### 3. BUYER (for PTB buy & approve)
- **Address**: `0x73b3bc71eacfddc8d0a736129f500dcc7b105e93060510f11c928fc4b9637f44`
- **Status**: ❌ No gas
- **Usage**: Purchasing tickets from kiosk
- **File**: `.secrets/BUYER.json`
- **Web Faucet**: https://faucet.sui.io/?address=0x73b3bc71eacfddc8d0a736129f500dcc7b105e93060510f11c928fc4b9637f44

## Quick Actions

### Fund with Web Faucets
```bash
# Open all faucet links (will open 3 tabs)
open "https://faucet.sui.io/?address=0x44e2baf0ceafa68fc742412676245e451fd2327438a9dd3c9f6e824b5fb9dd06"
open "https://faucet.sui.io/?address=0x73b3bc71eacfddc8d0a736129f500dcc7b105e93060510f11c928fc4b9637f44"
```

### Alternative Faucets (if rate-limited)
- M1 Stake: https://faucet.m1stake.com (paste address manually)
- Sui Learn: https://faucet.suilearn.io (paste address manually)
- Blockbolt: https://faucet.blockbolt.io (paste address manually)

### Check Balances
```bash
# CLI Publisher
sui client gas 0x44e2baf0ceafa68fc742412676245e451fd2327438a9dd3c9f6e824b5fb9dd06

# SELLER
sui client gas 0x17d071be65e54fa6252be15699462d5c4f98b25680f7ff0ca3d2a4b33f6d3950

# BUYER
sui client gas 0x73b3bc71eacfddc8d0a736129f500dcc7b105e93060510f11c928fc4b9637f44
```

## Next Steps (after funding)

Once all addresses have gas:

1. **Build & Test Move** (M1)
   ```bash
   cd packages/move/ticket && sui move build && sui move test && cd ../../..
   ```
   ✅ Already passed!

2. **Deploy Package** (M2)
   ```bash
   bash scripts/deploy_package.sh
   ```
   → Writes `PACKAGE_ID` to `scripts/env.sh`

3. **Create Transfer Policy** (M3)
   ```bash
   bash scripts/create_policy.sh
   ```
   → Writes `POLICY_ID` to `scripts/env.sh`

4. **Run PTB Flows**
   ```bash
   # Mint & List (SELLER)
   ./scripts/demo_flow.sh mint-list
   
   # Buy & Approve (BUYER)
   ./scripts/demo_flow.sh buy-approve
   
   # Check-in (mark ticket as used)
   ./scripts/demo_flow.sh check-in <TICKET_OBJECT_ID>
   ```

## USDC (Optional - for M2/M3)

If you need testnet USDC for testing payment flows:

```bash
# Request USDC for BUYER
bash scripts/usdc_request.sh $(jq -r .address ./.secrets/BUYER.json)
```

Circle USDC Testnet Faucet: https://faucet.circle.com/ (select Sui Testnet)

```

### VERCEL_DEPLOYMENT.md

```markdown
# Vercel Deployment Guide

This guide covers deploying the DropKit web app to Vercel.

## Prerequisites

1. A Vercel account (sign up at https://vercel.com)
2. GitHub repository connected to Vercel (or use Vercel CLI)

## Quick Deploy

### Option 1: Deploy via GitHub (Recommended)

1. Push this repository to GitHub
2. Go to https://vercel.com/new
3. Import your GitHub repository
4. Vercel will auto-detect the Vite configuration
5. Add environment variables (see below)
6. Click "Deploy"

### Option 2: Deploy via Vercel CLI

```bash
# Install Vercel CLI
npm i -g vercel

# Deploy from project root
vercel

# Follow the prompts, then deploy to production
vercel --prod
```

## Environment Variables

Configure these in Vercel Dashboard → Settings → Environment Variables:

### Required for OAuth (zkLogin)

- `VITE_OAUTH_GOOGLE_CLIENT_ID` - Your Google OAuth client ID
- `VITE_OAUTH_REDIRECT_URL` - Your deployed URL + `/auth` (e.g., `https://yourdomain.vercel.app/auth`)

### Optional (already set in vercel.json)

- `VITE_PACKAGE_ID` - Sui package ID (testnet)
- `VITE_POLICY_ID` - Transfer policy ID (testnet)
- `VITE_WALRUS_PUBLISHER_URL` - Walrus publisher endpoint
- `VITE_WALRUS_AGGREGATOR_URL` - Walrus aggregator endpoint

## Build Configuration

The project is configured to build from the `web` directory:

- **Build Command**: `cd web && npm install && npm run build`
- **Output Directory**: `web/dist`
- **Install Command**: `cd web && npm install`
- **Framework**: Vite

## Post-Deployment

### 1. Update OAuth Redirect URI

After deployment, update your Google OAuth settings:

1. Go to https://console.cloud.google.com/apis/credentials
2. Edit your OAuth 2.0 Client ID
3. Add your Vercel URL to "Authorized redirect URIs":
   - `https://your-app.vercel.app/auth`
   - `https://your-app.vercel.app` (for zkLogin callback)

### 2. Update Environment Variables

In Vercel Dashboard:
1. Go to Settings → Environment Variables
2. Set `VITE_OAUTH_REDIRECT_URL` to `https://your-app.vercel.app/auth`
3. Redeploy if needed

### 3. Test the Deployment

1. Visit your Vercel URL
2. Test wallet connection
3. Try creating an event
4. Verify transactions on Sui testnet

## Troubleshooting

### Build Fails

- Check that Node.js version is 18.x or higher
- Verify all dependencies are in `web/package.json`
- Check build logs in Vercel dashboard

### Environment Variables Not Loading

- Ensure variables are prefixed with `VITE_`
- Redeploy after adding new variables
- Check browser console for `import.meta.env` values

### Routing Issues (404 on refresh)

- Verify `vercel.json` rewrites are in place
- This should already be configured in the root `vercel.json`

### OAuth Redirect Errors

- Double-check redirect URI matches exactly
- Ensure OAuth client ID is correct
- Check browser console for detailed errors

## Custom Domain

To add a custom domain:

1. Go to Vercel Dashboard → Settings → Domains
2. Add your domain
3. Update DNS records as instructed
4. Update `VITE_OAUTH_REDIRE
[truncated — 880 more characters]
```

### scripts/package.json

```
{
  "name": "dropkit-scripts",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "description": "Automation scripts for DropKit testnet development",
  "scripts": {
    "postinstall": "echo '✔ Scripts dependencies installed'",
    "gen:wallet:seller": "tsx gen_wallet.ts SELLER",
    "gen:wallet:buyer": "tsx gen_wallet.ts BUYER",
    "faucet:sui:seller": "bash faucet_sui.sh $(jq -r .address ../.secrets/SELLER.json)",
    "faucet:sui:buyer": "bash faucet_sui.sh $(jq -r .address ../.secrets/BUYER.json)",
    "faucet:usdc:buyer": "USDC_OWNER=$(jq -r .address ../.secrets/BUYER.json) tsx faucet_usdc.ts",
    "walrus:check": "tsx walrus_check.ts"
  },
  "dependencies": {
    "@mysten/sui": "^1.0.0",
    "node-fetch": "^3.3.2",
    "open": "^10.0.0"
  },
  "devDependencies": {
    "@types/node": "^20.11.0",
    "tsx": "^4.7.0",
    "typescript": "^5.6.3"
  },
  "engines": {
    "node": ">=20.0.0"
  }
}

```

### web/package.json

```
{
  "name": "dropkit-web",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "build:check": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "@mysten/dapp-kit": "^0.19.6",
    "@mysten/enoki": "^0.12.8",
    "@mysten/sui": "^1.43.1",
    "@tanstack/react-query": "^5.90.5",
    "framer-motion": "^11.18.2",
    "lucide-react": "^0.344.0",
    "qrcode.react": "^4.2.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.22.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.55",
    "@types/react-dom": "^18.2.19",
    "@typescript-eslint/eslint-plugin": "^6.21.0",
    "@typescript-eslint/parser": "^6.21.0",
    "@vitejs/plugin-react": "^4.2.1",
    "autoprefixer": "^10.4.17",
    "eslint": "^8.56.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.5",
    "postcss": "^8.4.35",
    "tailwindcss": "^3.4.1",
    "typescript": "^5.3.3",
    "vite": "^5.1.0"
  }
}

```

### web/src/main.tsx

```typescript
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './styles.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

```

### web/src/App.tsx

```typescript
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { createNetworkConfig, SuiClientProvider, WalletProvider } from '@mysten/dapp-kit';
import { getFullnodeUrl } from '@mysten/sui/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Header } from './components/Header';
import { ScrollProgress } from './components/motion/ScrollProgress';
import { Landing } from './pages/Landing';
import { AppConsole } from './pages/AppConsole';
import { MyTickets } from './pages/MyTickets';
import { Collections } from './pages/Collections';
import { CheckIn } from './pages/CheckIn';
import { AuthCallback } from './pages/AuthCallback';
import { Events } from './pages/Events';
import CreateEvent from './pages/CreateEvent';
import Privacy from './pages/Privacy';
import Terms from './pages/Terms';

// Configure Sui network
const { networkConfig } = createNetworkConfig({
  testnet: { url: getFullnodeUrl('testnet') },
  mainnet: { url: getFullnodeUrl('mainnet') },
});

// Create React Query client
const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <SuiClientProvider networks={networkConfig} defaultNetwork="testnet">
        <WalletProvider autoConnect>
          <BrowserRouter>
            <ScrollProgress />
            <div className="min-h-screen">
              <Header />
              <Routes>
                <Route path="/" element={<Landing />} />
                <Route path="/events" element={<Events />} />
                <Route path="/create" element={<CreateEvent />} />
                <Route path="/my-tickets" element={<MyTickets />} />
                <Route path="/collections" element={<Collections />} />
                <Route path="/console" element={<AppConsole />} />
                <Route path="/checkin" element={<CheckIn />} />
                <Route path="/auth" element={<AuthCallback />} />
                <Route path="/privacy" element={<Privacy />} />
                <Route path="/terms" element={<Terms />} />
              </Routes>
            </div>
          </BrowserRouter>
        </WalletProvider>
      </SuiClientProvider>
    </QueryClientProvider>
  );
}

export default App;
```

### web/postcss.config.js

```javascript
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

```

### web/vite.config.ts

```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': '/src',
    },
  },
})

```

### scripts/.last_mint.sh

```shell
export LAST_KIOSK_ID=0x690040a8da685f2ccbe9788c4172c3aa664ba947a11b0d458012c4fcd32f182a
export LAST_LISTING_ID=0xf1ff5c21d815547cb58665bc6956ea8c2e6b9cce6e4b97aa1f5dd025bfb41c51
export LAST_TICKET_ID=0xf1ff5c21d815547cb58665bc6956ea8c2e6b9cce6e4b97aa1f5dd025bfb41c51

```

### scripts/check_seller_address.ts

```typescript
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { fromB64 } from '@mysten/sui/utils';
import fs from 'node:fs';

const sellerData = JSON.parse(fs.readFileSync('../.secrets/SELLER.json', 'utf-8'));
const secretKeyBytes = fromB64(sellerData.secretKeyB64);
const keypair = Ed25519Keypair.fromSecretKey(secretKeyBytes.slice(0, 32));
const derivedAddress = keypair.getPublicKey().toSuiAddress();

console.log('Stored address:  ', sellerData.address);
console.log('Derived address: ', derivedAddress);
console.log('Match:', sellerData.address === derivedAddress);

```

[103 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]