TokenTransferService.php 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. namespace Services;
  3. use Libs\BashExecutor;
  4. class TokenTransferService
  5. {
  6. private string $easyCliPath;
  7. public function __construct(?string $easyCliPath = null)
  8. {
  9. $this->easyCliPath = $easyCliPath ?? dirname(__DIR__) . '/bin/easycli';
  10. }
  11. public function transferFrom(string $fromAddress, string $toAddress, string $tokenExternalId): array
  12. {
  13. $from = trim($fromAddress);
  14. $to = trim($toAddress);
  15. $token = trim($tokenExternalId);
  16. if ($from === '' || $to === '' || $token === '') {
  17. throw new \InvalidArgumentException('Parâmetros inválidos para transferência de token.');
  18. }
  19. if (!is_file($this->easyCliPath) || !is_executable($this->easyCliPath)) {
  20. throw new \RuntimeException('easycli executable not found or not executable');
  21. }
  22. $command = sprintf(
  23. '%s token transfer --to %s --token-id %s',
  24. escapeshellarg($this->easyCliPath),
  25. escapeshellarg($to),
  26. escapeshellarg($token)
  27. );
  28. $result = BashExecutor::run($command, 120);
  29. $stdout = trim((string)($result['output'] ?? ''));
  30. $stderr = trim((string)($result['error'] ?? ''));
  31. $combinedOutput = trim(implode("\n", array_filter([$stdout, $stderr])));
  32. if (($result['exitCode'] ?? 1) !== 0) {
  33. $message = $combinedOutput !== '' ? $combinedOutput : 'Unknown easycli error';
  34. throw new \RuntimeException('easycli transfer failed: ' . $message);
  35. }
  36. if ($combinedOutput !== '' && preg_match('/execution\s+reverted/i', $combinedOutput)) {
  37. throw new \RuntimeException('easycli transfer failed: ' . $combinedOutput);
  38. }
  39. $txHash = $this->extractHashFromOutput($combinedOutput);
  40. return [
  41. 'output' => $stdout,
  42. 'error' => $stderr,
  43. 'tx_hash' => $txHash,
  44. ];
  45. }
  46. private function extractHashFromOutput(string $output): ?string
  47. {
  48. if ($output === '') {
  49. return null;
  50. }
  51. if (preg_match('/0x[a-fA-F0-9]{64}/', $output, $matches)) {
  52. return $matches[0];
  53. }
  54. return null;
  55. }
  56. }