https://github.com/madmatvey/gasfree_sdk
Ruby SDK for interacting with the GasFree.io API, enabling gasless transfers of TRC-20/ERC-20 tokens.
https://github.com/madmatvey/gasfree_sdk
erc20 gasless-sdk gasless-transactions gasless-tx ruby trc20
Last synced: 11 months ago
JSON representation
Ruby SDK for interacting with the GasFree.io API, enabling gasless transfers of TRC-20/ERC-20 tokens.
- Host: GitHub
- URL: https://github.com/madmatvey/gasfree_sdk
- Owner: madmatvey
- License: other
- Created: 2025-05-26T14:55:26.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-07-26T11:28:57.000Z (about 1 year ago)
- Last Synced: 2025-08-28T16:46:04.050Z (11 months ago)
- Topics: erc20, gasless-sdk, gasless-transactions, gasless-tx, ruby, trc20
- Language: Ruby
- Homepage: https://gasfree.io/docs/GasFree_specification.html
- Size: 174 KB
- Stars: 2
- Watchers: 0
- Forks: 12
- Open Issues: 21
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# GasFree SDK
Ruby SDK for GasFree.io - TRC-20 gasless transfer solution.
## 💬 Support & Consulting
If you encounter any issues, feel free to open a discussion or report a bug via the [GitHub Issues](https://github.com/madmatvey/gasfree_sdk/issues) page.
You can also [hire me as an external consultant](https://madmatvey.github.io/about/#cv) if you need help integrating or customizing the gem for your project.
If you find this gem useful and want to support further development, you're welcome to [donate here](https://madmatvey.github.io/about/#donate-me).
## Installation
This gem is published on [RubyGems.org](https://rubygems.org/gems/gasfree_sdk).
Add this line to your application's Gemfile:
```ruby
gem 'gasfree_sdk'
```
And then execute:
$ bundle install
Or install it yourself as:
$ gem install gasfree_sdk
## Configuration
```ruby
require 'gasfree_sdk'
GasfreeSdk.configure do |config|
config.api_key = "your-api-key"
config.api_secret = "your-api-secret"
config.api_endpoint = "https://open.gasfree.io/tron/" # TRON endpoint
end
# Note: The api_endpoint must be a valid http or https URL. If an invalid value is provided,
# a GasfreeSdk::Error will be raised during configuration.
```
## Basic Usage
### Initialize Client
```ruby
client = GasfreeSdk.client
```
### Get Supported Tokens
```ruby
tokens = client.tokens
tokens.each do |token|
puts "#{token.symbol} (#{token.token_address})"
puts " Activation Fee: #{token.activate_fee}"
puts " Transfer Fee: #{token.transfer_fee}"
end
```
### Get Service Providers
```ruby
providers = client.providers
providers.each do |provider|
puts "#{provider.name} (#{provider.address})"
puts " Max Pending Transfers: #{provider.config.max_pending_transfer}"
puts " Default Deadline: #{provider.config.default_deadline_duration}s"
end
```
### Check Account Information
```ruby
account = client.address("TYourTronAddress")
puts "GasFree Address: #{account.gas_free_address}"
puts "Active: #{account.active}"
puts "Nonce: #{account.nonce}"
account.assets.each do |asset|
puts "#{asset.token_symbol}: #{asset.frozen} frozen"
end
```
## TRON EIP-712 Signature Module
The SDK includes a comprehensive EIP-712 signature implementation specifically designed for TRON GasFree transfers. This module handles the complex cryptographic operations required for signing structured data according to the EIP-712 standard as implemented by TRON (TIP-712).
### Features
- **Complete EIP-712 Implementation**: Full support for EIP-712 structured data signing
- **TRON-Specific Adaptations**: Handles TRON address encoding and TIP-712 specifications
- **Dual Network Support**: Separate configurations for TRON Mainnet and Testnet (Nile)
- **Flexible Key Handling**: Support for multiple data key formats (camelCase, snake_case)
- **Built-in Cryptography**: Includes Keccak256 hashing and Base58 encoding for TRON addresses
### Basic Signature Usage
```ruby
# Example message data
message_data = {
token: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", # USDT TRC-20
serviceProvider: "TGzz8gjYiYRqpfmDwnLxfgPuLVNmpCswVp",
user: "TYRhsi1fkke2tjdVW9XGYLjf8TgbbutEgY",
receiver: "TW1dWXfta5ygVN298JBN2UPhaSAUzo2owZ",
value: "3000000", # 3 USDT (6 decimals)
maxFee: "2000000", # 2 USDT max fee
deadline: (Time.now.to_i + 300).to_s, # 5 minutes from now
version: 1,
nonce: 0
}
private_key = "your_private_key_hex"
# Sign for TRON Testnet (Nile)
testnet_signature = GasfreeSdk::TronEIP712Signer.sign_typed_data_testnet(private_key, message_data)
# Sign for TRON Mainnet
mainnet_signature = GasfreeSdk::TronEIP712Signer.sign_typed_data_mainnet(private_key, message_data)
# Generic signing with custom domain
signature = GasfreeSdk::TronEIP712Signer.sign_typed_data(
private_key,
message_data,
domain: GasfreeSdk::TronEIP712Signer::DOMAIN_TESTNET
)
```
### Advanced Usage
#### Custom Domain Configuration
```ruby
custom_domain = {
name: "GasFreeController",
version: "V1.0.0",
chainId: 728_126_428,
verifyingContract: "THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc"
}
signature = GasfreeSdk::TronEIP712Signer.sign_typed_data(
private_key,
message_data,
domain: custom_domain,
use_ethereum_v: true
)
```
#### Individual Cryptographic Operations
```ruby
# Keccak256 hashing
hash = GasfreeSdk::TronEIP712Signer.keccac256("data to hash")
hex_hash = GasfreeSdk::TronEIP712Signer.keccac256_hex("data to hash")
# EIP-712 type encoding
encoded_type = GasfreeSdk::TronEIP712Signer.encode_type(:PermitTransfer)
# Structured data hashing
message_hash = GasfreeSdk::TronEIP712Signer.hash_struct(:PermitTransfer, message_data)
domain_hash = GasfreeSdk::TronEIP712Signer.hash_domain
```
#### TRON Address Utilities
```ruby
# Base58 encoding/decoding for TRON addresses
binary_data = GasfreeSdk::Base58.base58_to_binary("TYRhsi1fkke2tjdVW9XGYLjf8TgbbutEgY")
base58_string = GasfreeSdk::Base58.binary_to_base58(binary_data)
```
### Domain Constants
The module provides pre-configured domain constants for both networks:
```ruby
# TRON Testnet (Nile)
GasfreeSdk::TronEIP712Signer::DOMAIN_TESTNET
# => {
# name: "GasFreeController",
# version: "V1.0.0",
# chainId: 728_126_428,
# verifyingContract: "THQGuFzL87ZqhxkgqYEryRAd7gqFqL5rdc"
# }
# TRON Mainnet
GasfreeSdk::TronEIP712Signer::DOMAIN_MAINNET
# => {
# name: "GasFreeController",
# version: "V1.0.0",
# chainId: 3_448_148_188,
# verifyingContract: "TFFAMQLZybALaLb4uxHA9RBE7pxhUAjF3U"
# }
```
### Submit Transfer with Signature
```ruby
# Create and submit a transfer request
token = client.tokens.first
provider = client.providers.first
message_data = {
token: token.token_address,
serviceProvider: provider.address,
user: "TYourTronAddress",
receiver: "TReceiverAddress",
value: "1000000", # 1 USDT
maxFee: "500000", # 0.5 USDT max fee
deadline: (Time.now.to_i + provider.config.default_deadline_duration).to_s,
version: 1,
nonce: account.nonce
}
# Sign the message
signature = GasfreeSdk::TronEIP712Signer.sign_typed_data_testnet(private_key, message_data)
# Create transfer request
request = GasfreeSdk::Models::TransferRequest.new(
token: message_data[:token],
service_provider: message_data[:serviceProvider],
user: message_data[:user],
receiver: message_data[:receiver],
value: message_data[:value],
max_fee: message_data[:maxFee],
deadline: message_data[:deadline].to_i,
version: message_data[:version],
nonce: message_data[:nonce],
sig: signature
)
# Submit the transfer
response = client.submit_transfer(request)
puts "Transfer ID: #{response.id}"
puts "State: #{response.state}"
```
### Monitor Transfer Status
```ruby
transfer_id = response.id
loop do
status = client.transfer_status(transfer_id)
puts "State: #{status.state}"
puts "Transaction Hash: #{status.txn_hash}" if status.txn_hash
break if %w[SUCCEED FAILED].include?(status.state)
sleep 2
end
```
## Debugging and Logging
The SDK uses a custom Faraday middleware (`SanitizedLogsMiddleware`) to ensure that **all HTTP request and response logs are automatically sanitized**. Sensitive data is never written to logs, even in debug mode.
### Enable Debug Logging
```bash
export DEBUG_GASFREE_SDK=1
```
When this environment variable is set, the SDK will log HTTP requests and responses using only sanitized data. This is handled automatically; you do not need to configure anything extra.
### How It Works
- The SDK integrates `SanitizedLogsMiddleware` into the Faraday stack.
- This middleware intercepts all HTTP traffic and logs method, URL, headers, and body **with sensitive fields masked** (e.g., `***REDACTED***`).
- The original data is never mutated, and only masked data is ever written to logs.
- No other HTTP logging middleware is used, so there is no risk of leaking secrets.
### Example Integration (automatic)
```ruby
client = GasfreeSdk.client
# If DEBUG_GASFREE_SDK=1, all HTTP logs will be sanitized automatically.
```
### Automatic Data Protection
When debug logging is enabled, sensitive fields (private keys, tokens, signatures, etc.) are automatically masked with `***REDACTED***` in all HTTP request/response logs.
**Protected fields include:**
- Headers: `Authorization`, `Api-Key`, `X-Api-Key`, etc.
- Body fields: `private_key`, `api_secret`, `signature`, `token`, etc.
### Example
```ruby
# With DEBUG_GASFREE_SDK=1
client = GasfreeSdk.client
tokens = client.tokens
# Console output (sensitive data automatically masked):
# GET https://open.gasfree.io/tron/api/v1/config/token/all
# Request Headers: {"Authorization"=>"***REDACTED***", "Timestamp"=>"1703123456"}
```
## Error Handling
```ruby
begin
response = client.submit_transfer(request)
rescue GasfreeSdk::APIError => e
puts "API Error (#{e.code}): #{e.message}"
case e.message
when /insufficient balance/
puts "Solution: Get test tokens or transfer tokens to GasFree address"
when /max fee exceeded/
puts "Solution: Increase maxFee parameter"
when /Invalid signature/
puts "Solution: Check private key and address correspondence"
end
rescue StandardError => e
puts "Error: #{e.message}"
end
```
## Examples
See the `examples/` directory for complete working examples:
- `examples/simple_usage_example.rb` - Basic TronEIP712Signer usage
## Dependencies
- `dry-configurable` - Configuration management
- `dry-struct` - Data structures
- `dry-types` - Type system
- `dry-validation` - Data validation
- `faraday` - HTTP client
- `faraday-retry` - HTTP retry logic
- `eth` - Ethereum utilities
- `rbsecp256k1` - Cryptographic operations for EIP-712 signatures
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/madmatvey/gasfree_sdk.
## License
The gem is available as open source under the terms of the [LGPL v3.0](https://www.gnu.org/licenses/lgpl-3.0.html) © 2025 Eugene Leontev (https://github.com/madmatvey)