@openocean.finance/widget 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/esm/components/Header/Header.js +3 -3
  2. package/dist/esm/components/Header/Header.js.map +1 -1
  3. package/dist/esm/components/Messages/PriceImpactHighMessage.d.ts +3 -2
  4. package/dist/esm/components/Messages/PriceImpactHighMessage.js +16 -9
  5. package/dist/esm/components/Messages/PriceImpactHighMessage.js.map +1 -1
  6. package/dist/esm/components/Messages/WarningMessages.js +5 -2
  7. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  8. package/dist/esm/components/Messages/useMessageQueue.d.ts +1 -0
  9. package/dist/esm/components/Messages/useMessageQueue.js +15 -4
  10. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  11. package/dist/esm/components/TransactionDetails.js +6 -4
  12. package/dist/esm/components/TransactionDetails.js.map +1 -1
  13. package/dist/esm/config/version.d.ts +1 -1
  14. package/dist/esm/config/version.js +1 -1
  15. package/dist/esm/hooks/useRoutes.js +3 -1
  16. package/dist/esm/hooks/useRoutes.js.map +1 -1
  17. package/dist/esm/hooks/useTokenPrice.d.ts +1 -1
  18. package/dist/esm/hooks/useTokenPrice.js +1 -1
  19. package/dist/esm/hooks/useTokenPrice.js.map +1 -1
  20. package/dist/esm/pages/MainPage/ReviewButton.js +10 -2
  21. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  22. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +10 -2
  23. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  24. package/dist/esm/services/OpenOceanService.d.ts +2 -0
  25. package/dist/esm/services/OpenOceanService.js +2 -0
  26. package/dist/esm/services/OpenOceanService.js.map +1 -1
  27. package/dist/esm/types/widget.d.ts +4 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +3 -3
  30. package/src/components/Header/Header.tsx +2 -2
  31. package/src/components/Messages/PriceImpactHighMessage.tsx +42 -10
  32. package/src/components/Messages/WarningMessages.tsx +15 -3
  33. package/src/components/Messages/useMessageQueue.ts +16 -4
  34. package/src/components/TransactionDetails.tsx +6 -4
  35. package/src/config/version.ts +1 -1
  36. package/src/hooks/useRoutes.ts +3 -0
  37. package/src/hooks/useTokenPrice.ts +1 -1
  38. package/src/pages/MainPage/ReviewButton.tsx +18 -2
  39. package/src/pages/TransactionPage/StartTransactionButton.tsx +17 -2
  40. package/src/services/OpenOceanService.ts +5 -1
  41. package/src/types/widget.ts +4 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openocean.finance/widget",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Openocean Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/index.js",
@@ -47,8 +47,8 @@
47
47
  "@mui/icons-material": "6.0.2",
48
48
  "@mui/material": "^6.4.8",
49
49
  "@mui/system": "^6.4.8",
50
- "@openocean.finance/wallet-management": "^1.0.7",
51
- "@openocean.finance/widget-sdk": "^1.0.3",
50
+ "@openocean.finance/wallet-management": "^1.0.8",
51
+ "@openocean.finance/widget-sdk": "^1.0.5",
52
52
  "@solana/wallet-adapter-base": "^0.9.24",
53
53
  "@solana/web3.js": "^1.98.0",
54
54
  "@tanstack/react-virtual": "^3.13.4",
@@ -7,7 +7,7 @@ import { ElementId, createElementId } from '../../utils/elements.js'
7
7
  import { stickyHeaderRoutes } from '../../utils/navigationRoutes.js'
8
8
  import { Container } from './Header.style.js'
9
9
  import { NavigationHeader } from './NavigationHeader.js'
10
- // import { WalletHeader } from './WalletHeader.js'
10
+ import { WalletHeader } from './WalletHeader.js'
11
11
 
