Skip to content

Commit e22ce57

Browse files
authored
Merge pull request #20 from dydxprotocol/sync/upstream-main-12-16-2025-2
chore: sync/upstream main 12 16 2025 2
2 parents 8ae8151 + 86ea18f commit e22ce57

39 files changed

+206
-483
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
"@cosmjs/stargate": "^0.32.1",
5555
"@cosmjs/tendermint-rpc": "^0.32.1",
5656
"@datadog/browser-logs": "^5.23.3",
57-
"@dydxprotocol/v4-client-js": "3.2.0",
58-
"@dydxprotocol/v4-localization": "1.1.365",
57+
"@dydxprotocol/v4-client-js": "3.3.0",
58+
"@dydxprotocol/v4-localization": "1.1.367",
5959
"@dydxprotocol/v4-proto": "^7.0.0-dev.0",
6060
"@emotion/is-prop-valid": "^1.3.0",
6161
"@hugocxl/react-to-image": "^0.0.9",

pnpm-lock.yaml

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ import { SkipProvider } from './hooks/transfers/skipClient';
5252
import { useAnalytics } from './hooks/useAnalytics';
5353
import { useBreakpoints } from './hooks/useBreakpoints';
5454
import { useCommandMenu } from './hooks/useCommandMenu';
55-
import { useComplianceState } from './hooks/useComplianceState';
5655
import { useInitializePage } from './hooks/useInitializePage';
5756
import { useLocalStorage } from './hooks/useLocalStorage';
57+
import { usePerpetualsComplianceState } from './hooks/usePerpetualsComplianceState';
5858
import { useReferralCode } from './hooks/useReferralCode';
5959
import { useShouldShowFooter } from './hooks/useShouldShowFooter';
6060
import { useSimpleUiEnabled } from './hooks/useSimpleUiEnabled';
@@ -109,7 +109,7 @@ const Content = () => {
109109
const isShowingFooter = useShouldShowFooter();
110110
const abDefaultToMarkets = useCustomFlagValue(CustomFlags.abDefaultToMarkets);
111111
const isSimpleUi = useSimpleUiEnabled();
112-
const { showComplianceBanner } = useComplianceState();
112+
const { showComplianceBanner } = usePerpetualsComplianceState();
113113
const isSimpleUiUserMenuOpen = useAppSelector(getIsUserMenuOpen);
114114

115115
// Track current path in Redux for conditional polling

src/bonsai/calculators/compliance.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,33 @@ import { ComplianceState } from '@/state/raw';
33
import { Compliance, ComplianceStatus } from '../types/summaryTypes';
44

55
export function calculateCompliance({
6+
geoHeaders,
67
geo: geoBase,
78
localAddressScreenV2,
89
sourceAddressScreenV2,
910
}: ComplianceState): Compliance {
10-
const rawGeo = geoBase.data;
1111
const geo = {
12-
currentlyGeoBlocked: rawGeo == null ? false : rawGeo.blocked && !rawGeo.whitelisted,
13-
currentCountry: rawGeo?.country,
12+
currentlyGeoBlocked: geoBase.data?.whitelisted
13+
? false
14+
: geoHeaders.data?.status === 'restricted',
15+
currentCountry: geoHeaders.data?.country,
1416
};
17+
1518
if (sourceAddressScreenV2.data?.status === ComplianceStatus.BLOCKED) {
1619
return {
1720
geo,
1821
status: ComplianceStatus.BLOCKED,
1922
updatedAt: sourceAddressScreenV2.data.updatedAt,
2023
};
2124
}
25+
2226
if (localAddressScreenV2.data?.errors != null) {
2327
return {
2428
geo,
2529
status: ComplianceStatus.UNKNOWN,
2630
};
2731
}
32+
2833
return {
2934
geo,
3035
...(localAddressScreenV2.data ?? {

src/bonsai/rest/compliance.ts

Lines changed: 4 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
1-
import { ComplianceV2Response } from '@dydxprotocol/v4-client-js';
2-
3-
import { DydxChainId, DydxNetwork, ENVIRONMENT_CONFIG_MAP } from '@/constants/networks';
41
import { timeUnits } from '@/constants/time';
52

6-
import { type AppDispatch, type RootState, type RootStore } from '@/state/_store';
3+
import { type RootStore } from '@/state/_store';
74
import { getUserSourceWalletAddress, getUserWalletAddress } from '@/state/accountInfoSelectors';
8-
import { appQueryClient } from '@/state/appQueryClient';
95
import { getSelectedDydxChainId, getSelectedNetwork } from '@/state/appSelectors';
106
import { createAppSelector } from '@/state/appTypes';
11-
import {
12-
ComplianceErrors,
13-
setLocalAddressScreenV2Raw,
14-
setSourceAddressScreenV2Raw,
15-
} from '@/state/raw';
7+
import { setLocalAddressScreenV2Raw, setSourceAddressScreenV2Raw } from '@/state/raw';
168
import { getHdKeyNonce } from '@/state/walletSelectors';
179

18-
import { signCompliancePayload } from '@/lib/compliance';
19-
import { mapIfPresent } from '@/lib/do';
20-
import { removeTrailingSlash } from '@/lib/stringifyHelpers';
21-
22-
import { loadableIdle, loadableLoaded } from '../lib/loadable';
23-
import { logBonsaiError } from '../logs';
24-
import { selectRawLocalAddressScreenV2 } from '../selectors/base';
10+
import { loadableIdle } from '../lib/loadable';
2511
import { ComplianceResponse, ComplianceStatus } from '../types/summaryTypes';
26-
import { IndexerWebsocketManager } from '../websocket/lib/indexerWebsocketManager';
2712
import { createIndexerQueryStoreEffect } from './lib/indexerQueryStoreEffect';
2813
import { queryResultToLoadable } from './lib/queryResultToLoadable';
2914

@@ -78,85 +63,6 @@ export enum ComplianceAction {
7863
INVALID_SURVEY = 'INVALID_SURVEY',
7964
}
8065

81-
const COMPLIANCE_PAYLOAD_MESSAGE = 'Verify account ownership';
82-
83-
async function updateCompliance({
84-
chainId,
85-
address,
86-
hdKeyNonce,
87-
network,
88-
status,
89-
action,
90-
}: {
91-
chainId: DydxChainId;
92-
address: string;
93-
hdKeyNonce: number;
94-
network: DydxNetwork;
95-
status: ComplianceStatus;
96-
action: ComplianceAction;
97-
}) {
98-
const networkConfig = ENVIRONMENT_CONFIG_MAP[network];
99-
const indexerUrl = mapIfPresent(
100-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
101-
networkConfig?.endpoints.indexers[0]?.api,
102-
removeTrailingSlash
103-
);
104-
const payload = {
105-
message: COMPLIANCE_PAYLOAD_MESSAGE,
106-
action,
107-
status,
108-
chainId,
109-
};
110-
111-
const signingResponse = await signCompliancePayload(address, hdKeyNonce, payload);
112-
if (!signingResponse) {
113-
return { status: ComplianceStatus.UNKNOWN };
114-
}
115-
116-
const parsedSigningResponse = JSON.parse(signingResponse);
117-
if (parsedSigningResponse.error != null) {
118-
return { status: ComplianceStatus.UNKNOWN };
119-
}
120-
121-
const { signedMessage, publicKey, timestamp, isKeplr } = parsedSigningResponse;
122-
123-
const urlAddition = isKeplr ? '/v4/compliance/geoblock-keplr' : '/v4/compliance/geoblock';
124-
const hasMessageAndKey = signedMessage !== null && publicKey !== null;
125-
const isKeplrOrHasTimestamp = timestamp !== null || isKeplr === true;
126-
127-
if (!hasMessageAndKey || !isKeplrOrHasTimestamp || !indexerUrl) {
128-
return { status: ComplianceStatus.UNKNOWN };
129-
}
130-
131-
const body = isKeplr
132-
? {
133-
address,
134-
message: payload.message,
135-
action: payload.action,
136-
signedMessage,
137-
pubkey: publicKey,
138-
}
139-
: {
140-
address,
141-
message: payload.message,
142-
currentStatus: payload.status,
143-
action: payload.action,
144-
signedMessage,
145-
pubkey: publicKey,
146-
timestamp,
147-
};
148-
149-
const options: RequestInit = {
150-
method: 'POST',
151-
headers: new globalThis.Headers([['Content-Type', 'application/json']]),
152-
body: JSON.stringify(body),
153-
};
154-
155-
const response = await fetch(`${indexerUrl}${urlAddition}`, options);
156-
const data = await response.json();
157-
return data as ComplianceV2Response & ComplianceErrors;
158-
}
159-
16066
export function setUpIndexerLocalAddressScreenV2Query(store: RootStore) {
16167
const cleanupEffect = createIndexerQueryStoreEffect(store, {
16268
name: 'localAddressScreenV2',
@@ -167,7 +73,7 @@ export function setUpIndexerLocalAddressScreenV2Query(store: RootStore) {
16773
address,
16874
network,
16975
],
170-
getQueryFn: (indexerClient, { chainId, address, network, hdKeyNonce }) => {
76+
getQueryFn: (indexerClient, { address, hdKeyNonce }) => {
17177
if (address == null || hdKeyNonce == null) {
17278
return null;
17379
}
@@ -181,19 +87,8 @@ export function setUpIndexerLocalAddressScreenV2Query(store: RootStore) {
18187
return { status: ComplianceStatus.UNKNOWN };
18288
}
18389

184-
const updateResult = updateCompliance({
185-
address,
186-
hdKeyNonce,
187-
chainId,
188-
network,
189-
status: firstScreenResult.status,
190-
action: ComplianceAction.CONNECT,
191-
});
192-
19390
return {
19491
...firstScreenResult,
195-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
196-
...(updateResult ?? {}),
19792
};
19893
};
19994
},
@@ -208,42 +103,3 @@ export function setUpIndexerLocalAddressScreenV2Query(store: RootStore) {
208103
store.dispatch(setLocalAddressScreenV2Raw(loadableIdle()));
209104
};
210105
}
211-
212-
export const triggerCompliance = (action: ComplianceAction) => {
213-
return async (dispatch: AppDispatch, getState: () => RootState) => {
214-
try {
215-
const state = getState();
216-
const currentLocalScreenStatus = selectRawLocalAddressScreenV2(state).data?.status;
217-
const chainId = getSelectedDydxChainId(state);
218-
const address = getUserWalletAddress(state);
219-
const hdKeyNonce = getHdKeyNonce(state);
220-
const network = getSelectedNetwork(state);
221-
222-
if (!address || !currentLocalScreenStatus || !hdKeyNonce) {
223-
throw new Error('TriggerCompliance: No account connected or screen status not loaded');
224-
}
225-
226-
const result = await updateCompliance({
227-
chainId,
228-
address,
229-
hdKeyNonce,
230-
network,
231-
status: currentLocalScreenStatus,
232-
action,
233-
});
234-
235-
dispatch(setLocalAddressScreenV2Raw(loadableLoaded(result)));
236-
237-
// force refresh all account information from indexer
238-
IndexerWebsocketManager.getActiveResources().forEach((r) => r.restart());
239-
appQueryClient.invalidateQueries({
240-
queryKey: ['indexer', 'account'],
241-
});
242-
243-
return true;
244-
} catch (e) {
245-
logBonsaiError('TriggerCompliance', 'failed to update compliance', { error: e });
246-
return false;
247-
}
248-
};
249-
};

src/bonsai/rest/fills.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function setUpFillsQuery(store: RootStore) {
1919
selector: selectParentSubaccountInfo,
2020
getQueryKey: (data) => ['account', 'fills', data.wallet, data.subaccount],
2121
getQueryFn: (indexerClient, data) => {
22-
if (!isTruthy(data.wallet) || data.subaccount == null) {
22+
if (!isTruthy(data.wallet) || data.subaccount == null || data.isGeoRestricted) {
2323
return null;
2424
}
2525
return () =>

0 commit comments

Comments
 (0)