-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add a feature to manually add custom tokens (#604)
- Loading branch information
Showing
30 changed files
with
822 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const DEFAULT_GAS_WANTED = 10_000_000; | ||
|
||
export const TRANSACTION_MESSAGE_SEND_OF_REGISTER = '200000000ugnot'; |
2 changes: 2 additions & 0 deletions
2
packages/adena-extension/src/common/errors/validation/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
export * from './address-book-validation-error'; | ||
export * from './password-validation-error'; | ||
export * from './token-validation-error'; |
23 changes: 23 additions & 0 deletions
23
packages/adena-extension/src/common/errors/validation/token-validation-error.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { BaseError } from '../base'; | ||
|
||
const ERROR_VALUE = { | ||
INVALID_REALM_PATH: { | ||
status: 4000, | ||
type: 'INVALID_REALM_PATH', | ||
message: 'Invalid realm path', | ||
}, | ||
ALREADY_ADDED: { | ||
status: 4000, | ||
type: 'ALREADY_ADDED', | ||
message: 'Already added', | ||
}, | ||
}; | ||
|
||
type ErrorType = keyof typeof ERROR_VALUE; | ||
|
||
export class TokenValidationError extends BaseError { | ||
constructor(errorType: ErrorType) { | ||
super(ERROR_VALUE[errorType]); | ||
Object.setPrototypeOf(this, TokenValidationError.prototype); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 5 additions & 5 deletions
10
packages/adena-extension/src/common/provider/gno/gno-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
export const parseGRC20ByABCIRender = ( | ||
response: string, | ||
): { | ||
tokenName: string; | ||
tokenSymbol: string; | ||
tokenDecimals: number; | ||
totalSupply: bigint; | ||
knownAccounts: bigint; | ||
} => { | ||
if (!response) { | ||
throw new Error('failed parse grc20 token render'); | ||
} | ||
|
||
const regex = | ||
/#\s(?<tokenName>.+)\s\(\$(?<tokenSymbol>.+)\)\s*\* \*\*Decimals\*\*: (?<tokenDecimals>\d+)\s*\* \*\*Total supply\*\*: (?<totalSupply>\d+)\s*\* \*\*Known accounts\*\*: (?<knownAccounts>\d+)/; | ||
|
||
const match = response.match(regex); | ||
|
||
if (!match || !match?.groups) { | ||
throw new Error('failed parse grc20 token render'); | ||
} | ||
|
||
return { | ||
tokenName: match.groups.tokenName, | ||
tokenSymbol: match.groups.tokenSymbol, | ||
tokenDecimals: parseInt(match.groups.tokenDecimals, 10), | ||
totalSupply: BigInt(match.groups.totalSupply), | ||
knownAccounts: BigInt(match.groups.knownAccounts), | ||
}; | ||
}; | ||
|
||
/** | ||
* realm's path format: {Domain}/{Type}/{Namespace}/{Remain Path...} | ||
*/ | ||
export const parseReamPathItemsByPath = ( | ||
realmPath: string, | ||
): { | ||
domain: string; | ||
type: string; | ||
namespace: string; | ||
remainPath: string; | ||
} => { | ||
const pathItems = realmPath.split('/'); | ||
if (pathItems.length < 4) { | ||
throw new Error('not available realm path, path size less than 4'); | ||
} | ||
|
||
const [domain, type, namespace, ...remainPathItems] = pathItems; | ||
|
||
const availableDomains = ['gno.land']; | ||
if (!availableDomains.includes(domain)) { | ||
throw new Error('not available realm path, domain is ' + domain); | ||
} | ||
|
||
const availableTypes = ['p', 'r']; | ||
if (!availableTypes.includes(type)) { | ||
throw new Error('not available realm path, type is ' + type); | ||
} | ||
|
||
return { | ||
domain, | ||
type, | ||
namespace, | ||
remainPath: remainPathItems.join('/'), | ||
}; | ||
}; | ||
|
||
export const parseGRC20ByFileContents = ( | ||
contents: string, | ||
): { | ||
tokenName: string; | ||
tokenSymbol: string; | ||
tokenDecimals: number; | ||
} | null => { | ||
const newBankerRegex = /grc20\.NewBanker\(([^)]+)\)/; | ||
const match = contents.match(newBankerRegex); | ||
const matchLine = match?.[1] || null; | ||
|
||
if (!matchLine) { | ||
return null; | ||
} | ||
|
||
const args = matchLine.split(',').map((arg) => arg.trim()); | ||
if (args.length < 3) { | ||
return null; | ||
} | ||
|
||
const tokenName = args[0].startsWith('"') ? args[0].slice(1, -1) : args[0]; | ||
const tokenSymbol = args[1].startsWith('"') ? args[1].slice(1, -1) : args[1]; | ||
const tokenDecimals = isNaN(Number(args[2])) ? 0 : Number(args[2]); | ||
|
||
return { | ||
tokenName, | ||
tokenSymbol, | ||
tokenDecimals, | ||
}; | ||
}; |
8 changes: 5 additions & 3 deletions
8
...rc/components/pages/additional-token/additional-token-info/additional-token-info.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 15 additions & 15 deletions
30
...ion/src/components/pages/additional-token/additional-token-info/additional-token-info.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,50 @@ | ||
import React from 'react'; | ||
import { AdditionalTokenInfoWrapper, AdditionalTokenInfoItemWrapper } from './additional-token-info.styles'; | ||
import { | ||
AdditionalTokenInfoItemWrapper, | ||
AdditionalTokenInfoWrapper, | ||
TokenInfoValueLoadingBox, | ||
} from './additional-token-info.styles'; | ||
|
||
export interface AdditionalTokenInfoProps { | ||
isLoading: boolean; | ||
symbol: string; | ||
path: string; | ||
decimals: string; | ||
} | ||
|
||
export interface AdditionalTokenInfoBlockProps { | ||
isLoading: boolean; | ||
title: string; | ||
value: string; | ||
} | ||
|
||
const AdditionalTokenInfoBlock: React.FC<AdditionalTokenInfoBlockProps> = ({ | ||
title, | ||
value, | ||
isLoading, | ||
}) => { | ||
return ( | ||
<AdditionalTokenInfoItemWrapper> | ||
<span className='title'>{title}:</span> | ||
<span className='value'>{value}</span> | ||
|
||
{isLoading ? <TokenInfoValueLoadingBox /> : <span className='value'>{value}</span>} | ||
</AdditionalTokenInfoItemWrapper> | ||
); | ||
}; | ||
|
||
const AdditionalTokenInfo: React.FC<AdditionalTokenInfoProps> = ({ | ||
isLoading, | ||
symbol, | ||
path, | ||
decimals, | ||
}) => { | ||
return ( | ||
<AdditionalTokenInfoWrapper> | ||
<AdditionalTokenInfoBlock | ||
title='Token Symbol' | ||
value={symbol} | ||
/> | ||
<AdditionalTokenInfoBlock | ||
title='Token Path' | ||
value={path} | ||
/> | ||
<AdditionalTokenInfoBlock | ||
title='Token Decimals' | ||
value={decimals} | ||
/> | ||
<AdditionalTokenInfoBlock title='Token Symbol' value={symbol} isLoading={isLoading} /> | ||
<AdditionalTokenInfoBlock title='Token Path' value={path} isLoading={isLoading} /> | ||
<AdditionalTokenInfoBlock title='Token Decimals' value={decimals} isLoading={isLoading} /> | ||
</AdditionalTokenInfoWrapper> | ||
); | ||
}; | ||
|
||
export default AdditionalTokenInfo; | ||
export default AdditionalTokenInfo; |
33 changes: 33 additions & 0 deletions
33
...s/pages/additional-token/additional-token-path-input/additional-token-path-input.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React from 'react'; | ||
|
||
import { render } from '@testing-library/react'; | ||
import { RecoilRoot } from 'recoil'; | ||
import { ThemeProvider } from 'styled-components'; | ||
|
||
import { GlobalPopupStyle } from '@styles/global-style'; | ||
import theme from '@styles/theme'; | ||
|
||
import AdditionalTokenPathInput, { | ||
AdditionalTokenPathInputProps, | ||
} from './additional-token-path-input'; | ||
|
||
describe('AdditionalTokenPathInput Component', () => { | ||
it('AdditionalTokenPathInput render', () => { | ||
const args: AdditionalTokenPathInputProps = { | ||
keyword: '', | ||
onChangeKeyword: () => { | ||
return; | ||
}, | ||
errorMessage: 'error', | ||
}; | ||
|
||
render( | ||
<RecoilRoot> | ||
<GlobalPopupStyle /> | ||
<ThemeProvider theme={theme}> | ||
<AdditionalTokenPathInput {...args} /> | ||
</ThemeProvider> | ||
</RecoilRoot>, | ||
); | ||
}); | ||
}); |
13 changes: 13 additions & 0 deletions
13
...ages/additional-token/additional-token-path-input/additional-token-path-input.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Meta, StoryObj } from '@storybook/react'; | ||
import AdditionalTokenPathInput, { | ||
type AdditionalTokenPathInputProps, | ||
} from './additional-token-path-input'; | ||
|
||
export default { | ||
title: 'components/additional-token/AdditionalTokenPathInput', | ||
component: AdditionalTokenPathInput, | ||
} as Meta<typeof AdditionalTokenPathInput>; | ||
|
||
export const Default: StoryObj<AdditionalTokenPathInputProps> = { | ||
args: {}, | ||
}; |
27 changes: 27 additions & 0 deletions
27
.../pages/additional-token/additional-token-path-input/additional-token-path-input.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import styled from 'styled-components'; | ||
|
||
import { View } from '@components/atoms'; | ||
import { fonts, getTheme } from '@styles/theme'; | ||
|
||
export const AdditionalTokenPathInputWrapper = styled(View)` | ||
width: 100%; | ||
.search-input { | ||
height: 48px; | ||
padding: 13px 16px; | ||
background-color: ${getTheme('neutral', '_9')}; | ||
border: 1px solid ${getTheme('neutral', '_7')}; | ||
color: ${getTheme('neutral', '_1')}; | ||
border-radius: 30px; | ||
${fonts.body2Reg}; | ||
&.error { | ||
border-color: ${getTheme('red', '_5')}; | ||
} | ||
} | ||
.error-message { | ||
padding: 0 8px; | ||
height: 18px; | ||
} | ||
`; |
Oops, something went wrong.