Skip to content

Commit

Permalink
Merge branch 'main' into missing-reward-change-date
Browse files Browse the repository at this point in the history
  • Loading branch information
shjortConcordium authored Jan 18, 2024
2 parents 8c16fdb + 206e450 commit 4350b11
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 5 deletions.
6 changes: 6 additions & 0 deletions packages/browser-wallet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

- Missing date for delegation/validation stake decrease/stop has been restored.

## 1.3.0

### Added

- The EuroE token is now added to all accounts by default.

## 1.2.1

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-wallet/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@concordium/browser-wallet",
"private": true,
"version": "1.2.1",
"version": "1.3.0",
"description": "Browser extension wallet for the Concordium blockchain",
"author": "Concordium Software",
"license": "Apache-2.0",
Expand Down
62 changes: 60 additions & 2 deletions packages/browser-wallet/src/background/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,28 @@ import {
sessionPasscode,
storedAcceptedTerms,
storedAllowlist,
storedCredentials,
storedCurrentNetwork,
storedMigrations,
storedSelectedAccount,
storedTokenMetadata,
storedTokens,
} from '@shared/storage/access';

import { mainnet, stagenet, testnet } from '@shared/constants/networkConfiguration';
import { ChromeStorageKey, NetworkConfiguration } from '@shared/storage/types';
import { ChromeStorageKey, NetworkConfiguration, TokenStorage } from '@shared/storage/types';
import { getTermsAndConditionsConfig } from '@shared/utils/network-helpers';
import { parsePayload } from '@shared/utils/payload-helpers';
import { BackgroundSendTransactionPayload } from '@shared/utils/types';
import { buildURLwithSearchParameters } from '@shared/utils/url-helpers';
import { Buffer } from 'buffer/';
import { Migrations } from '@shared/constants/migrations';
import {
EUROE_MAINNET_INDEX,
EUROE_METADATA,
EUROE_TESTNET_INDEX,
euroeTokenStorage,
} from '@shared/constants/token-metadata';
import { startMonitoringPendingStatus } from './confirmation';
import { sendCredentialHandler } from './credential-deployment';
import { createIdProofHandler, runIfValidProof } from './id-proof';
Expand Down Expand Up @@ -152,10 +163,57 @@ async function migrateNetwork(network: NetworkConfiguration) {
}
}

/*
* Add the given token to all accounts of the given network, that don't already have it.
*/
async function addTokenToAccounts(network: NetworkConfiguration, contractIndex: number, token: TokenStorage) {
const tokens = await storedTokens.get(network.genesisHash);
const creds = await storedCredentials.get(network.genesisHash);
if (creds && creds.length > 0) {
const accountAddresses = creds.map((cred) => cred.address);
const newTokens = accountAddresses.reduce((accumulator, address) => {
const accTokens = tokens?.[address] || {};
if (contractIndex in accTokens) {
accumulator[address] = accTokens;
} else {
accumulator[address] = { [contractIndex]: [token], ...accTokens };
}
return accumulator;
}, {} as Record<string, Record<string, TokenStorage[]>>);
await storedTokens.set(network.genesisHash, newTokens);
}
}

/**
* Add euroe tokens to all accounts that don't already have it, if the migration has not atlready been run, and sets the euroe migration check.
*/
async function euroeMigration() {
const migrations = (await storedMigrations.get()) || [];
if (!migrations.includes(Migrations.euroe)) {
// Add metadata, if not present
const metadata = (await storedTokenMetadata.get()) || {};
const { metadataLink } = euroeTokenStorage;
if (!(metadataLink in metadata)) {
metadata[metadataLink] = EUROE_METADATA;
await storedTokenMetadata.set(metadata);
}
await addTokenToAccounts(mainnet, EUROE_MAINNET_INDEX, euroeTokenStorage);
await addTokenToAccounts(testnet, EUROE_TESTNET_INDEX, euroeTokenStorage);
await storedMigrations.set([...migrations, Migrations.euroe]);
}
}

async function runMigrations(network?: NetworkConfiguration) {
if (network) {
await migrateNetwork(network);
}
await euroeMigration();
}

