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

@abcwalletio/core

v1.1.1

Published

ABC WaaS core SDK — MPC-based wallet authentication, signing, and storage primitives

Readme

@abcwalletio/core

ABC Wallet-as-a-Service 핵심 SDK입니다. MPC(Multi-Party Computation) 기반 지갑 생성, 인증, 서명 기능을 제공합니다.

Installation

pnpm add @abcwalletio/core

Quick Start

import { createWaasSDK, MemoryStorage } from '@abcwalletio/core';

// SDK 초기화
const sdk = await createWaasSDK({
  storage: new MemoryStorage(),
  auth: {
    v2: {
      clientId: 'your-client-id',
      clientSecret: 'your-client-secret',
    },
  },
});

// WASM 초기화 확인
if (sdk.isReady()) {
  console.log('SDK is ready!');
}

Modules

Auth Module

인증 모듈은 두 가지 경로를 제공합니다 — 동일 SDK 인스턴스에서 공존 가능합니다.

| 경로 | 구조 | 적합한 경우 | |------|------|------------| | V2 (Secure Channel) | 브라우저가 이메일/비밀번호를 암호화해 WaaS에 직접 로그인 | 백엔드 없는 SPA, 간단한 통합, PoC | | V3 (TokenProvider 주입) | 고객사 백엔드/auth-service/v3/login으로 토큰을 발급해 프론트로 전달 | 자체 인증 스택이 있는 엔터프라이즈 |

// ─────────────────────────────────────────────────────────
// V3 인증 — TokenProvider 주입
// ─────────────────────────────────────────────────────────
// V3만 사용하면 clientSecret이 브라우저에 필요 없다.
const sdk = await createWaasSDK({
  storage,
  auth: {
    v3: {
      tokenProvider: async () => {
        // 고객사 백엔드가 자체 세션을 검증하고 WaaS 토큰을 대신 발급
        const r = await fetch('/api/waas/token', { credentials: 'include' });
        if (!r.ok) throw new Error('unauthorized');
        const { access_token, expires_in } = await r.json();
        return { accessToken: access_token, expiresIn: expires_in };
      },
      // 선택: 만료 몇 초 전에 재발급할지 (기본 300초)
      refreshThresholdSec: 300,
    },
  },
});

// 필요 시 명시적 토큰 확보 (자동 발급 포함)
const token = await sdk.auth.v3.getValidAccessToken();

// ─────────────────────────────────────────────────────────
// V2 인증 — Secure Channel 기반 (이메일/비밀번호)
// ─────────────────────────────────────────────────────────
const result = await sdk.auth.v2.loginWithEmail('[email protected]', 'password');

// 회원가입
await sdk.auth.v2.sendVerificationCode('[email protected]');
await sdk.auth.v2.registerWithEmail({
  email: '[email protected]',
  password: 'password123',
  verificationCode: '123456',
});

// 비밀번호 초기화
await sdk.auth.v2.sendResetPasswordCode('[email protected]');
await sdk.auth.v2.resetPassword('[email protected]', '123456', 'newPassword');

// ─────────────────────────────────────────────────────────
// 공통 기능 — V3/V2 어느 쪽이든 인증되면 성립
// ─────────────────────────────────────────────────────────
// 로컬 토큰 존재 여부 확인 (서버 왕복 없음)
const isAuthV3 = await sdk.auth.v3.isAuthenticated();  // V3 tokenProvider 활성 + 발급 성공
const isAuthV2 = await sdk.auth.v2.isAuthenticated();

// 서버 측 세션 유효성까지 검증 (getWalletUser 경로)
const serverOk = await sdk.verifyServerSession();

// 현재 사용자 정보 — V3는 user 정보를 보관하지 않으므로 V2만 조회
const user = await sdk.auth.v2.getUser();

// Access Token 가져오기 — V3 활성이면 필요 시 자동 발급 후 반환, 아니면 V2 폴백
const token = await sdk.auth.getAccessToken();

// SDK 레벨 로그아웃: abc_waas_* prefix 키만 삭제 + v3/v2 토큰 정리 + 'logout' broadcast
await sdk.logout();

// 또는 특정 모듈만 정리
await sdk.auth.v3.logout();  // V3 메모리 캐시 정리 + 'logout' 이벤트
await sdk.auth.v2.logout();

