initial setup

This commit is contained in:
andytudhope 2020-02-14 14:05:25 +02:00
parent 3368482022
commit 82a85d627d
11 changed files with 4128 additions and 92 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
build

View File

@ -0,0 +1,773 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
import {
EthereumCall,
EthereumEvent,
SmartContract,
EthereumValue,
JSONValue,
TypedMap,
Entity,
EthereumTuple,
Bytes,
Address,
BigInt,
CallResult
} from "@graphprotocol/graph-ts";
export class DAppCreated extends EthereumEvent {
get params(): DAppCreated__Params {
return new DAppCreated__Params(this);
}
}
export class DAppCreated__Params {
_event: DAppCreated;
constructor(event: DAppCreated) {
this._event = event;
}
get id(): Bytes {
return this._event.parameters[0].value.toBytes();
}
get newEffectiveBalance(): BigInt {
return this._event.parameters[1].value.toBigInt();
}
}
export class Upvote extends EthereumEvent {
get params(): Upvote__Params {
return new Upvote__Params(this);
}
}
export class Upvote__Params {
_event: Upvote;
constructor(event: Upvote) {
this._event = event;
}
get id(): Bytes {
return this._event.parameters[0].value.toBytes();
}
get newEffectiveBalance(): BigInt {
return this._event.parameters[1].value.toBigInt();
}
}
export class Downvote extends EthereumEvent {
get params(): Downvote__Params {
return new Downvote__Params(this);
}
}
export class Downvote__Params {
_event: Downvote;
constructor(event: Downvote) {
this._event = event;
}
get id(): Bytes {
return this._event.parameters[0].value.toBytes();
}
get newEffectiveBalance(): BigInt {
return this._event.parameters[1].value.toBigInt();
}
}
export class Withdraw extends EthereumEvent {
get params(): Withdraw__Params {
return new Withdraw__Params(this);
}
}
export class Withdraw__Params {
_event: Withdraw;
constructor(event: Withdraw) {
this._event = event;
}
get id(): Bytes {
return this._event.parameters[0].value.toBytes();
}
get newEffectiveBalance(): BigInt {
return this._event.parameters[1].value.toBigInt();
}
}
export class MetadataUpdated extends EthereumEvent {
get params(): MetadataUpdated__Params {
return new MetadataUpdated__Params(this);
}
}
export class MetadataUpdated__Params {
_event: MetadataUpdated;
constructor(event: MetadataUpdated) {
this._event = event;
}
get id(): Bytes {
return this._event.parameters[0].value.toBytes();
}
}
export class CeilingUpdated extends EthereumEvent {
get params(): CeilingUpdated__Params {
return new CeilingUpdated__Params(this);
}
}
export class CeilingUpdated__Params {
_event: CeilingUpdated;
constructor(event: CeilingUpdated) {
this._event = event;
}
get oldCeiling(): BigInt {
return this._event.parameters[0].value.toBigInt();
}
get newCeiling(): BigInt {
return this._event.parameters[1].value.toBigInt();
}
}
export class Discover__downvoteCostResult {
value0: BigInt;
value1: BigInt;
value2: BigInt;
constructor(value0: BigInt, value1: BigInt, value2: BigInt) {
this.value0 = value0;
this.value1 = value1;
this.value2 = value2;
}
toMap(): TypedMap<string, EthereumValue> {
let map = new TypedMap<string, EthereumValue>();
map.set("value0", EthereumValue.fromUnsignedBigInt(this.value0));
map.set("value1", EthereumValue.fromUnsignedBigInt(this.value1));
map.set("value2", EthereumValue.fromUnsignedBigInt(this.value2));
return map;
}
}
export class Discover__dappsResult {
value0: Address;
value1: Bytes;
value2: Bytes;
value3: BigInt;
value4: BigInt;
value5: BigInt;
value6: BigInt;
value7: BigInt;
value8: BigInt;
constructor(
value0: Address,
value1: Bytes,
value2: Bytes,
value3: BigInt,
value4: BigInt,
value5: BigInt,
value6: BigInt,
value7: BigInt,
value8: BigInt
) {
this.value0 = value0;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
this.value5 = value5;
this.value6 = value6;
this.value7 = value7;
this.value8 = value8;
}
toMap(): TypedMap<string, EthereumValue> {
let map = new TypedMap<string, EthereumValue>();
map.set("value0", EthereumValue.fromAddress(this.value0));
map.set("value1", EthereumValue.fromFixedBytes(this.value1));
map.set("value2", EthereumValue.fromFixedBytes(this.value2));
map.set("value3", EthereumValue.fromUnsignedBigInt(this.value3));
map.set("value4", EthereumValue.fromUnsignedBigInt(this.value4));
map.set("value5", EthereumValue.fromUnsignedBigInt(this.value5));
map.set("value6", EthereumValue.fromUnsignedBigInt(this.value6));
map.set("value7", EthereumValue.fromUnsignedBigInt(this.value7));
map.set("value8", EthereumValue.fromUnsignedBigInt(this.value8));
return map;
}
}
export class Discover extends SmartContract {
static bind(address: Address): Discover {
return new Discover("Discover", address);
}
upvoteEffect(_id: Bytes, _amount: BigInt): BigInt {
let result = super.call("upvoteEffect", [
EthereumValue.fromFixedBytes(_id),
EthereumValue.fromUnsignedBigInt(_amount)
]);
return result[0].toBigInt();
}
try_upvoteEffect(_id: Bytes, _amount: BigInt): CallResult<BigInt> {
let result = super.tryCall("upvoteEffect", [
EthereumValue.fromFixedBytes(_id),
EthereumValue.fromUnsignedBigInt(_amount)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
safeMax(): BigInt {
let result = super.call("safeMax", []);
return result[0].toBigInt();
}
try_safeMax(): CallResult<BigInt> {
let result = super.tryCall("safeMax", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
total(): BigInt {
let result = super.call("total", []);
return result[0].toBigInt();
}
try_total(): CallResult<BigInt> {
let result = super.tryCall("total", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
decimals(): BigInt {
let result = super.call("decimals", []);
return result[0].toBigInt();
}
try_decimals(): CallResult<BigInt> {
let result = super.tryCall("decimals", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
existingIDs(param0: Bytes): boolean {
let result = super.call("existingIDs", [
EthereumValue.fromFixedBytes(param0)
]);
return result[0].toBoolean();
}
try_existingIDs(param0: Bytes): CallResult<boolean> {
let result = super.tryCall("existingIDs", [
EthereumValue.fromFixedBytes(param0)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBoolean());
}
getDAppsCount(): BigInt {
let result = super.call("getDAppsCount", []);
return result[0].toBigInt();
}
try_getDAppsCount(): CallResult<BigInt> {
let result = super.tryCall("getDAppsCount", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
max(): BigInt {
let result = super.call("max", []);
return result[0].toBigInt();
}
try_max(): CallResult<BigInt> {
let result = super.tryCall("max", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
downvoteCost(_id: Bytes): Discover__downvoteCostResult {
let result = super.call("downvoteCost", [
EthereumValue.fromFixedBytes(_id)
]);
return new Discover__downvoteCostResult(
result[0].toBigInt(),
result[1].toBigInt(),
result[2].toBigInt()
);
}
try_downvoteCost(_id: Bytes): CallResult<Discover__downvoteCostResult> {
let result = super.tryCall("downvoteCost", [
EthereumValue.fromFixedBytes(_id)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(
new Discover__downvoteCostResult(
value[0].toBigInt(),
value[1].toBigInt(),
value[2].toBigInt()
)
);
}
ceiling(): BigInt {
let result = super.call("ceiling", []);
return result[0].toBigInt();
}
try_ceiling(): CallResult<BigInt> {
let result = super.tryCall("ceiling", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
dapps(param0: BigInt): Discover__dappsResult {
let result = super.call("dapps", [
EthereumValue.fromUnsignedBigInt(param0)
]);
return new Discover__dappsResult(
result[0].toAddress(),
result[1].toBytes(),
result[2].toBytes(),
result[3].toBigInt(),
result[4].toBigInt(),
result[5].toBigInt(),
result[6].toBigInt(),
result[7].toBigInt(),
result[8].toBigInt()
);
}
try_dapps(param0: BigInt): CallResult<Discover__dappsResult> {
let result = super.tryCall("dapps", [
EthereumValue.fromUnsignedBigInt(param0)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(
new Discover__dappsResult(
value[0].toAddress(),
value[1].toBytes(),
value[2].toBytes(),
value[3].toBigInt(),
value[4].toBigInt(),
value[5].toBigInt(),
value[6].toBigInt(),
value[7].toBigInt(),
value[8].toBigInt()
)
);
}
id2index(param0: Bytes): BigInt {
let result = super.call("id2index", [EthereumValue.fromFixedBytes(param0)]);
return result[0].toBigInt();
}
try_id2index(param0: Bytes): CallResult<BigInt> {
let result = super.tryCall("id2index", [
EthereumValue.fromFixedBytes(param0)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
withdrawMax(_id: Bytes): BigInt {
let result = super.call("withdrawMax", [EthereumValue.fromFixedBytes(_id)]);
return result[0].toBigInt();
}
try_withdrawMax(_id: Bytes): CallResult<BigInt> {
let result = super.tryCall("withdrawMax", [
EthereumValue.fromFixedBytes(_id)
]);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toBigInt());
}
controller(): Address {
let result = super.call("controller", []);
return result[0].toAddress();
}
try_controller(): CallResult<Address> {
let result = super.tryCall("controller", []);
if (result.reverted) {
return new CallResult();
}
let value = result.value;
return CallResult.fromValue(value[0].toAddress());
}
}
export class WithdrawCall extends EthereumCall {
get inputs(): WithdrawCall__Inputs {
return new WithdrawCall__Inputs(this);
}
get outputs(): WithdrawCall__Outputs {
return new WithdrawCall__Outputs(this);
}
}
export class WithdrawCall__Inputs {
_call: WithdrawCall;
constructor(call: WithdrawCall) {
this._call = call;
}
get _id(): Bytes {
return this._call.inputValues[0].value.toBytes();
}
get _amount(): BigInt {
return this._call.inputValues[1].value.toBigInt();
}
}
export class WithdrawCall__Outputs {
_call: WithdrawCall;
constructor(call: WithdrawCall) {
this._call = call;
}
}
export class UpvoteCall extends EthereumCall {
get inputs(): UpvoteCall__Inputs {
return new UpvoteCall__Inputs(this);
}
get outputs(): UpvoteCall__Outputs {
return new UpvoteCall__Outputs(this);
}
}
export class UpvoteCall__Inputs {
_call: UpvoteCall;
constructor(call: UpvoteCall) {
this._call = call;
}
get _id(): Bytes {
return this._call.inputValues[0].value.toBytes();
}
get _amount(): BigInt {
return this._call.inputValues[1].value.toBigInt();
}
}
export class UpvoteCall__Outputs {
_call: UpvoteCall;
constructor(call: UpvoteCall) {
this._call = call;
}
}
export class ChangeControllerCall extends EthereumCall {
get inputs(): ChangeControllerCall__Inputs {
return new ChangeControllerCall__Inputs(this);
}
get outputs(): ChangeControllerCall__Outputs {
return new ChangeControllerCall__Outputs(this);
}
}
export class ChangeControllerCall__Inputs {
_call: ChangeControllerCall;
constructor(call: ChangeControllerCall) {
this._call = call;
}
get _newController(): Address {
return this._call.inputValues[0].value.toAddress();
}
}
export class ChangeControllerCall__Outputs {
_call: ChangeControllerCall;
constructor(call: ChangeControllerCall) {
this._call = call;
}
}
export class CreateDAppCall extends EthereumCall {
get inputs(): CreateDAppCall__Inputs {
return new CreateDAppCall__Inputs(this);
}
get outputs(): CreateDAppCall__Outputs {
return new CreateDAppCall__Outputs(this);
}
}
export class CreateDAppCall__Inputs {
_call: CreateDAppCall;
constructor(call: CreateDAppCall) {
this._call = call;
}
get _id(): Bytes {
return this._call.inputValues[0].value.toBytes();
}
get _amount(): BigInt {
return this._call.inputValues[1].value.toBigInt();
}
get _metadata(): Bytes {
return this._call.inputValues[2].value.toBytes();
}
}
export class CreateDAppCall__Outputs {
_call: CreateDAppCall;
constructor(call: CreateDAppCall) {
this._call = call;
}
}
export class SetCeilingCall extends EthereumCall {
get inputs(): SetCeilingCall__Inputs {
return new SetCeilingCall__Inputs(this);
}
get outputs(): SetCeilingCall__Outputs {
return new SetCeilingCall__Outputs(this);
}
}
export class SetCeilingCall__Inputs {
_call: SetCeilingCall;
constructor(call: SetCeilingCall) {
this._call = call;
}
get _newCeiling(): BigInt {
return this._call.inputValues[0].value.toBigInt();
}
}
export class SetCeilingCall__Outputs {
_call: SetCeilingCall;
constructor(call: SetCeilingCall) {
this._call = call;
}
}
export class ReceiveApprovalCall extends EthereumCall {
get inputs(): ReceiveApprovalCall__Inputs {
return new ReceiveApprovalCall__Inputs(this);
}
get outputs(): ReceiveApprovalCall__Outputs {
return new ReceiveApprovalCall__Outputs(this);
}
}
export class ReceiveApprovalCall__Inputs {
_call: ReceiveApprovalCall;
constructor(call: ReceiveApprovalCall) {
this._call = call;
}
get _from(): Address {
return this._call.inputValues[0].value.toAddress();
}
get _amount(): BigInt {
return this._call.inputValues[1].value.toBigInt();
}
get _token(): Address {
return this._call.inputValues[2].value.toAddress();
}
get _data(): Bytes {
return this._call.inputValues[3].value.toBytes();
}
}
export class ReceiveApprovalCall__Outputs {
_call: ReceiveApprovalCall;
constructor(call: ReceiveApprovalCall) {
this._call = call;
}
}
export class DownvoteCall extends EthereumCall {
get inputs(): DownvoteCall__Inputs {
return new DownvoteCall__Inputs(this);
}
get outputs(): DownvoteCall__Outputs {
return new DownvoteCall__Outputs(this);
}
}
export class DownvoteCall__Inputs {
_call: DownvoteCall;
constructor(call: DownvoteCall) {
this._call = call;
}
get _id(): Bytes {
return this._call.inputValues[0].value.toBytes();
}
get _amount(): BigInt {
return this._call.inputValues[1].value.toBigInt();
}
}
export class DownvoteCall__Outputs {
_call: DownvoteCall;
constructor(call: DownvoteCall) {
this._call = call;
}
}
export class SetMetadataCall extends EthereumCall {
get inputs(): SetMetadataCall__Inputs {
return new SetMetadataCall__Inputs(this);
}
get outputs(): SetMetadataCall__Outputs {
return new SetMetadataCall__Outputs(this);
}
}
export class SetMetadataCall__Inputs {
_call: SetMetadataCall;
constructor(call: SetMetadataCall) {
this._call = call;
}
get _id(): Bytes {
return this._call.inputValues[0].value.toBytes();
}
get _metadata(): Bytes {
return this._call.inputValues[1].value.toBytes();
}
}
export class SetMetadataCall__Outputs {
_call: SetMetadataCall;
constructor(call: SetMetadataCall) {
this._call = call;
}
}
export class ConstructorCall extends EthereumCall {
get inputs(): ConstructorCall__Inputs {
return new ConstructorCall__Inputs(this);
}
get outputs(): ConstructorCall__Outputs {
return new ConstructorCall__Outputs(this);
}
}
export class ConstructorCall__Inputs {
_call: ConstructorCall;
constructor(call: ConstructorCall) {
this._call = call;
}
get _SNT(): Address {
return this._call.inputValues[0].value.toAddress();
}
}
export class ConstructorCall__Outputs {
_call: ConstructorCall;
constructor(call: ConstructorCall) {
this._call = call;
}
}

183
generated/schema.ts Normal file
View File

@ -0,0 +1,183 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
import {
TypedMap,
Entity,
Value,
ValueKind,
store,
Address,
Bytes,
BigInt,
BigDecimal
} from "@graphprotocol/graph-ts";
export class DappMeta extends Entity {
constructor(id: string) {
super();
this.set("id", Value.fromString(id));
}
save(): void {
let id = this.get("id");
assert(id !== null, "Cannot save DappMeta entity without an ID");
assert(
id.kind == ValueKind.STRING,
"Cannot save DappMeta entity with non-string ID. " +
'Considering using .toHex() to convert the "id" to a string.'
);
store.set("DappMeta", id.toString(), this);
}
static load(id: string): DappMeta | null {
return store.get("DappMeta", id) as DappMeta | null;
}
get id(): string {
let value = this.get("id");
return value.toString();
}
set id(value: string) {
this.set("id", Value.fromString(value));
}
get ipfsHash(): string {
let value = this.get("ipfsHash");
return value.toString();
}
set ipfsHash(value: string) {
this.set("ipfsHash", Value.fromString(value));
}
get hash(): string {
let value = this.get("hash");
return value.toString();
}
set hash(value: string) {
this.set("hash", Value.fromString(value));
}
get details(): string {
let value = this.get("details");
return value.toString();
}
set details(value: string) {
this.set("details", Value.fromString(value));
}
get status(): string {
let value = this.get("status");
return value.toString();
}
set status(value: string) {
this.set("status", Value.fromString(value));
}
}
export class Detail extends Entity {
constructor(id: string) {
super();
this.set("id", Value.fromString(id));
}
save(): void {
let id = this.get("id");
assert(id !== null, "Cannot save Detail entity without an ID");
assert(
id.kind == ValueKind.STRING,
"Cannot save Detail entity with non-string ID. " +
'Considering using .toHex() to convert the "id" to a string.'
);
store.set("Detail", id.toString(), this);
}
static load(id: string): Detail | null {
return store.get("Detail", id) as Detail | null;
}
get id(): string {
let value = this.get("id");
return value.toString();
}
set id(value: string) {
this.set("id", Value.fromString(value));
}
get identifier(): string {
let value = this.get("identifier");
return value.toString();
}
set identifier(value: string) {
this.set("identifier", Value.fromString(value));
}
get name(): string {
let value = this.get("name");
return value.toString();
}
set name(value: string) {
this.set("name", Value.fromString(value));
}
get uploader(): string {
let value = this.get("uploader");
return value.toString();
}
set uploader(value: string) {
this.set("uploader", Value.fromString(value));
}
get url(): string {
let value = this.get("url");
return value.toString();
}
set url(value: string) {
this.set("url", Value.fromString(value));
}
get description(): string {
let value = this.get("description");
return value.toString();
}
set description(value: string) {
this.set("description", Value.fromString(value));
}
get category(): string {
let value = this.get("category");
return value.toString();
}
set category(value: string) {
this.set("category", Value.fromString(value));
}
get image(): string {
let value = this.get("image");
return value.toString();
}
set image(value: string) {
this.set("image", Value.fromString(value));
}
get dateAdded(): BigInt {
let value = this.get("dateAdded");
return value.toBigInt();
}
set dateAdded(value: BigInt) {
this.set("dateAdded", Value.fromBigInt(value));
}
}

View File

@ -1,6 +1,35 @@
type ExampleEntity @entity {
type DappMeta @entity {
id: ID!
count: BigInt!
id: Bytes! # bytes32
newEffectiveBalance: BigInt! # uint256
ipfsHash: String!
hash: String!
details: Detail! @derivedFrom(field: "identifier")
status: Status!
}
type Detail @entity {
id: ID!
identifier: DappMeta!
name: String!
uploader: String!
url: String!
description: String!
category: DAppCategories!
image: String!
dateAdded: BigInt!
}
enum Status {
NEW
APPROVED
UPDATED
}
enum DAppCategories {
EXCHANGES
MARKETPLACES
COLLECTIBLES
GAMES
SOCIAL_NETWORKS
UTILITIES
OTHER
}

37
src/ipfs.ts Normal file
View File

@ -0,0 +1,37 @@
import { ipfs, json, JSONValue, JSONValueKind, log, TypedMap } from '@graphprotocol/graph-ts';
import { asObject, kindToString } from './util';
import { TransactionInfo } from './transaction';
/**
* Loads a JSON blob from IPFS, parses the JSON and makes sure the JSON is a valid JSON object.
* Returns `null` otherwise.
*/
export function loadFromIpfs(ifpsHash: string, tx: TransactionInfo): TypedMap<string, JSONValue> | null {
if (tx.state.ipfsReqs > 7) {
// Workaround to avoid the subgraph from failing when a call handler takes > 180s
// See https://github.com/graphprotocol/graph-node/issues/963
log.warning(
'[mapping] [loadIpfs] Too many IPFS requests while processing this transaction {}, skipping fetching hash={}',
[tx.toString(), ifpsHash]
);
return null;
}
tx.state.ipfsReqs += 1;
log.debug('[mapping] [loadIpfs] Loading JSON blob from ipfs hash={} for {}', [ifpsHash, tx.toString()]);
let bytes = ipfs.cat(ifpsHash);
log.debug('[mapping] [loadIpfs] Completed ipfs.cat from ipfs hash={} for {}', [ifpsHash, tx.toString()]);
if (bytes !== null) {
let data = json.fromBytes(bytes!);
if (data === null) {
return null;
}
if (data.kind !== JSONValueKind.OBJECT) {
log.debug('[mapping] [loadIpfs] JSON data from IPFS is of type={}, expected OBJECT in {}', [
kindToString(data.kind),
tx.toString(),
]);
}
return asObject(data);
}
return null;
};

View File

@ -1,75 +1,90 @@
import { BigInt } from "@graphprotocol/graph-ts"
import {
Contract,
DAppCreated,
Upvote,
Downvote,
Withdraw,
MetadataUpdated,
CeilingUpdated
} from "../generated/Contract/Contract"
import { ExampleEntity } from "../generated/schema"
DAppCreated as DAppCreatedEvent,
Discover as DiscoverContract
} from "../generated/Discover/Discover"
import {
DappMeta,
Detail
} from "../generated/schema"
export function handleDAppCreated(event: DAppCreated): void {
// Entities can be loaded from the store using a string ID; this ID
// needs to be unique across all entities of the same type
let entity = ExampleEntity.load(event.transaction.from.toHex())
import {
log,
ipfs,
json,
TypedMap,
JSONValue,
Bytes,
Value,
BigDecimal,
ByteArray,
BigInt } from '@graphprotocol/graph-ts'
// Entities only exist after they have been saved to the store;
// `null` checks allow to create entities on demand
if (entity == null) {
entity = new ExampleEntity(event.transaction.from.toHex())
import { loadFromIpfs } from "./ipfs";
import { TransactionInfo, State } from "./transaction";
// Entity fields can be set using simple assignments
entity.count = BigInt.fromI32(0)
}
// BigInt and BigDecimal math are supported
entity.count = entity.count + BigInt.fromI32(1)
export function handleDAppCreated(event: DAppCreatedEvent): void {
let contract = DiscoverContract.bind(event.address)
let entity = new DappMeta(
event.transaction.hash.toHex() + "-" + event.logIndex.toString()
)
// Entity fields can be set based on event parameters
entity.id = event.params.id
entity.newEffectiveBalance = event.params.newEffectiveBalance
let entity2 = new Detail(
event.transaction.hash.toHex() + "-" + event.logIndex.toString()
)
let id = event.params.id
let count = contract.getDAppsCount()
let dappIdx = contract.id2index(id)
let dapp = contract.dapps(dappIdx)
let metadata = dapp.value2 // bytes32 representation of ipfs Hash where all metadata is stored
let bytes32toHex = metadata.toHexString()
let ipfsHashHex = '1220' + bytes32toHex.slice(2)
ipfsHashHex = '0x' + ipfsHashHex
// Entities can be written to the store with `.save()`
log.info('Hows everything {} {} {} {} {}', [count.toHexString(), dappIdx.toHexString(), id.toHex(), bytes32toHex, ipfsHashHex])
let ipfsHashBytes = Bytes.fromHexString(ipfsHashHex)
let ipfsHash = ipfsHashBytes.toBase58()
log.info("IPFS HASH: {}", [ipfsHash])
let tx: TransactionInfo
tx.blockNumber = event.block.number.toI32()
tx.timestamp = event.block.timestamp.toI32()
tx.from = event.transaction.from
tx.hash = event.transaction.hash
tx.state.ipfsReqs = 0
if (ipfsHash != 'QmS6a72GnPvUCMwKKrVGE41yY8RYwVVoBTrEbW6XWDu1EY' && ipfsHash != 'QmfCbEDwZ7sVSzcmivp3WvKd9pcKHhmCXiFwFuuQJmhPhs') {
let ipfsData = loadFromIpfs(ipfsHash, tx)
log.debug("Transaction (Tx): {}", [tx.toString()])
log.debug("IPFS DATA is {}", [ipfsData.get("name").toString()])
entity2.name = ipfsData.get("name").toString()
entity2.url = ipfsData.get("url").toString()
entity2.description = ipfsData.get("description").toString()
entity2.dateAdded = ipfsData.get("dateAdded").toBigInt()
entity2.category = ipfsData.get("category").toString()
entity2.uploader = ipfsData.get("uploader").toString()
entity2.image = ipfsData.get("image").toString()
entity2.identifier = event.transaction.hash.toHex() + "-" + event.logIndex.toString()
entity2.save()
entity.ipfsHash = ipfsHash
entity.hash = event.transaction.hash.toHex()
entity.status = "NEW"
entity.save()
}
// entity.compressedMetadata = web3Utils.keccak256(
// JSON.stringify(metadata),
// )
// entity.status = "NEW"
// Note: If a handler doesn't require existing field values, it is faster
// _not_ to load the entity from the store. Instead, create it fresh with
// `new Entity(...)`, set the fields that should be updated and save the
// entity back to the store. Fields that were not set or unset remain
// unchanged, allowing for partial updates to be applied.
// It is also possible to access smart contracts from mappings. For
// example, the contract that has emitted the event can be connected to
// with:
//
// let contract = Contract.bind(event.address)
//
// The following functions can then be called on this contract to access
// state variables and other data:
//
// - contract.upvoteEffect(...)
// - contract.safeMax(...)
// - contract.total(...)
// - contract.decimals(...)
// - contract.existingIDs(...)
// - contract.getDAppsCount(...)
// - contract.max(...)
// - contract.downvoteCost(...)
// - contract.ceiling(...)
// - contract.dapps(...)
// - contract.id2index(...)
// - contract.withdrawMax(...)
// - contract.controller(...)
}
export function handleUpvote(event: Upvote): void {}
export function handleDownvote(event: Downvote): void {}
export function handleWithdraw(event: Withdraw): void {}
export function handleMetadataUpdated(event: MetadataUpdated): void {}
export function handleCeilingUpdated(event: CeilingUpdated): void {}
// entity.id = event.params.id
// entity.newEffectiveBalance = event.params.newEffectiveBalance
}

71
src/transaction.ts Normal file
View File

@ -0,0 +1,71 @@
import { Bytes, Address, EthereumCall, Value } from '@graphprotocol/graph-ts';
/**
* Some state information to keep track while processing a transaction
*/
export class State {
/** Number of IPFS.cat calls made so far */
ipfsReqs: u32 = 0;
}
/**
* Stores some specific information about an ethereum transaction
*/
export class TransactionInfo {
blockNumber: i32;
timestamp: i32;
from: Address;
hash: Bytes;
state: State;
/** Extract transaction info from an ethereum call */
static fromEthereumCall(call: EthereumCall): TransactionInfo {
let info = new TransactionInfo();
info.blockNumber = call.block.number.toI32();
info.timestamp = call.block.timestamp.toI32();
info.hash = call.transaction.hash;
info.from = call.transaction.from;
info.state = new State();
return info;
}
/** Restore transaction info from value */
static fromValue(value: Value): TransactionInfo {
let arr = value.toArray();
let info = new TransactionInfo();
info.blockNumber = arr[0].toI32();
info.timestamp = arr[1].toI32();
info.hash = arr[2].toBytes();
info.from = arr[3].toAddress();
return info;
}
/**
* Store transaction info in a Value, which can be passed
* around in ipfs.map/mapJSON async calls
*/
toValue(): Value {
let timestamp = Value.fromI32(this.timestamp);
let block = Value.fromI32(this.blockNumber);
let hash = Value.fromBytes(this.hash);
let from = Value.fromAddress(this.from);
let encoded = Value.fromArray([block, timestamp, hash, from]);
return encoded;
}
/** Clone the transaction, but keep the original state field */
clone(): TransactionInfo {
let cloned = TransactionInfo.fromValue(this.toValue());
// Keep the original state reference.
cloned.state = this.state;
return cloned;
}
toString(): string {
let res = 'tx=';
res += this.hash.toHex();
res += ', ipfsReqs=';
res += this.state.ipfsReqs.toString();
return res;
}
}

96
src/util.ts Normal file
View File

@ -0,0 +1,96 @@
import { Bytes, JSONValue, JSONValueKind, TypedMap } from '@graphprotocol/graph-ts';
/**
* Make sure the given JSONValue is a string and returns string it contains.
* Returns `null` otherwise.
*/
export function asString(val: JSONValue | null): string | null {
if (val != null && val.kind === JSONValueKind.STRING) {
return val.toString();
}
return null;
}
/**
* Makes sure the given JSONValue is an object and return the object it contains.
* Returns `null` otherwise.
*/
export function asObject(val: JSONValue | null): TypedMap<string, JSONValue> | null {
if (val != null && val.kind === JSONValueKind.OBJECT) {
return val.toObject();
}
return null;
}
/**
* Make sure the given JSONValue is an array and returns that array it contains.
* Returns `null` otherwise.
*/
export function asArray(val: JSONValue | null): Array<JSONValue> | null {
if (val != null && val.kind === JSONValueKind.ARRAY) {
return val.toArray();
}
return null;
}
/**
* Retrieves an integer value from the JSON object with the given key. If this key
* doesn't exist, or the value is not a number, it returns `defaultValue` instead.
*/
export function intValue(obj: TypedMap<string, JSONValue>, key: string, defaultValue: BigInt): BigInt {
let val = obj.get(key);
if (val !== null && val.kind === JSONValueKind.NUMBER) {
let i = val.toI64();
return i as BigInt;
}
return defaultValue;
}
/**
* This function checks if the given byte array contains a valid
* UTF-8 sequence and can be successfully parsed into a string.
*/
export function isValidUtf8(bytes: Bytes): boolean {
let pending = 0;
for (let i = 0; i < bytes.length; i++) {
let b = bytes[i];
if (pending === 0) {
let m = 0b10000000;
while ((m & b) !== 0) {
pending += 1;
m = m >> 1;
}
if (pending === 0) {
continue;
}
if (pending === 1 || pending > 4) {
return false;
}
} else {
if ((b & 0b11000000) !== 0b10000000) {
return false;
}
}
pending -= 1;
}
return pending === 0;
}
export function kindToString(kind: JSONValueKind): string {
switch (kind) {
case JSONValueKind.ARRAY:
return 'ARRAY';
case JSONValueKind.OBJECT:
return 'OBJECT';
case JSONValueKind.STRING:
return 'STRING';
case JSONValueKind.NUMBER:
return 'NUMBER';
case JSONValueKind.BOOL:
return 'BOOL';
case JSONValueKind.NULL:
return 'NULL';
default:
return '?';
}
}

View File

@ -1,38 +1,42 @@
specVersion: 0.0.1
specVersion: 0.0.2
description: Open, economic ranking for Ethereum
repository: https://github.com/dap-ps/graph
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: Contract
name: Discover
network: mainnet
source:
address: "0x5bCF2767F86f14eDd82053bfBfd5069F68C2C5F8"
abi: Contract
abi: Discover
startBlock: 8302637
mapping:
kind: ethereum/events
apiVersion: 0.0.2
apiVersion: 0.0.3
language: wasm/assemblyscript
entities:
- DAppCreated
- Upvote
- Downvote
- Withdraw
- MetadataUpdated
- CeilingUpdated
- DappMeta
# - DAppCreated
# - Upvote
# - Downvote
# - Withdraw
# - MetadataUpdated
# - CeilingUpdated
abis:
- name: Contract
file: ./abis/Contract.json
- name: Discover
file: ./abis/Discover.json
eventHandlers:
- event: DAppCreated(indexed bytes32,uint256)
handler: handleDAppCreated
- event: Upvote(indexed bytes32,uint256)
handler: handleUpvote
- event: Downvote(indexed bytes32,uint256)
handler: handleDownvote
- event: Withdraw(indexed bytes32,uint256)
handler: handleWithdraw
- event: MetadataUpdated(indexed bytes32)
handler: handleMetadataUpdated
- event: CeilingUpdated(uint256,uint256)
handler: handleCeilingUpdated
# - event: Upvote(indexed bytes32,uint256)
# handler: handleUpvote
# - event: Downvote(indexed bytes32,uint256)
# handler: handleDownvote
# - event: Withdraw(indexed bytes32,uint256)
# handler: handleWithdraw
# - event: MetadataUpdated(indexed bytes32)
# handler: handleMetadataUpdated
# - event: CeilingUpdated(uint256,uint256)
# handler: handleCeilingUpdated
file: ./src/mapping.ts

2826
yarn.lock Normal file

File diff suppressed because it is too large Load Diff