Verified Commit b104afaa authored by Andranik's avatar Andranik

Add utils package

parent a161aa80
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sensio Example</title>
<link
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
crossorigin="anonymous"
>
</head>
<body>
<div class="contaner">
<div class="row">
</div>
</div>
</body>
</html>
\ No newline at end of file
import { ApiPromise } from '@polkadot/api';
// initialise via static create
const api = await ApiPromise.create();
// make a call to retrieve the current network head
api.rpc.chain.subscribeNewHeads((header) => {
console.log(`Chain is at #${header.number}`);
});
This diff is collapsed.
{
"name": "sensio-sdk-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@polkadot/api": "^1.14.1"
}
}
......@@ -39,7 +39,9 @@
"p:fix": "prettier --write ./packages/*/src/**.{ts,tsx,js,md}",
"l:check": "prettier --check ./packages/*/src/**.{ts,tsx,js,md}",
"l:fix": "prettier --write ./packages/*/src/**.{ts,tsx,js,md}",
"std": "standardx src/**/*.ts src/**/*.tsx --fix"
"std": "standardx src/**/*.ts src/**/*.tsx --fix",
"operations:generate": "lerna run generate --scope @sensio/operations",
"operations:clean": "lerna run clean --scope @sensio/operations"
},
"license": "Apache-2.0"
}
import CID from 'cids';
import * as imghash from 'imghash';
import mh from 'multihashing-async';
/**
* Pack the input. Using serialization like cbor or JSON.stringify
*/
export function pack(o: any): string {
const r = JSON.stringify(o);
// calculateSize(r);
return r;
}
/**
* Calculate the Multihash from the spec
*/
export async function calculateHash(
data: Buffer,
algo = 'blake2b',
length = 256,
): Promise<Buffer> {
const hash = await mh(data, `${algo}-${length}`);
return hash;
}
/**
* Create Content address
*/
export function createCID(
data: Buffer,
codec = 'raw',
baseName = 'base32',
): CID {
return new CID(1, codec, data, baseName);
}
/**
* Use only binary ascii representation
* @param b {Buffer}
* @return {Promise<string>}
*/
export async function calculatePhash(b): Promise<string> {
return imghash.hash(b, 16, 'binary');
}
/**
* elapsed time, useful for performance testing
* @param start is ret value of process.hrtime()
* @return {number} miliseconds
*/
export const elapsedTime = (start) => {
const elapsed = Date.now() - start;
return elapsed;
};
const toType = function (obj) {
return {}.toString
.call(obj)
.match(/\s([a-zA-Z]+)/)[1]
.toLowerCase();
};
/**
* Uses JSON.stringify then creates the buffer and gets byteLength
* @param {any} a
*/
export function calculateSize(a) {
let len;
if (Buffer.isBuffer(a)) {
len = a.byteLength;
} else {
len = Buffer.from(JSON.stringify(a)).byteLength;
}
console.log(
`Param is of type ${toType(a).toUpperCase()} with length ${parseFloat(
len / 1024,
).toFixed(2)}kb`,
);
}
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import { formatToUUID } from '../../proofs/execution';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import formatToUUID from '../../../../utils/formatToUUID';
import config from './config';
/**
......
import ExifReader from 'exifreader';
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import { stringToU8a } from '@polkadot/util';
import ExifReader from 'exifreader';
import { calculateHash, createCID, pack } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......@@ -14,7 +15,7 @@ export default async function metadataHash({ file }): Promise<string> {
ret = createCID(
await calculateHash(
Buffer.from(stringToU8a(pack(tags))),
Buffer.from(stringToU8a(JSON.stringify(tags))),
config.data.hashing.algo,
config.data.hashing.bits,
),
......
import { calculatePhash } from '../../helpers';
import calculatePhash from '../../../../utils/calculatePhash';
import config from './config';
/**
......
import { calculateHash, createCID } from '../../helpers';
import createCID from '../../../../utils/createCID';
import calculateHash from '../../../../utils/calculateHash';
import config from './config';
/**
......
import { hexToString } from '@polkadot/util';
import React, { useEffect, useState } from 'react';
import {
Container,
Dimmer,
Divider,
Form,
Grid,
Loader,
Message,
} from 'semantic-ui-react';
import { CUSTOM_TYPES } from '../../../config/common.json';
import { useSubstrate } from '../../../substrate-lib';
import { getOperations, saveRuleToNetwork } from '../helpers';
import CreateRuleChooser from './CreateRuleChooser';
function formatForWhat() {
return CUSTOM_TYPES.ForWhat._enum.map((m, i) => {
return { key: i, text: m, value: i };
});
}
export default function CreateRule(props) {
const defaultVal = {
version: 1,
name: 'For flower petal',
desc: 'Generic rule for flower petal full description',
creator: 'urn:pgp:d1f5e247a976f1e3c14f0a437a6db9962ef3978e',
forWhat: 1,
ops: [],
};
const { api } = useSubstrate();
const { accountPair } = props;
const [ops, setOps] = useState([]);
const [ruleOps, setRuleOps] = useState([]);
const [selectableOps, setSelectableOps] = useState([]);
const [rule, setRule] = useState(defaultVal);
const [errorMessage, setErrorMessage] = useState('');
const [readyToSubmit, setReadyToSubmit] = useState(false);
const [saving, setSaving] = useState(false);
const [savingMessage, setSavingMessage] = useState('Saving');
const formattedForWhat = formatForWhat();
/**
* MAIN SUBMIT METHOD
*/
async function handleSubmit() {
setErrorMessage('');
setSaving(true);
const opsForRule = ops
.filter(({ op }) => ruleOps.includes(hexToString(op.id.toString())))
.map(({ op }) => op);
const ruleData = api.createType('RuleData', {
...rule,
ops: opsForRule,
});
console.log(ruleData);
await saveRuleToNetwork(
api,
ruleData,
accountPair,
([error, message, success]) => {
if (error) {
console.error(error);
alert(error);
setSaving(false);
} else {
setSavingMessage(message);
if (success) {
setSavingMessage(message);
setSaving(false);
}
}
},
);
}
function handleOperationChange(e, { value }) {
e.preventDefault();
// const op = ops.find(({ op }) => {
// hexToString(op.id.toString()) === value
// ? console.log("yea", hexToString(op.id.toString()))
// : console.log("nay", hexToString(op.id.toString()));
// });
// console.log("find op", value, ops, op);
setRuleOps(value);
}
function handleValueChange(e, { name, value }) {
e.preventDefault();
setRule({
...rule,
[name]: value,
});
}
useEffect(() => {
if (ruleOps.length >= 1) {
setReadyToSubmit(true);
}
}, [ruleOps]);
useEffect(() => {
async function getOps() {
const opsList = await getOperations(api);
setOps(opsList);
const ret = [];
opsList.forEach(({ op: { id, data: o } }, i) => {
const opId = hexToString(id.toString());
const opName = hexToString(o.op.toString());
if (ret.find((r) => r.value === opName)) {
return;
}
// for now don't include ops that contain other ops, they are special
if (o.ops.length !== 0) {
return;
}
ret.push({
key: opId,
text: opName.replace(/_/gi, ' '),
value: opId,
});
});
setSelectableOps(ret);
}
getOps();
}, [api, selectableOps]);
const MessageExampleFloating = () => (
<Message negative floating>
{errorMessage}
</Message>
);
return (
<Container>
<Dimmer active={saving} inverted>
<Loader>{savingMessage} ...</Loader>
</Dimmer>
<Grid>
<Grid.Row color={'purple'}>
<Grid.Column width={4}>
<h1 style={{ marginLeft: 16 }}>Create PoE Rule</h1>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<CreateRuleChooser accountPair={accountPair} />
</Grid.Column>
</Grid.Row>
<Grid.Row>
{errorMessage && <MessageExampleFloating />}
<Grid.Column>
<Form>
<Form.Input
fluid
label="Version"
placeholder={rule.version}
defaultValue={rule.version}
type="number"
onChange={handleValueChange}
name="version"
/>
<Form.Input
fluid
label="Name"
placeholder={rule.name}
defaultValue={rule.name}
onChange={handleValueChange}
name="name"
input={{ maxLength: 20 }}
/>
<Form.Input
fluid
label="Description"
placeholder={rule.desc}
defaultValue={rule.desc}
onChange={handleValueChange}
name="desc"
/>
<Form.Input
fluid
label="Creator"
placeholder={rule.creator}
defaultValue={rule.creator}
onChange={handleValueChange}
name="creator"
/>
<Form.Select
fluid
label="For What"
options={formattedForWhat}
defaultValue={rule.forWhat}
onChange={handleValueChange}
name="forWhat"
/>
<Divider />
<Form.Select
fluid
multiple
search
selection
label="Operations"
options={selectableOps}
onChange={handleOperationChange}
value={ruleOps}
name="ops"
/>
<Form.Button
onClick={handleSubmit}
disabled={!readyToSubmit}
primary
>
Submit
</Form.Button>
</Form>
</Grid.Column>
</Grid.Row>
</Grid>
</Container>
);
}
import React, { useEffect, useState } from 'react';
import { Button, Grid, Loader, Segment } from 'semantic-ui-react';
import { useSubstrate } from '../../../substrate-lib';
import { createDefaultRules, getOperations } from '../helpers';
export default function CreateRuleChooser(props) {
const { accountPair } = props;
const { api } = useSubstrate();
const [creating, setCreating] = useState(false);
const [savingMessage, setSavingMessage] = useState(
'Saving, check console for more info',
);
const [ops, setOps] = useState([]);
function handleClickCreateDefaultRules(e) {
e.preventDefault();
setCreating(true);
createDefaultRules(api, accountPair, ops).then((r) => {
if (r) {
setSavingMessage('');
setCreating(false);
}
});
}
useEffect(() => {
async function run() {
const opsList = await getOperations(api);
setOps(opsList);
}
run();
}, [api]);
return (
<Segment>
<Loader active={creating} inline="centered">
{savingMessage} ...
</Loader>
<Grid stackable textAlign="center">
<Grid.Row verticalAlign="middle">
<Grid.Column>
<Button
disabled={creating}
onClick={handleClickCreateDefaultRules}
primary
>
Create Default Rules
</Button>
</Grid.Column>
</Grid.Row>
</Grid>
</Segment>
);
}
import React, { useEffect, useState } from 'react';
import { Statistic } from 'semantic-ui-react';
import { useSubstrate } from '../../../substrate-lib';
import { getRules } from '../helpers';
export default function RulesInfo(props) {
const { api } = useSubstrate();
const [rules, setRules] = useState([]);
useEffect(() => {
async function getInfo() {
try {
const r = await getRules(api);
setRules(r);
} catch (e) {
console.error(e);
}
}
getInfo();
const i = setInterval(getInfo, 3000);
return () => {
clearInterval(i);
};
}, [api]);
return <Statistic label={'PoE Rules'} value={rules.length} />;
}
import { hexToString } from '@polkadot/util';
import React, { useEffect, useState } from 'react';
import { Container, Grid, Icon, List } from 'semantic-ui-react';
import { useSubstrate } from '../../../substrate-lib';
import colors from '../../colors.json';
import CodeModal from '../CodeModal';
import { getRules } from '../helpers';
import CreateRuleChooser from './CreateRuleChooser';
export default function RulesList({ accountPair }) {
const { api } = useSubstrate();
const [rules, setRules] = useState([]);
const [interval, setCurrentInterval] = useState(0);
useEffect(() => {
async function getInfo() {
try {
const r = await getRules(api);
setRules(r);
} catch (e) {
console.error(e);
}
}
if (!interval) {
getInfo();
} else {
setCurrentInterval(setInterval(getInfo, 3000));
}
return () => {
clearInterval(interval);
};
}, [api, interval]);
return (
<Container>
<Grid>
<Grid.Row color={'purple'}>
<Grid.Column width={4}>
<h1 style={{ marginLeft: 16 }}>PoE Rules</h1>
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column>
<CreateRuleChooser accountPair={accountPair} />
</Grid.Column>
</Grid.Row>
{rules.length !== 0 && (
<Grid.Row>
<Grid.Column>
<List divided verticalAlign="middle" size="large">
{rules.map((v, i) => {
const {
rule: { id, data },
} = v;
const { forWhat, version, desc, name } = data;
const color = colors[i];
return (
<List.Item key={hexToString(id.toString())}>
<List.Content floated="right">
<CodeModal data={v} />
</List.Content>
<Icon
style={{
color: color,
fontSize: '2em',
paddingTop: 10,
}}
name="circle thin"
/>
<List.Content>
<List.Header>
Name: {hexToString(name.toString())}
</List.Header>
<List.Header>Operations: {data.ops.length}</List.Header>
<List.Description>
This is the rule for {forWhat.toString()} and version