This is an automated email from the ASF dual-hosted git repository. apratim pushed a commit to branch resilient-app-blog in repository https://gitbox.apache.org/repos/asf/incubator-resilientdb-blog.git
commit 1e8a2fc89f60edc74bfb10b3778ab285fc83c100 Author: Apratim Shukla <[email protected]> AuthorDate: Fri Mar 14 00:18:16 2025 -0700 Added Resilient App Blog --- _posts/2023-09-21-ResVault.md | 262 ----------------- _posts/2025-03-13-ResVault.md | 632 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 632 insertions(+), 262 deletions(-) diff --git a/_posts/2023-09-21-ResVault.md b/_posts/2023-09-21-ResVault.md deleted file mode 100644 index 5ac4ab7..0000000 --- a/_posts/2023-09-21-ResVault.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -layout: article -title: Getting started with ResVault -author: Apratim Shukla -tags: NexRes Wallet ResVault ResilientDBGraphQL -aside: - toc: true -article_header: - type: overlay - theme: dark - background_color: '#000000' - background_image: - gradient: 'linear-gradient(135deg, rgba(0, 204, 154 , .2), rgba(51, 154, 154, .2))' - src: /assets/images/resdb-gettingstarted/code_close_up.jpeg - ---- - -ResVault is a chrome extension that serves as a wallet for ResilientDB. The wallet allows you to commit and retrieve data from ResilientDB and provides user account creation and deletion. It communicates with ResilientDB using the ResilientDB GraphQL server and enables transaction logging. - -# Prerequisites -### Setup Python3.10 -Ensure you have Python3.10, otherwise download it and set it up as default. -- Check with: - > python3 --version - -### Setup ResilientDB -- You will need to clone the ResilientDB repo to get started: - > git clone https://github.com/resilientdb/resilientdb.git - -- Then navigate inside the ResilientDB directory: - > cd resilientdb - -- Install dependencies: - > sh INSTALL.sh - -- Run ResilientDB KV Service (this may take a few minutes for the first time): - > ./service/tools/kv/server_tools/start_kv_service.sh - -### Setup Crow HTTP server, SDK, and GraphQL server -- You will need to clone the ResilientDB GraphQL repo to get started: - > git clone https://github.com/ResilientApp/ResilientDB-GraphQL.git - -- Then navigate inside the ResilientDBGraphQL directory: - > cd ResilientDB-GraphQL - -- Install the Crow dependencies: - > sudo apt update - > sudo apt install build-essential - > sudo apt install python3.10-dev - > sudo apt install apt-transport-https curl gnupg - -- Build Crow HTTP server (this may take a few minutes for the first time): - > bazel build service/http_server:crow_service_main - -- Start the Crow HTTP server: - > bazel-bin/service/http_server/crow_service_main service/tools/config/interface/client.config service/http_server/server_config.config - -- Create virtual environment for the Python SDK: - > python3 -m venv venv --without-pip - -- Activate the virtual environment: - > source venv/bin/activate - -- Install pip in the virtual environment for the Python dependencies: - > curl https://bootstrap.pypa.io/get-pip.py \| python - -- Install the Python dependencies: - > pip install -r requirements.txt - -- Start the GraphQL server. (The GraphQL is implemented based on our Python SDK. For more information about the Python SDK, please refer to our SDK [blog](https://blog.resilientdb.com/2023/02/01/UsingPythonSDK.html)) - > python3 app.py - -# Setup Wallet -### Build from source code -You can generate the wallet build using the ResVault source code. To do this: -- Download NodeJS from [here](https://nodejs.org/en/download) and ensure that it's added to PATH. - -- Clone the ResVault repo to get started: - > git clone https://github.com/ResilientApp/ResVault.git - -- Then navigate inside the ResVault directory: - > cd ResVault - -- Install the dependencies. - > npm install - -- Build the wallet. - > npm run build - -- You will see the following message if build was successful: - ``` - The build folder is ready to be deployed. - You may serve it with a static server: - - serve -s build - - Find out more about deployment here: - - https://cra.link/deployment - ``` -- The build will now be available in `build` directory inside the ResVault directory. - -### Add build to chrome -Once you have generated the build: -- Open chrome and navigate to `chrome://extensions/` - -- Make sure developer mode is enabled using the toggle button. - -- Finally, load the extension by clicking on load unpacked button and then select the `build` folder that was created in the previous step. - -- Now you can open the wallet from the extension button and start using it! - -### Add release to chrome -Alternatively, you can use the release from the ResVault repo instead of generating your own build. To do this: - -- Download the latest build.zip from [here](https://github.com/ResilientApp/ResVault/releases). - -- Extract the contents in a new directory. - -- Open chrome and navigate to `chrome://extensions/` - -- Make sure developer mode is enabled using the toggle button. - -- Finally, load the extension by clicking on load unpacked button and then select the directory where you extracted the contents previously. - -- Now you can open the wallet from the extension button and start using it! - -# Usage -In order to use the ResVault chrome extension ensure that you have KV service, Crow HTTP server, and ResilientDB GraphQL server running in the terminal windows: - -- One terminal window should run: `bazel-bin/service/http_server/crow_service_main service/tools/config/interface/service.config service/http_server/server_config.config` after navigating inside the ResilientDB GraphQL directory. - -- The other terminal window should run: `./service/tools/kv/server_tools/start_kv_service.sh` after navigating inside the ResilientDB directory. - -- The final terminal window should run: `python3 app.py` after navigating inside the ResilientDB GraphQL directory. - -### GraphQL playground -Additionally, you can also experiment with the deployed instance of ResilientDB on <a href="https://cloud.resilientdb.com/graphql">https://cloud.resilientdb.com/graphql</a> - -#### Example Mutations -- Generate Keys - ``` - mutation { generateKeys { - publicKey - privateKey - } - } - ``` - -- Set Transaction - ``` - mutation { postTransaction(data: { - operation: "CREATE" - amount: 50 - signerPublicKey: "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" - signerPrivateKey: "5R4ER6smR6c6fsWt3unPqP6Rhjepbn82Us7hoSj5ZYCc" - recipientPublicKey: "ECJksQuF9UWi3DPCYvQqJPjF6BqSbXrnDiXUjdiVvkyH" - asset: """{ - "data": { "time": 1690881023169 - }, - }""" - }) { - id - } - } - ``` - -- Update Transaction - ``` - mutation { updateTransaction(data:{ - id: "a534f09b6983492f05c19c8a35024ca7109511f2057ae54b18b6bfd1b6d13af6" - operation: "" - amount: 70 - signerPublicKey: "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" - signerPrivateKey: "5R4ER6smR6c6fsWt3unPqP6Rhjepbn82Us7hoSj5ZYCc" - recipientPublicKey: "ECJksQuF9UWi3DPCYvQqJPjF6BqSbXrnDiXUjdiVvkyH" - asset: "" - }) { - id - version - amount - metadata - operation - asset - publicKey - uri - type - } - } - ``` - -- Update Multiple Transactions - ``` - mutation { updateMultipleTransaction(data:[{ - id: "a534f09b6983492f05c19c8a35024ca7109511f2057ae54b18b6bfd1b6d13af6" - signerPublicKey: "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" - signerPrivateKey: "5R4ER6smR6c6fsWt3unPqP6Rhjepbn82Us7hoSj5ZYCc" - operation: "" - amount: 40 - asset: "" - recipientPublicKey: "" - }, - { id: "b8e5173634eb0e0ce3dae30fc6b2a97987623e48231524aaf90a6e028ff048ee" - signerPublicKey: "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" - signerPrivateKey: "5R4ER6smR6c6fsWt3unPqP6Rhjepbn82Us7hoSj5ZYCc" - operation: "" - amount: 54 - asset: "" - recipientPublicKey: ""}]) { - id - version - amount - metadata - operation - asset - publicKey - uri - type - } - } - ``` -#### Example Queries -- Get Transaction - ``` - query {getTransaction(id: "a534f09b6983492f05c19c8a35024ca7109511f2057ae54b18b6bfd1b6d13af6") { - id - version - amount - metadata - operation - asset - publicKey - uri - type - signerPublicKey - }} - ``` - -- Get Filtered Transactions - ``` - query { getFilteredTransactions(filter: { - ownerPublicKey: "" - recipientPublicKey: "" - }) { - id - version - amount - metadata - operation - asset - publicKey - uri - type - } - } - ``` - -#### Demo video -Now you can use ResVault as shown in the video: -<iframe width="560" height="315" src="https://www.youtube.com/embed/NN9mK39gvmE?si=aWnudnwHMqpaz-iu" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> - -The next tutorial will elaborate on how to develop web applications to communicate with the wallet. \ No newline at end of file diff --git a/_posts/2025-03-13-ResVault.md b/_posts/2025-03-13-ResVault.md new file mode 100644 index 0000000..411ae3a --- /dev/null +++ b/_posts/2025-03-13-ResVault.md @@ -0,0 +1,632 @@ +--- +layout: article +title: Building Resilient Apps with ResilientDB +author: Apratim Shukla +tags: ResilientDB-Fullstack Wallet ResVault ResilientDBGraphQL +aside: + toc: true +article_header: + type: overlay + theme: dark + background_color: '#000000' + background_image: + gradient: 'linear-gradient(135deg, rgba(0, 204, 154 , .2), rgba(51, 154, 154, .2))' + src: /assets/images/resdb-gettingstarted/code_close_up.jpeg + +--- + +The ResilientDB Fullstack makes it easy to build and interact with blockchain-powered applications. At its core, it uses ResilientDB for high-speed transaction processing and ResVault as a wallet interface for seamless interactions. Web apps can connect effortlessly using the ResVault web SDK, while developers also get SDK support for Python, Rust, and TypeScript, making it simple to integrate ResilientDB into different applications. Whether you're building for the web or other platforms [...] + +### Core Components of a Resilient App +- **Your Decentralized App (dApp)** – Built on ResilientDB to enable trustless, high-throughput transactions. +- **ResVault** – A secure wallet interface that connects users to your dApp via the ResVault web SDK. +- **ResilientDB GraphQL Server** – Provides an intuitive API layer for interacting with blockchain data. +- **ResilientDB KV/Smart Contract Service** – A robust key-value store and smart contract execution engine, combined with Crow HTTP Server and SDK support for Python, TypeScript, and Rust. + + + +# Prerequisites + +- Docker - [Setup Instructions](https://docs.docker.com/get-started/) + +## Setting Up ResilientDB in Minutes + +Getting started with ResilientDB is incredibly simple with ResilientDB-Ansible, which automates the setup of the Crow HTTP server and GraphQL API. A cross-platform GUI installer with Tauri is also in the works to make deployment even easier. + +#### Quick Setup Instructions + +- Clone the ResilientDB-Ansible repository: +```bash +git clone https://github.com/ResilientEcosystem/resilientdb-ansible +cd resilientdb-ansible +``` + +- Build the Docker image: +```bash +docker build -t resilientdb-ansible . +``` + +- Run the container with required privileges: +```bash +docker run --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 -p 18000:18000 -p 8000:8000 resilientdb-ansible +``` + +Once the container is running, you can access: + +- ResilientDB Crow HTTP Server at http://localhost/crow (Exposed port **18000**) +- ResilientDB GraphQL API at http://localhost/graphql (Exposed port **8000**) + +This setup automatically configures ResilientDB with 4 replicas and 1 client, with Nginx handling routing inside the container. + +## Set Up ResVault: Your Gateway to ResilientDB + +ResVault is a Chrome extension wallet for ResilientDB, allowing users to commit and retrieve data, manage accounts, and track transactions, all through the ResilientDB GraphQL server. Think of it as Metamask for ResilientDB, but tailored for high-throughput blockchain applications. + +### Build ResVault from Source + +#### Prerequisite + +You need Node.js **v16.20.2** for the build. The recommended way to manage multiple Node.js versions is using [nvm](https://github.com/nvm-sh/nvm). + +#### Clone the ResVault Repository + +```bash +git clone https://github.com/apache/incubator-resilientdb-resvault +cd incubator-resilientdb-resvault +``` + +#### Install Dependencies +```bash +npm install +``` + +#### Build the Wallet +```bash +npm run build +``` + +#### Verify Successful Build +If everything goes well, you'll see this message: + +```bash +The build folder is ready to be deployed. +You may serve it with a static server: + + serve -s build + +Find out more about deployment here: + + https://cra.link/deployment +``` + +The wallet build will be available in the build directory inside `incubator-resilientdb-resvault` + +Now, you're all set to use ResVault as your secure wallet for ResilientDB transactions! + +### Add build to chrome +Once you have generated the build: +- Open chrome and navigate to `chrome://extensions/` + +- Make sure developer mode is enabled using the toggle button. + +- Finally, load the extension by clicking on load unpacked button and then select the `build` directory that was created in the previous step. + +- Now you can open the wallet from the extension button and start using it! + +## Integrating ResVault SDK with Your Resilient App + +If you’re looking for the simplest way to build a ResilientDB-powered React or Vue application with [ResVault SDK](https://www.npmjs.com/package/resvault-sdk) integration, `create-resilient-app` is the tool for you! + +### Why Use `create-resilient-app`? + +- Scaffold a new ResilientDB app with React or Vue in seconds. +- Supports both JavaScript and TypeScript for flexibility. +- Automatically integrates ResVault SDK, so you can start interacting with ResilientDB right away. +- No manual setup, just run a single command! + +#### Installation & Setup + +You don’t need to install anything globally. Just run: +```bash +npx create-resilient-app +``` + +Running the command without any flags will launch an interactive prompt. + +You'll be asked: +- **Project Name** – Give your app a name. +- **Framework** – Choose between React or Vue. +- **Language** – Choose between JavaScript or TypeScript. + +#### One-Command Setup + +Skip the prompts by specifying options directly: + +```bash +npx create-resilient-app --name my-app --framework react --language typescript +``` + +#### Example Commands + +Create a React app with TypeScript: +```bash +npx create-resilient-app --name my-react-app --framework react --language typescript +``` + +Create a Vue app with JavaScript: +```bash +npx create-resilient-app --name my-vue-app --framework vue --language javascript +``` + +#### Project Setup & Running + +After the project is generated, navigate to your project directory: + +```bash +cd my-app +``` + +Then install the required dependencies: + +```bash +npm install +``` + +#### Start Your Project + +For React: +```bash +npm start +``` + +For Vue: +```bash +npm run dev +``` + +Now, you can customize your app and start building powerful ResilientDB-powered decentralized applications. + + + +## Next Steps: Connect Your Resilient App to ResVault + +Now that you’ve set up your first Resilient App, it’s time to connect it to ResVault and start interacting with ResilientDB. + +#### Open Your Resilient App + + - Navigate to your Resilient App in your browser. + +#### Open ResVault & Create an Account + +- Open the ResVault extension in your browser. + +- If you haven’t created an account yet, set a secure password and let ResVault generate your keys securely. + + + +#### Choose a Network in ResVault and Connect + +- Once at the ResVault Dashboard, click the dropdown menu at the top. + +- By default, it is set to ResilientDB Mainnet, which connects to ResilientDB Cloud ([cloud.resilientdb.com/graphql](https://cloud.resilientdb.com/graphql)). + +- If you are running ResilientDB locally, select ResilientDB Localnet from the dropdown. + +- On the right side of the dropdown, you’ll see a site icon, click on it once to connect ResVault to your Resilient App. + + + +#### Click "Sign In Via ResVault" in Your Resilient App + +- Inside your Resilient App, click Sign In Via ResVault. + +- ResVault will prompt you to approve the transaction. + +- Once approved, ResVault will sign the transaction using your keys and send it to ResilientDB. + +- Your app will receive a callback confirming successful authentication and will be redirected to the authenticated page. + +- Now, you can send more transactions by submitting the form inside the authenticated page (with any JSON data as well). + + + +#### Submit Transactions from the Authenticated Page + +- Now that you’re authenticated, you can send more transactions using the form inside the authenticated page. + +- The form allows you to submit any JSON data, which will be securely signed and sent to ResilientDB. + + + +You’re now fully connected to ResilientDB via ResVault! Whether on Mainnet (Cloud) or Localnet, you can authenticate, send transactions, and interact with decentralized applications seamlessly. + +## Client-Side Indexing Support in ResilientDB for Filtering in Your Resilient App + +When building ResilientDB-powered applications, efficient data retrieval is crucial. If your Resilient App needs a filtering functionality, you can index ResilientDB transaction data on the client side using MongoDB. This tutorial will guide you through setting up real-time synchronization with MongoDB using ResilientDB's WebSocket and HTTP APIs for efficient querying. + +### Prerequisites + +- MongoDB - [Setup Instructions](https://www.mongodb.com/docs/manual/installation/) + +### Why Client-Side Indexing? + +- Efficient filtering of ResilientDB transactions for dApps. + +- Real-time sync using WebSocket and HTTP. + +- Query transactions based on public keys, timestamps, asset JSON, or metadata. + +- Automatic reconnection, batching, and concurrency handling. + +### Syncing ResilientDB Data to MongoDB for Efficient Filtering + +#### Install the Required Library + +For Node.js, install: + +```bash +npm install resilient-node-cache +``` + +For Python, install: + +```bash +pip install resilient-python-cache +``` + +#### Configure MongoDB and ResilientDB + +Before syncing, ensure MongoDB is running and configure your connection settings: + +- Node.js Configuration (`sync.js`) + +```JavaScript +const { WebSocketMongoSync } = require('resilient-node-cache'); + +const mongoConfig = { + uri: 'mongodb://localhost:27017', + dbName: 'myDatabase', + collectionName: 'myCollection', +}; + +/* resilientdb://localhost/crow to sync localnet */ +const resilientDBConfig = { + baseUrl: 'resilientdb://crow.resilientdb.com', + httpSecure: true, + wsSecure: true, +}; + +const sync = new WebSocketMongoSync(mongoConfig, resilientDBConfig); + +sync.on('connected', () => { + console.log('WebSocket connected.'); +}); + +sync.on('data', (newBlocks) => { + console.log('Received new blocks:', newBlocks); +}); + +sync.on('error', (error) => { + console.error('Error:', error); +}); + +sync.on('closed', () => { + console.log('Connection closed.'); +}); + +(async () => { + try { + await sync.initialize(); + console.log('Synchronization initialized.'); + } catch (error) { + console.error('Error during sync initialization:', error); + } +})(); +``` + +- Python Configuration (`sync.py`) + +```python +import asyncio +from resilient_python_cache import ResilientPythonCache, MongoConfig, ResilientDBConfig + +async def main(): + mongo_config = MongoConfig( + uri="mongodb://localhost:27017", + db_name="myDatabase", + collection_name="myCollection" + ) + + # resilientdb://localhost/crow to sync localnet + resilient_db_config = ResilientDBConfig( + base_url="resilientdb://crow.resilientdb.com", + http_secure=True, + ws_secure=True + ) + + cache = ResilientPythonCache(mongo_config, resilient_db_config) + + cache.on("connected", lambda: print("WebSocket connected.")) + cache.on("data", lambda new_blocks: print("Received new blocks:", new_blocks)) + cache.on("error", lambda error: print("Error:", error)) + cache.on("closed", lambda: print("Connection closed.")) + + try: + await cache.initialize() + print("Synchronization initialized.") + await asyncio.Future() # Run indefinitely + except Exception as error: + print("Error during sync initialization:", error) + finally: + await cache.close() + +if __name__ == "__main__": + asyncio.run(main()) +``` + +#### Fetch Transactions by Public Key + +Once transactions are synced to MongoDB, you can query them efficiently using the public key of the owner. + +- Node.js Query (`fetchTransactions.js`) + +```JavaScript +const { MongoClient } = require('mongodb'); + +const mongoConfig = { + uri: 'mongodb://localhost:27017', + dbName: 'myDatabase', + collectionName: 'myCollection', +}; + +const targetPublicKey = "8LUKr81SmkdDhuBNAHfH9C8G5m6Cye2mpUggVu61USbD"; + +(async () => { + const client = new MongoClient(mongoConfig.uri); + + try { + await client.connect(); + const db = client.db(mongoConfig.dbName); + const collection = db.collection(mongoConfig.collectionName); + + console.log('Connected to MongoDB for fetching transactions.'); + + // Create an index for faster querying + const indexName = await collection.createIndex({ "transactions.value.inputs.owners_before": 1 }); + console.log(`Index created: ${indexName}`); + + const pipeline = [ + { $unwind: "$transactions" }, + { $unwind: "$transactions.value.inputs" }, + { $match: { "transactions.value.inputs.owners_before": targetPublicKey } }, + { $sort: { "transactions.value.asset.data.timestamp": -1 } }, + { $project: { transaction: "$transactions", _id: 0 } } + ]; + + const transactions = await collection.aggregate(pipeline).toArray(); + console.log(`Transactions:`, JSON.stringify(transactions, null, 2)); + + } catch (error) { + console.error('Error fetching transactions:', error); + } finally { + await client.close(); + } +})(); +``` + +- Python Query (`fetch_transactions.py`) + +```Python +from pymongo import MongoClient + +mongo_config = { + "uri": "mongodb://localhost:27017", + "db_name": "myDatabase", + "collection_name": "myCollection", +} + +target_public_key = "8LUKr81SmkdDhuBNAHfH9C8G5m6Cye2mpUggVu61USbD" + +client = MongoClient(mongo_config["uri"]) +db = client[mongo_config["db_name"]] +collection = db[mongo_config["collection_name"]] + +print("Connected to MongoDB for fetching transactions.") + +# Create an index for optimized querying +index_name = collection.create_index("transactions.value.inputs.owners_before") +print(f"Index created: {index_name}") + +# Define aggregation pipeline to fetch transactions by public key +pipeline = [ + {"$unwind": "$transactions"}, + {"$unwind": "$transactions.value.inputs"}, + {"$match": {"transactions.value.inputs.owners_before": target_public_key}}, + {"$sort": {"transactions.value.asset.data.timestamp": -1}}, + {"$project": {"transaction": "$transactions", "_id": 0}} +] + +transactions = list(collection.aggregate(pipeline)) + +if transactions: + print("Transactions:", transactions) +else: + print(f"No transactions found for publicKey: {target_public_key}") + +client.close() +``` + +Now, your Resilient App can efficiently filter transactions based on user-specific data without slow queries to the blockchain. + +## Using ResilientDB GraphQL for Transactions and Queries + +ResilientDB provides a **GraphQL API** for seamless interaction with the blockchain, allowing you to send transactions and fetch transaction details efficiently. + +### **Accessing ResilientDB GraphQL** + +- **For Localnet:** ResilientDB GraphQL is available at: + ``` + http://localhost/graphql + ``` +- **For Mainnet (ResilientDB Cloud):** + ``` + https://cloud.resilientdb.com/graphql + ``` + +**ResVault** uses this GraphQL API internally to send transactions using stored keys. You can also use it directly in your application. + +--- + +### **Sending a Transaction via GraphQL** + +You can send a transaction to **ResilientDB** using the `postTransaction` mutation. + +### **Mutation Example** +```graphql +mutation { + postTransaction(data: { + operation: "CREATE" + amount: 50632 + signerPublicKey: "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" + signerPrivateKey: "5R4ER6smR6c6fsWt3unPqP6Rhjepbn82Us7hoSj5ZYCc" + recipientPublicKey: "ECJksQuF9UWi3DPCYvQqJPjF6BqSbXrnDiXUjdiVvkyH" + asset: { + data: { + time: 1690881023169 + } + } + }) { + id + } +} +``` +### **Explanation:** +- **operation:** `"CREATE"` defines the type of transaction. +- **amount:** `50632` specifies the transaction value. +- **signerPublicKey & signerPrivateKey:** Used for transaction signing. +- **recipientPublicKey:** Defines the recipient of the transaction. +- **asset:** Stores additional transaction data (any JSON). + +**🔹 Expected Response:** +```json +{ + "data": { + "postTransaction": { + "id": "f1df753f782dccd7e345175f67a3f8026113b1074724b202f24aa9073644ab47" + } + } +} +``` +The response includes the **transaction ID**, which can be used to fetch details later. + +## **Fetching a Transaction by ID** + +You can retrieve transaction details using the `getTransaction` query. + +### **Query Example** +```graphql +query { + getTransaction(id: "f1df753f782dccd7e345175f67a3f8026113b1074724b202f24aa9073644ab47") { + id + version + amount + metadata + operation + asset + publicKey + uri + type + signerPublicKey + } +} +``` + +### **Explanation:** +- **id:** Transaction ID (retrieved from the previous mutation). + +**Expected Response:** +```json +{ + "data": { + "getTransaction": { + "id": "f1df753f782dccd7e345175f67a3f8026113b1074724b202f24aa9073644ab47", + "version": "2.0", + "amount": 50632, + "metadata": null, + "operation": "CREATE", + "asset": { + "data": { + "time": 1690881023169 + } + }, + "publicKey": "ECJksQuF9UWi3DPCYvQqJPjF6BqSbXrnDiXUjdiVvkyH", + "uri": "ni:///sha-256;ORrcs4QnlphyiTL69-rcLNPNV_SfaCgmg7ywRhGgYBM?fpt=ed25519-sha-256&cost=131072", + "type": "ed25519-sha-256", + "signerPublicKey": "8fPAqJvAFAkqGs8GdmDDrkHyR7hHsscVjes39TVVfN54" + } + } +} +``` + +--- + +## **ResilientDB GraphQL Schema Overview** +ResilientDB currently supports: + +### **Mutation: `postTransaction`** +```graphql +postTransaction(data: PrepareAsset!): CommitTransaction! +``` +#### **PrepareAsset Fields:** +| Field | Type | Description | +|---------------------|----------|-------------| +| operation | String! | The type of transaction (CREATE) | +| amount | Int! | The amount associated with the transaction | +| signerPublicKey | String! | Public key of the sender | +| signerPrivateKey | String! | Private key for signing the transaction | +| recipientPublicKey | String! | Public key of the recipient | +| asset | JSONScalar! | Additional transaction data (any JSON) | + +#### **CommitTransaction Response Fields:** +| Field | Type | Description | +|-------|--------|-------------| +| id | String! | Unique transaction ID | + + +### **Query: `getTransaction`** +```graphql +getTransaction(id: ID!): RetrieveTransaction! +``` +#### **RetrieveTransaction Response Fields:** +| Field | Type | Description | +|-----------------|----------|-------------| +| id | String! | Transaction ID | +| version | String! | Version of the transaction | +| amount | String! | Transaction amount | +| uri | String! | URI (if applicable) | +| type | String! | Type of transaction | +| publicKey | String! | Public key associated with the transaction | +| operation | String! | Type of operation (CREATE) | +| metadata | String | Optional metadata | +| asset | JSONScalar! | Transaction asset data (any JSON) | +| signerPublicKey | String! | Public key of the signer | + + +**Note:** Two transactions will have identical IDs if all the fields in the postTransaction mutation are exactly the same. This is because ResilientDB deterministically generates transaction IDs based on the input fields, ensuring consistency across identical transactions. + +#### **What You Can Do with ResilientDB GraphQL** + +- **Send transactions** using `postTransaction`. + +- **Retrieve transactions** by ID using `getTransaction`. + +- **Use it in ResVault** for transaction signing. + +- **Directly interact with ResilientDB** via GraphQL instead of manually handling HTTP requests. + +**Congratulations! Your first Resilient App now has all the essential components set up! You’re now ready to build, authenticate, and interact seamlessly with ResilientDB. Happy coding!** + +--- + +#### Demo video +Coming soon!
