Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
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
exchain
nebula
Commits
88a06467
Commit
88a06467
authored
Aug 12, 2023
by
Will Cory
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: Clena up file structure
chore: linter fix: Better error handling
parent
9aa29eff
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
327 additions
and
0 deletions
+327
-0
common.go
indexer/api/handlers/common.go
+51
-0
deposits.go
indexer/api/handlers/deposits.go
+94
-0
healthz.go
indexer/api/handlers/healthz.go
+13
-0
withdrawals.go
indexer/api/handlers/withdrawals.go
+117
-0
context.go
indexer/api/middleware/context.go
+52
-0
No files found.
indexer/api/handlers/common.go
0 → 100644
View file @
88a06467
package
handlers
import
(
"encoding/json"
"net/http"
"github.com/ethereum/go-ethereum/log"
)
// lazily typing numbers fixme
type
Transaction
struct
{
Timestamp
uint64
`json:"timestamp"`
BlockNumber
int64
`json:"number"`
// viem treats me as a BigInt maybe consider just stringing me too. Not 100% necessary though
BlockHash
string
`json:"hash"`
TransactionHash
string
`json:"transactionHash"`
// TODO maybe include me
// ParentBlockHash string `json:"parentHash"`
}
type
Extensions
struct
{
OptimismBridgeAddress
string
`json:"OptimismBridgeAddress"`
}
type
TokenInfo
struct
{
// TODO lazily typing ints go through them all with fine tooth comb once api is up
ChainId
int
`json:"chainId"`
Address
string
`json:"address"`
Name
string
`json:"name"`
Symbol
string
`json:"symbol"`
Decimals
int
`json:"decimals"`
LogoURI
string
`json:"logoURI"`
Extensions
Extensions
`json:"extensions"`
}
func
jsonResponse
(
w
http
.
ResponseWriter
,
logger
log
.
Logger
,
data
interface
{},
statusCode
int
)
{
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/json"
)
jsonData
,
err
:=
json
.
Marshal
(
data
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Internal server error"
,
http
.
StatusInternalServerError
)
logger
.
Error
(
"Failed to marshal JSON: %v"
,
err
)
return
}
w
.
WriteHeader
(
statusCode
)
_
,
err
=
w
.
Write
(
jsonData
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Internal server error"
,
http
.
StatusInternalServerError
)
logger
.
Error
(
"Failed to write JSON data"
,
err
)
return
}
}
indexer/api/handlers/deposits.go
0 → 100644
View file @
88a06467
package
handlers
import
(
"net/http"
"github.com/ethereum-optimism/optimism/indexer/api/middleware"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum/go-ethereum/common"
"github.com/go-chi/chi/v5"
)
type
DepositItem
struct
{
Guid
string
`json:"guid"`
From
string
`json:"from"`
To
string
`json:"to"`
// TODO could consider OriginTx to be more generic to handling L2 to L2 deposits
// this seems more clear today though
Tx
Transaction
`json:"Block"`
Amount
string
`json:"amount"`
L1Token
TokenInfo
`json:"l1Token"`
L2Token
TokenInfo
`json:"l2Token"`
}
type
DepositResponse
struct
{
Cursor
string
`json:"cursor"`
HasNextPage
bool
`json:"hasNextPage"`
Items
[]
DepositItem
`json:"items"`
}
// TODO this is original spec but maybe include the l2 block info too for the relayed tx
func
newDepositResponse
(
deposits
[]
*
database
.
L1BridgeDepositWithTransactionHashes
)
DepositResponse
{
var
items
[]
DepositItem
for
_
,
deposit
:=
range
deposits
{
item
:=
DepositItem
{
Guid
:
deposit
.
L1BridgeDeposit
.
TransactionSourceHash
.
String
(),
Tx
:
Transaction
{
BlockNumber
:
420420
,
// TODO
BlockHash
:
"0x420"
,
// TODO
TransactionHash
:
"0x420"
,
// TODO
Timestamp
:
deposit
.
L1BridgeDeposit
.
Tx
.
Timestamp
,
},
From
:
deposit
.
L1BridgeDeposit
.
Tx
.
FromAddress
.
String
(),
To
:
deposit
.
L1BridgeDeposit
.
Tx
.
ToAddress
.
String
(),
Amount
:
deposit
.
L1BridgeDeposit
.
Tx
.
Amount
.
Int
.
String
(),
L1Token
:
TokenInfo
{
ChainId
:
1
,
Address
:
deposit
.
L1BridgeDeposit
.
TokenPair
.
L1TokenAddress
.
String
(),
Name
:
"TODO"
,
Symbol
:
"TODO"
,
Decimals
:
420
,
LogoURI
:
"TODO"
,
Extensions
:
Extensions
{
OptimismBridgeAddress
:
"0x420"
,
// TODO
},
},
L2Token
:
TokenInfo
{
ChainId
:
10
,
Address
:
deposit
.
L1BridgeDeposit
.
TokenPair
.
L2TokenAddress
.
String
(),
Name
:
"TODO"
,
Symbol
:
"TODO"
,
Decimals
:
420
,
LogoURI
:
"TODO"
,
Extensions
:
Extensions
{
OptimismBridgeAddress
:
"0x420"
,
// TODO
},
},
}
items
=
append
(
items
,
item
)
}
return
DepositResponse
{
Cursor
:
"42042042-4204-4204-4204-420420420420"
,
// TODO
HasNextPage
:
false
,
// TODO
Items
:
items
,
}
}
func
L1DepositsHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
btv
:=
middleware
.
GetBridgeTransfersView
(
r
.
Context
())
logger
:=
middleware
.
GetLogger
(
r
.
Context
())
address
:=
common
.
HexToAddress
(
chi
.
URLParam
(
r
,
"address"
))
deposits
,
err
:=
btv
.
L1BridgeDepositsByAddress
(
address
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Internal server error reading deposits"
,
http
.
StatusInternalServerError
)
logger
.
Error
(
"Unable to read deposits from DB"
)
logger
.
Error
(
err
.
Error
())
}
response
:=
newDepositResponse
(
deposits
)
jsonResponse
(
w
,
logger
,
response
,
http
.
StatusOK
)
}
indexer/api/handlers/healthz.go
0 → 100644
View file @
88a06467
package
handlers
import
(
"net/http"
"github.com/ethereum-optimism/optimism/indexer/api/middleware"
)
func
HealthzHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
logger
:=
middleware
.
GetLogger
(
r
.
Context
())
jsonResponse
(
w
,
logger
,
"ok"
,
http
.
StatusOK
)
}
indexer/api/handlers/withdrawals.go
0 → 100644
View file @
88a06467
package
handlers
import
(
"net/http"
"github.com/ethereum-optimism/optimism/indexer/api/middleware"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum/go-ethereum/common"
"github.com/go-chi/chi/v5"
)
type
Proof
struct
{
TransactionHash
string
`json:"transactionHash"`
BlockTimestamp
uint64
`json:"blockTimestamp"`
BlockNumber
int
`json:"blockNumber"`
}
type
Claim
struct
{
TransactionHash
string
`json:"transactionHash"`
BlockTimestamp
uint64
`json:"blockTimestamp"`
BlockNumber
int
`json:"blockNumber"`
}
type
WithdrawalItem
struct
{
Guid
string
`json:"guid"`
BlockTimestamp
uint64
`json:"blockTimestamp"`
From
string
`json:"from"`
To
string
`json:"to"`
TransactionHash
string
`json:"transactionHash"`
Amount
string
`json:"amount"`
BlockNumber
int
`json:"blockNumber"`
Proof
Proof
`json:"proof"`
Claim
Claim
`json:"claim"`
WithdrawalState
string
`json:"withdrawalState"`
L1Token
TokenInfo
`json:"l1Token"`
L2Token
TokenInfo
`json:"l2Token"`
}
type
WithdrawalResponse
struct
{
Cursor
string
`json:"cursor"`
HasNextPage
bool
`json:"hasNextPage"`
Items
[]
WithdrawalItem
`json:"items"`
}
func
newWithdrawalResponse
(
withdrawals
[]
*
database
.
L2BridgeWithdrawalWithTransactionHashes
)
WithdrawalResponse
{
var
items
[]
WithdrawalItem
for
_
,
withdrawal
:=
range
withdrawals
{
item
:=
WithdrawalItem
{
Guid
:
withdrawal
.
L2BridgeWithdrawal
.
TransactionWithdrawalHash
.
String
(),
BlockTimestamp
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Timestamp
,
From
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
FromAddress
.
String
(),
To
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
ToAddress
.
String
(),
TransactionHash
:
withdrawal
.
L2TransactionHash
.
String
(),
Amount
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Amount
.
Int
.
String
(),
BlockNumber
:
420
,
// TODO
Proof
:
Proof
{
TransactionHash
:
withdrawal
.
ProvenL1TransactionHash
.
String
(),
BlockTimestamp
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Timestamp
,
BlockNumber
:
420
,
// TODO Block struct instead
},
Claim
:
Claim
{
TransactionHash
:
withdrawal
.
FinalizedL1TransactionHash
.
String
(),
BlockTimestamp
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Timestamp
,
// Using L2 timestamp for now, might need adjustment
BlockNumber
:
420
,
// TODO block struct
},
WithdrawalState
:
"COMPLETE"
,
// TODO
L1Token
:
TokenInfo
{
ChainId
:
1
,
Address
:
withdrawal
.
L2BridgeWithdrawal
.
TokenPair
.
L1TokenAddress
.
String
(),
Name
:
"Example"
,
// TODO
Symbol
:
"EXAMPLE"
,
// TODO
Decimals
:
18
,
// TODO
LogoURI
:
"https://ethereum-optimism.github.io/data/OP/logo.svg"
,
// TODO
Extensions
:
Extensions
{
OptimismBridgeAddress
:
"0x636Af16bf2f682dD3109e60102b8E1A089FedAa8"
,
},
},
L2Token
:
TokenInfo
{
ChainId
:
10
,
Address
:
withdrawal
.
L2BridgeWithdrawal
.
TokenPair
.
L2TokenAddress
.
String
(),
Name
:
"Example"
,
// TODO
Symbol
:
"EXAMPLE"
,
// TODO
Decimals
:
18
,
// TODO
LogoURI
:
"https://ethereum-optimism.github.io/data/OP/logo.svg"
,
// TODO
Extensions
:
Extensions
{
OptimismBridgeAddress
:
"0x36Af16bf2f682dD3109e60102b8E1A089FedAa86"
,
},
},
}
items
=
append
(
items
,
item
)
}
return
WithdrawalResponse
{
Cursor
:
"42042042-0420-4204-2042-420420420420"
,
// TODO
HasNextPage
:
true
,
// TODO
Items
:
items
,
}
}
func
L2WithdrawalsHandler
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
btv
:=
middleware
.
GetBridgeTransfersView
(
r
.
Context
())
logger
:=
middleware
.
GetLogger
(
r
.
Context
())
address
:=
common
.
HexToAddress
(
chi
.
URLParam
(
r
,
"address"
))
withdrawals
,
err
:=
btv
.
L2BridgeWithdrawalsByAddress
(
address
)
if
err
!=
nil
{
http
.
Error
(
w
,
"Internal server error fetching withdrawals"
,
http
.
StatusInternalServerError
)
logger
.
Error
(
"Unable to read deposits from DB"
)
logger
.
Error
(
err
.
Error
())
return
}
response
:=
newWithdrawalResponse
(
withdrawals
)
jsonResponse
(
w
,
logger
,
response
,
http
.
StatusOK
)
}
indexer/api/middleware/context.go
0 → 100644
View file @
88a06467
package
middleware
import
(
"context"
"net/http"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum/go-ethereum/log"
)
type
contextKey
string
const
(
loggerKey
contextKey
=
"logger"
bridgeTransfersViewKey
contextKey
=
"bridgeTransfersView"
)
// Setters
func
setLogger
(
ctx
context
.
Context
,
logger
log
.
Logger
)
context
.
Context
{
return
context
.
WithValue
(
ctx
,
loggerKey
,
logger
)
}
func
setBridgeTransfersView
(
ctx
context
.
Context
,
bv
database
.
BridgeTransfersView
)
context
.
Context
{
return
context
.
WithValue
(
ctx
,
bridgeTransfersViewKey
,
bv
)
}
// Getters
func
GetLogger
(
ctx
context
.
Context
)
log
.
Logger
{
logger
,
ok
:=
ctx
.
Value
(
loggerKey
)
.
(
log
.
Logger
)
if
!
ok
{
panic
(
"Logger not found in context!"
)
}
return
logger
}
func
GetBridgeTransfersView
(
ctx
context
.
Context
)
database
.
BridgeTransfersView
{
bv
,
ok
:=
ctx
.
Value
(
bridgeTransfersViewKey
)
.
(
database
.
BridgeTransfersView
)
if
!
ok
{
panic
(
"BridgeTransfersView not found in context!"
)
}
return
bv
}
func
ContextMiddleware
(
logger
log
.
Logger
,
bv
database
.
BridgeTransfersView
)
func
(
http
.
Handler
)
http
.
Handler
{
return
func
(
next
http
.
Handler
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
ctx
:=
setLogger
(
r
.
Context
(),
logger
)
ctx
=
setBridgeTransfersView
(
ctx
,
bv
)
next
.
ServeHTTP
(
w
,
r
.
WithContext
(
ctx
))
})
}
}
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