diff --git a/examples/node/2-store-read-file/2mb.jpg b/examples/node/2-store-read-file/2mb.jpg deleted file mode 100644 index d613bf36..00000000 Binary files a/examples/node/2-store-read-file/2mb.jpg and /dev/null differ diff --git a/examples/node/2-store-read-file/index.ts b/examples/node/2-store-read-file/index.ts index 5b6ba0db..8483d96b 100644 --- a/examples/node/2-store-read-file/index.ts +++ b/examples/node/2-store-read-file/index.ts @@ -23,12 +23,12 @@ const dir = path.dirname(fileURLToPath(import.meta.url)); /** * The file to be stored */ -const inputFilePath = path.resolve(dir, '2mb.jpg'); +const inputFilePath = path.resolve(dir, '../assets/nature.jpg'); /** * The path to store the downloaded file */ -const outputFilePath = path.resolve(dir, '2mb-downloaded.jpg'); +const outputFilePath = path.resolve(dir, '../assets/nature-downloaded.jpg'); /** * Create a DDC client instance and connect it to DDC TESTNET diff --git a/examples/node/5-use-exported-account/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json b/examples/node/5-use-exported-account/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json new file mode 100644 index 00000000..fd214064 --- /dev/null +++ b/examples/node/5-use-exported-account/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json @@ -0,0 +1,6 @@ +{ + "encoded": "kBkc/6ghJVs4thxE7ZMSRhxyVtYi2EzjJz8gvI2HfKQAgAAAAQAAAAgAAAAs5o9q7l+BpKkYsTXvuroLsxdysjikaK8qRkm13kzbnCfG5t9Df2QnQfHxrYyboPp5SoGdKxhnz5HRLK4/Fq1wPZpk43XSaa/b4PxOphxLfFYdjG2MJt80QSIzzRrP6TNj6R/YfMsKSySGqYHgiOkVnJJyZq0Exc35+3W6CyESzciXzDIw2iYzNdV5CJWpiAtgnW7tHxmsldKhUmYf", + "encoding": { "content": ["pkcs8", "ed25519"], "type": ["scrypt", "xsalsa20-poly1305"], "version": "3" }, + "address": "5EdskhqqsNCUABVFhsZkxXfG2p4sRtf9ChU9iC5pE9bhx1kP", + "meta": {} +} diff --git a/examples/node/5-use-exported-account/index.ts b/examples/node/5-use-exported-account/index.ts new file mode 100644 index 00000000..2b1983d0 --- /dev/null +++ b/examples/node/5-use-exported-account/index.ts @@ -0,0 +1,31 @@ +import { DdcClient, File, TESTNET, JsonSigner } from '@cere-ddc-sdk/ddc-client'; +import * as fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +// The wallet should have enough CERE to pay for the transaction fees +const pathToAccount = './6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json'; +const accountPassphrase = '1234'; + +// The DDC bucket where the file will be stored +const bucketId = BigInt(448920); + +// Detect the current directory +const dir = path.dirname(fileURLToPath(import.meta.url)); + +// Create DDC client instance using JSON account exported from Cere Wallet +const keyringPair = JSON.parse(fs.readFileSync(path.resolve(dir, pathToAccount)).toString()); +const jsonSigner = new JsonSigner(keyringPair, { passphrase: accountPassphrase }); +const client = await DdcClient.create(jsonSigner, TESTNET); + +// Upload file +const pathToFileToUpload = path.resolve(dir, '../assets/nature.jpg'); +const fileToUpload = new File(fs.createReadStream(pathToFileToUpload), { size: fs.statSync(pathToFileToUpload).size }); +const uploadedFileUri = await client.store(bucketId, fileToUpload); +console.log( + 'The file can be accessed by this URL', + `https://cdn.testnet.cere.network/${bucketId}/${uploadedFileUri.cid}`, +); +console.log('File stored into bucket', bucketId, 'with CID', uploadedFileUri.cid); + +await client.disconnect(); diff --git a/examples/node/6-developer-console-compatibility/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json b/examples/node/6-developer-console-compatibility/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json new file mode 100644 index 00000000..fd214064 --- /dev/null +++ b/examples/node/6-developer-console-compatibility/6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json @@ -0,0 +1,6 @@ +{ + "encoded": "kBkc/6ghJVs4thxE7ZMSRhxyVtYi2EzjJz8gvI2HfKQAgAAAAQAAAAgAAAAs5o9q7l+BpKkYsTXvuroLsxdysjikaK8qRkm13kzbnCfG5t9Df2QnQfHxrYyboPp5SoGdKxhnz5HRLK4/Fq1wPZpk43XSaa/b4PxOphxLfFYdjG2MJt80QSIzzRrP6TNj6R/YfMsKSySGqYHgiOkVnJJyZq0Exc35+3W6CyESzciXzDIw2iYzNdV5CJWpiAtgnW7tHxmsldKhUmYf", + "encoding": { "content": ["pkcs8", "ed25519"], "type": ["scrypt", "xsalsa20-poly1305"], "version": "3" }, + "address": "5EdskhqqsNCUABVFhsZkxXfG2p4sRtf9ChU9iC5pE9bhx1kP", + "meta": {} +} diff --git a/examples/node/6-developer-console-compatibility/README.md b/examples/node/6-developer-console-compatibility/README.md new file mode 100644 index 00000000..448f8498 --- /dev/null +++ b/examples/node/6-developer-console-compatibility/README.md @@ -0,0 +1,8 @@ +# Developer console compatibility + +You can use this guide if you want your files uploaded via SDK to be visible in Developer Console. + +By default, files uploaded to DDC aren't indexed. +Once you uploaded file to DDC you receive it's CID a unique hash-based identifier so later you can access your file using bucket id and CID. + +In order to have a folder structure (hierarchy) Developer Console uses DAG API. That API allows us to structure set of files if a folder hierarchy where each folder is a separate DAG node. So when client uploads a file or creates a folder the all DAG node above it are updated as well. diff --git a/examples/node/6-developer-console-compatibility/index.ts b/examples/node/6-developer-console-compatibility/index.ts new file mode 100644 index 00000000..299ef713 --- /dev/null +++ b/examples/node/6-developer-console-compatibility/index.ts @@ -0,0 +1,54 @@ +import { DdcClient, File, Link, DagNodeUri, DagNode, JsonSigner, TESTNET } from '@cere-ddc-sdk/ddc-client'; +import * as fs from 'fs'; +import { fileURLToPath } from 'url'; +import path from 'path'; + +// The wallet should have enough CERE to pay for the transaction fees +const pathToAccount = './6S5nrcLgUrhC2tLpaG83VLrMndnQ66DPTz7j6PoRnQjZKpvx.json'; +const accountPassphrase = '1234'; + +// The DDC bucket where the file will be stored +const bucketId = BigInt(448924); + +// Detect the current directory +const dir = path.dirname(fileURLToPath(import.meta.url)); + +const pathToFileToUpload = path.resolve(dir, '../assets/nature.jpg'); +const fileName = pathToFileToUpload.substring(pathToFileToUpload.lastIndexOf('/') + 1); + +// Initialise client using JSON account exported from Cere Wallet +const keyringPair = JSON.parse(fs.readFileSync(path.resolve(dir, pathToAccount)).toString()); +const jsonSigner = new JsonSigner(keyringPair, { passphrase: accountPassphrase }); +const client = await DdcClient.create(jsonSigner, { ...TESTNET, logLevel: 'fatal' }); + +// Upload file +const fileSize = fs.statSync(pathToFileToUpload).size; +const fileToUpload = new File(fs.createReadStream(pathToFileToUpload), { + size: fileSize, +}); +const uploadedFileUri = await client.store(bucketId, fileToUpload); +console.log('File stored into bucket', bucketId, 'with CID', uploadedFileUri.cid); +console.log( + 'The file can be accessed by this URL', + `https://cdn.testnet.cere.network/${bucketId}/${uploadedFileUri.cid}`, +); + +// Attach uploaded file to 'fs' DAG node (where 'fs' is a CNS name used by Developer Console to index files) +const filePathInDeveloperConsole = 'photos/nature/'; +const rootDagNode = await client.read(new DagNodeUri(bucketId, 'fs'), { cacheControl: 'no-cache' }).catch((res) => { + if (res.message == 'Cannot resolve CNS name: "fs"') { + return new DagNode(null); + } else { + throw new Error("Failed to fetch 'fs' DAG node"); + } +}); +rootDagNode.links.push(new Link(uploadedFileUri.cid, fileSize, filePathInDeveloperConsole + fileName)); +await client.store(bucketId, rootDagNode, { name: 'fs' }); +console.log( + 'The file can be found in developer console in bucket', + bucketId, + 'and path is', + filePathInDeveloperConsole, +); + +await client.disconnect(); diff --git a/examples/node/README.md b/examples/node/README.md index 73466ad4..fd196eb2 100644 --- a/examples/node/README.md +++ b/examples/node/README.md @@ -6,6 +6,8 @@ This examples directory contains several common DDC SDK use-cases for NodeJs app - [How to store and read a file](./2-store-read-file/index.ts) - [How to upload a website](./3-upload-website/index.ts) - [How to stream events](./4-store-read-events/index.ts) +- [How to use exported account (Cere Wallet)](./5-use-exported-account/index.ts) +- [How to index files so that they are visible in Developer Console](./6-developer-console-compatibility/index.ts) ## Quick start @@ -32,13 +34,13 @@ Run the following commands from the project root 4. Go to `examples` directory ```bash - cd ./examples + cd ./examples/node ``` 5. Run an example ```bash - npm run example:1 # can be 1-4 + npm run example:1 # can be 1-6 ``` diff --git a/examples/node/assets/nature.jpg b/examples/node/assets/nature.jpg new file mode 100644 index 00000000..9b8fdb34 Binary files /dev/null and b/examples/node/assets/nature.jpg differ diff --git a/examples/node/package.json b/examples/node/package.json index bbada09f..9fbfcccd 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -7,7 +7,9 @@ "example:1": "ts-node --esm ./1-create-bucket/index.ts", "example:2": "ts-node --esm ./2-store-read-file/index.ts", "example:3": "ts-node --esm ./3-upload-website/index.ts", - "example:4": "ts-node --esm ./4-store-read-events/index.ts" + "example:4": "ts-node --esm ./4-store-read-events/index.ts", + "example:5": "ts-node --esm ./5-use-exported-account/index.ts", + "example:6": "ts-node --esm ./6-developer-console-compatibility/index.ts" }, "dependencies": { "@cere-ddc-sdk/ddc-client": "2.13.0",