Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: staking info #2

Merged
merged 4 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ NEXT_PUBLIC_FLOWNS_URL=https://www.flowns.org/domain
NEXT_PUBLIC_FIND_URL=https://find.xyz
NEXT_PUBLIC_BAYOU_URL=https://flow.bayou33.app
NEXT_PUBLIC_DRIZZLE_URL=https://www.drizzle33.app
NEXT_PUBLIC_INCREMENT_URL=https://increment.fi
NEXT_PUBLIC_INCREMENT_URL=https://app.increment.fi
NEXT_PUBLIC_LINK_URL=https://link.ecdao.org

NEXT_PUBLIC_NFTCATALOG_ADDRESS=0x49a7cda3a1eecc29
Expand Down
2 changes: 1 addition & 1 deletion .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ NEXT_PUBLIC_FLOWNS_URL=https://www.flowns.org/domain
NEXT_PUBLIC_FIND_URL=https://find.xyz
NEXT_PUBLIC_BAYOU_URL=https://flow.bayou33.app
NEXT_PUBLIC_DRIZZLE_URL=https://www.drizzle33.app
NEXT_PUBLIC_INCREMENT_URL=https://increment.fi
NEXT_PUBLIC_INCREMENT_URL=https://app.increment.fi
NEXT_PUBLIC_LINK_URL=https://link.ecdao.org

