Skip to content
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
14 changes: 14 additions & 0 deletions src/constants/v2Addrs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,17 @@ export const MULTICALL_ADDRESS: AddressMap = {
[ChainId.BUILDNET]: 'AS1yphCWi7gychZWYPpqrKDiGb6ZacRoji8YYMLHtQ2TSuuQFqLC',
[ChainId.MAINNET]: 'AS1FJrNBtZ5oXK9y6Wcmiio5AV6rR2UopqqdQWhBH4Fss9JNMySm'
}

/**
* DEX governance SDK
*/

export const VOTING_ESCROW_ADDRESS: AddressMap = {
[ChainId.BUILDNET]: '',
[ChainId.MAINNET]: 'AS1q76iSMJ8Dj5gVBVK26y11yuFi9eVzUmTzwf5ANgoypMVcNjXj'
}

export const VOTER_ADDRESS: AddressMap = {
[ChainId.BUILDNET]: '',
[ChainId.MAINNET]: 'AS1rg37d1cFXrSXbEaKbGPBKRXahshk6VgvwJXjg48MbyuwM1ea6'
}
179 changes: 179 additions & 0 deletions src/contracts/ve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { GlobalPoint, LockedBalance, UserPoint } from '../types/governance'
import { IBaseContract } from './base'
import { Args, bytesToStr, byteToBool, U64, U256 } from '@massalabs/massa-web3'

export class IVotingEscrow extends IBaseContract {
async ownerOf(tokenId: number): Promise<string> {
return this.extract(['idToOwner::' + tokenId]).then((r) => {
if (!r[0].length) throw new Error('Not found')
return bytesToStr(r[0])
})
}
async balanceOf(user: string): Promise<number> {
return this.extract(['ownerToNFTokenCount::' + user]).then((r) => {
if (!r[0].length) throw new Error('Not found')
return Number(U64.fromBytes(r[0]))
})
}
async getApproved(tokenId: number): Promise<string> {
return this.extract(['idToApprovals::' + tokenId]).then((r) => {
if (!r[0].length) throw new Error('Not found')
return bytesToStr(r[0])
})
}
async isApprovedForAll(owner: string, operator: string): Promise<boolean> {
return this.extract(['ownerToOperators::' + owner + operator]).then((r) => {
if (!r[0].length) throw new Error('Not found')
return byteToBool(r[0])
})
}
async isApprovedOrOwner(spender: string, tokenId: number): Promise<boolean> {
return this.read({
targetFunction: 'isApprovedOrOwner',
parameter: new Args()
.addString(spender)
.addU64(BigInt(tokenId))
.serialize()
}).then((r) => byteToBool(r.value))
}

async locked(tokenId: number): Promise<LockedBalance> {
return this.read({
targetFunction: 'locked',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
}).then((r) => new LockedBalance().deserialize(r.value).instance)
}
async userPointHistory(tokenId: number, loc: number): Promise<UserPoint> {
return this.read({
targetFunction: 'userPointHistory',
parameter: new Args()
.addU64(BigInt(tokenId))
.addU64(BigInt(loc))
.serialize()
}).then((r) => new UserPoint().deserialize(r.value).instance)
}
async pointHistory(loc: number): Promise<GlobalPoint> {
return this.read({
targetFunction: 'pointHistory',
parameter: new Args().addU64(BigInt(loc)).serialize()
}).then((r) => new GlobalPoint().deserialize(r.value).instance)
}
async balanceOfNFT(tokenId: number): Promise<bigint> {
return this.read({
targetFunction: 'balanceOfNFT',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
}).then((r) => U256.fromBytes(r.value))
}
async balanceOfNFTAt(tokenId: number, timestamp: number): Promise<bigint> {
return this.read({
targetFunction: 'balanceOfNFTAt',
parameter: new Args()
.addU64(BigInt(tokenId))
.addU64(BigInt(timestamp))
.serialize()
}).then((r) => U256.fromBytes(r.value))
}
async totalSupply(): Promise<bigint> {
return this.read({
targetFunction: 'totalSupply',
parameter: new Args().serialize()
}).then((r) => U256.fromBytes(r.value))
}
async totalSupplyAt(timestamp: number): Promise<bigint> {
return this.read({
targetFunction: 'totalSupplyAt',
parameter: new Args().addU64(BigInt(timestamp)).serialize()
}).then((r) => U256.fromBytes(r.value))
}
async delegates(tokenId: number): Promise<number> {
return this.read({
targetFunction: 'delegates',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
}).then((r) => Number(U64.fromBytes(r.value)))
}

async approve(to: string, tokenId: number): Promise<string> {
return this.call({
targetFunction: 'approve',
parameter: new Args().addString(to).addU64(BigInt(tokenId)).serialize()
})
}
async setApprovalForAll(
operator: string,
approved: boolean
): Promise<string> {
return this.call({
targetFunction: 'setApprovalForAll',
parameter: new Args().addString(operator).addBool(approved).serialize()
})
}
async transferFrom(
from: string,
to: string,
tokenId: number
): Promise<string> {
return this.call({
targetFunction: 'transferFrom',
parameter: new Args()
.addString(from)
.addString(to)
.addU64(BigInt(tokenId))
.serialize()
})
}

depositFor(tokenId: number, amount: bigint): Promise<string> {
return this.call({
targetFunction: 'depositFor',
parameter: new Args().addU64(BigInt(tokenId)).addU256(amount).serialize()
})
}
createLock(amount: bigint, duration: number): Promise<string> {
return this.call({
targetFunction: 'createLock',
parameter: new Args().addU256(amount).addU64(BigInt(duration)).serialize()
})
}
increaseAmount(tokenId: number, amount: bigint): Promise<string> {
return this.call({
targetFunction: 'increaseAmount',
parameter: new Args().addU64(BigInt(tokenId)).addU256(amount).serialize()
})
}
increaseUnlockTime(tokenId: number, lockDuration: number): Promise<string> {
return this.call({
targetFunction: 'increaseUnlockTime',
parameter: new Args()
.addU64(BigInt(tokenId))
.addU64(BigInt(lockDuration))
.serialize()
})
}
withdraw(tokenId: number): Promise<string> {
return this.call({
targetFunction: 'withdraw',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
})
}
lockPermanent(tokenId: number): Promise<string> {
return this.call({
targetFunction: 'lockPermanent',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
})
}
unlockPermanent(tokenId: number): Promise<string> {
return this.call({
targetFunction: 'unlockPermanent',
parameter: new Args().addU64(BigInt(tokenId)).serialize()
})
}
delegate(delegator: number, delegatee: number): Promise<string> {
return this.call({
targetFunction: 'delegate',
parameter: new Args()
.addU64(BigInt(delegator))
.addU64(BigInt(delegatee))
.serialize()
})
}
}
16 changes: 16 additions & 0 deletions src/contracts/voter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { IBaseContract } from './base'
import { U64 } from '@massalabs/massa-web3'

