Skip to content

Commit

Permalink
feat(compliance): Compliance UI for read only, close only and Complia…
Browse files Browse the repository at this point in the history
…nce configuration (#433)

* Add compliance dialog

* address comments

* UI for various compliance states

* bump abacus, remove transfer

* update localization

* fix spacing

* bump localizatoin

* add testflag

* address comments

* fix lint

* fix merge
  • Loading branch information
rosepuppy authored Apr 30, 2024
1 parent 9c36cb5 commit 8191f8e
Show file tree
Hide file tree
Showing 31 changed files with 1,175 additions and 144 deletions.
99 changes: 50 additions & 49 deletions public/configs/v1/env.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"apps": {
"ios": {
"scheme": "dydx-t-v4"
"scheme": "dydxv4"
}
},
"tokens": {
Expand Down Expand Up @@ -35,11 +35,11 @@
"image": "/currencies/usdc.png"
}
},
"[mainnet chain id]": {
"comment": "Change according to mainnet release",
"dydx-mainnet-1": {
"comment": "Mainnet",
"chain": {
"name": "TokenName",
"denom": "tokenDenom",
"name": "DYDX",
"denom": "adydx",
"decimals": 18,
"image": "/currencies/dydx.png"
},
Expand Down Expand Up @@ -100,29 +100,29 @@
"launchIncentive": "https://cloud.chaoslabs.co",
"tradingRewardsLearnMore": "https://docs.dydx.exchange/rewards/trading_rewards"
},
"[mainnet chain id]": {
"tos": "[HTTP link to TOS]",
"privacy": "[HTTP link to Privacy Policy]",
"statusPage": "[HTTP link to status page]",
"mintscan": "[HTTP link to Mintscan, with {tx_hash} placeholder]",
"mintscanBase": "[HTTP link to TOS mintscan base url]",
"feedback": "[HTTP link to feedback form, can be null]",
"blogs": "[HTTP link to blogs, can be null]",
"foundation": "[HTTP link to foundation, can be null]",
"reduceOnlyLearnMore": "[HTTP link to reduce-only learn more, can be null]",
"documentation": "[HTTP link to documentation, can be null]",
"community": "[HTTP link to community, can be null]",
"help": "[HTTP link to help page, can be null]",
"governanceLearnMore": "[HTTP link to governance learn more, can be null]",
"newMarketProposalLearnMore": "[HTTP link to new market proposal learn more, can be null]",
"stakingLearnMore": "[HTTP link to staking learn more, can be null]",
"keplrDashboard": "[HTTP link to keplr dashboard, can be null]",
"strideZoneApp": "[HTTP link to stride zone app, can be null]",
"accountExportLearnMore": "[HTTP link to account export learn more, can be null]",
"walletLearnMore": "[HTTP link to wallet learn more, can be null]",
"withdrawalGateLearnMore": "[HTTP link to withdrawal gate learn more, can be null]",
"launchIncentive": "[HTTP link to launch incentive host, can be null]",
"tradingRewardsLearnMore": "[HTTP link to trading rewards learn more, can be null]"
"dydx-mainnet-1": {
"tos": "https://dydx.trade/terms",
"privacy": "https://dydx.trade/privacy",
"statusPage": "https://status.dydx.trade/",
"mintscan": "https://www.mintscan.io/dydx/tx/{tx_hash}",
"mintscanBase": "https://www.mintscan.io/dydx",
"feedback": "https://www.dydxopsdao.com/feedback",
"blogs": "https://www.dydx.foundation/blog",
"foundation": "https://www.dydx.foundation",
"reduceOnlyLearnMore": "https://help.dydx.trade/en/articles/8607918-reduce-only-order",
"documentation": "https://docs.dydx.trade/",
"community": "https://discord.com/invite/dydx",
"help": "https://help.dydx.trade/",
"governanceLearnMore": "https://help.dydx.trade/en/collections/6936883-governance-staking",
"newMarketProposalLearnMore": "https://dydx.exchange/blog/new-market-proposals",
"stakingLearnMore": "https://help.dydx.trade/en/articles/8581388-accessing-governance-and-staking-on-dydx-chain",
"keplrDashboard": "https://wallet.keplr.app/chains/dydx?tab=staking",
"strideZoneApp": "https://app.stride.zone/?chain=DYDX",
"accountExportLearnMore": "https://help.dydx.trade/en/articles/8581269-secret-phrase-on-dydx-chain",
"walletLearnMore": "https://help.dydx.trade/en/articles/8581303-supported-default-wallets-on-dydx-chain",
"withdrawalGateLearnMore": "https://help.dydx.trade/en/articles/9004706-withdrawals-on-dydx-chain#h_e61f043370",
"launchIncentive": "https://cloud.chaoslabs.co",
"tradingRewardsLearnMore": "https://docs.dydx.exchange/rewards/trading_rewards"
}
},
"wallets": {
Expand Down Expand Up @@ -162,21 +162,21 @@
"signTypedDataAction": "dYdX Chain Onboarding",
"signTypedDataDomainName": "dYdX Chain"
},
"[mainnet chain id]": {
"dydx-mainnet-1": {
"walletconnect": {
"client": {
"name": "[Name of the app]",
"description": "[Description of the app]",
"iconUrl": "[Relative URL of the icon URL]"
"name": "dYdX v4",
"description": "dYdX v4 App",
"iconUrl": "/logos/dydx-x.png"
},
"v2": {
"projectId": "[Project ID]"
"projectId": "fd67e5fbec90c07b6012699738d4a487"
}
},
"walletSegue": {
"callbackUrl": "[Relative callback URL for WalletSegue, should match apple-app-site-association]"
"callbackUrl": "/walletsegue"
},
"images": "[Relative URL for wallet images]",
"images": "/wallets/",
"signTypedDataAction": "dYdX Chain Onboarding",
"signTypedDataDomainName": "dYdX Chain"
}
Expand All @@ -196,11 +196,11 @@
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1zjkV9R7R_7KMItuzqzvKGwefSBRfE-ZNAx1LH55OcqY/edit?usp=sharing"
}
},
"[mainnet chain id]": {
"dydx-mainnet-1": {
"newMarketProposal": {
"initialDepositAmount": 0,
"delayBlocks": 0,
"newMarketsMethodology": "[URL to spreadsheet or document that explains methodology]"
"initialDepositAmount": 2000000000000000000000,
"delayBlocks": 3600,
"newMarketsMethodology": "https://docs.google.com/spreadsheets/d/1046uSR2sltA6siZGnvBlgUp4xlPNM7dPFvUgdACgTy4/edit?usp=sharing"
}
}
},
Expand Down Expand Up @@ -428,7 +428,7 @@
"ios": {
"minimalVersion": "1.0",
"build": 40000,
"url": "https://apps.apple.com/app/dydx/id1564787350"
"url": "https://apps.apple.com/app/dydx/id6475599596"
}
},
"featureFlags": {
Expand Down Expand Up @@ -702,24 +702,25 @@
"dydxprotocol-mainnet": {
"name": "v4",
"ethereumChainId": "1",
"dydxChainId": "[mainnet chain id]",
"dydxChainId": "dydx-mainnet-1",
"chainName": "dYdX Chain",
"chainLogo": "/dydx-chain.png",
"squidIntegratorId": "[mainnet squid integrator id]",
"squidIntegratorId": "dYdX-api",
"isMainNet": true,
"endpoints": {
"indexers": [
{
"api": "[REST endpoint]",
"socket": "[Websocket endpoint]"
"api": "https://indexer.dydx.trade",
"socket": "wss://indexer.dydx.trade"
}
],
"validators": [
"[Validator endpoint 1",
"[Validator endpoint n]"
"https://dydx-dao-rpc.polkachu.com",
"https://dydx-mainnet-full-rpc.public.blastapi.io",
"https://dydx-ops-rpc.kingnodes.com"
],
"0xsquid": "[0xSquid endpoint for mainnet]",
"nobleValidator": "[noble validator endpoint for mainnet]"
"0xsquid": "https://api.squidrouter.com",
"nobleValidator": "https://noble-rpc.polkachu.com/"
},
"featureFlags": {
"reduceOnlySupported": true,
Expand All @@ -732,4 +733,4 @@
}
}
}
}
}
54 changes: 27 additions & 27 deletions scripts/install-local-abacus.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,44 @@ import { execSync } from 'child_process';
const clean = process.argv.includes('--clean');

