Skip to content

Commit d22530b

Browse files
authored
feat(ur-sdk): Add V4 Parser to UR parser (#147)
1 parent e825eb6 commit d22530b

File tree

5 files changed

+383
-132
lines changed

5 files changed

+383
-132
lines changed

sdks/universal-router-sdk/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"@uniswap/v2-sdk": "^4.6.0",
3939
"@uniswap/v3-core": "1.0.0",
4040
"@uniswap/v3-sdk": "^3.17.0",
41-
"@uniswap/v4-sdk": "^1.6.3",
41+
"@uniswap/v4-sdk": "^1.10.0",
4242
"bignumber.js": "^9.0.2",
4343
"ethers": "^5.7.0"
4444
},

sdks/universal-router-sdk/src/utils/commandParser.ts

+64-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ethers } from 'ethers'
22
import { abi } from '@uniswap/universal-router/artifacts/contracts/UniversalRouter.sol/UniversalRouter.json'
33
import { Interface } from '@ethersproject/abi'
4-
import { CommandType, COMMAND_ABI_DEFINITION, Subparser } from '../utils/routerCommands'
4+
import { V4BaseActionsParser, V4RouterAction } from '@uniswap/v4-sdk'
5+
import { CommandType, COMMAND_DEFINITION, Subparser, Parser } from '../utils/routerCommands'
56

67
export type Param = {
78
readonly name: string
@@ -36,35 +37,55 @@ export abstract class CommandParser {
3637

3738
return {
3839
commands: commandTypes.map((commandType: CommandType, i: number) => {
39-
const abiDef = COMMAND_ABI_DEFINITION[commandType]
40-
const rawParams = ethers.utils.defaultAbiCoder.decode(
41-
abiDef.map((command) => command.type),
42-
inputs[i]
43-
)
44-
const params = rawParams.map((param: any, j: number) => {
45-
switch (abiDef[j].subparser) {
46-
case Subparser.V3PathExactIn:
47-
return {
48-
name: abiDef[j].name,
49-
value: parseV3PathExactIn(param),
50-
}
51-
case Subparser.V3PathExactOut:
52-
return {
53-
name: abiDef[j].name,
54-
value: parseV3PathExactOut(param),
55-
}
56-
default:
57-
return {
58-
name: abiDef[j].name,
59-
value: param,
60-
}
40+
const commandDef = COMMAND_DEFINITION[commandType]
41+
42+
if (commandDef.parser === Parser.V4Actions) {
43+
const { actions } = V4BaseActionsParser.parseCalldata(inputs[i])
44+
return {
45+
commandName: CommandType[commandType],
46+
commandType,
47+
params: v4RouterCallToParams(actions),
6148
}
62-
})
63-
64-
return {
65-
commandName: CommandType[commandType],
66-
commandType,
67-
params,
49+
} else if (commandDef.parser === Parser.Abi) {
50+
const abiDef = commandDef.params
51+
const rawParams = ethers.utils.defaultAbiCoder.decode(
52+
abiDef.map((command) => command.type),
53+
inputs[i]
54+
)
55+
56+
const params = rawParams.map((param: any, j: number) => {
57+
switch (abiDef[j].subparser) {
58+
case Subparser.V3PathExactIn:
59+
return {
60+
name: abiDef[j].name,
61+
value: parseV3PathExactIn(param),
62+
}
63+
case Subparser.V3PathExactOut:
64+
return {
65+
name: abiDef[j].name,
66+
value: parseV3PathExactOut(param),
67+
}
68+
default:
69+
return {
70+
name: abiDef[j].name,
71+
value: param,
72+
}
73+
}
74+
})
75+
return {
76+
commandName: CommandType[commandType],
77+
commandType,
78+
params,
79+
}
80+
} else if (commandDef.parser === Parser.V3Actions) {
81+
// TODO: implement better parsing here
82+
return {
83+
commandName: CommandType[commandType],
84+
commandType,
85+
params: inputs,
86+
}
87+
} else {
88+
throw new Error(`Unsupported parser: ${commandDef}`)
6889
}
6990
}),
7091
}
@@ -127,3 +148,17 @@ export function parseV3PathExactOut(path: string): readonly V3PathItem[] {
127148

128149
return res
129150
}
151+
152+
function v4RouterCallToParams(actions: readonly V4RouterAction[]): readonly Param[] {
153+
return actions.map((action) => {
154+
return {
155+
name: action.actionName,
156+
value: action.params.map((param) => {
157+
return {
158+
name: param.name,
159+
value: param.value,
160+
}
161+
}),
162+
}
163+
})
164+
}

0 commit comments

Comments
 (0)