diff --git a/src/Enums/AbiFunction.php b/src/Enums/AbiFunction.php index 2085133..afe0466 100644 --- a/src/Enums/AbiFunction.php +++ b/src/Enums/AbiFunction.php @@ -23,6 +23,7 @@ enum AbiFunction: string case USERNAME_RESIGNATION = 'resignUsername'; case MULTIPAYMENT = 'pay'; case TRANSFER = 'transfer'; + case APPROVE = 'approve'; public function transactionClass(): string { @@ -35,6 +36,7 @@ public function transactionClass(): string self::USERNAME_RESIGNATION => UsernameResignation::class, self::MULTIPAYMENT => Multipayment::class, self::TRANSFER => EvmCall::class, + self::APPROVE => EvmCall::class, }; } } diff --git a/src/Transactions/Builder/TokenApproveBuilder.php b/src/Transactions/Builder/TokenApproveBuilder.php new file mode 100644 index 0000000..74da71a --- /dev/null +++ b/src/Transactions/Builder/TokenApproveBuilder.php @@ -0,0 +1,38 @@ +to($address); + } + + public function spender(string $address, BigDecimal $amount): self + { + $payload = (new AbiEncoder(ContractAbiType::TOKEN))->encodeFunctionCall( + AbiFunction::APPROVE->value, + [$address, $amount] + ); + + $this->transaction->data['data'] = Helpers::removeLeadingHexZero($payload); + + return $this; + } + + protected function getTransactionInstance(array $data): AbstractTransaction + { + return new EvmCall($data); + } +} diff --git a/tests/Unit/Transactions/Builder/TokenApproveBuilderTest.php b/tests/Unit/Transactions/Builder/TokenApproveBuilderTest.php new file mode 100644 index 0000000..3c9b233 --- /dev/null +++ b/tests/Unit/Transactions/Builder/TokenApproveBuilderTest.php @@ -0,0 +1,37 @@ +contractAddress($contractAddress) + ->spender($spender, $amount); + + expect($builder->transaction->data['to'])->toBe($contractAddress); + expect($builder->transaction->data['value']->isZero())->toBeTrue(); + expect($builder->transaction->data['data'])->toBe($expectedPayload); +}); + +it('should sign and verify a token approve', function () { + $builder = TokenApproveBuilder::new() + ->contractAddress('0x6F0182a0cc707b055322CcF6d4CB6a5Aff1aEb22') + ->spender('0xA5cc0BfEB09742C5e4C610f2EBaaB82Eb142Ca10', BigDecimal::of('1000000000000')) + ->gasPrice(UnitConverter::parseUnits('5000000000', 'wei')) + ->gasLimit(UnitConverter::parseUnits('21000', 'wei')) + ->nonce('1') + ->sign($this->passphrase); + + expect($builder->verify())->toBeTrue(); + expect($builder->transaction->data['data'])->toStartWith('095ea7b3'); + expect($builder->transaction->data['to'])->toBe('0x6F0182a0cc707b055322CcF6d4CB6a5Aff1aEb22'); + expect($builder->transaction->data['value']->isZero())->toBeTrue(); +});