if (clean) {
infoMessage("Running deep clean.")
nonFatalExec('pnpm remove @dydxprotocol/v4-abacus') // remove abacus from node_modules
nonFatalExec('cd ../v4-abacus && ./gradlew clean') // cleanup gradle build outputs
nonFatalExec('cd ../v4-abacus && ./gradlew --stop') // stop any running gradle daemons
nonFatalExec('rm -rf ~/.gradle/caches') // nuke the gradle cache
infoMessage('Running deep clean.');
nonFatalExec('pnpm remove @dydxprotocol/v4-abacus'); // remove abacus from node_modules
nonFatalExec('cd ~/v4-abacus && ./gradlew clean'); // cleanup gradle build outputs
nonFatalExec('cd ~/v4-abacus && ./gradlew --stop'); // stop any running gradle daemons
nonFatalExec('rm -rf ~/.gradle/caches'); // nuke the gradle cache
}

infoMessage("Cleaning up any previously built abacus packages...")
nonFatalExec('rm ../v4-abacus/build/packages/*.tgz')
infoMessage('Cleaning up any previously built abacus packages...');
nonFatalExec('rm ~/v4-abacus/build/packages/*.tgz');

infoMessage("Building abacus...")
fatalExec('cd ../v4-abacus && ./gradlew packJsPackage');
infoMessage('Building abacus...');
fatalExec('cd ~/v4-abacus && ./gradlew packJsPackage');

