# Xpaid Wallet SDK

A robust, event-driven SDK for seamless iframe-based wallet interactions. Designed for embedding within partner applications, `XpaidWalletSdk` simplifies secure communication with the Xpaid Wallet.

## Installation

```sh
npm install xpaid-wallet-sdk
```

## Quick Start

### Initialize the SDK

```ts
import { Environment, Message, MessageSchema, SdkConfig, XpaidWalletSdk } from 'xpaid-wallet-sdk'

const config: SdkConfig = {
  containerId: 'wallet-container', // The ID of the HTML container where the iframe will be injected
  hashToken: 'hash-token', // Required authentication token
  environment: Environment.Production, // Optional: Environment
  width: '400px', // Optional: Custom width of the iframe
  height: '600px', // Optional: Custom height of the iframe
  colorScheme: { light: { primary: '#FF5733' } }, // Optional: Custom theme colors
}

XpaidWalletSdk.initialize(config)
```

## Getting Hash token

### Create/Update customer or Get a hash token for the customer

### Endpoint:
**POST** `https://stagewalletapi.xpaid.org/api/v1/customers`

### Request Headers:
| Header         | Type   | Description                          |
|---------------|--------|--------------------------------------|
| X-API-KEY     | string | Your personal API key               |
| X-SIGNATURE   | string | JSON payload signed with HMAC SHA-256 and Base64 encoded |

#### How to Generate X-SIGNATURE:

1. **Serialize the JSON payload** – Convert the request body into a JSON string.
2. **Get the API secret as bytes** – Your secret key must be used as a byte array.
3. **Hash the JSON payload using HMAC-SHA256** – Use your secret key to sign the JSON payload.
4. **Encode the resulting hash in Base64** – Convert the output to a Base64 string.
5. **Send X-SIGNATURE in the request header** – Attach the generated signature to the `X-SIGNATURE` header.

#### Example in C#:
```csharp
var jsonPayload = JsonSerializer.Serialize(createCustomerRequest);

var secretBytes = Encoding.UTF8.GetBytes(secret);
var payloadBytes = Encoding.UTF8.GetBytes(jsonPayload);

using var hmac = new HMACSHA256(secretBytes);
var hashBytes = hmac.ComputeHash(payloadBytes);

var signature = Convert.ToBase64String(hashBytes);
```

### Request Body:
Send a JSON object with the following fields:

| Field              | Type   | Required | Description |
|--------------------|--------|----------|-------------|
| email             | string | ✅        | Customer's email |
| firstName         | string | ✅        | Customer's first name |
| lastName          | string | ✅        | Customer's last name |
| externalCustomerId | string | ✅        | Unique external ID for the customer |
| iban              | string | ❌ (One of `iban` or `accountId` required) | IBAN of the customer |
| accountId         | string | ❌ (One of `iban` or `accountId` required) | Account ID of the customer |

### Request Example:
```json
{
  "email": "user@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "externalCustomerId": "ext-12345",
  "iban": "DE89370400440532013000"
}
```

### Successful Response (200):

```json
{
  "code": null,
  "data": {
    "customerId": "customer-id",
    "hashToken": "hash-token"
  },
  "message": null
}
```

### Possible Errors:

| Status Code | Error Code            | Message |
|------------|----------------------|-------------------------------------------------------------|
| 422        | Validation           | Either `iban` or `accountId` must be provided.             |
| 422        | Customer.Create      | Could not create a customer.                               |
| 422        | Customer.NotUnique   | Customer with the specified data is not unique. Try changing the `externalCustomerId`. |
| 500        | InternalServerError  | An unexpected error occurred. |

## Handling Wallet Events

### Subscribing to Events

```ts
function onTransferCreated(payload: MessageSchema[Message.TransferCreated]) {
  console.log('Transfer Created:', payload)
}

XpaidWalletSdk.subscribe(Message.TransferCreated, onTransferCreated)
```

### Unsubscribing from Events

```ts
XpaidWalletSdk.unsubscribe(Message.TransferCreated, onTransferCreated)
```

### Sending Messages to Wallet

```ts
XpaidWalletSdk.publish(Message.TransferConfirmed)
```

### Destroying the SDK

```ts
XpaidWalletSdk.destroy()
```

## API Reference

### `XpaidWalletSdk.initialize(config: SdkConfig): void`
Initializes the SDK and embeds the wallet iframe.

#### Parameters:
- `config.containerId` (string, required): The HTML element ID where the iframe will be embedded.
- `config.hashToken` (string, required): Secure token for authentication.
- `config.environment` (optional): Environment
- `config.width` (optional): Custom width for the iframe.
- `config.height` (optional): Custom height for the iframe.
- `config.colorScheme` (optional): Custom theme settings.

---

### `XpaidWalletSdk.subscribe(messageType: Message, handler: (payload) => void): void`
Subscribes to wallet events.

#### Parameters:
- `messageType` (Message): The event type to listen for.
- `handler` (function): The callback function that handles the event payload.

#### Example:
```ts
XpaidWalletSdk.subscribe(Message.TransferCreated, (payload) => {
  console.log('Transfer Created:', payload)
})
```

---

### `XpaidWalletSdk.unsubscribe(messageType: Message, handler: (payload) => void): void`
Unsubscribes from wallet events.

#### Example:
```ts
XpaidWalletSdk.unsubscribe(Message.TransferCreated, onTransferCreated)
```

---

### `XpaidWalletSdk.publish(messageType: Message, payload): void`
Sends messages to the wallet.

#### Example:
```ts
XpaidWalletSdk.publish(Message.TransferConfirmed)

XpaidWalletSdk.publish(Message.TransferRejected)
```

---

### `XpaidWalletSdk.destroy(): void`
Removes all event listeners and destroys the iframe instance.

#### Example:
```ts
XpaidWalletSdk.destroy()
```

## Available Events

| Event Type           | Payload Structure                   | Description                        |
|----------------------|----------------------------------|------------------------------------|
| `Message.AppReady`  | `-`                         | Triggered when the wallet is ready |
| `Message.TransferCreated` | ` { referenceId:string, amount: number, currency: string }` | Emitted when a transfer is created |
| `Message.TransferConfirmed` | `-`                 | Acknowledges a transfer confirmation |
| `Message.TransferRejected` | `-`                 | Confirms denial of transfer |
| `Message.SessionExpired` | `-`                     | Notifies that the session has expired |

## Notes
- The SDK uses an iframe-based communication system for secure interactions.
- Ensure that the `hashToken` is securely provided.

## License
MIT