NEXT_PUBLIC_NFTCATALOG_ADDRESS=0x49a7cda3a1eecc29
Expand Down
9 changes: 5 additions & 4 deletions components/common/Siderbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ export default function Sidebar(props) {
{ id: "1", label: `Key`, link: { pathname: "/account/[account]/key", query: { account: account } } },
{ id: "2", label: `Token`, link: { pathname: "/account/[account]/fungible_token", query: { account: account } } },
{ id: "3", label: `Collection`, link: { pathname: "/account/[account]/collection", query: { account: account } } },
{ id: "4", label: `Staking`, link: { pathname: "/account/[account]/staking", query: { account: account } } },
{
id: "4", label: "Storage", subItems: [
{ id: "4-0", isSubItem: true, label: "Public Items", smLabel: "Public", link: { pathname: "/account/[account]/public_item", query: { account: account } } },
{ id: "4-1", isSubItem: true, label: "Stored Items", smLabel: "Stored", link: { pathname: "/account/[account]/stored_item", query: { account: account } } },
{ id: "4-2", isSubItem: true, label: "Private Items", smLabel: "Private", link: { pathname: "/account/[account]/private_item", query: { account: account } } },
id: "5", label: "Storage", subItems: [
{ id: "5-0", isSubItem: true, label: "Public Items", smLabel: "Public", link: { pathname: "/account/[account]/public_item", query: { account: account } } },
{ id: "5-1", isSubItem: true, label: "Stored Items", smLabel: "Stored", link: { pathname: "/account/[account]/stored_item", query: { account: account } } },
{ id: "5-2", isSubItem: true, label: "Private Items", smLabel: "Private", link: { pathname: "/account/[account]/private_item", query: { account: account } } },
]
}
// { id: "5", label: `Analyzer`, link: { pathname: "/account/[account]/analyzer", query: { account: account } } },
Expand Down
3 changes: 3 additions & 0 deletions flow/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,11 @@ export const getStoredItems = async (address, paths) => {
if isNFTCollection && conformedMetadataViews {
if let collectionRef = account.borrow<&{MetadataViews.ResolverCollection, NonFungibleToken.CollectionPublic}>(from: path) {
tokenIDs = collectionRef.getIDs()
// TODO: move to a list
if tokenIDs.length > 0
&& path != /storage/RaribleNFTCollection
&& path != /storage/ARTIFACTPackV3Collection
&& path != /storage/ArleeScene {
let resolver = collectionRef.borrowViewResolver(id: tokenIDs[0])
if let display = MetadataViews.getNFTCollectionDisplay(resolver) {
Expand Down
215 changes: 215 additions & 0 deletions flow/staking_scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
import * as fcl from "@onflow/fcl"

export const getEpochMetadata = async (epochCounter) => {
const code = `
import FlowEpoch from 0x8624b52f9ddcd04a
pub fun main(epochCounter: UInt64): FlowEpoch.EpochMetadata? {
return FlowEpoch.getEpochMetadata(epochCounter)
}
`

const result = await fcl.query({
cadence: code,
args: (arg, t) => [
arg(epochCounter, t.UInt64)
]
})

return result
}

export const getStakingInfo = async (address) => {
const code = `
import LockedTokens from 0x8d0e87b65159ae63
import FlowIDTableStaking from 0x8624b52f9ddcd04a
import FlowEpoch from 0x8624b52f9ddcd04a
pub struct EpochInfo {
pub let currentEpochCounter: UInt64
pub let currentEpochPhase: UInt8
init(
currentEpochCounter: UInt64,
currentEpochPhase: UInt8
) {
self.currentEpochCounter = currentEpochCounter
self.currentEpochPhase = currentEpochPhase
}
}
pub struct Result {
pub let stakingInfo: StakingInfo?
init(stakingInfo: StakingInfo?) {
self.stakingInfo = stakingInfo
}
}
pub struct StakingInfo {
pub let epochInfo: EpochInfo
pub let lockedAddress: Address
pub let lockedBalance: UFix64
pub let unlockLimit: UFix64
pub let nodeInfo: NodeInfo?
pub let delegatorInfo: DelegatorInfo?
init(
epochInfo: EpochInfo,
lockedAddress: Address,
lockedBalance: UFix64,
unlockLimit: UFix64,
nodeInfo: NodeInfo?,
delegatorInfo: DelegatorInfo?,
) {
self.epochInfo = epochInfo
self.lockedAddress = lockedAddress
self.lockedBalance = lockedBalance
self.unlockLimit = unlockLimit
self.nodeInfo = nodeInfo
self.delegatorInfo = delegatorInfo
}
}
pub struct NodeInfo {
pub let id: String
pub let networkingAddress: String
pub let role: UInt8
pub let tokensStaked: UFix64
pub let tokensCommitted: UFix64
pub let tokensUnstaking: UFix64
pub let tokensUnstaked: UFix64
pub let tokensRewarded: UFix64
pub let delegatorIDCounter: UInt32
pub let tokensRequestedToUnstake: UFix64
pub let initialWeight: UInt64
init(nodeID: String) {
let nodeInfo = FlowIDTableStaking.NodeInfo(nodeID: nodeID)
self.id = nodeInfo.id
self.networkingAddress = nodeInfo.networkingAddress
self.role = nodeInfo.role
self.tokensStaked = nodeInfo.tokensStaked
self.tokensCommitted = nodeInfo.tokensCommitted
self.tokensUnstaking = nodeInfo.tokensUnstaking
self.tokensUnstaked = nodeInfo.tokensUnstaked
self.tokensRewarded = nodeInfo.tokensRewarded
self.delegatorIDCounter = nodeInfo.delegatorIDCounter
self.tokensRequestedToUnstake = nodeInfo.tokensRequestedToUnstake
self.initialWeight = nodeInfo.initialWeight
}
}
pub struct DelegatorInfo {
pub let id: UInt32
pub let nodeID: String
pub let tokensCommitted: UFix64
pub let tokensStaked: UFix64
pub let tokensUnstaking: UFix64
pub let tokensRewarded: UFix64
pub let tokensUnstaked: UFix64
pub let tokensRequestedToUnstake: UFix64
init(nodeID: String, delegatorID: UInt32) {
let delegatorInfo = FlowIDTableStaking.DelegatorInfo(nodeID: nodeID, delegatorID: delegatorID)
self.id = delegatorInfo.id
self.nodeID = delegatorInfo.nodeID
self.tokensCommitted = delegatorInfo.tokensCommitted
self.tokensStaked = delegatorInfo.tokensStaked
self.tokensUnstaking = delegatorInfo.tokensUnstaking
self.tokensRewarded = delegatorInfo.tokensRewarded
self.tokensUnstaked = delegatorInfo.tokensUnstaked
self.tokensRequestedToUnstake = delegatorInfo.tokensRequestedToUnstake
}
}
pub fun main(address: Address): Result {
let tokenHolderRef =
getAuthAccount(address)
.borrow<&LockedTokens.TokenHolder>(from: LockedTokens.TokenHolderStoragePath)
var stakingInfo: StakingInfo? = nil
if let tokenHolder = tokenHolderRef {
let lockedAddress = tokenHolder.getLockedAccountAddress()
let lockedBalance = tokenHolder.getLockedAccountBalance()
let unlockLimit = tokenHolder.getUnlockLimit()
var nodeInfo: NodeInfo? = nil
var delegatorInfo: DelegatorInfo? = nil
if let delegatorNodeID = tokenHolder.getDelegatorNodeID() {
if let delegatorID = tokenHolder.getDelegatorID() {
nodeInfo = NodeInfo(nodeID: delegatorNodeID)
delegatorInfo = DelegatorInfo(nodeID: delegatorNodeID, delegatorID: delegatorID)
}
}
let epochInfo = EpochInfo(
currentEpochCounter: FlowEpoch.currentEpochCounter,
currentEpochPhase: FlowEpoch.currentEpochPhase.rawValue
)
stakingInfo = StakingInfo(
epochInfo: epochInfo,
lockedAddress: lockedAddress,
lockedBalance: lockedBalance,
unlockLimit: unlockLimit,
nodeInfo: nodeInfo,
delegatorInfo: delegatorInfo
)
}
return Result(stakingInfo: stakingInfo)
}
`

const result = await fcl.query({
cadence: code,
args: (arg, t) => [
arg(address, t.Address)
]
})

return result
}

export const getNodeInfo = async (nodeID) => {
const code = `
import FlowIDTableStaking from 0x8624b52f9ddcd04a
pub fun main(nodeID: String): FlowIDTableStaking.NodeInfo {
return FlowIDTableStaking.NodeInfo(nodeID: nodeID)
}
`

const result = await fcl.query({
cadence: code,
args: (arg, t) => [
arg(nodeID, t.String)
]
})

return result
}

export const getDelegatorInfo = async (nodeID, delegatorID) => {
const code = `
import FlowIDTableStaking from 0x8624b52f9ddcd04a
pub fun main(nodeID: String, delegatorID: UInt32): FlowIDTableStaking.DelegatorInfo {
return FlowIDTableStaking.DelegatorInfo(nodeID: nodeID, delegatorID: delegatorID)
}
`

const result = await fcl.query({
cadence: code,
args: (arg, t) => [
arg(nodeID, t.String),
arg(delegatorID, t.UInt32)
]
})

return result
}
43 changes: 43 additions & 0 deletions pages/account/[account]/analyzer.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,58 @@
import { useRouter } from "next/router"
import Layout from "../../../components/common/Layout"
import { huntStorage, huntPrivate, huntPublic } from "../../../flow/bug_hunter"
import { getDelegatorInfo, getEpochMetadata, getNodeInfo, getStakingInfo } from "../../../flow/staking_scripts"

export default function Analyzer() {
const router = useRouter()
const { account } = router.query

const getNodeIDs = (collectorClusters) => {
let totalNodeIDs = []
for (let i = 0; i < collectorClusters.length; i++) {
let cluster = collectorClusters[i]
let nodeWeights = cluster.nodeWeights
let nodeIDs = Object.keys(nodeWeights)
totalNodeIDs.push(...nodeIDs)
}
return totalNodeIDs
}

return (
<div className="container mx-auto max-w-7xl min-w-[380px] px-2">
<Layout>
<div className="flex flex-col gap-x-2">
<button
onClick={async () => {
let info = await getStakingInfo("0x0a1381bc9aa8b362")
console.log(info)
}}>
Staking Info
</button>
<button
onClick={async () => {
let info = await getDelegatorInfo("41f82d558dad936f3b3875d08d0cbdd4045a4c7024292e195e1df1066c5197fe", "1")
console.log(info)
}}>
Delegator Info
</button>
<button
onClick={async () => {
let epochMetadata = await getEpochMetadata(55)
console.log(epochMetadata)
let totalNodeIDs = getNodeIDs(epochMetadata.collectorClusters)
console.log(totalNodeIDs)
for (let i = 0; i < totalNodeIDs.length; i++) {
let nodeID = totalNodeIDs[i]
let nodeInfo = await getNodeInfo(nodeID)
if (parseInt(nodeInfo.delegatorIDCounter) == 1) {
console.log(nodeInfo)
break
}
}
}}>
Staking
</button>
<button
onClick={async () => {
await huntStorage(account)
Expand Down
Loading