# Stripe3D Asset Hub SDK

**100% Client-Side Payment Gateway SDK** built on Polkadot Asset Hub. Accept DOT payments without any backend infrastructure, servers, or smart contracts.

## ✨ Key Features

- 🌐 **100% Client-Side** - No backend, no databases, no servers required
- 🔗 **Asset Hub Native** - Built on Polkadot's specialized asset parachain
- ⚡ **Direct Payments** - Simple DOT transfers, no escrow complexity
- 🔐 **Wallet Integration** - Polkadot.js Extension support
- ⏱️ **Instant Settlement** - 6-second finality on Polkadot
- 🔄 **Real-Time Events** - Client-side blockchain event monitoring
- ✅ **Payment Verification** - On-chain payment verification before delivery
- 🔗 **Payment Links** - No-code shareable payment links with hosted checkout
- 🛡️ **Merchant Dashboard** - Beautiful dashboard for managing payments and links
- 🎯 **Rate Limiting** - Built-in anti-spam protection
- 🔒 **Type-Safe** - Full TypeScript support
- ✅ **Well Tested** - 98 tests passing with excellent coverage

## Installation

```bash
npm install @pmt-gateway/asset-hub-sdk
```

## Quick Start

### 1. Initialize the Gateway

```typescript
import { PMTGatewayAssetHub } from '@pmt-gateway/asset-hub-sdk';

const gateway = new PMTGatewayAssetHub({
  assetHub: {
    network: 'paseo', // or 'polkadot', 'kusama'
    rpcEndpoint: 'wss://sys.ibp.network/asset-hub-paseo'
  }
});

await gateway.initialize();
```

### 2. Create a Payment

```typescript
const payment = await gateway.createPayment({
  merchant: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
  amount: '1.5', // 1.5 DOT
  description: 'Premium subscription'
});

console.log('Payment ID:', payment.id);
console.log('Amount:', payment.amount);
```

### 3. Execute Payment (Direct Transfer)

```typescript
await gateway.executePayment(payment.id);

gateway.on('payment.completed', (event) => {
  console.log('Payment completed!', event.txHash);
  // Deliver digital product
});
```

### 4. Cancel Payment

```typescript
await gateway.cancelPayment(payment.id);

gateway.on('payment.cancelled', (event) => {
  console.log('Payment cancelled:', event.paymentId);
});
```

## Core API

### PMTGatewayAssetHub

Main SDK class for payment gateway operations.

#### Methods

**`initialize(): Promise<void>`**
- Connects to Asset Hub RPC endpoint
- Initializes payment service
- Must be called before any other operations

**`createPayment(params: CreatePaymentParams): Promise<PaymentIntent>`**
- Creates a new payment intent
- Stores payment in localStorage
- Emits `payment.created` event

```typescript
interface CreatePaymentParams {
  merchant: string;      // Merchant's Polkadot address
  amount: string | bigint;  // Amount in DOT (string) or Planck (bigint)
  currency?: string;     // Default: 'DOT'
  description?: string;  // Payment description
  externalId?: string;   // Your order/invoice ID
}
```

**`executePayment(paymentId: string): Promise<void>`**
- Executes direct DOT transfer to merchant
- Requires wallet to be connected
- Emits `payment.completed` event on success

**`cancelPayment(paymentId: string): Promise<void>`**
- Cancels a pending payment
- Can only cancel payments in 'created' status
- Emits `payment.cancelled` event

**`getPayment(paymentId: string): PaymentIntent | undefined`**
- Retrieves a single payment by ID

**`getAllPayments(): PaymentIntent[]`**
- Returns all cached payments

**`getMerchantPayments(merchantAddress: string): PaymentIntent[]`**
- Filters payments by merchant address

**`getBuyerPayments(buyerAddress: string): PaymentIntent[]`**
- Filters payments by buyer address

**`verifyPayment(paymentId: string): Promise<PaymentVerificationResult>`**
- Verifies a payment on-chain by querying blockchain events
- Returns verification details including block number, timestamp, and finalization status
- Critical for security before delivering products/services

**`createPaymentLink(params: CreatePaymentLinkParams): PaymentLink`**
- Creates a shareable no-code payment link
- Supports fixed or custom amounts
- Returns payment link with unique ID

**`getPaymentLink(linkId: string): PaymentLink | undefined`**
- Retrieves a payment link by ID

**`getPaymentLinkUrl(linkId: string, baseUrl?: string): string`**
- Returns the full URL for a payment link (for hosted checkout page)

