diff --git a/docs/explanations/tokens.md b/docs/explanations/tokens.md index cf3581590..c2a0fb717 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. @@ -103,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 | @@ -137,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. @@ -179,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 @@ -430,6 +463,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 and apply to all document types in the contract. + +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. @@ -510,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. diff --git a/docs/protocol-ref/data-contract.md b/docs/protocol-ref/data-contract.md index 9781ae682..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 @@ -40,7 +67,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 | | --------------- | -------------- | ---- | ----------- | @@ -54,6 +81,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. @@ -293,7 +322,9 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ "properties": { "position": true }, - "required": ["position"] + "required": [ + "position" + ] } } } @@ -353,6 +384,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": { @@ -442,7 +517,9 @@ The full schema is [defined is rs-dpp](https://github.com/dashpay/platform/blob/ "maxLength": 256 } }, - "required": ["resolution"], + "required": [ + "resolution" + ], "additionalProperties": false } }, @@ -519,6 +596,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": { @@ -578,6 +679,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 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 | | :---: | ----------------------------------------------- | ------- | 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 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. | 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()); +```