서버 세션 무효화 범위 현재 backend는 refresh token revocation endpoint를 제공하지 않습니다. logout() 이후에도 refresh token은 TTL이 만료될 때까지 서버 측에서 유효합니다. 토큰 유출 위험 환경에서는 호출측에서 별도 세션 파기 플로우를 추가하세요.

MPC Module

MPC 키 생성 및 서명 기능을 제공합니다.

// 키 생성
const keyResult = await sdk.mpc.generateKeyShare(
  'secp256k1', // curve: 'secp256k1' | 'ed25519'
  'password123' // 비밀번호 (8자 이상)
);
console.log('Key ID:', keyResult.keyId);
console.log('Public Key:', keyResult.publicKey);

// 키 복구 (기존 키가 있는 경우)
const recovered = await sdk.mpc.recoverKeyShare(
  'secp256k1',
  'password123'
);

// 일반 서명 (secp256k1 + ed25519)
const signResult = await sdk.mpc.sign(keyId, messageHash, 'password123');
console.log('Signature:', signResult.signature);

// MTA 서명 (secp256k1 전용, 더 효율적)
const mtaResult = await sdk.mpc.signMta(keyId, messageHash, 'password123');
console.log('Signature:', mtaResult.signature);

// 자동 서명 — curve에 따라 최적 방식 선택 (secp256k1 → signMta, ed25519 → sign)
const autoResult = await sdk.mpc.signAuto(keyId, messageHash, 'password123');

// 공개키 조회
const publicKey = await sdk.mpc.getPublicKey(keyId);

// 비밀번호 검증
const isValid = await sdk.mpc.validatePassword('password123');

// Share 유효성 검증
const shareValid = await sdk.mpc.validateShare('password123');

Wallet API Module

V3 Wallet API를 호출합니다.

// 지갑 정보 조회
const wallet = await sdk.wallet.getWallet();

// 지갑 키 목록 조회
const keys = await sdk.wallet.getWalletKeys();

// 지갑 사용자 정보 조회
const user = await sdk.wallet.getWalletUser();

// 지갑 토큰 발급 (MPC 노드 인증용)
const walletToken = await sdk.wallet.getWalletToken(keyId);

// 새 키 등록
await sdk.wallet.registerWalletKey(keyId, curve, publicKey);

Storage

다양한 Storage 구현체를 제공합니다. 모두 StorageInterface를 구현합니다.

MemoryStorage

인메모리 저장소입니다. 테스트나 SSR 환경에서 사용합니다.

import { MemoryStorage } from '@abcwalletio/core';

const storage = new MemoryStorage();

LocalStorageAdapter

window.localStorage를 래핑합니다. 영구 저장이 필요한 브라우저 환경에서 사용합니다.

import { LocalStorageAdapter } from '@abcwalletio/core';

const storage = new LocalStorageAdapter();

SessionStorageAdapter

window.sessionStorage를 래핑합니다. 세션 단위 저장이 필요한 경우 사용합니다.

import { SessionStorageAdapter } from '@abcwalletio/core';

const storage = new SessionStorageAdapter();

IndexedDBStorage

IndexedDB 기반 저장소입니다. 대용량 데이터나 더 안전한 저장이 필요한 경우 사용합니다.

import { IndexedDBStorage } from '@abcwalletio/core';

const storage = new IndexedDBStorage();
await storage.waitForInit(); // 비동기 초기화 대기

// 초기화 상태 확인
if (storage.ready) {
  console.log('IndexedDB is ready');
}

// 사용 후 정리
storage.close();

BridgeStorage

모바일 앱의 웹뷰에서 네이티브 앱과 통신하기 위한 비동기 저장소입니다. AsyncStorageInterface를 구현합니다.

import { BridgeStorage } from '@abcwalletio/core';

// 기본 사용법 (window.abcWaas.storage 자동 참조)
const storage = new BridgeStorage();

// 커스텀 storageKey 사용
const storage = new BridgeStorage({ storageKey: 'myCustomBridge' });

// 커스텀 핸들러 직접 주입
const storage = new BridgeStorage({ handler: myCustomHandler });

// 비동기 API 사용
const value = await storage.getItem('key');
await storage.setItem('key', 'value');
await storage.removeItem('key');
await storage.clear();

네이티브 앱 개발자 가이드