**`getMerchantPaymentLinks(merchantAddress: string): PaymentLink[]`**
- Filters payment links by merchant address

**`deactivatePaymentLink(linkId: string): void`**
- Deactivates a payment link (prevents new payments)

**`getAccounts(): WalletAccount[]`**
- Returns connected wallet accounts

**`getBalance(address: string): Promise<AccountBalance>`**
- Queries account balance from Asset Hub

**`getNetworkInfo(): Promise<NetworkInfo>`**
- Returns current network information (chain, version, block)

**`disconnect(): Promise<void>`**
- Disconnects from Asset Hub
- Cleans up resources

### PaymentIntent

```typescript
interface PaymentIntent {
  id: string;           // Unique payment ID
  buyer: string;        // Buyer's Polkadot address
  merchant: string;     // Merchant's Polkadot address
  amount: bigint;       // Amount in Planck (1 DOT = 10^10 Planck)
  currency: string;     // Currency code (e.g., 'DOT')
  status: PaymentStatus;  // Payment status
  createdAt: number;    // Creation timestamp
  updatedAt: number;    // Last update timestamp
  externalId?: string;  // Your order/invoice ID
  description?: string; // Payment description
  txHash?: string;      // Transaction hash (when completed)
}

type PaymentStatus = 'created' | 'completed' | 'cancelled' | 'failed';
```

### PaymentLink

```typescript
interface PaymentLink {
  id: string;                          // Unique link ID
  merchant: string;                    // Merchant's Polkadot address
  amount: bigint | 'custom';           // Fixed amount or 'custom' for user input
  currency: string;                    // Currency code (e.g., 'DOT')
  description?: string;                // Payment description
  externalId?: string;                 // Your reference ID
  successUrl?: string;                 // Redirect URL after successful payment
  cancelUrl?: string;                  // Redirect URL after cancelled payment
  metadata?: Record<string, string>;   // Custom metadata
  createdAt: number;                   // Creation timestamp
  expiresAt?: number;                  // Optional expiration timestamp
  active: boolean;                     // Link active status
  network: 'paseo' | 'polkadot' | 'kusama';  // Network
}

interface CreatePaymentLinkParams {
  merchant: string;
  amount: string | bigint | 'custom';
  description?: string;
  externalId?: string;
  successUrl?: string;
  cancelUrl?: string;
  metadata?: Record<string, string>;
  expiresAt?: number;
}
```

### PaymentVerificationResult

```typescript
interface PaymentVerificationResult {
  verified: boolean;       // Whether payment was verified on-chain
  exists: boolean;         // Whether transaction exists
  finalized: boolean;      // Whether block is finalized
  amount: bigint;          // Payment amount in Planck
  from: string;            // Sender address
  to: string;              // Recipient address
  blockNumber: number;     // Block number
  blockHash: string;       // Block hash
  timestamp: number;       // Block timestamp
  txHash: string;          // Transaction hash
  eventIndex?: number;     // Event index in block
  error?: string;          // Error message if verification failed
}
```

### Events

The SDK emits events for payment lifecycle tracking:

```typescript
gateway.on('payment.created', (event: PaymentEvent) => {
  console.log('Payment created:', event.paymentId);
});

gateway.on('payment.completed', (event: PaymentEvent) => {
  console.log('Payment completed:', event.paymentId);
  console.log('Transaction hash:', event.txHash);
  // Deliver product/service
});

gateway.on('payment.cancelled', (event: PaymentEvent) => {
  console.log('Payment cancelled:', event.paymentId);
});

gateway.on('payment.failed', (event: PaymentEvent) => {
  console.log('Payment failed:', event.paymentId);
  console.error('Error:', event.error);
});
```

## Payment Verification

Verify payments on-chain before delivering products/services:

```typescript
// After payment is completed
const result = await gateway.verifyPayment(payment.id);

if (result.verified && result.finalized) {
  console.log('Payment verified!');
  console.log('Block number:', result.blockNumber);
  console.log('Amount:', result.amount);
  console.log('From:', result.from);
  console.log('To:', result.to);
  console.log('Transaction:', result.txHash);

  // Safe to deliver product/service
  deliverProduct(payment.id);
} else {
  console.error('Verification failed:', result.error);
}
```

## Payment Links (No-Code Payments)

Create shareable payment links for non-technical users:

```typescript
// Create a payment link with fixed amount
const link = gateway.createPaymentLink({
  merchant: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
  amount: '10',  // 10 DOT
  description: 'Premium Plan',
  successUrl: 'https://mysite.com/success',
  externalId: 'order-123'
});

// Get the shareable URL
const url = gateway.getPaymentLinkUrl(link.id);
console.log('Share this link:', url);
// https://yoursite.com/checkout?link=pl_abc123...

// Create a payment link with custom amount (user chooses)
const customLink = gateway.createPaymentLink({
  merchant: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
  amount: 'custom',
  description: 'Donation',
});

// Get all merchant's payment links
const myLinks = gateway.getMerchantPaymentLinks(merchantAddress);

// Deactivate a payment link
gateway.deactivatePaymentLink(link.id);
```

### Hosted Checkout Page

Use the included checkout page at `examples/checkout/` for a no-code payment experience:

1. Create a payment link in your app
2. Share the checkout URL with your customer
3. Customer pays through the hosted checkout page
4. Verify the payment in your app before delivering

```typescript
// In your app: Create link
const link = gateway.createPaymentLink({
  merchant: merchantAddress,
  amount: '5.5',
  description: 'Product XYZ'
});

// Get checkout URL
const checkoutUrl = gateway.getPaymentLinkUrl(
  link.id,
  'https://yoursite.com/checkout'
);

// Share with customer via email, QR code, etc.
sendEmailWithPaymentLink(customer.email, checkoutUrl);
```

## Advanced Usage

### Asset Hub Service

Access the underlying Asset Hub service for advanced operations:

```typescript
const assetHubService = gateway.assetHub;

// Connect to Asset Hub
await assetHubService.connect();

// Enable wallet
await assetHubService.enableWallet();

// Get API instance
const api = assetHubService.getApi();

// Query network info
const networkInfo = await assetHubService.getNetworkInfo();
console.log('Chain:', networkInfo.chain);
console.log('Version:', networkInfo.version);
console.log('Block:', networkInfo.blockNumber);

// Get balance
const balance = await assetHubService.getBalance(address);
console.log('Free:', balance.free);
console.log('Reserved:', balance.reserved);
console.log('Total:', balance.total);
```

### Custom Assets

Use the AssetsService for custom token support:

```typescript
import { AssetsService } from '@pmt-gateway/asset-hub-sdk';

const assetsService = new AssetsService(api);

// Get asset metadata
const metadata = await assetsService.getAssetMetadata(assetId);
console.log('Name:', metadata.name);
console.log('Symbol:', metadata.symbol);
console.log('Decimals:', metadata.decimals);

// Get asset balance
const balance = await assetsService.getBalance(assetId, address);
console.log('Balance:', balance.balance);

// Transfer assets
const txHash = await assetsService.transfer(
  assetId,
  recipient,
  amount,
  signerAddress
);
```

### Validation

Built-in input validation for security:

```typescript
import { ValidationService } from '@pmt-gateway/asset-hub-sdk';

// Validate Polkadot address
ValidationService.validateAddress(userInput, 'merchant');

// Validate amount
ValidationService.validateAmount(amount, 'amount', {
  min: 0.01,
  max: 1000,
});

// Validate payment ID
ValidationService.validatePaymentId(paymentId);
```

### Error Handling

Structured error handling with detailed error information:

```typescript
import { ErrorHandler, PMTError, ErrorCode } from '@pmt-gateway/asset-hub-sdk';

try {
  await gateway.executePayment(paymentId);
} catch (error) {
  const pmtError = ErrorHandler.handle(error, 'executePayment');

  console.log('Code:', pmtError.code);
  console.log('Severity:', pmtError.severity);
  console.log('Retryable:', pmtError.retryable);

  // Get user-friendly message
  const userMessage = ErrorHandler.getUserMessage(pmtError);
  alert(userMessage);

  // Log for monitoring
  ErrorHandler.logError(pmtError, 'MyApp.executePayment');
}
```

### Rate Limiting

Client-side rate limiting for abuse prevention:

```typescript
import { RateLimiterService, RateLimitPresets } from '@pmt-gateway/asset-hub-sdk';

const limiter = new RateLimiterService(RateLimitPresets.payment);

// Check rate limit before operation
const status = limiter.recordRequest('createPayment');

if (!status.allowed) {
  const waitTime = Math.ceil((status.resetAt - Date.now()) / 1000);
  throw new Error(`Rate limit exceeded. Try again in ${waitTime}s`);
}

// Proceed with payment
await gateway.createPayment({ ... });
```

## Configuration

### Network Options

```typescript
interface AssetHubConfig {
  network: 'paseo' | 'polkadot' | 'kusama';
  rpcEndpoint: string;
}
```

**Supported Networks:**
- **Paseo** - Testnet (recommended for development)
  - `wss://sys.ibp.network/asset-hub-paseo`