infoMessage("Installing local abacus package...")
fatalExec("find ../v4-abacus/build/packages -name '*.tgz' | head -n 1 | xargs pnpm install");
infoMessage("Successfully installed local abacus package.")
infoMessage('Installing local abacus package...');
fatalExec("find ~/v4-abacus/build/packages -name '*.tgz' | head -n 1 | xargs pnpm install");
infoMessage('Successfully installed local abacus package.');

infoMessage("Generating local-abacus-hash...")
fatalExec("find ../v4-abacus/build/packages -name '*.tgz' | head -n 1 | shasum > local-abacus-hash");
infoMessage('Generating local-abacus-hash...');
fatalExec("find ~/v4-abacus/build/packages -name '*.tgz' | head -n 1 | shasum > local-abacus-hash");

infoMessage("Vite dev server should have restarted automatically.")
infoMessage('Vite dev server should have restarted automatically.');

function nonFatalExec(cmd) {
try {
execSync(cmd, { stdio: "inherit" });
} catch (error) {
// Do nothing.
}
try {
execSync(cmd, { stdio: 'inherit' });
} catch (error) {
// Do nothing.
}
}

function fatalExec(cmd) {
try {
execSync(cmd, { stdio: "inherit" });
} catch (error) {
process.exit(1);
}
try {
execSync(cmd, { stdio: 'inherit' });
} catch (error) {
process.exit(1);
}
}

