Skip to content

Commit a5a32e3

Browse files
committed
Add separate counter with MetaMask integration
1 parent 43f2b6f commit a5a32e3

File tree

11 files changed

+186
-4
lines changed

11 files changed

+186
-4
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Linera | Counter</title>
7+
<link href="/style.css" rel="stylesheet">
8+
<link href="/icon.png" rel="icon">
9+
<style type="text/css">
10+
.ui {
11+
display: flex;
12+
flex-direction: column;
13+
}
14+
15+
.ui .counter {
16+
font-size: 1.25rem;
17+
}
18+
</style>
19+
</head>
20+
<body>
21+
<div class="container">
22+
<div class="content">
23+
<div class="description">
24+
<h1>Counter</h1>
25+
<p>
26+
This is a simple application tracking some on-chain state that remembers the value of an integer counter.
27+
</p>
28+
<p>
29+
Click the button to submit a block that increments the counter, and watch your local node's state update in real-time.
30+
</p>
31+
</div>
32+
<div class="ui">
33+
<p class="counter">Clicks: <span id="count">0</span></p>
34+
<button id="increment-btn">Click me!</button>
35+
</div>
36+
</div>
37+
38+
<div class="logs">
39+
<h2>Connected as <code id="owner" class="hex">requesting owner…</code> </h2>
40+
<h2>Chain history for <code id="chain-id" class="hex">requesting chain…</code></h2>
41+
<ul id="logs">
42+
<template>
43+
<li>
44+
<span class="height"></span>: <span class="code hash"></span>
45+
</li>
46+
</template>
47+
</div>
48+
</div>
49+
</div>
50+
51+
<script type="importmap">
52+
{
53+
"imports": {
54+
"@linera/client": "./js/@linera/client/linera_web.js",
55+
"@linera/signer": "./js/@linera/signer/index.js"
56+
}
57+
}
58+
</script>
59+
60+
<script type="module">
61+
import * as linera from '@linera/client';
62+
import * as linera_signer from '@linera/signer';
63+
64+
const COUNTER_APP_ID = import.meta.env.VITE_COUNTER_APP_ID;
65+
66+
async function run() {
67+
await linera.default();
68+
const faucet = await new linera.Faucet(import.meta.env.VITE_FAUCET_URL);
69+
const signer = await new linera_signer.MetaMaskEIP191Signer();
70+
const wallet = await faucet.createWallet();
71+
const owner = await signer.address();
72+
document.getElementById('owner').innerText = owner;
73+
document.getElementById('chain-id').innerText = await faucet.claimChain(wallet, owner);
74+
const client = await new linera.Client(wallet, signer);
75+
const counter = await client.frontend().application(COUNTER_APP_ID);
76+
const logs = document.getElementById('logs');
77+
const incrementButton = document.getElementById('increment-btn');
78+
const blockTemplate = document.getElementById('block-template');
79+
80+
function addLogEntry(block) {
81+
const entry = logs.getElementsByTagName('template')[0].content.cloneNode(true);
82+
entry.querySelector('.height').textContent = block.height;
83+
entry.querySelector('.hash').textContent = block.hash;
84+
logs.insertBefore(entry, logs.firstChild);
85+
}
86+
87+
async function updateCount() {
88+
const response = await counter.query('{ "query": "query { value }" }');
89+
document.getElementById('count').innerText
90+
= JSON.parse(response).data.value;
91+
}
92+
93+
updateCount();
94+
client.onNotification(notification => {
95+
let newBlock = notification.reason.NewBlock;
96+
if (!newBlock) return;
97+
addLogEntry(newBlock);
98+
updateCount();
99+
});
100+
101+
incrementButton.addEventListener('click', () => {
102+
counter.query('{ "query": "mutation { increment(value: 1) }" }');
103+
});
104+
}
105+
106+
if (document.readyState === 'loading')
107+
document.addEventListener('DOMContentLoaded', run);
108+
else
109+
run();
110+
</script>
111+
</body>
112+
</html>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@linera/examples/hosted-counter-metamask",
3+
"private": true,
4+
"author": "Linera <[email protected]>",
5+
"license": "Apache-2.0",
6+
"version": "0.0.0",
7+
"type": "module",
8+
"scripts": {
9+
"dev": "vite",
10+
"build": "vite build",
11+
"preview": "vite preview",
12+
"ci": "pnpm install --frozen-lockfile && pnpm build"
13+
},
14+
"dependencies": {
15+
"@linera/client": "workspace:*",
16+
"@linera/signer": "workspace:*",
17+
"buffer": "^6.0.3"
18+
},
19+
"devDependencies": {
20+
"vite": "^5.4.11"
21+
}
22+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../assets/arrow.svg
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../assets/icon.png
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../node_modules/@linera/client/dist
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../assets/style.css
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { defineConfig } from 'vite';
2+
3+
// https://vitejs.dev/config/
4+
export default defineConfig({
5+
base: '/hosted/counter/',
6+
server: {
7+
headers: {
8+
'Cross-Origin-Embedder-Policy': 'require-corp',
9+
'Cross-Origin-Opener-Policy': 'same-origin',
10+
},
11+
},
12+
build: {
13+
rollupOptions: {
14+
external: ['@linera/client'],
15+
},
16+
},
17+
esbuild: {
18+
supported: {
19+
'top-level-await': true,
20+
},
21+
},
22+
optimizeDeps: {
23+
exclude: [
24+
'@linera/client',
25+
],
26+
},
27+
})

examples/hosted-counter/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ <h2>Chain history for <code id="chain-id" class="hex">requesting chain…</code>
6262
window.Buffer = Buffer;
6363

6464
import * as linera from '@linera/client';
65-
import * as signer from '@linera/signer';
65+
import * as linera_signer from '@linera/signer';
6666

6767
const COUNTER_APP_ID = import.meta.env.VITE_COUNTER_APP_ID;
6868

6969
async function run() {
7070
await linera.default();
7171
const faucet = await new linera.Faucet(import.meta.env.VITE_FAUCET_URL);
72-
const signer = await new signer.PrivateKey("f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66");
72+
const signer = await new linera_signer.PrivateKey("f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66");
7373
const wallet = await faucet.createWallet();
7474
const owner = await signer.address();
7575
document.getElementById('owner').innerText = owner;

examples/hosted-fungible/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ <h2>Chain history for <code id="chain-id" class="hex">requesting a new microchai
141141

142142
<script type="module">
143143
import * as linera from '@linera/client';
144-
import * as signer from '@linera/signer';
144+
import * as linera_signer from '@linera/signer';
145145

146146
// This needs to point at actual deployed fungible application ID.
147147
const FUNGIBLE_APP_ID = import.meta.env.VITE_FUNGIBLE_APP_ID;
@@ -220,7 +220,7 @@ <h2>Chain history for <code id="chain-id" class="hex">requesting a new microchai
220220

221221
await linera.default();
222222
const faucet = await new linera.Faucet(import.meta.env.VITE_FAUCET_URL);
223-
const signer = await new signer.PrivateKey("f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66");
223+
const signer = await new linera_signer.PrivateKey("f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66");
224224
const wallet = await faucet.createWallet();
225225
const owner = signer.address();
226226
const chainId = await faucet.claimChain(wallet, owner);

pnpm-lock.yaml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)