Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
bridge-backend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
movabridge
bridge-backend
Commits
a91214c9
Commit
a91214c9
authored
Nov 25, 2025
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add swap router support
parent
c3edc3cd
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1060 additions
and
73 deletions
+1060
-73
Bridge.go
contract/bridge/Bridge.go
+22
-1
bridge.json
contract/bridge/bridge.json
+38
-0
abi.go
contract/router/abi.go
+30
-0
method.go
contract/router/method.go
+70
-0
dao.go
dao/dao.go
+8
-0
db.go
dao/db.go
+558
-47
model.go
model/api/model.go
+88
-18
controller.go
server/controller.go
+181
-5
router.go
server/router.go
+16
-2
tokenrepo.go
tokenrepo/tokenrepo.go
+49
-0
No files found.
contract/bridge/Bridge.go
View file @
a91214c9
This diff is collapsed.
Click to expand it.
contract/bridge/bridge.json
View file @
a91214c9
...
@@ -1433,5 +1433,43 @@
...
@@ -1433,5 +1433,43 @@
],
],
"stateMutability"
:
"view"
,
"stateMutability"
:
"view"
,
"type"
:
"function"
"type"
:
"function"
},
{
"inputs"
:
[
{
"internalType"
:
"address"
,
"name"
:
"token"
,
"type"
:
"address"
},
{
"internalType"
:
"uint256"
,
"name"
:
"amount"
,
"type"
:
"uint256"
},
{
"internalType"
:
"uint256"
,
"name"
:
"toChainID"
,
"type"
:
"uint256"
},
{
"internalType"
:
"address"
,
"name"
:
"receiver"
,
"type"
:
"address"
},
{
"internalType"
:
"address"
,
"name"
:
"fromToken"
,
"type"
:
"address"
},
{
"internalType"
:
"address"
,
"name"
:
"toToken"
,
"type"
:
"address"
}
],
"name"
:
"outTransferSwap"
,
"outputs"
:
[],
"stateMutability"
:
"nonpayable"
,
"type"
:
"function"
}
}
]
]
\ No newline at end of file
contract/router/abi.go
0 → 100644
View file @
a91214c9
package
router
const
UniswapV2RouterABI
=
`[
{
"constant": true,
"inputs": [
{
"internalType": "uint256",
"name": "amountIn",
"type": "uint256"
},
{
"internalType": "address[]",
"name": "path",
"type": "address[]"
}
],
"name": "getAmountsOut",
"outputs": [
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]`
contract/router/method.go
0 → 100644
View file @
a91214c9
package
router
import
(
"context"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"math/big"
"strings"
)
// Pre-parse the router ABI once at init to avoid repeated JSON parsing cost.
var
(
parsedRouterABI
abi
.
ABI
parseRouterErr
error
)
func
init
()
{
parsedRouterABI
,
parseRouterErr
=
abi
.
JSON
(
strings
.
NewReader
(
UniswapV2RouterABI
))
}
// GetAmountsOut queries the router for the output amount given an input amount and swap path.
// Returns the final output amount (last element of amounts). It validates inputs and avoids panics
// on unexpected empty results.
func
GetAmountsOut
(
client
*
ethclient
.
Client
,
user
common
.
Address
,
router
common
.
Address
,
amountIn
*
big
.
Int
,
path
[]
string
,
)
(
*
big
.
Int
,
error
)
{
if
parseRouterErr
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"router ABI init: %w"
,
parseRouterErr
)
}
if
client
==
nil
{
return
nil
,
errors
.
New
(
"nil eth client"
)
}
if
amountIn
==
nil
{
return
nil
,
errors
.
New
(
"nil amountIn"
)
}
if
len
(
path
)
<
2
{
return
nil
,
fmt
.
Errorf
(
"path length must be >= 2, got %d"
,
len
(
path
))
}
addrPath
:=
make
([]
common
.
Address
,
0
,
len
(
path
))
for
_
,
addrStr
:=
range
path
{
if
!
common
.
IsHexAddress
(
addrStr
)
||
common
.
HexToAddress
(
addrStr
)
==
(
common
.
Address
{})
{
return
nil
,
fmt
.
Errorf
(
"invalid address in path: %s"
,
addrStr
)
}
addrPath
=
append
(
addrPath
,
common
.
HexToAddress
(
addrStr
))
}
contract
:=
bind
.
NewBoundContract
(
router
,
parsedRouterABI
,
client
,
client
,
client
)
callOpts
:=
&
bind
.
CallOpts
{
Context
:
context
.
Background
(),
From
:
user
,
// optional; included for completeness (some routers ignore).
}
var
amounts
=
make
([]
interface
{},
len
(
path
))
if
err
:=
contract
.
Call
(
callOpts
,
&
amounts
,
"getAmountsOut"
,
amountIn
,
addrPath
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"call getAmountsOut (amountIn=%s pathLen=%d): %w"
,
amountIn
.
String
(),
len
(
path
),
err
)
}
amountOut
:=
*
abi
.
ConvertType
(
amounts
[
len
(
path
)
-
1
],
new
(
*
big
.
Int
))
.
(
**
big
.
Int
)
return
amountOut
,
nil
}
dao/dao.go
View file @
a91214c9
...
@@ -124,3 +124,11 @@ func (d *Dao) GetOutConfig(chainId int64, token common.Address, toChainId int64)
...
@@ -124,3 +124,11 @@ func (d *Dao) GetOutConfig(chainId int64, token common.Address, toChainId int64)
}
}
return
syncer
.
GetOutConfig
(
token
,
toChainId
)
return
syncer
.
GetOutConfig
(
token
,
toChainId
)
}
}
func
(
d
*
Dao
)
GetChainConfig
(
chainId
int64
)
(
ChainInfo
,
error
)
{
chainInfo
,
ok
:=
d
.
chainGroup
[
chainId
]
if
!
ok
{
return
ChainInfo
{},
fmt
.
Errorf
(
"chain %d config not found"
,
chainId
)
}
return
chainInfo
,
nil
}
dao/db.go
View file @
a91214c9
This diff is collapsed.
Click to expand it.
model/api/model.go
View file @
a91214c9
package
api
package
api
type
ToToken
struct
{
type
To
Bridge
Token
struct
{
TokenContract
string
`json:"token_contract" bson:"token_contract"`
TokenContract
string
`json:"token_contract" bson:"token_contract"`
ToChainId
int64
`json:"to_chain_id" bson:"to_chain_id"`
ToChainId
int64
`json:"to_chain_id" bson:"to_chain_id"`
ToToken
string
`json:"to_token" bson:"to_token"`
ToToken
string
`json:"to_token" bson:"to_token"`
...
@@ -8,29 +8,53 @@ type ToToken struct {
...
@@ -8,29 +8,53 @@ type ToToken struct {
Fee
string
`json:"fee" bson:"fee"`
Fee
string
`json:"fee" bson:"fee"`
MaxLimit
string
`json:"max_limit" bson:"max_limit"`
MaxLimit
string
`json:"max_limit" bson:"max_limit"`
}
}
type
ChainConfig
struct
{
Chain
string
`json:"chain" bson:"chain"`
type
SwapPath
struct
{
ChainId
int64
`json:"chain_id" bson:"chain_id"`
SwapFromToken
string
`json:"swap_from_token" bson:"swap_from_token"`
BridgeContract
string
`json:"contract" bson:"contract"`
BridgeFromToken
string
`json:"bridge_from_token" bson:"bridge_from_token"`
SupportTokens
map
[
string
]
ToToken
`json:"support_tokens" bson:"support_tokens"`
BridgeToToken
string
`json:"bridge_to_token" bson:"bridge_to_token"`
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
SwapToToken
string
`json:"swap_to_token" bson:"swap_to_token"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
}
type
ToSwapToken
struct
{
ToChainId
int64
`json:"to_chain_id" bson:"to_chain_id"`
ToToken
string
`json:"to_token" bson:"to_token"`
ToTokenSymbol
string
`json:"to_token_symbol" bson:"to_token_symbol"`
Path
SwapPath
`json:"path" bson:"path"`
}
}
type
TokenInfo
struct
{
type
SupportBridgeTokenInfo
struct
{
Name
string
`json:"name" bson:"name"`
TokenContract
string
`json:"token_contract" bson:"token_contract"`
Contract
string
`json:"contract" bson:"contract"`
TokenSymbol
string
`json:"token_symbol" bson:"token_symbol"`
BridgeTokens
[]
ToBridgeToken
`json:"bridge_tokens" bson:"bridge_tokens"`
}
}
type
SwapPair
struct
{
type
SupportSwapTokenInfo
struct
{
From
TokenInfo
`json:"from" bson:"from"`
TokenContract
string
`json:"token_contract" bson:"token_contract"`
To
TokenInfo
`json:"to" bson:"to"`
TokenSymbol
string
`json:"token_symbol" bson:"token_symbol"`
SwapContract
string
`json:"swap_contract" bson:"swap_contract"`
SwapTokens
map
[
int64
]
map
[
string
]
ToSwapToken
`json:"swap_tokens" bson:"swap_tokens"`
SwapPath
[]
string
`json:"swap_path" bson:"swap_path"`
}
type
ChainConfig
struct
{
Chain
string
`json:"chain" bson:"chain"`
ChainId
int64
`json:"chain_id" bson:"chain_id"`
BridgeContract
string
`json:"contract" bson:"contract"`
SupportTokens
map
[
string
]
SupportBridgeTokenInfo
`json:"support_tokens" bson:"support_tokens"`
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
}
type
ChainSwapConfig
struct
{
Chain
string
`json:"chain" bson:"chain"`
ChainId
int64
`json:"chain_id" bson:"chain_id"`
BridgeContract
string
`json:"contract" bson:"contract"`
SupportTokens
map
[
string
]
SupportSwapTokenInfo
`json:"support_tokens" bson:"support_tokens"`
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
}
}
type
SwapConfigs
struct
{
type
SwapConfigs
struct
{
SwapPairs
map
[
string
]
SwapPair
`json:"swap_pairs" bson:"swap_pair
s"`
Chains
map
[
string
]
ChainSwapConfig
`json:"chains" bson:"chain
s"`
}
}
type
BridgeConfig
struct
{
type
BridgeConfig
struct
{
...
@@ -58,8 +82,54 @@ type History struct {
...
@@ -58,8 +82,54 @@ type History struct {
Finish
[]
*
HistoryInfo
`json:"finish" bson:"finish"`
Finish
[]
*
HistoryInfo
`json:"finish" bson:"finish"`
}
}
type
RouterQuery
struct
{
ChainId
int64
`json:"chain_id"`
User
string
`json:"user"`
}
type
QuoteBridgeParam
struct
{
FromChainId
int64
`json:"from_chain_id"`
ToChainId
int64
`json:"to_chain_id"`
FromToken
string
`json:"from_token"`
ToToken
string
`json:"to_token"`
InputAmount
string
`json:"amount"`
User
string
`json:"user"`
Receiver
string
`json:"receiver"`
}
type
QuoteSwapParam
struct
{
FromChainId
int64
`json:"from_chain_id"`
ToChainId
int64
`json:"to_chain_id"`
Path
SwapPath
`json:"path"`
InputAmount
string
`json:"amount"`
User
string
`json:"user"`
Receiver
string
`json:"receiver"`
}
type
TokenBalance
struct
{
Name
string
`json:"name"`
Decimals
int
`json:"decimals"`
Balance
string
`json:"balance"`
Contract
string
`json:"contract"`
}
type
TokenBalances
struct
{
Balances
[]
TokenBalance
`json:"balances"`
}
type
QuoteResult
struct
{
ToContract
string
`json:"to_contract"`
OutAmount
string
`json:"out_amount"`
Payload
string
`json:"payload"`
}
type
Querier
interface
{
type
Querier
interface
{
GetBridgeConfig
()
(
config
BridgeConfig
,
err
error
)
GetBridgeConfig
()
(
config
BridgeConfig
,
err
error
)
GetSwapConfig
(
chainId
int64
)
(
config
SwapConfigs
,
err
error
)
GetAllChainSwapConfig
()
(
map
[
int64
]
*
ChainSwapConfig
,
error
)
GetSwapConfig
(
int64
)
(
*
ChainSwapConfig
,
error
)
GetHistoryInfo
(
user
string
)
(
history
History
,
err
error
)
GetHistoryInfo
(
user
string
)
(
history
History
,
err
error
)
GetBridgeTokenBalance
(
chainId
int64
,
user
string
)
(
balances
TokenBalances
,
err
error
)
QuoteBridge
(
param
QuoteBridgeParam
)
(
quote
QuoteResult
,
err
error
)
GetSwapTokenBalance
(
chainId
int64
,
user
string
)
(
balances
TokenBalances
,
err
error
)
QuoteSwap
(
param
QuoteSwapParam
)
(
quote
QuoteResult
,
err
error
)
}
}
server/controller.go
View file @
a91214c9
...
@@ -2,6 +2,7 @@ package server
...
@@ -2,6 +2,7 @@ package server
import
(
import
(
"code.wuban.net.cn/movabridge/bridge-backend/constant"
"code.wuban.net.cn/movabridge/bridge-backend/constant"
apiModel
"code.wuban.net.cn/movabridge/bridge-backend/model/api"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
log
"github.com/sirupsen/logrus"
log
"github.com/sirupsen/logrus"
"strconv"
"strconv"
...
@@ -47,21 +48,113 @@ func getHistory(c *gin.Context) {
...
@@ -47,21 +48,113 @@ func getHistory(c *gin.Context) {
c
.
JSON
(
200
,
withSuccess
(
history
))
c
.
JSON
(
200
,
withSuccess
(
history
))
}
}
func
getSwapConfig
(
c
*
gin
.
Context
)
{
func
bridgeRouters
(
c
*
gin
.
Context
)
{
chainIdStr
:=
c
.
DefaultQuery
(
"chain"
,
""
)
if
_querier
==
nil
{
chainId
,
err
:=
strconv
.
ParseInt
(
chainIdStr
,
10
,
64
)
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
var
queryParam
apiModel
.
RouterQuery
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
config
,
err
:=
_querier
.
GetBridgeConfig
()
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Errorf
(
"convert chainId(%s) to int error: %v"
,
chainIdStr
,
err
)
log
.
Errorf
(
"get bridge config error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
config
))
}
func
bridgeBalance
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
var
queryParam
apiModel
.
RouterQuery
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
}
if
!
common
.
IsHexAddress
(
queryParam
.
User
)
{
log
.
Errorf
(
"invalid user address: %v"
,
queryParam
.
User
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
}
// get all tokens
balances
,
err
:=
_querier
.
GetBridgeTokenBalance
(
queryParam
.
ChainId
,
queryParam
.
User
)
if
err
!=
nil
{
log
.
Errorf
(
"get bridge balance error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
balances
))
}
func
bridgeQuote
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
return
}
}
var
queryParam
apiModel
.
QuoteBridgeParam
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
if
!
common
.
IsHexAddress
(
queryParam
.
User
)
{
log
.
Errorf
(
"invalid user address: %v"
,
queryParam
.
User
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
if
!
common
.
IsHexAddress
(
queryParam
.
Receiver
)
{
log
.
Errorf
(
"invalid receiver address: %v"
,
queryParam
.
Receiver
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
quote
,
err
:=
_querier
.
QuoteBridge
(
queryParam
)
if
err
!=
nil
{
log
.
Errorf
(
"get bridge quote error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
quote
))
}
func
getSwapRouters
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
var
queryParam
apiModel
.
RouterQuery
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
configs
,
err
:=
_querier
.
GetSwapConfig
(
queryParam
.
ChainId
)
if
err
!=
nil
{
log
.
Errorf
(
"get swap config error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
configs
))
}
configs
,
err
:=
_querier
.
GetSwapConfig
(
chainId
)
func
getAllSwapRouters
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
configs
,
err
:=
_querier
.
GetAllChainSwapConfig
()
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Errorf
(
"get swap config error: %v"
,
err
)
log
.
Errorf
(
"get swap config error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
...
@@ -69,3 +162,86 @@ func getSwapConfig(c *gin.Context) {
...
@@ -69,3 +162,86 @@ func getSwapConfig(c *gin.Context) {
}
}
c
.
JSON
(
200
,
withSuccess
(
configs
))
c
.
JSON
(
200
,
withSuccess
(
configs
))
}
}
func
swapBalance
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
var
queryParam
apiModel
.
RouterQuery
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
if
!
common
.
IsHexAddress
(
queryParam
.
User
)
{
log
.
Errorf
(
"invalid user address: %v"
,
queryParam
.
User
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
}
// get all tokens
balances
,
err
:=
_querier
.
GetSwapTokenBalance
(
queryParam
.
ChainId
,
queryParam
.
User
)
if
err
!=
nil
{
log
.
Errorf
(
"get swap balance error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
balances
))
}
func
swapQuote
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
var
queryParam
apiModel
.
QuoteSwapParam
if
err
:=
c
.
ShouldBindQuery
(
&
queryParam
);
err
!=
nil
{
log
.
Errorf
(
"bind query param error: %v"
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
if
!
common
.
IsHexAddress
(
queryParam
.
User
)
{
log
.
Errorf
(
"invalid user address: %v"
,
queryParam
.
User
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
if
!
common
.
IsHexAddress
(
queryParam
.
Receiver
)
{
log
.
Errorf
(
"invalid receiver address: %v"
,
queryParam
.
Receiver
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
quote
,
err
:=
_querier
.
QuoteSwap
(
queryParam
)
if
err
!=
nil
{
log
.
Errorf
(
"get swap quote error: %v"
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
quote
))
}
func
getSwapRoutersByChainId
(
c
*
gin
.
Context
)
{
if
_querier
==
nil
{
log
.
Error
(
"querier is nil"
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
chainIdStr
:=
c
.
Param
(
"chainid"
)
if
chainIdStr
==
""
{
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
chainId
,
err
:=
strconv
.
ParseInt
(
chainIdStr
,
10
,
64
)
if
err
!=
nil
{
log
.
Errorf
(
"convert chainid(%s) error: %v"
,
chainIdStr
,
err
)
c
.
JSON
(
200
,
withError
(
constant
.
InvalidParam
))
return
}
config
,
err
:=
_querier
.
GetSwapConfig
(
chainId
)
if
err
!=
nil
{
log
.
Errorf
(
"get swap config for chain %d error: %v"
,
chainId
,
err
)
c
.
JSON
(
500
,
withError
(
constant
.
InternalError
))
return
}
c
.
JSON
(
200
,
withSuccess
(
config
))
}
server/router.go
View file @
a91214c9
...
@@ -11,10 +11,24 @@ func initRouter(conf *config.Config, e *gin.Engine) {
...
@@ -11,10 +11,24 @@ func initRouter(conf *config.Config, e *gin.Engine) {
e
.
Use
(
middleware
.
CheckHeaderMiddleware
(
conf
.
Server
.
InvalidHeaders
))
e
.
Use
(
middleware
.
CheckHeaderMiddleware
(
conf
.
Server
.
InvalidHeaders
))
v1
:=
e
.
Group
(
"/api/v1"
)
v1
:=
e
.
Group
(
"/api/v1"
)
v1
.
GET
(
"/params"
,
getParam
)
{
{
user
:=
v1
.
Group
(
"/user"
)
user
:=
v1
.
Group
(
"/user"
)
user
.
GET
(
"/history"
,
getHistory
)
user
.
GET
(
"/history"
,
getHistory
)
}
}
v1
.
GET
(
"/params"
,
getParam
)
{
v1
.
GET
(
"/swapconfig"
,
getSwapConfig
)
bridge
:=
v1
.
Group
(
"/bridge"
)
bridge
.
POST
(
"/routers"
,
bridgeRouters
)
bridge
.
POST
(
"/balance"
,
bridgeBalance
)
bridge
.
POST
(
"/quote"
,
bridgeQuote
)
}
{
swap
:=
v1
.
Group
(
"/swap"
)
swap
.
GET
(
"/routers"
,
getSwapRouters
)
swap
.
GET
(
"/routers/:chain"
,
getSwapRoutersByChainId
)
swap
.
POST
(
"/balance"
,
swapBalance
)
swap
.
POST
(
"/quote"
,
swapQuote
)
}
}
}
tokenrepo/tokenrepo.go
View file @
a91214c9
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
"math/big"
"strings"
"strings"
"sync"
"sync"
)
)
...
@@ -88,3 +89,51 @@ func (tr *TokenRepo) RetriveTokenInfo(chainId int64, address string) (TokenInfo,
...
@@ -88,3 +89,51 @@ func (tr *TokenRepo) RetriveTokenInfo(chainId int64, address string) (TokenInfo,
tr
.
SetTokenInfo
(
address
,
info
)
tr
.
SetTokenInfo
(
address
,
info
)
return
info
,
nil
return
info
,
nil
}
}
func
(
tr
*
TokenRepo
)
RetriveTokenInfoAndBalance
(
client
*
ethclient
.
Client
,
address
string
,
user
string
)
(
TokenInfo
,
*
big
.
Int
,
error
)
{
info
:=
TokenInfo
{}
balance
:=
big
.
NewInt
(
0
)
contract
,
err
:=
token
.
NewTokenCaller
(
common
.
HexToAddress
(
address
),
client
)
if
err
!=
nil
{
return
info
,
balance
,
fmt
.
Errorf
(
"fail to connect contract err: %v"
,
err
)
}
callOpt
:=
&
bind
.
CallOpts
{
BlockNumber
:
nil
,
From
:
common
.
HexToAddress
(
user
),
Context
:
context
.
Background
(),
}
userBalance
,
err
:=
contract
.
BalanceOf
(
callOpt
,
common
.
HexToAddress
(
user
))
if
err
!=
nil
{
return
info
,
balance
,
err
}
else
{
balance
=
userBalance
}
if
value
,
ok
:=
tr
.
GetTokenInfo
(
address
);
ok
{
info
=
value
}
else
{
name
,
err
:=
contract
.
Name
(
callOpt
)
if
err
!=
nil
{
return
info
,
balance
,
err
}
symbol
,
err
:=
contract
.
Symbol
(
callOpt
)
if
err
!=
nil
{
return
info
,
balance
,
err
}
decimals
,
err
:=
contract
.
Decimals
(
callOpt
)
if
err
!=
nil
{
return
info
,
balance
,
err
}
info
:=
TokenInfo
{
Name
:
name
,
Symbol
:
symbol
,
Decimals
:
decimals
.
Int64
(),
Address
:
address
,
}
tr
.
SetTokenInfo
(
address
,
info
)
}
return
info
,
balance
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment