Skip to content

Commit 5f663f1

Browse files
Merge pull request #279 from daostack/278-fixedreputationallocation
[WIP] first implementation for reputationfromtoken
2 parents 4aa6f95 + f609c66 commit 5f663f1

File tree

5 files changed

+120
-17
lines changed

5 files changed

+120
-17
lines changed

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export { Queue, IQueueState, IQueueQueryOptions } from './queue'
99
export { Reputation, IReputationState, IReputationQueryOptions } from './reputation'
1010
export { Reward, IRewardState, IRewardQueryOptions } from './reward'
1111
export { Scheme, ISchemeState, ISchemeQueryOptions } from './scheme'
12+
export { ReputationFromTokenScheme } from './schemes/reputationFromToken'
1213
export { IContributionReward} from './schemes/contributionReward'
1314
export { IGenericScheme } from './schemes/genericScheme'
1415
export { ISchemeRegistrar } from './schemes/schemeRegistrar'

src/scheme.ts

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Operation, toIOperationObservable } from './operation'
77
import { IProposalCreateOptions, IProposalQueryOptions, Proposal } from './proposal'
88
import * as ContributionReward from './schemes/contributionReward'
99
import * as GenericScheme from './schemes/genericScheme'
10+
import { ReputationFromTokenScheme } from './schemes/reputationFromToken'
1011
import * as SchemeRegistrar from './schemes/schemeRegistrar'
1112
import { Address, ICommonQueryOptions, IStateful } from './types'
1213
import { createGraphQlQuery, isAddress } from './utils'
@@ -57,11 +58,25 @@ export interface ISchemeQueryOptions extends ICommonQueryOptions {
5758
}
5859
}
5960

