From 552f50992eec8b64556bf0d0cc617e87500806c7 Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 22 Apr 2025 15:48:28 -0400 Subject: [PATCH 01/10] docs: correct data contract error range --- docs/protocol-ref/errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/protocol-ref/errors.md b/docs/protocol-ref/errors.md index 54b76f089..5603f2a43 100644 --- a/docs/protocol-ref/errors.md +++ b/docs/protocol-ref/errors.md @@ -48,7 +48,7 @@ Code range: 10100-10199 ### Data Contract -Code range: 10200-10399 +Code range: 10200-10349 | Code | Error Description | Comment | | :---: | ----------------------------------------------- | ------- | From 5abae8e3c5e4ddb5f601687fe7043c1a9dd9585d Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 22 Apr 2025 15:48:58 -0400 Subject: [PATCH 02/10] docs(api): update token event info --- docs/reference/dapi-endpoints-platform-endpoints.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/reference/dapi-endpoints-platform-endpoints.md b/docs/reference/dapi-endpoints-platform-endpoints.md index 3be405cff..492be15e8 100644 --- a/docs/reference/dapi-endpoints-platform-endpoints.md +++ b/docs/reference/dapi-endpoints-platform-endpoints.md @@ -2212,7 +2212,6 @@ Retrieves a list of actions performed by a specific group within a contract. | | `freeze` | Freezes a specific entity's tokens. | | | `unfreeze` | Unfreezes a specific entity's tokens. | | | `destroy_frozen_funds` | Destroys frozen funds for a specified entity. | -| | `transfer` | Transfers tokens to another recipient. | | | `emergency_action` | Performs emergency actions like pausing or resuming the contract. | | | `token_config_update` | Updates token configuration settings. | | **DocumentEvent** | `create` | Represents the creation of a document. | @@ -2252,11 +2251,6 @@ Retrieves a list of actions performed by a specific group within a contract. | `destroy_frozen_funds` | `frozen_id` | Bytes | Identifier of the frozen entity. | | | `amount` | UInt64 | Amount of frozen funds to destroy. | | | `public_note` | String (Optional) | A public note for the destruction event. | -| `transfer` | `recipient_id` | Bytes | Identity ID of the recipient. | -| | `amount` | UInt64 | Amount of tokens transferred. | -| | `public_note` | String (Optional) | A public note for the transfer event. | -| | `shared_encrypted_note` | Object (Optional) | Encrypted note shared by sender and recipient. | -| | `personal_encrypted_note` | Object (Optional) | Personal encrypted note. | | `emergency_action` | `action_type` | Enum (`PAUSE = 0`, `RESUME = 1`) | Type of emergency action performed. | | | `public_note` | String (Optional) | A public note for the emergency action. | | `token_config_update` | `token_config_update_item` | Bytes | Configuration update details. | From 496e5f3dae8fe651a328e1f5154f86425f684a4b Mon Sep 17 00:00:00 2001 From: thephez Date: Tue, 22 Apr 2025 16:37:21 -0400 Subject: [PATCH 03/10] docs(ref): fix contract links --- docs/protocol-ref/data-contract.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index 9781ae682..a6619e48d 100644 --- a/docs/protocol-ref/data-contract.md +++ b/docs/protocol-ref/data-contract.md @@ -40,7 +40,7 @@ Include the following at the same level as the `properties` keyword to ensure pr ## Data Contract Object -The data contract object consists of the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/v1/data_contract.rs#L67-L105)): +The data contract object consists of the following fields as defined in the Rust reference client ([rs-dpp](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/v1/data_contract.rs#L77-L121)): | Property | Type | Size | Description | | --------------- | -------------- | ---- | ----------- | @@ -293,7 +293,9 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ "properties": { "position": true }, - "required": ["position"] + "required": [ + "position" + ] } } } @@ -442,7 +444,9 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ "maxLength": 256 } }, - "required": ["resolution"], + "required": [ + "resolution" + ], "additionalProperties": false } }, From 35e92ce728da3585993a50d0cc0ea9b38cc95647 Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 23 Apr 2025 12:28:59 -0400 Subject: [PATCH 04/10] docs: add token fee info to explanation --- docs/explanations/tokens.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index cf3581590..2e652a921 100644 --- a/docs/explanations/tokens.md +++ b/docs/explanations/tokens.md @@ -16,6 +16,7 @@ Dash Platform’s token functionality provides a straightforward, account-based - **Access Control [Groups](#groups)**: Multi-party groups with user-defined thresholds support complex authorization schemes for token management - **Built-in [Distribution](#distribution-rules)**: Manual minting or scheduled release over time - **Seamless Integration**: Tokens live alongside documents in a single data contract, enabling additional use cases (e.g., ticketing, digital assets, stablecoins) +- **Token-Based Document [Fees](#token-based-fees)**: Charge tokens for an application's document actions (e.g., create, transfer), with options to burn tokens or reward the contract owner The following sections describe the features and configuration options available for token creators using Dash Platform. @@ -430,6 +431,21 @@ For example, a group is defined with a required threshold of 10. The group membe In this group, Member A and Member C have a combined power of 11 and can perform actions without approval from Member B. If Member B proposes an action, Member A and C must both approve to authorize the action. +### Token-Based Fees + +Dash Platform allows developers to charge token fees for document-related actions (e.g., creating or transferring a document). This provides a way to monetize app usage or implement economic incentives using tokens. These fees are configured in the data contract under the `tokenCost` field. + +Examples: + +- Require 1000 tokens to create a document +- Burn 200 tokens when a document is transferred + +This allows for: + +- Spam protection (pay-to-post) +- Revenue generation for app creators +- Deflationary models via token burning + ## Token Creation Creating a token on Dash Platform consists of creating a data contract, registering it on the network, and then creating tokens based on the schema defined in the data contract. From f1327c6532176f83cb276172944b2da514f01588 Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 23 Apr 2025 16:43:32 -0400 Subject: [PATCH 05/10] docs: update token config info and action rules --- docs/explanations/tokens.md | 62 ++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index 2e652a921..7476d5aaf 100644 --- a/docs/explanations/tokens.md +++ b/docs/explanations/tokens.md @@ -104,11 +104,12 @@ When creating a token, you define its configuration using the following paramete | Configuration Parameter | Mutable | Default | |:------------------------|:------------------|:--------| | [Conventions](#display-conventions) | Yes | N/A. Depends on implementation | -| [Decimal precision](#display-conventions)| Yes | [8](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration_convention/v0/mod.rs#L38) | -| [Base supply](#token-supply) | **No** | [100000](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs#L159) | +| [Decimal precision](#display-conventions)| Yes | [8](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs#L376) | +| [Base supply](#token-supply) | **No** | [100000](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs#L378) | | [Maximum supply](#token-supply) | Yes | None | | [Keep history](#history) | Yes | True | | [Start paused](#initial-state) | Yes | False | +| [Allow transfer to frozen balance](#allow-transfer-to-frozen-balance) | Yes | True | | [Main control group](#main-control-group)| Yes | None | | Main control group can be modified | Yes | NoOne | @@ -138,6 +139,10 @@ When creating a token, you define its configuration using the following paramete - Whether the authority to change these parameters can be transferred or locked to "no one" - Example: "Only group #1 can update the max supply.” See the [Rules section](#rules) for details. +#### Allow Transfer to Frozen Balance + +- Allow transferring and minting of tokens to frozen identity token balances + #### Main Control Group - A group that can be referenced in other fields to control multiple aspects of the token with the same group. @@ -180,19 +185,46 @@ Rules can authorize no one, specific identities, or multiparty groups. The compl ##### Action Rules -Token action rules can be configured to allow updating who has access to many [token actions](#actions). The following table summarizes the available action rules: +Token action rules can be configured to control access to many [token actions](#actions). The +following table summarizes the configurable rules and their default authorized parties: + +###### General Controls + +| Configuration Rule | Can be Changed? | Default Authorized Party | +|:--------------------------------------|:----------------|:-------------------------| +| Conventions change rules | Yes | NoOne | +| Max supply change rules | Yes | NoOne | +| Main control group can be modified | Yes | NoOne | + +###### Minting and Burning + +| Configuration Rule | Can be Changed? | Default Authorized Party | +|:--------------------------------------|:----------------|:-------------------------| +| Manual minting rules | Yes | Contract Owner | +| Manual burning rules | Yes | Contract Owner | +| Minting: choosing destination rules | Yes | NoOne | + +###### Freezing Controls + +| Configuration Rule | Can be Changed? | Default Authorized Party | +|:--------------------------------------|:----------------|:-------------------------| +| Freeze rules | Yes | NoOne | +| Unfreeze rules | Yes | NoOne | +| Destroy frozen funds rules | Yes | NoOne | + +###### Distribution + +| Configuration Rule | Can be Changed? | Default Authorized Party | +|:--------------------------------------|:----------------|:-------------------------| +| Perpetual distribution rules | Yes | NoOne | +| New tokens destination identity rules | Yes | NoOne | +| Direct purchase pricing change rules | Yes | NoOne | + +###### Emergency -| Configuration Rule | Can be Changed? | Default Authorized Party| -|:-------------------|:------------------|:--------| -| Conventions change rules | Yes | NoOne | -| Max supply change rules | Yes | NoOne | -| Manual minting rules | Yes | Contract Owner | -| Manual burning rules | Yes | Contract Owner | -| Freeze rules | Yes | NoOne | -| Unfreeze rules | Yes | NoOne | -| Destroy frozen funds rules | Yes | NoOne | -| Emergency_action rules | Yes | NoOne | -| Main control group can be modified | Yes | NoOne | +| Configuration Rule | Can be Changed? | Default Authorized Party | +|:--------------------------------------|:----------------|:-------------------------| +| Emergency action rules | Yes | NoOne | ##### Distribution Rules @@ -433,7 +465,7 @@ In this group, Member A and Member C have a combined power of 11 and can perform ### Token-Based Fees -Dash Platform allows developers to charge token fees for document-related actions (e.g., creating or transferring a document). This provides a way to monetize app usage or implement economic incentives using tokens. These fees are configured in the data contract under the `tokenCost` field. +Dash Platform allows developers to charge token fees for document-related actions (e.g., creating or transferring a document). This provides a way to monetize app usage or implement economic incentives using tokens. These fees are configured in the data contract and apply to all document types in the contract. Examples: From fd73155270979682f9895150ab82ec1ca53f647a Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 23 Apr 2025 16:52:06 -0400 Subject: [PATCH 06/10] docs: add token direct purchase info --- docs/explanations/tokens.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index 7476d5aaf..c2a0fb717 100644 --- a/docs/explanations/tokens.md +++ b/docs/explanations/tokens.md @@ -558,4 +558,14 @@ Once the data contract design is completed, the contract can be registered on th ## Token Trading +### Direct Purchase + +Tokens can be configured to enable direct purchase by users. This allows the contract owner (or other authorized party) to sell the token directly to users at a fixed price or according to a tiered pricing schedule. + +The token’s [change control rules](#change-control-rules) include a `changeDirectPurchasePricingRules` setting to determine who is authorized to set or update the price. By default this is set to no one (`NoOne`) to disable direct sales. To allow direct sales, this rule should be set to authorize someone (e.g., the contract owner) to change pricing. + +When enabled, the authorized party can set the token price using a state transition. Users can purchase the token through Platform’s built-in mechanism (see [Token Set Purchase Price Transition](../protocol-ref/token.md#token-set-purchase-price-transition) and [Token Purchase Transition](../protocol-ref/token.md#token-purchase-transition)). The direct purchase system supports defining a minimum purchase amount and volume discounts via pricing tiers. The token’s price can also be removed to stop sales. + +### Marketplace + A planned token marketplace will support the trading of tokens. From a00c8b08c37ca4cbc8c33367cede8b44600b938e Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 23 Apr 2025 16:53:41 -0400 Subject: [PATCH 07/10] docs(ref): data contract updates --- docs/protocol-ref/data-contract.md | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index a6619e48d..3295a5e6a 100644 --- a/docs/protocol-ref/data-contract.md +++ b/docs/protocol-ref/data-contract.md @@ -54,6 +54,8 @@ The data contract object consists of the following fields as defined in the Rust | $defs | object | Varies | (Optional) Definitions for `$ref` references used in the `documents` object (if present, must be a non-empty object with \<= 100 valid properties) | | [groups](#data-contract-groups) | Group | Varies | (Optional) Groups that allow for specific multiparty actions on the contract. | | [tokens](./data-contract-token.md) | object | Varies | (Optional \*) Token definitions (see [Contract Tokens](./data-contract-token.md) for details) | +| keywords | array of strings | Varies | (Optional) Keywords associated with the contract to improve searchability. Maximum of 20 words. | +| description | string | 3-100 characters | (Optional) Brief description of the contract. | \* The data contract object must define documents or tokens. It may include both documents and tokens. @@ -355,6 +357,50 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ } } ] + }, + "documentActionTokenCost": { + "type": "object", + "properties": { + "contractId": { + "type": "array", + "contentMediaType": "application/x.dash.dpp.identifier", + "byteArray": true, + "minItems": 32, + "maxItems": 32 + }, + "tokenPosition": { + "type": "integer", + "minimum": 0, + "maximum": 65535 + }, + "amount": { + "type": "integer", + "minimum": 1, + "maximum": 281474976710655 + }, + "effect": { + "type": "integer", + "enum": [ + 0, + 1 + ], + "description": "0 - TransferTokenToContractOwner (default), 1 - Burn" + }, + "gasFeesPaidBy": { + "type": "integer", + "enum": [ + 0, + 1, + 2 + ], + "description": "0 - DocumentOwner (default), 1 - ContractOwner, 2 - PreferContractOwner" + } + }, + "required": [ + "tokenPosition", + "amount" + ], + "additionalProperties": false } }, "properties": { @@ -523,6 +569,30 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ ], "description": "Key requirements. 0 - Unique Non Replaceable, 1 - Multiple, 2 - Multiple with reference to latest key." }, + "tokenCost": { + "type": "object", + "properties": { + "create": { + "$ref": "#/$defs/documentActionTokenCost" + }, + "replace": { + "$ref": "#/$defs/documentActionTokenCost" + }, + "delete": { + "$ref": "#/$defs/documentActionTokenCost" + }, + "transfer": { + "$ref": "#/$defs/documentActionTokenCost" + }, + "update_price": { + "$ref": "#/$defs/documentActionTokenCost" + }, + "purchase": { + "$ref": "#/$defs/documentActionTokenCost" + } + }, + "additionalProperties": false + }, "properties": { "type": "object", "additionalProperties": { @@ -582,6 +652,17 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ "type": "string" } }, + "keywords": { + "type": "array", + "description": "List of up to 20 descriptive keywords for the contract, used in the Keyword Search contract", + "items": { + "type": "string", + "minLength": 3, + "maxLength": 50 + }, + "maxItems": 20, + "uniqueItems": true + }, "additionalProperties": { "type": "boolean", "const": false From 5945994b6c2d5c400e1a268b9664f84be9a566af Mon Sep 17 00:00:00 2001 From: thephez Date: Wed, 23 Apr 2025 17:08:21 -0400 Subject: [PATCH 08/10] docs: link updates --- docs/protocol-ref/token.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/protocol-ref/token.md b/docs/protocol-ref/token.md index 008ed40f5..ea05f0fe3 100644 --- a/docs/protocol-ref/token.md +++ b/docs/protocol-ref/token.md @@ -24,7 +24,7 @@ Each token transition must comply with the [token base transition defined in rs- #### Token id -The `$tokenId` is created by double sha256 hashing the token `$dataContractId` and `$tokenContractPosition` with a byte vector of the string "dash_token" as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/tokens/mod.rs#L22-L27). +The `$tokenId` is created by double sha256 hashing the token `$dataContractId` and `$tokenContractPosition` with a byte vector of the string "dash_token" as shown in [rs-dpp](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/tokens/mod.rs#L26-L31). ```rust // From the Rust reference implementation (rs-dpp) @@ -57,7 +57,7 @@ The token transition actions [defined in rs-dpp](https://github.com/dashpay/plat ### Token Notes -Some token transitions include optional notes fields. The maximum note length for these fields is [2048 characters](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/tokens/mod.rs#L14). +Some token transitions include optional notes fields. The maximum note length for these fields is [2048 characters](https://github.com/dashpay/platform/blob/v2.0-dev/packages/rs-dpp/src/tokens/mod.rs#L18). ### Token Burn Transition From 673c77619a16b7e5aa0bdf44adf33ccc1b97f5a0 Mon Sep 17 00:00:00 2001 From: thephez Date: Mon, 5 May 2025 13:04:55 -0400 Subject: [PATCH 09/10] docs: add contract fees info Based on dashpay/platform#2584 --- docs/protocol-ref/data-contract.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index 3295a5e6a..4abee4767 100644 --- a/docs/protocol-ref/data-contract.md +++ b/docs/protocol-ref/data-contract.md @@ -8,7 +8,34 @@ Data contracts define the schema (structure) of data an application will store on Dash Platform. Contracts are described using [JSON Schema](https://json-schema.org/understanding-json-schema/) which allows the platform to validate the contract-related data submitted to it. -The following sections provide details that developers need to construct valid contracts. All data contracts must define one or more [documents](#data-contract-documents) or [tokens](#data-contract-tokens), whereas definitions are optional and may not be used for simple contracts. +The following sections provide details that developers need to construct valid contracts. All data contracts must define at least one [document](#data-contract-documents) or [token](#data-contract-tokens). A contract may define multiple documents and/or tokens. + +### Fees + +Dash Platform charges fees for registering data contracts based on complexity. These fees compensate evonodes for their role in storing and processing contract-related data. + +The table below outlines the current fee structure for various data contract components. Fees are denominated in DASH and are charged at registration time based on the structure of the contract. + +| Fee Component | Amount (DASH) | Description | +|--------------------------------------------------------|-------------------|---------| +| `base_contract_registration_fee` | 0.1 | Fixed fee for every data contract. Covers the baseline cost of anchoring a contract into platform state. | +| `document_type_registration_fee` | 0.02 | Charged per [document type](./data-contract-document.md#contract-documents). Reflects indexing and storage schema overhead. | +| `document_type_base_non_unique`
`_index_registration_fee` | 0.01 | Per non-unique [index](./data-contract-document.md#document-indices) in a document type. Supports query operations. | +| `document_type_base_unique_index`
`_registration_fee` | 0.01 | Per unique [index](./data-contract-document.md#document-indices). Enforces uniqueness and adds validation complexity. | +| `document_type_base_contested`
`_index_registration_fee` | 1.0 | Per [contested index](./data-contract-document.md#contested-indices). Used for identity/username resolution; requires voting and [conflict resolution](../explanations/dpns.md#conflict-resolution) by masternodes and evonodes. | +| `token_registration_fee` | 0.1 | Per token defined in the contract. Reflects additional overhead from managing balances, transfers, and supply. | +| `token_uses_perpetual`
`_distribution_fee` | 0.1 | Additional fee for tokens that use perpetual (e.g., block-based) distribution mechanisms. These create ongoing state changes triggered by network events. | +| `token_uses_pre_programmed`
`_distribution_fee` | 0.1 | Charged when tokens use scheduled distributions (e.g., airdrops). Adds periodic complexity. | +| `search_keyword_fee` | 0.1 per keyword | Charged per search keyword defined. Keywords enable reverse lookups and indexing, increasing on-chain storage and filtering load. | + +These fees are additive. For example, a contract that defines two document types, each with one unique index, and one token using a perpetual distribution will incur the following total fee: + +```text +0.1 (base) + 0.02×2 (documents) + 0.01×2 (unique indices) = 0.16 DASH +0.1 (token) + 0.1 (perpetual) = 0.2 DASH + +Total fee: 0.16 + 0.2 = 0.36 DASH +``` ### General Constraints From b3608c74a0876bbd1687815c3d5ce3452ff8a61f Mon Sep 17 00:00:00 2001 From: thephez Date: Mon, 5 May 2025 15:35:04 -0400 Subject: [PATCH 10/10] docs: add js-sdk connection example for local build --- docs/tutorials/building-platform.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/tutorials/building-platform.md b/docs/tutorials/building-platform.md index de90ce34e..0c25ef1c2 100644 --- a/docs/tutorials/building-platform.md +++ b/docs/tutorials/building-platform.md @@ -206,3 +206,32 @@ docker volume prune -a # Removes all unused volumes docker system prune # Removes unused Docker data rm -rf ~/.dashmate # Deletes the Dashmate configuration ``` + +## Use JS SDK + +To connect to Dash Platform with the JavaScript SDK, use the `dapiAddresses` option and allow +self-signed certificates as shown in this example: + +```js +const Dash = require('dash'); + +const client = new Dash.Client({ + dapiAddresses: [ + { + protocol: 'https', + host: '127.0.0.1:2443', + allowSelfSignedCertificate: true, // For self-signed certs on local devnet + }, + ], +}); + +async function connect() { + const bestBlockHash = await client.getDAPIClient().core.getBestBlockHash(); + return bestBlockHash; +} + +connect() + .then((hash) => console.log('Connected. Best block hash:\n', hash)) + .catch((err) => console.error('Something went wrong:\n', err)) + .finally(() => client.disconnect()); +```