Skip to content
This repository has been archived by the owner on Apr 4, 2022. It is now read-only.

Commit

Permalink
Merge f3b8190 into 464538f
Browse files Browse the repository at this point in the history
  • Loading branch information
alfetopito committed Apr 20, 2020
2 parents 464538f + f3b8190 commit 457465e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gnosis.pm/dex-js",
"version": "0.2.2",
"version": "0.2.3-RC.2",
"description": "Gnosis Protocol JS integration: utils, contracts and other goodies",
"license": "MIT",
"bugs": {
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './format'
export * from './orders'
export * from './misc'
export * from './price'
export * from './urlEncoding'
48 changes: 48 additions & 0 deletions src/utils/urlEncoding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// We cannot have a dash in the symbol because:
// 1. We use a `-` to separate token symbols in the URL to name the market.
// For example "A-B", where A is the sell token and B is the buy token
// 2. Tokens can have dashes in their symbols
// 3. Even if we encode dashes to `%2D`, browsers auto convert them back to `-`
// For these reasons, we are picking a symbol that is not ambiguous with a dash
// and it has very little chance to be used as part of a token symbol.
// Meet, the circle dash ⊝ https://www.fileformat.info/info/unicode/char/229d/index.htm
const encodedDashSymbol = '\u229D'

const dashRegex = /-/g
const encodedDashRegex = new RegExp(encodedDashSymbol, 'g')

/**
* Encodes given symbol into a URL friendly string.
* Additionally, encodes chars that might be ambiguous in the URL
* such as a dash `-`
*
* @param symbol Symbol to URL encode
*/
export function encodeSymbol(symbol: string): string {
const sanitizedSymbol = symbol
.trim() // Your token has leading/trailing spaces? Bad luck
.replace(dashRegex, encodedDashSymbol) // Your token has dashes? you won't see them for awhile
return encodeURIComponent(sanitizedSymbol)
}

/**
* Syntactic sugar for encoding Token objects where `symbol` is an optional property.
* When there's no symbol, uses token address instead.
*
* @param token Object containing address and optionally symbol
*/
export function encodeTokenSymbol(token: { symbol?: string; address: string }): string {
return token.symbol ? encodeSymbol(token.symbol) : token.address
}

/**
* Decodes symbol which is URL encoded.
* Trims trailing and leading spaces.
*
* @param symbol URL encoded symbol
*/
export function decodeSymbol(symbol: string): string {
return decodeURIComponent(symbol)
.replace(encodedDashRegex, '-') // Put the dashes back
.trim() // Remove any leading/trailing spaces that might have sneaked in
}
24 changes: 24 additions & 0 deletions test/utils/urlEncoding/decodeSymbol.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { decodeSymbol } from '../../../src/utils'
describe('Decoding symbol', () => {
test('A-Z symbol', () => {
expect(decodeSymbol('TNK')).toBe('TNK')
})

test('Special chars', () => {
expect(decodeSymbol("Token%20%2F21%20%E2%8A%9D%2055%3F%20**%20%7C%E2%8A%9D%3D%2B%23%40%25%5E%26%60'%22")).toBe(
'Token /21 - 55? ** |-=+#@%^&`\'"',
)
})
test('Dash in the symbol', () => {
expect(decodeSymbol('TN%E2%8A%9DHUI')).toBe('TN-HUI')
})
test('Leading and trailing spaces', () => {
expect(decodeSymbol('%20SPACES%20HERE%20%20')).toBe('SPACES HERE')
})
test('Unicode chars', () => {
expect(decodeSymbol('Oh%20%F0%9F%92%BB%20%F0%9F%A7%B5%20%F0%9F%94%A5')).toBe('Oh 💻 🧵 🔥')
})
test('Address symbol', () => {
expect(decodeSymbol('0xa09000900')).toBe('0xa09000900')
})
})
27 changes: 27 additions & 0 deletions test/utils/urlEncoding/encodeSymbol.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { encodeSymbol } from '../../../src/utils'

describe('Encoding symbol', () => {
test('A-Z symbol', () => {
expect(encodeSymbol('DAI')).toBe('DAI')
})

test('Special chars symbol', () => {
expect(encodeSymbol('Token /21 - 55? ** |-=+#@%^&`\'"')).toBe(
"Token%20%2F21%20%E2%8A%9D%2055%3F%20**%20%7C%E2%8A%9D%3D%2B%23%40%25%5E%26%60'%22",
)
})

test('Should encode dash char "-"', () => {
expect(encodeSymbol('-')).toBe('%E2%8A%9D')
})

test('Unicode emojis symbol', () => {
expect(encodeSymbol('Oh 💻 🧵 🔥')).toBe('Oh%20%F0%9F%92%BB%20%F0%9F%A7%B5%20%F0%9F%94%A5')
})

test('Trims leading and trailing spaces', () => {
expect(encodeSymbol(' Why would someone do something like this? ')).toBe(
'Why%20would%20someone%20do%20something%20like%20this%3F',
)
})
})
28 changes: 28 additions & 0 deletions test/utils/urlEncoding/encodeTokenSymbol.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { encodeTokenSymbol } from '../../../src/utils'

describe('Encoding token', () => {
const address = '0x0000'
test('Token with A-Z symbol', () => {
const token = { symbol: 'TKN', address }

expect(encodeTokenSymbol(token)).toBe(token.symbol)
})

test('Token with special chars', () => {
const token = { symbol: ')(*&^%$#@!`~-\'";:.,<>?/\\', address }

expect(encodeTokenSymbol(token)).toBe(")(*%26%5E%25%24%23%40!%60~%E2%8A%9D'%22%3B%3A.%2C%3C%3E%3F%2F%5C")
})

test('Token with unicode chars', () => {
const token = { symbol: '🔥', address }

expect(encodeTokenSymbol(token)).toBe('%F0%9F%94%A5')
})

test('Token without symbol', () => {
const token = { address }

expect(encodeTokenSymbol(token)).toBe(token.address)
})
})

0 comments on commit 457465e

Please sign in to comment.