네이티브 앱에서 웹뷰에 브릿지를 주입해야 합니다.

1. window.abcWaas.storage 주입

// 네이티브 앱에서 웹뷰에 주입할 객체
window.abcWaas = {
  storage: {
    // 필수: ABC WaaS 브릿지 마커 메서드
    isAbcWaasBridge: () => Promise.resolve(true),

    // 필수: Storage 메서드들
    getItem: (key) => { /* Promise<string | null> 반환 */ },
    setItem: (key, value) => { /* Promise<void> 반환 */ },
    removeItem: (key) => { /* Promise<void> 반환 */ },

    // 선택: 추가 메서드
    clear: () => { /* Promise<void> 반환 */ },
    getAllKeys: () => { /* Promise<string[]> 반환 */ },
  }
};

2. 필수 메서드

SDK는 REQUIRED_BRIDGE_METHODS 상수로 필수 메서드를 정의합니다:

import { REQUIRED_BRIDGE_METHODS } from '@abcwalletio/core';
// ['isAbcWaasBridge', 'getItem', 'setItem', 'removeItem']
  • isAbcWaasBridge(): 유효한 ABC WaaS 브릿지임을 확인하는 마커 메서드. 반드시 Promise<true>를 반환해야 합니다.
  • getItem(key): 키에 해당하는 값을 반환
  • setItem(key, value): 키-값 쌍을 저장
  • removeItem(key): 키에 해당하는 값을 삭제

3. AsyncBridgeHandler 인터페이스

import type { AsyncBridgeHandler } from '@abcwalletio/core';

const handler: AsyncBridgeHandler = {
  isAbcWaasBridge: () => Promise.resolve(true),
  getItem: (key) => nativeStorage.get(key),
  setItem: (key, value) => nativeStorage.set(key, value),
  removeItem: (key) => nativeStorage.delete(key),
  // prefix-aware clear 또는 getAllKeys 중 **하나는 반드시 제공** 필요.
  // 둘 다 없으면 페이지 새로고침 후 `sdk.logout()`이 영속 키를 못 지움.
  clear: (prefix) => nativeStorage.clear(prefix),   // 선택 (prefix 인자 받음)
  getAllKeys: () => nativeStorage.keys(),           // 선택 (권장)
};

Custom Storage

StorageInterface를 직접 구현할 수도 있습니다. 모든 메서드가 비동기입니다.

import type { StorageInterface } from '@abcwalletio/core';

class CustomStorage implements StorageInterface {
  async getItem(key: string): Promise<string | null> { /* ... */ }
  async setItem(key: string, value: string): Promise<void> { /* ... */ }
  async removeItem(key: string): Promise<void> { /* ... */ }
  /**
   * prefix가 있으면 해당 prefix로 시작하는 키만, 없으면 전체 삭제.
   * 빈 문자열 prefix는 throw해야 합니다 (전체와 구분 모호).
   */
  async clear(prefix?: string): Promise<void> { /* ... */ }
}

AsyncStorageInterface (Deprecated)

StorageInterface의 별칭입니다. 하위 호환을 위해 유지되며, 새 코드에서는 StorageInterface를 직접 사용하세요.

Event System

SDK는 이벤트 시스템을 통해 인증 상태 변화를 알립니다.

이벤트 타입

| Event | Payload | Description | |-------|---------|-------------| | tokenRefreshed | { accessToken, refreshToken } | 토큰이 자동 갱신되었을 때 | | authError | { error: WaasError } | 인증 관련 에러 발생 시 | | logout | void | 로그아웃 시 |

이벤트 구독/해제

import { createWaasSDK, type WaasEventHandler } from '@abcwalletio/core';

const sdk = await createWaasSDK({ ... });

// 이벤트 핸들러 정의
const handleTokenRefreshed: WaasEventHandler<'tokenRefreshed'> = (payload) => {
  console.log('토큰이 갱신되었습니다:', payload.accessToken);
};

const handleAuthError: WaasEventHandler<'authError'> = (payload) => {
  console.error('인증 에러:', payload.error.message);
  // 로그인 페이지로 이동 등의 처리
};

const handleLogout: WaasEventHandler<'logout'> = () => {
  console.log('로그아웃되었습니다');
  // UI 상태 초기화 등
};

