npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sbcwallet

v0.0.6

Published

Unified Wallet-Pass SDK for Real-World Credentials

Readme

sbcwallet

Unified wallet-pass SDK for Apple Wallet (.pkpass) and Google Wallet.

Features

Supported Pass Types

| Pass Type | Apple Wallet | Google Wallet | |-----------|--------------|---------------| | Boarding Pass | ✅ boardingPass | ✅ flight, transit | | Event Ticket | ✅ eventTicket | ✅ eventTicket | | Store Card / Loyalty | ✅ storeCard | ✅ loyalty | | Coupon | ✅ coupon | ✅ offer | | Gift Card | ✅ storeCard | ✅ giftCard | | Transit Pass | ✅ boardingPass | ✅ transit | | Generic Pass | ✅ generic | ✅ generic |

Installation

npm install sbcwallet

Configuration

Environment Variables

# Google Wallet Configuration
GOOGLE_ISSUER_ID=your-issuer-id
GOOGLE_SA_JSON=/path/to/credentials.json

# Apple Wallet Configuration
APPLE_TEAM_ID=YOUR_TEAM_ID
APPLE_PASS_TYPE_ID=pass.com.example.app
APPLE_CERT_PATH=/path/to/certificate.p12
APPLE_CERT_PASSWORD=your-password
APPLE_WWDR_PATH=/path/to/wwdr.pem

For detailed setup instructions:


Quick Start

1. Boarding Pass

import { createBoardingPass } from 'sbcwallet'

const boardingPass = await createBoardingPass({
  serialNumber: 'FLIGHT-2026-001',
  description: 'Flight from Tehran to Muscat',
  
  flight: {
    flightNumber: 'W5-1234',
    departureAirport: 'IKA',
    departureCity: 'Tehran',
    arrivalAirport: 'MCT',
    arrivalCity: 'Muscat',
    departureTime: '2026-02-15T10:30:00Z',
    arrivalTime: '2026-02-15T12:30:00Z',
    boardingTime: '2026-02-15T09:45:00Z',
    gate: 'A12',
    terminal: 'Terminal 1'
  },
  
  passenger: {
    name: 'Ali Mohammadi',
    seat: '12A',
    class: 'Economy',
    boardingGroup: 'A',
    confirmationCode: 'ABC123'
  },
  
  airline: {
    name: 'Mahan Air',
    logoUrl: 'https://example.com/mahan-logo.png'
  },
  
  style: {
    backgroundColor: '#003366',
    foregroundColor: '#FFFFFF',
    labelColor: '#CCCCCC'
  },
  
  barcode: {
    type: 'QR',
    message: 'M1MOHAMMADI/ALI  EABC123 IKAMCTW5 1234 050Y012A0001 100'
  }
})

// Get Google Wallet Save URL
console.log('Google Save URL:', boardingPass.google?.saveUrl)

// Save Apple Wallet file
import { writeFile } from 'node:fs/promises'
if (boardingPass.apple?.pkpassBuffer) {
  await writeFile('boarding-pass.pkpass', boardingPass.apple.pkpassBuffer)
}

2. Event Ticket

import { createEventTicket } from 'sbcwallet'

const eventTicket = await createEventTicket({
  serialNumber: 'EVENT-2026-001',
  description: 'Traditional Music Concert',
  
  event: {
    name: 'Traditional Persian Music Concert',
    startDate: '2026-03-21T19:00:00Z',
    endDate: '2026-03-21T22:00:00Z',
    venue: {
      name: 'Vahdat Hall',
      address: 'Tehran, Hafez Street',
      latitude: 35.6892,
      longitude: 51.3890
    }
  },
  
  ticket: {
    section: 'VIP',
    row: 'A',
    seat: '15',
    ticketType: 'General Admission',
    ticketNumber: 'TKT-001234'
  },
  
  attendee: {
    name: 'Sara Ahmadi'
  },
  
  style: {
    backgroundColor: '#8B0000',
    foregroundColor: '#FFFFFF'
  },
  
  barcode: {
    type: 'QR',
    message: 'EVENT-2026-001-TKT-001234'
  }
})

3. Store Card / Loyalty Card

