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
5 changes: 5 additions & 0 deletions .changeset/clean-grapes-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphprotocol/grc-20": patch
---

all IDs with ATTRIBUTE in the name now changed PROPERTY. The constants with ATTRIBUTE still exist and marked as deprecated
5 changes: 5 additions & 0 deletions .changeset/swift-sloths-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphprotocol/grc-20": patch
---

Add utility functions createProperty, createType, createEntity
97 changes: 97 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,103 @@ const setRelationOp: CreateRelationOp = Relation.make({
const deleteRelationOp: DeleteRelationOp = Relation.remove('id of relation');
```

### Creating properties, types and entities

Working with triple and relations ops is a low level API and give you maximum flexibility. In order to ease the process of creating and updating data, the library also exports APIs for creating properties, types and entities.

```ts
import { Graph } from '@graphprotocol/grc-20';

// create a property
const propertyResult = Graph.createProperty({
name: 'name of the property',
type: 'TEXT', // TEXT | NUMBER | URL | TIME | POINT | CHECKBOX | RELATION,
});

// create a type
const { id: personTypeId, ops: createPersonTypeOps } = Graph.createType({
name: 'name of the type',
properties: […listOfPropertyIds],
});

// create an entity
const { id: restaurantId, ops: createRestaurantOps } = Graph.createEntity({
name: 'name of the entity',
types: […listOfTypeIds],
properties: {
// value property like text, number, url, time, point, checkbox
[propertyId]: {
type: 'TEXT', // TEXT | NUMBER | URL | TIME | POINT | CHECKBOX,
value: 'value of the property',
},
// relation property
[propertyId]: {
to: 'id of the entity',
},
},
});
```

#### Example Flow

```ts
import { Graph } from '@graphprotocol/grc-20';

const ops: Array<Op> = [];

// create an age property
const { id: agePropertyId, ops: createAgePropertyOps } = Graph.createProperty({
type: 'NUMBER',
name: 'Age',
});
ops.push(...createAgePropertyOps);

// create a likes property
const { id: likesPropertyId, ops: createLikesPropertyOps } = Graph.createProperty({
type: 'RELATION',
name: 'Likes',
});
ops.push(...createLikesPropertyOps);

// create a person type
const { id: personTypeId, ops: createPersonTypeOps } = Graph.createType({
name: 'Person',
properties: [agePropertyId, likesPropertyId],
});
ops.push(...createPersonTypeOps);

// create a restaurant entity with a website property
const restaurantTypeId = 'A9QizqoXSqjfPUBjLoPJa2';
const { id: restaurantId, ops: createRestaurantOps } = Graph.createEntity({
name: 'Yum Yum',
description: 'A restaurant serving fusion cuisine',
types: [restaurantTypeId],
properties: {
[WEBSITE_PROPERTY]: {
type: 'URL',
value: 'https://example.com',
},
},
});
ops.push(...createRestaurantOps);

// create a person entity with a likes relation to the restaurant entity
const { id: personId, ops: createPersonOps } = Graph.createEntity({
name: 'Jane Doe',
types: [personTypeId],
properties: {
[agePropertyId]: {
type: 'NUMBER',
value: 42,
},
[likesPropertyId]: {
to: restaurantId,
},
},
});
ops.push(...createPersonOps);
```

### Writing an edit to IPFS

Once you have a set of ops ready to publish, you'll need to binary encode them into an Edit and upload the Edit to IPFS.
Expand Down
8 changes: 4 additions & 4 deletions src/core/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ it('should generate ops for an account entity', () => {
const [accountTypeOp, networkOp, addressOp, nameOp] = ops;

expect(accountTypeOp.type).toBe('CREATE_RELATION');
expect(accountTypeOp.relation.type).toBe(SystemIds.TYPES_ATTRIBUTE);
expect(accountTypeOp.relation.type).toBe(SystemIds.TYPES_PROPERTY);
expect(accountTypeOp.relation.toEntity).toBe(SystemIds.ACCOUNT_TYPE);
expect(accountTypeOp.relation.fromEntity).toBe(accountId);

expect(networkOp.type).toBe('CREATE_RELATION');
expect(networkOp.relation.type).toBe(SystemIds.NETWORK_ATTRIBUTE);
expect(networkOp.relation.type).toBe(SystemIds.NETWORK_PROPERTY);
expect(networkOp.relation.toEntity).toBe(NetworkIds.ETHEREUM);
expect(networkOp.relation.fromEntity).toBe(accountId);

expect(addressOp.type).toBe('SET_TRIPLE');
expect(addressOp.triple.attribute).toBe(SystemIds.ADDRESS_ATTRIBUTE);
expect(addressOp.triple.attribute).toBe(SystemIds.ADDRESS_PROPERTY);
expect(addressOp.triple.value.type).toBe('TEXT');
expect(addressOp.triple.value.value).toBe(ZERO_ADDRESS);

expect(nameOp.type).toBe('SET_TRIPLE');
expect(nameOp.triple.attribute).toBe(SystemIds.NAME_ATTRIBUTE);
expect(nameOp.triple.attribute).toBe(SystemIds.NAME_PROPERTY);
expect(nameOp.triple.value.type).toBe('TEXT');
expect(nameOp.triple.value.value).toBe(ZERO_ADDRESS);
});
10 changes: 5 additions & 5 deletions src/core/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Relation } from '../relation.js';
import type { CreateRelationOp, SetTripleOp } from '../types.js';
import { getChecksumAddress } from './get-checksum-address.js';
import { ETHEREUM } from './ids/network.js';
import { ACCOUNT_TYPE, ADDRESS_ATTRIBUTE, NAME_ATTRIBUTE, NETWORK_ATTRIBUTE, TYPES_ATTRIBUTE } from './ids/system.js';
import { ACCOUNT_TYPE, ADDRESS_PROPERTY, NAME_PROPERTY, NETWORK_PROPERTY, TYPES_PROPERTY } from './ids/system.js';

type MakeAccountReturnType = {
accountId: string;
Expand Down Expand Up @@ -41,21 +41,21 @@ export function make(address: string): MakeAccountReturnType {
// Types -> Account
Relation.make({
fromId: accountId,
relationTypeId: TYPES_ATTRIBUTE,
relationTypeId: TYPES_PROPERTY,
toId: ACCOUNT_TYPE,
}),
// Network -> Ethereum
// Signals that the account is for the Ethereum family of chains
Relation.make({
fromId: accountId,
relationTypeId: NETWORK_ATTRIBUTE,
relationTypeId: NETWORK_PROPERTY,
toId: ETHEREUM,
}),
{
type: 'SET_TRIPLE',
triple: {
entity: accountId,
attribute: ADDRESS_ATTRIBUTE,
attribute: ADDRESS_PROPERTY,
value: {
type: 'TEXT',
value: checkedAddress,
Expand All @@ -66,7 +66,7 @@ export function make(address: string): MakeAccountReturnType {
type: 'SET_TRIPLE',
triple: {
entity: accountId,
attribute: NAME_ATTRIBUTE,
attribute: NAME_PROPERTY,
value: {
type: 'TEXT',
value: checkedAddress,
Expand Down
6 changes: 3 additions & 3 deletions src/core/blocks/data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it('should generate ops for a data block entity', () => {

expect(blockTypeOp?.type).toBe('CREATE_RELATION');
if (blockTypeOp?.type === 'CREATE_RELATION') {
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_ATTRIBUTE);
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_PROPERTY);
expect(blockTypeOp?.relation.toEntity).toBe(SystemIds.DATA_BLOCK);
}

Expand Down Expand Up @@ -44,7 +44,7 @@ it('should generate ops for a data block entity with a name', () => {

expect(blockTypeOp?.type).toBe('CREATE_RELATION');
if (blockTypeOp?.type === 'CREATE_RELATION') {
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_ATTRIBUTE);
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_PROPERTY);
expect(blockTypeOp?.relation.toEntity).toBe(SystemIds.DATA_BLOCK);
}

Expand All @@ -62,7 +62,7 @@ it('should generate ops for a data block entity with a name', () => {

expect(blockNameOp?.type).toBe('SET_TRIPLE');
if (blockNameOp?.type === 'SET_TRIPLE') {
expect(blockNameOp?.triple.attribute).toBe(SystemIds.NAME_ATTRIBUTE);
expect(blockNameOp?.triple.attribute).toBe(SystemIds.NAME_PROPERTY);
expect(blockNameOp?.triple.value.type).toBe('TEXT');
expect(blockNameOp?.triple.value.value).toBe('test-name');
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/blocks/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function make({ fromId, sourceType, position, name }: DataBlockArgs): (Se

const dataBlockType = Relation.make({
fromId: newBlockId,
relationTypeId: SystemIds.TYPES_ATTRIBUTE,
relationTypeId: SystemIds.TYPES_PROPERTY,
toId: SystemIds.DATA_BLOCK,
});

Expand All @@ -75,7 +75,7 @@ export function make({ fromId, sourceType, position, name }: DataBlockArgs): (Se
ops.push({
type: 'SET_TRIPLE',
triple: {
attribute: SystemIds.NAME_ATTRIBUTE,
attribute: SystemIds.NAME_PROPERTY,
entity: newBlockId,
value: {
type: 'TEXT',
Expand Down
2 changes: 1 addition & 1 deletion src/core/blocks/text.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it('should generate ops for a text block entity', () => {

expect(blockTypeOp?.type).toBe('CREATE_RELATION');
if (blockTypeOp?.type === 'CREATE_RELATION') {
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_ATTRIBUTE);
expect(blockTypeOp?.relation.type).toBe(SystemIds.TYPES_PROPERTY);
expect(blockTypeOp?.relation.toEntity).toBe(SystemIds.TEXT_BLOCK);
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/blocks/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function make({ fromId, text, position }: TextBlockArgs): Op[] {

const textBlockType = Relation.make({
fromId: newBlockId,
relationTypeId: SystemIds.TYPES_ATTRIBUTE,
relationTypeId: SystemIds.TYPES_PROPERTY,
toId: SystemIds.TEXT_BLOCK,
});

Expand Down
Loading
Loading