Skip to content

Commit dac0701

Browse files
Refactor: Move all components to separate files (#379)
* Move ENS Resolution to separate file * lint fixes * Move send form to separate file * chore: refactor signature types to different components (#380) * chore: refactor signature types to different components * fix: injection order of components * Simplify loading a batch of modules * Use parentContainer pattern across all components * Migrate malformed transactions form And committing a naming crime, but we will allow it * Use event listeners for enabling buttons when connected This introduces a new parameters on `globalContext` called `_connected` with a getter and setter. When set to a new value, the setter dispatches a custom event `globalConnectionChange`. Each module with a button that needs to be enabled when MetaMask is connected thus has an event listener for that event. Now, those buttons are enabled via the listener. This gets us part way to relying on listeners for all state changes. * Move encrypt-decrypt to separate module * Migrate encrypt-decrypt and all PPOMs Also fix a few small errors from previous commits * Fix imports * fix: permit message verification (#382) * chore: Split transactions into separate components (#383) * chore: Split transactions into separate components * chore: add index.js to export all modules * chore: add index.js to export all modules * Move interactions section to module files * Move connections to separate files Unfortunately most of the connection logic is still in index.js and is hard to untangle * Wrap an error message in template string * Migrate type onchange handler to module * Move sendDeepLink href set to module * set deep links in erc20 component code * Fix glaring typo * Programmatic sections * lint fixes * Move more events and utils * Lint fix and remove array * Decentralize clearDisplayElements * No more allConnectedButtons * Change innerHTML to innerText * No more initializeFormElements * Move 1559-related DOM updates to separate files * Move updating DOM for deployed contract to separate files * Move updating network specific buttons to separate file * Simplify connection event logic * Two more custom events * Fix small error * Remove unneeded lint disable line * fix: enable defaults on wallet connect (#384) --------- Co-authored-by: Priya <priya.narayanaswamy@consensys.net>
1 parent 15cb01a commit dac0701

39 files changed

Lines changed: 5219 additions & 4644 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules
33
.vscode
44
dist
55
.eslintcache
6+
.DS_Store
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* import { walletConnect } from "../../connections"; */
2+
import globalContext from '../..';
3+
4+
export function connectionsComponent(parentContainer) {
5+
parentContainer.insertAdjacentHTML(
6+
'beforeend',
7+
`<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-12">
8+
<div class="card">
9+
<div class="card-body">
10+
<h4 class="card-title">
11+
Connect Actions
12+
</h4>
13+
14+
<button
15+
class="btn btn-primary btn-lg btn-block mb-3"
16+
id="connectButton"
17+
disabled
18+
>
19+
Connect
20+
</button>
21+
22+
<button
23+
class="btn btn-primary btn-lg btn-block mb-3"
24+
id="walletConnect"
25+
>
26+
Wallet Connect
27+
</button>
28+
<button
29+
class="btn btn-primary btn-lg btn-block mb-3"
30+
id="sdkConnect"
31+
>
32+
SDK Connect
33+
</button>
34+
<hr />
35+
<button
36+
class="btn btn-primary btn-lg btn-block mb-3"
37+
id="getAccounts"
38+
>
39+
eth_accounts
40+
</button>
41+
42+
<p class="info-text alert alert-secondary">
43+
eth_accounts result: <span id="getAccountsResult"></span>
44+
</p>
45+
</div>
46+
</div>
47+
</div>`,
48+
);
49+
50+
/*
51+
const onboardButton = document.getElementById('connectButton');
52+
const walletConnectBtn = document.getElementById('walletConnect');
53+
const sdkConnectBtn = document.getElementById('sdkConnect');
54+
*/
55+
const getAccounts = document.getElementById('getAccounts');
56+
const getAccountsResult = document.getElementById('getAccountsResult');
57+
58+
document.addEventListener('disableAndClear', function () {
59+
getAccountsResult.innerText = '';
60+
});
61+
62+
getAccounts.onclick = async () => {
63+
try {
64+
const _accounts = await globalContext.provider.request({
65+
method: 'eth_accounts',
66+
});
67+
getAccountsResult.innerHTML = _accounts || 'Not able to get accounts';
68+
} catch (err) {
69+
console.error(err);
70+
getAccountsResult.innerHTML = `Error: ${err.message}`;
71+
}
72+
};
73+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './connections';
2+
export * from './permissions';
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { getPermissionsDisplayString } from '../../utils';
2+
import globalContext from '../..';
3+
4+
export function permissionsComponent(parentContainer) {
5+
parentContainer.insertAdjacentHTML(
6+
'beforeend',
7+
`<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-12">
8+
<div class="card">
9+
<div class="card-body">
10+
<h4 class="card-title">
11+
Permissions Actions
12+
</h4>
13+
14+
<button
15+
class="btn btn-primary btn-lg btn-block mb-3"
16+
id="requestPermissions"
17+
>
18+
Request Permissions
19+
</button>
20+
21+
<button
22+
class="btn btn-primary btn-lg btn-block mb-3"
23+
id="getPermissions"
24+
>
25+
Get Permissions
26+
</button>
27+
<button
28+
class="btn btn-primary btn-lg btn-block mb-3"
29+
id="revokeAccountsPermission"
30+
>
31+
Revoke Accounts Permission
32+
</button>
33+
34+
<p class="info-text alert alert-secondary">
35+
Permissions result: <span id="permissionsResult"></span>
36+
</p>
37+
</div>
38+
</div>
39+
</div>`,
40+
);
41+
42+
const requestPermissions = document.getElementById('requestPermissions');
43+
const getPermissions = document.getElementById('getPermissions');
44+
const revokeAccountsPermission = document.getElementById(
45+
'revokeAccountsPermission',
46+
);
47+
const permissionsResult = document.getElementById('permissionsResult');
48+
49+
document.addEventListener('disableAndClear', function () {
50+
permissionsResult.innerText = '';
51+
});
52+
53+
requestPermissions.onclick = async () => {
54+
try {
55+
const permissionsArray = await globalContext.provider.request({
56+
method: 'wallet_requestPermissions',
57+
params: [{ eth_accounts: {} }],
58+
});
59+
permissionsResult.innerHTML =
60+
getPermissionsDisplayString(permissionsArray);
61+
} catch (err) {
62+
console.error(err);
63+
permissionsResult.innerHTML = `Error: ${err.message}`;
64+
}
65+
};
66+
67+
getPermissions.onclick = async () => {
68+
try {
69+
const permissionsArray = await globalContext.provider.request({
70+
method: 'wallet_getPermissions',
71+
});
72+
permissionsResult.innerHTML =
73+
getPermissionsDisplayString(permissionsArray);
74+
} catch (err) {
75+
console.error(err);
76+
permissionsResult.innerHTML = `Error: ${err.message}`;
77+
}
78+
};
79+
80+
revokeAccountsPermission.onclick = async () => {
81+
try {
82+
await globalContext.provider.request({
83+
method: 'wallet_revokePermissions',
84+
params: [
85+
{
86+
eth_accounts: {},
87+
},
88+
],
89+
});
90+
} catch (err) {
91+
permissionsResult.innerHTML = `${err.message}`;
92+
}
93+
};
94+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import { encrypt } from '@metamask/eth-sig-util';
2+
import { stringifiableToHex } from '../../utils';
3+
import globalContext from '../..';
4+
5+
export function encryptDecryptComponent(parentContainer) {
6+
parentContainer.insertAdjacentHTML(
7+
'beforeend',
8+
`<div class="row d-flex justify-content-center">
9+
<div class="col-xl-4 col-lg-6 col-md-12 col-sm-12 col-12">
10+
<div class="card">
11+
<div class="card-body">
12+
<h4 class="card-title">
13+
Encrypt / Decrypt
14+
</h4>
15+
16+
<button
17+
class="btn btn-primary btn-lg btn-block mb-3"
18+
id="getEncryptionKeyButton"
19+
disabled
20+
>
21+
Get Encryption Key
22+
</button>
23+
24+
<hr />
25+
26+
<div id="encrypt-message-form">
27+
<input
28+
class="form-control"
29+
type="text"
30+
placeholder="Message to encrypt"
31+
id="encryptMessageInput"
32+
/>
33+
34+
<button
35+
class="btn btn-primary btn-lg btn-block mb-3"
36+
id="encryptButton"
37+
disabled
38+
>
39+
Encrypt
40+
</button>
41+
</div>
42+
43+
<hr />
44+
45+
<button
46+
class="btn btn-primary btn-lg btn-block mb-3"
47+
id="decryptButton"
48+
disabled
49+
>
50+
Decrypt
51+
</button>
52+
53+
<p class="info-text alert alert-secondary">
54+
Encryption key: <span id="encryptionKeyDisplay"></span>
55+
</p>
56+
57+
<p class="info-text text-truncate alert alert-secondary">
58+
Ciphertext: <span id="ciphertextDisplay"></span>
59+
</p>
60+
61+
<p class="info-text alert alert-secondary">
62+
Cleartext: <span id="cleartextDisplay"></span>
63+
</p>
64+
</div>
65+
</div>
66+
</div>
67+
</div>`,
68+
);
69+
70+
const getEncryptionKeyButton = document.getElementById(
71+
'getEncryptionKeyButton',
72+
);
73+
const encryptMessageInput = document.getElementById('encryptMessageInput');
74+
const encryptButton = document.getElementById('encryptButton');
75+
const decryptButton = document.getElementById('decryptButton');
76+
const encryptionKeyDisplay = document.getElementById('encryptionKeyDisplay');
77+
const ciphertextDisplay = document.getElementById('ciphertextDisplay');
78+
const cleartextDisplay = document.getElementById('cleartextDisplay');
79+
80+
document.addEventListener('globalConnectionChange', function (e) {
81+
if (e.detail.connected) {
82+
// MetaMask is connected, enable the button
83+
getEncryptionKeyButton.disabled = false;
84+
}
85+
});
86+
87+
document.addEventListener('disableAndClear', function () {
88+
getEncryptionKeyButton.disabled = true;
89+
encryptMessageInput.disabled = true;
90+
encryptButton.disabled = true;
91+
decryptButton.disabled = true;
92+
encryptionKeyDisplay.innerText = '';
93+
encryptMessageInput.value = '';
94+
ciphertextDisplay.innerText = '';
95+
cleartextDisplay.innerText = '';
96+
});
97+
98+
/**
99+
* Encrypt / Decrypt
100+
*/
101+
102+
getEncryptionKeyButton.onclick = async () => {
103+
try {
104+
encryptionKeyDisplay.innerText = await globalContext.provider.request({
105+
method: 'eth_getEncryptionPublicKey',
106+
params: [globalContext.accounts[0]],
107+
});
108+
encryptMessageInput.disabled = false;
109+
} catch (error) {
110+
encryptionKeyDisplay.innerText = `Error: ${error.message}`;
111+
encryptMessageInput.disabled = true;
112+
encryptButton.disabled = true;
113+
decryptButton.disabled = true;
114+
}
115+
};
116+
117+
encryptMessageInput.onkeyup = () => {
118+
if (
119+
!getEncryptionKeyButton.disabled &&
120+
encryptMessageInput.value.length > 0
121+
) {
122+
if (encryptButton.disabled) {
123+
encryptButton.disabled = false;
124+
}
125+
} else if (!encryptButton.disabled) {
126+
encryptButton.disabled = true;
127+
}
128+
};
129+
130+
encryptButton.onclick = () => {
131+
try {
132+
ciphertextDisplay.innerText = stringifiableToHex(
133+
encrypt({
134+
publicKey: encryptionKeyDisplay.innerText,
135+
data: encryptMessageInput.value,
136+
version: 'x25519-xsalsa20-poly1305',
137+
}),
138+
);
139+
decryptButton.disabled = false;
140+
} catch (error) {
141+
ciphertextDisplay.innerText = `Error: ${error.message}`;
142+
decryptButton.disabled = true;
143+
}
144+
};
145+
146+
decryptButton.onclick = async () => {
147+
try {
148+
cleartextDisplay.innerText = await globalContext.provider.request({
149+
method: 'eth_decrypt',
150+
params: [ciphertextDisplay.innerText, globalContext.accounts[0]],
151+
});
152+
} catch (error) {
153+
cleartextDisplay.innerText = `Error: ${error.message}`;
154+
}
155+
};
156+
}

0 commit comments

Comments
 (0)