定制 inodrahq/sui-sdk 二次开发

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

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

inodrahq/sui-sdk

Composer 安装命令:

composer require inodrahq/sui-sdk

包简介

The most complete PHP SDK for the Sui blockchain — 6 signature schemes, auto-resolving transactions, typed responses, JSON-RPC + gRPC

README 文档

README

A comprehensive PHP SDK for the Sui blockchain.

  • 6 signature schemes -- Ed25519, Secp256k1, Secp256r1, Multisig, zkLogin, Passkey
  • Auto-resolving Transaction builder -- gas price, budget, and coin selection handled automatically
  • 40+ RPC methods with typed response objects
  • Dual transport -- gPRC and JSON-RPC with automatic fallback
  • BIP-39 / BIP-32 key derivation with mnemonic generation
  • Convenience methods -- transfer, stake, merge, send in one call

Requirements

  • PHP 8.2+
  • ext-sodium
  • ext-bcmath
  • ext-openssl
  • ext-grpc (optional, for native gRPC transport -- gRPC-Web works without it)

Installation

composer require inodrahq/sui-sdk

Quick Start

use Inodrahq\SuiSdk\Wallet;
use Inodrahq\SuiSdk\SuiClient;

// Create a wallet
$wallet = new Wallet(); // random keypair
echo $wallet->getAddress(); // 0x...

// Or import from bech32 private key
$wallet = new Wallet('suiprivkey1...');

// Or from a mnemonic
$wallet = Wallet::fromMnemonic('abandon abandon abandon ...');

// Connect to testnet (JSON-RPC)
$client = SuiClient::forNetwork('testnet');

// Connect to testnet (gRPC -- requires ext-grpc)
$client = SuiClient::forNetworkGrpc('testnet');

// Check balance
$balance = $client->getBalance($wallet->getAddress());
echo $balance->totalBalance; // in MIST

Features

Auto-Resolving Transaction Builder

The Transaction class automatically resolves gas price, gas budget (via dry-run), and gas coin selection. No manual gas configuration needed.

use Inodrahq\SuiSdk\Transaction;

$tx = new Transaction($client);
$tx->setSender($wallet->getAddress());

// Gas price, budget, and coins are resolved automatically
$coin = $tx->splitCoins($tx->gas(), [$tx->pure('u64', '1000000000')]);
$tx->transferObjects([$coin], $tx->pure('address', $recipient));

// Build, sign, and execute in one call
$result = $tx->execute($wallet);
echo $result->digest;

Objects are also auto-resolved from the network:

// Automatically fetches object data and determines shared vs owned
$obj = $tx->object('0x5');

$tx->moveCall('0x3::sui_system::request_add_stake', [], [
    $obj,
    $coin,
    $tx->pure('address', $validatorAddress),
]);

You can still override any gas parameter manually:

$tx->setGasPrice(1000);
$tx->setGasBudget(10_000_000);
$tx->setGasPayment($objectRefs);

Signature Schemes

The SDK supports all six Sui signature schemes.

use Inodrahq\SuiSdk\Wallet;

// Ed25519 (default)
$wallet = new Wallet('suiprivkey1...');

// Secp256k1 -- auto-detected from key encoding
$wallet = new Wallet('suiprivkey1...');

// Secp256r1 -- auto-detected from key encoding
$wallet = new Wallet('suiprivkey1...');

// All wallets share the same API
$wallet->getAddress();       // 0x-prefixed Sui address
$wallet->sign($txData);      // returns base64 signature
$wallet->signPersonalMessage('Hello, Sui!');

Multisig:

use Inodrahq\SuiSdk\Crypto\MultiSig\MultiSigPublicKey;

$msig = new MultiSigPublicKey([$pk1, $pk2, $pk3], [1, 1, 1], 2);
$address = $msig->toSuiAddress();
$combinedSig = $msig->combineSignatures([$sig1, $sig2]);

zkLogin:

use Inodrahq\SuiSdk\Crypto\ZkLogin\ZkLoginAddress;

$address = ZkLoginAddress::fromJwtClaims($iss, $aud, $sub, $salt);

Passkey:

use Inodrahq\SuiSdk\Crypto\Passkey\PasskeyAuthenticator;

Typed Responses

All RPC methods return typed objects with IDE autocomplete support.

$balance = $client->getBalance($address);
echo $balance->totalBalance;    // string
echo $balance->coinObjectCount; // int
echo $balance->coinType;        // string

$coins = $client->getCoins($address);
foreach ($coins->data as $coin) {
    echo $coin->coinObjectId;  // IDE autocomplete works
    echo $coin->balance;
}

$tx = $client->getTransactionBlock($digest);
echo $tx->effects->status->status;  // "success"
echo $tx->effects->gasUsed->computationCost;

Wallet Management

use Inodrahq\SuiSdk\Wallet;

// Generate with mnemonic (BIP-39)
$result = Wallet::generateWithMnemonic();
$wallet = $result['wallet'];
$mnemonic = $result['mnemonic']; // 12 words, save this!

// 24-word mnemonic
$result = Wallet::generateWithMnemonic(256);

// Import from mnemonic
$wallet = Wallet::fromMnemonic('raccoon chalk symbol ...');

// Import from bech32 private key (SIP-15)
$wallet = new Wallet('suiprivkey1...');

// Access keys
$wallet->getAddress();       // 0x-prefixed hex
$wallet->getPublicKey();     // hex
$wallet->getPrivateKey();    // bech32
$wallet->getPrivateKeyHex(); // 0x-prefixed hex

Network Presets

use Inodrahq\SuiSdk\SuiClient;
use Inodrahq\SuiSdk\Network;

// JSON-RPC (default)
$client = SuiClient::forNetwork('mainnet');
$client = SuiClient::forNetwork('testnet');
$client = SuiClient::forNetwork('devnet');
$client = SuiClient::forNetwork('localnet');

// gRPC (requires ext-grpc)
$client = SuiClient::forNetworkGrpc('mainnet');
$client = SuiClient::forNetworkGrpc('testnet');
$client = SuiClient::forNetworkGrpc('devnet');

// With custom headers (e.g., API key)
$client = SuiClient::forNetwork('mainnet', [
    'x-api-key' => 'your-api-key',
]);

// Network URLs
Network::getRpcUrl('mainnet');    // https://fullnode.mainnet.sui.io:443
Network::getFaucetUrl('testnet'); // https://faucet.testnet.sui.io/v2/gas
Network::getExplorerUrl('mainnet'); // https://suivision.xyz/txblock/

Convenience Methods

High-level methods that handle coin selection, gas, and transaction building automatically:

// Transfer SUI (handles coin selection + gas automatically)
$result = $client->transferSui($wallet, $recipientAddress, '1000000000'); // 1 SUI

// Transfer any owned object
$result = $client->transferObject($wallet, $objectId, $recipientAddress);

// Merge all SUI coins into one
$result = $client->mergeAllCoins($wallet);

// Send non-SUI coins (USDC, etc.)
$result = $client->sendCoin($wallet, '0x...::usdc::USDC', $recipientAddress, '1000000');

// Stake SUI with a validator (minimum 1 SUI = 1_000_000_000 MIST)
$result = $client->stake($wallet, $validatorAddress, '1000000000');

// Unstake (withdraw) a StakedSui object
$result = $client->unstake($wallet, $stakedSuiObjectId);

Transaction Builder (Low-Level)

Build complex Programmable Transaction Blocks (PTBs) manually:

use Inodrahq\SuiSdk\TransactionBuilder;
use Inodrahq\SuiSdk\Bcs\Argument;

$builder = new TransactionBuilder();
$builder->setSender($wallet->getAddress());

// Split coins
$amount = $builder->addPureU64(1_000_000_000);
$coin = $builder->splitCoins(Argument::gasCoin(), [$amount]);

// Transfer
$dest = $builder->addPureAddress($recipientAddress);
$builder->transferObjects([$coin], $dest);

// Set gas
$builder->setGasBudget(10_000_000);

// Sign and execute
$tx = $builder->build();
$result = $client->signAndExecuteTransaction($tx, $wallet);

Available Commands

// SplitCoins -- split a coin into smaller coins
$result = $builder->splitCoins($coin, [$amount1, $amount2]);

// TransferObjects -- transfer objects to a destination
$builder->transferObjects([$obj1, $obj2], $destination);

// MergeCoins -- merge source coins into a destination coin
$builder->mergeCoins($destinationCoin, [$source1, $source2]);

// MoveCall -- call a Move function
$result = $builder->moveCall($package, $module, $function, $typeArgs, $args);

// Publish -- publish a Move package
$upgradeCap = $builder->publish($moduleBytes, $dependencies);

