diff --git a/docs/index.md b/docs/index.md index 46c1df723..9766b0b08 100644 --- a/docs/index.md +++ b/docs/index.md @@ -115,7 +115,6 @@ tutorials/setup-sdk-client tutorials/identities-and-names tutorials/contracts-and-documents tutorials/send-funds -tutorials/use-dapi-client-methods tutorials/setup-a-node tutorials/tui/index tutorials/building-platform diff --git a/docs/tutorials/connecting-to-testnet.md b/docs/tutorials/connecting-to-testnet.md index 4462ba753..91e6ecade 100644 --- a/docs/tutorials/connecting-to-testnet.md +++ b/docs/tutorials/connecting-to-testnet.md @@ -26,10 +26,10 @@ npm install @dashevo/evo-sdk ### 2. Connect to Dash Platform -Create a file named `dashConnect.mjs` with the following contents. Then run it by typing `node dashConnect.mjs` from the command line: +Create a file named `connect.mjs` with the following contents. Then run it by typing `node connect.mjs` from the command line: ```{code-block} javascript -:caption: dashConnect.mjs +:caption: connect.mjs import { EvoSDK } from '@dashevo/evo-sdk'; diff --git a/docs/tutorials/contracts-and-documents/delete-documents.md b/docs/tutorials/contracts-and-documents/delete-documents.md index 65ab30e05..fba3b5a16 100644 --- a/docs/tutorials/contracts-and-documents/delete-documents.md +++ b/docs/tutorials/contracts-and-documents/delete-documents.md @@ -18,7 +18,7 @@ In this tutorial we will delete data from Dash Platform. Data is stored in the f ## Code ```{code-block} javascript -:caption: deleteDocument.mjs +:caption: document-delete.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/contracts-and-documents/register-a-data-contract.md b/docs/tutorials/contracts-and-documents/register-a-data-contract.md index a49b410b9..094dc8033 100644 --- a/docs/tutorials/contracts-and-documents/register-a-data-contract.md +++ b/docs/tutorials/contracts-and-documents/register-a-data-contract.md @@ -316,11 +316,13 @@ const { identity, identityKey, signer } = await keyManager.getAuth(); const documentSchemas = { note: { type: 'object', - indices: [{ - name: 'ownerId', - properties: [{ $ownerId: 'asc' }], - unique: false, - }], + indices: [ + { + name: 'ownerId', + properties: [{ $ownerId: 'asc' }], + unique: false, + }, + ], properties: { message: { type: 'string', diff --git a/docs/tutorials/contracts-and-documents/retrieve-a-data-contract.md b/docs/tutorials/contracts-and-documents/retrieve-a-data-contract.md index 0e513a2e9..36feebbd1 100644 --- a/docs/tutorials/contracts-and-documents/retrieve-a-data-contract.md +++ b/docs/tutorials/contracts-and-documents/retrieve-a-data-contract.md @@ -15,7 +15,7 @@ In this tutorial we will retrieve the data contract created in the [Register a D ## Code ```{code-block} javascript -:caption: retrieveContract.mjs +:caption: contract-retrieve.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/contracts-and-documents/retrieve-data-contract-history.md b/docs/tutorials/contracts-and-documents/retrieve-data-contract-history.md index 817039d46..4754ce71e 100644 --- a/docs/tutorials/contracts-and-documents/retrieve-data-contract-history.md +++ b/docs/tutorials/contracts-and-documents/retrieve-data-contract-history.md @@ -18,7 +18,7 @@ information. ## Code ```{code-block} javascript -:caption: retrieveContractHistory.mjs +:caption: contract-retrieve-history.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/contracts-and-documents/retrieve-documents.md b/docs/tutorials/contracts-and-documents/retrieve-documents.md index 50a66ee23..df652971a 100644 --- a/docs/tutorials/contracts-and-documents/retrieve-documents.md +++ b/docs/tutorials/contracts-and-documents/retrieve-documents.md @@ -15,7 +15,7 @@ In this tutorial we will retrieve some of the current data from a data contract. ## Code ```{code-block} javascript -:caption: getDocuments.mjs +:caption: document-retrieve.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/contracts-and-documents/submit-documents.md b/docs/tutorials/contracts-and-documents/submit-documents.md index 092590d82..c789eb361 100644 --- a/docs/tutorials/contracts-and-documents/submit-documents.md +++ b/docs/tutorials/contracts-and-documents/submit-documents.md @@ -17,7 +17,7 @@ In this tutorial we will submit some data to an application on Dash Platform. Da ## Code ```{code-block} javascript -:caption: submitDocument.mjs +:caption: document-submit.mjs import { Document } from '@dashevo/evo-sdk'; import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/contracts-and-documents/update-a-data-contract.md b/docs/tutorials/contracts-and-documents/update-a-data-contract.md index 8fa424d9e..e0e4c761e 100644 --- a/docs/tutorials/contracts-and-documents/update-a-data-contract.md +++ b/docs/tutorials/contracts-and-documents/update-a-data-contract.md @@ -35,12 +35,13 @@ const { identityKey, signer } = await keyManager.getAuth(); // Edit these values for your environment // Your contract ID from the Register a Data Contract tutorial const DATA_CONTRACT_ID = - process.env.DATA_CONTRACT_ID ?? - 'YOUR_DATA_CONTRACT_ID'; + process.env.DATA_CONTRACT_ID ?? 'YOUR_DATA_CONTRACT_ID'; const DOCUMENT_TYPE = 'note'; if (!DATA_CONTRACT_ID || DATA_CONTRACT_ID === 'YOUR_DATA_CONTRACT_ID') { - throw new Error('Set DATA_CONTRACT_ID (env var or in code) to your contract ID from the Register a Data Contract tutorial'); + throw new Error( + 'Set DATA_CONTRACT_ID (env var or in code) to your contract ID from the Register a Data Contract tutorial', + ); } try { @@ -86,12 +87,13 @@ const { identityKey, signer } = await keyManager.getAuth(); // Edit these values for your environment // Your contract ID from the Register a Data Contract tutorial const DATA_CONTRACT_ID = - process.env.DATA_CONTRACT_ID ?? - 'YOUR_DATA_CONTRACT_ID'; + process.env.DATA_CONTRACT_ID ?? 'YOUR_DATA_CONTRACT_ID'; const DOCUMENT_TYPE = 'note'; if (!DATA_CONTRACT_ID || DATA_CONTRACT_ID === 'YOUR_DATA_CONTRACT_ID') { - throw new Error('Set DATA_CONTRACT_ID (env var or in code) to your contract ID from the Register a Data Contract tutorial'); + throw new Error( + 'Set DATA_CONTRACT_ID (env var or in code) to your contract ID from the Register a Data Contract tutorial', + ); } try { diff --git a/docs/tutorials/contracts-and-documents/update-documents.md b/docs/tutorials/contracts-and-documents/update-documents.md index 6d39c5451..e14f3a31a 100644 --- a/docs/tutorials/contracts-and-documents/update-documents.md +++ b/docs/tutorials/contracts-and-documents/update-documents.md @@ -18,7 +18,7 @@ In this tutorial we will update existing data on Dash Platform. Data is stored i ## Code ```{code-block} javascript -:caption: updateDocument.mjs +:caption: document-update.mjs import { Document } from '@dashevo/evo-sdk'; import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/create-and-fund-a-wallet.md b/docs/tutorials/create-and-fund-a-wallet.md index 231ed5433..849628381 100644 --- a/docs/tutorials/create-and-fund-a-wallet.md +++ b/docs/tutorials/create-and-fund-a-wallet.md @@ -13,7 +13,7 @@ In order to make create an identity on Dash Platform, you need a platform addres # Code ```{code-block} javascript -:caption: generateWallet.mjs +:caption: create-wallet.mjs import { wallet, PlatformAddressSigner, PrivateKey } from '@dashevo/evo-sdk'; diff --git a/docs/tutorials/identities-and-names.md b/docs/tutorials/identities-and-names.md index c77eef381..15ad4d00f 100644 --- a/docs/tutorials/identities-and-names.md +++ b/docs/tutorials/identities-and-names.md @@ -15,7 +15,6 @@ identities-and-names/retrieve-an-identity identities-and-names/topup-an-identity-balance identities-and-names/withdraw-an-identity-balance identities-and-names/update-an-identity -identities-and-names/retrieve-an-accounts-identities identities-and-names/transfer-credits-to-an-identity identities-and-names/register-a-name-for-an-identity identities-and-names/retrieve-a-name diff --git a/docs/tutorials/identities-and-names/register-a-name-for-an-identity.md b/docs/tutorials/identities-and-names/register-a-name-for-an-identity.md index 70b1b824c..a5df78b23 100644 --- a/docs/tutorials/identities-and-names/register-a-name-for-an-identity.md +++ b/docs/tutorials/identities-and-names/register-a-name-for-an-identity.md @@ -25,7 +25,7 @@ Pass only the label (e.g., `myname`), not the full domain name. The `.dash` suff ::: ```{code-block} javascript -:caption: registerName.mjs +:caption: name-register.mjs import { setupDashClient } from '../setupDashClient.mjs'; @@ -47,7 +47,9 @@ try { console.log('Name registered:\n', result.toJSON()); } catch (e) { if (e.message?.includes('duplicate unique properties')) { - console.error(`Name "${NAME_LABEL}.dash" is already registered. Try a different name.`); + console.error( + `Name "${NAME_LABEL}.dash" is already registered. Try a different name.`, + ); } else { console.error('Something went wrong:\n', e.message); } diff --git a/docs/tutorials/identities-and-names/register-an-identity.md b/docs/tutorials/identities-and-names/register-an-identity.md index b338efbe0..d86b7ba8f 100644 --- a/docs/tutorials/identities-and-names/register-an-identity.md +++ b/docs/tutorials/identities-and-names/register-an-identity.md @@ -19,13 +19,15 @@ Identities serve as the basis for interactions with Dash Platform. They consist ## Code ```{code-block} javascript -:caption: registerIdentity.mjs +:caption: identity-register.mjs import { randomBytes } from 'node:crypto'; import { Identity, Identifier } from '@dashevo/evo-sdk'; import { setupDashClient } from '../setupDashClient.mjs'; -const { sdk, keyManager, addressKeyManager } = await setupDashClient({ requireIdentity: false }); +const { sdk, keyManager, addressKeyManager } = await setupDashClient({ + requireIdentity: false, +}); try { // Build the identity shell with 5 standard public keys @@ -37,15 +39,20 @@ try { // Create the identity on-chain, funded from the platform address const result = await sdk.addresses.createIdentity({ identity, - inputs: [{ - address: addressKeyManager.primaryAddress.bech32m, - amount: 5000000n, // Credits to fund the new identity - }], + inputs: [ + { + address: addressKeyManager.primaryAddress.bech32m, + amount: 5000000n, // Credits to fund the new identity + }, + ], identitySigner: keyManager.getFullSigner(), addressSigner: addressKeyManager.getSigner(), }); - console.log('Identity registered!\nIdentity ID:', result.identity.id.toString()); + console.log( + 'Identity registered!\nIdentity ID:', + result.identity.id.toString(), + ); } catch (e) { // Known SDK bug: proof verification fails but the identity was created // Issue: https://github.com/dashpay/platform/issues/3095 diff --git a/docs/tutorials/identities-and-names/retrieve-a-name.md b/docs/tutorials/identities-and-names/retrieve-a-name.md index 7e624302e..70586df1e 100644 --- a/docs/tutorials/identities-and-names/retrieve-a-name.md +++ b/docs/tutorials/identities-and-names/retrieve-a-name.md @@ -17,7 +17,7 @@ In this tutorial we will retrieve the name created in the [Register a Name for a :::{tab-item} Resolve by Name ```{code-block} javascript -:caption: resolve-by-name.mjs +:caption: name-resolve-by-name.mjs import { setupDashClient } from '../setupDashClient.mjs'; @@ -45,7 +45,7 @@ Identity ID for "quantumexplorer.dash": BNnn19SAJZuvsUu787dMzPDXASwuCrm4yQ864tEp :::{tab-item} Get Identity Names ```{code-block} javascript -:caption: get-identity-names.mjs +:caption: name-get-identity-names.mjs import { setupDashClient } from '../setupDashClient.mjs'; @@ -78,7 +78,7 @@ Name(s) retrieved for GgZekwh38XcWQTyWWWvmw6CEYFnLU7yiZFPWZEjqKHit: :::{tab-item} Search for Name ```{code-block} javascript -:caption: search-by-name.mjs +:caption: name-search-by-name.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/identities-and-names/retrieve-an-accounts-identities.md b/docs/tutorials/identities-and-names/retrieve-an-accounts-identities.md deleted file mode 100644 index 761edca55..000000000 --- a/docs/tutorials/identities-and-names/retrieve-an-accounts-identities.md +++ /dev/null @@ -1,55 +0,0 @@ -```{eval-rst} -.. tutorials-retrieve-accounts-identities: -``` - -# Retrieve an account's identities - -:::{attention} -This tutorial has not been migrated to use the latest Dash SDK yet and is out-of-date. -::: - -In this tutorial we will retrieve the list of identities associated with a specified mnemonic-based account. Since multiple identities may be created using the same mnemonic, it is helpful to have a way to quickly retrieve all these identities (e.g. if importing the mnemonic into a new device). - -## Prerequisites - -- [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) -- A wallet mnemonic -- A configured client: [Setup SDK Client](../setup-sdk-client.md) -- A Dash Platform Identity: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) - -## Code - -```javascript -const setupDashClient = require('../setupDashClient'); - -const client = setupDashClient(); - -const retrieveIdentityIds = async () => { - const account = await client.getWalletAccount(); - return account.identities.getIdentityIds(); -}; - -retrieveIdentityIds() - .then((d) => console.log('Mnemonic identities:\n', d)) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); -``` - -Example Response - -```json -[ - "6Jz8pFZFhssKSTacgQmZP14zGZNnFYZFKSbx4WVAJFy3", - "8XoJHG96Vfm3eGh1A7HiDpMb1Jw2B9opRJe8Z38urapt", - "CEPMcuBgAWeaCXiP2gJJaStANRHW6b158UPvL1C8zw2W", - "GTGZrkPC72tWeBaqopSCKgiBkVVQR3s3yBsVeMyUrmiY" -] -``` - -## What's Happening - -After we initialize the Client and getting the account, we call `account.identities.getIdentityIds()` to retrieve a list of all identities created with the wallet mnemonic. The list of identities is output to the console. - -:::{note} -Since the SDK does not cache wallet information, lengthy re-syncs (5+ minutes) may be required for some Core chain wallet operations. See [Wallet Operations](../setup-sdk-client.md#wallet-operations) for options. -::: diff --git a/docs/tutorials/identities-and-names/retrieve-an-identity.md b/docs/tutorials/identities-and-names/retrieve-an-identity.md index 538c4522f..da19ae18e 100644 --- a/docs/tutorials/identities-and-names/retrieve-an-identity.md +++ b/docs/tutorials/identities-and-names/retrieve-an-identity.md @@ -15,7 +15,7 @@ In this tutorial we will retrieve the identity created in the [Register an Ident ## Code ```{code-block} javascript -:caption: retrieveIdentity.mjs +:caption: identity-retrieve.mjs import { setupDashClient } from '../setupDashClient.mjs'; diff --git a/docs/tutorials/identities-and-names/topup-an-identity-balance.md b/docs/tutorials/identities-and-names/topup-an-identity-balance.md index 969b84c6b..06a798185 100644 --- a/docs/tutorials/identities-and-names/topup-an-identity-balance.md +++ b/docs/tutorials/identities-and-names/topup-an-identity-balance.md @@ -4,49 +4,55 @@ # Topup an identity's balance -:::{attention} -This tutorial has not been migrated to use the latest Dash SDK yet and is out-of-date. -::: - The purpose of this tutorial is to walk through the steps necessary to add credits to an identity's balance. ## Overview -As users interact with Dash Platform applications, the credit balance associated with their identity will decrease. Eventually it will be necessary to topup the balance by converting some Dash to credits. Additional details regarding credits can be found in the [Credits description](../../explanations/identity.md#credits). +As users interact with Dash Platform applications, the credit balance associated with their identity will decrease. Eventually it will be necessary to top up the balance by transferring credits from a funded platform address. Additional details regarding credits can be found in the [Credits description](../../explanations/identity.md#credits). ## Prerequisites - [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) -- A wallet mnemonic with some funds in it: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) +- A platform address with a balance: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) - A configured client: [Setup SDK Client](../setup-sdk-client.md) - A Dash Platform Identity: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) ## Code -```javascript -const setupDashClient = require('../setupDashClient'); - -const client = setupDashClient(); - -const topupIdentity = async () => { - const identityId = 'an identity ID goes here'; - const topUpAmount = 100000; // Number of duffs - - await client.platform.identities.topUp(identityId, topUpAmount); - return client.platform.identities.get(identityId); -}; - -topupIdentity() - .then((d) => console.log('Identity credit balance: ', d.balance)) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); +```{code-block} javascript +:caption: identity-topup.mjs + +import { setupDashClient } from '../setupDashClient.mjs'; + +const { sdk, addressKeyManager, keyManager } = await setupDashClient(); +const signer = addressKeyManager.getSigner(); + +try { + // Identity ID from the identity create tutorial + const IDENTITY_ID = keyManager.identityId; + const identity = await sdk.identities.fetch(IDENTITY_ID); + + const result = await sdk.addresses.topUpIdentity({ + identity, + inputs: [ + { + address: addressKeyManager.primaryAddress.bech32m, + amount: 200000n, // Credits to transfer + }, + ], + signer, + }); + + console.log(`Top-up result: + Start balance: ${identity.toJSON().balance} + Final balance: ${result.newBalance}`); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} ``` ## What's Happening -After connecting to the Client, we call `platform.identities.topUp` with an identity ID and a topup amount in duffs (1 duff = 1000 credits). This creates a lock transaction and increases the identity's credit balance by the relevant amount (minus fee). The updated balance is output to the console. +After connecting to the client, we get the address signer from the address key manager and fetch the identity to top up using its ID from the key manager. -:::{note} -:class: note -Since the SDK does not cache wallet information, lengthy re-syncs (5+ minutes) may be required for some Core chain wallet operations. See [Wallet Operations](../setup-sdk-client.md#wallet-operations) for options. -::: +We then call `sdk.addresses.topUpIdentity()` with the identity, the source platform address, the amount of credits to transfer, and the signer to authorize the transfer. The start and final balances are logged to confirm the top-up succeeded. diff --git a/docs/tutorials/identities-and-names/transfer-credits-to-an-identity.md b/docs/tutorials/identities-and-names/transfer-credits-to-an-identity.md index 96320e074..d514344c8 100644 --- a/docs/tutorials/identities-and-names/transfer-credits-to-an-identity.md +++ b/docs/tutorials/identities-and-names/transfer-credits-to-an-identity.md @@ -4,10 +4,6 @@ # Transfer to an Identity -:::{attention} -This tutorial has not been migrated to use the latest Dash SDK yet and is out-of-date. -::: - The purpose of this tutorial is to walk through the steps necessary to transfer credits to an identity. Additional details regarding credits can be found in the [credits description](../../explanations/identity.md#credits). @@ -15,46 +11,40 @@ identity. Additional details regarding credits can be found in the [credits desc - [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) -- A wallet mnemonic with some funds in it: [Tutorial: Create and Fund a - Wallet](../../tutorials/create-and-fund-a-wallet.md) - A configured client: [Setup SDK Client](../setup-sdk-client.md) - Two Dash Platform Identities: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) ## Code -```javascript -const setupDashClient = require('../setupDashClient'); +```{code-block} javascript +:caption: identity-transfer-credits.mjs -const client = setupDashClient(); +import { setupDashClient } from '../setupDashClient.mjs'; -const transferCreditsToIdentity = async () => { - const identityId = 'identity ID of the sender goes here'; - const identity = await client.platform.identities.get(identityId); +const { sdk, keyManager } = await setupDashClient(); +const { identity, signer } = await keyManager.getTransfer(); - const recipientID = 'identity ID of the recipient goes here'; - console.log('Recipient identity balance before transfer: ', recipientIdentity.balance); - const transferAmount = 300000; // Number of credits to transfer +// Default recipient (testnet). Replace or override via RECIPIENT_ID. +const recipientId = + process.env.RECIPIENT_ID ?? '7XcruVSsGQVSgTcmPewaE4tXLutnW1F6PXxwMbo8GYQC'; +const transferAmount = 100000n; // Credits to transfer - await client.platform.identities.creditTransfer( +try { + await sdk.identities.creditTransfer({ identity, - recipientID, - transferAmount, - ); - return client.platform.identities.get(identityId); -}; - -transferCreditsToIdentity() - .then((d) => console.log('Recipient identity balance after transfer: ', d.balance)) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); + recipientId, + amount: transferAmount, + signer, + }); + + const recipient = await sdk.identities.fetch(recipientId); + console.log('Recipient identity balance after transfer:', recipient.balance); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} ``` ## What's Happening -After connecting to the Client, we call `platform.identities.creditTransfer` with our identity, the recipient's identity ID, and the amount to transfer. After the credits are transferred to the recipient, we retrieve the recipient's identity and output their updated balance to the console. - -:::{note} -:class: note -Since the SDK does not cache wallet information, lengthy re-syncs (5+ minutes) may be required for some Core chain wallet operations. See [Wallet Operations](../setup-sdk-client.md#wallet-operations) for options. -::: +After connecting to the client, we get the transfer key signer using `keyManager.getTransfer()`. We then call `sdk.identities.creditTransfer()` with our identity, the recipient's identity ID, and the amount to transfer. After the credits are transferred, we retrieve the recipient's identity and output their updated balance to the console. diff --git a/docs/tutorials/identities-and-names/update-an-identity.md b/docs/tutorials/identities-and-names/update-an-identity.md index 0cd037906..36b67578b 100644 --- a/docs/tutorials/identities-and-names/update-an-identity.md +++ b/docs/tutorials/identities-and-names/update-an-identity.md @@ -4,98 +4,117 @@ # Update an identity -:::{attention} -This tutorial has not been migrated to use the latest Dash SDK yet and is out-of-date. -::: - +It is possible to update identities to add new keys or disable existing ones. Platform retains disabled keys so that any existing data they signed can still be verified while preventing them from signing new data. ## Prerequisites - [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) -- A wallet mnemonic with some funds in it: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) +- A platform address with a balance: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) - A configured client: [Setup SDK Client](../setup-sdk-client.md) - A Dash Platform Identity: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) ## Code -The two examples below demonstrate updating an existing identity to add a new key and disabling an existing key: +The two examples below demonstrate updating an existing identity to disable an existing key and to add a new key: :::{attention} -The current SDK version signs all state transitions with public key id `1`. If it is disabled, the SDK will be unable to use the identity. Future SDK versions will provide a way to also sign using keys added in an identity update. +The identity's master key must be used to sign identity update state transitions. ::: ::::{tab-set} :::{tab-item} Disable identity key -```javascript -const setupDashClient = require('../setupDashClient'); -const client = setupDashClient(); +```{code-block} javascript +:caption: identity-update-disable-key.mjs -const updateIdentityDisableKey = async () => { - const identityId = 'an identity ID goes here'; - const keyId = 'a public key ID goes here'; // One of the identity's public key IDs +import { setupDashClient } from '../setupDashClient.mjs'; - // Retrieve the identity to be updated and the public key to disable - const existingIdentity = await client.platform.identities.get(identityId); - const publicKeyToDisable = existingIdentity.getPublicKeyById(keyId); +const { sdk, keyManager } = await setupDashClient(); +const { identity, signer } = await keyManager.getMaster(); - const updateDisable = { - disable: [publicKeyToDisable], - }; +const KEY_ID = 99; // Replace with one of the identity's existing public key IDs - await client.platform.identities.update(existingIdentity, updateDisable); - return client.platform.identities.get(identityId); -} +console.log(`Disabling key ${KEY_ID} on identity ${keyManager.identityId}...`); + +try { + await sdk.identities.update({ + identity, + disablePublicKeys: [KEY_ID], // Disable public key id KEY_ID + signer, + }); -updateIdentityDisableKey() - .then((d) => console.log('Identity updated:\n', d.toJSON())) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); + const updatedIdentity = await sdk.identities.fetch(keyManager.identityId); + console.log('Identity updated:\n', updatedIdentity.toJSON()); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} ``` ::: :::{tab-item} Add identity key -```javascript -const setupDashClient = require('../setupDashClient'); - -const client = setupDashClient(); - -const updateIdentityAddKey = async () => { - const identityId = 'an identity ID goes here'; - const existingIdentity = await client.platform.identities.get(identityId); - const newKeyId = existingIdentity.toJSON().publicKeys.length; - - // Get an unused identity index - const account = await client.platform.client.getWalletAccount(); - const identityIndex = await account.getUnusedIdentityIndex(); - // Get unused private key and construct new identity public key - const { privateKey: identityPrivateKey } = - account.identities.getIdentityHDKeyByIndex(identityIndex, 0); - - const identityPublicKey = identityPrivateKey.toPublicKey().toBuffer(); - - const newPublicKey = new IdentityPublicKeyWithWitness(1); - newPublicKey.setId(newKeyId); - newPublicKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.HIGH); - newPublicKey.setData(identityPublicKey); - - const updateAdd = { - add: [newPublicKey], - }; - - // Submit the update signed with the new key - await client.platform.identities.update(existingIdentity, updateAdd, { - [newPublicKey.getId()]: identityPrivateKey, +```{code-block} javascript +:caption: identity-update-add-key.mjs + +import { + IdentityPublicKeyInCreation, + KeyType, + Purpose, + SecurityLevel, + wallet, +} from '@dashevo/evo-sdk'; +import { + setupDashClient, + clientConfig, + dip13KeyPath, +} from '../setupDashClient.mjs'; + +const { sdk, keyManager } = await setupDashClient(); + +// Fetch identity to determine the next available key ID +const { identity, signer } = await keyManager.getMaster(); +const existingKeys = identity.toJSON().publicKeys; +const newKeyId = Math.max(...existingKeys.map((k) => k.id)) + 1; + +console.log(`Adding key ${newKeyId} to identity ${keyManager.identityId}...`); + +// Derive the new key using the standard DIP-13 path +const newKeyPath = await dip13KeyPath( + clientConfig.network, + keyManager.identityIndex, + newKeyId, +); +const newKeyInfo = await wallet.deriveKeyFromSeedWithPath({ + mnemonic: clientConfig.mnemonic, + path: newKeyPath, + network: clientConfig.network, +}); +const newKeyObj = newKeyInfo.toObject(); + +// Build the new public key +const newPublicKey = new IdentityPublicKeyInCreation({ + keyId: newKeyId, + purpose: Purpose.AUTHENTICATION, + securityLevel: SecurityLevel.HIGH, + keyType: KeyType.ECDSA_SECP256K1, + data: Uint8Array.from(Buffer.from(newKeyObj.publicKey, 'hex')), +}); + +// Add the new key's WIF to the signer so it can co-sign +signer.addKeyFromWif(newKeyObj.privateKeyWif); + +try { + await sdk.identities.update({ + identity, + addPublicKeys: [newPublicKey], + signer, }); - return client.platform.identities.get(identityId); -}; - -updateIdentityAddKey() - .then((d) => console.log('Identity updated:\n', d.toJSON())) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); + const updatedIdentity = await sdk.identities.fetch(keyManager.identityId); + console.log('Identity updated:\n', updatedIdentity.toJSON()); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} ``` ::: :::: @@ -104,23 +123,12 @@ updateIdentityAddKey() ### Disabling keys -After we initialize the Client, we retrieve our existing identity and provide the `id` of one (or more) of the identity keys to disable. The update is submitted to DAPI using the `platform.identities.update` method with two arguments: - -1. An identity -2. An object containing the key(s) to be disabled - -Internally, the method creates a State Transition containing the updated identity, signs the state transition, and submits the signed state transition to DAPI. After the identity is updated, we output it to the console. +After connecting to the client, we get the master key signer from the key manager. We specify the key ID to disable and call `sdk.identities.update()` with an array of key IDs to disable. The updated identity is then fetched and logged to confirm the change. ### Adding keys -After we initialize the Client, we retrieve our existing identity and set an `id` for the key to be added. Next, we get an unused private key from our wallet and use it to derive a public key to add to our identity. The update is submitted to DAPI using the `platform.identities.update` method with three arguments: - -1. An identity -2. An object containing the key(s) to be added -3. An object containing the id and private key for each public key being added +After connecting to the client, we get the master key signer and inspect the identity's existing keys to determine the next available key ID. We then derive a new key using the DIP-13 derivation path, build an `IdentityPublicKeyInCreation` object, and add the new key's WIF to the signer so it can co-sign (proving ownership). Finally, we call `sdk.identities.update()` with the new public key to add. :::{note} When adding new public keys, they must be signed using the associated private key to prove ownership of the keys. ::: - -Internally, the method creates a State Transition containing the updated identity, signs the state transition, and submits the signed state transition to DAPI. After the identity is updated, we output it to the console. diff --git a/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md b/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md index fd88deeca..f94ce4c28 100644 --- a/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md +++ b/docs/tutorials/identities-and-names/withdraw-an-identity-balance.md @@ -2,13 +2,9 @@ .. tutorials-withdraw-identity-balance: ``` -:::{attention} -This tutorial has not been migrated to use the latest Dash SDK yet and is out-of-date. -::: - # Withdraw an Identity's balance -The purpose of this tutorial is to walk through the steps necessary to withdraw part of their identity's balance from Platform to a Dash address. +The purpose of this tutorial is to walk through the steps necessary to withdraw part of an identity's balance from Platform to a Dash address. ## Overview @@ -17,54 +13,44 @@ Over time, users may want to convert some of their identity's [Platform credits] ## Prerequisites - [General prerequisites](../../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) -- A wallet mnemonic with some funds in it: [Tutorial: Create and Fund a Wallet](../../tutorials/create-and-fund-a-wallet.md) - A configured client: [Setup SDK Client](../setup-sdk-client.md) - A Dash Platform Identity with a credit balance: [Tutorial: Register an Identity](../../tutorials/identities-and-names/register-an-identity.md) - A Core chain address to receive the withdrawn credits as Dash ## Code -```javascript -const setupDashClient = require('../setupDashClient'); +```{code-block} javascript +:caption: identity-withdraw-credits.mjs -const client = setupDashClient(); +import { setupDashClient } from '../setupDashClient.mjs'; -const withdrawCredits = async () => { - const identityId = 'an identity ID goes here'; - const identity = await client.platform.identities.get(identityId); +const { sdk, keyManager } = await setupDashClient(); +const { identity, signer } = await keyManager.getTransfer(); - console.log('Identity balance before transfer: ', identity.balance); +console.log('Identity balance before withdrawal:', identity.balance); - const toAddress = 'a Dash address goes here'; - const amount = 1000000; // Number of credits to withdraw - const amountDash = amount / (1000 * 100000000); +// Default: testnet faucet address. Replace or override via WITHDRAWAL_ADDRESS. +const toAddress = + process.env.WITHDRAWAL_ADDRESS ?? 'yXWJGWuD4VBRMp9n2MtXQbGpgSeWyTRHme'; +const amount = 190000n; // Credits to withdraw +const amountDash = Number(amount) / (1000 * 100000000); - console.log(`Withdrawing ${amount} credits (${amountDash} DASH)`); - // Temporarily force minRelay to have a value so withdrawal succeeds - // https://github.com/dashpay/platform/issues/2233 - client.wallet.storage.getDefaultChainStore().state.fees.minRelay = 1000; +console.log(`Withdrawing ${amount} credits (${amountDash} DASH)`); - const response = await client.platform.identities.withdrawCredits( +try { + const remainingBalance = await sdk.identities.creditWithdrawal({ identity, amount, - { - toAddress, - }, - ); - return client.platform.identities.get(identityId); -}; - -withdrawCredits() - .then((d) => console.log('Identity balance after withdrawal: ', d.balance)) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); + toAddress, + signer, + }); + + console.log(`Identity balance after withdrawal: ${remainingBalance} credits`); +} catch (e) { + console.error('Something went wrong:\n', e.message); +} ``` ## What's Happening -After connecting to the Client, we get an identity and set the withdrawal address and amount. We then call `platform.identities.withdrawCredits` with the identity, withdrawal amount in credits, and the destination address. This creates an unlock transaction and decreases the identity's credit balance by the relevant amount including a fee. The updated identity balance is output to the console. Once the withdrawal is processed, it is broadcast to the Core chain where the unlocked Dash is sent to the provided destination address. - -:::{note} -:class: note -Since the SDK does not cache wallet information, lengthy re-syncs (5+ minutes) may be required for some Core chain wallet operations. See [Wallet Operations](../setup-sdk-client.md#wallet-operations) for options. -::: +After connecting to the client, we get the transfer key signer using `keyManager.getTransfer()` and log the identity's current balance. We also convert the credit amount to Dash for display (1000 credits = 1 duff = 0.00000001 DASH). We then call `sdk.identities.creditWithdrawal()` with the identity, withdrawal amount in credits, the destination Core chain address, and the signer to authorize the withdrawal. The remaining credit balance is logged to confirm the withdrawal succeeded. diff --git a/docs/tutorials/setup-sdk-client.md b/docs/tutorials/setup-sdk-client.md index f771b43c9..9e7036bd4 100644 --- a/docs/tutorials/setup-sdk-client.md +++ b/docs/tutorials/setup-sdk-client.md @@ -75,7 +75,7 @@ const clientConfig = { * Returns the full 7-level hardened path: * m/9'/{coin}'/5'/0'/0'/{identityIndex}'/{keyIndex}' */ -async function dip13KeyPath(network, identityIndex, keyIndex) { +export async function dip13KeyPath(network, identityIndex, keyIndex) { const base = network === 'testnet' ? await wallet.derivationPathDip13Testnet(5) @@ -546,7 +546,7 @@ class AddressKeyManager { export async function setupDashClient({ requireIdentity = true, - identityIndex = 0, + identityIndex, } = {}) { const { network, mnemonic } = clientConfig; const sdk = await createClient(network); diff --git a/docs/tutorials/use-dapi-client-methods.md b/docs/tutorials/use-dapi-client-methods.md deleted file mode 100644 index 784747c0f..000000000 --- a/docs/tutorials/use-dapi-client-methods.md +++ /dev/null @@ -1,39 +0,0 @@ -```{eval-rst} -.. tutorials-dapi-client-methods: -``` - -# Use DAPI client methods - -In addition to the SDK methods for interacting with identities, names, contracts, and documents, the SDK also provides direct access to DAPI client methods. - -## Prerequisites - -- [General prerequisites](../tutorials/introduction.md#prerequisites) (Node.js / Dash SDK installed) - -# Code - -The following example demonstrates several of the Core DAPI client methods. DAPI client also has several Platform methods accessible via `getDAPIClient().platform.*`. The methods can be found here in the [js-dapi-client repository](https://github.com/dashpay/platform/tree/master/packages/js-dapi-client/lib/methods). - -```javascript -const Dash = require('dash'); - -const client = new Dash.Client({ network: 'testnet' }); - -async function dapiClientMethods() { - console.log(await client.getDAPIClient().core.getBlockHash(1)); - console.log(await client.getDAPIClient().core.getBestBlockHash()); - console.log(await client.getDAPIClient().core.getBlockByHeight(1)); - await client.getDAPIClient().core.getMasternodeStatus(); - - return client.getDAPIClient().core.getBlockchainStatus(); -} - -dapiClientMethods() - .then((d) => console.log('Core status:\n', d)) - .catch((e) => console.error('Something went wrong:\n', e)) - .finally(() => client.disconnect()); -``` - -:::{note} -Examples using DAPI client to access many of the DAPI endpoints can be found in the [DAPI Endpoint Reference section](../reference/dapi-endpoints.md). -:::