diff --git a/.github/grpc-queries-cache.json b/.github/grpc-queries-cache.json
index 33fa12dbe1c..ed3e6d2954a 100644
--- a/.github/grpc-queries-cache.json
+++ b/.github/grpc-queries-cache.json
@@ -116,7 +116,7 @@
"status": "implemented"
},
"getTokenContractInfo": {
- "status": "not_implemented"
+ "status": "implemented"
},
"getTokenPreProgrammedDistributions": {
"status": "not_implemented"
@@ -143,5 +143,5 @@
"status": "not_implemented"
}
},
- "last_updated": "2025-01-06T00:00:00Z"
+ "last_updated": "2025-07-14T03:27:11.465612"
}
\ No newline at end of file
diff --git a/.github/scripts/check-grpc-coverage.py b/.github/scripts/check-grpc-coverage.py
index 97c9adf351f..62681b849e7 100755
--- a/.github/scripts/check-grpc-coverage.py
+++ b/.github/scripts/check-grpc-coverage.py
@@ -170,6 +170,28 @@ def save_cache(cache_file, cache_data):
json.dump(cache_data, f, indent=2)
+def check_wasm_sdk_documentation():
+ """Check WASM SDK documentation completeness"""
+ wasm_sdk_path = Path(__file__).parent.parent.parent / 'packages' / 'wasm-sdk'
+ check_script = wasm_sdk_path / 'check_documentation.py'
+
+ if not check_script.exists():
+ return True, [] # Skip if WASM SDK doesn't have the check script
+
+ # Run the documentation check
+ import subprocess
+ result = subprocess.run(['python3', str(check_script)], cwd=wasm_sdk_path, capture_output=True, text=True)
+
+ # Parse the output to find errors
+ errors = []
+ if result.returncode != 0:
+ output_lines = result.stdout.strip().split('\n')
+ for line in output_lines:
+ if line.startswith('ERROR:'):
+ errors.append(line)
+
+ return result.returncode == 0, errors
+
def main():
"""Main function to check gRPC coverage."""
# Get paths
@@ -313,12 +335,29 @@ def main():
print("\n" + report_content)
- # Exit with error only if there are missing NEW queries
- if missing_new_queries:
- print(f"\nERROR: {len(missing_new_queries)} NEW queries are not implemented in rs-sdk")
+ # Check WASM SDK documentation
+ print("\n" + "=" * 80)
+ print("Checking WASM SDK Documentation...")
+ print("=" * 80)
+
+ wasm_docs_ok, wasm_errors = check_wasm_sdk_documentation()
+
+ if wasm_docs_ok:
+ print("✅ WASM SDK documentation is up to date")
+ else:
+ print(f"❌ WASM SDK documentation has {len(wasm_errors)} errors:")
+ for error in wasm_errors:
+ print(f" {error}")
+ print("\nTo fix WASM SDK documentation errors, run:")
+ print(" cd packages/wasm-sdk && python3 generate_docs.py")
+
+ # Exit with error if there are missing NEW queries or documentation errors
+ if missing_new_queries or not wasm_docs_ok:
+ if missing_new_queries:
+ print(f"\nERROR: {len(missing_new_queries)} NEW queries are not implemented in rs-sdk")
sys.exit(1)
else:
- print("\nSUCCESS: All NEW gRPC queries are implemented in rs-sdk (or excluded)")
+ print("\nSUCCESS: All NEW gRPC queries are implemented in rs-sdk (or excluded) and documentation is up to date")
sys.exit(0)
diff --git a/.github/workflows/wasm-sdk-documentation-check.yml b/.github/workflows/wasm-sdk-documentation-check.yml
new file mode 100644
index 00000000000..a77d22c559b
--- /dev/null
+++ b/.github/workflows/wasm-sdk-documentation-check.yml
@@ -0,0 +1,152 @@
+name: Check WASM SDK Documentation
+
+on:
+ workflow_dispatch:
+ pull_request:
+ paths:
+ - 'packages/wasm-sdk/index.html'
+ - 'packages/wasm-sdk/docs.html'
+ - 'packages/wasm-sdk/AI_REFERENCE.md'
+ - 'packages/wasm-sdk/docs_manifest.json'
+ - 'packages/wasm-sdk/generate_docs.py'
+ - 'packages/wasm-sdk/check_documentation.py'
+ - '.github/workflows/wasm-sdk-documentation-check.yml'
+ push:
+ branches:
+ - master
+ - 'v*-dev'
+ paths:
+ - 'packages/wasm-sdk/index.html'
+ - 'packages/wasm-sdk/docs.html'
+ - 'packages/wasm-sdk/AI_REFERENCE.md'
+ - 'packages/wasm-sdk/docs_manifest.json'
+ - 'packages/wasm-sdk/generate_docs.py'
+ - 'packages/wasm-sdk/check_documentation.py'
+ - '.github/workflows/wasm-sdk-documentation-check.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ check-wasm-sdk-documentation:
+ name: Check WASM SDK Documentation
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Check out repo
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.x'
+
+ - name: Check documentation completeness
+ id: doc-check
+ working-directory: packages/wasm-sdk
+ run: |
+ # Run the documentation check
+ if python3 check_documentation.py; then
+ echo "status=success" >> $GITHUB_OUTPUT
+ else
+ echo "status=failure" >> $GITHUB_OUTPUT
+ fi
+
+ # Note: At this point, the documentation hasn't been regenerated yet,
+ # so this check will only detect if the PR already includes documentation changes
+ if git diff --quiet HEAD -- docs.html docs_manifest.json AI_REFERENCE.md; then
+ echo "docs_modified=false" >> $GITHUB_OUTPUT
+ else
+ echo "docs_modified=true" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Upload documentation check report
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: documentation-check-report
+ path: packages/wasm-sdk/documentation-check-report.txt
+
+ - name: Comment PR
+ if: github.event_name == 'pull_request' && steps.doc-check.outputs.status == 'failure'
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const reportPath = 'packages/wasm-sdk/documentation-check-report.txt';
+
+ if (fs.existsSync(reportPath)) {
+ const report = fs.readFileSync(reportPath, 'utf8');
+ const status = '${{ steps.doc-check.outputs.status }}' === 'success' ? '✅' : '❌';
+
+ // Find existing comment
+ const { data: comments } = await github.rest.issues.listComments({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ });
+
+ const botComment = comments.find(comment =>
+ comment.user.type === 'Bot' &&
+ comment.body.includes('WASM SDK Documentation Check')
+ );
+
+ const body = `### ${status} WASM SDK Documentation Check\n\n\`\`\`\n${report}\n\`\`\`\n\n**To fix documentation issues:**\n\`\`\`bash\ncd packages/wasm-sdk\npython3 generate_docs.py\n\`\`\``;
+
+ if (botComment) {
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: botComment.id,
+ body: body
+ });
+ } else {
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body: body
+ });
+ }
+ }
+
+ - name: Auto-update documentation (non-protected branches)
+ if: github.event_name == 'push' && !contains(github.ref, 'master') && !contains(github.ref, 'main') && steps.doc-check.outputs.status == 'failure'
+ working-directory: packages/wasm-sdk
+ run: |
+ # Generate updated documentation
+ python3 generate_docs.py
+ # Check if there are changes
+ if ! git diff --quiet docs.html docs_manifest.json AI_REFERENCE.md; then
+ git config --local user.email "github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+ git add docs.html docs_manifest.json AI_REFERENCE.md
+ git commit -m "chore: update WASM SDK documentation [skip ci]"
+ git push
+ fi
+
+ - name: Create documentation update PR (protected branches)
+ if: github.event_name == 'push' && (contains(github.ref, 'master') || contains(github.ref, 'main')) && steps.doc-check.outputs.status == 'failure'
+ uses: peter-evans/create-pull-request@v5
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ commit-message: "chore: update WASM SDK documentation"
+ title: "chore: update WASM SDK documentation"
+ body: |
+ This PR updates the WASM SDK documentation to match the current implementation.
+
+ Auto-generated by GitHub Actions.
+ branch: auto-update-wasm-docs-${{ github.run_number }}
+ base: ${{ github.ref_name }}
+ path: packages/wasm-sdk
+
+ - name: Fail if documentation is out of date
+ if: steps.doc-check.outputs.status == 'failure' && github.event_name == 'pull_request'
+ run: |
+ echo "Documentation is out of date. Please run 'python3 generate_docs.py' in packages/wasm-sdk/"
+ exit 1
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8c3806b7365..6d8b24ae784 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,10 @@ packages/wasm-sdk/.cargo/
packages/wasm-sdk/pkg/
packages/wasm-sdk/dist/
packages/wasm-sdk/*.bak
+packages/wasm-sdk/wasm_sdk.js
+packages/wasm-sdk/wasm_sdk_bg.wasm
+packages/wasm-sdk/documentation-check-report.txt
+packages/wasm-sdk/extracted_definitions.json
# gRPC coverage report
grpc-coverage-report.txt
diff --git a/CLAUDE.md b/CLAUDE.md
index ccaf6a1c3f8..2c6a306e558 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -97,6 +97,8 @@ yarn configure:tests:network
**SDK** (`packages/js-dash-sdk`, `packages/rs-sdk`): Client libraries providing high-level interfaces for building applications on Dash Platform.
+**WASM SDK** (`packages/wasm-sdk`): WebAssembly bindings for browser-based applications. See [AI_REFERENCE.md](packages/wasm-sdk/AI_REFERENCE.md) for comprehensive API documentation.
+
**Dashmate** (`packages/dashmate`): Node management tool for setting up and managing Dash Platform nodes.
### Data Contracts
@@ -114,6 +116,10 @@ Platform uses data contracts to define application data schemas:
2. **Cross-language Integration**: WASM bindings connect Rust and JavaScript code
3. **Local Development**: Docker Compose environment managed by dashmate
4. **Testing**: Comprehensive test suites at unit, integration, and e2e levels
+5. **WASM SDK Development**:
+ - Build with `./build.sh` in `packages/wasm-sdk`
+ - Test with web interface at `index.html`
+ - Keep docs in sync: `python3 generate_docs.py`
### Important Patterns
diff --git a/packages/wasm-sdk/.gitignore b/packages/wasm-sdk/.gitignore
deleted file mode 100644
index 03314f77b5a..00000000000
--- a/packages/wasm-sdk/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-Cargo.lock
diff --git a/packages/wasm-sdk/AI_REFERENCE.md b/packages/wasm-sdk/AI_REFERENCE.md
new file mode 100644
index 00000000000..fb5cab7a8aa
--- /dev/null
+++ b/packages/wasm-sdk/AI_REFERENCE.md
@@ -0,0 +1,1139 @@
+# Dash Platform WASM JS SDK - AI Reference
+
+## Overview
+The Dash Platform WASM JS SDK provides WebAssembly bindings for interacting with Dash Platform from JavaScript/TypeScript. This reference is optimized for AI understanding and quick implementation.
+
+## Quick Setup
+```javascript
+// Import and initialize
+import init, { WasmSdk } from './pkg/wasm_sdk.js';
+
+await init();
+const transport = {
+ url: "https://52.12.176.90:1443/", // testnet
+ network: "testnet"
+};
+const proofs = true; // Enable proof verification
+const sdk = await WasmSdk.new(transport, proofs);
+```
+
+## Authentication
+Most state transitions require authentication:
+```javascript
+const identityHex = "hex_encoded_identity";
+const privateKeyHex = "hex_encoded_private_key";
+```
+
+## Query Operations
+
+### Pattern
+All queries follow this pattern:
+```javascript
+const result = await sdk.{query_name}(param1, param2, ...);
+```
+
+### Available Queries
+
+#### Identity Queries
+
+**Get Identity** - `getIdentity`
+*Fetch an identity by its identifier*
+
+Parameters:
+- `id` (text, required) - Identity ID
+
+Example:
+```javascript
+const identity = await sdk.getIdentity("GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec");
+```
+
+**Get Identity Keys** - `getIdentityKeys`
+*Retrieve keys associated with an identity*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+- `keyRequestType` (select, optional) - Key Request Type
+ - Options: `all` (All Keys (AllKeys {}) - Get all keys for the identity), `specific` (Specific Keys (SpecificKeys with key_ids) - Get specific keys by ID [🚧 Work in Progress]), `search` (Search Keys (SearchKey with purpose_map) - Search by purpose and security level [🚧 Work in Progress])
+- `specificKeyIds` (array, optional) - Specific Key IDs (required for 'specific' type)
+ - Example: `0,1,2`
+- `searchPurposeMap` (text, optional) - Search Purpose Map JSON (required for 'search' type)
+ - Example: `{"0": {"0": "current"}, "1": {"0": "all"}}`
+
+Example:
+```javascript
+const result = await sdk.getIdentityKeys("identityId");
+```
+
+**Get Identities Contract Keys** - `getIdentitiesContractKeys`
+*Get keys for multiple identities related to a specific contract*
+
+Parameters:
+- `identitiesIds` (array, required) - Identity IDs
+- `contractId` (text, required) - Contract ID
+- `documentTypeName` (text, optional) - Document Type (optional)
+- `keyRequestType` (select, optional) - Key Request Type
+
+Example:
+```javascript
+const result = await sdk.getIdentitiesContractKeys([], "contractId");
+```
+
+**Get Identity Nonce** - `getIdentityNonce`
+*Get the current nonce for an identity*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+
+Example:
+```javascript
+const result = await sdk.getIdentityNonce("identityId");
+```
+
+**Get Identity Contract Nonce** - `getIdentityContractNonce`
+*Get the nonce for an identity in relation to a specific contract*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+- `contractId` (text, required) - Contract ID
+
+Example:
+```javascript
+const result = await sdk.getIdentityContractNonce("identityId", "contractId");
+```
+
+**Get Identity Balance** - `getIdentityBalance`
+*Get the credit balance of an identity*
+
+Parameters:
+- `id` (text, required) - Identity ID
+
+Example:
+```javascript
+const balance = await sdk.getIdentityBalance(identityId);
+```
+
+**Get Identities Balances** - `getIdentitiesBalances`
+*Get balances for multiple identities*
+
+Parameters:
+- `identityIds` (array, required) - Identity IDs
+
+Example:
+```javascript
+const result = await sdk.getIdentitiesBalances([]);
+```
+
+**Get Identity Balance and Revision** - `getIdentityBalanceAndRevision`
+*Get both balance and revision number for an identity*
+
+Parameters:
+- `id` (text, required) - Identity ID
+
+Example:
+```javascript
+const result = await sdk.getIdentityBalanceAndRevision("id");
+```
+
+**Get Identity by Unique Public Key Hash** - `getIdentityByPublicKeyHash`
+*Find an identity by its unique public key hash*
+
+Parameters:
+- `publicKeyHash` (text, required) - Public Key Hash
+ - Example: `b7e904ce25ed97594e72f7af0e66f298031c1754`
+
+Example:
+```javascript
+const result = await sdk.getIdentityByPublicKeyHash("publicKeyHash");
+```
+
+**Get Identity by Non-Unique Public Key Hash** - `getIdentityByNonUniquePublicKeyHash`
+*Find identities by non-unique public key hash*
+
+Parameters:
+- `publicKeyHash` (text, required) - Public Key Hash
+ - Example: `518038dc858461bcee90478fd994bba8057b7531`
+
+Example:
+```javascript
+const result = await sdk.getIdentityByNonUniquePublicKeyHash("publicKeyHash");
+```
+
+**Get Identity Token Balances** - `getIdentityTokenBalances`
+*Get token balances for an identity*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+- `tokenIds` (array, required) - Token IDs
+
+Example:
+```javascript
+const result = await sdk.getIdentityTokenBalances("identityId", []);
+```
+
+**Get Identities Token Balances** - `getIdentitiesTokenBalances`
+*Get token balance for multiple identities*
+
+Parameters:
+- `identityIds` (array, required) - Identity IDs
+- `tokenId` (text, required) - Token ID
+ - Example: `Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv`
+
+Example:
+```javascript
+const result = await sdk.getIdentitiesTokenBalances([], "tokenId");
+```
+
+**Get Identity Token Info** - `getIdentityTokenInfos`
+*Get token information for an identity's tokens*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+- `tokenIds` (array, optional) - Token IDs (optional)
+ - Example: `["Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv"]`
+
+Example:
+```javascript
+const result = await sdk.getIdentityTokenInfos("identityId");
+```
+
+**Get Identities Token Info** - `getIdentitiesTokenInfos`
+*Get token information for multiple identities with a specific token*
+
+Parameters:
+- `identityIds` (array, required) - Identity IDs
+- `tokenId` (text, required) - Token ID
+ - Example: `Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv`
+
+Example:
+```javascript
+const result = await sdk.getIdentitiesTokenInfos([], "tokenId");
+```
+
+#### Data Contract Queries
+
+**Get Data Contract** - `getDataContract`
+*Fetch a data contract by its identifier*
+
+Parameters:
+- `id` (text, required) - Data Contract ID
+ - Example: `GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec`
+
+Example:
+```javascript
+const result = await sdk.getDataContract("id");
+```
+
+**Get Data Contract History** - `getDataContractHistory`
+*Get the version history of a data contract*
+
+Parameters:
+- `id` (text, required) - Data Contract ID
+ - Example: `GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec`
+- `limit` (number, optional) - Limit
+- `offset` (number, optional) - Offset
+
+Example:
+```javascript
+const result = await sdk.getDataContractHistory("id");
+```
+
+**Get Data Contracts** - `getDataContracts`
+*Fetch multiple data contracts by their identifiers*
+
+Parameters:
+- `ids` (array, required) - Data Contract IDs
+ - Example: `["GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", "ALybvzfcCwMs7sinDwmtumw17NneuW7RgFtFHgjKmF3A"]`
+
+Example:
+```javascript
+const result = await sdk.getDataContracts([]);
+```
+
+#### Document Queries
+
+**Get Documents** - `getDocuments`
+*Query documents from a data contract*
+
+Parameters:
+- `dataContractId` (text, required) - Data Contract ID
+ - Example: `GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec`
+- `documentType` (text, required) - Document Type
+ - Example: `domain`
+- `whereClause` (text, optional) - Where Clause (JSON)
+ - Example: `[["normalizedParentDomainName", "==", "dash"], ["normalizedLabel", "==", "therea1s11mshaddy5"]]`
+- `orderBy` (text, optional) - Order By (JSON)
+ - Example: `[["$createdAt", "desc"]]`
+- `limit` (number, optional) - Limit
+
+Example:
+```javascript
+const docs = await sdk.getDocuments(
+ contractId,
+ "note",
+ JSON.stringify([["$ownerId", "==", identityId]]),
+ JSON.stringify([["$createdAt", "desc"]]),
+ 10
+);
+```
+
+**Get Document** - `getDocument`
+*Fetch a specific document by ID*
+
+Parameters:
+- `dataContractId` (text, required) - Data Contract ID
+ - Example: `GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec`
+- `documentType` (text, required) - Document Type
+ - Example: `domain`
+- `documentId` (text, required) - Document ID
+ - Example: `7NYmEKQsYtniQRUmxwdPGeVcirMoPh5ZPyAKz8BWFy3r`
+
+Example:
+```javascript
+const result = await sdk.getDocument("dataContractId", "documentType", "documentId");
+```
+
+#### DPNS Queries
+
+**Get DPNS Usernames** - `getDpnsUsername`
+*Get DPNS usernames for an identity*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+
+Example:
+```javascript
+const result = await sdk.getDpnsUsername("identityId");
+```
+
+**DPNS Check Availability** - `dpnsCheckAvailability`
+*Check if a DPNS username is available*
+
+Parameters:
+- `label` (text, required) - Label (Username)
+
+Example:
+```javascript
+const result = await sdk.dpnsCheckAvailability("label");
+```
+
+**DPNS Resolve Name** - `dpnsResolve`
+*Resolve a DPNS name to an identity ID*
+
+Parameters:
+- `name` (text, required) - Name
+
+Example:
+```javascript
+const result = await sdk.dpnsResolve("name");
+```
+
+#### Voting & Contested Resources
+
+**Get Contested Resources** - `getContestedResources`
+*Get list of contested resources*
+
+Parameters:
+- `resultType` (select, required) - Result Type
+- `documentTypeName` (text, required) - Document Type
+- `indexName` (text, required) - Index Name
+- `count` (number, optional) - Count
+
+Example:
+```javascript
+const result = await sdk.getContestedResources("resultType", "documentTypeName", "indexName");
+```
+
+**Get Contested Resource Vote State** - `getContestedResourceVoteState`
+*Get the current vote state for a contested resource*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `documentTypeName` (text, required) - Document Type
+- `indexName` (text, required) - Index Name
+
+Example:
+```javascript
+const result = await sdk.getContestedResourceVoteState("contractId", "documentTypeName", "indexName");
+```
+
+**Get Contested Resource Voters for Identity** - `getContestedResourceVotersForIdentity`
+*Get voters who voted for a specific identity in a contested resource*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `documentTypeName` (text, required) - Document Type
+- `indexName` (text, required) - Index Name
+- `contestantId` (text, required) - Contestant Identity ID
+
+Example:
+```javascript
+const result = await sdk.getContestedResourceVotersForIdentity("contractId", "documentTypeName", "indexName", "contestantId");
+```
+
+**Get Contested Resource Identity Votes** - `getContestedResourceIdentityVotes`
+*Get all votes cast by a specific identity*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+
+Example:
+```javascript
+const result = await sdk.getContestedResourceIdentityVotes("identityId");
+```
+
+**Get Vote Polls by End Date** - `getVotePollsByEndDate`
+*Get vote polls within a time range*
+
+Parameters:
+- `startTimeMs` (number, required) - Start Time (ms)
+- `endTimeMs` (number, required) - End Time (ms)
+
+Example:
+```javascript
+const result = await sdk.getVotePollsByEndDate(100, 100);
+```
+
+#### Protocol & Version
+
+**Get Protocol Version Upgrade State** - `getProtocolVersionUpgradeState`
+*Get the current state of protocol version upgrades*
+
+No parameters required.
+
+Example:
+```javascript
+const result = await sdk.getProtocolVersionUpgradeState();
+```
+
+**Get Protocol Version Upgrade Vote Status** - `getProtocolVersionUpgradeVoteStatus`
+*Get voting status for protocol version upgrades*
+
+Parameters:
+- `startProTxHash` (text, required) - Start ProTx Hash
+ - Example: `143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113`
+- `count` (number, required) - Count
+
+Example:
+```javascript
+const result = await sdk.getProtocolVersionUpgradeVoteStatus("startProTxHash", 100);
+```
+
+#### Epoch & Block
+
+**Get Epochs Info** - `getEpochsInfo`
+*Get information about epochs*
+
+Parameters:
+- `epoch` (number, required) - Start Epoch
+- `count` (number, required) - Count
+- `ascending` (checkbox, optional) - Ascending Order
+
+Example:
+```javascript
+const result = await sdk.getEpochsInfo(100, 100);
+```
+
+**Get Current Epoch** - `getCurrentEpoch`
+*Get information about the current epoch*
+
+No parameters required.
+
+Example:
+```javascript
+const result = await sdk.getCurrentEpoch();
+```
+
+**Get Finalized Epoch Info** - `getFinalizedEpochInfos`
+*Get information about finalized epochs*
+
+Parameters:
+- `startEpoch` (number, required) - Start Epoch
+- `count` (number, required) - Count
+
+Example:
+```javascript
+const result = await sdk.getFinalizedEpochInfos(100, 100);
+```
+
+**Get Evonodes Proposed Epoch Blocks by IDs** - `getEvonodesProposedEpochBlocksByIds`
+*Get proposed blocks by evonode IDs*
+
+Parameters:
+- `ids` (array, required) - ProTx Hashes
+ - Example: `["143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113"]`
+
+Example:
+```javascript
+const result = await sdk.getEvonodesProposedEpochBlocksByIds([]);
+```
+
+**Get Evonodes Proposed Epoch Blocks by Range** - `getEvonodesProposedEpochBlocksByRange`
+*Get proposed blocks by range*
+
+Parameters:
+- `startProTxHash` (text, required) - Start ProTx Hash
+ - Example: `143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113`
+- `count` (number, required) - Count
+
+Example:
+```javascript
+const result = await sdk.getEvonodesProposedEpochBlocksByRange("startProTxHash", 100);
+```
+
+#### Token Queries
+
+**Get Token Statuses** - `getTokenStatuses`
+*Get token statuses*
+
+Parameters:
+- `tokenIds` (array, required) - Token IDs
+
+Example:
+```javascript
+const result = await sdk.getTokenStatuses([]);
+```
+
+**Get Token Direct Purchase Prices** - `getTokenDirectPurchasePrices`
+*Get direct purchase prices for tokens*
+
+Parameters:
+- `tokenIds` (array, required) - Token IDs
+
+Example:
+```javascript
+const result = await sdk.getTokenDirectPurchasePrices([]);
+```
+
+**Get Token Contract Info** - `getTokenContractInfo`
+*Get information about a token contract*
+
+Parameters:
+- `dataContractId` (text, required) - Data Contract ID
+ - Example: `EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta`
+
+Example:
+```javascript
+const result = await sdk.getTokenContractInfo("dataContractId");
+```
+
+**Get Token Perpetual Distribution Last Claim** - `getTokenPerpetualDistributionLastClaim`
+*Get last claim information for perpetual distribution*
+
+Parameters:
+- `identityId` (text, required) - Identity ID
+- `tokenId` (text, required) - Token ID
+
+Example:
+```javascript
+const result = await sdk.getTokenPerpetualDistributionLastClaim("identityId", "tokenId");
+```
+
+**Get Token Total Supply** - `getTokenTotalSupply`
+*Get total supply of a token*
+
+Parameters:
+- `tokenId` (text, required) - Token ID
+ - Example: `Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv`
+
+Example:
+```javascript
+const result = await sdk.getTokenTotalSupply("tokenId");
+```
+
+#### Group Queries
+
+**Get Group Info** - `getGroupInfo`
+*Get information about a group*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `groupContractPosition` (number, required) - Group Contract Position
+
+Example:
+```javascript
+const result = await sdk.getGroupInfo("contractId", 100);
+```
+
+**Get Group Infos** - `getGroupInfos`
+*Get information about multiple groups*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `startAtGroupContractPosition` (number, optional) - Start at Position
+- `startGroupContractPositionIncluded` (checkbox, optional) - Include Start Position
+- `count` (number, optional) - Count
+
+Example:
+```javascript
+const result = await sdk.getGroupInfos("contractId");
+```
+
+**Get Group Actions** - `getGroupActions`
+*Get actions for a group*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `groupContractPosition` (number, required) - Group Contract Position
+- `status` (select, required) - Status
+ - Options: `ACTIVE` (Active), `CLOSED` (Closed)
+- `startActionId` (text, optional) - Start Action ID
+- `startActionIdIncluded` (checkbox, optional) - Include Start Action
+- `count` (number, optional) - Count
+
+Example:
+```javascript
+const result = await sdk.getGroupActions("contractId", 100, "status");
+```
+
+**Get Group Action Signers** - `getGroupActionSigners`
+*Get signers for a group action*
+
+Parameters:
+- `contractId` (text, required) - Contract ID
+- `groupContractPosition` (number, required) - Group Contract Position
+- `status` (select, required) - Status
+ - Options: `ACTIVE` (Active), `CLOSED` (Closed)
+- `actionId` (text, required) - Action ID
+
+Example:
+```javascript
+const result = await sdk.getGroupActionSigners("contractId", 100, "status", "actionId");
+```
+
+#### System & Utility
+
+**Get Status** - `getStatus`
+*Get system status*
+
+No parameters required.
+
+Example:
+```javascript
+const result = await sdk.getStatus();
+```
+
+**Get Current Quorums Info** - `getCurrentQuorumsInfo`
+*Get information about current quorums*
+
+No parameters required.
+
+Example:
+```javascript
+const result = await sdk.getCurrentQuorumsInfo();
+```
+
+**Get Prefunded Specialized Balance** - `getPrefundedSpecializedBalance`
+*Get prefunded specialized balance*
+
+Parameters:
+- `identityId` (text, required) - Specialized Balance ID
+ - Example: `AzaU7zqCT7X1kxh8yWxkT9PxAgNqWDu4Gz13emwcRyAT`
+
+Example:
+```javascript
+const result = await sdk.getPrefundedSpecializedBalance("identityId");
+```
+
+**Get Total Credits in Platform** - `getTotalCreditsInPlatform`
+*Get total credits in the platform*
+
+No parameters required.
+
+Example:
+```javascript
+const result = await sdk.getTotalCreditsInPlatform();
+```
+
+**Get Path Elements** - `getPathElements`
+*Access any data in the Dash Platform state tree. This low-level query allows direct access to GroveDB storage by specifying a path through the tree structure and keys to retrieve at that path. Common paths include: Identities (32), Tokens (96), DataContractDocuments (64), Balances (16), Votes (80), and more.*
+
+Parameters:
+- `path` (array, required) - Path
+- `keys` (array, required) - Keys
+
+Example:
+```javascript
+// Access any data in the Dash Platform state tree
+// Common root paths:
+// - DataContractDocuments: 64
+// - Identities: 32
+// - UniquePublicKeyHashesToIdentities: 24
+// - NonUniquePublicKeyKeyHashesToIdentities: 8
+// - Tokens: 16
+// - Pools: 48
+// - PreFundedSpecializedBalances: 40
+// - SpentAssetLockTransactions: 72
+// - WithdrawalTransactions: 80
+// - GroupActions: 88
+// - Balances: 96
+// - Misc: 104
+// - Votes: 112
+// - Versions: 120
+
+// Example: Get identity balance
+const result = await sdk.getPathElements(['96'], ['identityId']);
+
+// Example: Get identity info
+const identityKeys = await sdk.getPathElements(['32'], ['identityId']);
+
+// Example: Get contract documents
+const documents = await sdk.getPathElements(['64'], ['contractId', '1', 'documentType']);
+```
+
+**Wait for State Transition Result** - `waitForStateTransitionResult`
+*Internal query to wait for and retrieve the result of a previously submitted state transition*
+
+Parameters:
+- `stateTransitionHash` (text, required) - State Transition Hash
+
+Example:
+```javascript
+const result = await sdk.waitForStateTransitionResult("stateTransitionHash");
+```
+
+## State Transition Operations
+
+### Pattern
+All state transitions require authentication and follow this pattern:
+```javascript
+const result = await sdk.{transition_name}(identityHex, ...params, privateKeyHex);
+```
+
+### Available State Transitions
+
+#### Identity Transitions
+
+**Identity Create** - `identityCreate`
+*Create a new identity with initial credits*
+
+Parameters (in addition to identity/key):
+- `publicKeys` (keyArray, required) - Public Keys
+- `assetLockProof` (assetLockProof, required) - Asset Lock Proof
+
+Example:
+```javascript
+const result = await sdk.identityCreate(identityHex, /* params */, privateKeyHex);
+```
+
+**Identity Top Up** - `identityTopUp`
+*Add credits to an existing identity*
+
+Parameters (in addition to identity/key):
+- `assetLockProof` (assetLockProof, required) - Asset Lock Proof
+
+Example:
+```javascript
+const result = await sdk.identityTopUp(identityHex, /* params */, privateKeyHex);
+```
+
+**Identity Update** - `identityUpdate`
+*Update identity keys (add or disable)*
+
+Parameters (in addition to identity/key):
+- `addPublicKeys` (textarea, optional) - Keys to Add (JSON array)
+ - Example: `[{"keyType":"ECDSA_HASH160","purpose":"AUTHENTICATION","data":"base64_key_data"}]`
+- `disablePublicKeys` (text, optional) - Key IDs to Disable (comma-separated)
+ - Example: `2,3,5`
+
+Example:
+```javascript
+const result = await sdk.identityUpdate(identityHex, /* params */, privateKeyHex);
+```
+
+**Identity Credit Transfer** - `identityCreditTransfer`
+*Transfer credits between identities*
+
+Parameters (in addition to identity/key):
+- `recipientId` (text, required) - Recipient Identity ID
+- `amount` (number, required) - Amount (credits)
+
+Example:
+```javascript
+const result = await sdk.identityCreditTransfer(identityHex, /* params */, privateKeyHex);
+```
+
+**Identity Credit Withdrawal** - `identityCreditWithdrawal`
+*Withdraw credits from identity to Dash address*
+
+Parameters (in addition to identity/key):
+- `toAddress` (text, required) - Dash Address
+- `amount` (number, required) - Amount (credits)
+- `coreFeePerByte` (number, optional) - Core Fee Per Byte (optional)
+
+Example:
+```javascript
+const result = await sdk.identityCreditWithdrawal(identityHex, /* params */, privateKeyHex);
+```
+
+#### Data Contract Transitions
+
+**Data Contract Create** - `dataContractCreate`
+*Create a new data contract*
+
+Parameters (in addition to identity/key):
+- `canBeDeleted` (checkbox, optional) - Can Be Deleted
+- `readonly` (checkbox, optional) - Read Only
+- `keepsHistory` (checkbox, optional) - Keeps History
+- `documentsKeepHistoryContractDefault` (checkbox, optional) - Documents Keep History (Default)
+- `documentsMutableContractDefault` (checkbox, optional) - Documents Mutable (Default)
+- `documentsCanBeDeletedContractDefault` (checkbox, optional) - Documents Can Be Deleted (Default)
+- `requiresIdentityEncryptionBoundedKey` (text, optional) - Requires Identity Encryption Key (optional)
+- `requiresIdentityDecryptionBoundedKey` (text, optional) - Requires Identity Decryption Key (optional)
+- `documentSchemas` (json, required) - Document Schemas JSON
+ - Example: `{
+ "note": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "maxLength": 100,
+ "position": 0
+ }
+ },
+ "required": ["message"],
+ "additionalProperties": false
+ }
+}`
+- `groups` (json, optional) - Groups (optional)
+ - Example: `{}`
+- `tokens` (json, optional) - Tokens (optional)
+ - Example: `{}`
+- `keywords` (text, optional) - Keywords (comma separated, optional)
+- `description` (text, optional) - Description (optional)
+
+Example:
+```javascript
+const result = await sdk.dataContractCreate(identityHex, /* params */, privateKeyHex);
+```
+
+**Data Contract Update** - `dataContractUpdate`
+*Add document types, groups, or tokens to an existing data contract*
+
+Parameters (in addition to identity/key):
+- `dataContractId` (text, required) - Data Contract ID
+- `newDocumentSchemas` (json, optional) - New Document Schemas to Add (optional)
+ - Example: `{
+ "newType": {
+ "type": "object",
+ "properties": {
+ "field": {
+ "type": "string",
+ "maxLength": 100,
+ "position": 0
+ }
+ },
+ "required": ["field"],
+ "additionalProperties": false
+ }
+}`
+- `newGroups` (json, optional) - New Groups to Add (optional)
+ - Example: `{}`
+- `newTokens` (json, optional) - New Tokens to Add (optional)
+ - Example: `{}`
+
+Example:
+```javascript
+const result = await sdk.dataContractUpdate(identityHex, /* params */, privateKeyHex);
+```
+
+#### Document Transitions
+
+**Document Create** - `documentCreate`
+*Create a new document*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `fetchSchema` (button, optional) - Fetch Schema
+- `documentFields` (dynamic, optional) - Document Fields
+
+Example:
+```javascript
+const result = await sdk.document_create(
+ identityHex,
+ contractId,
+ "note",
+ JSON.stringify({ message: "Hello!" }),
+ privateKeyHex
+);
+```
+
+**Document Replace** - `documentReplace`
+*Replace an existing document*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `documentId` (text, required) - Document ID
+- `loadDocument` (button, optional) - Load Document
+- `documentFields` (dynamic, optional) - Document Fields
+
+Example:
+```javascript
+const result = await sdk.documentReplace(identityHex, /* params */, privateKeyHex);
+```
+
+**Document Delete** - `documentDelete`
+*Delete an existing document*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `documentId` (text, required) - Document ID
+
+Example:
+```javascript
+const result = await sdk.documentDelete(identityHex, /* params */, privateKeyHex);
+```
+
+**Document Transfer** - `documentTransfer`
+*Transfer document ownership*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `documentId` (text, required) - Document ID
+- `recipientId` (text, required) - Recipient Identity ID
+
+Example:
+```javascript
+const result = await sdk.documentTransfer(identityHex, /* params */, privateKeyHex);
+```
+
+**Document Purchase** - `documentPurchase`
+*Purchase a document*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `documentId` (text, required) - Document ID
+- `price` (number, required) - Price (credits)
+
+Example:
+```javascript
+const result = await sdk.documentPurchase(identityHex, /* params */, privateKeyHex);
+```
+
+**Document Set Price** - `documentSetPrice`
+*Set or update document price*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `documentType` (text, required) - Document Type
+- `documentId` (text, required) - Document ID
+- `price` (number, required) - Price (credits, 0 to remove)
+
+Example:
+```javascript
+const result = await sdk.documentSetPrice(identityHex, /* params */, privateKeyHex);
+```
+
+**DPNS Register Name** - `dpnsRegister`
+*Register a new DPNS username*
+
+Parameters (in addition to identity/key):
+- `label` (text, required) - Username
+ - Example: `Enter username (e.g., alice)`
+
+Example:
+```javascript
+const result = await sdk.dpnsRegister(identityHex, /* params */, privateKeyHex);
+```
+
+#### Token Transitions
+
+**Token Burn** - `tokenBurn`
+*Burn tokens*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenPosition` (number, required) - Token Contract Position
+- `amount` (text, required) - Amount to Burn
+- `keyId` (number, required) - Key ID (for signing)
+- `publicNote` (text, optional) - Public Note
+
+Example:
+```javascript
+const result = await sdk.tokenBurn(identityHex, /* params */, privateKeyHex);
+```
+
+**Token Mint** - `tokenMint`
+*Mint new tokens*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenPosition` (number, required) - Token Contract Position
+- `amount` (text, required) - Amount to Mint
+- `keyId` (number, required) - Key ID (for signing)
+- `issuedToIdentityId` (text, optional) - Issue To Identity ID
+- `publicNote` (text, optional) - Public Note
+
+Example:
+```javascript
+const result = await sdk.tokenMint(identityHex, /* params */, privateKeyHex);
+```
+
+**Token Transfer** - `tokenTransfer`
+*Transfer tokens to another identity*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenId` (text, required) - Token Contract Position
+- `amount` (number, required) - Amount to Transfer
+- `recipientId` (text, required) - Recipient Identity ID
+
+Example:
+```javascript
+const result = await sdk.token_transfer(
+ identityHex,
+ contractId,
+ tokenId,
+ 1000000, // amount
+ recipientId,
+ privateKeyHex
+);
+```
+
+**Token Freeze** - `tokenFreeze`
+*Freeze tokens for an identity*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenId` (text, required) - Token Contract Position
+- `identityId` (text, required) - Identity ID to Freeze
+
+Example:
+```javascript
+const result = await sdk.tokenFreeze(identityHex, /* params */, privateKeyHex);
+```
+
+**Token Unfreeze** - `tokenUnfreeze`
+*Unfreeze tokens for an identity*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenId` (text, required) - Token Contract Position
+- `identityId` (text, required) - Identity ID to Unfreeze
+
+Example:
+```javascript
+const result = await sdk.tokenUnfreeze(identityHex, /* params */, privateKeyHex);
+```
+
+**Token Destroy Frozen Funds** - `tokenDestroyFrozen`
+*Destroy frozen tokens*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+- `tokenId` (text, required) - Token Contract Position
+- `identityId` (text, required) - Identity ID
+
+Example:
+```javascript
+const result = await sdk.tokenDestroyFrozen(identityHex, /* params */, privateKeyHex);
+```
+
+#### Voting Transitions
+
+**DPNS Username** - `dpnsUsername`
+*Cast a vote for a contested DPNS username*
+
+Parameters (in addition to identity/key):
+- `contestedUsername` (text, required) - Contested Username
+ - Example: `Enter the contested username (e.g., 'myusername')`
+- `voteChoice` (select, required) - Vote Choice
+- `targetIdentity` (text, optional) - Target Identity ID (if voting for identity)
+ - Example: `Identity ID to vote for`
+
+Example:
+```javascript
+const result = await sdk.dpnsUsername(identityHex, /* params */, privateKeyHex);
+```
+
+**Contested Resource** - `masternodeVote`
+*Cast a vote for contested resources as a masternode*
+
+Parameters (in addition to identity/key):
+- `contractId` (text, required) - Data Contract ID
+ - Example: `Contract ID containing the contested resource`
+- `fetchContestedResources` (button, optional) - Get Contested Resources
+- `contestedResourceDropdown` (dynamic, optional) - Contested Resources
+- `voteChoice` (select, required) - Vote Choice
+- `targetIdentity` (text, optional) - Target Identity ID (if voting for identity)
+ - Example: `Identity ID to vote for`
+
+Example:
+```javascript
+const result = await sdk.masternodeVote(identityHex, /* params */, privateKeyHex);
+```
+
+## Common Patterns
+
+### Error Handling
+```javascript
+try {
+ const result = await sdk.getIdentity(identityId);
+ console.log(result);
+} catch (error) {
+ console.error("Query failed:", error);
+}
+```
+
+### Working with Proofs
+```javascript
+// Enable proofs during SDK initialization
+const sdk = await WasmSdk.new(transport, true);
+
+// Query with proof verification
+const identityWithProof = await sdk.getIdentity(identityId);
+```
+
+### Document Queries with Where/OrderBy
+```javascript
+// Where clause format: [[field, operator, value], ...]
+const whereClause = JSON.stringify([
+ ["$ownerId", "==", identityId],
+ ["age", ">=", 18]
+]);
+
+// OrderBy format: [[field, direction], ...]
+const orderBy = JSON.stringify([
+ ["$createdAt", "desc"]
+]);
+
+const docs = await sdk.getDocuments(
+ contractId,
+ documentType,
+ whereClause,
+ orderBy,
+ limit
+);
+```
+
+### Batch Operations
+```javascript
+// Get multiple identities
+const identityIds = ["id1", "id2", "id3"];
+const balances = await sdk.getIdentitiesBalances(identityIds);
+```
+
+## Important Notes
+
+1. **Network Endpoints**:
+ - Testnet: `https://52.12.176.90:1443/`
+ - Mainnet: Update when available
+
+2. **Identity Format**: Identity IDs and keys should be hex-encoded strings
+
+3. **Credits**: All fees are paid in credits (1 credit = 1 satoshi equivalent)
+
+4. **Nonces**: The SDK automatically handles nonce management for state transitions
+
+5. **Proofs**: Enable proofs for production applications to ensure data integrity
+
+## Troubleshooting
+
+- **Connection errors**: Verify network endpoint and that SDK is initialized
+- **Invalid parameters**: Check parameter types and required fields
+- **Authentication failures**: Ensure correct identity/key format and key permissions
+- **Query errors**: Validate contract IDs, document types, and field names exist
diff --git a/packages/wasm-sdk/CLAUDE.md b/packages/wasm-sdk/CLAUDE.md
index 8191e363c28..f2d9620bc8b 100644
--- a/packages/wasm-sdk/CLAUDE.md
+++ b/packages/wasm-sdk/CLAUDE.md
@@ -2,6 +2,15 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+## Documentation
+
+**IMPORTANT**: For comprehensive API reference and usage examples, see:
+- **[AI_REFERENCE.md](AI_REFERENCE.md)** - Complete API reference with all queries and state transitions
+- **[docs.html](docs.html)** - User-friendly documentation
+- **[index.html](index.html)** - Live interactive demo
+
+When implementing WASM SDK functionality, always refer to AI_REFERENCE.md first for accurate method signatures and examples.
+
## Important Notes
### Network Connectivity
@@ -42,6 +51,13 @@ Run `./build.sh` to build the WASM module. Output goes to `pkg/` directory.
4. Choose operation type (queries/state transitions)
5. Fill in parameters and execute
+## Documentation Maintenance
+
+When adding new queries or state transitions:
+1. Update the definitions in `index.html`
+2. Run `python3 generate_docs.py` to regenerate documentation
+3. The CI will fail if documentation is out of sync
+
## Common Issues
1. **"time not implemented on this platform"** - Fixed by using `js_sys::Date::now()` in WASM builds
diff --git a/packages/wasm-sdk/README.md b/packages/wasm-sdk/README.md
new file mode 100644
index 00000000000..2af5d43444f
--- /dev/null
+++ b/packages/wasm-sdk/README.md
@@ -0,0 +1,145 @@
+# Dash Platform WASM JS SDK
+
+This package provides WebAssembly bindings for the Dash Platform SDK, allowing JavaScript and TypeScript applications in browsers to interact with Dash Platform.
+
+## Overview
+
+The WASM JS SDK provides:
+- **Queries**: Read-only operations to fetch data from Dash Platform
+- **State Transitions**: Write operations to modify state on Dash Platform
+
+## Usage
+
+### Quick Start
+
+1. Build the WASM module:
+ ```bash
+ ./build.sh
+ ```
+
+2. Serve the demo application:
+ ```bash
+ python3 -m http.server 8888
+ ```
+
+3. Open http://localhost:8888 in your browser
+
+### Integration
+
+```javascript
+import init, { WasmSdk } from './pkg/wasm_sdk.js';
+
+// Initialize WASM module
+await init();
+
+// Create SDK instance
+const transport = {
+ url: "https://52.12.176.90:1443/", // testnet
+ network: "testnet"
+};
+const sdk = await WasmSdk.new(transport, true); // true = enable proofs
+
+// Example query
+const identity = await sdk.get_identity("GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec");
+```
+
+## Documentation
+
+- **[User Documentation](docs.html)**: Comprehensive guide for all queries and state transitions
+- **[AI Reference](AI_REFERENCE.md)**: Quick reference optimized for AI assistants and developers
+- **[Live Demo](index.html)**: Interactive interface to test all SDK functionality
+
+## Development
+
+### Building
+
+The SDK requires Rust and wasm-pack:
+
+```bash
+# Install wasm-pack if not already installed
+curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
+
+# Build the WASM module
+./build.sh
+```
+
+### Documentation
+
+**IMPORTANT**: Documentation must be kept in sync with `index.html`. When adding or modifying queries/state transitions in `index.html`, you MUST update the documentation:
+
+```bash
+# Regenerate documentation after changes to index.html
+python3 generate_docs.py
+
+# Check if documentation is up to date
+python3 check_documentation.py
+```
+
+The CI will fail if documentation is out of sync with the code.
+
+### Adding New Features
+
+1. Add the query/transition definition to `index.html`
+2. Implement the corresponding method in the Rust code
+3. Regenerate documentation: `python3 generate_docs.py`
+4. Test your changes using the web interface
+
+### CI/CD
+
+This package has automated checks for:
+- Documentation completeness (all queries/transitions must be documented)
+- Documentation freshness (docs must be regenerated when index.html changes)
+
+The checks run on:
+- Pull requests that modify relevant files
+- Pushes to master and release branches
+
+## Architecture
+
+### File Structure
+
+- `src/`: Rust source code
+ - `queries/`: Query implementations
+ - `state_transitions/`: State transition implementations
+ - `sdk.rs`: Main SDK interface
+- `index.html`: Interactive demo and test interface
+- `docs.html`: User-friendly documentation
+- `AI_REFERENCE.md`: Developer/AI reference documentation
+- `generate_docs.py`: Documentation generator
+- `check_documentation.py`: Documentation validation
+
+### Key Concepts
+
+1. **Queries**: Read operations that don't modify state
+ - Identity queries (balance, keys, nonce)
+ - Document queries (with where/orderBy support)
+ - Data contract queries
+ - Token queries
+ - System queries
+
+2. **State Transitions**: Operations that modify platform state
+ - Identity operations (create, update, transfer)
+ - Document operations (create, update, delete)
+ - Token operations (mint, burn, transfer)
+ - Voting operations
+
+3. **Proofs**: Cryptographic proofs can be requested for most queries to verify data authenticity
+
+## Testing
+
+The web interface (`index.html`) provides comprehensive testing capabilities:
+- Network selection (mainnet/testnet)
+- Query execution with parameter validation
+- State transition testing with authentication
+- Proof verification toggle
+
+## Contributing
+
+1. Make your changes
+2. Update documentation if needed: `python3 generate_docs.py`
+3. Run tests
+4. Submit a pull request
+
+## License
+
+See the main platform repository for license information.
\ No newline at end of file
diff --git a/packages/wasm-sdk/check_documentation.py b/packages/wasm-sdk/check_documentation.py
new file mode 100755
index 00000000000..d3c4ccc07b6
--- /dev/null
+++ b/packages/wasm-sdk/check_documentation.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python3
+"""
+Check that all queries and state transitions in index.html are documented
+"""
+
+import os
+import sys
+import json
+from pathlib import Path
+from datetime import datetime
+
+def check_documentation_completeness():
+ """Check if documentation is up to date with index.html"""
+
+ script_dir = Path(__file__).parent
+
+ # Required files
+ index_file = script_dir / 'index.html'
+ manifest_file = script_dir / 'docs_manifest.json'
+ docs_file = script_dir / 'docs.html'
+ ai_ref_file = script_dir / 'AI_REFERENCE.md'
+
+ errors = []
+ warnings = []
+
+ # Check if all required files exist
+ if not index_file.exists():
+ errors.append(f"ERROR: index.html not found at {index_file}")
+ return errors, warnings
+
+ if not manifest_file.exists():
+ errors.append(f"ERROR: Documentation manifest not found at {manifest_file}. Run generate_docs.py first.")
+ return errors, warnings
+
+ if not docs_file.exists():
+ errors.append(f"ERROR: User documentation not found at {docs_file}. Run generate_docs.py first.")
+
+ if not ai_ref_file.exists():
+ errors.append(f"ERROR: AI reference not found at {ai_ref_file}. Run generate_docs.py first.")
+
+ # Extract current definitions from index.html
+ print("Extracting definitions from index.html...")
+ import subprocess
+ result = subprocess.run(['python3', 'extract_definitions.py'], cwd=script_dir, capture_output=True, text=True)
+ if result.returncode != 0:
+ errors.append(f"ERROR: Failed to extract definitions: {result.stderr}")
+ return errors, warnings
+
+ # Load extracted definitions
+ extracted_file = script_dir / 'extracted_definitions.json'
+ if not extracted_file.exists():
+ errors.append("ERROR: Could not find extracted definitions")
+ return errors, warnings
+
+ with open(extracted_file, 'r') as f:
+ current_defs = json.load(f)
+
+ # Load documentation manifest
+ with open(manifest_file, 'r') as f:
+ manifest = json.load(f)
+
+ # Check if manifest is stale (older than 24 hours)
+ if 'generated_at' in manifest:
+ generated_time = datetime.fromisoformat(manifest['generated_at'])
+ age_hours = (datetime.now() - generated_time).total_seconds() / 3600
+ if age_hours > 24:
+ warnings.append(f"WARNING: Documentation was generated {age_hours:.1f} hours ago. Consider regenerating.")
+
+ # Extract all current queries and transitions
+ current_queries = set()
+ current_transitions = set()
+
+ for cat_key, category in current_defs.get('queries', {}).items():
+ for query_key in category.get('queries', {}).keys():
+ # Skip invalid entries
+ if query_key not in ['dependsOn', 'offset', 'limit']:
+ current_queries.add(query_key)
+
+ for cat_key, category in current_defs.get('transitions', {}).items():
+ for trans_key in category.get('transitions', {}).keys():
+ # Skip invalid entries
+ if trans_key not in ['dependsOn']:
+ current_transitions.add(trans_key)
+
+ documented_queries = set(manifest.get('queries', {}).keys())
+ documented_transitions = set(manifest.get('transitions', {}).keys())
+
+ # Find undocumented items
+ undocumented_queries = current_queries - documented_queries
+ undocumented_transitions = current_transitions - documented_transitions
+
+ # Find removed items (documented but no longer in code)
+ removed_queries = documented_queries - current_queries
+ removed_transitions = documented_transitions - current_transitions
+
+ # Report findings
+ if undocumented_queries:
+ errors.append(f"ERROR: {len(undocumented_queries)} queries are not documented:")
+ for q in sorted(undocumented_queries):
+ errors.append(f" - {q}")
+
+ if undocumented_transitions:
+ errors.append(f"ERROR: {len(undocumented_transitions)} state transitions are not documented:")
+ for t in sorted(undocumented_transitions):
+ errors.append(f" - {t}")
+
+ if removed_queries:
+ warnings.append(f"WARNING: {len(removed_queries)} queries are documented but no longer exist:")
+ for q in sorted(removed_queries):
+ warnings.append(f" - {q}")
+
+ if removed_transitions:
+ warnings.append(f"WARNING: {len(removed_transitions)} transitions are documented but no longer exist:")
+ for t in sorted(removed_transitions):
+ warnings.append(f" - {t}")
+
+ # Check file timestamps
+ index_mtime = os.path.getmtime(index_file)
+
+ if docs_file.exists():
+ docs_mtime = os.path.getmtime(docs_file)
+ if index_mtime > docs_mtime:
+ warnings.append("WARNING: index.html has been modified after docs.html was generated")
+
+ if ai_ref_file.exists():
+ ai_mtime = os.path.getmtime(ai_ref_file)
+ if index_mtime > ai_mtime:
+ warnings.append("WARNING: index.html has been modified after AI_REFERENCE.md was generated")
+
+ return errors, warnings
+
+def main():
+ """Main function"""
+
+ errors, warnings = check_documentation_completeness()
+
+ # Write report
+ report_lines = []
+ report_lines.append("=" * 80)
+ report_lines.append("Documentation Completeness Check")
+ report_lines.append("=" * 80)
+ report_lines.append(f"Timestamp: {datetime.now().isoformat()}\n")
+
+ if not errors and not warnings:
+ report_lines.append("✅ All documentation is up to date!")
+ else:
+ if warnings:
+ report_lines.append(f"⚠️ {len(warnings)} warnings found:\n")
+ for warning in warnings:
+ report_lines.append(warning)
+ report_lines.append("")
+
+ if errors:
+ report_lines.append(f"❌ {len(errors)} errors found:\n")
+ for error in errors:
+ report_lines.append(error)
+ report_lines.append("")
+
+ report_lines.append("=" * 80)
+
+ if errors:
+ report_lines.append("\nTo fix these errors, run: python3 generate_docs.py")
+
+ # Print report
+ report = '\n'.join(report_lines)
+ print(report)
+
+ # Save report
+ with open('documentation-check-report.txt', 'w') as f:
+ f.write(report)
+
+ # Exit with error if there are any errors
+ return 1 if errors else 0
+
+if __name__ == '__main__':
+ sys.exit(main())
\ No newline at end of file
diff --git a/packages/wasm-sdk/docs.html b/packages/wasm-sdk/docs.html
new file mode 100644
index 00000000000..40e1b20d0af
--- /dev/null
+++ b/packages/wasm-sdk/docs.html
@@ -0,0 +1,3031 @@
+
+
+
+
+
+ Dash Platform WASM JS SDK Documentation
+
+
+
+
+
+
+
+
+
+
Loading WASM module...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Dash Platform WASM JS SDK Documentation
+
+
+
Overview
+
The Dash Platform WASM JS SDK provides a WebAssembly-based interface for interacting with the Dash Platform from JavaScript and TypeScript applications.
+ This documentation covers all available queries and state transitions.
+
+
Key Concepts
+
+ Queries : Read-only operations that fetch data from the platform
+ State Transitions : Write operations that modify state on the platform
+ Proofs : Cryptographic proofs can be requested for most queries to verify data authenticity
+ Credits : The platform's unit of account for paying transaction fees
+ Default Limits : All queries with optional limit parameters default to a maximum of 100 items if not specified
+
+
+
Note: All examples below can be run directly in your browser using the testnet. Click the "Run" button to execute any example.
+
+
+ Test Identity: All examples use the testnet identity 5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk
+ This is a known identity with activity on testnet that you can use for testing.
+
+
+
+
Queries
+
+
+
Identity Queries
+
+
+
Get Identity
+
Fetch an identity by its identifier
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.identity_fetch(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
Get Identity Keys
+
Retrieve keys associated with an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+ Key Request Type
+ select
+ (optional)
+Options: All Keys (AllKeys {}) - Get all keys for the identity, Specific Keys (SpecificKeys with key_ids) - Get specific keys by ID [🚧 Work in Progress], Search Keys (SearchKey with purpose_map) - Search by purpose and security level [🚧 Work in Progress]
+
+ Specific Key IDs (required for 'specific' type)
+ array
+ (optional)
+Example: 0,1,2
+
+ Search Purpose Map JSON (required for 'search' type)
+ text
+ (optional)
+Example: {"0": {"0": "current"}, "1": {"0": "all"}}
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_keys(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', 'all');
+
Run
+
+
Example 2 - Get Specific Keys
+
return await window.wasmFunctions.get_identity_keys(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', 'specific', [0, 1, 2]);
+
Run
+
+
+
+
+
+
+
+
Get Identities Contract Keys
+
Get keys for multiple identities related to a specific contract
+
+
+
Parameters:
+
+
+ Identity IDs
+ array
+ (required)
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Document Type (optional)
+ text
+ (optional)
+
+
+ Key Request Type
+ select
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identities_contract_keys(sdk, ['5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk'], 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'domain', 'all');
+
Run
+
+
+
+
+
+
Get Identity Nonce
+
Get the current nonce for an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_nonce(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
Get Identity Contract Nonce
+
Get the nonce for an identity in relation to a specific contract
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+ Contract ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_contract_nonce(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec');
+
Run
+
+
+
+
+
+
Get Identity Balance
+
Get the credit balance of an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_balance(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
Get Identities Balances
+
Get balances for multiple identities
+
+
+
Parameters:
+
+
+ Identity IDs
+ array
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identities_balances(sdk, ['5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk']);
+
Run
+
+
+
+
+
+
Get Identity Balance and Revision
+
Get both balance and revision number for an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_balance_and_revision(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
Get Identity by Unique Public Key Hash
+
Find an identity by its unique public key hash
+
+
+
Parameters:
+
+
+ Public Key Hash
+ text
+ (required)
+Example: b7e904ce25ed97594e72f7af0e66f298031c1754
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_by_public_key_hash(sdk, 'b7e904ce25ed97594e72f7af0e66f298031c1754');
+
Run
+
+
+
+
+
+
Get Identity by Non-Unique Public Key Hash
+
Find identities by non-unique public key hash
+
+
+
Parameters:
+
+
+ Public Key Hash
+ text
+ (required)
+Example: 518038dc858461bcee90478fd994bba8057b7531
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_by_non_unique_public_key_hash(sdk, '518038dc858461bcee90478fd994bba8057b7531');
+
Run
+
+
+
+
+
+
Get Identity Token Balances
+
Get token balances for an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+ Token IDs
+ array
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_token_balances(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', ['Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv']);
+
Run
+
+
+
+
+
+
Get Identities Token Balances
+
Get token balance for multiple identities
+
+
+
Parameters:
+
+
+ Identity IDs
+ array
+ (required)
+
+
+ Token ID
+ text
+ (required)
+Example: Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv
+
+
+
+
Example
+
return await window.wasmFunctions.get_identities_token_balances(sdk, ['5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk'], 'Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv');
+
Run
+
+
+
+
+
+
Get Identity Token Info
+
Get token information for an identity's tokens
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+ Token IDs (optional)
+ array
+ (optional)
+Example: ["Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv"]
+
+
+
+
Example
+
return await window.wasmFunctions.get_identity_token_infos(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', ['Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv']);
+
Run
+
+
+
+
+
+
Get Identities Token Info
+
Get token information for multiple identities with a specific token
+
+
+
Parameters:
+
+
+ Identity IDs
+ array
+ (required)
+
+
+ Token ID
+ text
+ (required)
+Example: Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv
+
+
+
+
Example
+
return await window.wasmFunctions.get_identities_token_infos(sdk, ['5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk'], 'Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv');
+
Run
+
+
+
+
+
+
Data Contract Queries
+
+
+
Get Data Contract
+
Fetch a data contract by its identifier
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
+
+
+
+
Example
+
return await window.wasmFunctions.data_contract_fetch(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec');
+
Run
+
+
+
+
+
+
Get Data Contract History
+
Get the version history of a data contract
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
+
+ Limit
+ number
+ (optional)
+Default: 100 (maximum items returned if not specified)
+
+ Offset
+ number
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_data_contract_history(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 10, 0);
+
Run 🚧 Work in Progress
+
+
+
+
+
+
Get Data Contracts
+
Fetch multiple data contracts by their identifiers
+
+
+
Parameters:
+
+
+ Data Contract IDs
+ array
+ (required)
+Example: ["GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec", "ALybvzfcCwMs7sinDwmtumw17NneuW7RgFtFHgjKmF3A"]
+
+
+
+
Example
+
return await window.wasmFunctions.get_data_contracts(sdk, ['GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'ALybvzfcCwMs7sinDwmtumw17NneuW7RgFtFHgjKmF3A']);
+
Run
+
+
+
+
+
+
Document Queries
+
+
+
Get Documents
+
Query documents from a data contract
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
+
+ Document Type
+ text
+ (required)
+Example: domain
+
+ Where Clause (JSON)
+ text
+ (optional)
+Example: [["normalizedParentDomainName", "==", "dash"], ["normalizedLabel", "==", "therea1s11mshaddy5"]]
+
+ Order By (JSON)
+ text
+ (optional)
+Example: [["$createdAt", "desc"]]
+
+ Limit
+ number
+ (optional)
+Default: 100 (maximum items returned if not specified)
+
+
+
+
Example
+
return await window.wasmFunctions.get_documents(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'domain', JSON.stringify([["normalizedParentDomainName", "==", "dash"]]), JSON.stringify([["normalizedLabel", "asc"]]), 10);
+
Run
+
+
+
+
+
+
Get Document
+
Fetch a specific document by ID
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec
+
+ Document Type
+ text
+ (required)
+Example: domain
+
+ Document ID
+ text
+ (required)
+Example: 7NYmEKQsYtniQRUmxwdPGeVcirMoPh5ZPyAKz8BWFy3r
+
+
+
+
Example
+
return await window.wasmFunctions.get_document(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'domain', '7NYmEKQsYtniQRUmxwdPGeVcirMoPh5ZPyAKz8BWFy3r');
+
Run
+
+
+
+
+
+
DPNS Queries
+
+
+
Get DPNS Usernames
+
Get DPNS usernames for an identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_dpns_usernames(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
DPNS Check Availability
+
Check if a DPNS username is available
+
+
+
Parameters:
+
+
+ Label (Username)
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.dpns_is_name_available(sdk, 'alice');
+
Run
+
+
+
+
+
+
DPNS Resolve Name
+
Resolve a DPNS name to an identity ID
+
+
+
Parameters:
+
+
+ Name
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.dpns_resolve_name(sdk, 'alice');
+
Run
+
+
+
+
+
+
Voting & Contested Resources
+
+
+
Get Contested Resources
+
Get list of contested resources
+
+
+
Parameters:
+
+
+ Result Type
+ select
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Index Name
+ text
+ (required)
+
+
+ Count
+ number
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_contested_resources(sdk, 'documents', 'domain', 'parentNameAndLabel', 100);
+
Run
+
+
+
+
+
+
Get Contested Resource Vote State
+
Get the current vote state for a contested resource
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Index Name
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_contested_resource_vote_state(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'domain', 'parentNameAndLabel');
+
Run
+
+
+
+
+
+
Get Contested Resource Voters for Identity
+
Get voters who voted for a specific identity in a contested resource
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Index Name
+ text
+ (required)
+
+
+ Contestant Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_contested_resource_voters_for_identity(sdk, 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec', 'domain', 'parentNameAndLabel', '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run 🚧 Work in Progress
+
+
+
+
+
+
Get Contested Resource Identity Votes
+
Get all votes cast by a specific identity
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_contested_resource_identity_votes(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk');
+
Run
+
+
+
+
+
+
Get Vote Polls by End Date
+
Get vote polls within a time range
+
+
+
Parameters:
+
+
+ Start Time (ms)
+ number
+ (required)
+
+
+ End Time (ms)
+ number
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_vote_polls_by_end_date(sdk, Date.now() - 86400000, Date.now());
+
Run
+
+
+
+
+
+
Protocol & Version
+
+
+
Get Protocol Version Upgrade State
+
Get the current state of protocol version upgrades
+
+
+
Parameters:
+
No parameters required
+
+
+
+
Example
+
return await window.wasmFunctions.get_protocol_version_upgrade_state(sdk);
+
Run
+
+
+
+
+
+
Get Protocol Version Upgrade Vote Status
+
Get voting status for protocol version upgrades
+
+
+
Parameters:
+
+
+ Start ProTx Hash
+ text
+ (required)
+Example: 143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113
+
+ Count
+ number
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_protocol_version_upgrade_vote_status(sdk, '143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113', 100);
+
Run
+
+
+
+
+
+
Epoch & Block
+
+
+
Get Epochs Info
+
Get information about epochs
+
+
+
Parameters:
+
+
+ Start Epoch
+ number
+ (required)
+
+
+ Count
+ number
+ (required)
+
+
+ Ascending Order
+ checkbox
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_epochs_info(sdk, 1000, 100, true);
+
Run
+
+
+
+
+
+
Get Current Epoch
+
Get information about the current epoch
+
+
+
Parameters:
+
No parameters required
+
+
+
+
Example
+
return await window.wasmFunctions.get_current_epoch(sdk);
+
Run
+
+
+
+
+
+
Get Finalized Epoch Info
+
Get information about finalized epochs
+
+
+
Parameters:
+
+
+ Start Epoch
+ number
+ (required)
+
+
+ Count
+ number
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_finalized_epoch_infos(sdk, 8635, 100);
+
Run
+
+
+
+
+
+
Get Evonodes Proposed Epoch Blocks by IDs
+
Get proposed blocks by evonode IDs
+
+
+
Parameters:
+
+
+ ProTx Hashes
+ array
+ (required)
+Example: ["143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113"]
+
+
+
+
Example
+
return await window.wasmFunctions.get_evonodes_proposed_epoch_blocks_by_ids(sdk, ['143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113']);
+
Run
+
+
+
+
+
+
Get Evonodes Proposed Epoch Blocks by Range
+
Get proposed blocks by range
+
+
+
Parameters:
+
+
+ Start ProTx Hash
+ text
+ (required)
+Example: 143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113
+
+ Count
+ number
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_evonodes_proposed_epoch_blocks_by_range(sdk, '143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113', 100);
+
Run
+
+
+
+
+
+
Token Queries
+
+
+
Get Token Statuses
+
Get token statuses
+
+
+
Parameters:
+
+
+ Token IDs
+ array
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_token_statuses(sdk, ['Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv', 'H7FRpZJqZK933r9CzZMsCuf1BM34NT5P2wSJyjDkprqy']);
+
Run
+
+
+
+
+
+
Get Token Direct Purchase Prices
+
Get direct purchase prices for tokens
+
+
+
Parameters:
+
+
+ Token IDs
+ array
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_token_direct_purchase_prices(sdk, ['H7FRpZJqZK933r9CzZMsCuf1BM34NT5P2wSJyjDkprqy']);
+
Run
+
+
+
+
+
+
Get Token Contract Info
+
Get information about a token contract
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta
+
+
+
+
Example
+
return await window.wasmFunctions.get_token_contract_info(sdk, 'EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta');
+
Run
+
+
+
+
+
+
Get Token Perpetual Distribution Last Claim
+
Get last claim information for perpetual distribution
+
+
+
Parameters:
+
+
+ Identity ID
+ text
+ (required)
+
+
+ Token ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_token_perpetual_distribution_last_claim(sdk, '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk', 'EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta');
+
Run 🚧 Work in Progress
+
+
+
+
+
+
Get Token Total Supply
+
Get total supply of a token
+
+
+
Parameters:
+
+
+ Token ID
+ text
+ (required)
+Example: Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv
+
+
+
+
Example
+
return await window.wasmFunctions.get_token_total_supply(sdk, 'Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv');
+
Run
+
+
+
+
+
+
Group Queries
+
+
+
Get Group Info
+
Get information about a group
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Group Contract Position
+ number
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_group_info(sdk, '49PJEnNx7ReCitzkLdkDNr4s6RScGsnNexcdSZJ1ph5N', 0);
+
Run
+
+
+
+
+
+
Get Group Infos
+
Get information about multiple groups
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Start at Position
+ number
+ (optional)
+
+
+ Include Start Position
+ checkbox
+ (optional)
+
+
+ Count
+ number
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_group_infos(sdk, '49PJEnNx7ReCitzkLdkDNr4s6RScGsnNexcdSZJ1ph5N', null, 100);
+
Run
+
+
+
+
+
+
Get Group Actions
+
Get actions for a group
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Group Contract Position
+ number
+ (required)
+
+
+ Status
+ select
+ (required)
+Options: Active, Closed
+
+ Start Action ID
+ text
+ (optional)
+
+
+ Include Start Action
+ checkbox
+ (optional)
+
+
+ Count
+ number
+ (optional)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_group_actions(sdk, '49PJEnNx7ReCitzkLdkDNr4s6RScGsnNexcdSZJ1ph5N', 0, 'ACTIVE', null, 100);
+
Run
+
+
+
+
+
+
Get Group Action Signers
+
Get signers for a group action
+
+
+
Parameters:
+
+
+ Contract ID
+ text
+ (required)
+
+
+ Group Contract Position
+ number
+ (required)
+
+
+ Status
+ select
+ (required)
+Options: Active, Closed
+
+ Action ID
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_group_action_signers(sdk, '49PJEnNx7ReCitzkLdkDNr4s6RScGsnNexcdSZJ1ph5N', 0, 'ACTIVE', '6XJzL6Qb8Zhwxt4HFwh8NAn7q1u4dwdoUf8EmgzDudFZ');
+
Run
+
+
+
+
+
+
System & Utility
+
+
+
Get Status
+
Get system status
+
+
+
Parameters:
+
No parameters required
+
+
+
+
Example
+
return await window.wasmFunctions.get_status(sdk);
+
Run
+
+
+
+
+
+
Get Current Quorums Info
+
Get information about current quorums
+
+
+
Parameters:
+
No parameters required
+
+
+
+
Example
+
return await window.wasmFunctions.get_current_quorums_info(sdk);
+
Run
+
+
+
+
+
+
Get Prefunded Specialized Balance
+
Get prefunded specialized balance
+
+
+
Parameters:
+
+
+ Specialized Balance ID
+ text
+ (required)
+Example: AzaU7zqCT7X1kxh8yWxkT9PxAgNqWDu4Gz13emwcRyAT
+
+
+
+
Example
+
return await window.wasmFunctions.get_prefunded_specialized_balance(sdk, 'AzaU7zqCT7X1kxh8yWxkT9PxAgNqWDu4Gz13emwcRyAT');
+
Run
+
+
+
+
+
+
+
Get total credits in the platform
+
+
+
Parameters:
+
No parameters required
+
+
+
+
Example
+
return await window.wasmFunctions.get_total_credits_in_platform(sdk);
+
Run
+
+
+
+
+
+
Get Path Elements
+
Access any data in the Dash Platform state tree. This low-level query allows direct access to GroveDB storage by specifying a path through the tree structure and keys to retrieve at that path. Common paths include: Identities (32), Tokens (96), DataContractDocuments (64), Balances (16), Votes (80), and more.
+
+
+
Parameters:
+
+
+ Path
+ array
+ (required)
+
+
+ Keys
+ array
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.get_path_elements(sdk, ['96'], ['5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk']);
+
Run 🚧 Work in Progress
+
+
Common Path Values:
+
+ Path Value Description
+ 64Data Contract Documents
+ 32Identities
+ 24Unique Public Key Hashes to Identities
+ 8Non-Unique Public Key Hashes to Identities
+ 16Tokens
+ 48Pools
+ 40Prefunded Specialized Balances
+ 72Spent Asset Lock Transactions
+ 80Withdrawal Transactions
+ 88Group Actions
+ 96Balances
+ 104Misc
+ 112Votes
+ 120Versions
+
+
Example Paths:
+
+ [32, identity_id] - Access identity data
+ [96, identity_id] - Access identity balance
+ [16, contract_id, token_id] - Access token info
+ [64, contract_id, 1, document_type] - Access documents by type
+ [88, contract_id, group_position] - Access group actions
+ [112] - Access votes tree
+
+
+
+
+
+
+
+
Wait for State Transition Result
+
Internal query to wait for and retrieve the result of a previously submitted state transition
+
+
+
Parameters:
+
+
+ State Transition Hash
+ text
+ (required)
+
+
+
+
+
Example
+
return await window.wasmFunctions.wait_for_state_transition_result(sdk, '0000000000000000000000000000000000000000000000000000000000000000');
+
This is an internal query used to wait for and retrieve the result of a previously submitted state transition. It requires a valid state transition hash from a prior operation.
+
+
+
+
State Transitions
+
+
Identity Transitions
+
+
+
Identity Create
+
Create a new identity with initial credits
+
+
+
Parameters:
+
+
+ Public Keys
+ keyArray
+ (required)
+
+
+ Asset Lock Proof
+ assetLockProof
+ (required)
+
+
+
+
+
+
Identity Top Up
+
Add credits to an existing identity
+
+
+
Parameters:
+
+
+ Asset Lock Proof
+ assetLockProof
+ (required)
+
+
+
+
+
+
Identity Update
+
Update identity keys (add or disable)
+
+
+
Parameters:
+
+
+ Keys to Add (JSON array)
+ textarea
+ (optional)
+Example: [{"keyType":"ECDSA_HASH160","purpose":"AUTHENTICATION","data":"base64_key_data"}]
+
+ Key IDs to Disable (comma-separated)
+ text
+ (optional)
+Example: 2,3,5
+
+
+
+
+
Identity Credit Transfer
+
Transfer credits between identities
+
+
+
Parameters:
+
+
+ Recipient Identity ID
+ text
+ (required)
+
+
+ Amount (credits)
+ number
+ (required)
+
+
+
+
+
+
Identity Credit Withdrawal
+
Withdraw credits from identity to Dash address
+
+
+
Parameters:
+
+
+ Dash Address
+ text
+ (required)
+
+
+ Amount (credits)
+ number
+ (required)
+
+
+ Core Fee Per Byte (optional)
+ number
+ (optional)
+
+
+
+
+
+
Data Contract Transitions
+
+
+
Data Contract Create
+
Create a new data contract
+
+
+
Parameters:
+
+
+ Can Be Deleted
+ checkbox
+ (optional)
+
+
+ Read Only
+ checkbox
+ (optional)
+
+
+ Keeps History
+ checkbox
+ (optional)
+
+
+ Documents Keep History (Default)
+ checkbox
+ (optional)
+
+
+ Documents Mutable (Default)
+ checkbox
+ (optional)
+
+
+ Documents Can Be Deleted (Default)
+ checkbox
+ (optional)
+
+
+ Requires Identity Encryption Key (optional)
+ text
+ (optional)
+
+
+ Requires Identity Decryption Key (optional)
+ text
+ (optional)
+
+
+ Document Schemas JSON
+ json
+ (required)
+Example: {
+ "note": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string",
+ "maxLength": 100,
+ "position": 0
+ }
+ },
+ "required": ["message"],
+ "additionalProperties": false
+ }
+}
+
+ Groups (optional)
+ json
+ (optional)
+Example: {}
+
+ Tokens (optional)
+ json
+ (optional)
+Example: {}
+
+ Keywords (comma separated, optional)
+ text
+ (optional)
+
+
+ Description (optional)
+ text
+ (optional)
+
+
+
+
+
+
Data Contract Update
+
Add document types, groups, or tokens to an existing data contract
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ New Document Schemas to Add (optional)
+ json
+ (optional)
+Example: {
+ "newType": {
+ "type": "object",
+ "properties": {
+ "field": {
+ "type": "string",
+ "maxLength": 100,
+ "position": 0
+ }
+ },
+ "required": ["field"],
+ "additionalProperties": false
+ }
+}
+
+ New Groups to Add (optional)
+ json
+ (optional)
+Example: {}
+
+ New Tokens to Add (optional)
+ json
+ (optional)
+Example: {}
+
+
+
+
+
Document Transitions
+
+
+
Document Create
+
Create a new document
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Fetch Schema
+ button
+ (optional)
+
+
+ Document Fields
+ dynamic
+ (optional)
+
+
+
+
+
+
Document Replace
+
Replace an existing document
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Document ID
+ text
+ (required)
+
+
+ Load Document
+ button
+ (optional)
+
+
+ Document Fields
+ dynamic
+ (optional)
+
+
+
+
+
+
Document Delete
+
Delete an existing document
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Document ID
+ text
+ (required)
+
+
+
+
+
+
Document Transfer
+
Transfer document ownership
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Document ID
+ text
+ (required)
+
+
+ Recipient Identity ID
+ text
+ (required)
+
+
+
+
+
+
Document Purchase
+
Purchase a document
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Document ID
+ text
+ (required)
+
+
+ Price (credits)
+ number
+ (required)
+
+
+
+
+
+
Document Set Price
+
Set or update document price
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Document Type
+ text
+ (required)
+
+
+ Document ID
+ text
+ (required)
+
+
+ Price (credits, 0 to remove)
+ number
+ (required)
+
+
+
+
+
+
DPNS Register Name
+
Register a new DPNS username
+
+
+
Parameters:
+
+
+ Username
+ text
+ (required)
+Example: Enter username (e.g., alice)
+
+
+
+
+
Token Transitions
+
+
+
Token Burn
+
Burn tokens
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ number
+ (required)
+
+
+ Amount to Burn
+ text
+ (required)
+
+
+ Key ID (for signing)
+ number
+ (required)
+
+
+ Public Note
+ text
+ (optional)
+
+
+
+
+
+
Token Mint
+
Mint new tokens
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ number
+ (required)
+
+
+ Amount to Mint
+ text
+ (required)
+
+
+ Key ID (for signing)
+ number
+ (required)
+
+
+ Issue To Identity ID
+ text
+ (optional)
+
+
+ Public Note
+ text
+ (optional)
+
+
+
+
+
+
Token Transfer
+
Transfer tokens to another identity
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ text
+ (required)
+
+
+ Amount to Transfer
+ number
+ (required)
+
+
+ Recipient Identity ID
+ text
+ (required)
+
+
+
+
+
+
Token Freeze
+
Freeze tokens for an identity
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ text
+ (required)
+
+
+ Identity ID to Freeze
+ text
+ (required)
+
+
+
+
+
+
Token Unfreeze
+
Unfreeze tokens for an identity
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ text
+ (required)
+
+
+ Identity ID to Unfreeze
+ text
+ (required)
+
+
+
+
+
+
Token Destroy Frozen Funds
+
Destroy frozen tokens
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+
+
+ Token Contract Position
+ text
+ (required)
+
+
+ Identity ID
+ text
+ (required)
+
+
+
+
+
+
Voting Transitions
+
+
+
DPNS Username
+
Cast a vote for a contested DPNS username
+
+
+
Parameters:
+
+
+ Contested Username
+ text
+ (required)
+Example: Enter the contested username (e.g., 'myusername')
+
+ Vote Choice
+ select
+ (required)
+Options: Abstain, Lock (Give to no one), Vote for Identity
+
+ Target Identity ID (if voting for identity)
+ text
+ (optional)
+Example: Identity ID to vote for
+
+
+
+
+
Contested Resource
+
Cast a vote for contested resources as a masternode
+
+
+
Parameters:
+
+
+ Data Contract ID
+ text
+ (required)
+Example: Contract ID containing the contested resource
+
+ Get Contested Resources
+ button
+ (optional)
+
+
+ Contested Resources
+ dynamic
+ (optional)
+
+
+ Vote Choice
+ select
+ (required)
+Options: Abstain, Lock (Give to no one), Vote for Identity
+
+ Target Identity ID (if voting for identity)
+ text
+ (optional)
+Example: Identity ID to vote for
+
+
+
+
↑ Top
+
+
+
+
+
diff --git a/packages/wasm-sdk/docs_manifest.json b/packages/wasm-sdk/docs_manifest.json
new file mode 100644
index 00000000000..14232e07a48
--- /dev/null
+++ b/packages/wasm-sdk/docs_manifest.json
@@ -0,0 +1,291 @@
+{
+ "generated_at": "2025-07-14T10:43:09.496444",
+ "queries": {
+ "getIdentity": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityKeys": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentitiesContractKeys": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityNonce": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityContractNonce": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityBalance": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentitiesBalances": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityBalanceAndRevision": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityByPublicKeyHash": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityByNonUniquePublicKeyHash": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityTokenBalances": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentitiesTokenBalances": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentityTokenInfos": {
+ "category": "identity",
+ "documented": true
+ },
+ "getIdentitiesTokenInfos": {
+ "category": "identity",
+ "documented": true
+ },
+ "getDataContract": {
+ "category": "dataContract",
+ "documented": true
+ },
+ "getDataContractHistory": {
+ "category": "dataContract",
+ "documented": true
+ },
+ "getDataContracts": {
+ "category": "dataContract",
+ "documented": true
+ },
+ "getDocuments": {
+ "category": "document",
+ "documented": true
+ },
+ "getDocument": {
+ "category": "document",
+ "documented": true
+ },
+ "getDpnsUsername": {
+ "category": "dpns",
+ "documented": true
+ },
+ "dpnsCheckAvailability": {
+ "category": "dpns",
+ "documented": true
+ },
+ "dpnsResolve": {
+ "category": "dpns",
+ "documented": true
+ },
+ "getContestedResources": {
+ "category": "voting",
+ "documented": true
+ },
+ "getContestedResourceVoteState": {
+ "category": "voting",
+ "documented": true
+ },
+ "getContestedResourceVotersForIdentity": {
+ "category": "voting",
+ "documented": true
+ },
+ "getContestedResourceIdentityVotes": {
+ "category": "voting",
+ "documented": true
+ },
+ "getVotePollsByEndDate": {
+ "category": "voting",
+ "documented": true
+ },
+ "getProtocolVersionUpgradeState": {
+ "category": "protocol",
+ "documented": true
+ },
+ "getProtocolVersionUpgradeVoteStatus": {
+ "category": "protocol",
+ "documented": true
+ },
+ "getEpochsInfo": {
+ "category": "epoch",
+ "documented": true
+ },
+ "getCurrentEpoch": {
+ "category": "epoch",
+ "documented": true
+ },
+ "getFinalizedEpochInfos": {
+ "category": "epoch",
+ "documented": true
+ },
+ "getEvonodesProposedEpochBlocksByIds": {
+ "category": "epoch",
+ "documented": true
+ },
+ "getEvonodesProposedEpochBlocksByRange": {
+ "category": "epoch",
+ "documented": true
+ },
+ "getTokenStatuses": {
+ "category": "token",
+ "documented": true
+ },
+ "getTokenDirectPurchasePrices": {
+ "category": "token",
+ "documented": true
+ },
+ "getTokenContractInfo": {
+ "category": "token",
+ "documented": true
+ },
+ "getTokenPerpetualDistributionLastClaim": {
+ "category": "token",
+ "documented": true
+ },
+ "getTokenTotalSupply": {
+ "category": "token",
+ "documented": true
+ },
+ "getGroupInfo": {
+ "category": "group",
+ "documented": true
+ },
+ "getGroupInfos": {
+ "category": "group",
+ "documented": true
+ },
+ "getGroupActions": {
+ "category": "group",
+ "documented": true
+ },
+ "getGroupActionSigners": {
+ "category": "group",
+ "documented": true
+ },
+ "getStatus": {
+ "category": "system",
+ "documented": true
+ },
+ "getCurrentQuorumsInfo": {
+ "category": "system",
+ "documented": true
+ },
+ "getPrefundedSpecializedBalance": {
+ "category": "system",
+ "documented": true
+ },
+ "getTotalCreditsInPlatform": {
+ "category": "system",
+ "documented": true
+ },
+ "getPathElements": {
+ "category": "system",
+ "documented": true
+ },
+ "waitForStateTransitionResult": {
+ "category": "system",
+ "documented": true
+ }
+ },
+ "transitions": {
+ "identityCreate": {
+ "category": "identity",
+ "documented": true
+ },
+ "identityTopUp": {
+ "category": "identity",
+ "documented": true
+ },
+ "identityUpdate": {
+ "category": "identity",
+ "documented": true
+ },
+ "identityCreditTransfer": {
+ "category": "identity",
+ "documented": true
+ },
+ "identityCreditWithdrawal": {
+ "category": "identity",
+ "documented": true
+ },
+ "dataContractCreate": {
+ "category": "dataContract",
+ "documented": true
+ },
+ "dataContractUpdate": {
+ "category": "dataContract",
+ "documented": true
+ },
+ "documentCreate": {
+ "category": "document",
+ "documented": true
+ },
+ "documentReplace": {
+ "category": "document",
+ "documented": true
+ },
+ "documentDelete": {
+ "category": "document",
+ "documented": true
+ },
+ "documentTransfer": {
+ "category": "document",
+ "documented": true
+ },
+ "documentPurchase": {
+ "category": "document",
+ "documented": true
+ },
+ "documentSetPrice": {
+ "category": "document",
+ "documented": true
+ },
+ "dpnsRegister": {
+ "category": "document",
+ "documented": true
+ },
+ "tokenBurn": {
+ "category": "token",
+ "documented": true
+ },
+ "tokenMint": {
+ "category": "token",
+ "documented": true
+ },
+ "tokenTransfer": {
+ "category": "token",
+ "documented": true
+ },
+ "tokenFreeze": {
+ "category": "token",
+ "documented": true
+ },
+ "tokenUnfreeze": {
+ "category": "token",
+ "documented": true
+ },
+ "tokenDestroyFrozen": {
+ "category": "token",
+ "documented": true
+ },
+ "dpnsUsername": {
+ "category": "voting",
+ "documented": true
+ },
+ "masternodeVote": {
+ "category": "voting",
+ "documented": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/wasm-sdk/extract_definitions.py b/packages/wasm-sdk/extract_definitions.py
new file mode 100644
index 00000000000..1afd42374ee
--- /dev/null
+++ b/packages/wasm-sdk/extract_definitions.py
@@ -0,0 +1,302 @@
+#!/usr/bin/env python3
+"""
+Extract query and state transition definitions from index.html
+"""
+
+import json
+import re
+from pathlib import Path
+
+def manual_extract_definitions(html_file):
+ """Manually extract definitions using targeted patterns"""
+
+ with open(html_file, 'r', encoding='utf-8') as f:
+ content = f.read()
+
+ # Extract the complete queryDefinitions block
+ query_start = content.find('const queryDefinitions = {')
+ if query_start == -1:
+ return {}, {}
+
+ # Find the end by counting braces
+ brace_count = 0
+ pos = query_start + len('const queryDefinitions = ')
+ query_end = pos
+
+ for i, char in enumerate(content[pos:], pos):
+ if char == '{':
+ brace_count += 1
+ elif char == '}':
+ brace_count -= 1
+ if brace_count == 0:
+ query_end = i + 1
+ break
+
+ query_block = content[pos:query_end]
+
+ # Extract state transition definitions
+ trans_start = content.find('const stateTransitionDefinitions = {')
+ if trans_start == -1:
+ return {}, {}
+
+ brace_count = 0
+ pos = trans_start + len('const stateTransitionDefinitions = ')
+ trans_end = pos
+
+ for i, char in enumerate(content[pos:], pos):
+ if char == '{':
+ brace_count += 1
+ elif char == '}':
+ brace_count -= 1
+ if brace_count == 0:
+ trans_end = i + 1
+ break
+
+ trans_block = content[pos:trans_end]
+
+ # Parse definitions
+ query_defs = parse_definition_block(query_block, 'queries')
+ trans_defs = parse_definition_block(trans_block, 'transitions')
+
+ return query_defs, trans_defs
+
+def parse_definition_block(block, item_type):
+ """Parse a definition block into structured data"""
+ definitions = {}
+
+ # First, find all category blocks with the pattern: categoryName: { label: "...", queries/transitions: { ... } }
+ # We need to match the full category structure, not just anything with a label
+ cat_pattern = r'(\w+):\s*\{\s*label:\s*"([^"]+)"[^}]*' + item_type + r':\s*\{'
+
+ for match in re.finditer(cat_pattern, block):
+ cat_key = match.group(1)
+ cat_label = match.group(2)
+
+ # Skip if this looks like it's inside another structure
+ # Check if the match is at the top level by ensuring no unclosed braces before it
+ prefix = block[:match.start()]
+ if prefix.count('{') - prefix.count('}') > 0:
+ continue
+
+ # Find this category's content
+ cat_start = match.start()
+
+ # Find the full category block by counting braces
+ brace_count = 0
+ cat_end = cat_start
+ in_category = False
+
+ for i, char in enumerate(block[cat_start:], cat_start):
+ if char == '{':
+ brace_count += 1
+ in_category = True
+ elif char == '}':
+ brace_count -= 1
+ if in_category and brace_count == 0:
+ cat_end = i + 1
+ break
+
+ cat_block = block[cat_start:cat_end]
+
+ # Now extract just the queries/transitions section
+ items_pattern = rf'{item_type}:\s*\{{'
+ items_match = re.search(items_pattern, cat_block)
+
+ if items_match:
+ items_start = items_match.end()
+
+ # Find the end of the items section by counting braces
+ brace_count = 1
+ items_end = items_start
+
+ for i, char in enumerate(cat_block[items_start:], items_start):
+ if char == '{':
+ brace_count += 1
+ elif char == '}':
+ brace_count -= 1
+ if brace_count == 0:
+ items_end = i
+ break
+
+ items_block = cat_block[items_start:items_end]
+
+ # Extract individual items
+ definitions[cat_key] = {
+ 'label': cat_label,
+ item_type: parse_items(items_block)
+ }
+
+ return definitions
+
+def parse_items(items_block):
+ """Parse individual query/transition items"""
+ items = {}
+
+ # Find each item that has label and description structure
+ # This pattern ensures we only match actual query/transition definitions
+ item_pattern = r'(\w+):\s*\{\s*label:\s*"'
+
+ matches = list(re.finditer(item_pattern, items_block))
+
+ for match in matches:
+ item_key = match.group(1)
+ item_start = match.start()
+
+ # Find the full item block by counting braces
+ brace_count = 0
+ item_end = item_start
+ in_item = False
+
+ for j, char in enumerate(items_block[item_start:], item_start):
+ if char == '{':
+ brace_count += 1
+ in_item = True
+ elif char == '}':
+ brace_count -= 1
+ if in_item and brace_count == 0:
+ item_end = j + 1
+ break
+
+ item_content = items_block[item_start + match.end() - match.start():item_end - 1]
+
+ # Extract item details
+ item_data = {}
+
+ # Extract label
+ label_match = re.search(r'label:\s*"([^"]+)"', item_content)
+ if label_match:
+ item_data['label'] = label_match.group(1)
+
+ # Extract description
+ desc_match = re.search(r'description:\s*"([^"]+)"', item_content)
+ if desc_match:
+ item_data['description'] = desc_match.group(1)
+
+ # Extract inputs
+ inputs_match = re.search(r'inputs:\s*\[', item_content)
+ if inputs_match:
+ inputs_start = inputs_match.end()
+
+ # Find the end of inputs array
+ bracket_count = 1
+ inputs_end = inputs_start
+
+ for j, char in enumerate(item_content[inputs_start:], inputs_start):
+ if char == '[':
+ bracket_count += 1
+ elif char == ']':
+ bracket_count -= 1
+ if bracket_count == 0:
+ inputs_end = j
+ break
+
+ inputs_content = item_content[inputs_start:inputs_end]
+ item_data['inputs'] = parse_inputs(inputs_content)
+ else:
+ item_data['inputs'] = []
+
+ items[item_key] = item_data
+
+ return items
+
+def parse_inputs(inputs_content):
+ """Parse input array"""
+ inputs = []
+
+ # Find each input object
+ obj_starts = [m.start() for m in re.finditer(r'\{', inputs_content)]
+
+ for start in obj_starts:
+ # Find the matching closing brace
+ brace_count = 1
+ end = start + 1
+
+ for i, char in enumerate(inputs_content[start + 1:], start + 1):
+ if char == '{':
+ brace_count += 1
+ elif char == '}':
+ brace_count -= 1
+ if brace_count == 0:
+ end = i + 1
+ break
+
+ obj_content = inputs_content[start:end]
+
+ # Parse this input object
+ input_data = {}
+
+ # Extract fields
+ fields = {
+ 'name': r'name:\s*"([^"]+)"',
+ 'type': r'type:\s*"([^"]+)"',
+ 'label': r'label:\s*"([^"]+)"',
+ 'placeholder': r'placeholder:\s*["\']([^"\']+)["\']',
+ }
+
+ for field, pattern in fields.items():
+ match = re.search(pattern, obj_content)
+ if match:
+ input_data[field] = match.group(1)
+
+ # Extract required
+ req_match = re.search(r'required:\s*(true|false)', obj_content)
+ if req_match:
+ input_data['required'] = req_match.group(1) == 'true'
+
+ # Extract options if present
+ options_match = re.search(r'options:\s*\[', obj_content)
+ if options_match:
+ options_start = options_match.end()
+ bracket_count = 1
+ options_end = options_start
+
+ for i, char in enumerate(obj_content[options_start:], options_start):
+ if char == '[':
+ bracket_count += 1
+ elif char == ']':
+ bracket_count -= 1
+ if bracket_count == 0:
+ options_end = i
+ break
+
+ options_content = obj_content[options_start:options_end]
+ input_data['options'] = []
+
+ # Extract each option
+ opt_pattern = r'\{\s*value:\s*"([^"]+)"[^}]*label:\s*"([^"]+)"[^}]*\}'
+ for opt_match in re.finditer(opt_pattern, options_content):
+ input_data['options'].append({
+ 'value': opt_match.group(1),
+ 'label': opt_match.group(2)
+ })
+
+ if input_data:
+ inputs.append(input_data)
+
+ return inputs
+
+def main():
+ index_file = Path(__file__).parent / 'index.html'
+
+ if not index_file.exists():
+ print(f"Error: {index_file} not found")
+ return 1
+
+ query_defs, trans_defs = manual_extract_definitions(index_file)
+
+ # Save to JSON for inspection
+ output = {
+ 'queries': query_defs,
+ 'transitions': trans_defs
+ }
+
+ with open('extracted_definitions.json', 'w') as f:
+ json.dump(output, f, indent=2)
+
+ print(f"Extracted {sum(len(cat.get('queries', {})) for cat in query_defs.values())} queries")
+ print(f"Extracted {sum(len(cat.get('transitions', {})) for cat in trans_defs.values())} transitions")
+
+ return 0
+
+if __name__ == '__main__':
+ exit(main())
\ No newline at end of file
diff --git a/packages/wasm-sdk/fixed_definitions.json b/packages/wasm-sdk/fixed_definitions.json
new file mode 100644
index 00000000000..88cbec21441
--- /dev/null
+++ b/packages/wasm-sdk/fixed_definitions.json
@@ -0,0 +1,1658 @@
+{
+ "queries": {
+ "identity": {
+ "label": "Identity Queries",
+ "queries": {
+ "getIdentity": {
+ "label": "Get Identity",
+ "description": "Fetch an identity by its identifier",
+ "inputs": [
+ {
+ "name": "id",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getIdentityKeys": {
+ "label": "Get Identity Keys",
+ "description": "Retrieve keys associated with an identity",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ },
+ {
+ "name": "keyRequestType",
+ "type": "select",
+ "label": "Key Request Type",
+ "required": false,
+ "options": [
+ {
+ "value": "all",
+ "label": "All Keys (AllKeys {}) - Get all keys for the identity"
+ },
+ {
+ "value": "specific",
+ "label": "Specific Keys (SpecificKeys with key_ids) - Get specific keys by ID [🚧 Work in Progress]"
+ },
+ {
+ "value": "search",
+ "label": "Search Keys (SearchKey with purpose_map) - Search by purpose and security level [🚧 Work in Progress]"
+ }
+ ]
+ },
+ {
+ "name": "specificKeyIds",
+ "type": "array",
+ "label": "Specific Key IDs (required for 'specific' type)",
+ "required": false,
+ "placeholder": "0,1,2"
+ },
+ {
+ "name": "searchPurposeMap",
+ "type": "text",
+ "label": "Search Purpose Map JSON (required for 'search' type)",
+ "required": false,
+ "placeholder": "{\"0\": {\"0\": \"current\"}, \"1\": {\"0\": \"all\"}}"
+ }
+ ]
+ },
+ "getIdentitiesContractKeys": {
+ "label": "Get Identities Contract Keys",
+ "description": "Get keys for multiple identities related to a specific contract",
+ "inputs": [
+ {
+ "name": "identitiesIds",
+ "type": "array",
+ "label": "Identity IDs",
+ "required": true
+ },
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentTypeName",
+ "type": "text",
+ "label": "Document Type (optional)",
+ "required": false
+ },
+ {
+ "name": "keyRequestType",
+ "type": "select",
+ "label": "Key Request Type",
+ "required": false
+ }
+ ]
+ },
+ "getIdentityNonce": {
+ "label": "Get Identity Nonce",
+ "description": "Get the current nonce for an identity",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getIdentityContractNonce": {
+ "label": "Get Identity Contract Nonce",
+ "description": "Get the nonce for an identity in relation to a specific contract",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ },
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ }
+ ]
+ },
+ "getIdentityBalance": {
+ "label": "Get Identity Balance",
+ "description": "Get the credit balance of an identity",
+ "inputs": [
+ {
+ "name": "id",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getIdentitiesBalances": {
+ "label": "Get Identities Balances",
+ "description": "Get balances for multiple identities",
+ "inputs": [
+ {
+ "name": "identityIds",
+ "type": "array",
+ "label": "Identity IDs",
+ "required": true
+ }
+ ]
+ },
+ "getIdentityBalanceAndRevision": {
+ "label": "Get Identity Balance and Revision",
+ "description": "Get both balance and revision number for an identity",
+ "inputs": [
+ {
+ "name": "id",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getIdentityByPublicKeyHash": {
+ "label": "Get Identity by Unique Public Key Hash",
+ "description": "Find an identity by its unique public key hash",
+ "inputs": [
+ {
+ "name": "publicKeyHash",
+ "type": "text",
+ "label": "Public Key Hash",
+ "required": true,
+ "placeholder": "b7e904ce25ed97594e72f7af0e66f298031c1754"
+ }
+ ]
+ },
+ "getIdentityByNonUniquePublicKeyHash": {
+ "label": "Get Identity by Non-Unique Public Key Hash",
+ "description": "Find identities by non-unique public key hash",
+ "inputs": [
+ {
+ "name": "publicKeyHash",
+ "type": "text",
+ "label": "Public Key Hash",
+ "required": true,
+ "placeholder": "518038dc858461bcee90478fd994bba8057b7531"
+ }
+ ]
+ },
+ "getIdentityTokenBalances": {
+ "label": "Get Identity Token Balances",
+ "description": "Get token balances for an identity",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ },
+ {
+ "name": "tokenIds",
+ "type": "array",
+ "label": "Token IDs",
+ "required": true
+ }
+ ]
+ },
+ "getIdentitiesTokenBalances": {
+ "label": "Get Identities Token Balances",
+ "description": "Get token balance for multiple identities",
+ "inputs": [
+ {
+ "name": "identityIds",
+ "type": "array",
+ "label": "Identity IDs",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token ID",
+ "required": true,
+ "placeholder": "Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv"
+ }
+ ]
+ },
+ "getIdentityTokenInfos": {
+ "label": "Get Identity Token Info",
+ "description": "Get token information for an identity's tokens",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ },
+ {
+ "name": "tokenIds",
+ "type": "array",
+ "label": "Token IDs (optional)",
+ "required": false,
+ "placeholder": "[\"Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv\"]"
+ }
+ ]
+ },
+ "getIdentitiesTokenInfos": {
+ "label": "Get Identities Token Info",
+ "description": "Get token information for multiple identities with a specific token",
+ "inputs": [
+ {
+ "name": "identityIds",
+ "type": "array",
+ "label": "Identity IDs",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token ID",
+ "required": true,
+ "placeholder": "Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv"
+ }
+ ]
+ }
+ }
+ },
+ "dataContract": {
+ "label": "Data Contract Queries",
+ "queries": {
+ "getDataContract": {
+ "label": "Get Data Contract",
+ "description": "Fetch a data contract by its identifier",
+ "inputs": [
+ {
+ "name": "id",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec"
+ }
+ ]
+ },
+ "getDataContractHistory": {
+ "label": "Get Data Contract History",
+ "description": "Get the version history of a data contract",
+ "inputs": [
+ {
+ "name": "id",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec"
+ },
+ {
+ "name": "limit",
+ "type": "number",
+ "label": "Limit",
+ "required": false
+ },
+ {
+ "name": "offset",
+ "type": "number",
+ "label": "Offset",
+ "required": false
+ }
+ ]
+ },
+ "getDataContracts": {
+ "label": "Get Data Contracts",
+ "description": "Fetch multiple data contracts by their identifiers",
+ "inputs": [
+ {
+ "name": "ids",
+ "type": "array",
+ "label": "Data Contract IDs",
+ "required": true,
+ "placeholder": "[\"GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec\", \"ALybvzfcCwMs7sinDwmtumw17NneuW7RgFtFHgjKmF3A\"]"
+ }
+ ]
+ }
+ }
+ },
+ "document": {
+ "label": "Document Queries",
+ "queries": {
+ "getDocuments": {
+ "label": "Get Documents",
+ "description": "Query documents from a data contract",
+ "inputs": [
+ {
+ "name": "dataContractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec"
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true,
+ "placeholder": "domain"
+ },
+ {
+ "name": "whereClause",
+ "type": "text",
+ "label": "Where Clause (JSON)",
+ "required": false,
+ "placeholder": "[[\"normalizedParentDomainName\", \"==\", \"dash\"], [\"normalizedLabel\", \"==\", \"therea1s11mshaddy5\"]]"
+ },
+ {
+ "name": "orderBy",
+ "type": "text",
+ "label": "Order By (JSON)",
+ "required": false,
+ "placeholder": "[[\"$createdAt\", \"desc\"]]"
+ },
+ {
+ "name": "limit",
+ "type": "number",
+ "label": "Limit",
+ "required": false
+ }
+ ]
+ },
+ "getDocument": {
+ "label": "Get Document",
+ "description": "Fetch a specific document by ID",
+ "inputs": [
+ {
+ "name": "dataContractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec"
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true,
+ "placeholder": "domain"
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true,
+ "placeholder": "7NYmEKQsYtniQRUmxwdPGeVcirMoPh5ZPyAKz8BWFy3r"
+ }
+ ]
+ }
+ }
+ },
+ "dpns": {
+ "label": "DPNS Queries",
+ "queries": {
+ "getDpnsUsername": {
+ "label": "Get DPNS Usernames",
+ "description": "Get DPNS usernames for an identity",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "dpnsCheckAvailability": {
+ "label": "DPNS Check Availability",
+ "description": "Check if a DPNS username is available",
+ "inputs": [
+ {
+ "name": "label",
+ "type": "text",
+ "label": "Label (Username)",
+ "required": true
+ }
+ ]
+ },
+ "dpnsResolve": {
+ "label": "DPNS Resolve Name",
+ "description": "Resolve a DPNS name to an identity ID",
+ "inputs": [
+ {
+ "name": "name",
+ "type": "text",
+ "label": "Name",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "voting": {
+ "label": "Voting & Contested Resources",
+ "queries": {
+ "getContestedResources": {
+ "label": "Get Contested Resources",
+ "description": "Get list of contested resources",
+ "inputs": [
+ {
+ "name": "resultType",
+ "type": "select",
+ "label": "Result Type",
+ "required": true
+ },
+ {
+ "name": "documentTypeName",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "indexName",
+ "type": "text",
+ "label": "Index Name",
+ "required": true
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": false
+ }
+ ]
+ },
+ "getContestedResourceVoteState": {
+ "label": "Get Contested Resource Vote State",
+ "description": "Get the current vote state for a contested resource",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentTypeName",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "indexName",
+ "type": "text",
+ "label": "Index Name",
+ "required": true
+ }
+ ]
+ },
+ "getContestedResourceVotersForIdentity": {
+ "label": "Get Contested Resource Voters for Identity",
+ "description": "Get voters who voted for a specific identity in a contested resource",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentTypeName",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "indexName",
+ "type": "text",
+ "label": "Index Name",
+ "required": true
+ },
+ {
+ "name": "contestantId",
+ "type": "text",
+ "label": "Contestant Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getContestedResourceIdentityVotes": {
+ "label": "Get Contested Resource Identity Votes",
+ "description": "Get all votes cast by a specific identity",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "getVotePollsByEndDate": {
+ "label": "Get Vote Polls by End Date",
+ "description": "Get vote polls within a time range",
+ "inputs": [
+ {
+ "name": "startTimeMs",
+ "type": "number",
+ "label": "Start Time (ms)",
+ "required": true
+ },
+ {
+ "name": "endTimeMs",
+ "type": "number",
+ "label": "End Time (ms)",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "protocol": {
+ "label": "Protocol & Version",
+ "queries": {
+ "getProtocolVersionUpgradeState": {
+ "label": "Get Protocol Version Upgrade State",
+ "description": "Get the current state of protocol version upgrades",
+ "inputs": []
+ },
+ "getProtocolVersionUpgradeVoteStatus": {
+ "label": "Get Protocol Version Upgrade Vote Status",
+ "description": "Get voting status for protocol version upgrades",
+ "inputs": [
+ {
+ "name": "startProTxHash",
+ "type": "text",
+ "label": "Start ProTx Hash",
+ "required": true,
+ "placeholder": "143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113"
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "epoch": {
+ "label": "Epoch & Block",
+ "queries": {
+ "getEpochsInfo": {
+ "label": "Get Epochs Info",
+ "description": "Get information about epochs",
+ "inputs": [
+ {
+ "name": "epoch",
+ "type": "number",
+ "label": "Start Epoch",
+ "required": true
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": true
+ },
+ {
+ "name": "ascending",
+ "type": "checkbox",
+ "label": "Ascending Order",
+ "required": false
+ }
+ ]
+ },
+ "getCurrentEpoch": {
+ "label": "Get Current Epoch",
+ "description": "Get information about the current epoch",
+ "inputs": []
+ },
+ "getFinalizedEpochInfos": {
+ "label": "Get Finalized Epoch Info",
+ "description": "Get information about finalized epochs",
+ "inputs": [
+ {
+ "name": "startEpoch",
+ "type": "number",
+ "label": "Start Epoch",
+ "required": true
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": true
+ }
+ ]
+ },
+ "getEvonodesProposedEpochBlocksByIds": {
+ "label": "Get Evonodes Proposed Epoch Blocks by IDs",
+ "description": "Get proposed blocks by evonode IDs",
+ "inputs": [
+ {
+ "name": "ids",
+ "type": "array",
+ "label": "ProTx Hashes",
+ "required": true,
+ "placeholder": "[\"143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113\"]"
+ }
+ ]
+ },
+ "getEvonodesProposedEpochBlocksByRange": {
+ "label": "Get Evonodes Proposed Epoch Blocks by Range",
+ "description": "Get proposed blocks by range",
+ "inputs": [
+ {
+ "name": "startProTxHash",
+ "type": "text",
+ "label": "Start ProTx Hash",
+ "required": true,
+ "placeholder": "143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113"
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "token": {
+ "label": "Token Queries",
+ "queries": {
+ "getTokenStatuses": {
+ "label": "Get Token Statuses",
+ "description": "Get token statuses",
+ "inputs": [
+ {
+ "name": "tokenIds",
+ "type": "array",
+ "label": "Token IDs",
+ "required": true
+ }
+ ]
+ },
+ "getTokenDirectPurchasePrices": {
+ "label": "Get Token Direct Purchase Prices",
+ "description": "Get direct purchase prices for tokens",
+ "inputs": [
+ {
+ "name": "tokenIds",
+ "type": "array",
+ "label": "Token IDs",
+ "required": true
+ }
+ ]
+ },
+ "getTokenContractInfo": {
+ "label": "Get Token Contract Info",
+ "description": "Get information about a token contract",
+ "inputs": [
+ {
+ "name": "dataContractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta"
+ }
+ ]
+ },
+ "getTokenPerpetualDistributionLastClaim": {
+ "label": "Get Token Perpetual Distribution Last Claim",
+ "description": "Get last claim information for perpetual distribution",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token ID",
+ "required": true
+ }
+ ]
+ },
+ "getTokenTotalSupply": {
+ "label": "Get Token Total Supply",
+ "description": "Get total supply of a token",
+ "inputs": [
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token ID",
+ "required": true,
+ "placeholder": "Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv"
+ }
+ ]
+ }
+ }
+ },
+ "group": {
+ "label": "Group Queries",
+ "queries": {
+ "getGroupInfo": {
+ "label": "Get Group Info",
+ "description": "Get information about a group",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "groupContractPosition",
+ "type": "number",
+ "label": "Group Contract Position",
+ "required": true
+ }
+ ]
+ },
+ "getGroupInfos": {
+ "label": "Get Group Infos",
+ "description": "Get information about multiple groups",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "startAtGroupContractPosition",
+ "type": "number",
+ "label": "Start at Position",
+ "required": false
+ },
+ {
+ "name": "startGroupContractPositionIncluded",
+ "type": "checkbox",
+ "label": "Include Start Position",
+ "required": false
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": false
+ }
+ ]
+ },
+ "getGroupActions": {
+ "label": "Get Group Actions",
+ "description": "Get actions for a group",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "groupContractPosition",
+ "type": "number",
+ "label": "Group Contract Position",
+ "required": true
+ },
+ {
+ "name": "status",
+ "type": "select",
+ "label": "Status",
+ "required": true,
+ "options": [
+ {
+ "value": "ACTIVE",
+ "label": "Active"
+ },
+ {
+ "value": "CLOSED",
+ "label": "Closed"
+ }
+ ]
+ },
+ {
+ "name": "startActionId",
+ "type": "text",
+ "label": "Start Action ID",
+ "required": false
+ },
+ {
+ "name": "startActionIdIncluded",
+ "type": "checkbox",
+ "label": "Include Start Action",
+ "required": false
+ },
+ {
+ "name": "count",
+ "type": "number",
+ "label": "Count",
+ "required": false
+ }
+ ]
+ },
+ "getGroupActionSigners": {
+ "label": "Get Group Action Signers",
+ "description": "Get signers for a group action",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Contract ID",
+ "required": true
+ },
+ {
+ "name": "groupContractPosition",
+ "type": "number",
+ "label": "Group Contract Position",
+ "required": true
+ },
+ {
+ "name": "status",
+ "type": "select",
+ "label": "Status",
+ "required": true,
+ "options": [
+ {
+ "value": "ACTIVE",
+ "label": "Active"
+ },
+ {
+ "value": "CLOSED",
+ "label": "Closed"
+ }
+ ]
+ },
+ {
+ "name": "actionId",
+ "type": "text",
+ "label": "Action ID",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "system": {
+ "label": "System & Utility",
+ "queries": {
+ "getStatus": {
+ "label": "Get Status",
+ "description": "Get system status",
+ "inputs": []
+ },
+ "getCurrentQuorumsInfo": {
+ "label": "Get Current Quorums Info",
+ "description": "Get information about current quorums",
+ "inputs": []
+ },
+ "getPrefundedSpecializedBalance": {
+ "label": "Get Prefunded Specialized Balance",
+ "description": "Get prefunded specialized balance",
+ "inputs": [
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Specialized Balance ID",
+ "required": true,
+ "placeholder": "AzaU7zqCT7X1kxh8yWxkT9PxAgNqWDu4Gz13emwcRyAT"
+ }
+ ]
+ },
+ "getTotalCreditsInPlatform": {
+ "label": "Get Total Credits in Platform",
+ "description": "Get total credits in the platform",
+ "inputs": []
+ },
+ "getPathElements": {
+ "label": "Get Path Elements",
+ "description": "Access any data in the Dash Platform state tree. This low-level query allows direct access to GroveDB storage by specifying a path through the tree structure and keys to retrieve at that path. Common paths include: Identities (32), Tokens (96), DataContractDocuments (64), Balances (16), Votes (80), and more.",
+ "inputs": [
+ {
+ "name": "path",
+ "type": "array",
+ "label": "Path",
+ "required": true
+ },
+ {
+ "name": "keys",
+ "type": "array",
+ "label": "Keys",
+ "required": true
+ }
+ ]
+ },
+ "waitForStateTransitionResult": {
+ "label": "Wait for State Transition Result",
+ "description": "Internal query to wait for and retrieve the result of a previously submitted state transition",
+ "inputs": [
+ {
+ "name": "stateTransitionHash",
+ "type": "text",
+ "label": "State Transition Hash",
+ "required": true
+ }
+ ]
+ }
+ }
+ }
+ },
+ "transitions": {
+ "identity": {
+ "label": "Identity Transitions",
+ "transitions": {
+ "identityCreate": {
+ "label": "Identity Create",
+ "description": "Create a new identity with initial credits",
+ "inputs": [
+ {
+ "name": "publicKeys",
+ "type": "keyArray",
+ "label": "Public Keys",
+ "required": true
+ },
+ {
+ "name": "assetLockProof",
+ "type": "assetLockProof",
+ "label": "Asset Lock Proof",
+ "required": true
+ }
+ ]
+ },
+ "identityTopUp": {
+ "label": "Identity Top Up",
+ "description": "Add credits to an existing identity",
+ "inputs": [
+ {
+ "name": "assetLockProof",
+ "type": "assetLockProof",
+ "label": "Asset Lock Proof",
+ "required": true
+ }
+ ]
+ },
+ "identityUpdate": {
+ "label": "Identity Update",
+ "description": "Update identity keys (add or disable)",
+ "inputs": [
+ {
+ "name": "addPublicKeys",
+ "type": "textarea",
+ "label": "Keys to Add (JSON array)",
+ "required": false,
+ "placeholder": "[{\"keyType\":\"ECDSA_HASH160\",\"purpose\":\"AUTHENTICATION\",\"data\":\"base64_key_data\"}]"
+ },
+ {
+ "name": "disablePublicKeys",
+ "type": "text",
+ "label": "Key IDs to Disable (comma-separated)",
+ "required": false,
+ "placeholder": "2,3,5"
+ }
+ ]
+ },
+ "identityCreditTransfer": {
+ "label": "Identity Credit Transfer",
+ "description": "Transfer credits between identities",
+ "inputs": [
+ {
+ "name": "recipientId",
+ "type": "text",
+ "label": "Recipient Identity ID",
+ "required": true
+ },
+ {
+ "name": "amount",
+ "type": "number",
+ "label": "Amount (credits)",
+ "required": true
+ }
+ ]
+ },
+ "identityCreditWithdrawal": {
+ "label": "Identity Credit Withdrawal",
+ "description": "Withdraw credits from identity to Dash address",
+ "inputs": [
+ {
+ "name": "toAddress",
+ "type": "text",
+ "label": "Dash Address",
+ "required": true
+ },
+ {
+ "name": "amount",
+ "type": "number",
+ "label": "Amount (credits)",
+ "required": true
+ },
+ {
+ "name": "coreFeePerByte",
+ "type": "number",
+ "label": "Core Fee Per Byte (optional)",
+ "required": false
+ }
+ ]
+ }
+ }
+ },
+ "dataContract": {
+ "label": "Data Contract Transitions",
+ "transitions": {
+ "dataContractCreate": {
+ "label": "Data Contract Create",
+ "description": "Create a new data contract",
+ "inputs": [
+ {
+ "name": "canBeDeleted",
+ "type": "checkbox",
+ "label": "Can Be Deleted",
+ "required": false
+ },
+ {
+ "name": "readonly",
+ "type": "checkbox",
+ "label": "Read Only",
+ "required": false
+ },
+ {
+ "name": "keepsHistory",
+ "type": "checkbox",
+ "label": "Keeps History",
+ "required": false
+ },
+ {
+ "name": "documentsKeepHistoryContractDefault",
+ "type": "checkbox",
+ "label": "Documents Keep History (Default)",
+ "required": false
+ },
+ {
+ "name": "documentsMutableContractDefault",
+ "type": "checkbox",
+ "label": "Documents Mutable (Default)",
+ "required": false,
+ "defaultValue": true
+ },
+ {
+ "name": "documentsCanBeDeletedContractDefault",
+ "type": "checkbox",
+ "label": "Documents Can Be Deleted (Default)",
+ "required": false,
+ "defaultValue": true
+ },
+ {
+ "name": "requiresIdentityEncryptionBoundedKey",
+ "type": "text",
+ "label": "Requires Identity Encryption Key (optional)",
+ "required": false
+ },
+ {
+ "name": "requiresIdentityDecryptionBoundedKey",
+ "type": "text",
+ "label": "Requires Identity Decryption Key (optional)",
+ "required": false
+ },
+ {
+ "name": "documentSchemas",
+ "type": "json",
+ "label": "Document Schemas JSON",
+ "required": true,
+ "placeholder": "{\n \"note\": {\n \"type\": \"object\",\n \"properties\": {\n \"message\": {\n \"type\": \"string\",\n \"maxLength\": 100,\n \"position\": 0\n }\n },\n \"required\": [\"message\"],\n \"additionalProperties\": false\n }\n}"
+ },
+ {
+ "name": "groups",
+ "type": "json",
+ "label": "Groups (optional)",
+ "required": false,
+ "placeholder": "{}"
+ },
+ {
+ "name": "tokens",
+ "type": "json",
+ "label": "Tokens (optional)",
+ "required": false,
+ "placeholder": "{}"
+ },
+ {
+ "name": "keywords",
+ "type": "text",
+ "label": "Keywords (comma separated, optional)",
+ "required": false
+ },
+ {
+ "name": "description",
+ "type": "text",
+ "label": "Description (optional)",
+ "required": false
+ }
+ ]
+ },
+ "dataContractUpdate": {
+ "label": "Data Contract Update",
+ "description": "Add document types, groups, or tokens to an existing data contract",
+ "inputs": [
+ {
+ "name": "dataContractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "newDocumentSchemas",
+ "type": "json",
+ "label": "New Document Schemas to Add (optional)",
+ "required": false,
+ "placeholder": "{\n \"newType\": {\n \"type\": \"object\",\n \"properties\": {\n \"field\": {\n \"type\": \"string\",\n \"maxLength\": 100,\n \"position\": 0\n }\n },\n \"required\": [\"field\"],\n \"additionalProperties\": false\n }\n}"
+ },
+ {
+ "name": "newGroups",
+ "type": "json",
+ "label": "New Groups to Add (optional)",
+ "required": false,
+ "placeholder": "{}"
+ },
+ {
+ "name": "newTokens",
+ "type": "json",
+ "label": "New Tokens to Add (optional)",
+ "required": false,
+ "placeholder": "{}"
+ }
+ ]
+ }
+ }
+ },
+ "document": {
+ "label": "Document Transitions",
+ "transitions": {
+ "documentCreate": {
+ "label": "Document Create",
+ "description": "Create a new document",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "fetchSchema",
+ "type": "button",
+ "label": "Fetch Schema",
+ "action": "fetchDocumentSchema"
+ },
+ {
+ "name": "documentFields",
+ "type": "dynamic",
+ "label": "Document Fields"
+ }
+ ]
+ },
+ "documentReplace": {
+ "label": "Document Replace",
+ "description": "Replace an existing document",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true
+ },
+ {
+ "name": "loadDocument",
+ "type": "button",
+ "label": "Load Document",
+ "action": "loadExistingDocument"
+ },
+ {
+ "name": "documentFields",
+ "type": "dynamic",
+ "label": "Document Fields"
+ }
+ ]
+ },
+ "documentDelete": {
+ "label": "Document Delete",
+ "description": "Delete an existing document",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true
+ }
+ ]
+ },
+ "documentTransfer": {
+ "label": "Document Transfer",
+ "description": "Transfer document ownership",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true
+ },
+ {
+ "name": "recipientId",
+ "type": "text",
+ "label": "Recipient Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "documentPurchase": {
+ "label": "Document Purchase",
+ "description": "Purchase a document",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true
+ },
+ {
+ "name": "price",
+ "type": "number",
+ "label": "Price (credits)",
+ "required": true
+ }
+ ]
+ },
+ "documentSetPrice": {
+ "label": "Document Set Price",
+ "description": "Set or update document price",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "documentType",
+ "type": "text",
+ "label": "Document Type",
+ "required": true
+ },
+ {
+ "name": "documentId",
+ "type": "text",
+ "label": "Document ID",
+ "required": true
+ },
+ {
+ "name": "price",
+ "type": "number",
+ "label": "Price (credits, 0 to remove)",
+ "required": true
+ }
+ ]
+ },
+ "dpnsRegister": {
+ "label": "DPNS Register Name",
+ "description": "Register a new DPNS username",
+ "inputs": [
+ {
+ "name": "label",
+ "type": "text",
+ "label": "Username",
+ "required": true,
+ "placeholder": "Enter username (e.g., alice)",
+ "validateOnType": true
+ }
+ ]
+ }
+ }
+ },
+ "token": {
+ "label": "Token Transitions",
+ "transitions": {
+ "tokenBurn": {
+ "label": "Token Burn",
+ "description": "Burn tokens",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenPosition",
+ "type": "number",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "amount",
+ "type": "text",
+ "label": "Amount to Burn",
+ "required": true
+ },
+ {
+ "name": "keyId",
+ "type": "number",
+ "label": "Key ID (for signing)",
+ "required": true
+ },
+ {
+ "name": "publicNote",
+ "type": "text",
+ "label": "Public Note",
+ "required": false
+ }
+ ]
+ },
+ "tokenMint": {
+ "label": "Token Mint",
+ "description": "Mint new tokens",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenPosition",
+ "type": "number",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "amount",
+ "type": "text",
+ "label": "Amount to Mint",
+ "required": true
+ },
+ {
+ "name": "keyId",
+ "type": "number",
+ "label": "Key ID (for signing)",
+ "required": true
+ },
+ {
+ "name": "issuedToIdentityId",
+ "type": "text",
+ "label": "Issue To Identity ID",
+ "required": false
+ },
+ {
+ "name": "publicNote",
+ "type": "text",
+ "label": "Public Note",
+ "required": false
+ }
+ ]
+ },
+ "tokenTransfer": {
+ "label": "Token Transfer",
+ "description": "Transfer tokens to another identity",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "amount",
+ "type": "number",
+ "label": "Amount to Transfer",
+ "required": true
+ },
+ {
+ "name": "recipientId",
+ "type": "text",
+ "label": "Recipient Identity ID",
+ "required": true
+ }
+ ]
+ },
+ "tokenFreeze": {
+ "label": "Token Freeze",
+ "description": "Freeze tokens for an identity",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID to Freeze",
+ "required": true
+ }
+ ]
+ },
+ "tokenUnfreeze": {
+ "label": "Token Unfreeze",
+ "description": "Unfreeze tokens for an identity",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID to Unfreeze",
+ "required": true
+ }
+ ]
+ },
+ "tokenDestroyFrozen": {
+ "label": "Token Destroy Frozen Funds",
+ "description": "Destroy frozen tokens",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true
+ },
+ {
+ "name": "tokenId",
+ "type": "text",
+ "label": "Token Contract Position",
+ "required": true
+ },
+ {
+ "name": "identityId",
+ "type": "text",
+ "label": "Identity ID",
+ "required": true
+ }
+ ]
+ }
+ }
+ },
+ "voting": {
+ "label": "Voting Transitions",
+ "transitions": {
+ "dpnsUsername": {
+ "label": "DPNS Username",
+ "description": "Cast a vote for a contested DPNS username",
+ "inputs": [
+ {
+ "name": "contestedUsername",
+ "type": "text",
+ "label": "Contested Username",
+ "required": true,
+ "placeholder": "Enter the contested username (e.g., 'myusername')"
+ },
+ {
+ "name": "voteChoice",
+ "type": "select",
+ "label": "Vote Choice",
+ "required": true,
+ "options": [
+ {
+ "value": "abstain",
+ "label": "Abstain"
+ },
+ {
+ "value": "lock",
+ "label": "Lock (Give to no one)"
+ },
+ {
+ "value": "towardsIdentity",
+ "label": "Vote for Identity"
+ }
+ ]
+ },
+ {
+ "name": "targetIdentity",
+ "type": "text",
+ "label": "Target Identity ID (if voting for identity)",
+ "required": false,
+ "placeholder": "Identity ID to vote for",
+ "dependsOn": {
+ "field": "voteChoice",
+ "value": "towardsIdentity"
+ }
+ }
+ ]
+ },
+ "masternodeVote": {
+ "label": "Contested Resource",
+ "description": "Cast a vote for contested resources as a masternode",
+ "inputs": [
+ {
+ "name": "contractId",
+ "type": "text",
+ "label": "Data Contract ID",
+ "required": true,
+ "placeholder": "Contract ID containing the contested resource"
+ },
+ {
+ "name": "fetchContestedResources",
+ "type": "button",
+ "label": "Get Contested Resources",
+ "action": "fetchContestedResources"
+ },
+ {
+ "name": "contestedResourceDropdown",
+ "type": "dynamic",
+ "label": "Contested Resources"
+ },
+ {
+ "name": "voteChoice",
+ "type": "select",
+ "label": "Vote Choice",
+ "required": true,
+ "options": [
+ {
+ "value": "abstain",
+ "label": "Abstain"
+ },
+ {
+ "value": "lock",
+ "label": "Lock (Give to no one)"
+ },
+ {
+ "value": "towardsIdentity",
+ "label": "Vote for Identity"
+ }
+ ]
+ },
+ {
+ "name": "targetIdentity",
+ "type": "text",
+ "label": "Target Identity ID (if voting for identity)",
+ "required": false,
+ "placeholder": "Identity ID to vote for",
+ "dependsOn": {
+ "field": "voteChoice",
+ "value": "towardsIdentity"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/wasm-sdk/generate_docs.py b/packages/wasm-sdk/generate_docs.py
new file mode 100755
index 00000000000..7eaf35a2707
--- /dev/null
+++ b/packages/wasm-sdk/generate_docs.py
@@ -0,0 +1,1791 @@
+#!/usr/bin/env python3
+"""
+Documentation generator for WASM JS SDK
+Extracts query and state transition definitions from index.html
+and generates both user documentation (HTML) and AI reference (Markdown)
+"""
+
+import os
+import re
+import json
+import html
+from pathlib import Path
+from datetime import datetime
+
+def extract_definitions_from_html(html_content):
+ """Extract query and state transition definitions from index.html"""
+
+ # Extract queryDefinitions
+ query_match = re.search(r'const queryDefinitions = ({[\s\S]*?});(?=\s*(?:const|//|$))', html_content)
+ query_definitions = {}
+ if query_match:
+ # Clean up the JavaScript object to make it JSON-parseable
+ query_str = query_match.group(1)
+ # Convert JS object to JSON format
+ query_str = re.sub(r'(\w+):', r'"\1":', query_str) # Add quotes to keys
+ query_str = re.sub(r',\s*}', '}', query_str) # Remove trailing commas
+ query_str = re.sub(r',\s*]', ']', query_str) # Remove trailing commas in arrays
+ # Handle functions and complex values
+ query_str = re.sub(r'dependsOn:\s*{[^}]+}', '"dependsOn": {}', query_str)
+ query_str = re.sub(r'action:\s*"[^"]*"', '"action": ""', query_str)
+ query_str = re.sub(r'dynamic:\s*true', '"dynamic": true', query_str)
+ query_str = re.sub(r'defaultValue:\s*true', '"defaultValue": true', query_str)
+ query_str = re.sub(r'validateOnType:\s*true', '"validateOnType": true', query_str)
+
+ try:
+ query_definitions = json.loads(query_str)
+ except json.JSONDecodeError as e:
+ print(f"Warning: Could not parse query definitions: {e}")
+ # Fallback to regex extraction
+ query_definitions = extract_definitions_regex(html_content, 'queryDefinitions')
+
+ # Extract stateTransitionDefinitions
+ transition_match = re.search(r'const stateTransitionDefinitions = ({[\s\S]*?});(?=\s*(?:const|//|$))', html_content)
+ transition_definitions = {}
+ if transition_match:
+ trans_str = transition_match.group(1)
+ trans_str = re.sub(r'(\w+):', r'"\1":', trans_str)
+ trans_str = re.sub(r',\s*}', '}', trans_str)
+ trans_str = re.sub(r',\s*]', ']', trans_str)
+ trans_str = re.sub(r'dependsOn:\s*{[^}]+}', '"dependsOn": {}', trans_str)
+ trans_str = re.sub(r'action:\s*"[^"]*"', '"action": ""', trans_str)
+ trans_str = re.sub(r'dynamic:\s*true', '"dynamic": true', trans_str)
+ trans_str = re.sub(r'defaultValue:\s*true', '"defaultValue": true', trans_str)
+ trans_str = re.sub(r'validateOnType:\s*true', '"validateOnType": true', trans_str)
+
+ try:
+ transition_definitions = json.loads(trans_str)
+ except json.JSONDecodeError as e:
+ print(f"Warning: Could not parse transition definitions: {e}")
+ transition_definitions = extract_definitions_regex(html_content, 'stateTransitionDefinitions')
+
+ return query_definitions, transition_definitions
+
+def extract_definitions_regex(html_content, definition_name):
+ """Robust regex extraction method for JavaScript object definitions"""
+ definitions = {}
+
+ # Find the complete definition block
+ pattern = rf'const {definition_name} = (\{{(?:[^{{}}]|{{[^{{}}]*}})*\}});'
+ match = re.search(pattern, html_content, re.DOTALL)
+ if not match:
+ return definitions
+
+ full_def = match.group(1)
+
+ # Extract each category
+ cat_pattern = r'(\w+):\s*\{[^}]*label:\s*"([^"]+)"[^}]*(?:queries|transitions):\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}'
+
+ for cat_match in re.finditer(cat_pattern, full_def, re.DOTALL):
+ cat_key = cat_match.group(1)
+ cat_label = cat_match.group(2)
+ items_block = cat_match.group(3)
+
+ items_key = 'queries' if 'query' in definition_name else 'transitions'
+ definitions[cat_key] = {
+ 'label': cat_label,
+ items_key: {}
+ }
+
+ # Extract individual queries/transitions
+ item_pattern = r'(\w+):\s*\{([^}]+(?:\{[^}]*\}[^}]*)*)\}'
+
+ for item_match in re.finditer(item_pattern, items_block):
+ item_key = item_match.group(1)
+ item_content = item_match.group(2)
+
+ # Extract item details
+ item_data = {}
+
+ # Extract label
+ label_match = re.search(r'label:\s*"([^"]+)"', item_content)
+ if label_match:
+ item_data['label'] = label_match.group(1)
+
+ # Extract description
+ desc_match = re.search(r'description:\s*"([^"]+)"', item_content)
+ if desc_match:
+ item_data['description'] = desc_match.group(1)
+
+ # Extract inputs array
+ inputs_match = re.search(r'inputs:\s*\[([^\]]+(?:\[[^\]]*\][^\]]*)*)\]', item_content, re.DOTALL)
+ if inputs_match:
+ inputs_str = inputs_match.group(1)
+ item_data['inputs'] = extract_inputs(inputs_str)
+ else:
+ item_data['inputs'] = []
+
+ definitions[cat_key][items_key][item_key] = item_data
+
+ return definitions
+
+def generate_example_code(query_key, inputs):
+ """Generate example code for a query"""
+
+ # Test data for various query types
+ # Using a known testnet identity with activity
+ test_data = {
+ 'identity_id': '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk',
+ 'specialized_balance_id': 'AzaU7zqCT7X1kxh8yWxkT9PxAgNqWDu4Gz13emwcRyAT',
+ 'contract_id': 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
+ 'data_contract_id': 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
+ 'token_contract_id': 'ALybvzfcCwMs7sinDwmtumw17NneuW7RgFtFHgjKmF3A',
+ 'group_contract_id': '49PJEnNx7ReCitzkLdkDNr4s6RScGsnNexcdSZJ1ph5N',
+ 'public_key_hash_unique': 'b7e904ce25ed97594e72f7af0e66f298031c1754',
+ 'public_key_hash_non_unique': '518038dc858461bcee90478fd994bba8057b7531',
+ 'pro_tx_hash': '143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113',
+ 'token_id': 'Hqyu8WcRwXCTwbNxdga4CN5gsVEGc67wng4TFzceyLUv',
+ 'document_type': 'domain',
+ 'document_id': '7NYmEKQsYtniQRUmxwdPGeVcirMoPh5ZPyAKz8BWFy3r',
+ 'username': 'alice',
+ 'epoch': 8635
+ }
+
+ # Map input names to test values
+ param_mapping = {
+ 'id': f"'{test_data['data_contract_id']}'" if 'getDataContract' in query_key else f"'{test_data['identity_id']}'",
+ 'identityId': f"'{test_data['specialized_balance_id']}'" if 'getPrefundedSpecializedBalance' in query_key else f"'{test_data['identity_id']}'",
+ 'ids': f"['{test_data['data_contract_id']}', '{test_data['token_contract_id']}']" if 'getDataContracts' in query_key else f"['{test_data['pro_tx_hash']}']" if 'Evonodes' in query_key else f"['{test_data['identity_id']}']",
+ 'identitiesIds': f"['{test_data['identity_id']}']",
+ 'identityIds': f"['{test_data['identity_id']}']",
+ 'contractId': f"'{test_data['group_contract_id']}'" if ('group' in query_key.lower() or 'Group' in query_key) else f"'{test_data['token_contract_id']}'" if ('token' in query_key.lower() or 'Token' in query_key) and 'TokenBalance' not in query_key and 'TokenInfo' not in query_key else f"'{test_data['contract_id']}'",
+ 'dataContractId': "'EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta'" if 'getTokenContractInfo' in query_key else f"'{test_data['data_contract_id']}'",
+ 'publicKeyHash': f"'{test_data['public_key_hash_unique']}'" if 'ByPublicKeyHash' in query_key and 'NonUnique' not in query_key else f"'{test_data['public_key_hash_non_unique']}'",
+ 'startProTxHash': f"'{test_data['pro_tx_hash']}'",
+ 'tokenId': "'EETVvWgohFDKtbB3ejEzBcDRMNYkc9TtgXY6y8hzP3Ta'" if 'getTokenPerpetualDistributionLastClaim' in query_key else f"'{test_data['token_id']}'",
+ 'tokenIds': f"['{test_data['token_id']}', 'H7FRpZJqZK933r9CzZMsCuf1BM34NT5P2wSJyjDkprqy']" if 'getTokenStatuses' in query_key else "['H7FRpZJqZK933r9CzZMsCuf1BM34NT5P2wSJyjDkprqy']" if 'getTokenDirectPurchasePrices' in query_key else f"['{test_data['token_id']}']",
+ 'documentType': f"'{test_data['document_type']}'",
+ 'documentId': f"'{test_data['document_id']}'",
+ 'label': f"'{test_data['username']}'",
+ 'name': f"'{test_data['username']}'",
+ 'epoch': '1000' if 'getEpochsInfo' in query_key else test_data['epoch'],
+ 'keyRequestType': "'all'",
+ 'limit': '10',
+ 'count': '100',
+ 'offset': '0',
+ 'startEpoch': '8635',
+ 'startTimeMs': 'Date.now() - 86400000', # 24 hours ago
+ 'endTimeMs': 'Date.now()',
+ 'ascending': 'true',
+ 'orderAscending': 'true',
+ 'resultType': "'documents'",
+ 'documentTypeName': "'domain'",
+ 'indexName': "'parentNameAndLabel'",
+ 'contestantId': f"'{test_data['identity_id']}'",
+ 'amount': '1000000',
+ 'recipientId': f"'{test_data['identity_id']}'",
+ 'toAddress': "'yNPbcFfabtNmmxKdGwhHomdYfVs6gikbPf'",
+ 'whereClause': 'JSON.stringify([["normalizedParentDomainName", "==", "dash"]])',
+ 'orderBy': 'JSON.stringify([["normalizedLabel", "asc"]])',
+ 'groupContractPosition': '0',
+ 'groupContractPositions': '[0]',
+ 'startAtGroupContractPosition': '0',
+ 'startGroupContractPositionIncluded': 'false',
+ 'status': "'ACTIVE'",
+ 'startActionId': "'0'",
+ 'startActionIdIncluded': 'false',
+ 'actionId': "'6XJzL6Qb8Zhwxt4HFwh8NAn7q1u4dwdoUf8EmgzDudFZ'",
+ 'path': "['96']",
+ 'keys': f"['{test_data['identity_id']}']",
+ 'stateTransitionHash': "'0000000000000000000000000000000000000000000000000000000000000000'"
+ }
+
+ # Handle special cases for functions with structured parameters
+ if query_key == 'getGroupInfos':
+ # getGroupInfos expects: sdk, contractId, startAtInfo (object or null), count
+ params = [f"'{test_data['group_contract_id']}'", "null", "100"]
+ elif query_key == 'getGroupActions':
+ # getGroupActions expects: sdk, contractId, groupContractPosition, status, startAtInfo (object or null), count
+ params = [f"'{test_data['group_contract_id']}'", "0", "'ACTIVE'", "null", "100"]
+ else:
+ # Generate parameters normally
+ params = []
+ for input_def in inputs:
+ name = input_def.get('name', '')
+ if name in param_mapping:
+ params.append(str(param_mapping[name]))
+ elif input_def.get('required', False):
+ # Generate a default value based on type
+ if input_def.get('type') == 'array':
+ params.append('[]')
+ elif input_def.get('type') == 'number':
+ params.append('100')
+ elif input_def.get('type') == 'checkbox':
+ params.append('false')
+ else:
+ params.append('""')
+
+ # Handle special function name mappings
+ func_name_map = {
+ 'getIdentity': 'identity_fetch',
+ 'getIdentityKeys': 'get_identity_keys',
+ 'getIdentitiesContractKeys': 'get_identities_contract_keys',
+ 'getIdentityNonce': 'get_identity_nonce',
+ 'getIdentityContractNonce': 'get_identity_contract_nonce',
+ 'getIdentityBalance': 'get_identity_balance',
+ 'getIdentitiesBalances': 'get_identities_balances',
+ 'getIdentityBalanceAndRevision': 'get_identity_balance_and_revision',
+ 'getIdentityByPublicKeyHash': 'get_identity_by_public_key_hash',
+ 'getIdentityByNonUniquePublicKeyHash': 'get_identity_by_non_unique_public_key_hash',
+ 'getDataContract': 'data_contract_fetch',
+ 'getDataContractHistory': 'get_data_contract_history',
+ 'getDataContracts': 'get_data_contracts',
+ 'getDocuments': 'get_documents',
+ 'getDocument': 'get_document',
+ 'getDpnsUsername': 'get_dpns_usernames',
+ 'dpnsCheckAvailability': 'dpns_is_name_available',
+ 'dpnsResolve': 'dpns_resolve_name',
+ 'getContestedResources': 'get_contested_resources',
+ 'getContestedResourceVoteState': 'get_contested_resource_vote_state',
+ 'getContestedResourceVotersForIdentity': 'get_contested_resource_voters_for_identity',
+ 'getContestedResourceIdentityVotes': 'get_contested_resource_identity_votes',
+ 'getVotePollsByEndDate': 'get_vote_polls_by_end_date',
+ 'getProtocolVersionUpgradeState': 'get_protocol_version_upgrade_state',
+ 'getProtocolVersionUpgradeVoteStatus': 'get_protocol_version_upgrade_vote_status',
+ 'getEpochsInfo': 'get_epochs_info',
+ 'getCurrentEpoch': 'get_current_epoch',
+ 'getFinalizedEpochInfos': 'get_finalized_epoch_infos',
+ 'getEvonodesProposedEpochBlocksByIds': 'get_evonodes_proposed_epoch_blocks_by_ids',
+ 'getEvonodesProposedEpochBlocksByRange': 'get_evonodes_proposed_epoch_blocks_by_range',
+ 'getIdentityTokenBalances': 'get_identity_token_balances',
+ 'getIdentitiesTokenBalances': 'get_identities_token_balances',
+ 'getIdentityTokenInfos': 'get_identity_token_infos',
+ 'getIdentitiesTokenInfos': 'get_identities_token_infos',
+ 'getTokenStatuses': 'get_token_statuses',
+ 'getTokenDirectPurchasePrices': 'get_token_direct_purchase_prices',
+ 'getTokenContractInfo': 'get_token_contract_info',
+ 'getTokenPerpetualDistributionLastClaim': 'get_token_perpetual_distribution_last_claim',
+ 'getTokenTotalSupply': 'get_token_total_supply',
+ 'getGroupInfo': 'get_group_info',
+ 'getGroupInfos': 'get_group_infos',
+ 'getGroupActions': 'get_group_actions',
+ 'getGroupActionSigners': 'get_group_action_signers',
+ 'getStatus': 'get_status',
+ 'getCurrentQuorumsInfo': 'get_current_quorums_info',
+ 'getPrefundedSpecializedBalance': 'get_prefunded_specialized_balance',
+ 'getTotalCreditsInPlatform': 'get_total_credits_in_platform',
+ 'getPathElements': 'get_path_elements',
+ 'waitForStateTransitionResult': 'wait_for_state_transition_result'
+ }
+
+ func_name = func_name_map.get(query_key, query_key)
+
+ # Add sdk as first parameter for all functions
+ all_params = ['sdk'] + params
+
+ # Generate the function call (functions are imported directly, not methods on sdk)
+ return f'return await window.wasmFunctions.{func_name}({", ".join(all_params)});'
+
+def extract_inputs(inputs_str):
+ """Extract input definitions from JavaScript array string"""
+ inputs = []
+
+ # Match individual input objects
+ input_pattern = r'\{([^}]+(?:\{[^}]*\}[^}]*)*)\}'
+
+ for match in re.finditer(input_pattern, inputs_str):
+ input_content = match.group(1)
+ input_data = {}
+
+ # Extract name
+ name_match = re.search(r'name:\s*"([^"]+)"', input_content)
+ if name_match:
+ input_data['name'] = name_match.group(1)
+
+ # Extract type
+ type_match = re.search(r'type:\s*"([^"]+)"', input_content)
+ if type_match:
+ input_data['type'] = type_match.group(1)
+
+ # Extract label
+ label_match = re.search(r'label:\s*"([^"]+)"', input_content)
+ if label_match:
+ input_data['label'] = label_match.group(1)
+
+ # Extract required
+ req_match = re.search(r'required:\s*(true|false)', input_content)
+ if req_match:
+ input_data['required'] = req_match.group(1) == 'true'
+
+ # Extract placeholder
+ placeholder_match = re.search(r'placeholder:\s*["\']([^"\']+)["\']', input_content)
+ if placeholder_match:
+ input_data['placeholder'] = placeholder_match.group(1)
+
+ # Extract options if present
+ options_match = re.search(r'options:\s*\[([^\]]+)\]', input_content)
+ if options_match:
+ options_str = options_match.group(1)
+ input_data['options'] = []
+
+ # Extract each option
+ opt_pattern = r'\{\s*value:\s*"([^"]+)"[^}]*label:\s*"([^"]+)"[^}]*\}'
+ for opt_match in re.finditer(opt_pattern, options_str):
+ input_data['options'].append({
+ 'value': opt_match.group(1),
+ 'label': opt_match.group(2)
+ })
+
+ if input_data:
+ inputs.append(input_data)
+
+ return inputs
+
+def generate_sidebar_entries(definitions, type_prefix, section_class=""):
+ """Generate sidebar entries for queries or transitions"""
+ html = ""
+ for cat_key, category in definitions.items():
+ html += f' {category.get("label", cat_key)} \n'
+ items = category.get('queries' if type_prefix == 'query' else 'transitions', {})
+ for item_key in items:
+ item = items[item_key]
+ html += f' {item.get("label", item_key)} \n'
+ return html
+
+def generate_operation_docs(definitions, type_name, type_prefix):
+ """Generate documentation for operations (queries or transitions)"""
+ html = ""
+ for cat_key, category in definitions.items():
+ html += f'''\n
+
{category.get('label', cat_key)}
+'''
+
+ items_key = 'queries' if type_prefix == 'query' else 'transitions'
+ items = category.get(items_key, {})
+ for item_key, item in items.items():
+ html += generate_operation_entry(item_key, item, type_prefix)
+
+ html += ' '
+ return html
+
+def generate_operation_entry(operation_key, operation, type_prefix):
+ """Generate documentation for a single operation"""
+ html = f'''
+
{operation.get('label', operation_key)}
+
{operation.get('description', 'No description available')}
+
+
+
Parameters:
+'''
+
+ inputs = operation.get('inputs', [])
+ if not inputs:
+ html += '
No parameters required
'
+ else:
+ for param in inputs:
+ html += generate_parameter_entry(param)
+
+ html += '''
+
+
+
Example
+'''
+
+ if type_prefix == 'query':
+ example_code = generate_example_code(operation_key, inputs)
+ html += f'
{example_code}
\n'
+
+ # Special handling for certain operations
+ if operation_key == 'waitForStateTransitionResult':
+ html += '
This is an internal query used to wait for and retrieve the result of a previously submitted state transition. It requires a valid state transition hash from a prior operation.
'
+ else:
+ html += f'
Run '
+ if operation_key in ['getPathElements', 'getDataContractHistory', 'getContestedResourceVotersForIdentity', 'getTokenPerpetualDistributionLastClaim']:
+ html += '
🚧 Work in Progress '
+
+ # Add special examples and info
+ if operation_key == 'getIdentityKeys':
+ html += '''\n
+
Example 2 - Get Specific Keys
+
return await window.wasmFunctions.get_identity_keys(sdk, \'5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk\', \'specific\', [0, 1, 2]);
+
Run
+
+
'''
+ elif operation_key == 'getPathElements':
+ html += generate_path_elements_info()
+
+ html += f'\n
'
+ else:
+ # State transitions don't have run buttons
+ html += f'
{generate_transition_example(operation_key)}
'
+
+ html += '''
+
+'''
+ return html
+
+def generate_parameter_entry(param):
+ """Generate documentation for a single parameter"""
+ required_text = '(required) ' if param.get('required', False) else '(optional) '
+ html = f'''
+ {param.get('label', param.get('name', 'Unknown'))}
+ {param.get('type', 'text')}
+ {required_text}
+'''
+ if param.get('placeholder'):
+ html += f' Example: {html.escape(param.get("placeholder"))} \n'
+ elif param.get('name') == 'limit' and not param.get('required', False):
+ html += ' Default: 100 (maximum items returned if not specified) \n'
+ if param.get('options'):
+ html += ' Options: '
+ opts = [f'{opt.get("label", opt.get("value"))}' for opt in param.get('options', [])]
+ html += ', '.join(opts)
+ html += ' \n'
+ html += '
\n'
+ return html
+
+def generate_transition_example(trans_key):
+ """Generate example code for state transitions"""
+ if trans_key == 'documentCreate':
+ return '''const result = await sdk.document_create(
+ identityHex,
+ contractId,
+ "note",
+ JSON.stringify({ message: "Hello!" }),
+ privateKeyHex
+);'''
+ elif trans_key == 'tokenTransfer':
+ return '''const result = await sdk.token_transfer(
+ identityHex,
+ contractId,
+ tokenId,
+ 1000000, // amount
+ recipientId,
+ privateKeyHex
+);'''
+ else:
+ return f'const result = await sdk.{trans_key}(identityHex, /* params */, privateKeyHex);'
+
+def generate_path_elements_info():
+ """Generate path elements documentation"""
+ return '''\n
+
Common Path Values:
+
+ Path Value Description
+ 64Data Contract Documents
+ 32Identities
+ 24Unique Public Key Hashes to Identities
+ 8Non-Unique Public Key Hashes to Identities
+ 16Tokens
+ 48Pools
+ 40Prefunded Specialized Balances
+ 72Spent Asset Lock Transactions
+ 80Withdrawal Transactions
+ 88Group Actions
+ 96Balances
+ 104Misc
+ 112Votes
+ 120Versions
+
+
Example Paths:
+
+ [32, identity_id] - Access identity data
+ [96, identity_id] - Access identity balance
+ [16, contract_id, token_id] - Access token info
+ [64, contract_id, 1, document_type] - Access documents by type
+ [88, contract_id, group_position] - Access group actions
+ [112] - Access votes tree
+
+
'''
+
+def generate_user_docs_html(query_defs, transition_defs):
+ """Generate user-friendly HTML documentation"""
+
+ html_content = '''
+
+
+
+
+ Dash Platform WASM JS SDK Documentation
+
+
+
+
+
+
+
+
+
+
Loading WASM module...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Dash Platform WASM JS SDK Documentation
+
+
+
Overview
+
The Dash Platform WASM JS SDK provides a WebAssembly-based interface for interacting with the Dash Platform from JavaScript and TypeScript applications.
+ This documentation covers all available queries and state transitions.
+
+
Key Concepts
+
+ Queries : Read-only operations that fetch data from the platform
+ State Transitions : Write operations that modify state on the platform
+ Proofs : Cryptographic proofs can be requested for most queries to verify data authenticity
+ Credits : The platform's unit of account for paying transaction fees
+ Default Limits : All queries with optional limit parameters default to a maximum of 100 items if not specified
+
+
+
Note: All examples below can be run directly in your browser using the testnet. Click the "Run" button to execute any example.
+
+
+ Test Identity: All examples use the testnet identity 5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk
+ This is a known identity with activity on testnet that you can use for testing.
+
+
+
+
Queries
+'''
+
+ # Add query documentation
+ html_content += generate_operation_docs(query_defs, 'query', 'query')
+
+ # Add state transition documentation
+ html_content += '
State Transitions '
+ html_content += generate_operation_docs(transition_defs, 'transition', 'transition')
+
+ # Close main content div
+ html_content += '''
+
↑ Top
+
+
+
+
+
+'''
+
+ return html_content
+
+def generate_ai_reference_md(query_defs, transition_defs):
+ """Generate AI-friendly markdown reference"""
+
+ md_content = '''# Dash Platform WASM JS SDK - AI Reference
+
+## Overview
+The Dash Platform WASM JS SDK provides WebAssembly bindings for interacting with Dash Platform from JavaScript/TypeScript. This reference is optimized for AI understanding and quick implementation.
+
+## Quick Setup
+```javascript
+// Import and initialize
+import init, { WasmSdk } from './pkg/wasm_sdk.js';
+
+await init();
+const transport = {
+ url: "https://52.12.176.90:1443/", // testnet
+ network: "testnet"
+};
+const proofs = true; // Enable proof verification
+const sdk = await WasmSdk.new(transport, proofs);
+```
+
+## Authentication
+Most state transitions require authentication:
+```javascript
+const identityHex = "hex_encoded_identity";
+const privateKeyHex = "hex_encoded_private_key";
+```
+
+## Query Operations
+
+### Pattern
+All queries follow this pattern:
+```javascript
+const result = await sdk.{query_name}(param1, param2, ...);
+```
+
+### Available Queries
+'''
+
+ # Document all queries
+ for cat_key, category in query_defs.items():
+ md_content += f"\n#### {category.get('label', cat_key)}\n"
+
+ queries = category.get('queries', {})
+ for query_key, query in queries.items():
+ md_content += f"\n**{query.get('label', query_key)}** - `{query_key}`\n"
+ md_content += f"*{query.get('description', 'No description')}*\n\n"
+
+ # Parameters
+ inputs = query.get('inputs', [])
+ if inputs:
+ md_content += "Parameters:\n"
+ for param in inputs:
+ req = "required" if param.get('required', False) else "optional"
+ md_content += f"- `{param.get('name', 'unknown')}` ({param.get('type', 'text')}, {req})"
+
+ if param.get('label') and param.get('label') != param.get('name'):
+ md_content += f" - {param.get('label')}"
+
+ if param.get('placeholder'):
+ md_content += f"\n - Example: `{param.get('placeholder')}`"
+
+ if param.get('options'):
+ md_content += "\n - Options: "
+ opts = [f"`{opt.get('value')}` ({opt.get('label')})" for opt in param.get('options', [])]
+ md_content += ', '.join(opts)
+
+ md_content += "\n"
+ else:
+ md_content += "No parameters required.\n"
+
+ # Example
+ md_content += f"\nExample:\n```javascript\n"
+
+ # Generate example based on query type
+ if query_key == 'getIdentity':
+ md_content += 'const identity = await sdk.getIdentity("GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec");'
+ elif query_key == 'getDocuments':
+ md_content += '''const docs = await sdk.getDocuments(
+ contractId,
+ "note",
+ JSON.stringify([["$ownerId", "==", identityId]]),
+ JSON.stringify([["$createdAt", "desc"]]),
+ 10
+);'''
+ elif query_key == 'getIdentityBalance':
+ md_content += 'const balance = await sdk.getIdentityBalance(identityId);'
+ elif query_key == 'getPathElements':
+ md_content += '''// Access any data in the Dash Platform state tree
+// Common root paths:
+// - DataContractDocuments: 64
+// - Identities: 32
+// - UniquePublicKeyHashesToIdentities: 24
+// - NonUniquePublicKeyKeyHashesToIdentities: 8
+// - Tokens: 16
+// - Pools: 48
+// - PreFundedSpecializedBalances: 40
+// - SpentAssetLockTransactions: 72
+// - WithdrawalTransactions: 80
+// - GroupActions: 88
+// - Balances: 96
+// - Misc: 104
+// - Votes: 112
+// - Versions: 120
+
+// Example: Get identity balance
+const result = await sdk.getPathElements(['96'], ['identityId']);
+
+// Example: Get identity info
+const identityKeys = await sdk.getPathElements(['32'], ['identityId']);
+
+// Example: Get contract documents
+const documents = await sdk.getPathElements(['64'], ['contractId', '1', 'documentType']);'''
+ else:
+ # Generic example
+ params = []
+ for inp in inputs:
+ if inp.get('required', False):
+ if inp.get('type') == 'array':
+ params.append('[]')
+ elif inp.get('type') == 'number':
+ params.append('100')
+ else:
+ params.append(f'"{inp.get("name", "value")}"')
+ md_content += f'const result = await sdk.{query_key}({", ".join(params)});'
+
+ md_content += "\n```\n"
+
+ # Document state transitions
+ md_content += "\n## State Transition Operations\n\n### Pattern\n"
+ md_content += "All state transitions require authentication and follow this pattern:\n"
+ md_content += "```javascript\nconst result = await sdk.{transition_name}(identityHex, ...params, privateKeyHex);\n```\n"
+
+ md_content += "\n### Available State Transitions\n"
+
+ for cat_key, category in transition_defs.items():
+ md_content += f"\n#### {category.get('label', cat_key)}\n"
+
+ transitions = category.get('transitions', {})
+ for trans_key, transition in transitions.items():
+ md_content += f"\n**{transition.get('label', trans_key)}** - `{trans_key}`\n"
+ md_content += f"*{transition.get('description', 'No description')}*\n\n"
+
+ # Parameters
+ inputs = transition.get('inputs', [])
+ if inputs:
+ md_content += "Parameters (in addition to identity/key):\n"
+ for param in inputs:
+ req = "required" if param.get('required', False) else "optional"
+ md_content += f"- `{param.get('name', 'unknown')}` ({param.get('type', 'text')}, {req})"
+
+ if param.get('label') and param.get('label') != param.get('name'):
+ md_content += f" - {param.get('label')}"
+
+ if param.get('placeholder'):
+ md_content += f"\n - Example: `{param.get('placeholder')}`"
+
+ md_content += "\n"
+
+ # Example
+ md_content += f"\nExample:\n```javascript\n"
+
+ # Generate specific examples
+ if trans_key == 'documentCreate':
+ md_content += '''const result = await sdk.document_create(
+ identityHex,
+ contractId,
+ "note",
+ JSON.stringify({ message: "Hello!" }),
+ privateKeyHex
+);'''
+ elif trans_key == 'tokenTransfer':
+ md_content += '''const result = await sdk.token_transfer(
+ identityHex,
+ contractId,
+ tokenId,
+ 1000000, // amount
+ recipientId,
+ privateKeyHex
+);'''
+ else:
+ md_content += f'const result = await sdk.{trans_key}(identityHex, /* params */, privateKeyHex);'
+
+ md_content += "\n```\n"
+
+ # Add common patterns section
+ md_content += '''
+## Common Patterns
+
+### Error Handling
+```javascript
+try {
+ const result = await sdk.getIdentity(identityId);
+ console.log(result);
+} catch (error) {
+ console.error("Query failed:", error);
+}
+```
+
+### Working with Proofs
+```javascript
+// Enable proofs during SDK initialization
+const sdk = await WasmSdk.new(transport, true);
+
+// Query with proof verification
+const identityWithProof = await sdk.getIdentity(identityId);
+```
+
+### Document Queries with Where/OrderBy
+```javascript
+// Where clause format: [[field, operator, value], ...]
+const whereClause = JSON.stringify([
+ ["$ownerId", "==", identityId],
+ ["age", ">=", 18]
+]);
+
+// OrderBy format: [[field, direction], ...]
+const orderBy = JSON.stringify([
+ ["$createdAt", "desc"]
+]);
+
+const docs = await sdk.getDocuments(
+ contractId,
+ documentType,
+ whereClause,
+ orderBy,
+ limit
+);
+```
+
+### Batch Operations
+```javascript
+// Get multiple identities
+const identityIds = ["id1", "id2", "id3"];
+const balances = await sdk.getIdentitiesBalances(identityIds);
+```
+
+## Important Notes
+
+1. **Network Endpoints**:
+ - Testnet: `https://52.12.176.90:1443/`
+ - Mainnet: Update when available
+
+2. **Identity Format**: Identity IDs and keys should be hex-encoded strings
+
+3. **Credits**: All fees are paid in credits (1 credit = 1 satoshi equivalent)
+
+4. **Nonces**: The SDK automatically handles nonce management for state transitions
+
+5. **Proofs**: Enable proofs for production applications to ensure data integrity
+
+## Troubleshooting
+
+- **Connection errors**: Verify network endpoint and that SDK is initialized
+- **Invalid parameters**: Check parameter types and required fields
+- **Authentication failures**: Ensure correct identity/key format and key permissions
+- **Query errors**: Validate contract IDs, document types, and field names exist
+'''
+
+ return md_content
+
+def main():
+ """Main function to generate documentation"""
+
+ # Get paths
+ script_dir = Path(__file__).parent
+ index_file = script_dir / 'index.html'
+
+ if not index_file.exists():
+ print(f"Error: index.html not found at {index_file}")
+ return 1
+
+ # First check if we have manually fixed definitions
+ fixed_file = script_dir / 'fixed_definitions.json'
+ extracted_file = script_dir / 'extracted_definitions.json'
+
+ if fixed_file.exists():
+ print("Using manually fixed definitions...")
+ definitions_file = fixed_file
+ else:
+ # Extract definitions using the extraction script
+ print("Extracting definitions from index.html...")
+ import subprocess
+ result = subprocess.run(['python3', 'extract_definitions.py'], cwd=script_dir, capture_output=True, text=True)
+ if result.returncode != 0:
+ print(f"Error extracting definitions: {result.stderr}")
+ return 1
+
+ if not extracted_file.exists():
+ print("Error: Could not find extracted definitions")
+ return 1
+ definitions_file = extracted_file
+
+ with open(definitions_file, 'r') as f:
+ extracted = json.load(f)
+
+ query_defs = extracted.get('queries', {})
+ transition_defs = extracted.get('transitions', {})
+
+ # Clean up the extracted data (remove invalid entries like 'dependsOn')
+ for cat_key, category in list(query_defs.items()):
+ queries = category.get('queries', {})
+ for q_key in list(queries.keys()):
+ if q_key in ['dependsOn', 'offset', 'limit'] or not queries[q_key].get('label'):
+ del queries[q_key]
+
+ for cat_key, category in list(transition_defs.items()):
+ transitions = category.get('transitions', {})
+ for t_key in list(transitions.keys()):
+ if t_key in ['dependsOn'] or not transitions[t_key].get('label'):
+ del transitions[t_key]
+
+ print(f"Found {sum(len(cat.get('queries', {})) for cat in query_defs.values())} queries")
+ print(f"Found {sum(len(cat.get('transitions', {})) for cat in transition_defs.values())} state transitions")
+
+ # Generate user docs
+ print("\nGenerating user documentation (docs.html)...")
+ user_docs_html = generate_user_docs_html(query_defs, transition_defs)
+ docs_file = script_dir / 'docs.html'
+ with open(docs_file, 'w', encoding='utf-8') as f:
+ f.write(user_docs_html)
+ print(f"Written to {docs_file}")
+
+ # Generate AI reference
+ print("\nGenerating AI reference (AI_REFERENCE.md)...")
+ ai_reference_md = generate_ai_reference_md(query_defs, transition_defs)
+ ai_ref_file = script_dir / 'AI_REFERENCE.md'
+ with open(ai_ref_file, 'w', encoding='utf-8') as f:
+ f.write(ai_reference_md)
+ print(f"Written to {ai_ref_file}")
+
+ # Generate documentation manifest for CI checks
+ manifest = {
+ "generated_at": datetime.now().isoformat(),
+ "queries": {},
+ "transitions": {}
+ }
+
+ for cat_key, category in query_defs.items():
+ for query_key in category.get('queries', {}).keys():
+ manifest["queries"][query_key] = {
+ "category": cat_key,
+ "documented": True
+ }
+
+ for cat_key, category in transition_defs.items():
+ for trans_key in category.get('transitions', {}).keys():
+ manifest["transitions"][trans_key] = {
+ "category": cat_key,
+ "documented": True
+ }
+
+ manifest_file = script_dir / 'docs_manifest.json'
+ with open(manifest_file, 'w', encoding='utf-8') as f:
+ json.dump(manifest, f, indent=2)
+ print(f"\nGenerated documentation manifest at {manifest_file}")
+
+ print("\nDocumentation generation complete!")
+ return 0
+
+if __name__ == "__main__":
+ exit(main())
\ No newline at end of file
diff --git a/packages/wasm-sdk/index.html b/packages/wasm-sdk/index.html
index 61adc5181d4..1996061fe50 100644
--- a/packages/wasm-sdk/index.html
+++ b/packages/wasm-sdk/index.html
@@ -7,6 +7,9 @@
+ Dash Platform WASM JS SDK
+
+
+
+
+ Check Identity Keys
+
+
+ Identity ID:
+
+
+
+
+ Private Key (WIF):
+
+
+
+ Check Keys
+ Fetch Identity Only
+
+
+
+
+
+