12
12
  export const HeaderContainer: FC<PropsWithChildren> = ({ children }) => {
13
13
  const { pathname } = useLocation()
@@ -52,7 +52,7 @@ export const HeaderContainer: FC<PropsWithChildren> = ({ children }) => {
52
52
  export const Header: FC = () => {
53
53
  return (
54
54
  <HeaderContainer>
55
- {/* <WalletHeader /> */}
55
+ <WalletHeader />
56
56
  <NavigationHeader />
57
57
  </HeaderContainer>
58
58
  )
@@ -1,17 +1,44 @@
1
- import { type BoxProps, Typography } from '@mui/material'
2
- import { useTranslation } from 'react-i18next'
1
+ import { WarningRounded } from '@mui/icons-material'
2
+ import {
3
+ type BoxProps,
4
+ Checkbox,
5
+ FormControlLabel,
6
+ Typography,
7
+ } from '@mui/material'
3
8
  import { AlertMessage } from './AlertMessage.js'
4
-
5
- interface GasSufficiencyMessageProps extends BoxProps {
6
- // insufficientGas?: GasSufficiency[]
9
+ import { useStorePriceImpactAcknowledged } from './useMessageQueue.js'
10
+ interface PriceImpactHighMessageProps extends BoxProps {
11
+ onAcknowledge?: (acknowledged: boolean) => void
7
12
  }
8
13
 
9
- export const PriceImpactHighMessage: React.FC<GasSufficiencyMessageProps> = ({
14
+ export const PriceImpactHighMessage: React.FC<PriceImpactHighMessageProps> = ({
15
+ onAcknowledge,
10
16
  ...props
11
17
  }) => {
12
- const { t } = useTranslation()
18
+ const acknowledged = useStorePriceImpactAcknowledged(
19
+ (state) => state.priceImpactAcknowledged
20
+ )
21
+ const setAcknowledged = useStorePriceImpactAcknowledged(
22
+ (state) => state.setPriceImpactAcknowledged
23
+ )
24
+
25
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
26
+ const newValue = event.target.checked
27
+ setAcknowledged(newValue)
28
+ onAcknowledge?.(newValue)
29
+ }
30
+
13
31
  return (
14
- <AlertMessage severity="warning" {...props}>
32
+ <AlertMessage
33
+ severity="warning"
34
+ icon={<WarningRounded />}
35
+ title={
36
+ <Typography variant="body2" sx={{ color: 'text.primary' }}>
37
+ Price impact is too high
38
+ </Typography>
39
+ }
40
+ {...props}
41
+ >
15
42
  <Typography
16
43
  variant="body2"
17
44
  sx={{
@@ -19,9 +46,14 @@ export const PriceImpactHighMessage: React.FC<GasSufficiencyMessageProps> = ({
19
46
  pt: 1,
20
47
  }}
21
48
  >
22
- Price impact is too high. I acknowledge the risk and confirm to continue
23
- the trade despite loss of funs
49
+ I acknowledge the risk and confirm to continue the trade despite loss of
50
+ funds
24
51
  </Typography>
52
+ <FormControlLabel
53
+ control={<Checkbox checked={acknowledged} onChange={handleChange} />}
54
+ label="I understand and accept the risk"
55
+ sx={{ alignItems: 'center', px: 2, pt: 1 }}
56
+ />
25
57
  </AlertMessage>
26
58
  )
27
59
  }
@@ -7,7 +7,10 @@ import { GasSufficiencyMessage } from './GasSufficiencyMessage.js'
7
7
  import { GasSufficiencyMessageBridge } from './GasSufficiencyMessageBridge.js'
8
8
  import { PriceImpactHighMessage } from './PriceImpactHighMessage.js'
9
9
  import { ToAddressRequiredMessage } from './ToAddressRequiredMessage.js'
10
- import { useMessageQueue } from './useMessageQueue.js'
10
+ import {
11
+ useMessageQueue,
12
+ useStorePriceImpactAcknowledged,
13
+ } from './useMessageQueue.js'
11
14
 
12
15
  type WarningMessagesProps = BoxProps & {
13
16
  route?: Route
@@ -20,7 +23,9 @@ export const WarningMessages: React.FC<WarningMessagesProps> = ({
20
23
  ...props
21
24
  }) => {
22
25
  const { messages, hasMessages } = useMessageQueue(route, allowInteraction)
23
-
26
+ const setPriceImpactAcknowledged = useStorePriceImpactAcknowledged(
27
+ (state) => state.setPriceImpactAcknowledged
28
+ )
24
29
  const getMessage = () => {
25
30
  switch (messages[0]?.id) {
26
31
  case 'INSUFFICIENT_FUNDS':
@@ -37,7 +42,14 @@ export const WarningMessages: React.FC<WarningMessagesProps> = ({
37
42
  case 'ACCOUNT_NOT_DEPLOYED':
38
43
  return <AccountNotDeployedMessage {...props} />
39
44
  case 'PRICE_IMPACT_HIGH':
40
- return <PriceImpactHighMessage {...props} />
45
+ return (
46
+ <PriceImpactHighMessage
47
+ onAcknowledge={(e) => {
48
+ setPriceImpactAcknowledged(e)
49
+ }}
50
+ {...props}
51
+ />
52
+ )
41
53
  case 'TO_ADDRESS_REQUIRED':
42
54
  const fromChainId = route?.fromChainId
43
55
  const toChainId = route?.toChainId
@@ -1,5 +1,6 @@
1
1
  import type { Route } from '@openocean.finance/widget-sdk'
2
2
  import { useMemo } from 'react'
3
+ import { create } from 'zustand'
3
4
  import { useFromTokenSufficiency } from '../../hooks/useFromTokenSufficiency.js'
4
5
  import { useGasSufficiency } from '../../hooks/useGasSufficiency.js'
5
6
  import { useGasSufficiencyBridge } from '../../hooks/useGasSufficiencyBridge.js'
@@ -7,6 +8,15 @@ import { useIsCompatibleDestinationAccount } from '../../hooks/useIsCompatibleDe
7
8
  import { usePriceImpact } from '../../hooks/usePriceImpact.js'
8
9
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
9
10
 
11
+ export const useStorePriceImpactAcknowledged = create((set) => ({
12
+ priceImpactAcknowledged: false,
13
+ setPriceImpactAcknowledged: (v: boolean) =>
14
+ set((state) => {
15
+ return {
16
+ priceImpactAcknowledged: v,
17
+ }
18
+ }),
19
+ }))
10
20
  interface QueuedMessage {
11
21
  id: string
12
22
  priority: number
@@ -33,16 +43,16 @@ export const useMessageQueue = (route?: Route, allowInteraction?: boolean) => {
33
43
  const messageQueue = useMemo(() => {
34
44
  const queue: QueuedMessage[] = []
35
45
 
36
- if (Math.abs(priceImpact) >= 0.3) {
46
+ if (insufficientFromToken) {
37
47
  queue.push({
38
- id: 'PRICE_IMPACT_HIGH',
48
+ id: 'INSUFFICIENT_FUNDS',
39
49
  priority: 1,
40
50
  })
41
51
  }
42
52
 
43
- if (insufficientFromToken) {
53
+ if (priceImpact <= -0.3) {
44
54
  queue.push({
45
- id: 'INSUFFICIENT_FUNDS',
55
+ id: 'PRICE_IMPACT_HIGH',
46
56
  priority: 1,
47
57
  })
48
58
  }
@@ -81,9 +91,11 @@ export const useMessageQueue = (route?: Route, allowInteraction?: boolean) => {
81
91
  allowInteraction,
82
92
  insufficientFromToken,
83
93
  insufficientGas,
94
+ insufficientBridge,
84
95
  isCompatibleDestinationAccount,
85
96
  requiredToAddress,
86
97
  toAddress,
98
+ priceImpact,
87
99
  ])
88
100
 
89
101
  return {
@@ -291,10 +291,12 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
291
291
  sx={{
292
292
  fontWeight: 600,
293
293
  color: priceImpact
294
- ? Math.abs(Number(priceImpact)) >= 0.3
295
- ? 'error.main'
296
- : 'orange'
297
- : 'main',
294
+ ? Number(priceImpact) < 0
295
+ ? Number(priceImpact) > -0.3
296
+ ? 'orange'
297
+ : 'error.main'
298
+ : 'green'
299
+ : '',
298
300
  }}
299
301
  >
300
302
  {priceImpact ? t('format.percent', { value: priceImpact }) : '--'}
@@ -1,2 +1,2 @@
1
1
  export const name = '@openocean.finance/widget'
2
- export const version = '1.0.7'
2
+ export const version = '1.0.8'
@@ -37,6 +37,7 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
37
37
  fee,
38
38
  feeConfig,
39
39
  useRelayerRoutes,
40
+ referrer
40
41
  } = useWidgetConfig()
41
42
  const setExecutableRoute = useSetExecutableRoute()
42
43
  const queryClient = useQueryClient()
@@ -238,6 +239,8 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
238
239
  slippage: formattedSlippage, // OpenOcean expects slippage like '100' for 1%
239
240
  gasPrice: gasPrice || '10', // Consider chain-specific defaults
240
241
  enabledDexIds: fromChainId === 1151111081099710 ? '6' : '', // Example for Solana specific dex
242
+ referrer: referrer?.address || '',
243
+ referrerFee: referrer?.fee || '',
241
244
  })
242
245
  } else {
243
246
  // Use getQuote if account is not connected (view mode)
@@ -10,7 +10,7 @@ export const useTokenPrice = (chainId?: number, token?: TokenAmount) => {
10
10
  return undefined
11
11
  }
12
12
  const prices = await OpenOceanService.getTokensPrice(chainId.toString(), [token.address])
13
- return prices[token.address.toLowerCase()]
13
+ return prices[token.address.toLowerCase()] || 0
14
14
  },
15
15
  enabled: !!chainId && !!token?.address,
16
16
  refetchInterval: 60_000, // 每分钟更新一次价格
@@ -1,7 +1,10 @@
1
1
  import { useTranslation } from 'react-i18next'
2
2
  import { useNavigate } from 'react-router-dom'
3
3
  import { BaseTransactionButton } from '../../components/BaseTransactionButton/BaseTransactionButton.js'
4
- import { useMessageQueue } from '../../components/Messages/useMessageQueue.js'
4
+ import {
5
+ useMessageQueue,
6
+ useStorePriceImpactAcknowledged,
7
+ } from '../../components/Messages/useMessageQueue.js'
5
8
  import { useRoutes } from '../../hooks/useRoutes.js'
6
9
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
7
10
  import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
@@ -21,7 +24,20 @@ export const ReviewButton: React.FC = () => {
21
24
 
22
25
  const currentRoute = routes?.[0]
23
26
 
24
- const { hasMessages } = useMessageQueue(currentRoute, {})
27
+ const { messages } = useMessageQueue(currentRoute)
28
+ const priceImpactAcknowledged = useStorePriceImpactAcknowledged(
29
+ (state) => state.priceImpactAcknowledged
30
+ )
31
+
32
+ let hasMessages = messages.length > 0
33
+ if (messages.length > 0) {
34
+ const message: any = messages.find(
35
+ (message) => message.id === 'PRICE_IMPACT_HIGH'
36
+ )
37
+ if (message && priceImpactAcknowledged) {
38
+ hasMessages = false
39
+ }
40
+ }
25
41
 
26
42
  const handleClick = async () => {
27
43
  if (!currentRoute) {
@@ -1,5 +1,8 @@
1
1
  import { BaseTransactionButton } from '../../components/BaseTransactionButton/BaseTransactionButton.js'
2
- import { useMessageQueue } from '../../components/Messages/useMessageQueue.js'
2
+ import {
3
+ useMessageQueue,
4
+ useStorePriceImpactAcknowledged,
5
+ } from '../../components/Messages/useMessageQueue.js'
3
6
  import type { StartTransactionButtonProps } from './types.js'
4
7
 
5
8
  export const StartTransactionButton: React.FC<StartTransactionButtonProps> = ({
@@ -8,8 +11,20 @@ export const StartTransactionButton: React.FC<StartTransactionButtonProps> = ({
8
11
  text,
9
12
  loading,
10
13
  }) => {
11
- const { hasMessages, isLoading } = useMessageQueue(route, true)
14
+ const { messages, isLoading } = useMessageQueue(route)
15
+ const priceImpactAcknowledged = useStorePriceImpactAcknowledged(
16
+ (state) => state.priceImpactAcknowledged
17
+ )
12
18
 
19
+ let hasMessages = messages.length > 0
20
+ if (messages.length > 0) {
21
+ const message: any = messages.find(
22
+ (message) => message.id === 'PRICE_IMPACT_HIGH'
23
+ )
24
+ if (message && priceImpactAcknowledged) {
25
+ hasMessages = false
26
+ }
27
+ }
13
28
  return (
14
29
  <BaseTransactionButton
15
30
  onClick={onClick}
@@ -77,7 +77,9 @@ export class OpenOceanService {
77
77
  gasPrice?: string
78
78
  disabledDexIds?: string
79
79
  enabledDexIds?: string
80
- referrer?: string
80
+ referrer?: string,
81
+ referrerFee?: string,
82
+ referrerFeeShare?: string
81
83
  }) {
82
84
  const apiUrl = this.getApiUrl(params.chain)
83
85
  const slippage = (Number(params.slippage || '1') * 10000).toString()
@@ -94,6 +96,8 @@ export class OpenOceanService {
94
96
  disabledDexIds: params.disabledDexIds || '',
95
97
  enabledDexIds: params.enabledDexIds || '',
96
98
  referrer: params.referrer || '0x3487ef9f9b36547e43268b8f0e2349a226c70b53',
99
+ referrerFee: (Number(params.referrerFee || '0') * 100).toString(),
100
+ referrerFeeShare: params.referrerFeeShare || '1500',
97
101
  })
98
102
  const isV1Api = Object.keys(this.CHAIN_ID_MAP).includes(params.chain.toString())
99
103
  const swapEndpoint = isV1Api ? 'swap-quote' : 'swap'
@@ -231,7 +231,10 @@ export interface WidgetConfig {
231
231
  apiKey?: string
232
232
  fee?: number
233
233
  feeConfig?: WidgetFeeConfig
234
- referrer?: string
234
+ referrer?: {
235
+ address: string
236
+ fee: string
237
+ }
235
238
 
236
239
  routePriority?: Order
237
240
  slippage?: number