Idempotent Proxy: proxy HTTPS Outcalls to any Web2 service

I believe there isn’t sufficient incentive for a malignant replica to steal OpenAI tokens.

If a scenario with enough incentive does arise, it can be addressed by upgrading the proxy_token mechanism, such as:

  1. Regenerating the proxy_token for each proxy service request, without caching it in the canister;
  2. Strictly limiting the resource boundaries that each proxy_token can access;
  3. Ensuring that each proxy_token can only be used once by the proxy service.

The Idempotent Proxy will play a crucial role in the CK-Doge project:

Hey @zensh,

The usage of the idempotent proxy is concerning for a project that controls user funds. Aren’t there no public RPC providers or block explorers that support IPv6?

Or are you doing on-chain light client verification of the data you are fetching via the idempotent proxy?

The currently deployed Idempotent Proxy and Dogecoin node are for local testing only. When deploying the testnet version online, IPv6 will be added to the Idempotent Proxy. For the mainnet deployment, we plan to integrate well-known, trusted public RPC providers for dual verification of the block tip.

The CK-Doge canister will also perform hash chain validation on the block data it fetchs.

Furthermore, CK-Doge could be a highly influential project. It aims to integrate Dogecoin, a cryptocurrency with a market cap of $20 billion, into the third-generation blockchain, ICP. This could bring new vitality to Dogecoin’s consensus, as Dogecoin nodes have not been updated for a long time and seem difficult to update.

But will you still be using the idempotent proxy in between the canister and these RPC providers?
This would still mean that the proxy would need to be trusted.

It doesn’t seem to validate proof of work. This would make it much harder for a malicious proxy or RPC provider to feed invalid blocks.

In the current implementation, trust in the RPC provider is indeed necessary.

The CK-Doge canister maintains tip_height and tip_blockhash. It reads the next block hash from tip_height, and then retrieves block data using the block hash.
The CK-Doge canister verifies that the block’s hash matches the expected value and that its prev_blockhash equals the hash of the previous block (tip_blockhash).

If the RPC provider gives CK-Doge canister forged block data, it would need to consistently provide forged data for continued operation. External observers can detect an attack on the CK-Doge canister by examining the tip_height and tip_blockhash.

Thus, tip_height and tip_blockhash is crucial for verifying the authenticity of the blocks. If CK-Doge canister retrieves block data from multiple RPC providers, it can validate the data by comparing the tip_blockhash from each provider.

I will continue to explore better solutions.

1 Like

hey @zensh!

congrats for the project!
I want to use it to get the BTC price in a Rust canister.
I have the following Rust code to calling to your idempotent-proxy-canister :

#[ic_cdk::update]
async fn get_btc_price_proxy() -> (Nat, String) {
    let host = "api.coingecko.com";
    let url = format!(
        "https://{}/api/v3/simple/price?ids=bitcoin&vs_currencies=usd",
        host
    );

    let request_headers = vec![HttpHeader {
        name: "accept".to_string(),
        value: "application/json".to_string(),
    }];

    let args = CanisterHttpRequestArgument {
        url,
        max_response_bytes: None,
        method: HttpMethod::GET,
        headers: request_headers,
        body: None,
        transform: None,
    };
    let res: Result<(HttpResponse,), _> = ic_cdk::call(
        Principal::from_str("hpudd-yqaaa-aaaap-ahnbq-cai").unwrap(),
        "proxy_http_request",
        (args,),
    )
    .await;
    let res = res.unwrap().0;
    let str_body = String::from_utf8(res.body).expect("Transformed response is not UTF-8 encoded.");

    (res.status, str_body)
}

but it response me the following error (logically): (403, "caller is not allowed").

so, how could I use the proxy? I imagine that I should deploy my own idempotent-proxy-canister , but what of Idempotent Proxy Cloudflare Workers? should I call yours workers?

thank you!

The core component of Idempotent Proxy is a Web2 service, which can be either the idempotent-proxy-cf-worker deployed via Cloudflare Worker or the standalone idempotent-proxy-server. Since it may contain sensitive configuration data such as API keys, it’s generally recommended to deploy your own Idempotent Proxy service.

If you’re using Idempotent Proxy in a testing environment, you can use our deployed idempotent-proxy-cf-worker, but please avoid using it in production.

To deploy your own idempotent-proxy-canister, follow these steps:

dfx canister call idempotent-proxy-canister admin_set_agents '
  (vec {
    record {
      name = "TestAgent";
      endpoint = "https://idempotent-proxy-cf-worker.zensh.workers.dev";
      max_cycles = 100000000000;
      proxy_token = null;
    };
  })
'

In the future, we plan to offer Idempotent Proxy as an IaaS service on the ICP mainnet, making it available for ICP projects without requiring developers to deploy it themselves.

1 Like

hello @zensh
I saw that this project being mentioned by the developer of offchain-proxy.
It helps in calling IPv4 apis. Does Idempoent-proxy also helps in calling IPv4 apis?

  1. The canister calls the Idempotent Proxy, so the Idempotent Proxy must provide an IPv6 access point.
  2. The Idempotent Proxy calling other Web2 services is not restricted; it can use either IPv6 or IPv4, and can use either HTTPS or HTTP.