From ba183e813bb7156ea8624a9d20fd28d0167d481a Mon Sep 17 00:00:00 2001
From: Brent
Date: Fri, 1 Jul 2022 14:45:22 -0400
Subject: [PATCH 1/7] mnemonic import split
---
packages/test-project/tests/common/tests.js | 7 +-
packages/ui/src/pages/ImportAccount.ts | 249 ++++++++++++++++++--
2 files changed, 239 insertions(+), 17 deletions(-)
diff --git a/packages/test-project/tests/common/tests.js b/packages/test-project/tests/common/tests.js
index ca6abfbf..0481f472 100644
--- a/packages/test-project/tests/common/tests.js
+++ b/packages/test-project/tests/common/tests.js
@@ -50,7 +50,12 @@ function ImportAccount(account) {
await extensionPage.click('#importAccount');
await extensionPage.waitForSelector('#accountName');
await extensionPage.type('#accountName', account.name);
- await extensionPage.type('#enterMnemonic', account.mnemonic);
+ const accountMnemonic = account.mnemonic.split(' ');
+ for (let i = 0; i < accountMnemonic.length; i++) {
+ const mnemonicWordId = '#mnemonicWord' + i;
+ await extensionPage.type(mnemonicWordId, accountMnemonic[i]);
+ }
+ await extensionPage.waitForTimeout(200);
await extensionPage.click('#nextStep');
await inputPassword();
await extensionPage.waitForTimeout(2000);
diff --git a/packages/ui/src/pages/ImportAccount.ts b/packages/ui/src/pages/ImportAccount.ts
index 393ae1c2..a118198b 100644
--- a/packages/ui/src/pages/ImportAccount.ts
+++ b/packages/ui/src/pages/ImportAccount.ts
@@ -1,6 +1,6 @@
import { FunctionalComponent } from 'preact';
import { html } from 'htm/preact';
-import { useState, useContext } from 'preact/hooks';
+import { useState, useContext, useEffect } from 'preact/hooks';
import { route } from 'preact-router';
import { JsonRpcMethod } from '@algosigner/common/messaging/types';
@@ -14,8 +14,9 @@ import algosdk from 'algosdk';
const ImportAccount: FunctionalComponent = (props: any) => {
const store: any = useContext(StoreContext);
+ const wordsNumber = 25;
const { ledger } = props;
- const [mnemonic, setMnemonic] = useState('');
+ const [mnemonicArray, setMnemonicArray] = useState>(new Array(wordsNumber));
const [address, setAddress] = useState('');
const [isRef, setIsRef] = useState(false);
const [name, setName] = useState('');
@@ -24,16 +25,15 @@ const ImportAccount: FunctionalComponent = (props: any) => {
const [authError, setAuthError] = useState('');
const [error, setError] = useState('');
- const matches = mnemonic.trim().split(/[\s\t\r\n]+/) || [];
const disabled =
name.trim().length === 0 ||
- (!isRef && matches.length !== 25) ||
+ (!isRef && (mnemonicArray.length !== 25 || mnemonicArray.some((e) => e === ''))) ||
(isRef && !algosdk.isValidAddress(address));
const importAccount = (pwd: string) => {
const params = {
passphrase: pwd,
- mnemonic: matches.join(' '),
+ mnemonic: mnemonicArray.join(' '),
address: address,
isRef: isRef,
name: name.trim(),
@@ -64,13 +64,61 @@ const ImportAccount: FunctionalComponent = (props: any) => {
};
const handleMnemonicInput = (e) => {
- setMnemonic(e.target.value);
+ const localMnemonicArray = mnemonicArray;
+ const inputText = e.target.value.toString().trim();
+ const inputArray = inputText.split(/[\s\t\r\n,]+/);
+
+ // If it is a single word then update that word placement in the array
+ if (inputArray.length === 1) {
+ localMnemonicArray[e.target.id.toString().replace('mnemonicWord', '')] = inputText;
+ }
+ // If it is multiple words then verify there are 25 and split
+ else if (inputArray.length === wordsNumber) {
+ for(let i = 0; i < wordsNumber; i++) {
+ localMnemonicArray[i.toString()] = inputArray[i].trim();
+ }
+
+ // For the case the user is typing the full mnemonic
+ // after the split the last element will be empty
+ // so we must focust that element now to continue typing
+ const element = document.getElementById('mnemonicWord24');
+ if (element) {
+ element.focus();
+ }
+
+ }
+ // If it is multiple words but they are not 25 then warn, but allow for typing out 25.
+ else {
+ console.log('[WARNING] - Mnemonic words must be a single word or the entire 25 mnemonic.')
+ localMnemonicArray[e.target.id.toString().replace('mnemonicWord', '')] = inputText;
+ }
+
+ setMnemonicArray([]);
+ setMnemonicArray(localMnemonicArray);
};
const handleAddressInput = (e) => {
setAddress(e.target.value);
};
+ const handleMnemonicIconClick = (iconNumber) => {
+ // Mnemonic boxes are prefixed with "mnemonicWord"
+ const wordId = 'mnemonicWord' + iconNumber;
+ const element = document.getElementById(wordId);
+
+ // As long as we can locate the element just swap the show/hide icon and text/password
+ if (element !== null) {
+ if (element['type'] === 'password') {
+ element['type'] = 'text';
+ element.parentElement?.querySelectorAll('svg')[0]?.setAttribute('data-icon','eye');
+ }
+ else {
+ element['type'] = 'password';
+ element.parentElement?.querySelectorAll('svg')[0]?.setAttribute('data-icon','eye-slash');
+ }
+ }
+ }
+
return html`
<${HeaderView} action="${() => route('/wallet')}" title="Import ${ledger} account" />
@@ -122,17 +170,186 @@ const ImportAccount: FunctionalComponent = (props: any) => {
`}
${!isRef &&
html`
-
Insert the 25 word mnemonic of the account:
-
+
Insert the 25 word mnemonic of the account:
+
`}
-
+
${error !== undefined && error.length > 0 && error}
From 867641ef0d9498aa94b8213512440ccca66e7778 Mon Sep 17 00:00:00 2001
From: Jan Marcano
Date: Mon, 4 Jul 2022 14:01:58 -0300
Subject: [PATCH 2/7] Improve Cache clearing
---
packages/common/src/messaging/types.ts | 1 +
.../background/messaging/internalMethods.ts | 24 +++++++++++++++----
.../src/background/messaging/task.ts | 8 +++----
.../extension/src/background/utils/helper.ts | 2 +-
packages/ui/src/components/SettingsMenu.ts | 8 ++++---
5 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/packages/common/src/messaging/types.ts b/packages/common/src/messaging/types.ts
index 4f287471..cf97d40d 100644
--- a/packages/common/src/messaging/types.ts
+++ b/packages/common/src/messaging/types.ts
@@ -29,6 +29,7 @@ export enum JsonRpcMethod {
GetSession = 'get-session',
Login = 'login',
Logout = 'logout',
+ ClearCache = 'clear-cache',
AccountDetails = 'account-details',
Transactions = 'transactions',
AssetDetails = 'asset-details',
diff --git a/packages/extension/src/background/messaging/internalMethods.ts b/packages/extension/src/background/messaging/internalMethods.ts
index c071531e..04d5482a 100644
--- a/packages/extension/src/background/messaging/internalMethods.ts
+++ b/packages/extension/src/background/messaging/internalMethods.ts
@@ -273,6 +273,21 @@ export class InternalMethods {
return true;
}
+ public static [JsonRpcMethod.Logout](request: any, sendResponse: Function) {
+ InternalMethods.clearSession();
+ Task.clearPool();
+ sendResponse(true);
+ return true;
+ }
+
+ public static [JsonRpcMethod.ClearCache](request: any, sendResponse: Function) {
+ const extensionStorage = new ExtensionStorage();
+ extensionStorage.setStorage('cache', initializeCache(), (isSuccessful) =>
+ sendResponse(isSuccessful)
+ );
+ return true;
+ }
+
public static [JsonRpcMethod.CreateAccount](request: any, sendResponse: Function) {
var keys = algosdk.generateAccount();
var mnemonic = algosdk.secretKeyToMnemonic(keys.sk);
@@ -583,20 +598,19 @@ export class InternalMethods {
// Check for asset details saved in storage, if needed
if ('assets' in res && res.assets.length > 0) {
- const missingAssets = [];
+ const assetDetails = [];
for (var i = res.assets.length - 1; i >= 0; i--) {
const assetId = res.assets[i]['asset-id'];
if (assetId in cache.assets[ledger]) {
res.assets[i] = {
- ...res.assets[i],
...cache.assets[ledger][assetId],
+ ...res.assets[i],
};
- } else {
- missingAssets.push(assetId);
}
+ assetDetails.push(assetId);
}
- if (missingAssets.length > 0) AssetsDetailsHelper.add(missingAssets, ledger);
+ if (assetDetails.length > 0) AssetsDetailsHelper.add(assetDetails, ledger);
res.assets.sort((a, b) => a['asset-id'] - b['asset-id']);
}
diff --git a/packages/extension/src/background/messaging/task.ts b/packages/extension/src/background/messaging/task.ts
index c6e427aa..562fc027 100644
--- a/packages/extension/src/background/messaging/task.ts
+++ b/packages/extension/src/background/messaging/task.ts
@@ -1275,11 +1275,11 @@ export class Task {
[JsonRpcMethod.Login]: (request: any, sendResponse: Function) => {
return InternalMethods[JsonRpcMethod.Login](request, sendResponse);
},
- /* eslint-disable-next-line no-unused-vars */
[JsonRpcMethod.Logout]: (request: any, sendResponse: Function) => {
- InternalMethods.clearSession();
- Task.clearPool();
- sendResponse(true);
+ return InternalMethods[JsonRpcMethod.Logout](request, sendResponse);
+ },
+ [JsonRpcMethod.ClearCache]: (request: any, sendResponse: Function) => {
+ return InternalMethods[JsonRpcMethod.ClearCache](request, sendResponse);
},
[JsonRpcMethod.GetSession]: (request: any, sendResponse: Function) => {
return InternalMethods[JsonRpcMethod.GetSession](request, sendResponse);
diff --git a/packages/extension/src/background/utils/helper.ts b/packages/extension/src/background/utils/helper.ts
index 9f333ace..dd577d23 100644
--- a/packages/extension/src/background/utils/helper.ts
+++ b/packages/extension/src/background/utils/helper.ts
@@ -17,7 +17,7 @@ export function getIndexer(ledger: string) {
// Helper function to initialize Cache
export function initializeCache(
- c: Cache | undefined,
+ c: Cache | undefined = undefined,
ledger: Ledger | undefined = undefined
): Cache {
let cache: Cache;
diff --git a/packages/ui/src/components/SettingsMenu.ts b/packages/ui/src/components/SettingsMenu.ts
index f7d4ff70..7864c0c8 100644
--- a/packages/ui/src/components/SettingsMenu.ts
+++ b/packages/ui/src/components/SettingsMenu.ts
@@ -35,9 +35,11 @@ const SettingsMenu: FunctionalComponent = () => {
};
const clearCache = () => {
- store.clearCache(() => {
- route('/wallet');
- flip();
+ sendMessage(JsonRpcMethod.ClearCache, {}, function () {
+ store.clearCache(() => {
+ route('/wallet');
+ flip();
+ });
});
};
From 15fd74841c52eb0cc150842532d50c86af7fc451 Mon Sep 17 00:00:00 2001
From: Brent
Date: Tue, 5 Jul 2022 13:50:50 -0400
Subject: [PATCH 3/7] Adjust spacing for vertical scroll bar
---
packages/ui/src/pages/ImportAccount.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/ui/src/pages/ImportAccount.ts b/packages/ui/src/pages/ImportAccount.ts
index a118198b..9d550d41 100644
--- a/packages/ui/src/pages/ImportAccount.ts
+++ b/packages/ui/src/pages/ImportAccount.ts
@@ -350,7 +350,7 @@ const ImportAccount: FunctionalComponent = (props: any) => {
`}
-
+
${error !== undefined && error.length > 0 && error}
From f79b772298f86f30bb3fc8717fa842892d37ca61 Mon Sep 17 00:00:00 2001
From: Brent
Date: Tue, 5 Jul 2022 15:51:42 -0400
Subject: [PATCH 4/7] Update wording for import
---
packages/ui/src/pages/ImportAccount.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/packages/ui/src/pages/ImportAccount.ts b/packages/ui/src/pages/ImportAccount.ts
index 9d550d41..0c6e02d1 100644
--- a/packages/ui/src/pages/ImportAccount.ts
+++ b/packages/ui/src/pages/ImportAccount.ts
@@ -170,7 +170,14 @@ const ImportAccount: FunctionalComponent = (props: any) => {
`}
${!isRef &&
html`
- Insert the 25 word mnemonic of the account:
+
+
+ Insert the 25 word mnemonic of the account
+
+
+ (Entire mnemonic may be pasted into a single field):
+
+
From d0c4e8f2e21590754346313dbe22784cec09cc7a Mon Sep 17 00:00:00 2001
From: Jan Marcano
Date: Wed, 6 Jul 2022 14:08:26 -0300
Subject: [PATCH 5/7] Patch 1.9.2
---
.github/release-drafter.yml | 2 +-
.nvmrc | 2 +-
README.md | 5 ++++-
docs/connection-issues.md | 4 ----
packages/common/package.json | 2 +-
packages/crypto/package.json | 4 ++--
packages/dapp/package.json | 2 +-
packages/extension/manifest.json | 2 +-
packages/extension/package.json | 2 +-
packages/storage/package.json | 4 ++--
packages/test-project/package.json | 2 +-
packages/ui/package.json | 2 +-
12 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
index 56043a45..3c778438 100644
--- a/.github/release-drafter.yml
+++ b/.github/release-drafter.yml
@@ -1,4 +1,4 @@
template: |
- ## Patch X.Y.Z
+ ## Updates
$CHANGES
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
index d3d3a1a9..90e4166a 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-12.15
+16.15
diff --git a/README.md b/README.md
index 14807e76..c27bda8d 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Developers working with dApps may also install directly from the release package
An interactive transition guide is available [here](https://purestake.github.io/algosigner-dapp-example/v1v2TransitionGuide.html).
-## 1.9.1 Release
+## 1.9.2 Release
### Main updates
This update adds supports for easier transfers with the new autocomplete feature. Start typing an account, contact name or name service alias on the destination field when sending Algos or ASAs and you'll be able to select the desired address from a dropdown. This also marks the end of the support of the older signing methods that were previously available.
@@ -24,6 +24,9 @@ This update adds supports for easier transfers with the new autocomplete feature
- External name services (NFDomains and Algorand Namespace Service)
- `AlgoSigner.sign()` and `AlgoSigner.signMultisig()` have been deprecated
+### Other updates
+- Improved Account Importing and Cache Clearing
+
## New Users
- Watch [Getting Started with AlgoSigner](https://youtu.be/tG-xzG8r770)
diff --git a/docs/connection-issues.md b/docs/connection-issues.md
index 29d50318..7a10abfb 100644
--- a/docs/connection-issues.md
+++ b/docs/connection-issues.md
@@ -8,23 +8,19 @@ Find and press any disconnect button present on the dApp.
-
Open the config menu and log out of AlgoSigner.
-
Reload the tab/window where the dApp is open and attempt to connect again.
-
-
## Additional steps
diff --git a/packages/common/package.json b/packages/common/package.json
index 82728264..e3b8d2fb 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -1,6 +1,6 @@
{
"name": "@algosigner/common",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
"description": "Common library functions for AlgoSigner.",
"repository": "https://github.com/PureStake/algosigner",
diff --git a/packages/crypto/package.json b/packages/crypto/package.json
index c3f5987e..9ebd1191 100644
--- a/packages/crypto/package.json
+++ b/packages/crypto/package.json
@@ -1,8 +1,8 @@
{
"name": "algosigner-crypto",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
- "description": "Cryptographic wrapper for saving and retrieving extention information in Algosigner.",
+ "description": "Cryptographic wrapper for saving and retrieving extention information in AlgoSigner.",
"repository": {
"type": "git",
"url": "https://github.com/PureStake/algosigner/packages/crypto.git"
diff --git a/packages/dapp/package.json b/packages/dapp/package.json
index bba0a1d3..86aabc75 100644
--- a/packages/dapp/package.json
+++ b/packages/dapp/package.json
@@ -1,6 +1,6 @@
{
"name": "@algosigner/dapp",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
"repository": "https://github.com/PureStake/algosigner",
"license": "MIT",
diff --git a/packages/extension/manifest.json b/packages/extension/manifest.json
index 65117c23..b145ff9c 100644
--- a/packages/extension/manifest.json
+++ b/packages/extension/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "AlgoSigner",
"author": "https://developer.purestake.io",
- "version": "1.9.1",
+ "version": "1.9.2",
"description": "Algorand Wallet Extension | Send & Receive ALGOs | Sign dApp Transactions",
"icons": {
"48": "icon.png"
diff --git a/packages/extension/package.json b/packages/extension/package.json
index 498f0714..9ed4a224 100644
--- a/packages/extension/package.json
+++ b/packages/extension/package.json
@@ -1,6 +1,6 @@
{
"name": "algosigner-extension",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
"repository": "https://github.com/PureStake/algosigner",
"license": "MIT",
diff --git a/packages/storage/package.json b/packages/storage/package.json
index 9f3b60f9..8852dc1f 100644
--- a/packages/storage/package.json
+++ b/packages/storage/package.json
@@ -1,10 +1,10 @@
{
"name": "algosigner-storage",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
"repository": "https://github.com/PureStake/algosigner",
"license": "MIT",
- "description": "Storage wrapper for saving and retrieving extention information in Algosigner.",
+ "description": "Storage wrapper for saving and retrieving extention information in AlgoSigner.",
"devDependencies": {
"ts-loader": "^9.2.6",
"typescript": "^4.4.4",
diff --git a/packages/test-project/package.json b/packages/test-project/package.json
index 91eed2f1..228dc84a 100644
--- a/packages/test-project/package.json
+++ b/packages/test-project/package.json
@@ -1,6 +1,6 @@
{
"name": "algorand-test-project",
- "version": "1.9.1",
+ "version": "1.9.2",
"repository": "https://github.com/PureStake/algosigner",
"license": "MIT",
"description": "Repository for tests",
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 1d9c3430..5daece6b 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "algosigner-ui",
- "version": "1.9.1",
+ "version": "1.9.2",
"author": "https://developer.purestake.io",
"repository": "https://github.com/PureStake/algosigner",
"license": "MIT",
From fc8da153cebba848737f7f497dcba9fa41155ed8 Mon Sep 17 00:00:00 2001
From: Brent
Date: Thu, 7 Jul 2022 10:43:52 -0400
Subject: [PATCH 6/7] Delay mnemonic trim for field typing
---
packages/ui/src/pages/ImportAccount.ts | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/packages/ui/src/pages/ImportAccount.ts b/packages/ui/src/pages/ImportAccount.ts
index 0c6e02d1..d90979e0 100644
--- a/packages/ui/src/pages/ImportAccount.ts
+++ b/packages/ui/src/pages/ImportAccount.ts
@@ -31,6 +31,11 @@ const ImportAccount: FunctionalComponent = (props: any) => {
(isRef && !algosdk.isValidAddress(address));
const importAccount = (pwd: string) => {
+ // Trim mnemonic words
+ for (let i = 0; i < mnemonicArray.length; i++) {
+ mnemonicArray[i] = mnemonicArray[i].trim();
+ }
+
const params = {
passphrase: pwd,
mnemonic: mnemonicArray.join(' '),
@@ -65,7 +70,7 @@ const ImportAccount: FunctionalComponent = (props: any) => {
const handleMnemonicInput = (e) => {
const localMnemonicArray = mnemonicArray;
- const inputText = e.target.value.toString().trim();
+ const inputText = e.target.value.toString();
const inputArray = inputText.split(/[\s\t\r\n,]+/);
// If it is a single word then update that word placement in the array
@@ -75,7 +80,7 @@ const ImportAccount: FunctionalComponent = (props: any) => {
// If it is multiple words then verify there are 25 and split
else if (inputArray.length === wordsNumber) {
for(let i = 0; i < wordsNumber; i++) {
- localMnemonicArray[i.toString()] = inputArray[i].trim();
+ localMnemonicArray[i.toString()] = inputArray[i];
}
// For the case the user is typing the full mnemonic
From 8f2b5d59ae585c9d71a70aee71a53cd3ec9b2c7b Mon Sep 17 00:00:00 2001
From: Jan Marcano
Date: Thu, 7 Jul 2022 12:50:05 -0300
Subject: [PATCH 7/7] Fix internal Alias reload
---
packages/common/src/config.ts | 2 +-
packages/extension/src/background/messaging/internalMethods.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/common/src/config.ts b/packages/common/src/config.ts
index 156dbc0d..5dbdcce6 100644
--- a/packages/common/src/config.ts
+++ b/packages/common/src/config.ts
@@ -49,7 +49,7 @@ export class AliasConfig {
};
static [Namespace.ANS]: ConfigTemplate = {
- name: 'Algorand Namespace Service',
+ name: 'Algorand Name Service',
ledgers: {
[Ledger.TestNet]:
'https://testnet.api.algonameservice.com/names?pattern=${term}' +
diff --git a/packages/extension/src/background/messaging/internalMethods.ts b/packages/extension/src/background/messaging/internalMethods.ts
index 04d5482a..aec2d6da 100644
--- a/packages/extension/src/background/messaging/internalMethods.ts
+++ b/packages/extension/src/background/messaging/internalMethods.ts
@@ -64,10 +64,11 @@ export class InternalMethods {
extensionStorage.getStorage('contacts', (storedContacts: any) => {
const aliases = {};
const wallet = session.wallet;
+ const contacts = storedContacts || [];
// Format contacts as aliases
const contactAliases = [];
- for (const c of storedContacts) {
+ for (const c of contacts) {
contactAliases.push({
name: c.name,
address: c.address,