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
Show 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
...
@@ -54,7 +54,7 @@ type BridgesubmitParams struct {
...
@@ -54,7 +54,7 @@ type BridgesubmitParams struct {
// BridgeContractMetaData contains all meta data concerning the BridgeContract contract.
// BridgeContractMetaData contains all meta data concerning the BridgeContract contract.
var
BridgeContractMetaData
=
&
bind
.
MetaData
{
var
BridgeContractMetaData
=
&
bind
.
MetaData
{
ABI
:
"[{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
previousAdmin
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newAdmin
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
AdminChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
beacon
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
BeaconUpgraded
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
oldReceiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newReceiver
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
FeeReceiverChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
previousOwner
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
OwnershipTransferred
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
prior
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
present
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
RequirementChange
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
fromToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
toToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
swap
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address[]
\"
,
\"
name
\"
:
\"
path
\"
,
\"
type
\"
:
\"
address[]
\"
}],
\"
name
\"
:
\"
SwapConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
TokenOutConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TransferIn
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferInConfirmation
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TransferInExecution
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferInRejection
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferOut
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
oldTreasury
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newTreasury
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TreasuryChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
TreasuryConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
contractBalance
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
treasuryBalance
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TreasuryTransfer
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
implementation
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
Upgraded
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
ValidatorAddition
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
ValidatorRemoval
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
_inID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
_outID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
addValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
autoTransferToTreasury
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
calculateTreasuryTransfer
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
canTransfer
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
transferAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
willReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
currentBalance
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
components
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
limit
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
isBurn
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
internalType
\"
:
\"
structBridge.OutConfig
\"
,
\"
name
\"
:
\"
config
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
name
\"
:
\"
changeOutConfig
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
required
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
changeValidRequired
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
confirmInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
to
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
emergencyWithdraw
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
feeReceiver
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
getInId
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
getSupportedTokensOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address[]
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address[]
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
inTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
inTransfers
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
executed
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
confirmCounter
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
rejectCounter
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
initialOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
initialize
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
isChecked
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isConfirmed
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isRejected
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isTokenSupportedOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
isTokenTransferEnabled
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isValidator
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
outConfiguration
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
limit
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
isBurn
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
outTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
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
\"
}],
\"
name
\"
:
\"
outTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
outTransfers
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
receiveAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"
signature
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
owner
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
proxiableUUID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
rejectInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
removeValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
renounceOwnership
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newValidator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
replaceValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
retryTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newReceiver
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
setFeeReceiver
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newTreasury
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
setTreasury
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
setTreasuryConfig
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sendToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
sendAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"
signature
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structBridge.submitParams
\"
,
\"
name
\"
:
\"
params
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
name
\"
:
\"
submitInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
supportedTokensOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
transferOwnership
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
treasury
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
treasuryConfigs
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
treasuryTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newImplementation
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
upgradeTo
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newImplementation
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
data
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
name
\"
:
\"
upgradeToAndCall
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
validRequired
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
}]"
,
ABI
:
"[{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
previousAdmin
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newAdmin
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
AdminChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
beacon
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
BeaconUpgraded
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
oldReceiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newReceiver
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
FeeReceiverChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
previousOwner
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
OwnershipTransferred
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
prior
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
present
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
RequirementChange
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
fromToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
toToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
swap
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address[]
\"
,
\"
name
\"
:
\"
path
\"
,
\"
type
\"
:
\"
address[]
\"
}],
\"
name
\"
:
\"
SwapConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
TokenOutConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TransferIn
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferInConfirmation
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TransferInExecution
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferInRejection
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TransferOut
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
oldTreasury
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newTreasury
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
TreasuryChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
TreasuryConfigChanged
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
contractBalance
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
treasuryBalance
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
TreasuryTransfer
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:true,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
implementation
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
Upgraded
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
ValidatorAddition
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
anonymous
\"
:false,
\"
inputs
\"
:[{
\"
indexed
\"
:false,
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
ValidatorRemoval
\"
,
\"
type
\"
:
\"
event
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
_inID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
_outID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
addValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
autoTransferToTreasury
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
calculateTreasuryTransfer
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
canTransfer
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
transferAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
willReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
currentBalance
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
components
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
limit
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
isBurn
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
internalType
\"
:
\"
structBridge.OutConfig
\"
,
\"
name
\"
:
\"
config
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
name
\"
:
\"
changeOutConfig
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
required
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
changeValidRequired
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
confirmInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
to
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
emergencyWithdraw
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
feeReceiver
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
getInId
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
getSupportedTokensOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address[]
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address[]
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
inTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
inTransfers
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
executed
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
confirmCounter
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
rejectCounter
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
initialOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
initialize
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
isChecked
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isConfirmed
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isRejected
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isTokenSupportedOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
isTokenTransferEnabled
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
isValidator
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
outConfiguration
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
limit
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
isBurn
\"
,
\"
type
\"
:
\"
bool
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
outTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
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
\"
}],
\"
name
\"
:
\"
outTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
outTransfers
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fee
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiveToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
receiveAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"
signature
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
owner
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
proxiableUUID
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
rejectInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
removeValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
renounceOwnership
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
validator
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newValidator
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
replaceValidator
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
inId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
retryTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newReceiver
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
setFeeReceiver
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newTreasury
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
setTreasury
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
name
\"
:
\"
setTreasuryConfig
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
components
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
toChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
receiver
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
token
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
amount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
outId
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
fromChainID
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sender
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
sendToken
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
sendAmount
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bytes32
\"
,
\"
name
\"
:
\"
signature
\"
,
\"
type
\"
:
\"
bytes32
\"
}],
\"
internalType
\"
:
\"
structBridge.submitParams
\"
,
\"
name
\"
:
\"
params
\"
,
\"
type
\"
:
\"
tuple
\"
}],
\"
name
\"
:
\"
submitInTransfer
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
name
\"
:
\"
supportedTokensOut
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newOwner
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
transferOwnership
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
treasury
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
treasuryConfigs
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
minReserve
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"
reserveRatio
\"
,
\"
type
\"
:
\"
uint256
\"
},{
\"
internalType
\"
:
\"
bool
\"
,
\"
name
\"
:
\"
enabled
\"
,
\"
type
\"
:
\"
bool
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
treasuryTotal
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newImplementation
\"
,
\"
type
\"
:
\"
address
\"
}],
\"
name
\"
:
\"
upgradeTo
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
nonpayable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[{
\"
internalType
\"
:
\"
address
\"
,
\"
name
\"
:
\"
newImplementation
\"
,
\"
type
\"
:
\"
address
\"
},{
\"
internalType
\"
:
\"
bytes
\"
,
\"
name
\"
:
\"
data
\"
,
\"
type
\"
:
\"
bytes
\"
}],
\"
name
\"
:
\"
upgradeToAndCall
\"
,
\"
outputs
\"
:[],
\"
stateMutability
\"
:
\"
payable
\"
,
\"
type
\"
:
\"
function
\"
},{
\"
inputs
\"
:[],
\"
name
\"
:
\"
validRequired
\"
,
\"
outputs
\"
:[{
\"
internalType
\"
:
\"
uint256
\"
,
\"
name
\"
:
\"\"
,
\"
type
\"
:
\"
uint256
\"
}],
\"
stateMutability
\"
:
\"
view
\"
,
\"
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
\"
}
]"
,
}
}
// BridgeContractABI is the input ABI used to generate the binding from.
// BridgeContractABI is the input ABI used to generate the binding from.
...
@@ -1300,6 +1300,27 @@ func (_BridgeContract *BridgeContractTransactorSession) OutTransfer(token common
...
@@ -1300,6 +1300,27 @@ func (_BridgeContract *BridgeContractTransactorSession) OutTransfer(token common
return
_BridgeContract
.
Contract
.
OutTransfer
(
&
_BridgeContract
.
TransactOpts
,
token
,
amount
,
toChainID
,
receiver
)
return
_BridgeContract
.
Contract
.
OutTransfer
(
&
_BridgeContract
.
TransactOpts
,
token
,
amount
,
toChainID
,
receiver
)
}
}
// OutTransferSwap is a paid mutator transaction binding the contract method 0x433ba133.
//
// Solidity: function outTransferSwap(address token, uint256 amount, uint256 toChainID, address receiver, address fromToken, address toToken) returns()
func
(
_BridgeContract
*
BridgeContractTransactor
)
OutTransferSwap
(
opts
*
bind
.
TransactOpts
,
token
common
.
Address
,
amount
*
big
.
Int
,
toChainID
*
big
.
Int
,
receiver
common
.
Address
,
fromToken
common
.
Address
,
toToken
common
.
Address
)
(
*
types
.
Transaction
,
error
)
{
return
_BridgeContract
.
contract
.
Transact
(
opts
,
"outTransferSwap"
,
token
,
amount
,
toChainID
,
receiver
,
fromToken
,
toToken
)
}
// OutTransferSwap is a paid mutator transaction binding the contract method 0x433ba133.
//
// Solidity: function outTransferSwap(address token, uint256 amount, uint256 toChainID, address receiver, address fromToken, address toToken) returns()
func
(
_BridgeContract
*
BridgeContractSession
)
OutTransferSwap
(
token
common
.
Address
,
amount
*
big
.
Int
,
toChainID
*
big
.
Int
,
receiver
common
.
Address
,
fromToken
common
.
Address
,
toToken
common
.
Address
)
(
*
types
.
Transaction
,
error
)
{
return
_BridgeContract
.
Contract
.
OutTransferSwap
(
&
_BridgeContract
.
TransactOpts
,
token
,
amount
,
toChainID
,
receiver
,
fromToken
,
toToken
)
}
// OutTransferSwap is a paid mutator transaction binding the contract method 0x433ba133.
//
// Solidity: function outTransferSwap(address token, uint256 amount, uint256 toChainID, address receiver, address fromToken, address toToken) returns()
func
(
_BridgeContract
*
BridgeContractTransactorSession
)
OutTransferSwap
(
token
common
.
Address
,
amount
*
big
.
Int
,
toChainID
*
big
.
Int
,
receiver
common
.
Address
,
fromToken
common
.
Address
,
toToken
common
.
Address
)
(
*
types
.
Transaction
,
error
)
{
return
_BridgeContract
.
Contract
.
OutTransferSwap
(
&
_BridgeContract
.
TransactOpts
,
token
,
amount
,
toChainID
,
receiver
,
fromToken
,
toToken
)
}
// RejectInTransfer is a paid mutator transaction binding the contract method 0x9004e82d.
// RejectInTransfer is a paid mutator transaction binding the contract method 0x9004e82d.
//
//
// Solidity: function rejectInTransfer(uint256 inId) returns()
// Solidity: function rejectInTransfer(uint256 inId) returns()
...
...
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
...
@@ -2,11 +2,16 @@ package dao
...
@@ -2,11 +2,16 @@ package dao
import
(
import
(
"code.wuban.net.cn/movabridge/bridge-backend/constant"
"code.wuban.net.cn/movabridge/bridge-backend/constant"
"code.wuban.net.cn/movabridge/bridge-backend/contract/bridge"
"code.wuban.net.cn/movabridge/bridge-backend/contract/router"
apiModel
"code.wuban.net.cn/movabridge/bridge-backend/model/api"
apiModel
"code.wuban.net.cn/movabridge/bridge-backend/model/api"
"context"
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
log
"github.com/sirupsen/logrus"
log
"github.com/sirupsen/logrus"
"math/big"
"sort"
"sort"
"strings"
"time"
"time"
dbModel
"code.wuban.net.cn/movabridge/bridge-backend/model/db"
dbModel
"code.wuban.net.cn/movabridge/bridge-backend/model/db"
...
@@ -103,7 +108,7 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
...
@@ -103,7 +108,7 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
RpcUrl
:
chainInfo
.
Rpc
,
RpcUrl
:
chainInfo
.
Rpc
,
ExplorerUrl
:
chainInfo
.
Explorer
,
ExplorerUrl
:
chainInfo
.
Explorer
,
BridgeContract
:
info
.
Contract
,
BridgeContract
:
info
.
Contract
,
SupportTokens
:
make
(
map
[
string
]
apiModel
.
ToToken
),
SupportTokens
:
make
(
map
[
string
]
apiModel
.
SupportBridgeTokenInfo
),
}
}
}
else
{
}
else
{
chainConfig
=
_chainConfig
chainConfig
=
_chainConfig
...
@@ -117,7 +122,7 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
...
@@ -117,7 +122,7 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
})
.
Error
(
"not found token info with tokenrepo, skip symbol info"
)
})
.
Error
(
"not found token info with tokenrepo, skip symbol info"
)
}
}
tokenInfo
:=
apiModel
.
ToToken
{
tokenInfo
:=
apiModel
.
To
Bridge
Token
{
TokenContract
:
info
.
Token
,
TokenContract
:
info
.
Token
,
ToChainId
:
info
.
ToChainId
,
ToChainId
:
info
.
ToChainId
,
ToToken
:
info
.
ToToken
,
ToToken
:
info
.
ToToken
,
...
@@ -128,7 +133,16 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
...
@@ -128,7 +133,16 @@ func (d *Dao) GetBridgeConfig() (config apiModel.BridgeConfig, err error) {
tokenInfo
.
Fee
=
outConfig
.
Fee
.
String
()
tokenInfo
.
Fee
=
outConfig
.
Fee
.
String
()
tokenInfo
.
MaxLimit
=
outConfig
.
Limit
.
String
()
tokenInfo
.
MaxLimit
=
outConfig
.
Limit
.
String
()
}
}
chainConfig
.
SupportTokens
[
info
.
TokenName
]
=
tokenInfo
if
m
,
exist
:=
chainConfig
.
SupportTokens
[
info
.
TokenName
];
exist
{
m
.
BridgeTokens
=
append
(
m
.
BridgeTokens
,
tokenInfo
)
chainConfig
.
SupportTokens
[
info
.
TokenName
]
=
m
}
else
{
chainConfig
.
SupportTokens
[
info
.
TokenName
]
=
apiModel
.
SupportBridgeTokenInfo
{
TokenContract
:
info
.
Token
,
TokenSymbol
:
info
.
TokenName
,
BridgeTokens
:
[]
apiModel
.
ToBridgeToken
{
tokenInfo
},
}
}
config
.
Chains
[
chainInfo
.
Name
]
=
chainConfig
config
.
Chains
[
chainInfo
.
Name
]
=
chainConfig
}
}
...
@@ -200,72 +214,569 @@ func (d *Dao) GetHistoryInfo(user string) (history apiModel.History, err error)
...
@@ -200,72 +214,569 @@ func (d *Dao) GetHistoryInfo(user string) (history apiModel.History, err error)
}
}
func
(
d
*
Dao
)
GetSwapConfig
(
chainId
int64
)
(
config
apiModel
.
SwapConfigs
,
err
error
)
{
type
tokenBalance
struct
{
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
SwapTokenInfo
)
.
TableName
())
Name
string
Decimals
int
Balance
*
big
.
Int
Contract
string
}
func
(
d
*
Dao
)
GetBridgeTokenBalance
(
chainId
int64
,
user
string
)
(
balances
apiModel
.
TokenBalances
,
err
error
)
{
balances
=
apiModel
.
TokenBalances
{
Balances
:
make
([]
apiModel
.
TokenBalance
,
0
),
}
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
BridgeTokenInfo
)
.
TableName
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
// Find all swap token info fillter by chain_id.
cursor
,
err
:=
collection
.
Find
(
ctx
,
bson
.
M
{})
cursor
,
err
:=
collection
.
Find
(
ctx
,
bson
.
M
{})
if
err
!=
nil
{
if
err
!=
nil
{
return
config
,
err
return
balances
,
err
}
}
defer
cursor
.
Close
(
ctx
)
defer
cursor
.
Close
(
ctx
)
var
swaps
[]
dbModel
.
Swap
TokenInfo
var
tokens
[]
dbModel
.
Bridge
TokenInfo
err
=
cursor
.
All
(
ctx
,
&
swap
s
)
err
=
cursor
.
All
(
ctx
,
&
token
s
)
if
err
!=
nil
{
if
err
!=
nil
{
return
config
,
err
return
balances
,
err
}
}
config
.
SwapPairs
=
make
(
map
[
string
]
apiModel
.
SwapPair
)
chainClient
:=
d
.
ChainClient
(
chainId
)
// Convert database model to API model
if
chainClient
==
nil
{
for
_
,
info
:=
range
swaps
{
log
.
Error
(
"not found chain client for chain id:"
,
chainId
)
if
info
.
ChainId
!=
chainId
{
return
balances
,
nil
}
var
innerBalance
=
make
([]
tokenBalance
,
0
)
for
_
,
token
:=
range
tokens
{
if
token
.
ChainId
!=
chainId
{
continue
continue
}
}
swap
:=
apiModel
.
SwapPair
{
tokenInfo
,
balance
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfoAndBalance
(
chainClient
,
token
.
Token
,
user
)
From
:
apiModel
.
TokenInfo
{
if
err
!=
nil
{
Contract
:
info
.
Token
,
log
.
WithFields
(
log
.
Fields
{
Name
:
info
.
TokenName
,
"chain_id"
:
token
.
ChainId
,
},
"token"
:
token
.
Token
,
To
:
apiModel
.
TokenInfo
{
"error"
:
err
,
Contract
:
info
.
ToToken
,
})
.
Error
(
"get token balance failed, skip this token"
)
Name
:
""
,
continue
},
SwapContract
:
info
.
SwapContract
,
SwapPath
:
make
([]
string
,
0
),
}
}
for
_
,
pathToken
:=
range
info
.
SwapPath
{
innerBalance
=
append
(
innerBalance
,
tokenBalance
{
swap
.
SwapPath
=
append
(
swap
.
SwapPath
,
pathToken
)
Name
:
tokenInfo
.
Symbol
,
Decimals
:
int
(
tokenInfo
.
Decimals
),
Balance
:
balance
,
Contract
:
token
.
Token
,
})
}
}
if
swap
.
From
.
Name
==
""
{
// sort balances by Balance desc
tokenInfo
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfo
(
info
.
ChainId
,
info
.
Token
)
sort
.
Slice
(
innerBalance
,
func
(
i
,
j
int
)
bool
{
return
innerBalance
[
i
]
.
Balance
.
Cmp
(
innerBalance
[
j
]
.
Balance
)
>
0
})
for
_
,
b
:=
range
innerBalance
{
balances
.
Balances
=
append
(
balances
.
Balances
,
apiModel
.
TokenBalance
{
Name
:
b
.
Name
,
Decimals
:
b
.
Decimals
,
Balance
:
b
.
Balance
.
String
(),
Contract
:
b
.
Contract
,
})
}
return
balances
,
nil
}
func
(
d
*
Dao
)
buildBridgePayload
(
token
common
.
Address
,
amount
*
big
.
Int
,
toChainID
*
big
.
Int
,
receiver
common
.
Address
)
([]
byte
,
error
)
{
contractAbi
,
_
:=
bridge
.
BridgeContractMetaData
.
GetAbi
()
return
contractAbi
.
Pack
(
"outTransfer"
,
token
,
amount
,
toChainID
,
receiver
)
}
func
(
d
*
Dao
)
QuoteBridge
(
param
apiModel
.
QuoteBridgeParam
)
(
quote
apiModel
.
QuoteResult
,
err
error
)
{
chainInfo
,
err
:=
d
.
GetChainConfig
(
param
.
FromChainId
)
if
err
!=
nil
{
log
.
Error
(
"not found chain config for chain id:"
,
param
.
FromChainId
)
return
quote
,
nil
}
outConfig
,
err
:=
d
.
GetOutConfig
(
param
.
FromChainId
,
common
.
HexToAddress
(
param
.
FromToken
),
param
.
ToChainId
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
info
.
ChainId
,
"chain_id"
:
param
.
FromChainId
,
"token"
:
info
.
Token
,
"token"
:
param
.
FromToken
,
"to_chain"
:
param
.
ToChainId
,
"error"
:
err
,
"error"
:
err
,
})
.
Error
(
"not found token info with tokenrepo, skip symbol info"
)
})
.
Error
(
"get out config failed"
)
}
else
{
return
quote
,
err
swap
.
From
.
Name
=
tokenInfo
.
Symbol
}
_
,
balance
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfoAndBalance
(
chainInfo
.
cli
,
param
.
FromToken
,
param
.
User
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
FromToken
,
"user"
:
param
.
User
,
"error"
:
err
,
})
.
Error
(
"get user balance failed"
)
return
quote
,
err
}
// check balance and param.InputAmount
// check param.InputAmount and outConfig.Limit
// calculate out amount = input amount - fee
inputAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
param
.
InputAmount
,
10
)
if
!
ok
{
log
.
WithFields
(
log
.
Fields
{
"input_amount"
:
param
.
InputAmount
,
})
.
Error
(
"invalid input amount"
)
return
quote
,
nil
}
if
balance
.
Cmp
(
inputAmount
)
<
0
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
FromToken
,
"user"
:
param
.
User
,
"balance"
:
balance
.
String
(),
"inputAmount"
:
inputAmount
.
String
(),
})
.
Error
(
"user balance insufficient"
)
return
quote
,
fmt
.
Errorf
(
"user balance insufficient"
)
}
if
inputAmount
.
Cmp
(
outConfig
.
Limit
)
>
0
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
FromToken
,
"user"
:
param
.
User
,
"inputAmount"
:
inputAmount
.
String
(),
"limit"
:
outConfig
.
Limit
.
String
(),
})
.
Error
(
"input amount exceed limit"
)
return
quote
,
fmt
.
Errorf
(
"input amount exceed limit"
)
}
}
fee
:=
outConfig
.
Fee
if
inputAmount
.
Cmp
(
fee
)
<=
0
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
FromToken
,
"user"
:
param
.
User
,
"inputAmount"
:
inputAmount
.
String
(),
"fee"
:
fee
.
String
(),
})
.
Error
(
"input amount less than fee"
)
return
quote
,
fmt
.
Errorf
(
"input amount less than fee"
)
}
outAmount
:=
new
(
big
.
Int
)
.
Sub
(
inputAmount
,
fee
)
quote
=
apiModel
.
QuoteResult
{
ToContract
:
chainInfo
.
conf
.
BridgeContract
,
OutAmount
:
outAmount
.
String
(),
}
}
if
swap
.
To
.
Name
==
""
{
// build payload
toTokenInfo
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfo
(
info
.
ChainId
,
info
.
ToToken
)
payload
,
err
:=
d
.
buildBridgePayload
(
common
.
HexToAddress
(
param
.
ToToken
),
inputAmount
,
big
.
NewInt
(
param
.
ToChainId
),
common
.
HexToAddress
(
param
.
Receiver
)
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
info
.
ChainId
,
"chain_id"
:
param
.
FromChainId
,
"token"
:
info
.
ToToken
,
"token"
:
param
.
FromToken
,
"user"
:
param
.
User
,
"inputAmount"
:
inputAmount
.
String
(),
"error"
:
err
,
"error"
:
err
,
})
.
Error
(
"not found token info with tokenrepo, skip symbol info"
)
})
.
Error
(
"build bridge payload failed"
)
return
quote
,
err
}
quote
.
Payload
=
common
.
Bytes2Hex
(
payload
)
return
quote
,
nil
}
func
(
d
*
Dao
)
GetAllChainSwapConfig
()
(
map
[
int64
]
*
apiModel
.
ChainSwapConfig
,
error
)
{
var
res
=
make
(
map
[
int64
]
*
apiModel
.
ChainSwapConfig
)
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
BridgeTokenInfo
)
.
TableName
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
cursor
,
err
:=
collection
.
Find
(
ctx
,
bson
.
M
{})
if
err
!=
nil
{
return
res
,
err
}
defer
cursor
.
Close
(
ctx
)
var
tokens
[]
dbModel
.
BridgeTokenInfo
err
=
cursor
.
All
(
ctx
,
&
tokens
)
if
err
!=
nil
{
return
res
,
err
}
for
_
,
token
:=
range
tokens
{
if
_
,
exist
:=
res
[
token
.
ChainId
];
!
exist
{
chainConfig
,
err
:=
d
.
GetSwapConfig
(
token
.
ChainId
)
if
err
!=
nil
{
continue
}
else
{
}
else
{
swap
.
To
.
Name
=
toTokenInfo
.
Symbol
res
[
token
.
ChainId
]
=
chainConfig
}
}
}
return
res
,
nil
}
func
(
d
*
Dao
)
GetSwapConfig
(
chainId
int64
)
(
*
apiModel
.
ChainSwapConfig
,
error
)
{
chainInfo
,
err
:=
d
.
GetChainConfig
(
chainId
)
if
err
!=
nil
{
log
.
Error
(
"not found chain config for chain id:"
,
chainId
)
return
nil
,
fmt
.
Errorf
(
"not found chain config for chain id: %s"
,
chainId
)
}
chainRepo
,
exist
:=
d
.
chainList
.
Get
(
chainId
)
if
!
exist
{
log
.
Error
(
"not found chain info in chainlist for chain id:"
,
chainId
)
return
nil
,
fmt
.
Errorf
(
"not found chain info in chainlist for chain id: %s"
,
chainId
)
}
config
:=
&
apiModel
.
ChainSwapConfig
{
Chain
:
chainRepo
.
Name
,
ChainId
:
chainId
,
RpcUrl
:
chainRepo
.
Rpc
,
ExplorerUrl
:
chainRepo
.
Explorer
,
BridgeContract
:
chainInfo
.
conf
.
BridgeContract
,
SupportTokens
:
make
(
map
[
string
]
apiModel
.
SupportSwapTokenInfo
),
}
bridgeTokens
,
err
:=
d
.
getSupportedBridgeChains
(
chainId
,
""
)
if
err
!=
nil
{
return
config
,
err
}
for
_
,
bridgeToken
:=
range
bridgeTokens
{
swapChains
:=
[]
dbModel
.
BridgeTokenInfo
{
bridgeToken
}
toChains
:=
d
.
getTargetChainSwapTokens
(
swapChains
,
apiModel
.
SwapPath
{
SwapFromToken
:
bridgeToken
.
Token
,
BridgeFromToken
:
bridgeToken
.
Token
,
})
if
len
(
toChains
)
>
0
{
config
.
SupportTokens
[
bridgeToken
.
Token
]
=
apiModel
.
SupportSwapTokenInfo
{
TokenContract
:
bridgeToken
.
Token
,
TokenSymbol
:
bridgeToken
.
TokenName
,
SwapTokens
:
toChains
,
}
}
}
}
swapTokens
,
err
:=
d
.
getSupportedSwapTokens
(
chainId
)
if
err
!=
nil
{
return
config
,
err
}
for
_
,
swap
:=
range
swapTokens
{
// if swap.ToToken is support, then it can swap to all bridged tokens and target chain token swaps.
swapChains
,
err
:=
d
.
getSupportedBridgeChains
(
chainId
,
swap
.
ToToken
)
if
err
!=
nil
{
return
config
,
err
}
}
config
.
SwapPairs
[
swap
.
From
.
Name
]
=
swap
toChains
:=
d
.
getTargetChainSwapTokens
(
swapChains
,
apiModel
.
SwapPath
{
SwapFromToken
:
swap
.
Token
,
BridgeFromToken
:
swap
.
ToToken
,
})
if
len
(
toChains
)
>
0
{
config
.
SupportTokens
[
swap
.
Token
]
=
apiModel
.
SupportSwapTokenInfo
{
TokenContract
:
swap
.
Token
,
TokenSymbol
:
swap
.
TokenName
,
SwapTokens
:
toChains
,
}
}
}
}
return
config
,
nil
return
config
,
nil
}
}
func
(
d
*
Dao
)
GetSwapTokenBalance
(
chainId
int64
,
user
string
)
(
balances
apiModel
.
TokenBalances
,
err
error
)
{
balances
=
apiModel
.
TokenBalances
{
Balances
:
make
([]
apiModel
.
TokenBalance
,
0
),
}
chainSwapConfig
,
err
:=
d
.
GetSwapConfig
(
chainId
)
if
err
!=
nil
{
return
balances
,
err
}
chainInfo
,
err
:=
d
.
GetChainConfig
(
chainId
)
if
err
!=
nil
{
log
.
Error
(
"not found chain config for chain id:"
,
chainId
)
return
balances
,
nil
}
innerBalance
:=
make
([]
tokenBalance
,
0
)
for
_
,
token
:=
range
chainSwapConfig
.
SupportTokens
{
tokenInfo
,
balance
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfoAndBalance
(
chainInfo
.
cli
,
token
.
TokenContract
,
user
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
chainId
,
"token"
:
token
.
TokenContract
,
"error"
:
err
,
})
.
Error
(
"get token balance failed, skip this token"
)
continue
}
innerBalance
=
append
(
innerBalance
,
tokenBalance
{
Name
:
tokenInfo
.
Symbol
,
Decimals
:
int
(
tokenInfo
.
Decimals
),
Balance
:
balance
,
Contract
:
token
.
TokenContract
,
})
}
// sort balances by Balance desc
sort
.
Slice
(
innerBalance
,
func
(
i
,
j
int
)
bool
{
return
innerBalance
[
i
]
.
Balance
.
Cmp
(
innerBalance
[
j
]
.
Balance
)
>
0
})
for
_
,
b
:=
range
innerBalance
{
balances
.
Balances
=
append
(
balances
.
Balances
,
apiModel
.
TokenBalance
{
Name
:
b
.
Name
,
Decimals
:
b
.
Decimals
,
Balance
:
b
.
Balance
.
String
(),
Contract
:
b
.
Contract
,
})
}
return
balances
,
nil
}
func
(
d
*
Dao
)
QuoteSwap
(
param
apiModel
.
QuoteSwapParam
)
(
quote
apiModel
.
QuoteResult
,
err
error
)
{
chainInfo
,
err
:=
d
.
GetChainConfig
(
param
.
FromChainId
)
if
err
!=
nil
{
log
.
Error
(
"not found chain config for chain id:"
,
param
.
FromChainId
)
return
quote
,
nil
}
_
,
balance
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfoAndBalance
(
chainInfo
.
cli
,
param
.
Path
.
SwapFromToken
,
param
.
User
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
Path
.
SwapFromToken
,
"user"
:
param
.
User
,
"error"
:
err
,
})
.
Error
(
"get user balance failed"
)
return
quote
,
err
}
// check balance and param.InputAmount
inputAmount
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
param
.
InputAmount
,
10
)
if
!
ok
{
log
.
WithFields
(
log
.
Fields
{
"input_amount"
:
param
.
InputAmount
,
})
.
Error
(
"invalid input amount"
)
return
quote
,
nil
}
if
balance
.
Cmp
(
inputAmount
)
<
0
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
Path
.
SwapFromToken
,
"user"
:
param
.
User
,
"balance"
:
balance
.
String
(),
"inputAmount"
:
inputAmount
.
String
(),
})
.
Error
(
"user balance insufficient"
)
return
quote
,
fmt
.
Errorf
(
"user balance insufficient"
)
}
quote
=
apiModel
.
QuoteResult
{
ToContract
:
chainInfo
.
conf
.
BridgeContract
,
OutAmount
:
inputAmount
.
String
(),
}
// if need swap, then calculate out amount after swap.
if
param
.
Path
.
SwapFromToken
!=
param
.
Path
.
BridgeFromToken
{
// swap from token -> bridge from token
swapConfig
,
err
:=
d
.
findSwapConfig
(
param
.
FromChainId
,
param
.
Path
.
SwapFromToken
,
param
.
Path
.
BridgeFromToken
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"swap_from_token"
:
param
.
Path
.
SwapFromToken
,
"bridge_from_token"
:
param
.
Path
.
BridgeFromToken
,
"error"
:
err
,
})
.
Error
(
"not found swap config for swap from token to bridge from token"
)
return
quote
,
err
}
swapFromAmount
,
err
:=
router
.
GetAmountsOut
(
chainInfo
.
cli
,
common
.
HexToAddress
(
param
.
User
),
common
.
HexToAddress
(
swapConfig
.
SwapContract
),
inputAmount
,
swapConfig
.
SwapPath
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"swap_from_token"
:
param
.
Path
.
SwapFromToken
,
"bridge_from_token"
:
param
.
Path
.
BridgeFromToken
,
"input_amount"
:
inputAmount
.
String
(),
"error"
:
err
,
})
.
Error
(
"get swap amounts out failed"
)
return
quote
,
err
}
inputAmount
=
swapFromAmount
}
// then sub bridge fee.
outConfig
,
err
:=
d
.
GetOutConfig
(
param
.
FromChainId
,
common
.
HexToAddress
(
param
.
Path
.
BridgeFromToken
),
param
.
ToChainId
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"bridge_from_token"
:
param
.
Path
.
BridgeFromToken
,
"to_chain"
:
param
.
ToChainId
,
"error"
:
err
,
})
.
Error
(
"get out config failed"
)
return
quote
,
err
}
if
outConfig
.
ReceiveToken
!=
common
.
HexToAddress
(
param
.
Path
.
BridgeToToken
)
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"bridge_from_token"
:
param
.
Path
.
BridgeFromToken
,
"to_chain"
:
param
.
ToChainId
,
"bridge_to_token"
:
param
.
Path
.
BridgeToToken
,
"receive_token"
:
outConfig
.
ReceiveToken
.
Hex
(),
})
.
Error
(
"bridge to token not match receive token"
)
return
quote
,
fmt
.
Errorf
(
"bridge to token not match receive token"
)
}
fee
:=
outConfig
.
Fee
if
inputAmount
.
Cmp
(
fee
)
<=
0
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"bridge_from_token"
:
param
.
Path
.
BridgeFromToken
,
"to_chain"
:
param
.
ToChainId
,
"inputAmount"
:
inputAmount
.
String
(),
"fee"
:
fee
.
String
(),
})
.
Error
(
"input amount less than fee"
)
return
quote
,
fmt
.
Errorf
(
"input amount less than fee"
)
}
outAmount
:=
new
(
big
.
Int
)
.
Sub
(
inputAmount
,
fee
)
quote
.
OutAmount
=
outAmount
.
String
()
// if target need swap, then calculate out amount after target swap.
if
param
.
Path
.
BridgeToToken
!=
param
.
Path
.
SwapToToken
{
// swap from bridge to token -> swap to token
swapConfig
,
err
:=
d
.
findSwapConfig
(
param
.
ToChainId
,
param
.
Path
.
BridgeToToken
,
param
.
Path
.
SwapToToken
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
ToChainId
,
"bridge_to_token"
:
param
.
Path
.
BridgeToToken
,
"swap_to_token"
:
param
.
Path
.
SwapToToken
,
"error"
:
err
,
})
.
Error
(
"not found swap config for bridge to token to swap to token"
)
return
quote
,
err
}
swapToAmount
,
err
:=
router
.
GetAmountsOut
(
chainInfo
.
cli
,
common
.
HexToAddress
(
param
.
User
),
common
.
HexToAddress
(
swapConfig
.
SwapContract
),
outAmount
,
swapConfig
.
SwapPath
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
ToChainId
,
"bridge_to_token"
:
param
.
Path
.
BridgeToToken
,
"swap_to_token"
:
param
.
Path
.
SwapToToken
,
"input_amount"
:
outAmount
.
String
(),
"error"
:
err
,
})
.
Error
(
"get swap amounts out failed"
)
return
quote
,
err
}
quote
.
OutAmount
=
swapToAmount
.
String
()
}
// build payload
payload
,
err
:=
d
.
buildSwapPayload
(
common
.
HexToAddress
(
param
.
Path
.
BridgeFromToken
),
inputAmount
,
big
.
NewInt
(
param
.
ToChainId
),
common
.
HexToAddress
(
param
.
Receiver
),
common
.
HexToAddress
(
param
.
Path
.
SwapFromToken
),
common
.
HexToAddress
(
param
.
Path
.
SwapToToken
))
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
param
.
FromChainId
,
"token"
:
param
.
Path
.
SwapFromToken
,
"user"
:
param
.
User
,
"inputAmount"
:
inputAmount
.
String
(),
"error"
:
err
,
})
.
Error
(
"build swap payload failed"
)
return
quote
,
err
}
quote
.
Payload
=
common
.
Bytes2Hex
(
payload
)
return
quote
,
nil
}
func
(
d
*
Dao
)
getSupportedBridgeChains
(
fromChain
int64
,
token
string
)
(
configs
[]
dbModel
.
BridgeTokenInfo
,
err
error
)
{
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
BridgeTokenInfo
)
.
TableName
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
filter
:=
bson
.
M
{
"chain_id"
:
fromChain
}
if
token
!=
""
{
filter
[
"token"
]
=
strings
.
ToLower
(
token
)
}
cursor
,
err
:=
collection
.
Find
(
ctx
,
filter
)
if
err
!=
nil
{
return
configs
,
err
}
defer
cursor
.
Close
(
ctx
)
err
=
cursor
.
All
(
ctx
,
&
configs
)
return
configs
,
err
}
func
(
d
*
Dao
)
getTargetChainSwapTokens
(
targetChains
[]
dbModel
.
BridgeTokenInfo
,
fromPath
apiModel
.
SwapPath
)
map
[
int64
]
map
[
string
]
apiModel
.
ToSwapToken
{
toChains
:=
make
(
map
[
int64
]
map
[
string
]
apiModel
.
ToSwapToken
)
for
_
,
sc
:=
range
targetChains
{
if
!
sc
.
Enabled
{
continue
}
tokens
,
exist
:=
toChains
[
sc
.
ToChainId
]
if
!
exist
{
tokens
=
make
(
map
[
string
]
apiModel
.
ToSwapToken
)
toChains
[
sc
.
ToChainId
]
=
tokens
}
toTokenInfo
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfo
(
sc
.
ToChainId
,
sc
.
ToToken
)
if
err
!=
nil
{
log
.
WithFields
(
log
.
Fields
{
"chain_id"
:
sc
.
ToChainId
,
"token"
:
sc
.
ToToken
,
})
.
Error
(
"get token info failed"
)
continue
}
tokens
[
sc
.
ToToken
]
=
apiModel
.
ToSwapToken
{
ToChainId
:
sc
.
ToChainId
,
ToToken
:
sc
.
ToToken
,
ToTokenSymbol
:
toTokenInfo
.
Symbol
,
Path
:
apiModel
.
SwapPath
{
SwapFromToken
:
fromPath
.
SwapFromToken
,
BridgeFromToken
:
fromPath
.
BridgeFromToken
,
BridgeToToken
:
sc
.
ToToken
,
SwapToToken
:
sc
.
ToToken
,
},
}
// get all supported swap tokens for toChainId
targetChainSwapTokens
,
err
:=
d
.
getSupportedSwapTokens
(
sc
.
ToChainId
)
if
err
!=
nil
{
continue
}
for
_
,
targetSwap
:=
range
targetChainSwapTokens
{
if
common
.
HexToAddress
(
targetSwap
.
Token
)
==
common
.
HexToAddress
(
sc
.
ToToken
)
{
tokenInfo
,
err
:=
d
.
tokenRepo
.
RetriveTokenInfo
(
targetSwap
.
ChainId
,
targetSwap
.
ToToken
)
if
err
!=
nil
{
continue
}
// add targetSwap.ToToken to toChains
tokens
[
targetSwap
.
ToToken
]
=
apiModel
.
ToSwapToken
{
ToChainId
:
targetSwap
.
ChainId
,
ToToken
:
targetSwap
.
ToToken
,
ToTokenSymbol
:
tokenInfo
.
Symbol
,
Path
:
apiModel
.
SwapPath
{
SwapFromToken
:
fromPath
.
SwapFromToken
,
BridgeFromToken
:
fromPath
.
BridgeFromToken
,
BridgeToToken
:
sc
.
ToToken
,
SwapToToken
:
targetSwap
.
ToToken
,
},
}
}
}
toChains
[
sc
.
ToChainId
]
=
tokens
}
return
toChains
}
func
(
d
*
Dao
)
getSupportedSwapTokens
(
chainId
int64
)
(
tokens
[]
dbModel
.
SwapTokenInfo
,
err
error
)
{
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
SwapTokenInfo
)
.
TableName
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
cursor
,
err
:=
collection
.
Find
(
ctx
,
bson
.
M
{
"chain_id"
:
chainId
})
if
err
!=
nil
{
return
tokens
,
err
}
defer
cursor
.
Close
(
ctx
)
err
=
cursor
.
All
(
ctx
,
&
tokens
)
return
tokens
,
err
}
func
(
d
*
Dao
)
buildSwapPayload
(
token
common
.
Address
,
amount
*
big
.
Int
,
toChainID
*
big
.
Int
,
receiver
common
.
Address
,
fromToken
common
.
Address
,
toToken
common
.
Address
)
([]
byte
,
error
)
{
contractAbi
,
_
:=
bridge
.
BridgeContractMetaData
.
GetAbi
()
return
contractAbi
.
Pack
(
"outTransferSwap"
,
token
,
amount
,
toChainID
,
receiver
,
fromToken
,
toToken
)
}
func
(
d
*
Dao
)
findSwapConfig
(
chainId
int64
,
from
string
,
to
string
)
(
*
dbModel
.
SwapTokenInfo
,
error
)
{
collection
:=
d
.
db
.
Collection
(
new
(
dbModel
.
SwapTokenInfo
)
.
TableName
())
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
var
swapConfig
dbModel
.
SwapTokenInfo
err
:=
collection
.
FindOne
(
ctx
,
bson
.
M
{
"chain_id"
:
chainId
,
"token"
:
strings
.
ToLower
(
from
),
"to_token"
:
strings
.
ToLower
(
to
)})
.
Decode
(
&
swapConfig
)
if
err
==
mongo
.
ErrNoDocuments
{
return
nil
,
ErrRecordNotFound
}
return
&
swapConfig
,
err
}
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
SwapPath
struct
{
SwapFromToken
string
`json:"swap_from_token" bson:"swap_from_token"`
BridgeFromToken
string
`json:"bridge_from_token" bson:"bridge_from_token"`
BridgeToToken
string
`json:"bridge_to_token" bson:"bridge_to_token"`
SwapToToken
string
`json:"swap_to_token" bson:"swap_to_token"`
}
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
SupportBridgeTokenInfo
struct
{
TokenContract
string
`json:"token_contract" bson:"token_contract"`
TokenSymbol
string
`json:"token_symbol" bson:"token_symbol"`
BridgeTokens
[]
ToBridgeToken
`json:"bridge_tokens" bson:"bridge_tokens"`
}
type
SupportSwapTokenInfo
struct
{
TokenContract
string
`json:"token_contract" bson:"token_contract"`
TokenSymbol
string
`json:"token_symbol" bson:"token_symbol"`
SwapTokens
map
[
int64
]
map
[
string
]
ToSwapToken
`json:"swap_tokens" bson:"swap_tokens"`
}
type
ChainConfig
struct
{
type
ChainConfig
struct
{
Chain
string
`json:"chain" bson:"chain"`
Chain
string
`json:"chain" bson:"chain"`
ChainId
int64
`json:"chain_id" bson:"chain_id"`
ChainId
int64
`json:"chain_id" bson:"chain_id"`
BridgeContract
string
`json:"contract" bson:"contract"`
BridgeContract
string
`json:"contract" bson:"contract"`
SupportTokens
map
[
string
]
ToToken
`json:"support_tokens" bson:"support_tokens"`
SupportTokens
map
[
string
]
SupportBridgeTokenInfo
`json:"support_tokens" bson:"support_tokens"`
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
}
}
type
TokenInfo
struct
{
type
ChainSwapConfig
struct
{
Name
string
`json:"name" bson:"name"`
Chain
string
`json:"chain" bson:"chain"`
Contract
string
`json:"contract" bson:"contract"`
ChainId
int64
`json:"chain_id" bson:"chain_id"`
}
BridgeContract
string
`json:"contract" bson:"contract"`
SupportTokens
map
[
string
]
SupportSwapTokenInfo
`json:"support_tokens" bson:"support_tokens"`
type
SwapPair
struct
{
ExplorerUrl
string
`json:"explorer_url" bson:"explorer_url"`
From
TokenInfo
`json:"from" bson:"from"`
RpcUrl
string
`json:"rpc" bson:"rpc"`
To
TokenInfo
`json:"to" bson:"to"`
SwapContract
string
`json:"swap_contract" bson:"swap_contract"`
SwapPath
[]
string
`json:"swap_path" bson:"swap_path"`
}
}
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