// Upgrade -- upgrade a Move package
$result = $builder->upgrade($moduleBytes, $dependencies, $package, $ticket);

// MakeMoveVec -- create a vector of Move values
$vec = $builder->makeMoveVec($typeTag, [$elem1, $elem2]);

Pure Input Helpers

$builder->addPureU64(1000);
$builder->addPureU8(42);
$builder->addPureBool(true);
$builder->addPureString('hello');
$builder->addPureBytes("\x01\x02\x03");
$builder->addPureAddress('0x...');

Object Inputs

use Inodrahq\SuiSdk\Bcs\ObjectArg;
use Inodrahq\SuiSdk\Bcs\SuiAddress;
use Inodrahq\SuiSdk\Bcs\U64;

// Owned or immutable object
$arg = $builder->addObjectInput(ObjectArg::immOrOwnedObject($objectRef));

// Shared object (e.g., SuiSystemState at 0x5)
$arg = $builder->addObjectInput(ObjectArg::sharedObject(
    new SuiAddress('0x5'), // object ID
    new U64(1),            // initial shared version
    true,                  // mutable
));

// Receiving object
$arg = $builder->addObjectInput(ObjectArg::receiving($objectRef));

Full RPC API

All 40+ Sui RPC methods are supported:

// Coin queries
$client->getCoins($owner);
$client->getAllCoins($owner);
$client->getBalance($owner);
$client->getAllBalances($owner);
$client->getCoinMetadata($coinType);
$client->getTotalSupply($coinType);

// Objects
$client->getObject($id, $options);
$client->multiGetObjects($ids, $options);
$client->getOwnedObjects($owner, $query, $cursor, $limit);
$client->getDynamicFields($parentId);
$client->getDynamicFieldObject($parentId, $name);

// Move
$client->getMoveFunctionArgTypes($package, $module, $function);
$client->getNormalizedMoveModule($package, $module);
$client->getNormalizedMoveFunction($package, $module, $function);
$client->getNormalizedMoveStruct($package, $module, $struct);
$client->getNormalizedMoveModulesByPackage($package);

// Transactions
$client->getTransactionBlock($digest, $options);
$client->multiGetTransactionBlocks($digests, $options);
$client->getTotalTransactionBlocks();
$client->dryRunTransactionBlock($txBytesBase64);
$client->devInspectTransactionBlock($sender, $txBytesBase64, $gasPrice);
$client->executeTransactionBlock($txBytes, $signatures, $options, $requestType);
$client->signAndExecuteTransaction($txData, $wallet);
$client->waitForTransaction($digest, $timeout);
$client->queryTransactionBlocks($query, $cursor, $limit, $descendingOrder);
$client->queryEvents($query, $cursor, $limit, $descendingOrder);

// Governance
$client->getReferenceGasPrice();
$client->getStakes($owner);
$client->getStakesByIds($stakedSuiIds);
$client->getLatestSuiSystemState();
$client->getValidatorsApy();
$client->getCommitteeInfo($epoch);

// Chain
$client->getChainIdentifier();
$client->getLatestCheckpointSequenceNumber();
$client->getCheckpoint($id);
$client->getCheckpoints($cursor, $limit, $descendingOrder);
$client->getRpcApiVersion();
$client->getProtocolConfig($version);

// Name Service
$client->resolveNameServiceAddress($name);
$client->resolveNameServiceNames($address);

// History
$client->tryGetPastObject($objectId, $version, $options);
$client->tryMultiGetPastObjects($pastObjects, $options);

Paginated Responses

use Inodrahq\SuiSdk\PaginatedResponse;

// All paginated methods return PaginatedResponse
$page = $client->getCoins($owner);
echo $page->count();       // number of items
echo $page->hasNextPage;   // bool
echo $page->nextCursor;    // cursor for next page

// Iterate through all pages
foreach ($client->iterateCoins($owner) as $page) {
    foreach ($page->data as $coin) {
        echo $coin->coinObjectId . "\n";
    }
}

Signature Verification

use Inodrahq\SuiSdk\Crypto\Verifier;

// Verify a transaction signature
$isValid = Verifier::verifyTransactionSignature($signature, $txBytes);

// Verify a personal message signature
$isValid = Verifier::verifyPersonalMessage($signature, $message);

// Extract info from a signature
$publicKey = Verifier::extractPublicKey($signature); // hex
$address = Verifier::extractAddress($signature);     // 0x...

Transport Layer