// 이벤트 구독
sdk.on('tokenRefreshed', handleTokenRefreshed);
sdk.on('authError', handleAuthError);
sdk.on('logout', handleLogout);

// 이벤트 해제
sdk.off('tokenRefreshed', handleTokenRefreshed);

Auto Token Refresh

SDK는 JWT 토큰 자동 갱신 기능을 제공합니다. getValidAccessToken() 메서드를 사용하면 토큰 만료를 자동으로 처리합니다. V2와 V3의 갱신 방식이 다릅니다.

| 경로 | 갱신 방식 | 저장소 | |------|----------|--------| | V2 | refresh_token을 서버에 제출해 access token 재발급 | Storage(localStorage 등) | | V3 | tokenProvider를 재호출해 고객사 백엔드에서 새 토큰을 가져옴 | 메모리만 (Storage 미저장) |

V2 사용법

try {
  const accessToken = await sdk.auth.v2.getValidAccessToken();
  // accessToken을 사용한 API 호출
} catch (error) {
  console.error('인증 필요:', error);
}

V3 사용법

try {
  const accessToken = await sdk.auth.v3.getValidAccessToken();
  // 만료 임박 시 SDK가 자동으로 tokenProvider를 재호출해 새 토큰을 발급받음
} catch (error) {
  console.error('tokenProvider 호출 실패:', error);
}

동작 방식

  1. 토큰 유효성 검사: 현재 Access Token의 만료 시간 확인
  2. 자동 갱신:
    • V2 — 만료 5분 전이면 Refresh Token으로 자동 갱신
    • V3 — 만료 refreshThresholdSec초 전(기본 300)이면 tokenProvider 재호출 (동시 호출은 싱글플라이트로 1회만 실행)
  3. 이벤트 발생: 갱신 성공 시 tokenRefreshed 이벤트 발생
  4. 에러 처리: 갱신 실패 시 authError 이벤트 발생 후 자동 로그아웃

자동 갱신 흐름

getValidAccessToken() 호출
    │
    ▼
토큰 존재 확인 ──No──▶ authError 이벤트 + 에러 throw
    │
   Yes
    ▼
만료 5분 전? ──No──▶ 현재 토큰 반환
    │
   Yes
    ▼
refreshToken() 호출
    │
    ├─Success─▶ tokenRefreshed 이벤트 + 새 토큰 반환
    │
    └─Failure─▶ authError 이벤트 + logout 이벤트 + 에러 throw

수동 토큰 갱신

필요한 경우 수동으로 토큰을 갱신할 수 있습니다.

const result = await sdk.auth.v2.refreshToken();

if (result.success) {
  console.log('새 토큰:', result.accessToken);
} else {
  console.error('갱신 실패:', result.error);
  // 갱신 실패 시 자동으로 logout 이벤트가 발생합니다
}

Storage Keys

SDK가 내부적으로 사용하는 Storage 키입니다. 모두 abc_waas_ prefix를 공유하며, sdk.logout()은 이 prefix 범위만 정리해 호스트 앱의 다른 localStorage 데이터를 보존합니다.

| Key | Description | |-----|-------------| | abc_waas_shares | MPC 쉐어 번들 (curve별 ShareData를 JSON으로 묶어 저장) | | abc_waas_auth_token | V2 Access Token | | abc_waas_refresh_token | V2 Refresh Token | | abc_waas_user | V2 사용자 정보 |

V3는 토큰을 Storage에 저장하지 않습니다. 새로고침 시 tokenProvider가 다시 호출되어 메모리 캐시를 복구합니다.

Error Handling

SDK는 WaasError 클래스를 통해 에러를 처리합니다.

import { WaasError, WaasErrorCode } from '@abcwalletio/core';

try {
  await sdk.mpc.generateKeyShare('secp256k1', 'password');
} catch (error) {
  if (error instanceof WaasError) {
    console.log('Code:', error.code);
    console.log('Message:', error.message);
    console.log('Details:', error.details);

    switch (error.code) {
      case WaasErrorCode.AUTH_FAILED:
        // 인증 실패 처리
        break;
      case WaasErrorCode.MPC_SHARE_NOT_FOUND:
        // Share 없음 처리
        break;
      // ...
    }
  }
}

API 레벨 에러 처리

SDK는 HTTP 200 응답이라도 응답 body에 에러 코드가 포함된 경우 자동으로 감지하여 처리합니다.

