@kaleido-xlm/cli 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/templates/marketplace-with-token/README.md +19 -0
- package/templates/marketplace-with-token/contracts/marketplace/.gitkeep +0 -0
- package/templates/marketplace-with-token/contracts/token/.gitkeep +0 -0
- package/templates/marketplace-with-token/kaleido.artifacts.json +10 -0
- package/templates/marketplace-with-token/kaleido.config.ts +30 -0
- package/templates/marketplace-with-token/kaleido.template.json +21 -0
- package/templates/marketplace-with-token/package.json +17 -0
- package/templates/marketplace-with-token/src/main.ts +1 -0
- package/templates/marketplace-with-token/tsconfig.json +11 -0
- package/templates/react-vite-counter/README.md +58 -0
- package/templates/react-vite-counter/contracts/counter/Cargo.toml +23 -0
- package/templates/react-vite-counter/contracts/counter/src/lib.rs +36 -0
- package/templates/react-vite-counter/index.html +12 -0
- package/templates/react-vite-counter/kaleido.config.ts +26 -0
- package/templates/react-vite-counter/kaleido.template.json +21 -0
- package/templates/react-vite-counter/package.json +29 -0
- package/templates/react-vite-counter/public/.gitkeep +1 -0
- package/templates/react-vite-counter/src/App.tsx +18 -0
- package/templates/react-vite-counter/src/components/CounterCard.tsx +29 -0
- package/templates/react-vite-counter/src/components/WalletButton.tsx +12 -0
- package/templates/react-vite-counter/src/contracts/generated/.gitkeep +1 -0
- package/templates/react-vite-counter/src/main.tsx +10 -0
- package/templates/react-vite-counter/src/styles.css +155 -0
- package/templates/react-vite-counter/tsconfig.json +21 -0
- package/templates/react-vite-counter/vite.config.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaleido-xlm/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Developer toolkit CLI for building dApps on Stellar/Soroban",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"stellar",
|
|
@@ -38,11 +38,12 @@
|
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
40
|
"dist",
|
|
41
|
+
"templates",
|
|
41
42
|
"README.md",
|
|
42
43
|
"LICENSE"
|
|
43
44
|
],
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@kaleido-xlm/core": "^0.1.
|
|
46
|
+
"@kaleido-xlm/core": "^0.1.1",
|
|
46
47
|
"chalk": "^5.4.1",
|
|
47
48
|
"commander": "^12.1.0"
|
|
48
49
|
},
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"vitest": "^2.1.8"
|
|
54
55
|
},
|
|
55
56
|
"scripts": {
|
|
56
|
-
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
57
|
+
"build": "tsup src/index.ts --format esm --dts --clean && rm -rf ./templates && cp -r ../templates ./templates",
|
|
57
58
|
"dev": "tsx src/index.ts",
|
|
58
59
|
"test": "vitest run --pool=threads",
|
|
59
60
|
"typecheck": "tsc --noEmit"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
Experimental Kaleido multi-contract template.
|
|
4
|
+
|
|
5
|
+
## Deploy
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npx kaleido build token
|
|
10
|
+
npx kaleido build marketplace
|
|
11
|
+
npx kaleido deploy --network testnet --source alice
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Deploy order:
|
|
15
|
+
|
|
16
|
+
1. `token`
|
|
17
|
+
2. `marketplace`
|
|
18
|
+
|
|
19
|
+
`marketplace.deployArgs.tokenContractId` resolves from `${contracts.token.contractId}` after the token deploy writes `kaleido.artifacts.json`.
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { defineConfig } from "@kaleido-xlm/core";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
project: "__PROJECT_NAME__",
|
|
5
|
+
defaultNetwork: "testnet",
|
|
6
|
+
contracts: {
|
|
7
|
+
token: {
|
|
8
|
+
path: "./contracts/token",
|
|
9
|
+
wasm: "./contracts/token/target/wasm32v1-none/release/token.wasm"
|
|
10
|
+
},
|
|
11
|
+
marketplace: {
|
|
12
|
+
path: "./contracts/marketplace",
|
|
13
|
+
wasm: "./contracts/marketplace/target/wasm32v1-none/release/marketplace.wasm",
|
|
14
|
+
dependsOn: ["token"],
|
|
15
|
+
deployArgs: {
|
|
16
|
+
tokenContractId: "${contracts.token.contractId}"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
networks: {
|
|
21
|
+
testnet: {
|
|
22
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
23
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
frontend: {
|
|
27
|
+
framework: "vite-react",
|
|
28
|
+
bindingsOutput: "./src/contracts/generated"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "marketplace-with-token",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Experimental multi-contract Soroban template with token dependency injection.",
|
|
5
|
+
"kaleido": {
|
|
6
|
+
"compatibleCore": "^0.1.0",
|
|
7
|
+
"templateVersion": 1
|
|
8
|
+
},
|
|
9
|
+
"frontend": {
|
|
10
|
+
"framework": "vite-react",
|
|
11
|
+
"packageManager": "npm"
|
|
12
|
+
},
|
|
13
|
+
"contracts": {
|
|
14
|
+
"path": "contracts",
|
|
15
|
+
"default": "marketplace"
|
|
16
|
+
},
|
|
17
|
+
"files": {
|
|
18
|
+
"config": "kaleido.config.ts",
|
|
19
|
+
"artifacts": "kaleido.artifacts.json"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"kaleido:build": "kaleido build token && kaleido build marketplace",
|
|
8
|
+
"kaleido:deploy": "kaleido deploy --network testnet"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@kaleido-xlm/core": "^0.1.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@kaleido-xlm/cli": "^0.1.0",
|
|
15
|
+
"typescript": "^5.7.2"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const placeholder = "marketplace-with-token template bootstrap";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# __PROJECT_NAME__
|
|
2
|
+
|
|
3
|
+
Kaleido counter dApp for Stellar/Soroban.
|
|
4
|
+
|
|
5
|
+
## CLI Flow
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npx kaleido build counter
|
|
10
|
+
npx kaleido deploy counter --network testnet --source alice
|
|
11
|
+
npx kaleido generate counter --network testnet
|
|
12
|
+
npx kaleido invoke counter.increment --network testnet --source alice
|
|
13
|
+
npm run dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Use a Stellar CLI identity alias or public account address for `--source`; do not pass seed phrases or secret keys.
|
|
17
|
+
|
|
18
|
+
## Client Smoke Path
|
|
19
|
+
|
|
20
|
+
After `kaleido generate`, wire generated bindings to the client:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createKaleidoClient } from "@kaleido-xlm/client";
|
|
24
|
+
import { freighterWalletAdapter } from "@kaleido-xlm/client/freighter";
|
|
25
|
+
import * as Counter from "./contracts/generated/counter";
|
|
26
|
+
import artifacts from "../kaleido.artifacts.json";
|
|
27
|
+
|
|
28
|
+
export const kaleidoClient = createKaleidoClient({
|
|
29
|
+
network: {
|
|
30
|
+
name: "testnet",
|
|
31
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
32
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
33
|
+
},
|
|
34
|
+
artifacts,
|
|
35
|
+
wallet: freighterWalletAdapter,
|
|
36
|
+
contracts: {
|
|
37
|
+
counter: {
|
|
38
|
+
binding: Counter
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Build XDR without wallet signing:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const tx = await kaleidoClient.contract("counter").buildXdr("increment");
|
|
48
|
+
console.log(tx.preparedXdr);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Invoke through Freighter:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const result = await kaleidoClient.contract("counter").invoke("increment", {
|
|
55
|
+
debugXdr: true
|
|
56
|
+
});
|
|
57
|
+
console.log(result.transactionHash);
|
|
58
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "counter"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
|
|
6
|
+
[lib]
|
|
7
|
+
crate-type = ["cdylib"]
|
|
8
|
+
|
|
9
|
+
[dependencies]
|
|
10
|
+
soroban-sdk = "26.0.0"
|
|
11
|
+
|
|
12
|
+
[dev-dependencies]
|
|
13
|
+
soroban-sdk = { version = "26.0.0", features = ["testutils"] }
|
|
14
|
+
|
|
15
|
+
[profile.release]
|
|
16
|
+
opt-level = "z"
|
|
17
|
+
overflow-checks = true
|
|
18
|
+
debug = 0
|
|
19
|
+
strip = "symbols"
|
|
20
|
+
debug-assertions = false
|
|
21
|
+
panic = "abort"
|
|
22
|
+
codegen-units = 1
|
|
23
|
+
lto = true
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#![no_std]
|
|
2
|
+
|
|
3
|
+
use soroban_sdk::{contract, contractimpl, Env};
|
|
4
|
+
|
|
5
|
+
#[contract]
|
|
6
|
+
pub struct CounterContract;
|
|
7
|
+
|
|
8
|
+
#[contractimpl]
|
|
9
|
+
impl CounterContract {
|
|
10
|
+
pub fn get(env: Env) -> u32 {
|
|
11
|
+
env.storage().instance().get(&"count").unwrap_or(0)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn increment(env: Env) -> u32 {
|
|
15
|
+
let count = Self::get(env.clone()) + 1;
|
|
16
|
+
env.storage().instance().set(&"count", &count);
|
|
17
|
+
count
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[cfg(test)]
|
|
22
|
+
mod test {
|
|
23
|
+
use super::*;
|
|
24
|
+
use soroban_sdk::Env;
|
|
25
|
+
|
|
26
|
+
#[test]
|
|
27
|
+
fn increments_counter() {
|
|
28
|
+
let env = Env::default();
|
|
29
|
+
let contract_id = env.register(CounterContract, ());
|
|
30
|
+
let client = CounterContractClient::new(&env, &contract_id);
|
|
31
|
+
|
|
32
|
+
assert_eq!(client.get(), 0);
|
|
33
|
+
assert_eq!(client.increment(), 1);
|
|
34
|
+
assert_eq!(client.get(), 1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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>__PROJECT_NAME__</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineConfig } from "@kaleido-xlm/core";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
project: "__PROJECT_NAME__",
|
|
5
|
+
defaultNetwork: "testnet",
|
|
6
|
+
contracts: {
|
|
7
|
+
counter: {
|
|
8
|
+
path: "./contracts/counter",
|
|
9
|
+
wasm: "./contracts/counter/target/wasm32v1-none/release/counter.wasm"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
networks: {
|
|
13
|
+
testnet: {
|
|
14
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
15
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
16
|
+
},
|
|
17
|
+
mainnet: {
|
|
18
|
+
rpcUrl: "https://mainnet.sorobanrpc.com",
|
|
19
|
+
networkPassphrase: "Public Global Stellar Network ; September 2015"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
frontend: {
|
|
23
|
+
framework: "vite-react",
|
|
24
|
+
bindingsOutput: "./src/contracts/generated"
|
|
25
|
+
}
|
|
26
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-vite-counter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Minimal Vite + React + Soroban counter dApp.",
|
|
5
|
+
"kaleido": {
|
|
6
|
+
"compatibleCore": "^0.1.0",
|
|
7
|
+
"templateVersion": 1
|
|
8
|
+
},
|
|
9
|
+
"frontend": {
|
|
10
|
+
"framework": "vite-react",
|
|
11
|
+
"packageManager": "npm"
|
|
12
|
+
},
|
|
13
|
+
"contracts": {
|
|
14
|
+
"path": "contracts",
|
|
15
|
+
"default": "counter"
|
|
16
|
+
},
|
|
17
|
+
"files": {
|
|
18
|
+
"config": "kaleido.config.ts",
|
|
19
|
+
"artifacts": "kaleido.artifacts.json"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__PROJECT_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"kaleido:build": "kaleido build counter",
|
|
11
|
+
"kaleido:deploy": "kaleido deploy counter",
|
|
12
|
+
"kaleido:generate": "kaleido generate counter"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@kaleido-xlm/client": "^0.1.0",
|
|
16
|
+
"@kaleido-xlm/core": "^0.1.0",
|
|
17
|
+
"@stellar/freighter-api": "^4.0.0",
|
|
18
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
19
|
+
"vite": "^6.0.6",
|
|
20
|
+
"react": "^18.3.1",
|
|
21
|
+
"react-dom": "^18.3.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@kaleido-xlm/cli": "^0.1.0",
|
|
25
|
+
"@types/react": "^18.3.18",
|
|
26
|
+
"@types/react-dom": "^18.3.5",
|
|
27
|
+
"typescript": "^5.7.2"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CounterCard } from "./components/CounterCard";
|
|
2
|
+
import { WalletButton } from "./components/WalletButton";
|
|
3
|
+
|
|
4
|
+
export default function App() {
|
|
5
|
+
return (
|
|
6
|
+
<main className="app-shell">
|
|
7
|
+
<header className="topbar">
|
|
8
|
+
<div>
|
|
9
|
+
<p className="eyebrow">Kaleido</p>
|
|
10
|
+
<h1>__PROJECT_NAME__</h1>
|
|
11
|
+
</div>
|
|
12
|
+
<WalletButton />
|
|
13
|
+
</header>
|
|
14
|
+
|
|
15
|
+
<CounterCard />
|
|
16
|
+
</main>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
export function CounterCard() {
|
|
4
|
+
const [count, setCount] = useState(0);
|
|
5
|
+
const formattedCount = useMemo(() => new Intl.NumberFormat().format(count), [count]);
|
|
6
|
+
|
|
7
|
+
return (
|
|
8
|
+
<section className="counter-panel" aria-labelledby="counter-title">
|
|
9
|
+
<div className="counter-panel__header">
|
|
10
|
+
<div>
|
|
11
|
+
<p className="eyebrow">Counter Contract</p>
|
|
12
|
+
<h2 id="counter-title">Counter</h2>
|
|
13
|
+
</div>
|
|
14
|
+
<span className="network-pill">testnet</span>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div className="counter-value">{formattedCount}</div>
|
|
18
|
+
|
|
19
|
+
<div className="counter-actions">
|
|
20
|
+
<button type="button" onClick={() => setCount((value) => value + 1)}>
|
|
21
|
+
Increment
|
|
22
|
+
</button>
|
|
23
|
+
<button className="secondary-button" type="button" onClick={() => setCount(0)}>
|
|
24
|
+
Reset
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
</section>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
export function WalletButton() {
|
|
4
|
+
const [connected, setConnected] = useState(false);
|
|
5
|
+
|
|
6
|
+
return (
|
|
7
|
+
<button className="wallet-button" type="button" onClick={() => setConnected((value) => !value)}>
|
|
8
|
+
<span className={connected ? "status-dot status-dot--on" : "status-dot"} />
|
|
9
|
+
{connected ? "Connected" : "Connect"}
|
|
10
|
+
</button>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color: #20232a;
|
|
3
|
+
background: #f4f2ec;
|
|
4
|
+
font-family:
|
|
5
|
+
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
6
|
+
font-synthesis: none;
|
|
7
|
+
text-rendering: optimizeLegibility;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
* {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
min-width: 320px;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
margin: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
button {
|
|
21
|
+
min-height: 44px;
|
|
22
|
+
border: 0;
|
|
23
|
+
border-radius: 8px;
|
|
24
|
+
padding: 0 16px;
|
|
25
|
+
background: #1d6154;
|
|
26
|
+
color: #ffffff;
|
|
27
|
+
font: inherit;
|
|
28
|
+
font-weight: 700;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
button:hover {
|
|
33
|
+
background: #174d44;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.app-shell {
|
|
37
|
+
width: min(960px, calc(100vw - 32px));
|
|
38
|
+
margin: 0 auto;
|
|
39
|
+
padding: 24px 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.topbar {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
gap: 16px;
|
|
47
|
+
margin-bottom: 32px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.topbar h1,
|
|
51
|
+
.counter-panel h2 {
|
|
52
|
+
margin: 0;
|
|
53
|
+
color: #16181d;
|
|
54
|
+
letter-spacing: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.topbar h1 {
|
|
58
|
+
font-size: clamp(2rem, 8vw, 4rem);
|
|
59
|
+
line-height: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.counter-panel h2 {
|
|
63
|
+
font-size: 1.35rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.eyebrow {
|
|
67
|
+
margin: 0 0 8px;
|
|
68
|
+
color: #697076;
|
|
69
|
+
font-size: 0.78rem;
|
|
70
|
+
font-weight: 800;
|
|
71
|
+
letter-spacing: 0.08em;
|
|
72
|
+
text-transform: uppercase;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.wallet-button,
|
|
76
|
+
.network-pill {
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
align-items: center;
|
|
79
|
+
gap: 8px;
|
|
80
|
+
white-space: nowrap;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.status-dot {
|
|
84
|
+
width: 8px;
|
|
85
|
+
height: 8px;
|
|
86
|
+
border-radius: 999px;
|
|
87
|
+
background: #a9afb4;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.status-dot--on {
|
|
91
|
+
background: #66c887;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.counter-panel {
|
|
95
|
+
border: 1px solid #d9d5ca;
|
|
96
|
+
border-radius: 8px;
|
|
97
|
+
padding: clamp(20px, 5vw, 40px);
|
|
98
|
+
background: #fffdf7;
|
|
99
|
+
box-shadow: 0 18px 60px rgba(32, 35, 42, 0.08);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.counter-panel__header {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: flex-start;
|
|
105
|
+
justify-content: space-between;
|
|
106
|
+
gap: 16px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.network-pill {
|
|
110
|
+
min-height: 32px;
|
|
111
|
+
border: 1px solid #d9d5ca;
|
|
112
|
+
border-radius: 999px;
|
|
113
|
+
padding: 0 12px;
|
|
114
|
+
color: #45515a;
|
|
115
|
+
font-weight: 700;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.counter-value {
|
|
119
|
+
margin: 48px 0;
|
|
120
|
+
color: #111318;
|
|
121
|
+
font-size: clamp(5rem, 24vw, 12rem);
|
|
122
|
+
font-weight: 900;
|
|
123
|
+
line-height: 0.9;
|
|
124
|
+
letter-spacing: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.counter-actions {
|
|
128
|
+
display: flex;
|
|
129
|
+
flex-wrap: wrap;
|
|
130
|
+
gap: 12px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.secondary-button {
|
|
134
|
+
border: 1px solid #d9d5ca;
|
|
135
|
+
background: #ffffff;
|
|
136
|
+
color: #20232a;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.secondary-button:hover {
|
|
140
|
+
background: #f4f2ec;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@media (max-width: 560px) {
|
|
144
|
+
.topbar,
|
|
145
|
+
.counter-panel__header {
|
|
146
|
+
align-items: stretch;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.wallet-button,
|
|
151
|
+
.counter-actions button {
|
|
152
|
+
width: 100%;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ES2020"],
|
|
6
|
+
"allowJs": false,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"module": "ESNext",
|
|
13
|
+
"moduleResolution": "Node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx"
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"references": []
|
|
21
|
+
}
|