-
Notifications
You must be signed in to change notification settings - Fork 25
Update examples to use latest linera-web APIs. #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 28 commits
acd76ad
89496ed
1086fca
3d9516f
a8bb8eb
01610ef
f236412
052b2f3
369b78d
39c57b5
300de33
23c9787
43f2b6f
6e71b49
93f5409
4fad1ef
26be11f
1ce1a4b
af5b5af
8575cf4
6730616
01328d9
ad24510
67d2443
a887355
ecb6e5f
c980910
b8867be
1e31661
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
VITE_FAUCET_URL=https://faucet.testnet-babbage.linera.net | ||
VITE_COUNTER_APP_ID= | ||
VITE_FUNGIBLE_APP_ID= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Linera | Counter</title> | ||
<link href="/style.css" rel="stylesheet"> | ||
<link href="/icon.png" rel="icon"> | ||
<style type="text/css"> | ||
.ui { | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.ui .counter { | ||
font-size: 1.25rem; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<div class="content"> | ||
<div class="description"> | ||
<h1>Counter</h1> | ||
<p> | ||
This is a simple application tracking some on-chain state that remembers the value of an integer counter. | ||
</p> | ||
<p> | ||
Click the button to submit a block that increments the counter, and watch your local node's state update in real-time. | ||
</p> | ||
</div> | ||
<div class="ui"> | ||
<p class="counter">Clicks: <span id="count">0</span></p> | ||
<button id="increment-btn">Click me!</button> | ||
</div> | ||
</div> | ||
|
||
<div class="logs"> | ||
<h2>Connected as <code id="owner" class="hex">requesting owner…</code> </h2> | ||
<h2>Chain history for <code id="chain-id" class="hex">requesting chain…</code></h2> | ||
<ul id="logs"> | ||
<template> | ||
<li> | ||
<span class="height"></span>: <span class="code hash"></span> | ||
</li> | ||
</template> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"@linera/client": "./js/@linera/client/linera_web.js", | ||
"@linera/signer": "./js/@linera/signer/index.js" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
import * as linera from '@linera/client'; | ||
import * as linera_signer from '@linera/signer'; | ||
|
||
const COUNTER_APP_ID = import.meta.env.VITE_COUNTER_APP_ID; | ||
|
||
async function run() { | ||
await linera.default(); | ||
const faucet = await new linera.Faucet(import.meta.env.VITE_FAUCET_URL); | ||
const signer = await new linera_signer.MetaMaskEIP191Signer(); | ||
const wallet = await faucet.createWallet(); | ||
const owner = await signer.address(); | ||
document.getElementById('owner').innerText = owner; | ||
document.getElementById('chain-id').innerText = await faucet.claimChain(wallet, owner); | ||
const client = await new linera.Client(wallet, signer); | ||
const counter = await client.frontend().application(COUNTER_APP_ID); | ||
const logs = document.getElementById('logs'); | ||
const incrementButton = document.getElementById('increment-btn'); | ||
const blockTemplate = document.getElementById('block-template'); | ||
|
||
function addLogEntry(block) { | ||
const entry = logs.getElementsByTagName('template')[0].content.cloneNode(true); | ||
entry.querySelector('.height').textContent = block.height; | ||
entry.querySelector('.hash').textContent = block.hash; | ||
logs.insertBefore(entry, logs.firstChild); | ||
} | ||
|
||
async function updateCount() { | ||
const response = await counter.query('{ "query": "query { value }" }'); | ||
document.getElementById('count').innerText | ||
= JSON.parse(response).data.value; | ||
} | ||
|
||
updateCount(); | ||
client.onNotification(notification => { | ||
let newBlock = notification.reason.NewBlock; | ||
if (!newBlock) return; | ||
addLogEntry(newBlock); | ||
updateCount(); | ||
}); | ||
|
||
incrementButton.addEventListener('click', () => { | ||
counter.query('{ "query": "mutation { increment(value: 1) }" }'); | ||
}); | ||
} | ||
|
||
if (document.readyState === 'loading') | ||
document.addEventListener('DOMContentLoaded', run); | ||
else | ||
run(); | ||
</script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "@linera/examples/hosted-counter-metamask", | ||
"private": true, | ||
"author": "Linera <[email protected]>", | ||
"license": "Apache-2.0", | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"preview": "vite preview", | ||
"ci": "pnpm build" | ||
}, | ||
"dependencies": { | ||
"@linera/client": "workspace:*", | ||
"@linera/signer": "workspace:*" | ||
}, | ||
"devDependencies": { | ||
"vite": "^5.4.11" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../assets/arrow.svg |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../assets/icon.png |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../node_modules/@linera/client/dist |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../assets/style.css |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { defineConfig } from 'vite'; | ||
|
||
// https://vitejs.dev/config/ | ||
export default defineConfig({ | ||
base: '/hosted/counter/', | ||
server: { | ||
headers: { | ||
'Cross-Origin-Embedder-Policy': 'require-corp', | ||
'Cross-Origin-Opener-Policy': 'same-origin', | ||
}, | ||
}, | ||
build: { | ||
rollupOptions: { | ||
external: ['@linera/client'], | ||
}, | ||
}, | ||
esbuild: { | ||
supported: { | ||
'top-level-await': true, | ||
}, | ||
}, | ||
optimizeDeps: { | ||
exclude: [ | ||
'@linera/client', | ||
], | ||
}, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,6 +127,7 @@ <h4>Transfer</h4> | |
</div> | ||
|
||
<div class="logs"> | ||
<h2>Connected as <code id="owner" class="hex">requesting owner…</code> </h2> | ||
<h2>Chain history for <code id="chain-id" class="hex">requesting a new microchain…</code></h2> | ||
<ul id="logs"> | ||
<template> | ||
|
@@ -140,8 +141,10 @@ <h2>Chain history for <code id="chain-id" class="hex">requesting a new microchai | |
|
||
<script type="module"> | ||
import * as linera from '@linera/client'; | ||
import { PrivateKey } from '@linera/signer'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I think it would be better to use this qualified as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I guess it was imported unqualified because the module name used to be suffixed to the class name as well, but that's no longer the case) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Exactly :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kind of agree, which is why it's a nit, but for people encountering this API for the first time it might be best to be super explicit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's why I wanted to call this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've written this before but — the reason modules are nice to have as a language construct is that the information that is obvious about a name changes depending on the context. Back in the good old days of C we would always have to write
When you try to include all possible context into the base name, you're cursing your users to always include all of that context, even when it's not relevant, and to not be able to decide (or at least be strongly discouraged from deciding) what information is relevant to them. Conversely, you're taking on the burden of trying to guess all the possible contexts that the name could appear in and creating a name that's suitably unambiguous in every single one. Using the language's module facilities, on the other hand, means consumers (including you, the producer!) can adapt the name in different contexts to omit the information that's obvious and keep or add information that's pertinent. The fact that the word ‘signer’ is pertinent in this context doesn't mean it's pertinent in all contexts such that it should be made part of the core name. In fact, a great example of a context in which it's not pertinent at all (because it's super obvious) is the module where it's defined, |
||
|
||
const FUNGIBLE_APP_ID = '465e465b050db5034fd8a51df46b9a7cf02a8a6414cc2b94b102e912208d4a4b'; | ||
// This needs to point at actual deployed fungible application ID. | ||
const FUNGIBLE_APP_ID = import.meta.env.VITE_FUNGIBLE_APP_ID; | ||
|
||
const gql = (query, variables = {}) => JSON.stringify({ query, variables }); | ||
|
||
|
@@ -216,11 +219,14 @@ <h2>Chain history for <code id="chain-id" class="hex">requesting a new microchai | |
}); | ||
|
||
await linera.default(); | ||
const faucet = await new linera.Faucet('https://faucet.testnet-babbage.linera.net'); | ||
const faucet = await new linera.Faucet(import.meta.env.VITE_FAUCET_URL); | ||
const signer = new PrivateKey("f77a21701522a03b01c111ad2d2cdaf2b8403b47507ee0aec3c2e52b765d7a66"); | ||
const wallet = await faucet.createWallet(); | ||
const client = await new linera.Client(wallet); | ||
const chainId = await faucet.claimChain(client); | ||
const owner = signer.address(); | ||
const chainId = await faucet.claimChain(wallet, owner); | ||
const client = await new linera.Client(wallet, signer); | ||
document.querySelector('#chain-id').innerText = chainId; | ||
document.querySelector('#owner').innerText = owner; | ||
|
||
const application = await client.frontend().application(FUNGIBLE_APP_ID); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,23 @@ | |
"keywords": [], | ||
"author": "Linera <[email protected]>", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"@linera/client": "workspace:*", | ||
"@linera/signer": "workspace:*" | ||
}, | ||
"devDependencies": { | ||
"@types/chrome": "^0.0.267", | ||
"@types/jest": "^29.5.14", | ||
"@types/node": "^24.0.0", | ||
"@types/randomstring": "^1.3.0", | ||
"ts-auto-guard": "^5.0.1", | ||
"typescript": "^5.8.3", | ||
"vite": "^5.4.5" | ||
}, | ||
"pnpm": { | ||
"onlyBuiltDependencies": [ | ||
"@linera/client" | ||
"@linera/client", | ||
"@linera/signer" | ||
] | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.