Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit ac4b73a

Browse files
authored
[R4R] update api && example (#8)
* update bundlePrice api * add example of sending bundle with deposit coinbase * add contract/deposit.sol * update readme.md * fix typo
1 parent feb2aca commit ac4b73a

6 files changed

Lines changed: 127 additions & 13 deletions

File tree

client/client.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package client
22

33
import (
44
"context"
5-
"math/big"
65

76
"github.com/ethereum/go-ethereum/common"
87
"github.com/ethereum/go-ethereum/rpc"
@@ -43,8 +42,8 @@ func (ec *Client) SendBundle(ctx context.Context, bundle *SendBundleArgs) (commo
4342
return hash, err
4443
}
4544

46-
func (ec *Client) BundlePrice(ctx context.Context) (*big.Int, error) {
47-
var bundlePrice big.Int
45+
func (ec *Client) BundlePrice(ctx context.Context) (*BundlePrice, error) {
46+
var bundlePrice BundlePrice
4847

4948
err := ec.CallContext(ctx, &bundlePrice, "eth_bundlePrice")
5049
return &bundlePrice, err
@@ -62,4 +61,4 @@ func (ec *Client) GetStatus(ctx context.Context) (*Status, error) {
6261

6362
err := ec.CallContext(ctx, &status, "eth_validatorStatus")
6463
return &status, err
65-
}
64+
}

client/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,9 @@ type Status struct {
3030
Status int64 `json:"status"`
3131
Validators map[string]int64 `json:"validators"`
3232
}
33+
34+
// BundlePrice is the response for the API `eth_bundlePrice`
35+
type BundlePrice struct {
36+
BundlePrice *big.Int `json:"bundlePrice"`
37+
MinimalGasPrice *big.Int `json:"minimalGasPrice"`
38+
}

contract/deposit.sol

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Solidity files have to start with this pragma.
2+
// It will be used by the Solidity compiler to validate its version.
3+
pragma solidity ^0.7.3;
4+
5+
contract Deposit {
6+
/**
7+
* A function to deposit value for coinbase.
8+
*/
9+
function deposit() external payable {
10+
block.coinbase.transfer(msg.value);
11+
}
12+
}

example/abi/deposit_coinbase.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package abi
2+
3+
var DEPOSIT_COINBASE_ABI = `[{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"}]`

example/example.go

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@ import (
2020
"github.com/node-real/go-direct-route/example/utils"
2121
)
2222

23+
// Minnet endpoint
2324
var rpcEndPoint = "https://bsc-dataseed.binance.org"
24-
25-
// Testnet endpoint
26-
//var rpcEndPoint = "https://data-seed-prebsc-1-s1.binance.org:8545"
27-
2825
var directRouteEndPoint = "https://api.nodereal.io/direct-route"
2926

3027
// Testnet endpoint
31-
//var directRouteEndPoint = "https://testnet-api.nodereal.io/direct-route"
28+
// var rpcEndPoint = "https://data-seed-prebsc-1-s1.binance.org:8545"
29+
// var directRouteEndPoint = "https://testnet-api.nodereal.io/direct-route"
3230

3331
var account1, _ = utils.FromHexKey("input your private key1 here")
3432
var account2, _ = utils.FromHexKey("input your private key2 here")
@@ -40,7 +38,7 @@ func getBundlePriceDemo() {
4038
if err != nil {
4139
log.Fatal(fmt.Sprintf("failed to get bundle price %v", err))
4240
}
43-
fmt.Printf("get bundle price price %s\n", price.String())
41+
fmt.Printf("get bundle price: %s, minmal gas price: %s\n", price.BundlePrice.String(), price.MinimalGasPrice.String())
4442
}
4543

4644
func getServiceStatus() {
@@ -60,10 +58,14 @@ the two transaction should be all success or all failed.
6058
func sendBNBByBundleDemo() {
6159
directClient, _ := client.Dial(directRouteEndPoint)
6260
rpcClient, _ := ethclient.Dial(rpcEndPoint)
63-
price, err := directClient.BundlePrice(context.Background())
61+
bundlePrice, err := directClient.BundlePrice(context.Background())
6462
if err != nil {
6563
log.Fatalf("failed to get bundle price%v", err)
6664
}
65+
price := bundlePrice.BundlePrice
66+
if price.Cmp(bundlePrice.MinimalGasPrice) < 0 {
67+
price = bundlePrice.MinimalGasPrice
68+
}
6769

6870
n1, _ := rpcClient.PendingNonceAt(context.Background(), account1.Addr)
6971

@@ -125,7 +127,14 @@ we want the bundle been verified on chain during [now+20 second, now+80 second].
125127
func sendBUSDByBundleDemo() {
126128
directClient, _ := client.Dial(directRouteEndPoint)
127129
rpcClient, _ := ethclient.Dial(rpcEndPoint)
128-
price, _ := directClient.BundlePrice(context.Background())
130+
bundlePrice, err := directClient.BundlePrice(context.Background())
131+
if err != nil {
132+
log.Fatalf("failed to get bundle price%v", err)
133+
}
134+
price := bundlePrice.BundlePrice
135+
if price.Cmp(bundlePrice.MinimalGasPrice) < 0 {
136+
price = bundlePrice.MinimalGasPrice
137+
}
129138

130139
n1, _ := rpcClient.PendingNonceAt(context.Background(), account1.Addr)
131140

@@ -185,6 +194,80 @@ func sendBUSDByBundleDemo() {
185194
}
186195
}
187196

197+
func sendBNBByBundleWithDepositCoinbaseDemo() {
198+
directClient, _ := client.Dial(directRouteEndPoint)
199+
rpcClient, _ := ethclient.Dial(rpcEndPoint)
200+
bundlePrice, err := directClient.BundlePrice(context.Background())
201+
if err != nil {
202+
log.Fatalf("failed to get bundle price%v", err)
203+
}
204+
price := bundlePrice.BundlePrice
205+
if price.Cmp(bundlePrice.MinimalGasPrice) < 0 {
206+
price = bundlePrice.MinimalGasPrice
207+
}
208+
n1, _ := rpcClient.PendingNonceAt(context.Background(), account1.Addr)
209+
210+
chainId := big.NewInt(56)
211+
212+
// testnet chain id
213+
//chainId := big.NewInt(97)
214+
215+
valueToTransfer := big.NewInt(100 * params.GWei)
216+
gasLimit := uint64(70000)
217+
depositCoinbaseABI, _ := abi.JSON(strings.NewReader(eabi.DEPOSIT_COINBASE_ABI))
218+
data1, _ := depositCoinbaseABI.Pack("deposit")
219+
220+
// testnet contract addr
221+
// depositCoinbaseAddr := common.HexToAddress("0xE7febD44315508a1100E1a06701e7e0Ae5e325Bc")
222+
223+
// mainnet contract addr
224+
depositCoinbaseAddr := common.HexToAddress("0xB3BB00B9785f35D0BE13B2BD91C8e3742D9Ab03a")
225+
226+
tx1, hash1, _ := utils.SignTransaction(account1, depositCoinbaseAddr, valueToTransfer, data1, n1, gasLimit, price, chainId)
227+
tx2, hash2, _ := utils.SignTransaction(account1, account2.Addr, valueToTransfer, nil, n1+1, gasLimit, price, chainId)
228+
229+
maxTime := uint64(time.Now().Unix() + 80)
230+
231+
bundle := &client.SendBundleArgs{
232+
Txs: []string{hexutil.Encode(tx1), hexutil.Encode(tx2)},
233+
MaxBlockNumber: "",
234+
MinTimestamp: nil,
235+
MaxTimestamp: &maxTime,
236+
RevertingTxHashes: nil,
237+
}
238+
bundleHash, err := directClient.SendBundle(context.Background(), bundle)
239+
if err != nil {
240+
log.Fatalf("failed to send bundle %v", err)
241+
}
242+
fmt.Printf("successfull send bundle, hash %v\n", bundleHash)
243+
244+
queryBundle, err := directClient.GetBundleByHash(context.Background(), bundleHash)
245+
if err != nil || queryBundle == nil {
246+
log.Fatalf("failed to query bundle %v", err)
247+
}
248+
249+
bz, _ := json.Marshal(queryBundle)
250+
fmt.Printf("The bundle is %s\n", string(bz))
251+
252+
found := false
253+
for i := 0; i < 42; i++ {
254+
r1, err1 := rpcClient.TransactionReceipt(context.Background(), hash1)
255+
r2, err2 := rpcClient.TransactionReceipt(context.Background(), hash2)
256+
if r1 != nil && err1 == nil && r2 != nil && err2 == nil {
257+
found = true
258+
break
259+
}
260+
time.Sleep(3 * time.Second)
261+
}
262+
if found {
263+
fmt.Println("bundle verified on chain")
264+
} else {
265+
log.Fatalf("bundle failed to be verified on chain or timeout")
266+
}
267+
}
268+
188269
func main() {
189-
sendBNBByBundleDemo()
270+
//sendBNBByBundleDemo()
271+
//sendBUSDByBundleDemo()
272+
sendBNBByBundleWithDepositCoinbaseDemo()
190273
}

readme.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ You can try Direct-Route Testnet by changing the endpoint to: `https://testnet-a
8585

8686
Please note you should use the BSC testnet RPC and use testnet chainId(97) when sign the transaction.
8787

88+
### Deposit coinbase contract
89+
90+
If you want to increase your *Bundle Price*, you can use this contract, which will transfer your provided *BNB* to the coinbase responsible for mining your bundle.
91+
please refer the `sendBNBByBundleWithDepositCoinbaseDemo()` in example.go.
92+
93+
1. mainnet: `0xB3BB00B9785f35D0BE13B2BD91C8e3742D9Ab03a`
94+
2. testnet: `0xE7febD44315508a1100E1a06701e7e0Ae5e325Bc`
95+
8896
### SDK Example
8997

9098
We provide three demos in `example.go`:
@@ -98,6 +106,9 @@ to each other, the second transaction is allowed to be failed,
98106
and the bundle should be verified on chain during [now+20 second, now+80 second].
99107
This case shows you how to interact with smart contract through direct-route,
100108
and how to control the timing to be verified.
109+
4. `sendBNBByBundleWithDepositCoinbaseDemo()`. In this case, we use two different
110+
accounts to send BNB to each other, and including deposit BNB to coinbase to increase *Bundle Price* the two transactions should be all
111+
successful or all failed.
101112

102113
If you want to try with above examples, what you need to do is just to
103114
replace the private keys of `account1` and `account2` in `example.go`

0 commit comments

Comments
 (0)