cosmos-connect-react 0.1.2 → 0.1.3

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 CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "cosmos-connect-react",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
7
11
  "scripts": {
8
12
  "build": "tsc && cp src/styles.css dist/"
9
13
  },
@@ -1,75 +0,0 @@
1
- import React, {
2
- createContext,
3
- useContext,
4
- useEffect,
5
- useState,
6
- ReactNode,
7
- } from 'react';
8
- import {
9
- Client,
10
- ClientState,
11
- createClient,
12
- ClientConfig,
13
- TERRA_CLASSIC,
14
- KeplrWallet,
15
- GalaxyStationWallet,
16
- LeapWallet,
17
- WalletConnectWallet,
18
- } from 'cosmos-connect-core';
19
-
20
- interface CosmosContextValue {
21
- client: Client;
22
- state: ClientState;
23
- }
24
-
25
- const CosmosContext = createContext<CosmosContextValue | null>(null);
26
-
27
- const DEFAULT_CONFIG: ClientConfig = {
28
- chains: [TERRA_CLASSIC],
29
- wallets: [
30
- new GalaxyStationWallet(),
31
- new KeplrWallet(),
32
- new LeapWallet(),
33
- new WalletConnectWallet({
34
- projectId: '39190b939e067ecb6dccdb7c77653a42', // Default placeholder or instructions needed
35
- }),
36
- ],
37
- };
38
-
39
- export interface CosmosProviderProps {
40
- children: ReactNode;
41
- config?: Partial<ClientConfig>;
42
- }
43
-
44
- export const CosmosProvider: React.FC<CosmosProviderProps> = ({
45
- children,
46
- config,
47
- }) => {
48
- const [client] = useState(() => {
49
- const fullConfig: ClientConfig = {
50
- chains: config?.chains || DEFAULT_CONFIG.chains,
51
- wallets: config?.wallets || DEFAULT_CONFIG.wallets,
52
- storage: config?.storage || DEFAULT_CONFIG.storage,
53
- };
54
- return createClient(fullConfig);
55
- });
56
- const [state, setState] = useState<ClientState>(client.state);
57
-
58
- useEffect(() => {
59
- return client.subscribe(setState);
60
- }, [client]);
61
-
62
- return (
63
- <CosmosContext.Provider value={{ client, state }}>
64
- {children}
65
- </CosmosContext.Provider>
66
- );
67
- };
68
-
69
- export const useCosmos = () => {
70
- const context = useContext(CosmosContext);
71
- if (!context) {
72
- throw new Error('useCosmos must be used within a CosmosProvider');
73
- }
74
- return context;
75
- };
@@ -1,51 +0,0 @@
1
- import React from 'react';
2
-
3
- interface AvatarProps {
4
- address: string;
5
- size?: number;
6
- }
7
-
8
- /**
9
- * A simple, colorful avatar generated from the address.
10
- * Mimics the ConnectKit/RainbowKit feel.
11
- */
12
- export const Avatar: React.FC<AvatarProps> = ({ address, size = 32 }) => {
13
- // Simple deterministic color generation from address
14
- const colors = [
15
- '#FFADAD', '#FFD6A5', '#FDFFB6', '#CAFFBF',
16
- '#9BF6FF', '#A0C4FF', '#BDB2FF', '#FFC6FF'
17
- ];
18
-
19
- const getHash = (str: string) => {
20
- let hash = 0;
21
- for (let i = 0; i < str.length; i++) {
22
- hash = str.charCodeAt(i) + ((hash << 5) - hash);
23
- }
24
- return hash;
25
- };
26
-
27
- const colorIndex = Math.abs(getHash(address)) % colors.length;
28
- const secondaryColorIndex = (colorIndex + 3) % colors.length;
29
-
30
- return (
31
- <div
32
- style={{
33
- width: size,
34
- height: size,
35
- borderRadius: '50%',
36
- background: `linear-gradient(135deg, ${colors[colorIndex]} 0%, ${colors[secondaryColorIndex]} 100%)`,
37
- display: 'flex',
38
- alignItems: 'center',
39
- justifyContent: 'center',
40
- fontSize: size * 0.4,
41
- fontWeight: 'bold',
42
- color: 'white',
43
- textShadow: '0 1px 2px rgba(0,0,0,0.1)',
44
- flexShrink: 0,
45
- overflow: 'hidden'
46
- }}
47
- >
48
- {address.slice(-2).toUpperCase()}
49
- </div>
50
- );
51
- };
@@ -1,44 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { useAccount } from '../hooks.js';
3
- import { ConnectModal } from './ConnectModal.js';
4
- import { Avatar } from './Avatar.js';
5
-
6
- export const ConnectButton: React.FC = () => {
7
- const { isConnected, address, status } = useAccount();
8
- const [isModalOpen, setIsModalOpen] = useState(false);
9
-
10
- const formatAddress = (addr: string) => {
11
- return `${addr.slice(0, 8)}...${addr.slice(-4)}`;
12
- };
13
-
14
- if (isConnected && address) {
15
- return (
16
- <>
17
- <button className="cc-pill" onClick={() => setIsModalOpen(true)}>
18
- <Avatar address={address} size={24} />
19
- <span className="cc-pill-text">{formatAddress(address)}</span>
20
- </button>
21
- <ConnectModal
22
- isOpen={isModalOpen}
23
- onClose={() => setIsModalOpen(false)}
24
- />
25
- </>
26
- );
27
- }
28
-
29
- return (
30
- <>
31
- <button
32
- className="cc-btn"
33
- onClick={() => setIsModalOpen(true)}
34
- disabled={status === 'connecting'}
35
- >
36
- {status === 'connecting' ? 'Connecting...' : 'Connect Wallet'}
37
- </button>
38
- <ConnectModal
39
- isOpen={isModalOpen}
40
- onClose={() => setIsModalOpen(false)}
41
- />
42
- </>
43
- );
44
- };
@@ -1,138 +0,0 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { AnimatePresence, motion } from 'framer-motion';
3
- import { useCosmos } from '../CosmosProvider.js';
4
- import { useConnect, useAccount } from '../hooks.js';
5
-
6
- import Connectors from './Pages/Connectors.js';
7
- import About from './Pages/About.js';
8
- import Profile from './Pages/Profile.js';
9
- import Connecting from './Pages/Connecting.js';
10
-
11
- interface ConnectModalProps {
12
- isOpen: boolean;
13
- onClose: () => void;
14
- }
15
-
16
- export type ModalRoute = 'connectors' | 'about' | 'profile' | 'connecting';
17
-
18
- export const ConnectModal: React.FC<ConnectModalProps> = ({ isOpen, onClose }) => {
19
- const { client } = useCosmos();
20
- const { connect } = useConnect();
21
- const { isConnected, status } = useAccount();
22
-
23
- const [route, setRoute] = useState<ModalRoute>('connectors');
24
- const [pendingWallet, setPendingWallet] = useState<any>(null);
25
-
26
- // Sync route with connection status
27
- useEffect(() => {
28
- if (isConnected) {
29
- setRoute('profile');
30
- } else if (status === 'connecting') {
31
- setRoute('connecting');
32
- } else if (!isOpen) {
33
- setRoute('connectors');
34
- }
35
- }, [isConnected, status, isOpen]);
36
-
37
- if (!isOpen) return null;
38
-
39
- const handleWalletSelect = async (wallet: any) => {
40
- try {
41
- setPendingWallet(wallet);
42
- setRoute('connecting');
43
- const chainId = client.getChains()[0]?.chainId || 'columbus-5';
44
- await connect(wallet.id, chainId);
45
- } catch (error) {
46
- console.error('Failed to connect:', error);
47
- setRoute('connectors');
48
- }
49
- };
50
-
51
- const showBackButton = route !== 'connectors' && route !== 'profile';
52
- const showInfoButton = route === 'connectors';
53
-
54
- const variants = {
55
- initial: (direction: number) => ({
56
- x: direction > 0 ? 50 : -50,
57
- opacity: 0,
58
- }),
59
- animate: {
60
- x: 0,
61
- opacity: 1,
62
- },
63
- exit: (direction: number) => ({
64
- x: direction < 0 ? 50 : -50,
65
- opacity: 0,
66
- }),
67
- };
68
-
69
- // Direction logic for transitions (simple for now)
70
- const getDirection = (newRoute: ModalRoute) => {
71
- if (newRoute === 'about' || newRoute === 'connecting') return 1;
72
- return -1;
73
- };
74
-
75
- const renderPage = () => {
76
- switch (route) {
77
- case 'connectors':
78
- return <Connectors onSelect={handleWalletSelect} />;
79
- case 'about':
80
- return <About />;
81
- case 'profile':
82
- return <Profile />;
83
- case 'connecting':
84
- return <Connecting wallet={pendingWallet} onCancel={() => setRoute('connectors')} />;
85
- default:
86
- return null;
87
- }
88
- };
89
-
90
- const getTitle = () => {
91
- switch (route) {
92
- case 'profile': return 'Account';
93
- case 'about': return 'About Wallets';
94
- case 'connecting': return 'Requesting Connection';
95
- default: return 'Connect Wallet';
96
- }
97
- };
98
-
99
- return (
100
- <div className="cc-modal-overlay" onClick={onClose}>
101
- <motion.div
102
- className="cc-modal-content"
103
- onClick={(e) => e.stopPropagation()}
104
- initial={{ scale: 0.95, opacity: 0 }}
105
- animate={{ scale: 1, opacity: 1 }}
106
- exit={{ scale: 0.95, opacity: 0 }}
107
- >
108
- <div className="cc-modal-header">
109
- {showBackButton ? (
110
- <button className="cc-back-btn" onClick={() => setRoute('connectors')}>←</button>
111
- ) : showInfoButton ? (
112
- <button className="cc-help-btn" onClick={() => setRoute('about')} title="About Wallets">?</button>
113
- ) : <div style={{ width: 28 }} />}
114
-
115
- <span className="cc-modal-title">{getTitle()}</span>
116
-
117
- <button className="cc-close-btn" onClick={onClose}>&times;</button>
118
- </div>
119
-
120
- <div className="cc-modal-body">
121
- <AnimatePresence exitBeforeEnter initial={false}>
122
- <motion.div
123
- key={route}
124
- custom={getDirection(route)}
125
- variants={variants}
126
- initial="initial"
127
- animate="animate"
128
- exit="exit"
129
- transition={{ duration: 0.2, ease: "easeInOut" }}
130
- >
131
- {renderPage()}
132
- </motion.div>
133
- </AnimatePresence>
134
- </div>
135
- </motion.div>
136
- </div>
137
- );
138
- };
@@ -1,37 +0,0 @@
1
- import React from 'react';
2
-
3
- const About: React.FC = () => {
4
- return (
5
- <div className="cc-page-about">
6
- <div className="cc-about-steps">
7
- <div className="cc-about-step">
8
- <div className="cc-step-num">1</div>
9
- <div className="cc-step-content">
10
- <h4>Get a Wallet</h4>
11
- <p>A wallet lets you connect to Terra Classic and manage your LUNC assets safely.</p>
12
- </div>
13
- </div>
14
- <div className="cc-about-step">
15
- <div className="cc-step-num">2</div>
16
- <div className="cc-step-content">
17
- <h4>Add some LUNC</h4>
18
- <p>You'll need some LUNC in your wallet to pay for gas fees on the Terra network.</p>
19
- </div>
20
- </div>
21
- <div className="cc-about-step">
22
- <div className="cc-step-num">3</div>
23
- <div className="cc-step-content">
24
- <h4>Connect & Stake</h4>
25
- <p>Connect your wallet to this app to start staking, voting, or trading.</p>
26
- </div>
27
- </div>
28
- </div>
29
-
30
- <button className="cc-primary-btn" onClick={() => window.open('https://www.galaxy-station.app/', '_blank')}>
31
- Get Galaxy Station
32
- </button>
33
- </div>
34
- );
35
- };
36
-
37
- export default About;
@@ -1,30 +0,0 @@
1
- import React from 'react';
2
-
3
- interface ConnectingProps {
4
- wallet: any;
5
- onCancel: () => void;
6
- }
7
-
8
- const Connecting: React.FC<ConnectingProps> = ({ wallet, onCancel }) => {
9
- return (
10
- <div className="cc-page-connecting">
11
- <div className="cc-connecting-view">
12
- <div className="cc-spinner-container">
13
- <div className="cc-spinner"></div>
14
- {wallet?.icon && (
15
- <img src={wallet.icon} alt="" className="cc-spinner-icon" />
16
- )}
17
- </div>
18
- <h3 className="cc-connecting-title">Requesting Connection</h3>
19
- <p className="cc-connecting-text">
20
- Open the {wallet?.name || 'Wallet'} extension to continue.
21
- </p>
22
- <button className="cc-footer-btn" onClick={onCancel}>
23
- Cancel
24
- </button>
25
- </div>
26
- </div>
27
- );
28
- };
29
-
30
- export default Connecting;
@@ -1,30 +0,0 @@
1
- import React from 'react';
2
- import { useCosmos } from '../../CosmosProvider.js';
3
-
4
- interface ConnectorsProps {
5
- onSelect: (wallet: any) => void;
6
- }
7
-
8
- const Connectors: React.FC<ConnectorsProps> = ({ onSelect }) => {
9
- const { client } = useCosmos();
10
- const wallets = client.getWallets();
11
-
12
- return (
13
- <div className="cc-page-connectors">
14
- <div className="cc-wallet-list">
15
- {wallets.map((wallet) => (
16
- <button
17
- key={wallet.id}
18
- className="cc-wallet-item"
19
- onClick={() => onSelect(wallet)}
20
- >
21
- <span>{wallet.name}</span>
22
- {wallet.icon && <img src={wallet.icon} alt={wallet.name} className="cc-wallet-icon" />}
23
- </button>
24
- ))}
25
- </div>
26
- </div>
27
- );
28
- };
29
-
30
- export default Connectors;
@@ -1,66 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { useCosmos } from '../../CosmosProvider.js';
3
- import { useAccount, useDisconnect, useBalance } from '../../hooks.js';
4
- import { Avatar } from '../Avatar.js';
5
-
6
- const Profile: React.FC = () => {
7
- const { client } = useCosmos();
8
- const { address } = useAccount();
9
- const { disconnect } = useDisconnect();
10
- const { balance, isLoading: isBalanceLoading } = useBalance();
11
- const [copyFeedback, setCopyFeedback] = useState(false);
12
-
13
- const formatBalance = (bal: { amount: string; denom: string } | null) => {
14
- if (!bal) return '0.00 LUNC';
15
- const amount = parseFloat(bal.amount) / 1000000;
16
- return `${amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} LUNC`;
17
- };
18
-
19
- const handleCopy = () => {
20
- if (address) {
21
- navigator.clipboard.writeText(address);
22
- setCopyFeedback(true);
23
- setTimeout(() => setCopyFeedback(false), 2000);
24
- }
25
- };
26
-
27
- if (!address) return null;
28
-
29
- return (
30
- <div className="cc-page-profile">
31
- <div className="cc-profile-view">
32
- <div className="cc-profile-avatar">
33
- <Avatar address={address} size={84} />
34
- </div>
35
-
36
- <div className="cc-profile-info">
37
- <h3 className="cc-profile-address">
38
- {address.slice(0, 12)}...{address.slice(-6)}
39
- </h3>
40
- <div className="cc-profile-balance">
41
- {isBalanceLoading ? 'Loading...' : formatBalance(balance)}
42
- </div>
43
- </div>
44
-
45
- <div className="cc-profile-actions">
46
- <button className="cc-util-btn" onClick={handleCopy}>
47
- {copyFeedback ? 'Copied!' : 'Copy Address'}
48
- </button>
49
- <button
50
- className="cc-util-btn"
51
- onClick={() => disconnect()}
52
- style={{ color: '#ef4444' }}
53
- >
54
- Disconnect
55
- </button>
56
- </div>
57
-
58
- <div className="cc-profile-footer">
59
- Connected to {client.getChains()[0]?.chainId}
60
- </div>
61
- </div>
62
- </div>
63
- );
64
- };
65
-
66
- export default Profile;
package/src/hooks.ts DELETED
@@ -1,73 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
- import { useCosmos } from './CosmosProvider.js';
3
- import { useCallback } from 'react';
4
-
5
- export const useAccount = () => {
6
- const { state } = useCosmos();
7
- return {
8
- address: state.account?.address,
9
- status: state.status,
10
- isConnected: state.status === 'connected',
11
- isConnecting: state.status === 'connecting',
12
- isDisconnected: state.status === 'disconnected',
13
- account: state.account,
14
- };
15
- };
16
-
17
- export const useConnect = () => {
18
- const { client } = useCosmos();
19
-
20
- const connect = useCallback(async (walletId: string, chainId: string) => {
21
- return client.connect(walletId, chainId);
22
- }, [client]);
23
-
24
- return { connect };
25
- };
26
-
27
- export const useDisconnect = () => {
28
- const { client } = useCosmos();
29
-
30
- const disconnect = useCallback(async () => {
31
- return client.disconnect();
32
- }, [client]);
33
-
34
- return { disconnect };
35
- };
36
-
37
- export const useClient = () => {
38
- const { client } = useCosmos();
39
- return client;
40
- };
41
-
42
- export const useBalance = () => {
43
- const { state } = useCosmos();
44
- const [balance, setBalance] = useState<{ amount: string; denom: string } | null>(null);
45
- const [isLoading, setIsLoading] = useState(false);
46
-
47
- useEffect(() => {
48
- const address = state.account?.address;
49
- const rest = state.currentChain?.rest;
50
-
51
- if (address && rest) {
52
- setIsLoading(true);
53
- const fetchBalance = async () => {
54
- try {
55
- const res = await fetch(
56
- `${rest}/cosmos/bank/v1beta1/balances/${address}/by_denom?denom=uluna`
57
- );
58
- const data = await res.json();
59
- setBalance(data.balance || { amount: '0', denom: 'uluna' });
60
- } catch (error) {
61
- console.error('Failed to fetch balance:', error);
62
- } finally {
63
- setIsLoading(false);
64
- }
65
- };
66
- fetchBalance();
67
- } else {
68
- setBalance(null);
69
- }
70
- }, [state.account?.address, state.currentChain]);
71
-
72
- return { balance, isLoading };
73
- };
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- export * from './CosmosProvider.js';
2
- export * from './hooks.js';
3
- export * from './components/ConnectButton.js';
4
- export * from './components/ConnectModal.js';
5
- export * from './components/Avatar.js';
6
- import './styles.css';
package/src/styles.css DELETED
@@ -1,329 +0,0 @@
1
- :root {
2
- /* Official ConnectKit Tokens Refined */
3
- --ck-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
4
- --ck-border-radius: 20px;
5
- --ck-secondary-button-border-radius: 16px;
6
-
7
- --ck-body-background: #ffffff;
8
- --ck-body-color: #373737;
9
- --ck-body-color-muted: #999999;
10
- --ck-body-background-secondary: #f6f7f9;
11
- --ck-body-background-tertiary: #F3F4F7;
12
- --ck-body-divider: #f7f6f8;
13
-
14
- --ck-accent-color: #3b82f6;
15
- --ck-overlay-background: rgba(71, 88, 107, 0.24);
16
- }
17
-
18
- [data-theme='dark'] {
19
- --ck-body-background: #2B2B2B;
20
- --ck-body-color: #ffffff;
21
- --ck-body-color-muted: rgba(255, 255, 255, 0.4);
22
- --ck-body-background-secondary: #333333;
23
- --ck-body-background-tertiary: #333333;
24
- --ck-body-divider: #383838;
25
- --ck-overlay-background: rgba(0,0,0,0.4);
26
- }
27
-
28
- .cc-modal-overlay {
29
- position: fixed;
30
- top: 0;
31
- left: 0;
32
- right: 0;
33
- bottom: 0;
34
- background: var(--ck-overlay-background);
35
- display: flex;
36
- align-items: center;
37
- justify-content: center;
38
- z-index: 1000;
39
- backdrop-filter: blur(10px);
40
- }
41
-
42
- .cc-modal-content {
43
- background: var(--ck-body-background);
44
- color: var(--ck-body-color);
45
- width: 100%;
46
- max-width: 400px;
47
- border-radius: var(--ck-border-radius);
48
- box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.02), 0 20px 25px -5px rgba(0, 0, 0, 0.08);
49
- padding: 1.5rem;
50
- position: relative;
51
- font-family: var(--ck-font-family);
52
- overflow: hidden;
53
- }
54
-
55
- .cc-modal-header {
56
- display: flex;
57
- align-items: center;
58
- justify-content: space-between;
59
- margin-bottom: 1.5rem;
60
- min-height: 32px;
61
- }
62
-
63
- .cc-help-btn, .cc-back-btn {
64
- background: none;
65
- border: 1px solid var(--ck-body-divider);
66
- color: var(--ck-body-color-muted);
67
- width: 28px;
68
- height: 28px;
69
- border-radius: 50%;
70
- cursor: pointer;
71
- display: flex;
72
- align-items: center;
73
- justify-content: center;
74
- font-size: 0.875rem;
75
- transition: all 0.2s;
76
- z-index: 1;
77
- }
78
-
79
- .cc-help-btn:hover, .cc-back-btn:hover {
80
- background: var(--ck-body-background-secondary);
81
- color: var(--ck-body-color);
82
- }
83
-
84
- .cc-modal-title {
85
- position: absolute;
86
- left: 50%;
87
- transform: translateX(-50%);
88
- font-size: 1rem;
89
- font-weight: 700;
90
- letter-spacing: -0.01em;
91
- }
92
-
93
- .cc-close-btn {
94
- background: var(--ck-body-background-secondary);
95
- border: none;
96
- color: var(--ck-body-color-muted);
97
- width: 32px;
98
- height: 32px;
99
- border-radius: 50%;
100
- cursor: pointer;
101
- display: flex;
102
- align-items: center;
103
- justify-content: center;
104
- font-size: 1.25rem;
105
- transition: all 0.2s;
106
- z-index: 1;
107
- }
108
-
109
- /* Page Containers */
110
- .cc-modal-body {
111
- position: relative;
112
- }
113
-
114
- /* Wallet List */
115
- .cc-wallet-list {
116
- display: flex;
117
- flex-direction: column;
118
- gap: 0.5rem;
119
- }
120
-
121
- .cc-wallet-item {
122
- display: flex;
123
- align-items: center;
124
- justify-content: space-between;
125
- padding: 0.875rem 1.25rem;
126
- background: var(--ck-body-background-secondary);
127
- border: none;
128
- border-radius: var(--ck-secondary-button-border-radius);
129
- cursor: pointer;
130
- width: 100%;
131
- transition: all 0.2s ease;
132
- color: var(--ck-body-color);
133
- font-weight: 600;
134
- font-size: 1rem;
135
- }
136
-
137
- .cc-wallet-item:hover {
138
- background: var(--ck-body-background-tertiary);
139
- transform: scale(1.01);
140
- }
141
-
142
- .cc-wallet-icon {
143
- width: 32px;
144
- height: 32px;
145
- border-radius: 8px;
146
- }
147
-
148
- /* About View */
149
- .cc-about-steps {
150
- display: flex;
151
- flex-direction: column;
152
- gap: 1.25rem;
153
- margin-bottom: 2rem;
154
- }
155
-
156
- .cc-about-step {
157
- display: flex;
158
- gap: 1rem;
159
- align-items: flex-start;
160
- }
161
-
162
- .cc-step-num {
163
- background: var(--ck-body-background-secondary);
164
- color: var(--ck-body-color);
165
- width: 24px;
166
- height: 24px;
167
- border-radius: 6px;
168
- display: flex;
169
- align-items: center;
170
- justify-content: center;
171
- font-size: 0.75rem;
172
- font-weight: 800;
173
- flex-shrink: 0;
174
- margin-top: 2px;
175
- }
176
-
177
- .cc-step-content h4 {
178
- margin: 0 0 0.25rem 0;
179
- font-size: 0.9375rem;
180
- font-weight: 700;
181
- }
182
-
183
- .cc-step-content p {
184
- margin: 0;
185
- font-size: 0.8125rem;
186
- color: var(--ck-body-color-muted);
187
- line-height: 1.4;
188
- }
189
-
190
- /* Profile View */
191
- .cc-profile-view {
192
- display: flex;
193
- flex-direction: column;
194
- align-items: center;
195
- text-align: center;
196
- }
197
-
198
- .cc-profile-avatar {
199
- margin-bottom: 1.5rem;
200
- box-shadow: 0 0 0 8px rgba(59, 130, 246, 0.05);
201
- border-radius: 50%;
202
- }
203
-
204
- .cc-profile-address {
205
- font-size: 1.25rem;
206
- font-weight: 800;
207
- letter-spacing: -0.02em;
208
- margin-bottom: 0.25rem;
209
- }
210
-
211
- .cc-profile-balance {
212
- font-size: 1rem;
213
- font-weight: 600;
214
- color: var(--ck-body-color-muted);
215
- margin-bottom: 2rem;
216
- }
217
-
218
- .cc-profile-actions {
219
- display: grid;
220
- grid-template-columns: 1fr 1fr;
221
- gap: 0.75rem;
222
- width: 100%;
223
- margin-bottom: 1.5rem;
224
- }
225
-
226
- .cc-util-btn {
227
- padding: 0.75rem;
228
- background: var(--ck-body-background-secondary);
229
- border: none;
230
- border-radius: 12px;
231
- font-weight: 600;
232
- font-size: 0.875rem;
233
- color: var(--ck-body-color);
234
- cursor: pointer;
235
- transition: all 0.2s;
236
- }
237
-
238
- .cc-util-btn:hover {
239
- background: var(--ck-body-background-tertiary);
240
- }
241
-
242
- /* General Utilities */
243
- .cc-primary-btn {
244
- background: var(--ck-accent-color);
245
- color: white;
246
- width: 100%;
247
- padding: 0.875rem;
248
- border-radius: var(--ck-secondary-button-border-radius);
249
- border: none;
250
- font-weight: 700;
251
- font-size: 0.9375rem;
252
- cursor: pointer;
253
- transition: all 0.2s;
254
- }
255
-
256
- .cc-primary-btn:hover {
257
- filter: brightness(1.1);
258
- transform: translateY(-1px);
259
- }
260
-
261
- .cc-footer-btn {
262
- margin-top: 1.5rem;
263
- padding-top: 1.5rem;
264
- border-top: 1px solid var(--ck-body-divider);
265
- background: none;
266
- border: none;
267
- width: 100%;
268
- display: flex;
269
- align-items: center;
270
- justify-content: center;
271
- gap: 0.5rem;
272
- color: var(--ck-body-color-muted);
273
- font-size: 0.875rem;
274
- font-weight: 500;
275
- cursor: pointer;
276
- }
277
-
278
- .cc-footer-btn:hover {
279
- color: var(--ck-body-color);
280
- }
281
-
282
- /* Spinner */
283
- .cc-spinner-container {
284
- position: relative;
285
- width: 80px;
286
- height: 80px;
287
- margin: 0 auto 2rem auto;
288
- }
289
-
290
- .cc-spinner {
291
- width: 100%;
292
- height: 100%;
293
- border: 4px solid var(--ck-body-background-secondary);
294
- border-top-color: var(--ck-accent-color);
295
- border-radius: 50%;
296
- animation: cc-spin 1s linear infinite;
297
- }
298
-
299
- .cc-spinner-icon {
300
- position: absolute;
301
- top: 50%;
302
- left: 50%;
303
- transform: translate(-50%, -50%);
304
- width: 40px;
305
- height: 40px;
306
- border-radius: 10px;
307
- }
308
-
309
- @keyframes cc-spin { to { transform: rotate(360deg); } }
310
-
311
- /* Pill */
312
- .cc-pill {
313
- display: inline-flex;
314
- align-items: center;
315
- gap: 0.75rem;
316
- padding: 4px 12px 4px 4px;
317
- background: var(--ck-body-background);
318
- border: 1px solid var(--ck-body-divider);
319
- border-radius: 99px;
320
- cursor: pointer;
321
- font-weight: 600;
322
- color: var(--ck-body-color);
323
- transition: all 0.2s;
324
- }
325
-
326
- .cc-pill:hover {
327
- border-color: var(--ck-accent-color);
328
- box-shadow: 0 4px 12px rgba(0,0,0,0.05);
329
- }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "declaration": true,
7
- "outDir": "./dist",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "jsx": "react-jsx",
13
- "lib": ["dom", "dom.iterable", "esnext"]
14
- },
15
- "include": ["src/**/*"]
16
- }