function infoMessage(message) {
console.log("\n**** install-local-abacus.js: "+message+"\n")
}
console.log('\n**** install-local-abacus.js: ' + message + '\n');
}
19 changes: 18 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PrivyProvider } from '@privy-io/react-auth';
import { PrivyWagmiConnector } from '@privy-io/wagmi-connector';
import { GrazProvider } from 'graz';
import { QueryClient, QueryClientProvider } from 'react-query';
import { useSelector } from 'react-redux';
import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
import styled, { AnyStyledComponent, css } from 'styled-components';
import { WagmiConfig } from 'wagmi';
Expand Down Expand Up @@ -47,6 +48,9 @@ import { GlobalCommandDialog } from '@/views/dialogs/GlobalCommandDialog';
import { parseLocationHash } from '@/lib/urlUtils';
import { config, configureChainsConfig, privyConfig } from '@/lib/wagmi';

import { ComplianceStates } from './constants/compliance';
import { useComplianceState } from './hooks/useComplianceState';

const NewMarket = lazy(() => import('@/pages/markets/NewMarket'));
const MarketsPage = lazy(() => import('@/pages/markets/Markets'));
const PortfolioPage = lazy(() => import('@/pages/portfolio/Portfolio'));
Expand All @@ -72,6 +76,8 @@ const Content = () => {
const { chainTokenLabel } = useTokenConfigs();
const location = useLocation();

const { complianceState } = useComplianceState();

const pathFromHash = useMemo(() => {
if (location.hash === '') {
return '';
Expand All @@ -97,7 +103,18 @@ const Content = () => {
<Route path={MarketsRoute.New} element={<NewMarket />} />
<Route path={AppRoute.Markets} element={<MarketsPage />} />
</Route>
<Route path={`/${chainTokenLabel}/*`} element={<TokenPage />} />

<Route
path={`/${chainTokenLabel}/*`}
element={
complianceState === ComplianceStates.FULL_ACCESS ? (
<TokenPage />
) : (
<Navigate to={DEFAULT_TRADE_ROUTE} />
)
}
/>

{isTablet && (
<>
<Route path={AppRoute.Alerts} element={<AlertsPage />} />
Expand Down
4 changes: 4 additions & 0 deletions src/constants/abacus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ export const RestrictionType = Abacus.exchange.dydx.abacus.output.Restriction;
const restrictionTypes = [...RestrictionType.values()] as const;
export type RestrictionTypes = (typeof restrictionTypes)[number];

// ------ Compliance ------ //
export const ComplianceStatus = Abacus.exchange.dydx.abacus.output.ComplianceStatus;
export type Compliance = Abacus.exchange.dydx.abacus.output.Compliance;

// ------ Api data ------ //
export const ApiData = Abacus.exchange.dydx.abacus.state.manager.ApiData;

Expand Down
13 changes: 13 additions & 0 deletions src/constants/compliance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export enum ComplianceReason {
MANUAL = 'MANUAL',
US_GEO = 'US_GEO',
CA_GEO = 'CA_GEO',
SANCTIONED_GEO = 'SANCTIONED_GEO',
COMPLIANCE_PROVIDER = 'COMPLIANCE_PROVIDER',
}

export enum ComplianceStates {
FULL_ACCESS = 'FUll_ACCESS',
READ_ONLY = 'READ_ONLY',
CLOSE_ONLY = 'CLOSE_ONLY',
}
2 changes: 2 additions & 0 deletions src/constants/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ export enum DialogTypes {
AdjustIsolatedMargin = 'AdjustIsolatedMargin',
AdjustTargetLeverage = 'AdjustTargetLeverage',
ClosePosition = 'ClosePosition',
ComplianceConfig = 'ComplianceConfig',
Deposit = 'Deposit',
DisconnectWallet = 'DisconnectWallet',
DisplaySettings = 'DisplaySettings',
ExchangeOffline = 'ExchangeOffline',
ExternalLink = 'ExternalLink',
ExternalNavStride = 'ExternalNavStride',
FillDetails = 'FillDetails',
GeoCompliance = 'GeoCompliance',
Help = 'Help',
ExternalNavKeplr = 'ExternalNavKeplr',
ManageFunds = 'ManageFunds',
Expand Down
Loading

0 comments on commit 8191f8e

Please sign in to comment.