Skip to content

Commit

Permalink
vue3
Browse files Browse the repository at this point in the history
Signed-off-by: Dominic Woerner <[email protected]>
  • Loading branch information
Dominic Woerner committed Nov 8, 2022
1 parent aff45fb commit 97c9e97
Show file tree
Hide file tree
Showing 57 changed files with 35,557 additions and 7,921 deletions.
1,880 changes: 1,880 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
[workspace]
members = [
"src/proxy_manager",
"src/eth_proxy_backend",
"src/eth_proxy_shared",
]
48 changes: 22 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
# eth_proxy
# MetaMask Proxy Canister PoC

Welcome to your new eth_proxy project and to the internet computer development community. By default, creating a new project adds this README and some template files to your project directory. You can edit these template files to customize your project and to include your own code to speed up the development cycle.
This Proof of Concept shows how MetaMask could be used on the Internet Computer, by using a proxy canister that acts as a personal JSON RPC Provider.
The proxy can be used to translate certain EVM contract calls to calls on the Internet Computer. This demo aims to implement this for DIP20 contract calls.

To get started, you might want to explore the project directory structure and the default configuration file. Working with this project in your development environment will not affect any production deployment or identity tokens.
## Architecture

To learn more before you start working with eth_proxy, see the following documentation available online:
![Architecture](./assets/metamask_ic_proxy_demo.svg)

