ZaaS GRPC API
GRPC API doc for ZaaS API
Please refer to the following server configuration and proto file for the grpc API. You can use https://buf.build/ along with its plugin https://buf.build/grpc-ecosystem/gateway to generate a grpc client. Refer to https://github.com/grpc-ecosystem/grpc-gateway/tree/main/examples/internal/clients for some example code.
Download zap.proto:
syntax = "proto3";
package zap.v1;
import "buf/validate/validate.proto";
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
// Dex is the type of dex to zap into/out of. It uses different enum values from the zap contract.
enum Dex {
// Unspecified value.
DEX_UNSPECIFIED = 0;
// For UniSwap V3.
DEX_UNISWAPV3 = 2;
// For PancakeSwap V3.
DEX_PANCAKESWAPV3 = 3;
// For Uniswap V2.
DEX_UNISWAPV2 = 4;
// For SushiSwap V2.
DEX_SUSHISWAPV2 = 5;
// For Curve
DEX_CURVE = 6;
}
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
title: "Zap Service"
description: "Zap Service for quickly zapping pool liquidity in a single transaction"
version: "1.2.0"
contact: {
url: "https://discord.gg/kyberswap"
email: "bd@kyber.network"
}
}
host: "pre-zap-api.kyberengineering.io"
base_path: "/{chain}"
schemes: HTTPS
responses: {
key: "400"
value: {
description: "Invalid Argument"
schema: {
json_schema: {ref: "#/definitions/rpcStatus"}
}
examples: {
key: "application/json"
value:
'{"code":3, "message":"validation error:\\\\\\\\n'
' - pool: missing tokens [Pool.tokens]\\\\\\\\n'
' - pool.id: value does not match regex pattern `^0x[0-9A-Za-z]{40}$` [string.pattern]\\\\\\\\n'
' - position: value is required [required]\\\\\\\\n'
' - token_in[0]: value does not match regex pattern `^0x[0-9A-Za-z]{40}(,0x[0-9A-Za-z]{40})*$` [string.pattern]\\\\\\\\n'
' - amount_in[0]: value does not match regex pattern `^\\\\\\\\d+(,\\\\\\\\d+)*$` [string.pattern]\\\\\\\\n'
' - fee_address: value does not match regex pattern `^0x[0-9A-Za-z]{40}$` [string.pattern]"}'
}
}
}
responses: {
key: "404"
value: {
description: "Not Found"
schema: {
json_schema: {ref: "#/definitions/rpcStatus"}
}
examples: {
key: "application/json"
value: '{"code":5, "message":"failed to get zap routes: cannot swap tokens [0xE2035f04040A135c4dA2f96AcA742143c57c79F9]"}'
}
}
}
};
// Service allows getting and building zap routes.
service Service {
// Get the best zap-in route.
rpc GetInRoute(GetInRouteRequest) returns (GetInRouteResponse) {
option (google.api.http) = {get: "/api/v1/in/route"};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
parameters: {
headers: {
name: "X-Client-Id"
description: "Client Id"
type: STRING
}
headers: {
name: "X-Request-Id"
description: "Request Id"
type: STRING
}
}
};
}
// Decode zap-in route for debugging purposes.
rpc DecodeInRoute(DecodeInRouteRequest) returns (DecodeInRouteResponse) {
option (google.api.http) = {
post: "/api/v1/in/route/decode"
body: "*"
};
}
// Build encoded data for the specified zap-in route.
rpc BuildInRoute(BuildInRouteRequest) returns (BuildInRouteResponse) {
option (google.api.http) = {
post: "/api/v1/in/route/build"
body: "*"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
parameters: {
headers: {
name: "X-Client-Id"
description: "Client Id"
type: STRING
}
headers: {
name: "X-Request-Id"
description: "Request Id"
type: STRING
}
}
};
}
// Get the best zap-migrate route.
rpc GetMigrateRoute(GetMigrateRouteRequest) returns (GetMigrateRouteResponse) {
option (google.api.http) = {get: "/api/v1/migrate/route"};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
parameters: {
headers: {
name: "X-Client-Id"
description: "Client Id"
type: STRING
}
headers: {
name: "X-Request-Id"
description: "Request Id"
type: STRING
}
}
responses: {
key: '200'
value: {
description: "OK"
examples: {
key: 'application/json'
value: '{"code":0,"data":{}}'
}
}
}
};
}
// Decode zap-migrate route for debugging purposes.
rpc DecodeMigrateRoute(DecodeMigrateRouteRequest) returns (DecodeMigrateRouteResponse) {
option (google.api.http) = {
post: "/api/v1/migrate/route/decode"
body: "*"
};
}
// Build encoded data for the specified zap-migrate route.
rpc BuildMigrateRoute(BuildMigrateRouteRequest) returns (BuildMigrateRouteResponse) {
option (google.api.http) = {
post: "/api/v1/migrate/route/build"
body: "*"
};
}
}
// Get the best zap-in route.
message GetInRouteRequest {
// which dex to use zap with
Dex dex = 1;
// the pool to zap into
Pool pool = 2 [(buf.validate.field).required = true];
// position details
Position position = 3 [(buf.validate.field).required = true];
// which token(s) to use as zap source. also accepts comma separated addresses
repeated string tokens_in = 4 [(buf.validate.field).repeated.items.string.pattern = "^0x[0-9A-Za-z]{40}(,0x[0-9A-Za-z]{40})*$"];
// amount(s) to zap including fee, corresponding to tokenIn. also accepts comma separated amounts.
repeated string amounts_in = 5 [(buf.validate.field).repeated.items.string.pattern = "^\\d+(,\\d+)*$"];
// which token(s) to use as zap source. also accepts comma separated addresses.
// deprecated: use tokens_in. if both fields are specified, they are combined
repeated string token_in = 14 [(buf.validate.field).repeated.items.string.pattern = "^0x[0-9A-Za-z]{40}(,0x[0-9A-Za-z]{40})*$"];
// amount(s) to zap including fee, corresponding to tokenIn. also accepts comma separated amounts.
// deprecated: use amounts_in. if both fields are specified, they are combined
repeated string amount_in = 15 [(buf.validate.field).repeated.items.string.pattern = "^\\d+(,\\d+)*$"];
option (buf.validate.message).cel = {
id: "GetInRouteRequest.tokens_in"
message: "missing tokens_in"
expression: "has(this.token_in) || has(this.tokens_in)"
};
option (buf.validate.message).cel = {
id: "GetInRouteRequest.amounts_in"
message: "missing amounts_in"
expression: "has(this.amount_in) || has(this.amounts_in)"
};
// aggregator options
AggregatorOptions aggregator_options = 6;
// the address of the fee recipient.
string fee_address = 7 [(buf.validate.field) = {
string: {pattern: "^0x[0-9A-Za-z]{40}$"}
ignore: IGNORE_IF_UNPOPULATED
}];
// fee percentage in per cent mille (0.001% or 1 in 100,000). Ignored if feeAddress is empty.
// From 0 to 100,000 inclusively. Example: 1 for 0.001%.
uint32 fee_pcm = 8 [(buf.validate.field).uint32 = {
gte: 0
lte: 100000
}];
// maximum slippage tolerance in basis points (0.01%), used for aggregator (exceeding which the transaction will
// revert) and pool swap during zap (for additional zapping and for refund).
// From 0 to 10,000 inclusively. Example: 1 for 0.01%.
uint32 slippage = 9 [(buf.validate.field).uint32 = {
gte: 0
lte: 10000
}];
}
// options for getting aggregator routes
message AggregatorOptions {
// whether to disable swapping with the aggregator
bool disable = 1;
// comma-separated list of sources to use for aggregator
string included_sources = 2;
// comma-separated list of sources to exclude for aggregator
string excluded_sources = 3;
}
// Pool describes the pool to zap into.
message Pool {
// id of the pool to zap into.
string id = 1 [(buf.validate.field).string.pattern = "^0x[0-9A-Za-z]{40}$"];
}
// Position describes either an existing position or a new one.
message Position {
option (buf.validate.message).cel = {
id: "position.ticks_check"
message: "tick_lower must be less than tick_upper"
expression: "!(has(this.tick_lower) || has(this.tick_upper)) || this.tick_lower < this.tick_upper"
};
// id of the position to add liquidity to; omit to create a new uniswapV3 position. for uniswapV2 this is user address
optional string id = 1;
// min tick of the position, required if creating a new uniswapV3 position.
optional sint32 tick_lower = 2;
// max tick of the position, required if creating a new uniswapV3 position.
optional sint32 tick_upper = 3;
}
// Returns the best route to zap-in to the specified pool position.
message GetInRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
PoolDetails pool_details = 1;
PositionDetails position_details = 2;
// zap details
ZapDetails zap_details = 3;
// the zap route to pass to build API to get call-data
bytes route = 4;
// the router address to check approval amount
string router_address = 5;
// rough estimate of gas required for the transaction
string gas = 6;
// USD value of estimated gas required
string gas_usd = 7;
}
}
// details of the pool
message PoolDetails {
string category = 1;
oneof pool {
UniswapV3 uniswap_v3 = 8;
UniswapV2 uniswap_v2 = 9;
}
// details of the uniswapV3 pool
message UniswapV3 {
// pool tick before zap
optional sint32 tick = 1;
// pool tick after zap
optional sint32 new_tick = 2;
// pool sqrt price (times 2^96) before zap
optional string sqrt_p = 3;
// pool sqrt price (times 2^96) after zap
optional string new_sqrt_p = 4;
}
// details of the uniswapV2 pool
message UniswapV2 {
// reserve0 before zap
optional string reserve0 = 1;
// reserve0 after zap
optional string new_reserve0 = 2;
// reserve1 before zap
optional string reserve1 = 3;
// reserve1 after zap
optional string new_reserve1 = 4;
}
}
// details of the new position state
message PositionDetails {
// how much position liquidity to be removed
string removed_liquidity = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field).pattern = "\\d+"];
// total USD value of the position to be removed
string removed_amount_usd = 2;
// how much position liquidity to be added
string added_liquidity = 3 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field).pattern = "\\d+"];
// total USD value of the position to be added
string added_amount_usd = 4;
}
// details of the zap
message ZapDetails {
// USD value of the source zap token amount
string initial_amount_usd = 1;
// list of zap actions
repeated Action actions = 2;
// one of the zap actions, specified by the type field
message Action {
ActionType type = 1;
oneof action {
FeeAction protocol_fee = 2;
FeeAction partner_fee = 3;
SwapAction aggregator_swap = 4;
SwapAction pool_swap = 5;
LiquidityAction add_liquidity = 6;
LiquidityAction remove_liquidity = 7;
RefundAction refund = 8;
}
}
// type of the zap action
enum ActionType {
// Unspecified action
ACTION_TYPE_UNSPECIFIED = 0;
// protocol fee
ACTION_TYPE_PROTOCOL_FEE = 1;
// partner fee
ACTION_TYPE_PARTNER_FEE = 2;
// aggregator swap
ACTION_TYPE_AGGREGATOR_SWAP = 3;
// pool swap
ACTION_TYPE_POOL_SWAP = 4;
// add liquidity
ACTION_TYPE_ADD_LIQUIDITY = 5;
// remove liquidity
ACTION_TYPE_REMOVE_LIQUIDITY = 6;
// refund
ACTION_TYPE_REFUND = 7;
}
// fee collection
message FeeAction {
// fee per cent mille (0.001%) of the source zap amount
uint32 pcm = 1;
// token amounts
repeated TokenAmount tokens = 2;
}
// token swap, either with aggregator or with pool
message SwapAction {
repeated Swap swaps = 1;
// a single swap
message Swap {
// swapped token amount
TokenAmount token_in = 1;
// returned token amount
TokenAmount token_out = 2;
}
}
// added or removed liquidity
message LiquidityAction {
// added or removed token amounts
repeated TokenAmount tokens = 1;
// collected fees
repeated TokenAmount fees = 2;
// added or removed token 0 amount. deprecated: use tokens
TokenAmount token0 = 3;
// added or removed token 1 amount. deprecated: use tokens
TokenAmount token1 = 4;
}
// refund left-over tokens to user
message RefundAction {
// refunded token amounts
repeated TokenAmount tokens = 1 [(buf.validate.field).repeated.items.required = true];
}
// token address and amount in wei and in usd
message TokenAmount {
// token address
string address = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field).pattern = "^0x[0-9A-Za-z]{40}$"];
// wei amount of the token
string amount = 2;
// USD value of the token
string amount_usd = 3;
}
// USD value of the final amount including the added position and the left-over amount
string final_amount_usd = 3;
// price impact after zapping of final amount against initial amount
optional float price_impact = 4;
}
// Decode zap-in route for debugging purposes.
message DecodeInRouteRequest {
// the route as returned from get-route endpoint.
bytes route = 1;
}
// Returns the zap-in route details.
message DecodeInRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
// JSON encode of the zap in route.
string json = 1;
}
}
// Build encoded data for zap-in transaction from the specified route.
message BuildInRouteRequest {
// the wallet sending the transaction, and thus, the tokens.
string sender = 1 [(buf.validate.field).string.pattern = "^0x[0-9A-Za-z]{40}$"];
// the wallet receiving the new position. default to sender if empty.
string recipient = 2 [(buf.validate.field) = {
string: {pattern: "^0x[0-9A-Za-z]{40}$"}
ignore: IGNORE_IF_UNPOPULATED
}];
// the route as returned from get-route endpoint.
bytes route = 3;
// deadline for the swap transaction to execute.
fixed32 deadline = 4 [(buf.validate.field).cel = {
id: "deadline.gte_now"
message: "deadline must be in the future"
expression: "this == 0u || this > int(now)"
}];
// the source of the zap-in transaction.
string source = 5;
// map of each token address to its ERC20 permit using EIP-2612 to skip a separate approval step.
map<string, string> permits = 6 [
(buf.validate.field).map.keys.string.pattern = "^0x[0-9A-Za-z]{40}$",
(buf.validate.field).map.values.string.pattern = "^0x[0-9A-Za-z]{448}$"
];
}
// Returns the zap-in transaction details.
message BuildInRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
// zap router address to send the zap-in transaction to
string router_address = 1;
// call data for the zap-in transaction
string call_data = 2;
// native token value to transfer with the zap-in transaction in case of zapping with native tokens
string value = 3;
}
}
// Get the best zap-migrate route.
message GetMigrateRouteRequest {
// which dex to zap migrate out from
Dex dex_from = 10;
// which dex to zap migrate in to
Dex dex_to = 1;
// the pool to zap into
Pool pool_from = 11 [(buf.validate.field).required = true];
// the pool to zap into
Pool pool_to = 2 [(buf.validate.field).required = true];
// old position details
Position position_from = 12 [
(buf.validate.field).required = true,
(buf.validate.field).cel = {
id: "position_from.has_id"
message: "position_from must provide an existing nft id"
expression: "has(this.id)"
}
];
// new position details
Position position_to = 3 [(buf.validate.field).required = true];
// liquidity amount to withdraw, or empty or 0 to withdraw all
string liquidity_out = 4 [(buf.validate.field).string.pattern = "^\\d*$"];
// aggregator options
AggregatorOptions aggregator_options = 6;
// options for getting aggregator routes
// the address of the fee recipient.
string fee_address = 7 [(buf.validate.field) = {
string: {pattern: "^0x[0-9A-Za-z]{40}$"}
ignore: IGNORE_IF_UNPOPULATED
}];
// fee percentage in per cent mille (0.001% or 1 in 100,000). Ignored if feeAddress is empty.
// From 0 to 100,000 inclusively. Example: 1 for 0.001%.
uint32 fee_pcm = 8 [(buf.validate.field).uint32 = {
gte: 0
lte: 100000
}];
// maximum slippage tolerance in basis points (0.01%), used for aggregator (exceeding which the transaction will
// revert) and pool swap during zap (for additional zapping and for refund).
// From 0 to 10,000 inclusively. Example: 1 for 0.01%.
uint32 slippage = 9 [(buf.validate.field).uint32 = {
gte: 0
lte: 10000
}];
}
// Returns the best route to zap-migrate from an existing position to the specified pool position.
message GetMigrateRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
PoolDetails pool_details = 1;
PositionDetails position_details = 2;
// zap details
ZapDetails zap_details = 3;
// the zap route to pass to build API to get call-data
bytes route = 4;
// the router address to check approval amount
string router_address = 5;
// rough estimate of gas required for the transaction
string gas = 6;
// USD value of estimated gas required
string gas_usd = 7;
}
}
// Decode zap-migrate route for debugging purposes.
message DecodeMigrateRouteRequest {
// the route as returned from get-route endpoint.
bytes route = 1;
}
// Returns the zap-migrate route details.
message DecodeMigrateRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
// JSON encode of the zap in route.
string json = 1;
}
}
// Build encoded data for zap-migrate transaction from the specified route.
message BuildMigrateRouteRequest {
// the wallet sending the transaction, and thus, the tokens.
string sender = 1 [(buf.validate.field).string.pattern = "^0x[0-9A-Za-z]{40}$"];
// the wallet receiving the new position. default to sender if empty.
string recipient = 2 [(buf.validate.field) = {
string: {pattern: "^0x[0-9A-Za-z]{40}$"}
ignore: IGNORE_IF_UNPOPULATED
}];
// the route as returned from get-route endpoint.
bytes route = 3;
// deadline for the swap transaction to execute.
fixed32 deadline = 4 [(buf.validate.field).cel = {
id: "deadline.gte_now"
message: "deadline must be in the future"
expression: "this == 0u || this > int(now)"
}];
// the source of the zap-migrate transaction.
string source = 5;
// whether to throw away the position NFT or keep it.
bool burn_nft = 6;
}
// Returns the zap-migrate transaction details.
message BuildMigrateRouteResponse {
// grpc error code
int32 code = 1;
// grpc error message
string message = 2;
// response data
Data data = 3;
// request trace id
string request_id = 4;
// Encompasses returned data.
message Data {
// zap router address to send the zap-migrate transaction to
string router_address = 1;
// call data for the zap-migrate transaction
string call_data = 2;
// native token value to transfer with the zap-migrate transaction in case of zapping with native tokens
string value = 3;
}
}
Last updated