- **Polkadot** - Production
  - `wss://polkadot-asset-hub-rpc.polkadot.io`
- **Kusama** - Canary network
  - `wss://kusama-asset-hub-rpc.polkadot.io`

## Architecture

```
┌──────────────────────────┐
│       Browser            │
│                          │
│   Stripe3D SDK           │
│   (100% Client-Side)     │
│                          │
└─────────┬────────────────┘
          │
          └──────► Asset Hub (Paseo/Polkadot)
                   • Direct token transfers
                   • No smart contracts
                   • No escrow complexity
                   • 6-second finality

100% CLIENT-SIDE • NO BACKEND • NO COMPLEXITY
```

## Security

### Best Practices

1. **Always validate user inputs**
   ```typescript
   ValidationService.validateAddress(merchantAddress, 'merchant');
   ValidationService.validateAmount(amount, 'amount');
   ```

2. **Handle errors properly**
   ```typescript
   try {
     await gateway.executePayment(paymentId);
   } catch (error) {
     const pmtError = ErrorHandler.handle(error);
     ErrorHandler.logError(pmtError);
   }
   ```

3. **Implement rate limiting**
   ```typescript
   const limiter = new RateLimiterService(RateLimitPresets.payment);
   const status = limiter.recordRequest('payment');
   if (!status.allowed) {
     throw new Error('Rate limit exceeded');
   }
   ```

4. **Verify on-chain data**
   - Always verify payment completion via transaction hash
   - Query on-chain state before delivering products
   - Implement confirmation requirements for high-value payments

### Security Features

- ✅ Input validation for all user-provided data
- ✅ Client-side rate limiting
- ✅ Wallet signature authentication
- ✅ On-chain transaction verification
- ✅ No exposed API keys or secrets
- ✅ Type-safe API with TypeScript

## Testing

Run the test suite:

```bash
npm test
```

Run tests with coverage:

```bash
npm run test:coverage
```

**Current Status:** 98 tests passing ✅

## Build

Build the SDK:

```bash
npm run build
```

This generates:
- `dist/index.js` - CommonJS bundle
- `dist/index.mjs` - ES Module bundle
- `dist/index.d.ts` - TypeScript declarations

## Browser Support

- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+

Requires browser support for:
- Web Crypto API
- WebSocket
- LocalStorage
- BigInt

## TypeScript Support

Full TypeScript definitions included:

```typescript
import {
  PMTGatewayAssetHub,
  PMTGatewayConfig,
  AssetHubService,
  PaymentService,
  AssetsService,
  CreatePaymentParams,
  PaymentIntent,
  PaymentStatus,
  PaymentEvent,
  AccountBalance,
  NetworkInfo,
  ValidationService,
  ValidationError,
  ErrorHandler,
  PMTError,
  ErrorCode,
  ErrorSeverity,
  RateLimiterService,
  RateLimitPresets,
} from '@pmt-gateway/asset-hub-sdk';
```

## Examples

Check out the live demo:

```bash
cd examples/paseo-demo
npm install
npm run dev
```

Visit `http://localhost:3000` and connect your Polkadot wallet!

## Requirements

- Node.js 18+
- @polkadot/api 12.x (included)
- TypeScript 5.x (for development)

## Performance

| Operation | Time |
|-----------|------|
| SDK Init | < 1s |
| Payment Creation | Instant |
| Payment Execution | 6-12s |
| Event Delivery | Real-time |

## Support

- **Main Docs:** `/README.md`
- **Demo Docs:** `/examples/paseo-demo/README.md`
- **Issues:** https://github.com/CoachCoe/pmt-gateway/issues

## License

MIT License

## Version

Current version: 3.0.0 - Simplified Direct Payments

## What's New in 3.0

- ✅ Asset Hub native - Built on Polkadot Asset Hub
- ✅ Direct payments - No escrow complexity
- ✅ 100% client-side - No backend required
- ✅ @polkadot/api - Native Substrate integration
- ✅ Wallet integration - Polkadot.js, Talisman, SubWallet
- ✅ Real-time events - Client-side event monitoring
- ✅ 98 tests passing - Comprehensive test coverage
- ❌ Removed escrow - Simplified payment flow
- ❌ Removed IPFS - No decentralized storage needed
- ❌ Removed Moonbeam - Pure Polkadot Asset Hub
- ❌ Removed smart contracts - Native transfers only

---

**Built with ❤️ for the truly decentralized future**

**Status:** ✅ Production Ready (Paseo Testnet)
