定制 timefrontiers/php-wallet 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

timefrontiers/php-wallet

Composer 安装命令:

composer require timefrontiers/php-wallet

包简介

Blockchain-like immutable wallet and transaction system with file-based ledger

README 文档

README

Blockchain-like immutable wallet and transaction system with file-based ledger.

Features

  • Immutable Ledger: Append-only file-based ledger as source of truth
  • Rolling Files: Monthly ledger archives prevent file bloat
  • Checkpointing: Periodic snapshots for fast recovery
  • Integrity Verification: Checksums detect tampering
  • Batch Transactions: Efficient bulk transfers
  • Payment Integration: Interface-based external payment verification
  • Flexible Database: Pass credentials at initialization

Installation

composer require timefrontiers/php-wallet

Quick Start

use TimeFrontiers\Wallet\{Config, Wallet, Transaction};

// Database credentials
$db_cred = [
  'server'   => 'localhost',
  'username' => 'wallet_user',
  'password' => 'secure_password',
  'database' => 'myapp_wallet',  // Your database name (with any prefix)
];

// Configure ledger path
Config::setLedgerPath('/var/data/.txhive/ledgers');

// Create/load wallets with credentials
$alice = new Wallet('USR123456', 'NGN', $db_cred);
$bob = new Wallet('USR789012', 'NGN', $db_cred);

// Check balance
echo $alice->balance(); // 5000.00

// Transfer
$hashes = Transaction::transfer($alice, $bob, 1000.00, 'Payment for services');

// Batch transfer
$result = Transaction::batch($alice)
  ->credit($bob, 500, 'Bonus')
  ->credit('219555555555555', 200, 'Refund')
  ->execute();

Database Setup

1. Create Your Database

Create your database manually with any required prefix:

CREATE DATABASE myprefix_wallet;

2. Run the Schema

The schema file is included in the package at schema/schema.sql:

mysql -u root -p myprefix_wallet < vendor/timefrontiers/php-wallet/schema/schema.sql

Or run directly in MySQL:

USE myprefix_wallet;
SOURCE /path/to/vendor/timefrontiers/php-wallet/schema/schema.sql;

Schema Tables

Table Purpose
wallets Wallet addresses and ownership
wallet_history Immutable transaction log (triggers prevent UPDATE/DELETE)
tranx_alert Notification queue
wallet_batches Batch transaction metadata (optional)
exchange_rates Dynamic rate history (optional)
ledger_integrity File checksum tracking (optional)
balance_snapshots Daily balance history (optional)

Schema Views

View Purpose
v_wallet_balances Quick balance lookup
v_recent_transactions Last 1000 transactions
v_pending_alerts Unsent notifications

Database Connection

Option 1: Pass Credentials to Constructor

$db_cred = [
  'server'   => 'localhost',
  'username' => 'db_user',
  'password' => 'db_pass',
  'database' => 'myprefix_wallet',
];

$wallet = new Wallet('USR123456', 'NGN', $db_cred);

Option 2: Pass PDO Instance

$pdo = new PDO('mysql:host=localhost;dbname=myprefix_wallet', 'user', 'pass');

$wallet = new Wallet('USR123456', 'NGN', $pdo);

Option 3: Set Shared Connection

// Set once at application startup
Wallet::setDatabase([
  'server'   => 'localhost',
  'username' => 'db_user',
  'password' => 'db_pass',
  'database' => 'myprefix_wallet',
]);

// Now credentials are optional
$wallet = new Wallet('USR123456', 'NGN');

Using Wallet's Connection

Each wallet instance has its own db connection:

$wallet = new Wallet('USR123456', 'NGN', $db_cred);

// Access the connection
$db = $wallet->db();

// Transaction methods use wallet's connection automatically
Transaction::transfer($from, $to, 100, 'Payment');

Configuration

use TimeFrontiers\Wallet\Config;

// Ledger storage path
Config::setLedgerPath('/var/data/.txhive/ledgers');

// Decimal precision (default: 8)
Config::setPrecision(8);

// Wallet address format (default: prefix=219, length=15)
Config::setAddressPrefix('219');
Config::setAddressLength(15);

// Batch ID format (default: prefix=127, length=15)
Config::setBatchPrefix('127');
Config::setBatchLength(15);

// Strict integrity mode (fail on ledger/DB mismatch)
Config::setStrictIntegrity(true);

// Payment verifier
Config::setPaymentVerifier(new MyPaymentVerifier());

// Exchange rates
Config::setExchangeProvider(new FixedRateProvider([
  'NGN:DWL' => 1.0,
  'USD:NGN' => 1550.0,
]));

Code Generation

Codes are generated with configurable prefix and length:

// Wallet address: 219 + 12 random digits = 219123456789012
Config::setAddressPrefix('219');
Config::setAddressLength(15);
$address = Config::generateAddress();

// Batch ID: 127 + 12 random digits = 127987654321098
Config::setBatchPrefix('127');
Config::setBatchLength(15);
$batch = Config::generateBatch();

// Generic code generation
$code = Config::generateCode('PRE', 18); // PRE + 15 digits

// Validation
Config::isValidAddress('219123456789012'); // true
Config::isValidBatch('127987654321098');   // true

Wallet Operations

Create/Load Wallet

// By user + currency (creates if not exists)
$wallet = new Wallet('USR123456', 'NGN', $db_cred);

// By address (must exist)
$wallet = new Wallet('219123456789012', '', $db_cred);

// Check existence
Wallet::exists('219123456789012', $pdo);

// Find user's wallets
$wallets = Wallet::findByUser('USR123456', $pdo);

Balance

// Get balance (from ledger - source of truth)
$balance = $wallet->balance();

// Verify against database (throws IntegrityException on mismatch)
$balance = $wallet->balance(verify: true);

// Check sufficient funds
$wallet->hasSufficientBalance(1000.00); // bool

Transactions

Transfer Between Wallets

$hashes = Transaction::transfer($from, $to, 1000.00, 'Payment');
// Returns: ['credit_hash', 'debit_hash']

Credit from External Payment

use TimeFrontiers\Wallet\Payment\MockPaymentVerifier;

$verifier = new MockPaymentVerifier();
$verifier->addPayment('PAY123456', 5000.00, 'NGN', 'paid');

$hash = Transaction::creditFromPayment(
  $wallet,
  'PAY123456',
  5000.00,
  'Top-up via Stripe',
  $verifier
);

Batch Transfers

$result = Transaction::batch($source_wallet)
  ->credit('219111111111111', 100.00, 'Bonus')
  ->credit('219222222222222', 50.00, 'Refund')
  ->credit('219333333333333', 25.00, 'Cashback')
  ->execute();

// Result
$result->batchId();        // '127123456789012'
$result->totalAmount();    // 175.00
$result->creditCount();    // 3
$result->hashes();         // All tx hashes
$result->creditHashes();   // Credit hashes only
$result->debitHash();      // Single debit hash

Bulk Credits

$result = Transaction::batch($source)
  ->creditMany([
    ['address' => '219111111111111', 'amount' => 100, 'narration' => 'Bonus'],
    ['address' => '219222222222222', 'amount' => 50, 'narration' => 'Refund'],
  ])
  ->execute();

Query Transactions

// Find by hash
$tx = Transaction::find('abc123...', $pdo);

// Find by address
$txs = Transaction::findByAddress('219123456789012', type: 'credit', limit: 50, db: $pdo);

// Find by batch
$txs = Transaction::findByBatch('127123456789012', $pdo);

Ledger System

File Structure

/.txhive/ledgers/USR123456/
  ├── 219123456789012.ledger           # Current active
  ├── 219123456789012.2024-01.ledger   # January archive
  ├── 219123456789012.2024-02.ledger   # February archive
  └── 219123456789012.checksum         # Integrity hash

Direct Ledger Access

$ledger = $wallet->ledger();

// Read operations
$ledger->balance();
$ledger->count();
$ledger->count('credit');
$ledger->totals();
$ledger->first();
$ledger->last();
$ledger->getTransaction('abc123');
$ledger->getTransactions('credit');

// Verification
$ledger->verify();

// Archives
$ledger->archives();

Recovery

// Rebuild ledger from database
$transactions = Transaction::findByAddress($address, db: $pdo);
$wallet->ledger()->rebuild($transactions);

Payment Integration

Implement Custom Verifier

use TimeFrontiers\Wallet\Payment\PaymentVerifierInterface;

class StripePaymentVerifier implements PaymentVerifierInterface {

  public function verify(string $reference, float $amount, string $currency): bool {
    $payment = \Stripe\PaymentIntent::retrieve($reference);
    
    return $payment->status === 'succeeded'
        && $payment->amount >= $amount * 100
        && strtoupper($payment->currency) === $currency;
  }

  public function availableBalance(string $reference): float {
    // Return available balance
  }

  public function markSpent(string $reference, float $amount, string $tx_hash): bool {
    // Record the claim
  }

  public function getPayment(string $reference): ?array {
    // Return payment details
  }

  public function isValidReference(string $reference): bool {
    return preg_match('/^pi_[a-zA-Z0-9]+$/', $reference);
  }
}

Error Handling

use TimeFrontiers\Wallet\Exception\{
  WalletException,
  WalletNotFoundException,
  InsufficientBalanceException,
  IntegrityException,
  PaymentVerificationException,
  TransactionException
};

try {
  Transaction::transfer($from, $to, 1000000, 'Big payment');
} catch (InsufficientBalanceException $e) {
  echo "Need {$e->required()}, have {$e->available()}";
  echo "Shortfall: {$e->shortfall()}";
} catch (IntegrityException $e) {
  echo "Ledger: {$e->ledgerBalance()}, DB: {$e->dbBalance()}";
} catch (PaymentVerificationException $e) {
  echo "Payment {$e->reference()} failed";
}

Security

Why File Ledger is More Secure

Aspect File Ledger Database
Attack Surface Server access only SQL injection, leaked creds
Remote Tampering Requires server access Multiple vectors
Access Control OS permissions App + DB users
Detection Checksums Requires audit logs

Best Practices

  1. Store ledgers outside web root: /var/data/.txhive/
  2. Restrict file permissions: chmod 600 on ledger files
  3. Use strict integrity mode: Fail on mismatch
  4. Regular backups: Archive ledger files
  5. Monitor alerts table: Process pending notifications

License

MIT License

timefrontiers/php-wallet 适用场景与选型建议

timefrontiers/php-wallet 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 9 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「php」 「ledger」 「transaction」 「wallet」 「immutable」 「blockchain」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 timefrontiers/php-wallet 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 timefrontiers/php-wallet 我们能提供哪些服务?
定制开发 / 二次开发

基于 timefrontiers/php-wallet 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 9
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 36
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-16