API 에러 응답 형식

서버에서 반환하는 API 레벨 에러 응답 형식:

interface ApiErrorResponse {
  code: string;    // "103", "104" 등 문자열
  message: string; // "JWT_EXPIRED", "INVALID_TOKEN" 등
}

지원하는 API 에러 코드

| API 에러 코드 | 메시지 | SDK 에러 코드 | 설명 | |--------------|--------|--------------|------| | 103 | JWT_EXPIRED | AUTH_EXPIRED | JWT 토큰 만료 - 자동 갱신 시도 | | 104 | INVALID_TOKEN | AUTH_INVALID_TOKEN | 유효하지 않은 토큰 |

HTTP 상태 코드 기반 자동 갱신

| HTTP 상태 코드 | SDK 에러 코드 | 설명 | |---------------|--------------|------| | 401 Unauthorized | AUTH_EXPIRED | 인증 만료 - 자동 갱신 시도 | | 403 Forbidden | AUTH_FAILED | 접근 권한 없음 - 자동 갱신 시도 |

HTTP 401/403 응답 시에도 JWT 만료와 동일하게 토큰 갱신을 시도합니다.

JWT 만료 시 자동 재시도

JWT가 만료된 경우(code: "103"), SDK는 자동으로 다음 과정을 수행합니다:

  1. Refresh Token을 사용하여 새로운 Access Token 발급 시도
  2. 갱신 성공 시 원래 요청을 새 토큰으로 1회 재시도
  3. 갱신 실패 시 AUTH_EXPIRED 에러 발생 및 authError 이벤트 emit
API 요청 → HTTP 200 + { code: "103" } 응답
    │
    ▼
토큰 갱신 시도 (refreshToken)
    │
    ├─ 성공 → 원래 요청 재시도 (새 토큰으로)
    │           │
    │           ├─ 성공 → 정상 결과 반환
    │           └─ 실패 → 에러 throw
    │
    └─ 실패 → authError 이벤트 + AUTH_EXPIRED 에러 throw

에러 처리 예시

import { WaasError, WaasErrorCode } from '@abcwalletio/core';

// authError 이벤트 구독
sdk.on('authError', (payload) => {
  if (payload.error.code === WaasErrorCode.AUTH_EXPIRED) {
    // 토큰 만료로 인한 갱신 실패
    // 로그인 페이지로 이동 등의 처리
    console.log('세션이 만료되었습니다. 다시 로그인해주세요.');
  }
});

try {
  const walletToken = await sdk.wallet.getWalletToken(keyId);
} catch (error) {
  if (error instanceof WaasError) {
    switch (error.code) {
      case WaasErrorCode.AUTH_EXPIRED:
        // JWT 만료 및 갱신 실패
        break;
      case WaasErrorCode.AUTH_INVALID_TOKEN:
        // 유효하지 않은 토큰
        break;
    }
  }
}

Error Codes

| Category | Code Range | Description | |----------|------------|-------------| | AUTH | 1000-1999 | 인증 관련 에러 | | WALLET | 2000-2999 | 지갑 관련 에러 | | MPC | 3000-3999 | MPC 연산 에러 | | STORAGE | 4000-4999 | Storage 에러 | | NETWORK | 5000-5999 | 네트워크 에러 | | PROVIDER | 6000-6999 | Provider 에러 | | WASM | 7000-7999 | WASM 에러 |

Configuration

Environment

SDK는 프로덕션 환경 (https://api.waas.myabcwallet.com)에 고정됩니다. environment는 공개 설정 필드가 아닙니다.

TypeScript Types

import type {
  // SDK
  WaasSDK,
  WaasSDKConfig,
  Environment,
  CurveType,

  // Auth
  AuthModule,
  AuthProvider,
  User,
  AuthResult,

  // MPC
  MpcModule,
  GenerateShareResult,
  RecoverShareResult,
  SignResult,

  // Wallet API
  WalletApiModule,
  WalletInfo,
  WalletKey,
  WalletUser,

  // Storage
  StorageInterface,
  AsyncStorageInterface,
  AsyncBridgeHandler,
  BridgeStorageOptions,

  // Error
  WaasError,
  WaasErrorCode,
} from '@abcwalletio/core';

License

MIT — Copyright (c) 2026 Ahnlab Blockchain Company