import { createStoreCard } from 'sbcwallet'

const storeCard = await createStoreCard({
  serialNumber: 'LOYALTY-001',
  description: 'X Cafe Loyalty Card',
  
  program: {
    name: 'X Rewards',
    issuerName: 'X Cafe',
    logoUrl: 'https://example.com/xcafe-logo.png'
  },
  
  member: {
    name: 'Mohammad Rezaei',
    memberId: 'MEM-123456',
    tier: 'Gold'
  },
  
  balance: {
    points: 1250,
    pointsLabel: 'Points',
    secondaryBalance: 50000,
    secondaryBalanceLabel: 'Credit'
  },
  
  style: {
    backgroundColor: '#111827',
    foregroundColor: '#F9FAFB',
    labelColor: '#9CA3AF'
  },
  
  barcode: {
    type: 'QR',
    message: 'MEM-123456'
  }
})

4. Coupon

import { createCoupon } from 'sbcwallet'

const coupon = await createCoupon({
  serialNumber: 'COUPON-001',
  description: '20% Off Purchase',
  
  offer: {
    title: '20% Special Discount',
    description: '20% off on all products',
    discountAmount: '20%',
    promoCode: 'SAVE20',
    issuerName: 'X Store',
    logoUrl: 'https://example.com/store-logo.png'
  },
  
  validity: {
    startDate: '2026-01-01T00:00:00Z',
    expirationDate: '2026-03-31T23:59:59Z'
  },
  
  terms: 'Minimum purchase $50. Cannot be combined with other offers.',
  
  style: {
    backgroundColor: '#DC2626',
    foregroundColor: '#FFFFFF'
  },
  
  barcode: {
    type: 'QR',
    message: 'COUPON-SAVE20-001'
  }
})

5. Gift Card

import { createGiftCard } from 'sbcwallet'

const giftCard = await createGiftCard({
  serialNumber: 'GIFT-001',
  description: '$500 Gift Card',
  
  card: {
    cardNumber: 'GIFT-1234-5678-9012',
    pin: '1234',
    initialBalance: 500,
    currentBalance: 500,
    currencyCode: 'USD',
    issuerName: 'Big Store',
    logoUrl: 'https://example.com/logo.png'
  },
  
  validity: {
    expirationDate: '2027-01-31T23:59:59Z'
  },
  
  recipient: {
    name: 'Dear Friend',
    message: 'Happy Birthday! 🎂'
  },
  
  style: {
    backgroundColor: '#7C3AED',
    foregroundColor: '#FFFFFF'
  },
  
  barcode: {
    type: 'QR',
    message: 'GIFT-1234-5678-9012'
  }
})

6. Transit Pass

import { createTransitPass } from 'sbcwallet'

const transitPass = await createTransitPass({
  serialNumber: 'TRANSIT-001',
  description: 'Metro Ticket',
  
  trip: {
    departureStation: 'Central Station',
    arrivalStation: 'Airport',
    departureTime: '2026-02-15T08:30:00Z',
    transitType: 'metro', // metro, bus, train, ferry, tram
    lineNumber: 'Line 1',
    vehicleNumber: 'Train 123'
  },
  
  ticket: {
    ticketNumber: 'MTR-001234',
    ticketType: 'Single Ride',
    validFrom: '2026-02-15T00:00:00Z',
    validUntil: '2026-02-15T23:59:59Z',
    zones: ['Zone 1', 'Zone 2']
  },
  
  passenger: {
    name: 'Reza Karimi'
  },
  
  operator: {
    name: 'Metro Transit',
    logoUrl: 'https://example.com/metro-logo.png'
  },
  
  style: {
    backgroundColor: '#0891B2',
    foregroundColor: '#FFFFFF'
  },
  
  barcode: {
    type: 'QR',
    message: 'MTR-001234'
  }
})

7. Generic Pass

import { createGenericPass } from 'sbcwallet'

