npm package: @human.tech/waap-sdk-core
Description: SDK for interacting with WaaP
Latest version: 0.1.2

# @silk-wallet/sdk-core

Core interfaces and types for the Silk Wallet SDK. This package contains platform-agnostic code and interfaces that are implemented by platform-specific packages.

## Installation

```bash
npm install @silk-wallet/silk-wallet-sdk-core
# or
yarn add @silk-wallet/silk-wallet-sdk
# or
pnpm add @silk-wallet/silk-wallet-sdk
```

## Usage

This package is typically not used directly. Instead, use one of the platform-specific implementations:

- `@silk-wallet/silk-wallet-sdk-web` for web applications
- `@silk-wallet/silk-wallet-sdk-react-native` for React Native applications

## What's Included

### Core Interfaces

- `StorageFacade` - Cross-platform storage abstraction
- `EthereumProvider` - Core wallet provider implementation
- `WalletMessageManager` - Message handling between app and wallet

### Storage Types

- `KeyValueStore` - Basic key-value storage interface
- `JsonStore` - JSON serialization helpers
- `StorageError` - Error handling for storage operations

### Utilities

- Platform detection
- Storage helpers and test utilities
- Key management and scoping

## Architecture

The core package provides the foundation for platform-specific implementations:

```
@silk-wallet/sdk-core (interfaces & core logic)
├── @silk-wallet/sdk-web (web implementation)
└── @silk-wallet/sdk-react-native (native implementation)
```

## License

```javascript
import { initSilk, SilkWalletConnect } from '@silk-wallet/silk-wallet-sdk'

SilkWalletConnect.setProjectId('YOUR_WALLETCONNECT_PROJECT_ID')
initSilk()
```

3. **Set it as an environment variable**:
   - Set `NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID` in your .env.local file (Next.js)
   - Or set `WALLET_CONNECT_PROJECT_ID` for other environments

### API Reference

The Silk SDK implements the standard Ethereum Provider API (EIP-1193) with some additional methods:

- `enable()`: Alias for `request({ method: 'eth_requestAccounts' })`
- `isConnected()`: Returns whether the provider is connected
- `login()`: Prompt the user to connect an external wallet
- `logout()`: Disconnect the current session
- `getLoginMethod()`: Returns the current login method ('human', 'injected', 'walletconnect', or null)
- `requestEmail()`: Request the user's email address
- `requestSBT(type)`: Request a Soulbound Token of the specified type
- `toggleDarkMode()`: Toggle between light and dark mode

### Auto-Connect Functionality

The Silk SDK automatically attempts to reconnect users when they refresh the page or return to your application. This works seamlessly in the background when you call `eth_requestAccounts`.

#### How Auto-Connect Works

1. When a user successfully logs in via `login()`, their choice is remembered
2. On subsequent page loads, calling `eth_requestAccounts` (before `login()`) will automatically attempt to reconnect using their previous method
3. If the previous method is no longer available or connected, the auto-connect will fail gracefully

#### Checking the Current Login Method

You can check which login method is currently active without triggering a connection:

```javascript
// Check the current login method
const loginMethod = window.silk.getLoginMethod()

if (loginMethod === 'human') {
  console.log('User is connected via Silk Human Wallet')
} else if (loginMethod === 'injected') {
  console.log('User is connected via injected wallet (e.g., MetaMask)')
} else if (loginMethod === 'walletconnect') {
  console.log('User is connected via WalletConnect')
} else {
  console.log('User is not connected')
}
```

**Note**: `getLoginMethod()` verifies that the connection is actually still valid. If the wallet extension is disabled, WalletConnect session expired, or any other connection issue exists, it will return `null` and automatically clean up the stored state.

#### Implementing Auto-Connect

```javascript
import { initSilk } from '@silk-wallet/silk-wallet-sdk'

// Initialize Silk
initSilk()

// Attempt to auto-connect
try {
  const accounts = await window.silk.request({
    method: 'eth_requestAccounts'
  })
  console.log('Auto-connected with accounts:', accounts)

  // Auto connect failed, proceed with regular login
  if (accounts.length === 0) {
    await window.silk.login()
  }
} catch (error) {
  console.log('Auto-connect failed, user needs to login again')
}
```

#### Logout and Cleanup

When you call `logout()`, the stored login method is automatically cleared:

```javascript
await window.silk.logout()
console.log(window.silk.getLoginMethod()) // Returns null
```

## Error Handling

```javascript
try {
  const accounts = await window.silk.request({ method: 'eth_requestAccounts' })
} catch (error) {
  console.error('Error connecting to Silk:', error)
}
```

## Events

The Silk provider emits various events you can listen to:

```javascript
// When the connection status changes
window.silk.on('connect', () => {
  console.log('Connected to Silk')
})

// When accounts change
window.silk.on('accountsChanged', (accounts) => {
  console.log('Active account changed:', accounts[0])
})

// When the chain changes
window.silk.on('chainChanged', (chainId) => {
  console.log('Chain changed to:', chainId)
})
```

## TypeScript Support

The Silk SDK includes TypeScript definitions. You can import them like this:

```typescript
import { initSilk, SilkProvider } from '@silk-wallet/silk-wallet-sdk'

// Now you can use type hints
const silk: SilkProvider = initSilk()
```

## Support

If you encounter any issues or have questions, please reach out to our support team or file an issue in our GitHub repository.

## Migrating from pre-v0.5.0

If you're migrating from a pre-v0.5.0 version, please note that event emitter fields like `uiMessageManager` have been removed from the `SilkEthereumProviderInterface`. For event handling, you should now use methods directly on the provider instance.

For example, if you were previously disconnecting with:

```js
async disconnect(): Promise<void> {
  const provider = await this.getProvider();
  provider.uiMessageManager.removeListener('accountsChanged', this.onAccountsChanged);
  provider.uiMessageManager.removeListener('chainChanged', this.onChainChanged);
  provider.uiMessageManager.removeListener('disconnect', this.onDisconnect);
}
```

You should now use:

```js
async disconnect(): Promise<void> {
  const provider = await this.getProvider();
  provider.removeListener('accountsChanged', this.onAccountsChanged);
  provider.removeListener('chainChanged', this.onChainChanged);
  provider.removeListener('disconnect', this.onDisconnect);
}
```

This follows the EIP-1193 standard for Ethereum providers.