61+
export interface ISchemeQueryOptions extends ICommonQueryOptions {
62+
where?: {
63+
address?: Address
64+
canDelegateCall?: boolean
65+
canRegisterSchemes?: boolean
66+
canUpgradeController?: boolean
67+
canManageGlobalConstraints?: boolean
68+
dao?: Address
69+
id?: string
70+
name?: string
71+
paramsHash?: string
72+
[key: string]: any
73+
}
74+
}
75+
6076
/**
6177
* A Scheme represents a scheme instance that is registered at a DAO
6278
*/
6379
export class Scheme implements IStateful<ISchemeState> {
64-
6580
/**
6681
* Scheme.search(context, options) searches for scheme entities
6782
* @param context an Arc instance that provides connection information
@@ -101,16 +116,15 @@ export class Scheme implements IStateful<ISchemeState> {
101116
}`
102117
const itemMap = (item: any): Scheme|null => {
103118
if (!options.where) { options.where = {}}
104-
return new Scheme(
105-
{
106-
address: item.address,
107-
dao: item.dao.id,
108-
id: item.id,
109-
name: item.name,
110-
paramsHash: item.paramsHash
111-
},
112-
context
113-
)
119+
120+
const scheme = new Scheme({
121+
address: item.address,
122+
dao: item.dao.id,
123+
id: item.id,
124+
name: item.name,
125+
paramsHash: item.paramsHash
126+
}, context)
127+
return scheme
114128
}
115129

116130
return context.getObservableList(
@@ -121,9 +135,10 @@ export class Scheme implements IStateful<ISchemeState> {
121135
}
122136

123137
public id: Address
124-
public staticState: ISchemeStaticState|null = null
138+
public staticState: ISchemeStaticState | null = null
139+
public ReputationFromToken: ReputationFromTokenScheme | null = null
125140

126-
constructor(idOrOpts: Address|ISchemeStaticState, public context: Arc) {
141+
constructor(idOrOpts: Address | ISchemeStaticState, public context: Arc) {
127142
this.context = context
128143
if (typeof idOrOpts === 'string') {
129144
this.id = idOrOpts as string
@@ -142,17 +157,21 @@ export class Scheme implements IStateful<ISchemeState> {
142157
* fetch the static state from the subgraph
143158
* @return the statatic state
144159
*/
145-
public async fetchStaticState(): Promise<ISchemeStaticState> {
160+
public async fetchStaticState(): Promise < ISchemeStaticState > {
146161
if (!!this.staticState) {
147162
return this.staticState
148163
} else {
149164
const state = await this.state().pipe(first()).toPromise()
150165
this.staticState = state
166+
if (this.staticState.name === 'ReputationFromToken') {
167+
this.ReputationFromToken = new ReputationFromTokenScheme(this)
168+
}
169+
151170
return state
152171
}
153172
}
154173

155-
public state(): Observable<ISchemeState> {
174+
public state(): Observable < ISchemeState > {
156175
const query = gql`
157176
{
158177
controllerScheme (id: "${this.id}") {
@@ -279,7 +298,7 @@ export class Scheme implements IStateful<ISchemeState> {
279298
* @param options [description ]
280299
* @return a Proposal instance
281300
*/
282-
public createProposal(options: IProposalCreateOptions): Operation<Proposal> {
301+
public createProposal(options: IProposalCreateOptions): Operation < Proposal > {
283302
const observable = Observable.create(async (observer: any) => {
284303
let msg: string
285304
const context = this.context

src/schemes/reputationFromToken.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { from } from 'rxjs'
2+
import { concatMap } from 'rxjs/operators'
3+
4+
import {
5+
Operation,
6+
toIOperationObservable
7+
} from '../operation'
8+
9+
import { Address } from '../types'
10+
11+
import { Scheme } from '../scheme'
12+
13+
export class ReputationFromTokenScheme {
14+
15+
constructor(public scheme: Scheme) {
16+
17+
}
18+
19+
public redeem(beneficiary: Address): Operation<any> {
20+
const mapReceipt = (receipt: any) => {
21+
return receipt
22+
}
23+
24+
const observable = from(this.getContract())
25+
.pipe(
26+
concatMap((contract) => {
27+
const errorHandler = async (error: Error) => {
28+
return error
29+
}
30+
31+
const redeemMethod = contract.methods.redeem(
32+
beneficiary
33+
)
34+
35+
return this.scheme.context.sendTransaction(redeemMethod, mapReceipt, errorHandler)
36+
})
37+
)
38+
return toIOperationObservable(observable)
39+
}
40+
41+
public async redemptionAmount(beneficiary: Address): Promise<number> {
42+
const contract = await this.getContract()
43+
const amount = await contract.methods.redeem(beneficiary).call()
44+
return amount
45+
}
46+
47+
private async getContract() {
48+
const state = await this.scheme.fetchStaticState()
49+
const contract = this.scheme.context.getContract(state.address)
50+
return contract
51+
}
52+
53+
}

test/operation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,5 @@ describe('Operation', () => {
6666
transactionHash: listOfUpdates[2].transactionHash
6767
})
6868

69-
}, 20000)
69+
})
7070
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Scheme } from '../src/scheme'
2+
import { getTestDAO, newArc } from './utils'
3+
4+
jest.setTimeout(60000)
5+
/**
6+
* Scheme test
7+
*/
8+
describe('Scheme', () => {
9+
10+
it.skip('Test the whole flow', async () => {
11+
const arc = await newArc()
12+
const dao = await getTestDAO()
13+
14+
const scheme = new Scheme({
15+
address: '0x1224',
16+
dao: dao.id,
17+
id: '0.x123455',
18+
name: 'ReputationFromToken',
19+
paramsHash: '0x124'
20+
}, arc)
21+
22+
expect(scheme.ReputationFromToken).not.toBeFalsy()
23+
if (scheme.ReputationFromToken) {
24+
const amount = await scheme.ReputationFromToken.redemptionAmount(arc.web3.eth.defaultAccount)
25+
expect(amount).toEqual(0)
26+
await scheme.ReputationFromToken.redeem(arc.web3.eth.defaultAccount)
27+
}
28+
})
29+
30+
})

0 commit comments

Comments
 (0)