Skip to content

Commit

Permalink
feat: ekoke canister http endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso committed Feb 17, 2024
1 parent a8a63da commit 3d4b7f1
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 9 deletions.
13 changes: 13 additions & 0 deletions src/declarations/deferred/deferred.did.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ export type GenericValue = { 'Nat64Content' : bigint } |
{ 'NestedContent' : Vec } |
{ 'Principal' : Principal } |
{ 'TextContent' : string };
export interface HttpRequest {
'url' : string,
'method' : string,
'body' : Uint8Array | number[],
'headers' : Array<[string, string]>,
}
export interface HttpResponse {
'body' : Uint8Array | number[],
'headers' : Array<[string, string]>,
'upgrade' : [] | [boolean],
'status_code' : number,
}
export interface Metadata {
'logo' : [] | [string],
'name' : [] | [string],
Expand Down Expand Up @@ -290,6 +302,7 @@ export interface _SERVICE {
'get_contract' : ActorMethod<[bigint], [] | [Contract]>,
'get_signed_contracts' : ActorMethod<[], Array<bigint>>,
'get_token' : ActorMethod<[bigint], [] | [TokenInfo]>,
'http_request' : ActorMethod<[HttpRequest], HttpResponse>,
'is_approved_for_all' : ActorMethod<[Principal, Principal], Result_2>,
'logo' : ActorMethod<[], [] | [string]>,
'metadata' : ActorMethod<[], Metadata>,
Expand Down
13 changes: 13 additions & 0 deletions src/declarations/deferred/deferred.did.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,18 @@ export const idlFactory = ({ IDL }) => {
'minted_by' : IDL.Principal,
});
const TokenInfo = IDL.Record({ 'token' : Token, 'contract' : Contract });
const HttpRequest = IDL.Record({
'url' : IDL.Text,
'method' : IDL.Text,
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
});
const HttpResponse = IDL.Record({
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
'upgrade' : IDL.Opt(IDL.Bool),
'status_code' : IDL.Nat16,
});
const Result_2 = IDL.Variant({ 'Ok' : IDL.Bool, 'Err' : NftError });
const Metadata = IDL.Record({
'logo' : IDL.Opt(IDL.Text),
Expand Down Expand Up @@ -334,6 +346,7 @@ export const idlFactory = ({ IDL }) => {
'get_contract' : IDL.Func([IDL.Nat], [IDL.Opt(Contract)], ['query']),
'get_signed_contracts' : IDL.Func([], [IDL.Vec(IDL.Nat)], ['query']),
'get_token' : IDL.Func([IDL.Nat], [IDL.Opt(TokenInfo)], ['query']),
'http_request' : IDL.Func([HttpRequest], [HttpResponse], ['query']),
'is_approved_for_all' : IDL.Func(
[IDL.Principal, IDL.Principal],
[Result_2],
Expand Down
17 changes: 15 additions & 2 deletions src/declarations/ekoke/ekoke.did.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,19 @@ export type EthNetwork = { 'Ethereum' : null } |
{ 'Goerli' : null } |
{ 'Sepolia' : null };
export interface HttpHeader { 'value' : string, 'name' : string }
export interface HttpRequest {
'url' : string,
'method' : string,
'body' : Uint8Array | number[],
'headers' : Array<[string, string]>,
}
export interface HttpResponse {
'body' : Uint8Array | number[],
'headers' : Array<[string, string]>,
'upgrade' : [] | [boolean],
'status_code' : number,
}
export interface HttpResponse_1 {
'status' : bigint,
'body' : Uint8Array | number[],
'headers' : Array<HttpHeader>,
Expand Down Expand Up @@ -170,7 +182,7 @@ export type TransferFromError = {
{ 'InsufficientFunds' : { 'balance' : bigint } };
export interface TransformArgs {
'context' : Uint8Array | number[],
'response' : HttpResponse,
'response' : HttpResponse_1,
}
export interface _SERVICE {
'admin_burn' : ActorMethod<[bigint], Result>,
Expand All @@ -193,7 +205,8 @@ export interface _SERVICE {
'erc20_swap_fee' : ActorMethod<[], Result_2>,
'get_contract_reward' : ActorMethod<[bigint, bigint], Result_3>,
'get_transaction' : ActorMethod<[bigint], Result_4>,
'http_transform_send_tx' : ActorMethod<[TransformArgs], HttpResponse>,
'http_request' : ActorMethod<[HttpRequest], HttpResponse>,
'http_transform_send_tx' : ActorMethod<[TransformArgs], HttpResponse_1>,
'icrc1_balance_of' : ActorMethod<[Account], bigint>,
'icrc1_decimals' : ActorMethod<[], number>,
'icrc1_fee' : ActorMethod<[], bigint>,
Expand Down
19 changes: 16 additions & 3 deletions src/declarations/ekoke/ekoke.did.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,27 @@ export const idlFactory = ({ IDL }) => {
'amount' : IDL.Nat,
});
const Result_4 = IDL.Variant({ 'Ok' : Transaction, 'Err' : EkokeError });
const HttpHeader = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
const HttpRequest = IDL.Record({
'url' : IDL.Text,
'method' : IDL.Text,
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
});
const HttpResponse = IDL.Record({
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(IDL.Tuple(IDL.Text, IDL.Text)),
'upgrade' : IDL.Opt(IDL.Bool),
'status_code' : IDL.Nat16,
});
const HttpHeader = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
const HttpResponse_1 = IDL.Record({
'status' : IDL.Nat,
'body' : IDL.Vec(IDL.Nat8),
'headers' : IDL.Vec(HttpHeader),
});
const TransformArgs = IDL.Record({
'context' : IDL.Vec(IDL.Nat8),
'response' : HttpResponse,
'response' : HttpResponse_1,
});
const MetadataValue = IDL.Variant({
'Int' : IDL.Int,
Expand Down Expand Up @@ -223,9 +235,10 @@ export const idlFactory = ({ IDL }) => {
'erc20_swap_fee' : IDL.Func([], [Result_2], []),
'get_contract_reward' : IDL.Func([IDL.Nat, IDL.Nat64], [Result_3], []),
'get_transaction' : IDL.Func([IDL.Nat64], [Result_4], ['query']),
'http_request' : IDL.Func([HttpRequest], [HttpResponse], ['query']),
'http_transform_send_tx' : IDL.Func(
[TransformArgs],
[HttpResponse],
[HttpResponse_1],
['query'],
),
'icrc1_balance_of' : IDL.Func([Account], [IDL.Nat], ['query']),
Expand Down
13 changes: 13 additions & 0 deletions src/deferred/deferred.did
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ type GenericValue = variant {
Principal : principal;
TextContent : text;
};
type HttpRequest = record {
url : text;
method : text;
body : vec nat8;
headers : vec record { text; text };
};
type HttpResponse = record {
body : vec nat8;
headers : vec record { text; text };
upgrade : opt bool;
status_code : nat16;
};
type Metadata = record {
logo : opt text;
name : opt text;
Expand Down Expand Up @@ -289,6 +301,7 @@ service : (DeferredInitData) -> {
get_contract : (nat) -> (opt Contract) query;
get_signed_contracts : () -> (vec nat) query;
get_token : (nat) -> (opt TokenInfo) query;
http_request : (HttpRequest) -> (HttpResponse) query;
is_approved_for_all : (principal, principal) -> (Result_2);
logo : () -> (opt text) query;
metadata : () -> (Metadata) query;
Expand Down
5 changes: 3 additions & 2 deletions src/did/src/ekoke/liquidity_pool.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use candid::{CandidType, Deserialize, Nat};
use icrc::icrc1::account::Account;
use serde::Serialize;

/// The accounts that hold the liquidity pools for the CKBTC and ICP tokens.
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize, Serialize)]
pub struct LiquidityPoolAccounts {
/// The account that holds the pool for the CKBTC token.
pub ckbtc: Account,
Expand All @@ -11,7 +12,7 @@ pub struct LiquidityPoolAccounts {
}

/// The balance of the liquidity pool
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize, Serialize)]
pub struct LiquidityPoolBalance {
/// CKBTC tokens hold in the liquidity pool
pub ckbtc: Nat,
Expand Down
17 changes: 15 additions & 2 deletions src/ekoke/ekoke.did
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,19 @@ type EkokeInitData = record {
};
type EthNetwork = variant { Ethereum; Goerli; Sepolia };
type HttpHeader = record { value : text; name : text };
type HttpRequest = record {
url : text;
method : text;
body : vec nat8;
headers : vec record { text; text };
};
type HttpResponse = record {
body : vec nat8;
headers : vec record { text; text };
upgrade : opt bool;
status_code : nat16;
};
type HttpResponse_1 = record {
status : nat;
body : vec nat8;
headers : vec HttpHeader;
Expand Down Expand Up @@ -152,7 +164,7 @@ type TransferFromError = variant {
TooOld;
InsufficientFunds : record { balance : nat };
};
type TransformArgs = record { context : vec nat8; response : HttpResponse };
type TransformArgs = record { context : vec nat8; response : HttpResponse_1 };
service : (EkokeInitData) -> {
admin_burn : (nat) -> (Result);
admin_cycles : () -> (nat) query;
Expand All @@ -171,7 +183,8 @@ service : (EkokeInitData) -> {
erc20_swap_fee : () -> (Result_2);
get_contract_reward : (nat, nat64) -> (Result_3);
get_transaction : (nat64) -> (Result_4) query;
http_transform_send_tx : (TransformArgs) -> (HttpResponse) query;
http_request : (HttpRequest) -> (HttpResponse) query;
http_transform_send_tx : (TransformArgs) -> (HttpResponse_1) query;
icrc1_balance_of : (Account) -> (nat) query;
icrc1_decimals : () -> (nat8) query;
icrc1_fee : () -> (nat) query;
Expand Down
50 changes: 50 additions & 0 deletions src/ekoke/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use did::{HttpRequest, HttpResponse};

use crate::app::EkokeCanister;

pub struct HttpApi;

impl HttpApi {
/// Handles an HTTP request
pub async fn handle_http_request(req: HttpRequest) -> HttpResponse {
// must be a GET request
if req.method != "GET" {
return HttpResponse::bad_request("expected GET method".to_string());
}
// Must be a JSON-RPC request
if req.headers.get("content-type").map(|s| s.as_ref()) != Some("application/json") {
return HttpResponse::bad_request(
"expected content-type: application/json".to_string(),
);
}
let method = match req.decode_method() {
Ok(request) => request,
Err(response) => return response,
};

match method.as_str() {
"liquidityPoolBalance" => Self::liquidity_pool_balance().await,
"liquidityPoolAccounts" => Self::liquidity_pool_accounts(),
_ => HttpResponse::bad_request("unknown method".to_string()),
}
}

async fn liquidity_pool_balance() -> HttpResponse {
let response = match EkokeCanister::liquidity_pool_balance().await {
Ok(response) => response,
Err(_) => {
return HttpResponse::internal_error(
"failed to get liquidity pool balance".to_string(),
)
}
};

HttpResponse::ok(response)
}

fn liquidity_pool_accounts() -> HttpResponse {
let params = EkokeCanister::liquidity_pool_accounts();

HttpResponse::ok(params)
}
}
8 changes: 8 additions & 0 deletions src/ekoke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
mod abi;
mod app;
mod constants;
mod http;
mod inspect;
mod utils;

Expand Down Expand Up @@ -254,6 +255,13 @@ fn http_transform_send_tx(raw: TransformArgs) -> HttpResponse {
raw.response
}

// HTTP endpoint
#[query]
#[candid_method(query)]
pub async fn http_request(req: did::HttpRequest) -> did::HttpResponse {
http::HttpApi::handle_http_request(req).await
}

#[allow(dead_code)]
fn main() {
// The line below generates did types and service definition from the
Expand Down

0 comments on commit 3d4b7f1

Please sign in to comment.