diff --git a/.nvmrc b/.nvmrc
index 5edcff036..9e15be387 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16
\ No newline at end of file
+v16.20.0
diff --git a/package-lock.json b/package-lock.json
index da0b0280b..12719ed3f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,18 +1,19 @@
{
"name": "Casper Wallet",
- "version": "1.6.0",
+ "version": "1.6.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "Casper Wallet",
- "version": "1.6.0",
+ "version": "1.6.3",
"dependencies": {
"@formatjs/intl": "2.6.2",
"@hookform/resolvers": "2.9.10",
"@hot-loader/react-dom": "^17.0.1",
"@lapo/asn1js": "1.2.4",
"@make-software/ces-js-parser": "1.3.2",
+ "@noble/ciphers": "^0.3.0",
"@scure/bip32": "1.3.2",
"@scure/bip39": "1.2.1",
"@types/argon2-browser": "1.18.1",
@@ -4269,6 +4270,14 @@
"integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==",
"dev": true
},
+ "node_modules/@noble/ciphers": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.3.0.tgz",
+ "integrity": "sha512-ldbrnOjmNRwFdXcTM6uXDcxpMIFrbzAWNnpBPp4oTJTFF0XByGD6vf45WrehZGXRQTRVV+Zm8YP+EgEf+e4cWA==",
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/@noble/curves": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
@@ -32070,6 +32079,11 @@
"integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==",
"dev": true
},
+ "@noble/ciphers": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.3.0.tgz",
+ "integrity": "sha512-ldbrnOjmNRwFdXcTM6uXDcxpMIFrbzAWNnpBPp4oTJTFF0XByGD6vf45WrehZGXRQTRVV+Zm8YP+EgEf+e4cWA=="
+ },
"@noble/curves": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
diff --git a/package.json b/package.json
index 0ce54135f..0e71df484 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "Casper Wallet",
"description": "Securely manage your CSPR tokens and interact with dapps with the self-custody wallet for the Casper blockchain.",
- "version": "1.6.2",
+ "version": "1.6.3",
"author": "MAKE LLC",
"scripts": {
"devtools:redux": "redux-devtools --hostname=localhost",
@@ -61,6 +61,7 @@
"@hot-loader/react-dom": "^17.0.1",
"@lapo/asn1js": "1.2.4",
"@make-software/ces-js-parser": "1.3.2",
+ "@noble/ciphers": "^0.3.0",
"@scure/bip32": "1.3.2",
"@scure/bip39": "1.2.1",
"@types/argon2-browser": "1.18.1",
diff --git a/src/apps/popup/app-router.tsx b/src/apps/popup/app-router.tsx
index 2be8040ae..983098e99 100644
--- a/src/apps/popup/app-router.tsx
+++ b/src/apps/popup/app-router.tsx
@@ -34,6 +34,7 @@ import { TokenDetailPage } from 'src/apps/popup/pages/token-details';
import { ActivityDetailsPage } from '@popup/pages/activity-details';
import { ReceivePage } from '@popup/pages/receive';
import { NftDetailsPage } from '@popup/pages/nft-details';
+import { WalletQrCodePage } from '@popup/pages/wallet-qr-code';
import { TransferNftPage } from '@popup/pages/transfer-nft';
import { ChangePasswordPage } from '@popup/pages/change-password';
@@ -242,6 +243,10 @@ function AppRoutes() {
} />
} />
} />
+ }
+ />
} />
void;
+ onClick?: (password: string) => Promise;
+ loading?: boolean;
}
export const BackupSecretPhrasePasswordPage = ({
- setPasswordConfirmed
+ setPasswordConfirmed,
+ onClick,
+ loading = false
}: BackupSecretPhrasePasswordPageType) => {
const { t } = useTranslation();
@@ -40,7 +44,8 @@ export const BackupSecretPhrasePasswordPage = ({
const {
register,
handleSubmit,
- formState: { errors, isDirty }
+ formState: { errors, isDirty },
+ getValues
} = useUnlockWalletForm(passwordHash, passwordSaltHash);
const isSubmitButtonDisabled = calculateSubmitButtonDisabled({
@@ -48,8 +53,17 @@ export const BackupSecretPhrasePasswordPage = ({
});
const onSubmit = () => {
- setPasswordConfirmed();
- dispatchToMainStore(loginRetryCountReseted());
+ if (onClick) {
+ const { password } = getValues();
+
+ onClick(password).then(() => {
+ setPasswordConfirmed();
+ dispatchToMainStore(loginRetryCountReseted());
+ });
+ } else {
+ setPasswordConfirmed();
+ dispatchToMainStore(loginRetryCountReseted());
+ }
};
return (
@@ -75,8 +89,8 @@ export const BackupSecretPhrasePasswordPage = ({
)}
renderFooter={() => (
-
)}
diff --git a/src/apps/popup/pages/home/components/tokens-list/utils.ts b/src/apps/popup/pages/home/components/tokens-list/utils.ts
index 61f7aa679..70c578ed3 100644
--- a/src/apps/popup/pages/home/components/tokens-list/utils.ts
+++ b/src/apps/popup/pages/home/components/tokens-list/utils.ts
@@ -32,8 +32,8 @@ export const formatErc20TokenBalance = (
name: token.contract_name,
balance: token.balance,
amount: erc20Amount,
- symbol: token.metadata?.symbol || '',
- decimals: token.metadata?.decimals,
+ symbol: token?.metadata?.symbol || '',
+ decimals: token?.metadata?.decimals,
amountFiat: null,
icon: token.icon_url || 'assets/icons/erc20-avatar.svg'
};
diff --git a/src/apps/popup/pages/navigation-menu/index.tsx b/src/apps/popup/pages/navigation-menu/index.tsx
index b53f95f58..4f434b3e9 100644
--- a/src/apps/popup/pages/navigation-menu/index.tsx
+++ b/src/apps/popup/pages/navigation-menu/index.tsx
@@ -183,6 +183,18 @@ export function NavigationMenuPageContent() {
},
{
id: 2,
+ title: t('Generate wallet QR code'),
+ description: t('Scan to import your wallet on mobile'),
+ iconPath: 'assets/icons/qr.svg',
+ disabled: false,
+ handleOnClick: () => {
+ closeNavigationMenu();
+
+ navigate(RouterPath.GenerateWalletQRCode);
+ }
+ },
+ {
+ id: 3,
title: t('Download account keys'),
description: t('For all accounts imported via file'),
iconPath: 'assets/icons/download.svg',
diff --git a/src/apps/popup/pages/receive/content.tsx b/src/apps/popup/pages/receive/content.tsx
index 18d9cb92d..a7cc7584b 100644
--- a/src/apps/popup/pages/receive/content.tsx
+++ b/src/apps/popup/pages/receive/content.tsx
@@ -58,7 +58,7 @@ export const ReceivePageContent = () => {
const tokens = useSelector(selectErc20Tokens, shallowEqual);
useEffect(() => {
- if (tokenData.symbol === 'CSPR') {
+ if (tokenData?.symbol === 'CSPR') {
const balance =
(csprBalance.amountMotes && motesToCSPR(csprBalance.amountMotes)) ||
'0';
@@ -66,10 +66,10 @@ export const ReceivePageContent = () => {
} else {
const erc20Tokens = formatErc20TokenBalance(tokens);
const balance =
- erc20Tokens?.find(t => t.symbol === tokenData.symbol)?.amount ?? '0';
+ erc20Tokens?.find(t => t?.symbol === tokenData?.symbol)?.amount ?? '0';
setTokenData(prev => ({ ...prev, balance }));
}
- }, [csprBalance, tokenData.symbol, tokens]);
+ }, [csprBalance, tokenData?.symbol, tokens]);
return (
@@ -80,7 +80,7 @@ export const ReceivePageContent = () => {
diff --git a/src/apps/popup/pages/token-details/token.tsx b/src/apps/popup/pages/token-details/token.tsx
index 84b751a2e..f8fc7cc3f 100644
--- a/src/apps/popup/pages/token-details/token.tsx
+++ b/src/apps/popup/pages/token-details/token.tsx
@@ -66,7 +66,7 @@ export const Token = ({ erc20Tokens }: TokenProps) => {
if (casperToken && activeAccount) {
setTokenData(casperToken);
setTokenInfoList([
- { id: 1, name: 'Symbol', value: casperToken.symbol }
+ { id: 1, name: 'Symbol', value: casperToken?.symbol }
]);
}
} else {
@@ -78,8 +78,8 @@ export const Token = ({ erc20Tokens }: TokenProps) => {
if (token) {
setTokenData(token);
setTokenInfoList([
- { id: 1, name: 'Symbol', value: token.symbol },
- { id: 2, name: 'Decimals', value: (token.decimals || 0).toString() }
+ { id: 1, name: 'Symbol', value: token?.symbol },
+ { id: 2, name: 'Decimals', value: (token?.decimals || 0).toString() }
]);
} else {
setTokenData(prev => (prev ? { ...prev, amount: '0' } : null));
diff --git a/src/apps/popup/pages/transfer/confirm-step.tsx b/src/apps/popup/pages/transfer/confirm-step.tsx
index 0c71a3445..d7aed6b45 100644
--- a/src/apps/popup/pages/transfer/confirm-step.tsx
+++ b/src/apps/popup/pages/transfer/confirm-step.tsx
@@ -134,7 +134,7 @@ export const ConfirmStep = ({
{listItems.text}
- {`${listItems.amount} ${listItems.symbol}`}
+ {`${listItems.amount} ${listItems?.symbol}`}
{listItems.fiatPrice == null
? null
diff --git a/src/apps/popup/pages/transfer/index.tsx b/src/apps/popup/pages/transfer/index.tsx
index 3830daa79..4f4d7e6ef 100644
--- a/src/apps/popup/pages/transfer/index.tsx
+++ b/src/apps/popup/pages/transfer/index.tsx
@@ -88,7 +88,6 @@ export const TransferPage = () => {
const { amountForm, recipientForm } = useTransferForm(
erc20Balance,
- erc20Decimals,
isErc20Transfer,
csprBalance.amountMotes,
paymentAmount
diff --git a/src/apps/popup/pages/wallet-qr-code/content.tsx b/src/apps/popup/pages/wallet-qr-code/content.tsx
new file mode 100644
index 000000000..49f3febde
--- /dev/null
+++ b/src/apps/popup/pages/wallet-qr-code/content.tsx
@@ -0,0 +1,73 @@
+import React, { useEffect, useState } from 'react';
+import { Trans, useTranslation } from 'react-i18next';
+import { QRCodeCanvas } from 'qrcode.react';
+import styled, { useTheme } from 'styled-components';
+
+import {
+ CenteredFlexRow,
+ ContentContainer,
+ ParagraphContainer,
+ SpacingSize
+} from '@libs/layout';
+import { Typography } from '@libs/ui';
+
+const QRContainer = styled(CenteredFlexRow)`
+ padding: 20px 16px;
+ background-color: ${({ theme }) => theme.color.backgroundPrimary};
+ border-radius: ${({ theme }) => theme.borderRadius.base}px;
+ margin-top: 20px;
+`;
+
+interface WalletQrCodePageContentProps {
+ qrStrings: string[];
+}
+
+export const WalletQrCodePageContent = ({
+ qrStrings
+}: WalletQrCodePageContentProps) => {
+ const theme = useTheme();
+ const [currentQrIndex, setCurrentQrIndex] = useState(0);
+
+ useEffect(() => {
+ const int = setInterval(() => {
+ setCurrentQrIndex(prev => {
+ const next = prev + 1;
+
+ if (next === qrStrings.length) {
+ return 0;
+ }
+
+ return next;
+ });
+ }, 500);
+
+ return () => clearInterval(int);
+ }, [qrStrings.length]);
+
+ const { t } = useTranslation();
+
+ return (
+
+
+
+ QR code is ready!
+
+
+
+
+ Scan this with your Casper Wallet app.
+
+
+
+
+
+
+ );
+};
diff --git a/src/apps/popup/pages/wallet-qr-code/index.tsx b/src/apps/popup/pages/wallet-qr-code/index.tsx
new file mode 100644
index 000000000..4c3e4539f
--- /dev/null
+++ b/src/apps/popup/pages/wallet-qr-code/index.tsx
@@ -0,0 +1,89 @@
+import React, { useCallback, useState } from 'react';
+import { Trans, useTranslation } from 'react-i18next';
+import { shallowEqual, useSelector } from 'react-redux';
+
+import {
+ FooterButtonsContainer,
+ HeaderSubmenuBarNavLink,
+ PopupHeader,
+ PopupLayout
+} from '@libs/layout';
+import { WalletQrCodePageContent } from '@popup/pages/wallet-qr-code/content';
+import { RouterPath, useTypedNavigate } from '@popup/router';
+import { Button } from '@libs/ui';
+import {
+ selectSecretPhrase,
+ selectVaultDerivedAccounts,
+ selectVaultImportedAccounts
+} from '@background/redux/vault/selectors';
+import { generateSyncWalletQrData } from '@libs/crypto';
+import { BackupSecretPhrasePasswordPage } from '@popup/pages/backup-secret-phrase-password';
+
+export const WalletQrCodePage = () => {
+ const [qrStrings, setQrStrings] = useState([]);
+ const [isPasswordConfirmed, setIsPasswordConfirmed] =
+ useState(false);
+ const [loading, setLoading] = useState(false);
+
+ const secretPhrase = useSelector(selectSecretPhrase);
+ const derivedAccounts = useSelector(selectVaultDerivedAccounts, shallowEqual);
+ const importedAccounts = useSelector(
+ selectVaultImportedAccounts,
+ shallowEqual
+ );
+
+ const navigate = useTypedNavigate();
+ const { t } = useTranslation();
+
+ const setPasswordConfirmed = useCallback(() => {
+ setIsPasswordConfirmed(true);
+ }, []);
+
+ const generateQRCode = async (password: string) => {
+ if (secretPhrase) {
+ setLoading(true);
+ const data = await generateSyncWalletQrData(
+ password,
+ secretPhrase,
+ derivedAccounts,
+ importedAccounts
+ );
+
+ setLoading(false);
+ setQrStrings(data);
+ }
+ };
+
+ if (!isPasswordConfirmed) {
+ return (
+
+ );
+ }
+
+ return (
+ (
+ (
+
+ )}
+ />
+ )}
+ renderContent={() => }
+ renderFooter={() => (
+
+ navigate(RouterPath.Home)}>
+ I'm done
+
+
+ )}
+ />
+ );
+};
diff --git a/src/apps/popup/router/paths.ts b/src/apps/popup/router/paths.ts
index 178e4544f..cc2e6eba6 100644
--- a/src/apps/popup/router/paths.ts
+++ b/src/apps/popup/router/paths.ts
@@ -20,6 +20,7 @@ export enum RouterPath {
Token = '/token/:tokenName',
Receive = '/receive',
NftDetails = '/nft-details/:contractPackageHash/nfts/:tokenId',
+ GenerateWalletQRCode = '/generate-wallet-qr-code',
TransferNft = '/transfer-nft/:contractPackageHash/nfts/:tokenId',
ChangePassword = '/change-password'
}
diff --git a/src/assets/icons/qr.svg b/src/assets/icons/qr.svg
new file mode 100644
index 000000000..816d0fec3
--- /dev/null
+++ b/src/assets/icons/qr.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/libs/crypto/hashing.ts b/src/libs/crypto/hashing.ts
index 65b855fa0..625053790 100644
--- a/src/libs/crypto/hashing.ts
+++ b/src/libs/crypto/hashing.ts
@@ -11,7 +11,7 @@ export function generateRandomSaltHex() {
return convertBytesToHex(generateRandomSaltBytes());
}
-const createScryptOptions = () => {
+export const createScryptOptions = () => {
const options = { N: 2 ** 18, r: 8, p: 1, dkLen: 32 };
return options;
};
diff --git a/src/libs/crypto/index.ts b/src/libs/crypto/index.ts
index b7ec89731..95030aebf 100644
--- a/src/libs/crypto/index.ts
+++ b/src/libs/crypto/index.ts
@@ -4,3 +4,4 @@ export * from './bip39';
export * from './bip44';
export * from './parse-secret-key-string';
export * from './sign-deploy';
+export * from './sync-wallet-qr';
diff --git a/src/libs/crypto/sync-wallet-qr.ts b/src/libs/crypto/sync-wallet-qr.ts
new file mode 100644
index 000000000..7a3e3c775
--- /dev/null
+++ b/src/libs/crypto/sync-wallet-qr.ts
@@ -0,0 +1,52 @@
+import { randomBytes } from '@noble/hashes/utils';
+import { aes_256_cbc } from '@noble/ciphers/webcrypto/aes';
+import { scryptAsync } from '@noble/hashes/scrypt';
+import { CLPublicKey } from 'casper-js-sdk';
+
+import { Account } from '@background/redux/vault/types';
+
+import { convertBytesToBase64 } from './utils';
+import { createScryptOptions } from './hashing';
+
+export const generateSyncWalletQrData = async (
+ password: string,
+ secretPhrase: string[],
+ derivedAccounts: Account[],
+ importedAccounts: Account[]
+) => {
+ const salt = randomBytes(16);
+ const iv = randomBytes(16);
+
+ const key = await scryptAsync(password, salt, createScryptOptions());
+
+ const qrDataString = JSON.stringify([
+ secretPhrase.join(' '),
+ derivedAccounts.map(da => da.name),
+ [
+ ...importedAccounts.map(acc => ({
+ secretKey: acc.secretKey,
+ label: acc.name,
+ publicKeyTag: CLPublicKey.fromHex(acc.publicKey).getTag()
+ }))
+ ]
+ ]);
+
+ const data = Uint8Array.from(Buffer.from(qrDataString));
+
+ const stream = aes_256_cbc(key, iv);
+ const cipher = await stream.encrypt(data);
+
+ const qrString = JSON.stringify([
+ convertBytesToBase64(cipher),
+ convertBytesToBase64(salt),
+ convertBytesToBase64(iv)
+ ]);
+
+ const qrBytes = Uint8Array.from(Buffer.from(qrString));
+ const qrData = convertBytesToBase64(qrBytes);
+ const qrDataArray = qrData.match(/.{1,200}/g);
+
+ return (qrDataArray ?? [qrData]).map(
+ (qr, i, arr) => `${i + 1}$${arr.length}$${qr}`
+ );
+};
diff --git a/src/libs/ui/components/erc20-token-activity-list/erc20-token-activity-list.tsx b/src/libs/ui/components/erc20-token-activity-list/erc20-token-activity-list.tsx
index 81df9fdc3..fe13e4c25 100644
--- a/src/libs/ui/components/erc20-token-activity-list/erc20-token-activity-list.tsx
+++ b/src/libs/ui/components/erc20-token-activity-list/erc20-token-activity-list.tsx
@@ -61,8 +61,8 @@ export const Erc20TokenActivityList = () => {
args: transaction.deploy?.args || '-',
status: transaction.deploy?.status || '-',
errorMessage: transaction.deploy?.error_message || null,
- decimals: transaction.contract_package?.metadata.decimals,
- symbol: transaction.contract_package?.metadata.symbol,
+ decimals: transaction.contract_package?.metadata?.decimals,
+ symbol: transaction.contract_package?.metadata?.symbol,
toPublicKey: transaction?.to_public_key,
fromPublicKey: transaction?.from_public_key || null,
contractPackage: transaction?.contract_package,
diff --git a/src/libs/ui/forms/form-validation-rules.ts b/src/libs/ui/forms/form-validation-rules.ts
index 504243a8b..e5ef55850 100644
--- a/src/libs/ui/forms/form-validation-rules.ts
+++ b/src/libs/ui/forms/form-validation-rules.ts
@@ -1,6 +1,7 @@
import * as Yup from 'yup';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
+import Big from 'big.js';
import { verifyPasswordAgainstHash } from '@src/libs/crypto/hashing';
import { dispatchToMainStore } from '@src/background/redux/utils';
@@ -12,10 +13,10 @@ import {
TRANSFER_COST_MOTES
} from '@src/constants';
import { isValidPublicKey, isValidU64 } from '@src/utils';
-import Big from 'big.js';
import { CSPRtoMotes, motesToCSPR } from '@libs/ui/utils/formatters';
export const minPasswordLength = 16;
+export const maxQrCodePasswordLength = 8;
const ERROR_DISPLAYED_BEFORE_ATTEMPT_IS_DECREMENTED = 1;
@@ -180,10 +181,7 @@ export const useCsprAmountRule = (amountMotes: string | null) => {
});
};
-export const useErc20AmountRule = (
- amount: string | null,
- decimals: number | null
-) => {
+export const useErc20AmountRule = (amount: string | null) => {
const { t } = useTranslation();
const maxAmount: string = amount == null ? '0' : Big(amount).toString();
diff --git a/src/libs/ui/forms/transfer.ts b/src/libs/ui/forms/transfer.ts
index 8536453e9..4adaf0d6d 100644
--- a/src/libs/ui/forms/transfer.ts
+++ b/src/libs/ui/forms/transfer.ts
@@ -25,7 +25,6 @@ export type TransferAmountFormValues = {
export function useTransferForm(
erc20Balance: string | null,
- decimals: number | null,
isErc20: boolean,
amountMotes: string | null,
paymentAmount: string
@@ -41,7 +40,7 @@ export function useTransferForm(
};
const erc20AmountFormSchema = Yup.object().shape({
- amount: useErc20AmountRule(erc20Balance, decimals),
+ amount: useErc20AmountRule(erc20Balance),
paymentAmount: usePaymentAmountRule(amountMotes),
transferIdMemo: useTransferIdMemoRule()
});
diff --git a/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj b/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj
index 30570fdf1..ba296e19e 100644
--- a/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj
+++ b/xcode-project/Casper Wallet/Casper Wallet.xcodeproj/project.pbxproj
@@ -500,7 +500,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Casper Wallet Extension/Casper_Wallet_Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 22;
+ CURRENT_PROJECT_VERSION = 23;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Casper Wallet Extension/Info.plist";
@@ -512,7 +512,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
- MARKETING_VERSION = 1.5.2;
+ MARKETING_VERSION = 1.6.0;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -530,7 +530,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Casper Wallet Extension/Casper_Wallet_Extension.entitlements";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 22;
+ CURRENT_PROJECT_VERSION = 23;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Casper Wallet Extension/Info.plist";
@@ -542,7 +542,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
- MARKETING_VERSION = 1.5.2;
+ MARKETING_VERSION = 1.6.0;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -564,7 +564,7 @@
CODE_SIGN_ENTITLEMENTS = "Casper Wallet/Casper Wallet.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 32;
+ CURRENT_PROJECT_VERSION = 35;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Casper Wallet/Info.plist";
@@ -578,7 +578,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
- MARKETING_VERSION = 1.6.2;
+ MARKETING_VERSION = 1.6.3;
OTHER_LDFLAGS = (
"-framework",
SafariServices,
@@ -601,7 +601,7 @@
CODE_SIGN_ENTITLEMENTS = "Casper Wallet/Casper Wallet.entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 32;
+ CURRENT_PROJECT_VERSION = 35;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Casper Wallet/Info.plist";
@@ -615,7 +615,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.14;
- MARKETING_VERSION = 1.6.2;
+ MARKETING_VERSION = 1.6.3;
OTHER_LDFLAGS = (
"-framework",
SafariServices,