PHPackages                             yannxtrem/katchika - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. yannxtrem/katchika

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

yannxtrem/katchika
==================

Package Laravel pour intégrer SHKeeper Crypto Multi-Wallet

v0.1.0(2mo ago)028MITPHPPHP ^8.1

Since Apr 9Pushed 2mo agoCompare

[ Source](https://github.com/yannXtrem/katchika)[ Packagist](https://packagist.org/packages/yannxtrem/katchika)[ RSS](/packages/yannxtrem-katchika/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (5)Versions (2)Used By (0)

Katchika - Laravel SHKeeper Crypto Payment Integration Package
==============================================================

[](#katchika---laravel-shkeeper-crypto-payment-integration-package)

A robust, production-ready Laravel package that seamlessly integrates **SHKeeper** as a multi-wallet backend for processing non-custodial cryptocurrency payments. Designed for SaaS platforms that need to accept crypto without KYC requirements while managing multiple user wallets, commissions, and payment workflows.

[![PHP](https://camo.githubusercontent.com/83dd395020c37276225039739320f6c8e7e99963ab21ee3d09282cb48dad2a60/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d626c7565)](https://www.php.net)[![Laravel](https://camo.githubusercontent.com/93554d1ac44e7880097a6bd117e99f90c33ddf03dcf0a37f3047fa50b8aaa4d2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31302532422d726564)](https://laravel.com)[![License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](LICENSE)

---

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [Architecture](#architecture)
- [API Reference](#api-reference)
- [Security](#security)
- [Testing](#testing)
- [Events](#events)
- [Extending](#extending)
- [Troubleshooting](#troubleshooting)

---

Features
--------

[](#features)

✨ **Multi-Wallet Management** - Create and manage system-level wallets per crypto for SHKeeper integration ✨ **Webhook Integration** - Handle SHKeeper payment confirmations via secure HMAC-verified webhooks ✨ **Transaction Tracking** - Monitor all payment lifecycle states (pending → paid → confirmed) ✨ **Commission Handling** - Built-in support for platform fee deductions via SHKeeper or post-processing
✨ **Event-Driven Architecture** - Extensible event system for custom business logic integration
✨ **Dashboard Components** - Pre-built Livewire/Blade components for user dashboards
✨ **Status API** - Public API endpoint for real-time transaction status polling
✨ **Offline-First Testing** - Full test suite runs without SHKeeper instance
✨ **Zero KYC** - Non-custodial architecture; SHKeeper handles blockchain directly

---

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10.0+
- SQLite, MySQL, PostgreSQL, or compatible database
- [SHKeeper](https://github.com/vsys-host/shkeeper.io) instance (for production)

### Optional Dependencies

[](#optional-dependencies)

- Orchestra/Testbench 8.0+ (for development/testing)

---

Installation
------------

[](#installation)

### 1. Composer Installation

[](#1-composer-installation)

```
composer require yannxtrem/katchika
```

#### Local installation without Packagist

[](#local-installation-without-packagist)

If you want to install this package from a local Laravel project without publishing it on Packagist, use Composer's `path` repository feature.

In your Laravel application's `composer.json`, add:

```
"repositories": [
  {
    "type": "path",
    "url": "../katchika"
  }
],
```

Then require the package locally:

```
composer require yannxtrem/katchika:@dev --prefer-source
```

The package source will be symlinked into your project and can be developed locally without Packagist.

### 2. Publish Configuration

[](#2-publish-configuration)

```
php artisan vendor:publish --provider="Katchika\KatchikaServiceProvider" --tag=config
```

This creates `config/shkeeper.php` in your Laravel application.

### 3. Run Migrations

[](#3-run-migrations)

```
php artisan migrate
```

Creates two tables:

- `shkeeper_wallets` - Stores wallet metadata and API keys
- `shkeeper_transactions` - Tracks payment transactions

### 4. Environment Configuration

[](#4-environment-configuration)

Add to your `.env`:

```
SHKEEPER_API_URL=https://api.shkeeper.example.com
SHKEEPER_API_KEY=fs9GYTyNdkjPHX36
SHKEEPER_WEBHOOK_SECRET=your_webhook_secret
```

---

Configuration
-------------

[](#configuration)

Edit `config/shkeeper.php` to customize the package behavior:

```
return [
    // SHKeeper API endpoint
    'api_base_url' => env('SHKEEPER_API_URL', 'https://api.shkeeper.example.com'),

    // Admin API key for wallet operations
    'api_key' => env('SHKEEPER_API_KEY', null),

    // Secret for webhook signature verification
    'webhook_secret' => env('SHKEEPER_WEBHOOK_SECRET', null),

    // Whitelist allowed IPs for webhook (empty = allow all)
    'webhook_ips' => [],

    // Cache TTL for exchange rates (seconds)
    'cache_ttl' => 300,

    // Enable/disable dashboard routes
    'enable_dashboard' => true,

    // Enable/disable webhook route
    'enable_routes' => true,

    // Default platform commission (5%)
    'default_platform_fee' => 0.05,
];
```

---

Usage
-----

[](#usage)

### Core: MultiWallet Service

[](#core-multiwallet-service)

The `MultiWalletService` manages the lifecycle of system-level wallets per crypto.

#### Creating a Wallet

[](#creating-a-wallet)

```
use Katchika\Services\MultiWalletService;

$service = new MultiWalletService();

// Create a BTC wallet with 3% fee for the application system
$wallet = $service->createWalletForCrypto('BTC', 0.03);

// Response
// {
//   "id": 1,
//   "crypto": "BTC",
//   "api_key": "sk_live_xxx",
//   "address": null,
//   "platform_fee": 0.03,
//   "created_at": "2026-03-22T10:00:00Z"
// }
```

#### Retrieving a Wallet

[](#retrieving-a-wallet)

```
$wallet = $service->getWalletForCrypto('BTC');

if ($wallet) {
    echo $wallet->address;
    echo $wallet->api_key;
}
```

#### Deleting a Wallet

[](#deleting-a-wallet)

```
$service->deleteWallet($wallet);
```

---

### Core: Transaction Manager

[](#core-transaction-manager)

The `TransactionManager` handles payment requests and status updates. Transaction ownership is optional and stored on the transaction record, not on the system wallet.

#### Creating a Payment Request

[](#creating-a-payment-request)

```
use Katchika\Services\TransactionManager;
use Katchika\Models\Wallet;

$manager = new TransactionManager();
$wallet = Wallet::find(1);

$transaction = $manager->createPaymentRequest(
    wallet: $wallet,
    fiatAmount: 100.00,
    cryptoAmount: 0.0025,
    externalId: 'order-12345',
    followerId: 123,
    ownerType: 'App\\Models\\User',  // Optional
    ownerId: 42,                        // Optional
    expiresAt: now()->addHour()
);

// Response
// {
//   "id": 42,
//   "wallet_id": 1,
//   "external_id": "order-12345",
//   "follower_id": 123,
//   "crypto": "BTC",
//   "fiat_amount": 100.00,
//   "crypto_amount": 0.0025,
//   "wallet_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
//   "status": "pending",
//   "expires_at": "2026-03-22T11:00:00Z",
//   "created_at": "2026-03-22T10:00:00Z"
// }
```

#### Updating Transaction Status

[](#updating-transaction-status)

Called automatically by the webhook, but can also be invoked manually:

```
$transaction = Transaction::find(42);

$transaction = $manager->getTransactionStatus($transaction, [
    'status' => 'paid',
    'txid' => 'abc123def456...',
    'paid_at' => now()->toDateTimeString(),
]);
```

### SHKeeper Request / Response Object Model

[](#shkeeper-request--response-object-model)

The package provides typed request and response classes for SHKeeper API calls.

#### Create a Payment Request using objects

[](#create-a-payment-request-using-objects)

```
use Katchika\Services\ShkeeperApiClient;
use Katchika\Services\Requests\CreatePaymentRequest;

$client = app(ShkeeperApiClient::class);
$request = new CreatePaymentRequest(
    crypto: 'ETH',
    externalId: 'order-999',
    fiat: 'USD',
    amount: '25.00',
    callbackUrl: 'https://example.com/callback',
    extra: [
        'customer_id' => 555
    ]
);

$response = $client->send($request);

if ($response->isSuccess()) {
    echo $response->externalId();
    echo $response->cryptoAmount();
    echo $response->walletAddress();
}
```

#### API error handling

[](#api-error-handling)

`ShkeeperApiClient::send()` throws `Katchika\Services\Exceptions\ShkeeperApiException` when the remote call fails or returns an error.

```
use Katchika\Services\Exceptions\ShkeeperApiException;

try {
    $response = $client->send($request);
} catch (ShkeeperApiException $exception) {
    logger()->error($exception->getMessage(), [
        'status' => $exception->httpStatus(),
        'body' => $exception->body(),
    ]);
}
```

---

### Models

[](#models)

#### Wallet Model

[](#wallet-model)

```
use Katchika\Models\Wallet;

$wallet = Wallet::find(1);

// Relations
$wallet->transactions;    // All transactions for this wallet

// Attributes
$wallet->crypto;          // Currency code (BTC, ETH, USDT, etc.)
$wallet->address;         // Blockchain address
$wallet->platform_fee;    // Commission percentage as decimal (0.05 = 5%)
$wallet->api_key;         // SHKeeper API key (encrypted)
```

#### Transaction Model

[](#transaction-model)

```
use Katchika\Models\Transaction;

$txn = Transaction::find(42);

// Relations
$txn->wallet;             // Parent wallet

// Key Attributes
$txn->external_id;        // Your application reference ID
$txn->follower_id;        // Optional customer/follower ID
$txn->status;             // 'pending', 'paid', 'expired', 'failed'
$txn->txid;               // Blockchain transaction hash (after payment)
$txn->crypto_amount;      // Amount in cryptocurrency
$txn->fiat_amount;        // Fiat equivalent (for display)
$txn->wallet_address;     // Where customer sends funds
$txn->paid_at;            // When payment was confirmed
$txn->expires_at;         // When payment offer expires
```

---

### Routes &amp; API Endpoints

[](#routes--api-endpoints)

#### Webhook Endpoint (Auto-Registered)

[](#webhook-endpoint-auto-registered)

**POST** `/shkeeper/webhook/{walletId}`

Receives payment confirmations from SHKeeper.

**Headers:**

- `X-SHKEEPER-SIGNATURE` (if configured): HMAC-SHA256 signature of request body

**Request Body:**

```
{
  "external_id": "order-12345",
  "status": "paid",
  "txid": "abc123def456...",
  "paid_at": "2026-03-22T10:05:00Z"
}
```

**Response:**

```
{
  "message": "Accepted"
}
```

**Status Codes:**

- `202 Accepted` - Webhook processed successfully
- `401 Unauthorized` - Invalid signature
- `403 Forbidden` - IP not whitelisted
- `404 Not Found` - Wallet or transaction not found
- `400 Bad Request` - Missing required fields

#### Transaction Status API

[](#transaction-status-api)

**GET** `/api/shkeeper/status/{externalId}`

Returns real-time transaction status (unauthenticated).

**Response:**

```
{
  "id": 42,
  "status": "paid",
  "crypto_amount": 0.0025,
  "wallet_address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
  "txid": "abc123def456...",
  "paid_at": "2026-03-22T10:05:00Z"
}
```

#### Dashboard Routes (Authenticated)

[](#dashboard-routes-authenticated)

These routes require the `auth` middleware and return JSON or Blade views.

- **GET** `/dashboard/shkeeper/` - User's wallets overview
- **GET** `/dashboard/shkeeper/transactions` - Transaction history (paginated)
- **GET** `/dashboard/shkeeper/wallet/{walletId}` - Wallet details and balance

---

Architecture
------------

[](#architecture)

### Database Schema

[](#database-schema)

#### `shkeeper_wallets` Table

[](#shkeeper_wallets-table)

ColumnTypeNotesidBIGINTPrimary keyowner\_typeVARCHARPolymorphic owner class (e.g., `App\Models\User`)owner\_idBIGINTPolymorphic owner IDcryptoVARCHAR(12)Currency code (BTC, ETH, USDT, etc.)api\_keyVARCHAREncrypted SHKeeper API keyaddressVARCHARBlockchain address (null until wallet activated)platform\_feeDECIMAL(8,4)Commission as decimal (0.05 = 5%)created\_atTIMESTAMPCreation timeupdated\_atTIMESTAMPLast update time#### `shkeeper_transactions` Table

[](#shkeeper_transactions-table)

ColumnTypeNotesidBIGINTPrimary keywallet\_idBIGINTForeign key to `shkeeper_wallets`external\_idVARCHARUnique reference from your appfollower\_idBIGINTNullable follower/customer referencecryptoVARCHAR(12)Currency codefiat\_amountDECIMAL(20,8)Fiat value (for display/reporting)crypto\_amountDECIMAL(30,18)Cryptographic valuewallet\_addressVARCHARPayment destination addressstatusVARCHAR'pending', 'paid', 'expired', 'failed'txidVARCHARBlockchain transaction hashpaid\_atTIMESTAMPConfirmation timestampexpires\_atTIMESTAMPOffer expirationraw\_webhook\_payloadJSONFull SHKeeper webhook datacreated\_atTIMESTAMPCreation timeupdated\_atTIMESTAMPLast update time### Data Flow

[](#data-flow)

```
┌──────────────────┐
│  SaaS Frontend   │
└────────┬─────────┘
         │
         │ 1. Create payment request
         ▼
┌──────────────────────────────────┐
│  Your Laravel Application        │
│  (using Katchika services)       │
└────────┬────────────────────────┘
         │
         │ 2. Call TransactionManager
         ▼
┌──────────────────────────────────┐
│ Katchika Package                 │
│ - Services                       │
│ - Models                         │
│ - Events                         │
└────────┬────────────────────────┘
         │
         │ 3. Store locally (DB)
         │ 4. Call SHKeeper API (optional)
         ▼
┌──────────────────────────────────┐
│ SHKeeper                         │
│ (multi-wallet blockchain manager)│
└────────┬────────────────────────┘
         │
         │ 5. Monitor blockchain
         │ 6. Generate address
         │ 7. Watch for payment
         ▼
┌──────────────────────────────────┐
│ Blockchain (BTC, ETH, etc.)      │
└────────┬────────────────────────┘
         │
         │ Customer sends crypto
         │
         │ 8. Transaction confirmed
         │ 9. Webhook callback
         ▼
┌──────────────────────────────────┐
│ Katchika Webhook Handler         │
│ POST /shkeeper/webhook/{walletId}│
└────────┬────────────────────────┘
         │
         │ 10. Verify signature
         │ 11. Update transaction status
         │ 12. Dispatch events
         ▼
┌──────────────────────────────────┐
│ Your Event Listeners             │
│ (activate subscription, etc.)    │
└──────────────────────────────────┘

```

---

API Reference
-------------

[](#api-reference)

### Service Classes

[](#service-classes)

#### MultiWalletService

[](#multiwalletservice)

```
namespace Katchika\Services;

class MultiWalletService
{
    public function createWalletForOwner(
        $owner,                    // Ownable model instance
        string $crypto,            // Currency code
        float $platformFee = null  // Commission (or use default)
    ): Wallet;

    public function getWalletForOwner(
        $owner,
        string $crypto
    ): ?Wallet;

    public function deleteWallet(Wallet $wallet): bool;
}
```

#### TransactionManager

[](#transactionmanager)

```
namespace Katchika\Services;

class TransactionManager
{
    public function createPaymentRequest(
        Wallet $wallet,
        float $fiatAmount,
        float $cryptoAmount,
        string $externalId,
        ?int $followerId = null,
        ?\DateTime $expiresAt = null
    ): Transaction;

    public function getTransactionStatus(
        Transaction $transaction,
        array $shkeeperPayload
    ): Transaction;
}
```

### Model Scopes

[](#model-scopes)

```
// Filter transactions by status
Transaction::where('status', 'paid')->get();

// Get pending transactions
Transaction::where('status', 'pending')->get();

// Transactions for a specific wallet
$wallet = Wallet::find(1);
$wallet->transactions()->get();

// Polymorphic owner lookup
Wallet::where('owner_type', User::class)
      ->where('owner_id', $userId)
      ->get();
```

---

Security
--------

[](#security)

### Best Practices Implemented

[](#best-practices-implemented)

✅ **Webhook Verification** - HMAC-SHA256 signature validation (optional, recommended)
✅ **IP Whitelisting** - Restrict webhook sources by IP address
✅ **API Key Encryption** - Private keys encrypted at rest using Laravel's encryption
✅ **Authentication** - Dashboard routes protected with `auth` middleware
✅ **HTTPS** - All API communication should use HTTPS in production
✅ **Rate Limiting** - Webhook endpoints should be rate-limited
✅ **Input Validation** - All external inputs validated before processing

### Webhook Security Setup

[](#webhook-security-setup)

```
// config/shkeeper.php

return [
    'webhook_secret' => env('SHKEEPER_WEBHOOK_SECRET', null),

    // Restrict to SHKeeper IPs
    'webhook_ips' => [
        '203.0.113.0',     // SHKeeper primary
        '203.0.113.1',     // SHKeeper secondary
    ],
];
```

### Protecting API Keys

[](#protecting-api-keys)

The package automatically encrypts sensitive fields when stored. In your application, never:

- Log API keys to console
- Expose keys in error messages
- Transmit keys over HTTP
- Store unencrypted backups containing keys

### Firewall Configuration (Production)

[](#firewall-configuration-production)

```
# nginx.conf
location /shkeeper/webhook/ {
    # Only allow SHKeeper IP
    allow 203.0.113.0;
    deny all;
}
```

---

Testing
-------

[](#testing)

### Running Tests

[](#running-tests)

```
cd katchika

# All tests
vendor/bin/phpunit --no-coverage

# Specific test class
vendor/bin/phpunit tests/MultiWalletServiceTest.php --no-coverage

# With coverage
vendor/bin/phpunit
```

### Test Coverage

[](#test-coverage)

- **Unit Tests**: Service methods, model relations
- **Integration Tests**: Webhook processing, event dispatch
- **Database Tests**: Transaction lifecycle, persistence

### Demo Server Testing

[](#demo-server-testing)

To test this package against the official SHKeeper demo server both locally and directly, export your demo credentials and run the sample demo script:

```
export SHKEEPER_API_URL=https://demo.shkeeper.io
export SHKEEPER_API_KEY=your_demo_api_key
composer demo
```

This runs `demo/demo.php` and performs a real API call to the demo server:

- `/api/v1/crypto` to list supported currencies
- `/api/v1/ETH/quote` to fetch a quote for 1 USD

If you want to keep using the demo server in automated tests, use:

```
composer test:integration
```

If `SHKEEPER_API_KEY` is not provided, the demo script will fail clearly and the integration tests will skip automatically.

### Writing Tests

[](#writing-tests)

Tests inherit from `Katchika\Tests\TestCase`, which auto-bootstraps:

- In-memory SQLite database
- Package service provider
- Migrations

Example:

```
namespace Katchika\Tests;

use Katchika\Models\Wallet;
use Katchika\Services\MultiWalletService;

class YourTest extends TestCase
{
    public function test_example()
    {
        $service = new MultiWalletService();
        $wallet = $service->createWalletForOwner($owner, 'BTC');

        $this->assertNotNull($wallet->id);
    }
}
```

---

Events
------

[](#events)

The package dispatches typed events to your application's event bus.

### PaymentRequestCreated

[](#paymentrequestcreated)

Fired when a new payment request is created.

```
use Katchika\Events\PaymentRequestCreated;

class PaymentRequestCreatedListener
{
    public function handle(PaymentRequestCreated $event)
    {
        $event->transaction;  // Transaction model

        // Send payment link to customer
        // Log request
        // Update inventory
    }
}
```

Register in `app/Providers/EventServiceProvider.php`:

```
protected $listen = [
    PaymentRequestCreated::class => [
        PaymentRequestCreatedListener::class,
    ],
];
```

### PaymentConfirmed

[](#paymentconfirmed)

Fired when payment is detected on the blockchain and confirmed.

```
use Katchika\Events\PaymentConfirmed;

class PaymentConfirmedListener
{
    public function handle(PaymentConfirmed $event)
    {
        // Activate subscription
        // Process order
        // Send notification
        // Update ledger
    }
}
```

### PaymentExpired

[](#paymentexpired)

Fired when a payment request expires without receiving funds.

```
use Katchika\Events\PaymentExpired;

class PaymentExpiredListener
{
    public function handle(PaymentExpired $event)
    {
        // Notify user
        // Clean up resources
        // Log failure
    }
}
```

---

Extending
---------

[](#extending)

### Custom Event Listeners

[](#custom-event-listeners)

Listen for events and implement your business logic:

```
namespace App\Listeners;

use Katchika\Events\PaymentConfirmed;
use App\Models\Subscription;

class ActivateSubscriptionOnPayment
{
    public function handle(PaymentConfirmed $event)
    {
        $transaction = $event->transaction;

        if ($transaction->follower_id) {
            Subscription::create([
                'user_id' => $transaction->follower_id,
                'tier' => 'premium',
                'expires_at' => now()->addMonth(),
            ]);
        }
    }
}
```

### Custom Commission Logic

[](#custom-commission-logic)

Option 1: SHKeeper native (recommended)

```
$service->createWalletForOwner($user, 'BTC', 0.05);  // 5% via SHKeeper
```

Option 2: Post-processing in listener

```
class CalculateCommission
{
    public function handle(PaymentConfirmed $event)
    {
        $txn = $event->transaction;
        $fee = $txn->crypto_amount * $txn->wallet->platform_fee;

        // Transfer fee to master wallet
        // Or create accounting entry
    }
}
```

### Polymorphic Owners

[](#polymorphic-owners)

Wallets support any `Eloquent` model via polymorphic relations:

```
// User wallet
$user = User::find(1);
$wallet = $service->createWalletForOwner($user, 'BTC');

// Organization wallet
$org = Organization::find(5);
$wallet = $service->createWalletForOwner($org, 'ETH');

// Team wallet
$team = Team::find(99);
$wallet = $service->createWalletForOwner($team, 'USDT');

// Query any owner's wallets
$wallet->owner;  // Returns User, Organization, or Team
```

---

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues

[](#common-issues)

#### "Wallet not found" on webhook

[](#wallet-not-found-on-webhook)

**Cause**: Webhook uses wallet ID, but wallet may not exist or has been deleted.

**Solution**: Verify wallet exists before creating payment request.

```
$wallet = Wallet::find($walletId);
if (!$wallet) {
    throw new \Exception('Wallet does not exist');
}
```

#### Signature validation fails

[](#signature-validation-fails)

**Cause**: Webhook secret mismatch or body encoding issue.

**Solution**: Ensure exact matching:

1. SHKeeper's webhook secret matches `SHKEEPER_WEBHOOK_SECRET`
2. Signature uses raw request body (not pretty-printed JSON)
3. Hash algorithm is SHA256

#### Transaction doesn't update from webhook

[](#transaction-doesnt-update-from-webhook)

**Cause**: Webhook IP not whitelisted or external\_id mismatch.

**Solution**:

```
# Debug webhook
tail -f storage/logs/laravel.log | grep "webhook"

# Check IP whitelist
php artisan tinker
>>> config('shkeeper.webhook_ips')
```

#### API key is empty

[](#api-key-is-empty)

**Cause**: Key wasn't populated when wallet created; SHKeeper API not called.

**Solution**: Ensure SHKeeper API credentials are configured:

```
config('shkeeper.api_key')      // Should be set
config('shkeeper.api_base_url') // Should be valid
```

---

Performance Optimization
------------------------

[](#performance-optimization)

### Database Indexing

[](#database-indexing)

Recommended indexes for production:

```
// In a migration
Schema::table('shkeeper_transactions', function (Blueprint $table) {
    $table->index('external_id');
    $table->index('status');
    $table->index('wallet_id');
    $table->index('created_at');
});

Schema::table('shkeeper_wallets', function (Blueprint $table) {
    $table->index(['owner_type', 'owner_id']);
    $table->index('crypto');
});
```

### Caching

[](#caching)

Cache transaction lookups:

```
$transaction = cache()->remember(
    "transaction.{$externalId}",
    config('shkeeper.cache_ttl'),
    fn() => Transaction::where('external_id', $externalId)->first()
);
```

### Async Webhooks

[](#async-webhooks)

Process webhooks asynchronously (recommended for high volume):

```
dispatch(
    new ProcessWebhook($transaction, $payload)
)->onQueue('shkeeper');
```

---

Roadmap
-------

[](#roadmap)

- v0.2.0: SHKeeper API client integration
- v0.3.0: QR code generation for payment display
- v0.4.0: Multi-currency rate conversion
- v0.5.0: Dashboard UI templates (Livewire)
- v1.0.0: Stable release with full documentation
- Future: Rate limiting, webhook retry logic, notification channels

---

Support &amp; Community
-----------------------

[](#support--community)

- **Issues**: [GitHub Issues](https://github.com/vsys-host/katchika/issues)
- **Discussions**: [GitHub Discussions](https://github.com/vsys-host/katchika/discussions)
- **Email**:

---

License
-------

[](#license)

MIT License - See [LICENSE](LICENSE) file for details.

---

Contributing
------------

[](#contributing)

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Write tests for new functionality
4. Ensure tests pass (`vendor/bin/phpunit`)
5. Commit changes (`git commit -am 'Add amazing feature'`)
6. Push to branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request

---

Changelog
---------

[](#changelog)

### v0.1.0 (2026-03-22)

[](#v010-2026-03-22)

- Initial release
- Core services: MultiWalletService, TransactionManager
- Models: Wallet, Transaction
- Webhook handling with HMAC verification
- Event system (PaymentRequestCreated, PaymentConfirmed, PaymentExpired)
- Dashboard API endpoints
- Comprehensive test suite
- Documentation and README

---

**Built with ❤️ for the crypto community.**

*Last Updated: March 22, 2026*

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance88

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

61d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/62825195?v=4)[yannXtrem](/maintainers/yannXtrem)[@yannXtrem](https://github.com/yannXtrem)

---

Top Contributors

[![yannXtrem](https://avatars.githubusercontent.com/u/62825195?v=4)](https://github.com/yannXtrem "yannXtrem (4 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/yannxtrem-katchika/health.svg)

```
[![Health](https://phpackages.com/badges/yannxtrem-katchika/health.svg)](https://phpackages.com/packages/yannxtrem-katchika)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45344.0k1](/packages/pressbooks-pressbooks)[flarum/core

Delightfully simple forum software.

261.4M2.2k](/packages/flarum-core)[rapidez/core

Rapidez Core

1822.4k65](/packages/rapidez-core)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
