@monygroupcorp/micro-web3 0.1.1 → 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/dist/micro-web3.cjs.js +2 -2
- package/dist/micro-web3.cjs.js.map +1 -1
- package/dist/micro-web3.esm.js +2 -2
- package/dist/micro-web3.esm.js.map +1 -1
- package/dist/micro-web3.umd.js +2 -2
- package/dist/micro-web3.umd.js.map +1 -1
- package/monygroupcorp-micro-web3-0.1.3.tgz +0 -0
- package/package.json +1 -1
- package/src/components/FloatingWalletButton/FloatingWalletButton.js +10 -5
- package/src/components/WalletButton/WalletButton.js +213 -0
- package/src/index.js +3 -1
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monygroupcorp/micro-web3",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A lean, reusable Web3 toolkit with components for wallet connection, IPFS, and common Web3 UI patterns.",
|
|
5
5
|
"main": "dist/micro-web3.cjs.js",
|
|
6
6
|
"module": "dist/micro-web3.esm.js",
|
|
@@ -230,13 +230,19 @@ export class FloatingWalletButton extends Component {
|
|
|
230
230
|
|
|
231
231
|
// Create WalletModal if not exists
|
|
232
232
|
if (!this.walletModal) {
|
|
233
|
-
this.walletModal = new WalletModal(
|
|
233
|
+
this.walletModal = new WalletModal({
|
|
234
234
|
providerMap,
|
|
235
235
|
walletIcons,
|
|
236
|
-
async (walletType) => {
|
|
236
|
+
onWalletSelected: async (walletType) => {
|
|
237
237
|
await this.handleWalletSelection(walletType);
|
|
238
|
-
}
|
|
239
|
-
);
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
if (!this.modalRoot) {
|
|
242
|
+
this.modalRoot = document.createElement('div');
|
|
243
|
+
document.body.appendChild(this.modalRoot);
|
|
244
|
+
}
|
|
245
|
+
this.walletModal.mount(this.modalRoot);
|
|
240
246
|
}
|
|
241
247
|
|
|
242
248
|
this.walletModal.show();
|
|
@@ -672,4 +678,3 @@ export class FloatingWalletButton extends Component {
|
|
|
672
678
|
return div.innerHTML;
|
|
673
679
|
}
|
|
674
680
|
}
|
|
675
|
-
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { FloatingWalletButton } from '../FloatingWalletButton/FloatingWalletButton.js';
|
|
2
|
+
import WalletModal from '../Wallet/WalletModal.js';
|
|
3
|
+
|
|
4
|
+
class WalletButtonModal extends WalletModal {
|
|
5
|
+
events() {
|
|
6
|
+
const baseEvents = typeof super.events === 'function' ? super.events() : {};
|
|
7
|
+
return {
|
|
8
|
+
...baseEvents,
|
|
9
|
+
'click .wallet-option': async (e) => {
|
|
10
|
+
const button = e?.target?.closest?.('.wallet-option');
|
|
11
|
+
const walletType = button?.dataset?.wallet;
|
|
12
|
+
if (!walletType) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (this.onWalletSelected) {
|
|
16
|
+
await this.onWalletSelected(walletType);
|
|
17
|
+
}
|
|
18
|
+
this.hide();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class WalletButton extends FloatingWalletButton {
|
|
25
|
+
constructor(props) {
|
|
26
|
+
super(props);
|
|
27
|
+
this.modalRoot = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async showWalletModal() {
|
|
31
|
+
const providerMap =
|
|
32
|
+
this.walletService?.providerMap ||
|
|
33
|
+
{
|
|
34
|
+
rabby: () => (window.ethereum?.isRabby ? window.ethereum : null),
|
|
35
|
+
rainbow: () => (window.ethereum?.isRainbow ? window.ethereum : null),
|
|
36
|
+
phantom: () => window.phantom?.ethereum || null,
|
|
37
|
+
metamask: () => window.ethereum || null,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const walletIcons =
|
|
41
|
+
this.walletService?.walletIcons ||
|
|
42
|
+
{
|
|
43
|
+
rabby: '/public/wallets/rabby.webp',
|
|
44
|
+
rainbow: '/public/wallets/rainbow.webp',
|
|
45
|
+
phantom: '/public/wallets/phantom.webp',
|
|
46
|
+
metamask: '/public/wallets/MetaMask.webp',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
if (!this.walletModal) {
|
|
50
|
+
this.walletModal = new WalletButtonModal({
|
|
51
|
+
providerMap,
|
|
52
|
+
walletIcons,
|
|
53
|
+
onWalletSelected: async (walletType) => {
|
|
54
|
+
await this.handleWalletSelection(walletType);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (!this.modalRoot) {
|
|
59
|
+
this.modalRoot = document.createElement('div');
|
|
60
|
+
document.body.appendChild(this.modalRoot);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.walletModal.mount(this.modalRoot);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.walletModal.show();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
onUnmount() {
|
|
70
|
+
if (this.modalRoot?.parentNode) {
|
|
71
|
+
this.modalRoot.parentNode.removeChild(this.modalRoot);
|
|
72
|
+
this.modalRoot = null;
|
|
73
|
+
}
|
|
74
|
+
super.onUnmount();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
render() {
|
|
78
|
+
if (this.state.loading) {
|
|
79
|
+
return `
|
|
80
|
+
<div class="floating-wallet-button loading">
|
|
81
|
+
<div class="wallet-spinner"></div>
|
|
82
|
+
</div>
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { walletConnected, address, balance, menuOpen } = this.state;
|
|
87
|
+
|
|
88
|
+
if (!walletConnected) {
|
|
89
|
+
return `
|
|
90
|
+
<div class="floating-wallet-button disconnected" data-ref="wallet-button">
|
|
91
|
+
<button class="wallet-btn" data-ref="connect-btn">
|
|
92
|
+
<span class="wallet-mark"></span>
|
|
93
|
+
<span class="wallet-text">Connect Wallet</span>
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const truncatedAddress = `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
100
|
+
const classNames = ['floating-wallet-button', 'connected'];
|
|
101
|
+
if (menuOpen) {
|
|
102
|
+
classNames.push('menu-open');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const markup = `
|
|
106
|
+
<div class="${classNames.join(' ')}" data-ref="wallet-button">
|
|
107
|
+
<button class="wallet-btn" data-ref="wallet-btn" title="${this.escapeHtml(address)}\nBalance: ${balance} ETH">
|
|
108
|
+
<span class="wallet-mark wallet-mark--connected"></span>
|
|
109
|
+
<span class="wallet-address">${this.escapeHtml(truncatedAddress)}</span>
|
|
110
|
+
<span class="wallet-disconnect" data-ref="inline-disconnect" title="Disconnect">⏏︎</span>
|
|
111
|
+
</button>
|
|
112
|
+
${this.renderWalletPanel(address, balance, menuOpen)}
|
|
113
|
+
</div>
|
|
114
|
+
`;
|
|
115
|
+
|
|
116
|
+
return this.minifyHtml(markup);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
events() {
|
|
120
|
+
const baseEvents = super.events?.() || {};
|
|
121
|
+
return {
|
|
122
|
+
...baseEvents,
|
|
123
|
+
'click [data-ref="inline-disconnect"]': (e) => this.handleInlineDisconnect(e),
|
|
124
|
+
'click [data-ref="wallet-btn"]': (e) => this.handleWalletToggle(e),
|
|
125
|
+
'click [data-ref="connect-btn"]': (e) => this.handleWalletToggle(e),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
renderWalletPanel(address, balance, menuOpen) {
|
|
130
|
+
const truncatedAddress = `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
131
|
+
|
|
132
|
+
const markup = `
|
|
133
|
+
<div class="wallet-info-panel" data-ref="wallet-panel" aria-hidden="${menuOpen ? 'false' : 'true'}">
|
|
134
|
+
<div class="wallet-info-row">
|
|
135
|
+
<span class="wallet-info-label">Address</span>
|
|
136
|
+
<span class="wallet-info-value">${this.escapeHtml(truncatedAddress)}</span>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="wallet-info-row">
|
|
139
|
+
<span class="wallet-info-label">ETH Balance</span>
|
|
140
|
+
<span class="wallet-info-value">${balance} ETH</span>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
return this.minifyHtml(markup);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
onStateUpdate(oldState, newState) {
|
|
149
|
+
if (typeof super.onStateUpdate === 'function') {
|
|
150
|
+
super.onStateUpdate(oldState, newState);
|
|
151
|
+
}
|
|
152
|
+
if (!oldState || oldState.menuOpen !== newState.menuOpen) {
|
|
153
|
+
if (newState.menuOpen) {
|
|
154
|
+
this.attachOutsideClickListener();
|
|
155
|
+
} else {
|
|
156
|
+
this.detachOutsideClickListener();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
attachOutsideClickListener() {
|
|
162
|
+
if (this.outsideClickHandler || this.outsideClickTimeout) return;
|
|
163
|
+
this.outsideClickHandler = (event) => {
|
|
164
|
+
if (!this.element) return;
|
|
165
|
+
const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
|
|
166
|
+
const clickedInside =
|
|
167
|
+
(path.length && path.includes(this.element)) ||
|
|
168
|
+
(event.target && this.element.contains(event.target));
|
|
169
|
+
if (!clickedInside) {
|
|
170
|
+
this.setState({ menuOpen: false });
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
this.outsideClickTimeout = window.setTimeout(() => {
|
|
174
|
+
document.addEventListener('click', this.outsideClickHandler);
|
|
175
|
+
this.outsideClickTimeout = null;
|
|
176
|
+
}, 0);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
detachOutsideClickListener() {
|
|
180
|
+
if (this.outsideClickTimeout) {
|
|
181
|
+
window.clearTimeout(this.outsideClickTimeout);
|
|
182
|
+
this.outsideClickTimeout = null;
|
|
183
|
+
}
|
|
184
|
+
if (this.outsideClickHandler) {
|
|
185
|
+
document.removeEventListener('click', this.outsideClickHandler);
|
|
186
|
+
this.outsideClickHandler = null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
setupDOMEventListeners() {
|
|
191
|
+
// Delegated events handle wiring in this component.
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
handleWalletToggle(e) {
|
|
195
|
+
this.handleButtonClick(e);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
handleInlineDisconnect(e) {
|
|
199
|
+
if (e) {
|
|
200
|
+
e.preventDefault();
|
|
201
|
+
e.stopPropagation();
|
|
202
|
+
}
|
|
203
|
+
super.handleDisconnect(e);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
minifyHtml(markup) {
|
|
207
|
+
return typeof markup === 'string'
|
|
208
|
+
? markup.replace(/>\s+</g, '><').trim()
|
|
209
|
+
: markup;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export default WalletButton;
|
package/src/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import * as IpfsService from './services/IpfsService.js';
|
|
|
7
7
|
|
|
8
8
|
// UI Components
|
|
9
9
|
import { FloatingWalletButton } from './components/FloatingWalletButton/FloatingWalletButton.js';
|
|
10
|
+
import { WalletButton } from './components/WalletButton/WalletButton.js';
|
|
10
11
|
import { WalletModal } from './components/Wallet/WalletModal.js';
|
|
11
12
|
import { IpfsImage } from './components/Ipfs/IpfsImage.js';
|
|
12
13
|
import { SwapInterface } from './components/Swap/SwapInterface.js';
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
|
|
30
31
|
// UI Components
|
|
31
32
|
FloatingWalletButton,
|
|
33
|
+
WalletButton,
|
|
32
34
|
WalletModal,
|
|
33
35
|
IpfsImage,
|
|
34
36
|
SwapInterface,
|
|
@@ -40,4 +42,4 @@ export {
|
|
|
40
42
|
PriceDisplay,
|
|
41
43
|
BalanceDisplay,
|
|
42
44
|
MessagePopup
|
|
43
|
-
};
|
|
45
|
+
};
|