62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
|
import { utils } from 'ethers'
|
||
|
import { FeeAmount } from './constants'
|
||
|
|
||
|
const ADDR_SIZE = 20
|
||
|
const FEE_SIZE = 3
|
||
|
const OFFSET = ADDR_SIZE + FEE_SIZE
|
||
|
const DATA_SIZE = OFFSET + ADDR_SIZE
|
||
|
|
||
|
export function encodePath(path: string[], fees: FeeAmount[]): string {
|
||
|
if (path.length != fees.length + 1) {
|
||
|
throw new Error('path/fee lengths do not match')
|
||
|
}
|
||
|
|
||
|
let encoded = '0x'
|
||
|
for (let i = 0; i < fees.length; i++) {
|
||
|
// 20 byte encoding of the address
|
||
|
encoded += path[i].slice(2)
|
||
|
// 3 byte encoding of the fee
|
||
|
encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
|
||
|
}
|
||
|
// encode the final token
|
||
|
encoded += path[path.length - 1].slice(2)
|
||
|
|
||
|
return encoded.toLowerCase()
|
||
|
}
|
||
|
|
||
|
function decodeOne(tokenFeeToken: Buffer): [[string, string], number] {
|
||
|
// reads the first 20 bytes for the token address
|
||
|
const tokenABuf = tokenFeeToken.slice(0, ADDR_SIZE)
|
||
|
const tokenA = utils.getAddress('0x' + tokenABuf.toString('hex'))
|
||
|
|
||
|
// reads the next 2 bytes for the fee
|
||
|
const feeBuf = tokenFeeToken.slice(ADDR_SIZE, OFFSET)
|
||
|
const fee = feeBuf.readUIntBE(0, FEE_SIZE)
|
||
|
|
||
|
// reads the next 20 bytes for the token address
|
||
|
const tokenBBuf = tokenFeeToken.slice(OFFSET, DATA_SIZE)
|
||
|
const tokenB = utils.getAddress('0x' + tokenBBuf.toString('hex'))
|
||
|
|
||
|
return [[tokenA, tokenB], fee]
|
||
|
}
|
||
|
|
||
|
export function decodePath(path: string): [string[], number[]] {
|
||
|
let data = Buffer.from(path.slice(2), 'hex')
|
||
|
|
||
|
let tokens: string[] = []
|
||
|
let fees: number[] = []
|
||
|
let i = 0
|
||
|
let finalToken: string = ''
|
||
|
while (data.length >= DATA_SIZE) {
|
||
|
const [[tokenA, tokenB], fee] = decodeOne(data)
|
||
|
finalToken = tokenB
|
||
|
tokens = [...tokens, tokenA]
|
||
|
fees = [...fees, fee]
|
||
|
data = data.slice((i + 1) * OFFSET)
|
||
|
i += 1
|
||
|
}
|
||
|
tokens = [...tokens, finalToken]
|
||
|
|
||
|
return [tokens, fees]
|
||
|
}
|