Add a script to publish records from a given directory #62
100
README.md
100
README.md
@ -544,103 +544,3 @@ Reassociate records (switch bond):
|
|||||||
```bash
|
```bash
|
||||||
$ laconic registry bond records reassociate --old-bond-id 5c40abd336ae1561f2a1b55be73b12f5a083080bf879b4c9288d182d238badb0 --new-bond-id 3e11c61f179897e4b12e9b63de35d36f88ac146755e7a28ce0bcdd07cf3a03ae
|
$ laconic registry bond records reassociate --old-bond-id 5c40abd336ae1561f2a1b55be73b12f5a083080bf879b4c9288d182d238badb0 --new-bond-id 3e11c61f179897e4b12e9b63de35d36f88ac146755e7a28ce0bcdd07cf3a03ae
|
||||||
```
|
```
|
||||||
|
|
||||||
## Endpoint Records Demo
|
|
||||||
|
|
||||||
* Create and populate `config.yml`
|
|
||||||
|
|
||||||
* Publish watcher records from [`records/watcher`](./records/watcher):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn ts-node src/publish-endponit-records.ts -c config.yml -r records/watcher
|
|
||||||
```
|
|
||||||
|
|
||||||
* Publish watcher deployment records from [`records/watcher-deployments`](./records/watcher-deployments):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn ts-node src/publish-endponit-records.ts -c config.yml -r records/watcher-deployments
|
|
||||||
```
|
|
||||||
|
|
||||||
* View the records at laconicd GQL endpoint <http://localhost:9473>:
|
|
||||||
|
|
||||||
```gql
|
|
||||||
{
|
|
||||||
queryRecords {
|
|
||||||
id
|
|
||||||
bondId
|
|
||||||
names
|
|
||||||
attributes {
|
|
||||||
key
|
|
||||||
value {
|
|
||||||
... on BooleanValue { bool: value }
|
|
||||||
... on IntValue { int: value }
|
|
||||||
... on FloatValue { float: value }
|
|
||||||
... on StringValue { string: value }
|
|
||||||
... on BytesValue { bytes: value }
|
|
||||||
... on LinkValue { link: value }
|
|
||||||
... on ArrayValue {
|
|
||||||
array: value {
|
|
||||||
... on BooleanValue { bool: value }
|
|
||||||
... on IntValue { int: value }
|
|
||||||
... on FloatValue { float: value }
|
|
||||||
... on StringValue { string: value }
|
|
||||||
... on BytesValue { bytes: value }
|
|
||||||
... on LinkValue { link: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
... on MapValue { map: value { key mapping: value { __typename } } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
* Query with filters, for example: query all `filecoin` `WatcherRecord`s:
|
|
||||||
|
|
||||||
```gql
|
|
||||||
{
|
|
||||||
queryRecords (
|
|
||||||
attributes: [
|
|
||||||
{
|
|
||||||
key: "type",
|
|
||||||
value: {
|
|
||||||
string: "WatcherRecord"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "chain",
|
|
||||||
value: {
|
|
||||||
string: "filecoin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
all: true
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
bondId
|
|
||||||
names
|
|
||||||
attributes {
|
|
||||||
key
|
|
||||||
value {
|
|
||||||
... on BooleanValue { bool: value }
|
|
||||||
... on IntValue { int: value }
|
|
||||||
... on FloatValue { float: value }
|
|
||||||
... on StringValue { string: value }
|
|
||||||
... on BytesValue { bytes: value }
|
|
||||||
... on LinkValue { link: value }
|
|
||||||
... on ArrayValue {
|
|
||||||
array: value {
|
|
||||||
... on BooleanValue { bool: value }
|
|
||||||
... on IntValue { int: value }
|
|
||||||
... on FloatValue { float: value }
|
|
||||||
... on StringValue { string: value }
|
|
||||||
... on BytesValue { bytes: value }
|
|
||||||
... on LinkValue { link: value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
... on MapValue { map: value { key mapping: value { __typename } } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
94
deploy-records.md
Normal file
94
deploy-records.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Records Demo
|
||||||
|
|
||||||
|
* Create and populate `config.yml`
|
||||||
|
|
||||||
|
* Publish watcher records from [`records/watcher`](./records/watcher):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Publishes records and corresponding 'deployment' records from the given directory
|
||||||
|
yarn ts-node src/publish-endponit-records.ts -c config.yml -r records/watcher
|
||||||
|
```
|
||||||
|
|
||||||
|
* View the records at laconicd GQL endpoint <http://localhost:9473>:
|
||||||
|
|
||||||
|
```gql
|
||||||
|
{
|
||||||
|
queryRecords {
|
||||||
|
id
|
||||||
|
bondId
|
||||||
|
names
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
... on BooleanValue { bool: value }
|
||||||
|
... on IntValue { int: value }
|
||||||
|
... on FloatValue { float: value }
|
||||||
|
... on StringValue { string: value }
|
||||||
|
... on BytesValue { bytes: value }
|
||||||
|
... on LinkValue { link: value }
|
||||||
|
... on ArrayValue {
|
||||||
|
array: value {
|
||||||
|
... on BooleanValue { bool: value }
|
||||||
|
... on IntValue { int: value }
|
||||||
|
... on FloatValue { float: value }
|
||||||
|
... on StringValue { string: value }
|
||||||
|
... on BytesValue { bytes: value }
|
||||||
|
... on LinkValue { link: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on MapValue { map: value { key mapping: value { __typename } } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Query with filters, for example: query all `filecoin` `WatcherRecord`s:
|
||||||
|
|
||||||
|
```gql
|
||||||
|
{
|
||||||
|
queryRecords (
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
key: "type",
|
||||||
|
value: {
|
||||||
|
string: "WatcherRecord"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "chain",
|
||||||
|
value: {
|
||||||
|
string: "filecoin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
all: true
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
bondId
|
||||||
|
names
|
||||||
|
attributes {
|
||||||
|
key
|
||||||
|
value {
|
||||||
|
... on BooleanValue { bool: value }
|
||||||
|
... on IntValue { int: value }
|
||||||
|
... on FloatValue { float: value }
|
||||||
|
... on StringValue { string: value }
|
||||||
|
... on BytesValue { bytes: value }
|
||||||
|
... on LinkValue { link: value }
|
||||||
|
... on ArrayValue {
|
||||||
|
array: value {
|
||||||
|
... on BooleanValue { bool: value }
|
||||||
|
... on IntValue { int: value }
|
||||||
|
... on FloatValue { float: value }
|
||||||
|
... on StringValue { string: value }
|
||||||
|
... on BytesValue { bytes: value }
|
||||||
|
... on LinkValue { link: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on MapValue { map: value { key mapping: value { __typename } } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
@ -2,6 +2,7 @@ import yargs from 'yargs';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { hideBin } from 'yargs/helpers';
|
import { hideBin } from 'yargs/helpers';
|
||||||
|
|
||||||
import { Registry } from '@cerc-io/registry-sdk';
|
import { Registry } from '@cerc-io/registry-sdk';
|
||||||
|
|
||||||
import { getConfig, getGasAndFees, getConnectionInfo, txOutput } from './util';
|
import { getConfig, getGasAndFees, getConnectionInfo, txOutput } from './util';
|
||||||
@ -11,42 +12,73 @@ async function main () {
|
|||||||
const { records: recordsDir, config } = argv;
|
const { records: recordsDir, config } = argv;
|
||||||
|
|
||||||
const { services: { registry: registryConfig } } = getConfig(config as string);
|
const { services: { registry: registryConfig } } = getConfig(config as string);
|
||||||
|
|
||||||
|
if (registryConfig.userKey == null) {
|
||||||
|
throw new Error('userKey not set in config');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registryConfig.bondId == null) {
|
||||||
|
throw new Error('bondId not set in config');
|
||||||
|
}
|
||||||
|
|
||||||
const { rpcEndpoint, gqlEndpoint, userKey, bondId, chainId } = getConnectionInfo(argv, registryConfig);
|
const { rpcEndpoint, gqlEndpoint, userKey, bondId, chainId } = getConnectionInfo(argv, registryConfig);
|
||||||
|
|
||||||
const registry = new Registry(gqlEndpoint, rpcEndpoint, chainId);
|
const registry = new Registry(gqlEndpoint, rpcEndpoint, chainId);
|
||||||
const fee = getGasAndFees(argv, registryConfig);
|
const fee = getGasAndFees(argv, registryConfig);
|
||||||
|
|
||||||
await fs.readdir(recordsDir, async (err, files) => {
|
// List record files
|
||||||
if (err) {
|
const files = fs.readdirSync(recordsDir);
|
||||||
console.error('Error reading directory:', err);
|
const jsonFiles = files.filter(file => path.extname(file).toLowerCase() === '.json');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter JSON files
|
// Read record from each JSON file
|
||||||
const jsonFiles = files.filter(file => path.extname(file).toLowerCase() === '.json');
|
for (let i = 0; i < jsonFiles.length; i++) {
|
||||||
|
const file = jsonFiles[i];
|
||||||
|
|
||||||
// Read content of each JSON file
|
const filePath = path.resolve(recordsDir, file);
|
||||||
for (let i = 0; i < jsonFiles.length; i++) {
|
const record = readRecord(filePath);
|
||||||
const file = jsonFiles[i];
|
|
||||||
|
|
||||||
const filePath = path.resolve(recordsDir, file);
|
// Publish record
|
||||||
|
const result = await registry.setRecord({ privateKey: userKey, record, bondId }, userKey, fee);
|
||||||
|
|
||||||
let record;
|
console.log(`Published record from ${file}`);
|
||||||
try {
|
txOutput(result, JSON.stringify(result, undefined, 2), argv.output, argv.verbose);
|
||||||
const data = fs.readFileSync(filePath, 'utf8');
|
|
||||||
record = JSON.parse(data);
|
// Find the deployment record using filename
|
||||||
} catch (error) {
|
const deploymentRecordsDir = path.resolve(recordsDir, 'deployments');
|
||||||
console.error(`Error reading file ${file}:`, err);
|
|
||||||
|
if (fs.statSync(deploymentRecordsDir).isDirectory()) {
|
||||||
|
const recordName = path.basename(file, path.extname(file));
|
||||||
|
const deploymentRecordFile = `${recordName}Deployment.json`;
|
||||||
|
const deploymentRecordFilePath = path.resolve(deploymentRecordsDir, deploymentRecordFile);
|
||||||
|
|
||||||
|
// Check if deployment record exists
|
||||||
|
if (fs.existsSync(deploymentRecordFilePath)) {
|
||||||
|
console.log(`Deployment record ${deploymentRecordFile} found`);
|
||||||
|
const deploymentRecord = readRecord(deploymentRecordFilePath);
|
||||||
|
|
||||||
|
// Set watcher field to watcher record id
|
||||||
|
deploymentRecord.watcher = result.id;
|
||||||
|
|
||||||
|
// Publish deployment record
|
||||||
|
const deploymentResult = await registry.setRecord({ privateKey: userKey, record: deploymentRecord, bondId }, userKey, fee);
|
||||||
|
|
||||||
|
console.log(`Published deployment record from ${deploymentRecordFile}`);
|
||||||
|
txOutput(deploymentResult, JSON.stringify(deploymentResult, undefined, 2), argv.output, argv.verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: validate the records using a schema
|
|
||||||
|
|
||||||
const result = await registry.setRecord({ privateKey: userKey, record, bondId }, userKey, fee);
|
|
||||||
|
|
||||||
console.log(`Published record ${file}`);
|
|
||||||
txOutput(result, JSON.stringify(result, undefined, 2), argv.output, argv.verbose);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readRecord (filePath: string): any {
|
||||||
|
let record;
|
||||||
|
try {
|
||||||
|
const data = fs.readFileSync(filePath, 'utf8');
|
||||||
|
record = JSON.parse(data);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error reading file ${filePath}:`, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArgs (): any {
|
function getArgs (): any {
|
||||||
|
Loading…
Reference in New Issue
Block a user