const genericPass = await createGenericPass({
  serialNumber: 'GENERIC-001',
  description: 'Gym Membership Card',
  
  header: 'Fitness Club',
  primaryText: 'John Smith',
  secondaryText: 'Gold Membership',
  
  auxiliaryFields: [
    { label: 'Member ID', value: 'MEM-789456' },
    { label: 'Join Date', value: '2025-06-01' }
  ],
  
  backFields: [
    { label: 'Address', value: '123 Main Street, City' },
    { label: 'Phone', value: '+1-234-567-8900' },
    { label: 'Hours', value: 'Mon-Fri: 6AM - 11PM' }
  ],
  
  images: {
    logoUrl: 'https://example.com/gym-logo.png',
    heroImageUrl: 'https://example.com/gym-hero.jpg'
  },
  
  style: {
    backgroundColor: '#065F46',
    foregroundColor: '#FFFFFF'
  },
  
  barcode: {
    type: 'QR',
    message: 'MEMBER-789456'
  }
})

Unified API

For more flexibility, you can use the generic createWalletPass function:

import { createWalletPass } from 'sbcwallet'

// Create any pass type by specifying passType
const pass = await createWalletPass({
  passType: 'eventTicket',
  // ... other parameters based on pass type
})

Pass Management

import {
  getWalletPass,
  listWalletPasses,
  updateWalletPassStatus,
  updateLoyaltyBalance,
  updateGiftCardBalance,
  sendPassNotification,
  regeneratePass
} from 'sbcwallet'

// Get pass by ID
const pass = await getWalletPass('PASS-123')

// List passes for a user
const userPasses = await listWalletPasses({ userId: 'USER-001' })

// Update pass status (e.g., for cancelled event)
await updateWalletPassStatus('PASS-123', 'cancelled')

// Update loyalty card points
await updateLoyaltyBalance('LOYALTY-001', {
  pointsDelta: 100,
  newTier: 'Platinum'
})

// Update gift card balance
await updateGiftCardBalance('GIFT-001', {
  newBalance: 350
})

// Send notification to pass (Google Wallet)
await sendPassNotification('PASS-123', {
  header: 'Reminder',
  body: 'Your event is tomorrow!'
})

// Regenerate pass after updates
const updatedPass = await regeneratePass('PASS-123')

Multi-tenant Loyalty

For complex scenarios like multi-business platforms:

Define a Business

import { createBusiness, createLoyaltyProgram } from 'sbcwallet'

const biz = createBusiness({
  name: 'X Cafe',
  programName: 'X Rewards',
  pointsLabel: 'Points',
  wallet: {
    googleWallet: {
      issuerName: 'X Cafe',
      backgroundColor: '#111827',
      logoUrl: 'https://example.com/logo.png',
      classOverrides: {
        reviewStatus: 'UNDER_REVIEW'
      }
    },
    appleWallet: {
      organizationName: 'X Cafe',
      logoText: 'X',
      backgroundColor: 'rgb(17, 24, 39)',
      passOverrides: {
        userInfo: { tenant: 'x' }
      }
    }
  }
})

await createLoyaltyProgram({
  businessId: biz.id,
  locations: [
    { latitude: 35.6892, longitude: 51.389 },
    { latitude: 35.7, longitude: 51.4 }
  ],
  relevantText: 'Welcome back — show this card at checkout',
  countryCode: 'OM',
  homepageUrl: 'https://example.com'
})

Issue a Card

import {
  createCustomerAccount,
  issueLoyaltyCard,
  updateLoyaltyPoints,
  getGoogleObject,
  getPkpassBuffer
} from 'sbcwallet'

const customer = createCustomerAccount({
  businessId: biz.id,
  fullName: 'Alice',
  memberId: 'USER-123'
})

const card = await issueLoyaltyCard({
  businessId: biz.id,
  customerId: customer.id,
  initialPoints: 10
})

// Update points
await updateLoyaltyPoints({ cardId: card.id, delta: 5 })

// Get Google Wallet Save URL
const { saveUrl } = await getGoogleObject('child', card)
console.log(saveUrl)

// Save Apple Wallet file
const pkpass = await getPkpassBuffer('child', card)
await writeFile('loyalty.pkpass', pkpass)

Location-based Features

Lock Screen Surfacing