- [Quick Start](https://smartcontracts.org/docs/quickstart/quickstart-intro.html)
- [SDK Developer Tools](https://smartcontracts.org/docs/developers-guide/sdk-guide.html)
- [Rust Canister Devlopment Guide](https://smartcontracts.org/docs/rust-guide/rust-intro.html)
- [ic-cdk](https://docs.rs/ic-cdk)
- [ic-cdk-macros](https://docs.rs/ic-cdk-macros)
- [Candid Introduction](https://smartcontracts.org/docs/candid-guide/candid-intro.html)
- [JavaScript API Reference](https://erxue-5aaaa-aaaab-qaagq-cai.raw.ic0.app)
## Demo Flow

If you want to start working on your project right away, you might want to try the following commands:

```bash
cd eth_proxy/
dfx help
dfx canister --help
```

## Running the project locally
## Status and To Dos

If you want to test your project locally, you can use the following commands:
[x] Proxy canister as MetaMask JSON RPC Provider
[x] Fake ERC20 related calls in proxy canister, in particular `transfer`
[ ] Proxy manager canister that is able to create a proxy canister for an Ethereum address dynamically

```bash
# Starts the replica, running in the background
dfx start --background

# Deploys your canisters to the replica and generates your candid interface
dfx deploy
```
## Issues


### Mapping from Ethereum addresses to principals

### Authentication of calls

All calls to the proxy canister are made using the anonymous identity, i.e. are unauthenticated. This is not a super big issue, since the actual transactions are signed and can be verified inside the proxy canister.
However, there are still some update calls, that are a bit problematic, i.e. RPC calls to get the current block number or the current transaction count. MetaMask seems to keep track of the current block height and makes frequent calls to the RPC provider to get the latest block height. If we don't increase our fake block height MetaMask won't do any other calls. In our current naive implementation, we just increase the block height by one every time this request is made. We do the same for the transaction count request, which determines the nonce MetaMask uses when creating a transaction. Ideally, these calls should only be allowed by the owner. A quick fix would be to introduce an API key that is added as a query parameter.

### Usage of the raw domain


Once the job completes, your application will be available at `http://localhost:4943?canisterId={asset_canister_id}`.
16 changes: 16 additions & 0 deletions assets/metamask_ic_proxy_demo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions canister_ids.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"eth_proxy_backend": {
"ic": "zyij3-ryaaa-aaaak-qaxpa-cai"
},
"eth_proxy_frontend": {
"ic": "dyqlv-5qaaa-aaaap-qatea-cai"
},
"eth_proxy_shared": {
"ic": "ezw7y-fqaaa-aaaap-qatua-cai"
},
"swap_frontend": {
"ic": "bzj7m-zyaaa-aaaap-qatjq-cai"
}
}
41 changes: 36 additions & 5 deletions dfx.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,51 @@
{
"canisters": {
"ledger": {
"type": "custom",
"wasm": "ledger.wasm",
"candid": "ledger.public.did",
"remote": {
"candid": "ledger.public.did",
"id": {
"ic": "ryjl3-tyaaa-aaaaa-aaaba-cai"
}
}
},
"proxy_manager": {
"candid": "src/proxy_manager/proxy_manager.did",
"package": "proxy_manager",
"type": "rust"
},
"eth_proxy_backend": {
"candid": "src/eth_proxy_backend/eth_proxy_backend.did",
"package": "eth_proxy_backend",
"type": "rust"
},
"eth_proxy_frontend": {
"eth_proxy_shared": {
"candid": "src/eth_proxy_shared/eth_proxy_shared.did",
"package": "eth_proxy_shared",
"type": "rust"
},
"frontend": {
"dependencies": [
"eth_proxy_backend"
"eth_proxy_shared"
],
"frontend": {
"entrypoint": "src/eth_proxy_frontend/src/index.html"
"entrypoint": "dist/index.html"
},
"source": [
"src/eth_proxy_frontend/assets",
"dist/eth_proxy_frontend/"
"dist/"
],
"type": "assets"
},
"swap_backend": {
"candid": "src/swap_backend/swap_backend.did",
"package": "swap_backend",
"type": "rust"
},
"swap_frontend": {
"source": [
"src/swap_frontend/dist/"
],
"type": "assets"
}
Expand Down
22 changes: 22 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/frontend/assets/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
<script type="module">
/**
* @dfinity/agent requires this. Can be removed once it's fixed
*/
import { Buffer } from "buffer"

window.global = window
window.Buffer = Buffer
</script>
<script type="module" src="/src/frontend/main.js"></script>
</body>
</html>
103 changes: 103 additions & 0 deletions ledger.private.did
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
type Tokens = record {
e8s : nat64;
};

type Duration = record {
secs: nat64;
nanos: nat32;
};

// Number of nanoseconds from the UNIX epoch in UTC timezone.
type TimeStamp = record {
timestamp_nanos: nat64;
};

type ArchiveOptions = record {
trigger_threshold : nat64;
num_blocks_to_archive : nat64;
node_max_memory_size_bytes: opt nat64;
max_message_size_bytes: opt nat64;
controller_id: principal;
cycles_for_archive_creation: opt nat64;
};

// Height of a ledger block.
type BlockHeight = nat64;

// A number associated with a transaction.
// Can be set by the caller in `send` call as a correlation identifier.
type Memo = nat64;

// Account identifier encoded as a 64-byte ASCII hex string.
type AccountIdentifier = text;

// Subaccount is an arbitrary 32-byte byte array.
type SubAccount = blob;

type Transfer = variant {
Burn: record {
from: AccountIdentifier;
amount: Tokens;
};
Mint: record {
to: AccountIdentifier;
amount: Tokens;
};
Send: record {
from: AccountIdentifier;
to: AccountIdentifier;
amount: Tokens;
};
};

type Transaction = record {
transfer: Transfer;
memo: Memo;
created_at: BlockHeight;
};

// Arguments for the `send_dfx` call.
type SendArgs = record {
memo: Memo;
amount: Tokens;
fee: Tokens;
from_subaccount: opt SubAccount;
to: AccountIdentifier;
created_at_time: opt TimeStamp;
};

// Arguments for the `notify` call.
type NotifyCanisterArgs = record {
// The of the block to send a notification about.
block_height: BlockHeight;
// Max fee, should be 10000 e8s.
max_fee: Tokens;
// Subaccount the payment came from.
from_subaccount: opt SubAccount;
// Canister that received the payment.
to_canister: principal;
// Subaccount that received the payment.
to_subaccount: opt SubAccount;
};

type AccountBalanceArgs = record {
account: AccountIdentifier;
};

type LedgerCanisterInitPayload = record {
minting_account: AccountIdentifier;
initial_values: vec record {AccountIdentifier; Tokens};
max_message_size_bytes: opt nat64;
transaction_window: opt Duration;
archive_options: opt ArchiveOptions;
send_whitelist: vec principal;
transfer_fee: opt Tokens;
token_symbol: opt text;
token_name: opt text;
};

service: (LedgerCanisterInitPayload) -> {
send_dfx : (SendArgs) -> (BlockHeight);
notify_dfx: (NotifyCanisterArgs) -> ();
account_balance_dfx : (AccountBalanceArgs) -> (Tokens) query;
}
Loading

0 comments on commit 97c9e97

Please sign in to comment.