Skip to content

Commit

Permalink
feat: implement zks_getTokenPrice endpoint (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
MexicanAce authored Aug 11, 2023
1 parent d55dafc commit c860c9b
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 22 deletions.
109 changes: 89 additions & 20 deletions SUPPORTED_APIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@
| `ETH` | `eth_uninstallFilter` | NOT IMPLEMENTED | Uninstalls a filter with given id |
| `ETH` | `eth_accounts` | NOT IMPLEMENTED | Returns a list of addresses owned by client |
| `ETH` | `eth_unsubscribe` | NOT IMPLEMENTED | Cancel a subscription to a particular event |
| [`ZKS`](#zks-namespace) | [`zks_estimateFee`](#zks_estimateFee) | SUPPORTED | Gets the Fee estimation data for a given Request |
| [`ZKS`](#zks-namespace) | [`zks_getTokenPrice`](#zks_getTokenPrice) | SUPPORTED | Gets the USD price of a token |

## Key

Expand Down Expand Up @@ -176,7 +178,7 @@ curl --request POST \

### `net_version`

[source](src/network_api.rs)
[source](src/net.rs)

Returns the current network id

Expand All @@ -199,7 +201,7 @@ curl --request POST \

### `net_peerCount`

[source](src/network_api.rs)
[source](src/net.rs)

Returns the number of connected peers

Expand All @@ -222,7 +224,7 @@ curl --request POST \

### `net_listening`

[source](src/network_api.rs)
[source](src/net.rs)

Returns `true` if the node is listening for connections

Expand All @@ -247,7 +249,7 @@ curl --request POST \

### `eth_chainId`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the current chain id

Expand All @@ -270,7 +272,7 @@ curl --request POST \

### `eth_estimateGas`

[source](src/eth_api.rs)
[source](src/node.rs)

Generates and returns an estimate of how much gas is necessary to allow the transaction to complete

Expand All @@ -280,7 +282,7 @@ Generates and returns an estimate of how much gas is necessary to allow the tran

#### Status

`PARTIALLY`
`SUPPORTED`

#### Example

Expand All @@ -290,17 +292,23 @@ curl --request POST \
--header 'content-type: application/json' \
--data '{
"jsonrpc": "2.0",
"id": "1",
"method": "eth_estimateGas",
"params": [{
"0x0000000000000000000000000000000000000000": true
}]
"id": "2",
"method": "eth_estimateGas",
"params": [{
"to": "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
"data": "0x0000",
"from": "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
"gas": "0x0000",
"gasPrice": "0x0000",
"value": "0x0000",
"nonce": "0x0000"
}, "latest"]
}'
```

### `eth_gasPrice`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the current price per gas in wei

Expand All @@ -323,7 +331,7 @@ curl --request POST \

### `eth_getBalance`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the balance of the account of given address

Expand Down Expand Up @@ -353,7 +361,7 @@ curl --request POST \

### `eth_getBlockByNumber`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns information about a block by block number

Expand Down Expand Up @@ -383,7 +391,7 @@ curl --request POST \

### `eth_getCode`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns code at a given address

Expand Down Expand Up @@ -413,7 +421,7 @@ curl --request POST \

### `eth_getTransactionByHash`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the information about a transaction requested by transaction hash

Expand Down Expand Up @@ -441,7 +449,7 @@ curl --request POST \

### `eth_getTransactionCount`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the number of transactions sent from an address

Expand Down Expand Up @@ -471,7 +479,7 @@ curl --request POST \

### `eth_blockNumber`

[source](src/eth_api.rs)
[source](src/node.rs)

Returns the number of most recent block

Expand All @@ -494,7 +502,7 @@ curl --request POST \

### `eth_call`

[source](src/eth_api.rs)
[source](src/node.rs)

Executes a new message call immediately without creating a transaction on the block chain

Expand Down Expand Up @@ -532,7 +540,7 @@ curl --request POST \

### `eth_sendRawTransaction`

[source](src/eth_api.rs)
[source](src/node.rs)

Creates new message call transaction or a contract creation for signed transactions

Expand All @@ -553,3 +561,64 @@ curl --request POST \
--data '{"jsonrpc": "2.0","id": "1","method": "eth_sendRawTransaction","params": ["0x0000"]
}'
```

## `ZKS NAMESPACE`

### `zks_estimateFee`

[source](src/zks.rs)

Generates and returns an estimate of how much gas is necessary to allow the transaction to complete

#### Arguments

+ `transaction: Transaction`

#### Status

`SUPPORTED`

#### Example

```bash
curl --request POST \
--url http://localhost:8011/ \
--header 'content-type: application/json' \
--data '{
"jsonrpc": "2.0",
"id": "2",
"method": "zks_estimateFee",
"params": [{
"to": "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
"data": "0x0000",
"from": "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
"gas": "0x0000",
"gasPrice": "0x0000",
"value": "0x0000",
"nonce": "0x0000"
}]
}'
```

### `zks_getTokenPrice`

[source](src/zks.rs)

Returns the token price given an Address

#### Arguments

+ `address: Address`

#### Status

`SUPPORTED`

#### Example

```bash
curl --request POST \
--url http://localhost:8011/ \
--header 'content-type: application/json' \
--data '{"jsonrpc": "2.0","id": "1","method": "zks_getTokenPrice","params": ["0x0000000000000000000000000000000000000000"]}'
```
86 changes: 84 additions & 2 deletions src/zks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use zksync_types::{api::BridgeAddresses, fee::Fee};
use zksync_web3_decl::error::Web3Error;

use crate::{node::InMemoryNodeInner, utils::IntoBoxedFuture};
use colored::Colorize;

/// Mock implementation of ZksNamespace - used only in the test node.
pub struct ZkMockNamespaceImpl {
Expand Down Expand Up @@ -104,9 +105,39 @@ impl ZksNamespaceT for ZkMockNamespaceImpl {

fn get_token_price(
&self,
_token_address: zksync_basic_types::Address,
token_address: zksync_basic_types::Address,
) -> jsonrpc_core::BoxFuture<jsonrpc_core::Result<BigDecimal>> {
not_implemented!()
match format!("{:?}", token_address).to_lowercase().as_str() {
"0x0000000000000000000000000000000000000000" => {
// ETH
Ok(1_500.into()).into_boxed_future()
}
"0x40609141db628beee3bfab8034fc2d8278d0cc78" => {
// LINK
Ok(1.into()).into_boxed_future()
}
"0x0bfce1d53451b4a8175dd94e6e029f7d8a701e9c" => {
// wBTC
Ok(1.into()).into_boxed_future()
}
"0x0faf6df7054946141266420b43783387a78d82a9" => {
// USDC
Ok(1.into()).into_boxed_future()
}
"0x3e7676937a7e96cfb7616f255b9ad9ff47363d4b" => {
// DAI
Ok(1.into()).into_boxed_future()
}
address => {
println!(
"{}",
format!("Token price requested for unknown address {:?}", address)
.to_string()
.red()
);
futures::future::err(into_jsrpc_error(Web3Error::InternalError)).boxed()
}
}
}

fn get_all_account_balances(
Expand Down Expand Up @@ -202,9 +233,12 @@ impl ZksNamespaceT for ZkMockNamespaceImpl {

#[cfg(test)]
mod tests {
use std::str::FromStr;

use crate::node::InMemoryNode;

use super::*;
use zksync_basic_types::Address;
use zksync_types::transaction_request::CallRequest;

#[tokio::test]
Expand Down Expand Up @@ -242,4 +276,52 @@ mod tests {
assert_eq!(result.max_priority_fee_per_gas, U256::from(0));
assert_eq!(result.gas_per_pubdata_limit, U256::from(4080));
}

#[tokio::test]
async fn test_get_token_price_given_eth_should_return_price() {
// Arrange
let node = InMemoryNode::new(None, crate::ShowCalls::None, false, false);
let namespace = ZkMockNamespaceImpl::new(node.get_inner());

let mock_address = Address::from_str("0x0000000000000000000000000000000000000000")
.expect("Failed to parse address");

// Act
let result = namespace.get_token_price(mock_address).await.unwrap();

// Assert
assert_eq!(result, BigDecimal::from(1_500));
}

#[tokio::test]
async fn test_get_token_price_given_capitalized_link_address_should_return_price() {
// Arrange
let node = InMemoryNode::new(None, crate::ShowCalls::None, false, false);
let namespace = ZkMockNamespaceImpl::new(node.get_inner());

let mock_address = Address::from_str("0x40609141Db628BeEE3BfAB8034Fc2D8278D0Cc78")
.expect("Failed to parse address");

// Act
let result = namespace.get_token_price(mock_address).await.unwrap();

// Assert
assert_eq!(result, BigDecimal::from(1));
}

#[tokio::test]
async fn test_get_token_price_given_unknown_address_should_return_error() {
// Arrange
let node = InMemoryNode::new(None, crate::ShowCalls::None, false, false);
let namespace = ZkMockNamespaceImpl::new(node.get_inner());

let mock_address = Address::from_str("0x0000000000000000000000000000000000000042")
.expect("Failed to parse address");

// Act
let result = namespace.get_token_price(mock_address).await;

// Assert
assert!(result.is_err());
}
}
11 changes: 11 additions & 0 deletions test_endpoints.http
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,15 @@ content-type: application/json
"value": "0x0000",
"nonce": "0x0000"
}, "latest"]
}

###
POST http://localhost:8011
content-type: application/json

{
"jsonrpc": "2.0",
"id": "1",
"method": "zks_getTokenPrice",
"params": ["0x0000000000000000000000000000000000000000"]
}

0 comments on commit c860c9b

Please sign in to comment.