From c0f8518dcc1886d58002910afc4b064fd2773e48 Mon Sep 17 00:00:00 2001 From: Jan Marcano Date: Mon, 1 Aug 2022 11:52:11 -0300 Subject: [PATCH] Show Warning when sending funds directly to a Governance accounts --- packages/common/src/messaging/types.ts | 1 + packages/common/src/strings.ts | 3 ++ .../background/messaging/internalMethods.ts | 23 ++++++++++++++- .../src/background/messaging/task.ts | 3 ++ packages/ui/src/pages/SendAlgos.ts | 28 +++++++++++++++++-- 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/common/src/messaging/types.ts b/packages/common/src/messaging/types.ts index 9fde3e67..ef95804c 100644 --- a/packages/common/src/messaging/types.ts +++ b/packages/common/src/messaging/types.ts @@ -46,6 +46,7 @@ export enum JsonRpcMethod { GetAliasedAddresses = 'get-aliased-addresses', GetNamespaceConfigs = 'get-namespace-configs', ToggleNamespaceConfig = 'toggle-namespace-config', + GetGovernanceAddresses = 'get-governance-addresses', // Ledger Device Methods LedgerSaveAccount = 'ledger-save-account', diff --git a/packages/common/src/strings.ts b/packages/common/src/strings.ts index 8a267a1a..0fc5c070 100644 --- a/packages/common/src/strings.ts +++ b/packages/common/src/strings.ts @@ -23,3 +23,6 @@ they are rekeyed to another normal account also on AlgoSigner.`; export const ALIAS_COLLISION_TOOLTIP: string = `Some of the aliases shown share the same name, make sure to verify which Namespace you're using by hovering on the alias before making a selection.`; + +export const GOVERNANCE_WARNING: string = + 'This is a Governance Address. You are not required to send funds in order to participate in Governance. Please see '; diff --git a/packages/extension/src/background/messaging/internalMethods.ts b/packages/extension/src/background/messaging/internalMethods.ts index 20de3930..9bf3851c 100644 --- a/packages/extension/src/background/messaging/internalMethods.ts +++ b/packages/extension/src/background/messaging/internalMethods.ts @@ -1,6 +1,6 @@ import algosdk from 'algosdk'; import { JsonRpcMethod } from '@algosigner/common/messaging/types'; -import { logging } from '@algosigner/common/logging'; +import { logging, LogLevel } from '@algosigner/common/logging'; import { ExtensionStorage } from '@algosigner/storage/src/extensionStorage'; import { Alias, Ledger, Namespace, NamespaceConfig } from '@algosigner/common/types'; import { RequestError } from '@algosigner/common/errors'; @@ -1291,4 +1291,25 @@ export class InternalMethods { }); return true; } + + public static [JsonRpcMethod.GetGovernanceAddresses](request: any, sendResponse: Function) { + const governanceAccounts: Array = []; + fetch('https://governance.algorand.foundation/api/periods/').then(async (fetchResponse) => { + if (fetchResponse.ok) { + const governanceResponse = await fetchResponse.json(); + if ('results' in governanceResponse) { + try { + governanceResponse['results'].forEach((p) => governanceAccounts.push(p['sign_up_address'])); + } catch (e) { + logging.log("Governance accounts couldn't be fetched. Error: "+e.message, LogLevel.Debug); + } + } + } + + if (governanceAccounts.length) { + sendResponse({accounts: governanceAccounts}); + } + }); + return true; + } } diff --git a/packages/extension/src/background/messaging/task.ts b/packages/extension/src/background/messaging/task.ts index deba957d..c61020d7 100644 --- a/packages/extension/src/background/messaging/task.ts +++ b/packages/extension/src/background/messaging/task.ts @@ -1264,6 +1264,9 @@ export class Task { [JsonRpcMethod.ToggleNamespaceConfig]: (request: any, sendResponse: Function) => { return InternalMethods[JsonRpcMethod.ToggleNamespaceConfig](request, sendResponse); }, + [JsonRpcMethod.GetGovernanceAddresses]: (request: any, sendResponse: Function) => { + return InternalMethods[JsonRpcMethod.GetGovernanceAddresses](request, sendResponse); + }, }, }; } diff --git a/packages/ui/src/pages/SendAlgos.ts b/packages/ui/src/pages/SendAlgos.ts index 4f6ed4cf..4aebe053 100644 --- a/packages/ui/src/pages/SendAlgos.ts +++ b/packages/ui/src/pages/SendAlgos.ts @@ -7,7 +7,7 @@ import { Key } from 'ts-key-enum'; import { JsonRpcMethod } from '@algosigner/common/messaging/types'; import { AliasConfig } from '@algosigner/common/config'; import { obfuscateAddress } from '@algosigner/common/utils'; -import { ALIAS_COLLISION_TOOLTIP } from '@algosigner/common/strings'; +import { ALIAS_COLLISION_TOOLTIP, GOVERNANCE_WARNING } from '@algosigner/common/strings'; import { StoreContext } from 'services/StoreContext'; import { sendMessage } from 'services/Messaging'; @@ -44,6 +44,7 @@ const SendAlgos: FunctionalComponent = (props: any) => { const [internalAliases, setInternalAliases] = useState([]); const [highlightedAlias, setHighlightedAlias] = useState(0); const [selectedDestination, setSelectedDestination] = useState(null); + const [governanceAddresses, setGovernanceAddresses] = useState>([]); const [addingContact, setAddingContact] = useState(false); const [newContactName, setNewContactName] = useState(''); const [loading, setLoading] = useState(false); @@ -70,6 +71,16 @@ const SendAlgos: FunctionalComponent = (props: any) => { setInternalAliases(Object.keys(response).flatMap((n) => response[n])); } } + // Fetch governance accounts + sendMessage(JsonRpcMethod.GetGovernanceAddresses, {}, (response) => { + if (response) { + if ('error' in response) { + setError(response.error.message); + } else { + setGovernanceAddresses(response['accounts']); + } + } + }); }); }, []); // Automatically focus textbox on load @@ -287,7 +298,13 @@ const SendAlgos: FunctionalComponent = (props: any) => { let ddClass: string = 'dropdown is-right'; if (ddActive) ddClass += ' is-active'; const youIndicator = html`YOU`; - const disabled = (!selectedDestination && !algosdk.isValidAddress(to)) || +amount < 0; + const isGovernance = + (to && governanceAddresses.includes(to)) || + (selectedDestination && + selectedDestination.address && + governanceAddresses.includes(selectedDestination.address)); + const disabled = + (!selectedDestination && !algosdk.isValidAddress(to)) || +amount < 0 || isGovernance; const isActive = (index: number) => (index === highlightedAlias ? 'is-active' : ''); // Render HTML @@ -472,6 +489,13 @@ const SendAlgos: FunctionalComponent = (props: any) => { onInput=${(e) => setNote(e.target.value)} /> + ${isGovernance && + html` + ${GOVERNANCE_WARNING} + + official site. + `}