export class IVoter extends IBaseContract {
async lastVoted(tokenIds: number[]): Promise<number[]> {
const bs = tokenIds.map((id: number) => `lastVoted::${id}`)
return this.extract(bs).then((r) => {
const lastVoted: number[] = []
r.forEach((item) => {
if (!item?.length) return
lastVoted.push(Number(U64.fromBytes(item)))
})
return lastVoted
})
}
}
119 changes: 119 additions & 0 deletions src/types/governance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Args, IDeserializedResult, ISerializable } from '@massalabs/massa-web3'

export class Checkpoint implements ISerializable<Checkpoint> {
constructor(
public fromTimestamp: number = 0,
public owner: string = '',
public delegatedBalance: bigint = 0n,
public delegatee: number = 0
) {}

serialize(): Uint8Array {
return new Args()
.addU64(BigInt(this.fromTimestamp))
.addString(this.owner)
.addU256(this.delegatedBalance)
.addU64(BigInt(this.delegatee))
.serialize()
}

deserialize(data: Uint8Array, offset = 0): IDeserializedResult<Checkpoint> {
const args = new Args(data, offset)
this.fromTimestamp = Number(args.nextU64())
this.owner = args.nextString()
this.delegatedBalance = args.nextU256()
this.delegatee = Number(args.nextU64())

return { instance: this, offset: args.getOffset() }
}
}

export class LockedBalance implements ISerializable<LockedBalance> {
constructor(
public amount: bigint = 0n,
public end: number = 0,
public isPermanent: boolean = false
) {}

serialize(): Uint8Array {
return new Args()
.addI128(BigInt(this.amount))
.addU64(BigInt(this.end))
.addBool(this.isPermanent)
.serialize()
}

deserialize(
data: Uint8Array,
offset = 0
): IDeserializedResult<LockedBalance> {
const args = new Args(data, offset)
this.amount = args.nextI128()
this.end = Number(args.nextU64())
this.isPermanent = args.nextBool()

return { instance: this, offset: args.getOffset() }
}
}

export class UserPoint implements ISerializable<UserPoint> {
constructor(
public bias: bigint = 0n,
public slope: bigint = 0n, // # -dweight / dt
public ts: number = 0,
public blk: number = 0, // block
public permanent: bigint = 0n
) {}

serialize(): Uint8Array {
return new Args()
.addI128(this.bias)
.addI128(this.slope)
.addU64(BigInt(this.ts))
.addU64(BigInt(this.blk))
.addU256(this.permanent)
.serialize()
}

deserialize(data: Uint8Array, offset = 0): IDeserializedResult<UserPoint> {
const args = new Args(data, offset)
this.bias = args.nextI128()
this.slope = args.nextI128()
this.ts = Number(args.nextU64())
this.blk = Number(args.nextU64())
this.permanent = args.nextU256()

return { instance: this, offset: args.getOffset() }
}
}

export class GlobalPoint implements ISerializable<GlobalPoint> {
constructor(
public bias: bigint = 0n,
public slope: bigint = 0n, // # -dweight / dt
public ts: number = 0,
public blk: number = 0, // block
public permanentLockBalance: bigint = 0n
) {}

serialize(): Uint8Array {
return new Args()
.addI128(this.bias)
.addI128(this.slope)
.addU64(BigInt(this.ts))
.addU64(BigInt(this.blk))
.addU256(this.permanentLockBalance)
.serialize()
}

deserialize(data: Uint8Array, offset = 0): IDeserializedResult<GlobalPoint> {
const args = new Args(data, offset)
this.bias = args.nextI128()
this.slope = args.nextI128()
this.ts = Number(args.nextU64())
this.blk = Number(args.nextU64())
this.permanentLockBalance = args.nextU256()

return { instance: this, offset: args.getOffset() }
}
}
Loading