// Apple Wallet: Auto-display when user is near location
createBusiness({
  wallet: {
    appleWallet: {
      passOverrides: {
        locations: [
          { latitude: 35.6892, longitude: 51.389 }
        ],
        relevantText: 'Welcome — show this card at checkout'
      }
    }
  }
})

Push Notifications

import { pushLoyaltyMessage } from 'sbcwallet'

// Google Wallet: Send message to pass
await pushLoyaltyMessage({
  cardId: card.id,
  header: 'X Cafe',
  body: 'You are nearby — show this card to earn points.',
  messageType: 'TEXT_AND_NOTIFY'
})

Demo Servers

Google Wallet

# Multi-tenant loyalty server
npm run loyalty:server:multi
# Open http://localhost:5190

# Simple loyalty server
npm run loyalty:server
# Open http://localhost:5189

# Google Wallet issuance (CLI)
node examples/loyalty-google-issue.js

Apple Wallet

# Apple Wallet server with web UI
node examples/loyalty-apple-server.js
# Open http://localhost:3001

# Apple Wallet issuance (CLI)
node examples/loyalty-apple-issue.js

Required Environment Variables for Apple Wallet

# Apple Developer credentials
APPLE_TEAM_ID=YOUR_TEAM_ID           # Your Apple Developer Team ID
APPLE_PASS_TYPE_ID=pass.com.x.y      # Your Pass Type Identifier
APPLE_CERT_PATH=/path/to/cert.p12    # Path to signing certificate
APPLE_CERT_PASSWORD=password         # Certificate password (if any)
APPLE_WWDR_PATH=/path/to/wwdr.pem    # Apple WWDR certificate

# Optional customization
LOYALTY_BUSINESS_NAME=SBC Coffee
LOYALTY_PROGRAM_NAME=SBC Rewards
LOYALTY_CUSTOMER_NAME=John Doe
LOYALTY_INITIAL_POINTS=10
LOYALTY_BG=#111827

TypeScript Support

This SDK is fully written in TypeScript with complete type definitions:

import type {
  // Pass types
  ApplePassType,
  GooglePassType,
  
  // Pass inputs
  BoardingPassInput,
  EventTicketInput,
  StoreCardInput,
  CouponInput,
  GiftCardInput,
  TransitPassInput,
  GenericPassInput,
  WalletPassInput,
  
  // Pass data
  WalletPassData,
  PassGenerationOptions,
  
  // Statuses
  EventStatus,
  FlightStatus,
  TransitStatus,
  OfferStatus,
  GiftCardStatus
} from 'sbcwallet'

Development

# Install dependencies
npm install

# Build project
npm run build

# Run tests
npm test

# Check package before publishing
npm pack --dry-run

API Reference

Pass Creation Functions

| Function | Description | |----------|-------------| | createBoardingPass(input) | Create flight/transit boarding pass | | createEventTicket(input) | Create event ticket | | createStoreCard(input) | Create loyalty/store card | | createCoupon(input) | Create discount coupon | | createGiftCard(input) | Create gift card | | createTransitPass(input) | Create transit pass | | createGenericPass(input) | Create generic pass | | createWalletPass(input) | Create any pass type |

Pass Management Functions

| Function | Description | |----------|-------------| | getWalletPass(id) | Get pass by ID | | listWalletPasses(filter) | List passes | | updateWalletPassStatus(id, status) | Update pass status | | updateLoyaltyBalance(id, data) | Update loyalty points | | updateGiftCardBalance(id, data) | Update gift card balance | | sendPassNotification(id, message) | Send notification | | regeneratePass(id) | Regenerate pass |

Loyalty Functions

| Function | Description | |----------|-------------| | createBusiness(config) | Define a business | | createLoyaltyProgram(config) | Create loyalty program | | createCustomerAccount(data) | Create customer account | | issueLoyaltyCard(data) | Issue loyalty card | | updateLoyaltyPoints(data) | Update points | | pushLoyaltyMessage(data) | Send message |

Apple Wallet Functions

| Function | Description | |----------|-------------| | getPkpassBuffer(type, card) | Get pkpass file buffer |

Google Wallet Functions

| Function | Description | |----------|-------------| | getGoogleObject(type, card) | Get Save URL |


License

MIT License - See LICENSE for details.