The SDK supports pluggable transports. Both JSON-RPC and gRPC use the same SuiClient API -- all methods work identically regardless of transport.

JSON-RPC (default)

use Inodrahq\SuiSdk\SuiClient;
use Inodrahq\SuiSdk\Transport\JsonRpcTransport;

// Using network preset
$client = SuiClient::forNetwork('mainnet');

// Custom endpoint with headers
$client = new SuiClient(new JsonRpcTransport('https://fullnode.mainnet.sui.io:443', [
    'x-api-key' => 'your-key',
]));

gRPC

gRPC provides better performance with binary serialization and HTTP/2. Requires the ext-grpc PHP extension:

# macOS
pecl install grpc

# Ubuntu/Debian
pecl install grpc
echo "extension=grpc.so" > /etc/php/8.2/mods-available/grpc.ini
phpenmod grpc

# Verify
php -m | grep grpc
use Inodrahq\SuiSdk\SuiClient;
use Inodrahq\SuiSdk\Transport\GrpcTransport;

// Using network preset
$client = SuiClient::forNetworkGrpc('testnet');

// Custom endpoint
$client = new SuiClient(new GrpcTransport('fullnode.mainnet.sui.io:443'));

// All methods work the same as JSON-RPC
$balance = $client->getBalance($address);
$result = $client->transferSui($wallet, $recipient, '1000000000');

gRPC coverage: Most RPC methods have gRPC equivalents. The following methods are JSON-RPC only and will automatically fall back to JSON-RPC via the MethodRouter:

Method Reason
getStakes No gRPC equivalent
getStakesByIds No gRPC equivalent
getLatestSuiSystemState No gRPC equivalent
getValidatorsApy No gRPC equivalent
getCommitteeInfo No gRPC equivalent
queryTransactionBlocks No gRPC equivalent
queryEvents No gRPC equivalent
getCheckpoints No gRPC equivalent
devInspectTransactionBlock No gRPC equivalent
getRpcApiVersion JSON-RPC specific

Examples

Deploy a Move Package

$moduleBytes = file_get_contents('build/MyPackage/bytecode_modules/my_module.mv');
$dep1 = new SuiAddress('0x1'); // MoveStdlib
$dep2 = new SuiAddress('0x2'); // Sui Framework

$builder = new TransactionBuilder();
$builder->setSender($wallet->getAddress());

$upgradeCap = $builder->publish([$moduleBytes], [$dep1, $dep2]);
$sender = $builder->addPureAddress($wallet->getAddress());
$builder->transferObjects([$upgradeCap], $sender);

$builder->setGasBudget(100_000_000);
$result = $client->signAndExecuteTransaction($builder->build(), $wallet);

Stake SUI

// Using the auto-resolving Transaction builder
$tx = new Transaction($client);
$tx->setSender($wallet->getAddress());

$amount = $tx->pure('u64', '1000000000');
$coin = $tx->splitCoins($tx->gas(), [$amount]);

$tx->moveCall('0x3::sui_system::request_add_stake', [], [
    $tx->object('0x5'),          // SuiSystemState (auto-resolved as shared)
    $coin,
    $tx->pure('address', $validatorAddress),
]);

$result = $tx->execute($wallet);

Or use the convenience method:

$result = $client->stake($wallet, $validatorAddress, '1000000000');

Send USDC

$result = $client->sendCoin(
    $wallet,
    '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',
    $recipientAddress,
    '1000000', // 1 USDC (6 decimals)
);

Testing

composer test

655 tests covering:

  • BIP-39 mnemonic generation/validation with Sui test vectors
  • SIP-15 wallet key encoding/decoding
  • All 6 signature schemes (Ed25519, Secp256k1, Secp256r1, Multisig, zkLogin, Passkey)
  • Transaction BCS parity with Rust (byte-for-byte)
  • Ed25519 / Secp256k1 / Secp256r1 signature parity
  • Auto-resolving Transaction builder (gas estimation, coin selection)
  • All RPC methods (mocked transport)
  • Transaction builder (all 7 command types)
  • Signature verification roundtrips
  • Typed response deserialization
  • Network presets and transport configuration
  • gRPC transport and method routing
  • Paginated response iteration
  • Convenience methods (transfer, stake, merge, send)
  • Integration transfer test (testnet)

License

MIT

inodrahq/sui-sdk 适用场景与选型建议

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

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

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

围绕 inodrahq/sui-sdk 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-10