const startupHandler = async () => {
const network = await storedCurrentNetwork.get();
runMigrations(network);
if (network) {
await migrateNetwork(network);
await startMonitoringPendingStatus(network);
}
checkForNewTermsAndConditions();
Expand Down
30 changes: 28 additions & 2 deletions packages/browser-wallet/src/background/update.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { storedCredentials, storedIdentities, useIndexedStorage } from '@shared/storage/access';
import { addToList, editList } from '@shared/storage/update';
import { storedCredentials, storedIdentities, storedTokens, useIndexedStorage } from '@shared/storage/access';
import { addToList, editList, updateRecord } from '@shared/storage/update';
import { Identity, WalletCredential } from '@shared/storage/types';
import { identityMatch } from '@shared/utils/identity-helpers';
import { EUROE_MAINNET_INDEX, EUROE_TESTNET_INDEX, euroeTokenStorage } from '@shared/constants/token-metadata';
import { mainnet, testnet } from '@shared/constants/networkConfiguration';

const identityLock = 'concordium_identity_lock';
const credentialLock = 'concordium_credential_lock';
const tokenLock = 'concordium_token_lock';

export async function addIdentity(identity: Identity | Identity[], genesisHash: string): Promise<void> {
return addToList(
Expand All @@ -14,7 +17,30 @@ export async function addIdentity(identity: Identity | Identity[], genesisHash:
);
}

// Add the euroe token to the credential(s)
async function addEuroeToken(cred: WalletCredential | WalletCredential[], genesisHash: string): Promise<void> {
const storage = useIndexedStorage(storedTokens, async () => genesisHash);
const add = async (index: string) => {
for (const { address } of Array.isArray(cred) ? cred : [cred]) {
await updateRecord(tokenLock, storage, address, { [index]: [euroeTokenStorage] });
}
};
switch (genesisHash) {
case mainnet.genesisHash:
await add(EUROE_MAINNET_INDEX.toString());
break;
case testnet.genesisHash:
await add(EUROE_TESTNET_INDEX.toString());
break;
default:
// The euroe Token only exists on mainnet and testnet, so for other networks we don't do anything.
}
}

export async function addCredential(cred: WalletCredential | WalletCredential[], genesisHash: string): Promise<void> {
// All accounts should have euroe token added as default
addEuroeToken(cred, genesisHash);

return addToList(
credentialLock,
cred,
Expand Down
2 changes: 2 additions & 0 deletions packages/browser-wallet/src/popup/store/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
sessionVerifiableCredentials,
sessionVerifiableCredentialMetadataUrls,
storedLog,
storedMigrations,
} from '@shared/storage/access';
import { ChromeStorageKey } from '@shared/storage/types';
import { atom, PrimitiveAtom, WritableAtom } from 'jotai';
Expand Down Expand Up @@ -73,6 +74,7 @@ const accessorMap: Record<ChromeStorageKey, StorageAccessor<any>> = {
getGenesisHash
),
[ChromeStorageKey.Log]: storedLog,
[ChromeStorageKey.Migrations]: storedMigrations,
};

export function resetOnUnmountAtom<V>(initial: V): PrimitiveAtom<V> {
Expand Down
3 changes: 3 additions & 0 deletions packages/browser-wallet/src/shared/constants/migrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum Migrations {
euroe = 'euroe_migration',
}
23 changes: 23 additions & 0 deletions packages/browser-wallet/src/shared/constants/token-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,26 @@ export const CCD_METADATA: TokenMetadata = {
display: CCD_IMAGE,
thumbnail: CCD_IMAGE,
};

export const EUROE_METADATA: TokenMetadata = {
name: 'EUROe Stablecoin',
symbol: 'EUROe',
decimals: 6,
unique: false,
description: 'EUROe is a modern European stablecoin - a digital representation of fiat Euros.',
thumbnail: {
url: 'https://dev.euroe.com/persistent/token-icon/png/32x32.png',
},
display: {
url: 'https://dev.euroe.com/persistent/token-icon/png/256x256.png',
},
attributes: [],
};

export const euroeTokenStorage = {
id: '',
metadataLink: 'https://euroesolanametadadev.blob.core.windows.net/euroesolanametadatadev/metadata-concordium.json',
};

export const EUROE_MAINNET_INDEX = 9390;
export const EUROE_TESTNET_INDEX = 7260;
2 changes: 2 additions & 0 deletions packages/browser-wallet/src/shared/storage/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { stringify } from '@concordium/browser-wallet-api/src/util';
import { parse } from '@shared/utils/payload-helpers';
import { VerifiableCredentialMetadata } from '@shared/utils/verifiable-credential-helpers';
import { Log } from '@shared/utils/log-helpers';
import { Migrations } from '@shared/constants/migrations';
import {
ChromeStorageKey,
EncryptedData,
Expand Down Expand Up @@ -237,3 +238,4 @@ export const sessionVerifiableCredentialMetadataUrls = makeIndexedStorageAccesso
'session',
ChromeStorageKey.TemporaryVerifiableCredentialMetadataUrls
);
export const storedMigrations = makeStorageAccessor<Migrations[]>('local', ChromeStorageKey.Migrations);
1 change: 1 addition & 0 deletions packages/browser-wallet/src/shared/storage/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export enum ChromeStorageKey {
TemporaryVerifiableCredentialMetadataUrls = 'tempVerifiableCredentialMetadataUrls',
Allowlist = 'allowlist',
Log = 'log',
Migrations = 'migrations',
}

export enum Theme {
Expand Down

0 comments on commit 4350b11

Please sign in to comment.