celo-sdk-java, originally adapted from Ethereum web3j, is a Java library for working with the Celo Blockchain and Celo Core Contracts.
- Connect to a node
- Access web3 object to interact with node's Json RPC API
- Send Transaction with celo's extra fields: (feeCurrency)
- Simple interface to interact with CELO and cUSD
- Simple interface to interact with Celo Core contracts
- Utilities
Java 8
Gradle 6
Install from repositories:
maven
<repositories>
<repository>
<id>bintray-celo-celo</id>
<name>bintray</name>
<url>https://dl.bintray.com/celo/celo</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.celo</groupId>
<artifactId>contractkit</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
Gradle
repositories {
maven {
url "https://dl.bintray.com/celo/celo"
}
}
compile 'org.celo:contractkit:0.0.1'
Install manually If you want to generate the jar and import manually.
git clone https://github.com/celo/celo-sdk-java.git
./gradlew clean build -xtest
./gradlew publishToMavenLocal
Most of tests uses Ganache testnet.
To start devchain run ./scripts/start_devchain.sh
script.
To reset devchain to the initial state run ./scripts/reset_devchain.sh
script. It's recommend to run script before run all tests.
./scripts/reset_devchain.sh
./scripts/start_devchain.sh
./gradlew clean test
You can read more about in this manual
- Create an Account on JFrog Bintray
- Create maven repository (name: celo)
- Build and upload library
./gradlew bintrayUpload -Dbintray.user=<YOUR_USER_NAME> -Dbintray.key=<YOUR_API_KEY>
The package will be created with these parameters
Repository: celo
Package: com.celo:contractkit
4 - After publish to the Bintray library can be published to the JCenter
Follow these manual
To start working with ContractKit you need a kit
instance and a valid net to connect with. In this example will use alfajores
(you can read more about it here)
import org.celo.contractkit.ContractKit;
ContractKit contractKit = ContractKit.build(new HttpService("https://alfajores-forno.celo-testnet.org"));
If you are hosting your own node you can connect our ContractKit to it.
Same as Web3
we support WebSockets
, RPC
and connecting via IPC
.
For this last one you will have to initialize the kit
with an instance of Web3
that has a valid IPC Provider
import org.celo.contractkit.ContractKit;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.ipc.UnixIpcService;
Web3j web3j = Web3j.build(new UnixIpcService("/path/to/socketfile"));
ContractKit contractKit = new ContractKit(web3j);
The following are some examples of the capabilities of the ContractKit
, assuming it is already connected to a node. If you aren't connected, here is a refresher.
kit
allows you to set default transaction options:
Web3j web3j = Web3j.build(new HttpService(ContractKit.ALFAJORES_TESTNET));
ContractKitOptions config = new ContractKitOptions.Builder()
.setFeeCurrency(CeloContract.GoldToken)
.setGasPrice(BigInteger.valueOf(21_000))
.build();
ContractKit contractKit = new ContractKit(web3j, config);
Multiple accounts can be added to the kit wallet. The first added account will be used by default.
Credentials credentials = Credentials.create(somePrivateKey);
contractKit.addAccount(credentials);
or
contractKit.addAccount(somePrivateKey);
To change default account to sign transactions
contractKit.setDefaultAccount(publicKey);
This method from the kit
will return the CELO, locked CELO, cUSD and total balance of the address
AccountBalance balance = contractKit.getTotalBalance(myAddress);
Deploying a contract with the default account already set.
You can verify the deployment on the Alfajores block explorer here. Wait for the receipt and log it to get the transaction details.
Web3j web3j = Web3j.build(new HttpService(ContractKit.ALFAJORES_TESTNET));
ContractKit contractKit = new ContractKit(web3j);
contractKit.addAccount(PRIVATE_KEY);
GoldToken deployedGoldenToken = contractKit.contracts.getGoldToken().deploy().send();
TransactionReceipt receipt = deployedGoldenToken.getTransactionReceipt().get();
String hash = receipt.getTransactionHash();
ExchangeWrapper exchange = contractKit.contracts.getExchange();
StableTokenWrapper stableToken = contractKit.contracts.getStableToken();
GoldTokenWrapper goldToken = contractKit.contracts.getGoldToken();
BigInteger cUsdBalance = stableToken.balanceOf(myAddress).send();
TransactionReceipt approveTx = stableToken.approve(exchange.getContractAddress(), cUsdBalance).send();
String approveTxHash = approveTx.getTransactionHash();
BigInteger goldAmount = exchange.quoteUsdSell(cUsdBalance).send();
TransactionReceipt sellTx = exchange.sellDollar(cUsdBalance, goldAmount).send();
String sellTxHash = sellTx.getTransactionHash();
celo-blockchain has two initial coins: CELO and cUSD (stableToken). Both implement the ERC20 standard, and to interact with them is as simple as:
GoldTokenWrapper goldtoken = contractKit.contracts.getGoldToken();
BigInteger goldBalance = goldtoken.balanceOf(someAddress).send();
To send funds:
BigInteger oneGold = Convert.toWei(BigDecimal.ONE, Convert.Unit.ETHER).toBigInteger();
TransactionReceipt tx = goldToken.transfer(someAddress, oneGold).send();
String hash = tx.getTransactionHash();
To interact with cUSD, is the same but with a different contract:
StableTokenWrapper stableToken = contractKit.contracts.getStableToken();
Apart from GoldToken and StableToken, there are many core contracts.
For the moment, we have contract wrappers for:
- Accounts
- Attestations
- BlockchainParameters
- DobleSigningSlasher
- DowntimeSlasher
- Election
- Escrow
- Exchange (Uniswap kind exchange between Gold and Stable tokens)
- GasPriceMinimum
- GoldToken
- Gobernance
- LockedGold
- Reserve
- SortedOracles
- Validators
- StableToken
Celo Core Contracts addresses, can be obtained by looking at the Registry
contract.
That's actually how kit
obtain them.
We expose the registry api, which can be accessed by:
String goldTokenAddress = contractKit.contracts.addressFor(CeloContract.GoldToken);
Celo transaction object is not the same as Ethereum's. There are three new fields present:
- feeCurrency (address of the ERC20 contract to use to pay for gas and the gateway fee)
- gatewayFeeRecipient (coinbase address of the full serving the light client's trasactions)
- gatewayFee (value paid to the gateway fee recipient, denominated in the fee currency)
This means that using web3.eth.sendTransaction
or myContract.methods.transfer().send()
should be avoided.
Instead, kit
provides an utility method to send transaction in both scenarios. If you use contract wrappers, there is no need to use this.
For a raw transaction:
CeloRawTransaction tx = CeloRawTransaction.createCeloTransaction(
BigInteger.ZERO,
GAS_PRICE,
GAS_LIMIT,
someAddress,
oneGwei,
contractKit.contracts.addressFor(CeloContract.StableToken),
null,
null
);
EthSendTransaction receipt = contractKit.sendTransaction(tx);
assertNotNull(receipt.getTransactionHash());