wallet tron transactions
This commit is contained in:
252
sdk/Wallet/Trc20Sdk.php
Normal file
252
sdk/Wallet/Trc20Sdk.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace Sdk\Wallet;
|
||||
|
||||
use App\Bean\Sdk\Wallet\Tron\NowBlockBean;
|
||||
use App\Bean\Sdk\Wallet\Tron\ResponseBean;
|
||||
use App\Bean\Sdk\Wallet\Tron\TokenAddressBean;
|
||||
use App\Bean\Sdk\Wallet\Tron\TransferTransactionBean;
|
||||
use App\Exceptions\WalletSdkException;
|
||||
use App\Tools\Math;
|
||||
use GuzzleHttp\Client;
|
||||
use IEXBase\TronAPI\Exception\TronException;
|
||||
use IEXBase\TronAPI\Provider\HttpProvider;
|
||||
use IEXBase\TronAPI\Tron;
|
||||
use Sdk\Wallet\Tools\Formatter;
|
||||
use Sdk\Wallet\Tools\Utils;
|
||||
|
||||
class Trc20Sdk
|
||||
{
|
||||
protected $tron;
|
||||
protected $tronContract;
|
||||
protected $config = [];
|
||||
protected TokenAddress $contractAddress;
|
||||
protected Http $http;
|
||||
const DECIMALS = 6;
|
||||
|
||||
function __construct(Client $_api, string $contractAddress)
|
||||
{
|
||||
$this->http = new Http($_api);
|
||||
$this->contractAddress = new TokenAddress($contractAddress);
|
||||
|
||||
$host = $this->getHttpClient()->getClient()->getConfig('base_uri')->getScheme() . '://' . $this->getHttpClient()->getClient()->getConfig('base_uri')->getHost();
|
||||
$fullNode = new HttpProvider($host);
|
||||
$solidityNode = new HttpProvider($host);
|
||||
$eventServer = new HttpProvider($host);
|
||||
try {
|
||||
$this->tron = new Tron($fullNode, $solidityNode, $eventServer);
|
||||
// $this->tronContract = new TRC20Contract($this->tron,$contractAddress);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
function getHttpClient(): Http
|
||||
{
|
||||
return $this->http;
|
||||
}
|
||||
|
||||
//获取当前最新区块事件
|
||||
function getLastBlockEvent(): NowBlockBean|bool
|
||||
{
|
||||
$data = [
|
||||
'limit' => 1,
|
||||
'order_by' => 'block_timestamp,desc',
|
||||
];
|
||||
$res = $this->getHttpClient()->get('/v1/blocks/latest/events', $data);
|
||||
if (!isset($res['data'][0])) return false;
|
||||
$ResponseBean = new ResponseBean($res);
|
||||
$item = $ResponseBean->getData()[0];
|
||||
return new NowBlockBean($item);
|
||||
}
|
||||
|
||||
//获取当前最新区块事件
|
||||
function getNowBlockNumber(): NowBlockBean|bool
|
||||
{
|
||||
return $this->getLastBlockEvent();
|
||||
}
|
||||
|
||||
//根据区块高度获取交易信息
|
||||
public function getTrc20BlockEventsByBlockNumber(string|int $blockNumber, $fingerprint = null, $limit = 200): bool|ResponseBean
|
||||
{
|
||||
$path = '/v1/contracts/' . $this->contractAddress->address . '/events';
|
||||
$data = [
|
||||
'block_number' => $blockNumber,
|
||||
'limit' => $limit,
|
||||
'only_confirmed' => true,
|
||||
];
|
||||
if (!empty($fingerprint)) $data['fingerprint'] = $fingerprint;
|
||||
$res = $this->getHttpClient()->get($path, $data);
|
||||
if (!isset($res['success'])) return false;
|
||||
if ($res['success'] !== true) return false;
|
||||
return new ResponseBean($res);
|
||||
}
|
||||
|
||||
//根据区块高度获取交易信息
|
||||
public function getTrc20BlockEventsTransferByBlockNumber(string|int $blockNumber, $fingerprint = null, $limit = 200): bool|ResponseBean
|
||||
{
|
||||
$path = '/v1/contracts/' . $this->contractAddress->address . '/events';
|
||||
$data = [
|
||||
'event_name' => 'Transfer',
|
||||
'block_number' => $blockNumber,
|
||||
'limit' => $limit,
|
||||
'only_confirmed' => true,
|
||||
'order_by' => 'block_timestamp,asc',
|
||||
];
|
||||
if (!empty($fingerprint)) $data['fingerprint'] = $fingerprint;
|
||||
$res = $this->getHttpClient()->get($path, $data);
|
||||
if (!isset($res['success'])) return false;
|
||||
if ($res['success'] !== true) return false;
|
||||
return new ResponseBean($res);
|
||||
}
|
||||
|
||||
//获取账户合约交易记录
|
||||
public function getAccountTrc20Events(string $address, $fingerprint = null, $limit = 200): bool|ResponseBean
|
||||
{
|
||||
$path = '/v1/accounts/' . $address . '//transactions/trc20';
|
||||
$data = [
|
||||
'limit' => $limit,
|
||||
'contract_address' => $this->contractAddress->address,
|
||||
'only_confirmed' => true,
|
||||
'order_by' => 'block_timestamp,desc',
|
||||
];
|
||||
if (!empty($fingerprint)) $data['fingerprint'] = $fingerprint;
|
||||
$res = $this->getHttpClient()->get($path, $data);
|
||||
if (!isset($res['success'])) return false;
|
||||
if ($res['success'] !== true) return false;
|
||||
return new ResponseBean($res);
|
||||
}
|
||||
|
||||
//获取TRC20余额
|
||||
function getTrc20Balance(string $address): float|string
|
||||
{
|
||||
$address = new TokenAddress($address);
|
||||
$format = Formatter::toAddressFormat($address->hexAddress);
|
||||
$res = $this->getHttpClient()->post('/wallet/triggersmartcontract', [
|
||||
'contract_address' => $this->contractAddress->hexAddress,
|
||||
'function_selector' => 'balanceOf(address)',
|
||||
'parameter' => $format,
|
||||
'owner_address' => $address->hexAddress,
|
||||
]);
|
||||
|
||||
if (!isset($res['result']['result'])) {
|
||||
throw new WalletSdkException('getTrc20Balance error');
|
||||
}
|
||||
if ($res['result']['result'] !== true) {
|
||||
throw new WalletSdkException('getTrc20Balance error');
|
||||
}
|
||||
|
||||
try {
|
||||
$hex_value = $res['constant_result'][0];
|
||||
$balance = Math::valueToAmount(hexdec($hex_value), self::DECIMALS);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage());
|
||||
}
|
||||
return $balance;
|
||||
}
|
||||
|
||||
//获取TRX余额
|
||||
function getTrxBalance(string $address): float
|
||||
{
|
||||
$this->tron->setAddress($address);
|
||||
return $this->tron->getBalance($address, true);
|
||||
}
|
||||
|
||||
//TRC20转账
|
||||
function trc20Transfer(TokenAddress $from, TokenAddress $to, float $amount): TransferTransactionBean|bool
|
||||
{
|
||||
$this->tron->setAddress($from->address);
|
||||
$this->tron->setPrivateKey($from->privateKey);
|
||||
|
||||
$toFormat = Formatter::toAddressFormat($to->hexAddress);
|
||||
try {
|
||||
$amount = Utils::toMinUnitByDecimals($amount, self::DECIMALS);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage());
|
||||
}
|
||||
$numberFormat = Formatter::toIntegerFormat($amount);
|
||||
|
||||
$body = $this->getHttpClient()->post('/wallet/triggersmartcontract', [
|
||||
'contract_address' => $this->contractAddress->hexAddress,
|
||||
'function_selector' => 'transfer(address,uint256)',
|
||||
'parameter' => "{$toFormat}{$numberFormat}",
|
||||
'fee_limit' => 30000000,
|
||||
'call_value' => 0,
|
||||
'owner_address' => $from->hexAddress,
|
||||
]);
|
||||
|
||||
if (!isset($body['result']['result'])) {
|
||||
throw new WalletSdkException(hex2bin($body['result']['message']));
|
||||
}
|
||||
|
||||
try {
|
||||
$tradeobj = $this->tron->signTransaction($body['transaction']);
|
||||
$response = $this->tron->sendRawTransaction($tradeobj);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
if (isset($response['result']) && $response['result'] == true) {
|
||||
return new TransferTransactionBean($body['transaction']);
|
||||
} else {
|
||||
throw new WalletSdkException(hex2bin($response['result']['message']));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//TRX转账
|
||||
function trxTransfer(TokenAddress $from, TokenAddress $to, float $amount): TransferTransactionBean
|
||||
{
|
||||
$this->tron->setAddress($from->address);
|
||||
$this->tron->setPrivateKey($from->privateKey);
|
||||
|
||||
try {
|
||||
$transaction = $this->tron->getTransactionBuilder()->sendTrx($to->address, $amount, $from->address);
|
||||
$signedTransaction = $this->tron->signTransaction($transaction);
|
||||
$response = $this->tron->sendRawTransaction($signedTransaction);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
|
||||
if (isset($response['result']) && $response['result'] == true) {
|
||||
$TransferTransactionBean = new TransferTransactionBean($signedTransaction);
|
||||
return $TransferTransactionBean;
|
||||
} else {
|
||||
throw new WalletSdkException(hex2bin($response['message']));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//根据交易hash获取交易信息
|
||||
function getTransactionByTid(string $tid): array
|
||||
{
|
||||
try {
|
||||
return $this->tron->getTransaction($tid);
|
||||
} catch (\Exception $e) {
|
||||
throw new WalletSdkException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
//检测交易是否成功
|
||||
function checkTransactionByTid(string $tid): bool
|
||||
{
|
||||
$res = $this->getTransactionByTid($tid);
|
||||
if (empty($res)) return false;
|
||||
if (!isset($res['ret']['contractRet'])) return false;
|
||||
if ($res['ret']['contractRet'] === 'SUCCESS') return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//生成新地址
|
||||
function createAccount(): TokenAddressBean
|
||||
{
|
||||
try {
|
||||
$res = $this->tron->createAccount();
|
||||
} catch (TronException $e) {
|
||||
throw new WalletSdkException($e->getMessage(), $e->getCode());
|
||||
}
|
||||
return new TokenAddressBean($res->getRawData());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user