dash-platform-sdk 1.3.0-dev.5 → 1.3.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/bundle.min.js +17 -17
  2. package/index.d.ts +1 -1
  3. package/index.js +2 -0
  4. package/package.json +7 -5
  5. package/proto/generated/google/protobuf/wrappers.js +615 -0
  6. package/proto/generated/platform.client.d.ts +46 -46
  7. package/proto/generated/platform.client.js +175 -0
  8. package/proto/generated/platform.d.ts +1 -1
  9. package/proto/generated/platform.js +8277 -0
  10. package/src/DashPlatformSDK.d.ts +14 -14
  11. package/src/DashPlatformSDK.js +101 -0
  12. package/src/constants.js +10 -0
  13. package/src/contestedResources/createStateTransition.js +6 -0
  14. package/src/contestedResources/getContestedResourceVoteState.d.ts +3 -3
  15. package/src/contestedResources/getContestedResourceVoteState.js +72 -0
  16. package/src/contestedResources/index.d.ts +3 -3
  17. package/src/contestedResources/index.js +30 -0
  18. package/src/dataContracts/create.d.ts +1 -1
  19. package/src/dataContracts/create.js +11 -0
  20. package/src/dataContracts/createStateTransition.js +19 -0
  21. package/src/dataContracts/getDataContractByIdentifier.d.ts +2 -2
  22. package/src/dataContracts/getDataContractByIdentifier.js +44 -0
  23. package/src/dataContracts/index.d.ts +2 -2
  24. package/src/dataContracts/index.js +57 -0
  25. package/src/documents/create.d.ts +1 -1
  26. package/src/documents/create.js +4 -0
  27. package/src/documents/createStateTransition.d.ts +1 -1
  28. package/src/documents/createStateTransition.js +52 -0
  29. package/src/documents/index.d.ts +2 -2
  30. package/src/documents/index.js +83 -0
  31. package/src/documents/query.d.ts +2 -2
  32. package/src/documents/query.js +62 -0
  33. package/src/grpcConnectionPool.d.ts +2 -2
  34. package/src/grpcConnectionPool.js +79 -0
  35. package/src/identities/createStateTransition.d.ts +1 -1
  36. package/src/identities/createStateTransition.js +34 -0
  37. package/src/identities/getIdentityBalance.d.ts +2 -2
  38. package/src/identities/getIdentityBalance.js +40 -0
  39. package/src/identities/getIdentityByIdentifier.d.ts +2 -2
  40. package/src/identities/getIdentityByIdentifier.js +40 -0
  41. package/src/identities/getIdentityByNonUniquePublicKeyHash.d.ts +1 -1
  42. package/src/identities/getIdentityByNonUniquePublicKeyHash.js +44 -0
  43. package/src/identities/getIdentityByPublicKeyHash.d.ts +1 -1
  44. package/src/identities/getIdentityByPublicKeyHash.js +40 -0
  45. package/src/identities/getIdentityContractNonce.d.ts +2 -2
  46. package/src/identities/getIdentityContractNonce.js +43 -0
  47. package/src/identities/getIdentityNonce.d.ts +2 -2
  48. package/src/identities/getIdentityNonce.js +41 -0
  49. package/src/identities/getIdentityPublicKeys.d.ts +2 -2
  50. package/src/identities/getIdentityPublicKeys.js +47 -0
  51. package/src/identities/index.d.ts +2 -2
  52. package/src/identities/index.js +141 -0
  53. package/src/keyPair/deriveChild.js +3 -0
  54. package/src/keyPair/derivePath.js +3 -0
  55. package/src/keyPair/index.d.ts +1 -1
  56. package/src/keyPair/index.js +89 -0
  57. package/src/keyPair/mnemonicToSeed.js +4 -0
  58. package/src/names/index.d.ts +2 -2
  59. package/src/names/index.js +102 -0
  60. package/src/names/registerName.d.ts +1 -1
  61. package/src/names/registerName.js +64 -0
  62. package/src/names/searchByIdentity.d.ts +1 -1
  63. package/src/names/searchByIdentity.js +5 -0
  64. package/src/names/searchByName.d.ts +1 -1
  65. package/src/names/searchByName.js +16 -0
  66. package/src/names/testNameContested.js +3 -0
  67. package/src/names/validateName.js +11 -0
  68. package/src/node/epochs.d.ts +1 -1
  69. package/src/node/epochs.js +46 -0
  70. package/src/node/index.d.ts +3 -3
  71. package/src/node/index.js +43 -0
  72. package/src/node/status.d.ts +2 -2
  73. package/src/node/status.js +41 -0
  74. package/src/node/totalCredits.d.ts +2 -2
  75. package/src/node/totalCredits.js +35 -0
  76. package/src/signer/AbstractSigner.js +1 -0
  77. package/src/signer/PrivateKeySigner.d.ts +1 -0
  78. package/src/signer/PrivateKeySigner.js +65 -0
  79. package/src/signer/setSigner.d.ts +1 -1
  80. package/src/signer/setSigner.js +5 -0
  81. package/src/stateTransitions/broadcast.d.ts +1 -1
  82. package/src/stateTransitions/broadcast.js +10 -0
  83. package/src/stateTransitions/index.d.ts +1 -1
  84. package/src/stateTransitions/index.js +34 -0
  85. package/src/stateTransitions/waitForStateTransitionResult.d.ts +1 -1
  86. package/src/stateTransitions/waitForStateTransitionResult.js +8 -0
  87. package/src/tokens/createStateTransition.d.ts +1 -1
  88. package/src/tokens/createStateTransition.js +67 -0
  89. package/src/tokens/getIdentitiesTokenBalances.d.ts +2 -2
  90. package/src/tokens/getIdentitiesTokenBalances.js +43 -0
  91. package/src/tokens/getIdentityTokensBalances.d.ts +2 -2
  92. package/src/tokens/getIdentityTokensBalances.js +43 -0
  93. package/src/tokens/getTokenContractInfo.d.ts +2 -2
  94. package/src/tokens/getTokenContractInfo.js +43 -0
  95. package/src/tokens/getTokenDirectPurchasePrices.d.ts +2 -2
  96. package/src/tokens/getTokenDirectPurchasePrices.js +40 -0
  97. package/src/tokens/getTokenTotalSupply.d.ts +2 -2
  98. package/src/tokens/getTokenTotalSupply.js +41 -0
  99. package/src/tokens/index.d.ts +5 -5
  100. package/src/tokens/index.js +108 -0
  101. package/src/types.d.ts +2 -2
  102. package/src/types.js +15 -0
  103. package/src/utils/base58ToBytes.js +4 -0
  104. package/src/utils/bytesToHex.js +3 -0
  105. package/src/utils/bytesToTypedArray.js +3 -0
  106. package/src/utils/calculateMsgHash.js +31 -0
  107. package/src/utils/calculateSignHash.d.ts +1 -1
  108. package/src/utils/calculateSignHash.js +8 -0
  109. package/src/utils/calculateStateIdHash.d.ts +1 -1
  110. package/src/utils/calculateStateIdHash.js +10 -0
  111. package/src/utils/convertToHomographSafeChars.js +11 -0
  112. package/src/utils/createVoterIdentityId.js +13 -0
  113. package/src/utils/getEvonodeList.d.ts +1 -1
  114. package/src/utils/getEvonodeList.js +12 -0
  115. package/src/utils/getQuorumPublicKey.js +18 -0
  116. package/src/utils/getRandomArrayItem.js +3 -0
  117. package/src/utils/getRandomBytes.js +4 -0
  118. package/src/utils/hexToBytes.js +3 -0
  119. package/src/utils/index.js +61 -0
  120. package/src/utils/indexBytesToString.js +4 -0
  121. package/src/utils/sha256.js +15 -0
  122. package/src/utils/signHash.js +22 -0
  123. package/src/utils/signRequestId.js +19 -0
  124. package/src/utils/sleep.js +3 -0
  125. package/src/utils/stringToIndexValueBytes.js +10 -0
  126. package/src/utils/verifyTenderdashProof.d.ts +1 -1
  127. package/src/utils/verifyTenderdashProof.js +26 -0
  128. package/src/voting/createStateTransition.js +6 -0
  129. package/src/voting/createVote.js +5 -0
  130. package/src/voting/index.d.ts +1 -1
  131. package/src/voting/index.js +55 -0
  132. package/test/unit/ContestedResources.spec.js +258 -0
  133. package/test/unit/DataContract.spec.js +75 -0
  134. package/test/unit/Document.spec.js +109 -0
  135. package/test/unit/Identity.spec.js +232 -0
  136. package/test/unit/KeyPair.spec.js +34 -0
  137. package/test/unit/Names.spec.js +33 -0
  138. package/test/unit/Node.spec.js +58 -0
  139. package/test/unit/SDK.spec.js +10 -0
  140. package/test/unit/Tokens.spec.js +121 -0
@@ -0,0 +1,141 @@
1
+ import getIdentityContractNonce from './getIdentityContractNonce.js';
2
+ import getIdentityPublicKeys from './getIdentityPublicKeys.js';
3
+ import getIdentityNonce from './getIdentityNonce.js';
4
+ import getIdentityBalance from './getIdentityBalance.js';
5
+ import getIdentityByPublicKeyHash from './getIdentityByPublicKeyHash.js';
6
+ import getIdentityByIdentifier from './getIdentityByIdentifier.js';
7
+ import { AssetLockProofWASM, ContractBoundsWASM, IdentifierWASM, IdentityPublicKeyInCreationWASM, OutPointWASM } from 'pshenmic-dpp';
8
+ import createStateTransition from './createStateTransition.js';
9
+ import getIdentityByNonUniquePublicKeyHash from './getIdentityByNonUniquePublicKeyHash.js';
10
+ import hexToBytes from '../utils/hexToBytes.js';
11
+ /**
12
+ * Collection of methods to query identities and its related data
13
+ *
14
+ * @hideconstructor
15
+ */
16
+ export class IdentitiesController {
17
+ /** @ignore */
18
+ grpcPool;
19
+ constructor(grpcPool) {
20
+ this.grpcPool = grpcPool;
21
+ }
22
+ /**
23
+ * Get current balance of your Identity by identifier
24
+ *
25
+ * @param identifier {IdentifierLike} Identifier of an identity
26
+ *
27
+ * @return {Promise<bigint>}
28
+ */
29
+ async getIdentityBalance(identifier) {
30
+ return await getIdentityBalance(this.grpcPool, identifier);
31
+ }
32
+ /**
33
+ * Retrieves an Identity from the network by give public key hash
34
+ *
35
+ * @param hex {string} public key hash value in hex, should be a length of 40
36
+ *
37
+ * @return {Promise<IdentityWASM>}
38
+ */
39
+ async getIdentityByPublicKeyHash(hex) {
40
+ if (hex.length !== 40) {
41
+ throw new Error('Public key hash should equal 40');
42
+ }
43
+ return await getIdentityByPublicKeyHash(this.grpcPool, hex);
44
+ }
45
+ /**
46
+ * Retrieves an Identity from the network by non-unique public key hash (like Voter Identity, SHA160)
47
+ *
48
+ * @param hex {string} public key hash value in hex, should be a length of 40
49
+ *
50
+ * @return {Promise<IdentityWASM>}
51
+ */
52
+ async getIdentityByNonUniquePublicKeyHash(hex) {
53
+ if (hex.length !== 40) {
54
+ throw new Error('Public key hash should equal 40');
55
+ }
56
+ return await getIdentityByNonUniquePublicKeyHash(this.grpcPool, hex);
57
+ }
58
+ /**
59
+ * Retrieves Identity by identifier from the network
60
+ * @param identifier {IdentifierLike} identifier
61
+ *
62
+ * @return {Promise<IdentityWASM>}
63
+ */
64
+ async getIdentityByIdentifier(identifier) {
65
+ return await getIdentityByIdentifier(this.grpcPool, identifier);
66
+ }
67
+ /**
68
+ * Get Identity Nonce (usually used by Identity transitions)
69
+ * @param identifier
70
+ */
71
+ async getIdentityNonce(identifier) {
72
+ return await getIdentityNonce(this.grpcPool, identifier);
73
+ }
74
+ /**
75
+ * Get Identity Contract Nonce (usually used by Document transitions)
76
+ * @param identifier
77
+ * @param dataContract
78
+ *
79
+ * @return {Promise<bigint>}
80
+ */
81
+ async getIdentityContractNonce(identifier, dataContract) {
82
+ return await getIdentityContractNonce(this.grpcPool, identifier, dataContract);
83
+ }
84
+ /**
85
+ * Retrieve given Identity's public keys
86
+ * @param identifier
87
+ *
88
+ * @return {Promise<IdentityPublicKeyWASM[]>}
89
+ */
90
+ async getIdentityPublicKeys(identifier) {
91
+ return await getIdentityPublicKeys(this.grpcPool, identifier);
92
+ }
93
+ /**
94
+ * Helper function for creating {StateTransitionWASM} for Identity transitions
95
+ *
96
+ * To create an IdentityCreateTransition, you should pass a params.assetLockProof object containing
97
+ * all necessary AssetLockProof data to make the transaction.
98
+ * Both InstantSend and ChainLock AssetLock proofs supported
99
+ *
100
+ * @param type {string} type of transition, must be a one of ('create' | 'update' | 'topUp')
101
+ * @param params {IdentityTransitionParams} params
102
+ */
103
+ createStateTransition(type, params) {
104
+ if (params.identityId != null) {
105
+ params.identityId = new IdentifierWASM(params.identityId);
106
+ }
107
+ if (params.disablePublicKeyIds == null) {
108
+ params.disablePublicKeyIds = [];
109
+ }
110
+ if (params.assetLockProof != null) {
111
+ const { type } = params.assetLockProof;
112
+ if (type === 'chainLock') {
113
+ const { txid, outputIndex, coreChainLockedHeight } = params.assetLockProof;
114
+ // @ts-expect-error
115
+ params.assetLockProof = AssetLockProofWASM.createChainAssetLockProof(coreChainLockedHeight, new OutPointWASM(txid, outputIndex));
116
+ }
117
+ else if (type === 'instantLock') {
118
+ const { transaction, outputIndex, instantLock } = params.assetLockProof;
119
+ // @ts-expect-error
120
+ params.assetLockProof = AssetLockProofWASM.createInstantAssetLockProof(hexToBytes(instantLock), hexToBytes(transaction), outputIndex);
121
+ }
122
+ else if (type == null) {
123
+ throw new Error('Missing Asset Lock type in the params');
124
+ }
125
+ else {
126
+ throw new Error(`Unknown Asset Lock type: ${type}`);
127
+ }
128
+ }
129
+ if (params.addPublicKeys != null) {
130
+ // @ts-expect-error
131
+ params.addPublicKeys = params.addPublicKeys
132
+ .map(({ id, purpose, securityLevel, keyType, readOnly, data, signature, contractBounds }) => new IdentityPublicKeyInCreationWASM(id, purpose, securityLevel, keyType, readOnly, data, signature, (contractBounds != null) ? new ContractBoundsWASM(contractBounds.dataContractId, contractBounds.documentType) : undefined));
133
+ }
134
+ if (params.publicKeys != null) {
135
+ // @ts-expect-error
136
+ params.publicKeys = params.publicKeys
137
+ .map(({ id, purpose, securityLevel, keyType, readOnly, data, signature, contractBounds }) => new IdentityPublicKeyInCreationWASM(id, purpose, securityLevel, keyType, readOnly, data, signature, (contractBounds != null) ? new ContractBoundsWASM(contractBounds.dataContractId, contractBounds.documentType) : undefined));
138
+ }
139
+ return createStateTransition(type, params);
140
+ }
141
+ }
@@ -0,0 +1,3 @@
1
+ export default function deriveChild(hdKey, index) {
2
+ return hdKey.deriveChild(index);
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function derivePath(hdKey, path) {
2
+ return hdKey.derive(path);
3
+ }
@@ -1,5 +1,5 @@
1
1
  import { HDKey } from '@scure/bip32';
2
- import { Network } from '../types';
2
+ import { Network } from '../types.js';
3
3
  /**
4
4
  * Collection of functions to work with private keys and seed phrases
5
5
  *
@@ -0,0 +1,89 @@
1
+ import { HDKey } from '@scure/bip32';
2
+ import mnemonicToSeed from './mnemonicToSeed.js';
3
+ import deriveChild from './deriveChild.js';
4
+ import derivePath from './derivePath.js';
5
+ import { p2pkh } from '@scure/btc-signer';
6
+ const DASH_VERSIONS = {
7
+ mainnet: { pubKeyHash: 0x4c, scriptHash: 0x10, bech32: 'dc', wif: 0xcc, private: 0x0488ade4, public: 0x0488b21e },
8
+ testnet: { pubKeyHash: 0x8c, scriptHash: 0x13, bech32: 'dc', wif: 0xef, private: 0x04358394, public: 0x043587cf }
9
+ };
10
+ /**
11
+ * Collection of functions to work with private keys and seed phrases
12
+ *
13
+ * @hideconstructor
14
+ */
15
+ export class KeyPairController {
16
+ /**
17
+ * Returns seed from mnemonic phrase
18
+ *
19
+ * @param mnemonic {string} - The BIP39 mnemonic phrase.
20
+ * @param salt {string=} - Optional salt for seed derivation.
21
+ *
22
+ * @return {Uint8Array} Seed bytes
23
+ */
24
+ mnemonicToSeed(mnemonic, salt) {
25
+ return mnemonicToSeed(mnemonic, salt);
26
+ }
27
+ /**
28
+ * Returns seed from mnemonic phrase
29
+ *
30
+ * @param seed {Uint8Array}
31
+ * @param network {Network} network
32
+ *
33
+ * @return {HDKey} HDKey
34
+ */
35
+ seedToHdKey(seed, network = 'mainnet') {
36
+ return HDKey.fromMasterSeed(seed, DASH_VERSIONS[network]);
37
+ }
38
+ /**
39
+ * Allows to derive child HD Key
40
+ *
41
+ * @param hdKey {HDKey} - The HDKey parent instance
42
+ * @param index {number} - Index of child
43
+ *
44
+ * @return {Promise<HDKey>} A promise that resolves child key
45
+ */
46
+ async deriveChild(hdKey, index) {
47
+ return deriveChild(hdKey, index);
48
+ }
49
+ /**
50
+ * Allows to derive HD key by path
51
+ *
52
+ * @param hdKey {HDKey} - The HDKey parent instance
53
+ * @param path {string} - Path of children
54
+ *
55
+ * @return {Promise<HDKey>} A promise that resolves key by path
56
+ */
57
+ async derivePath(hdKey, path) {
58
+ return derivePath(hdKey, path);
59
+ }
60
+ /**
61
+ * Derives an {HDKey} child by identity index and key index from an {HDKey}
62
+ *
63
+ * Usually used to get a identity private key from seed
64
+ *
65
+ * @param hdKey {HDKey}
66
+ * @param identityIndex {number}
67
+ * @param keyIndex {number}
68
+ * @param network {Network}
69
+ *
70
+ * @returns {HDKey}
71
+ */
72
+ deriveIdentityPrivateKey(hdKey, identityIndex, keyIndex, network) {
73
+ const networkIndex = network === 'mainnet' ? 5 : 1;
74
+ const pathPostfix = `/5'/0'/0'/${identityIndex}'/${keyIndex}'`;
75
+ return derivePath(hdKey, `m/9'/${networkIndex}'${pathPostfix}`);
76
+ }
77
+ /**
78
+ * Converts {PublicKey} to a Dash network address (P2PKH)
79
+ *
80
+ * @param publicKey {Uint8Array}
81
+ * @param network {Network}
82
+ *
83
+ * @returns {string}
84
+ */
85
+ p2pkhAddress(publicKey, network) {
86
+ const P2PKH = p2pkh(publicKey, DASH_VERSIONS[network]);
87
+ return P2PKH.address;
88
+ }
89
+ }
@@ -0,0 +1,4 @@
1
+ import { mnemonicToSeedSync as func } from '@scure/bip39';
2
+ export default function mnemonicToSeed(mnemonic, salt) {
3
+ return func(mnemonic, salt);
4
+ }
@@ -1,6 +1,6 @@
1
- import GRPCConnectionPool from '../grpcConnectionPool';
1
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
2
2
  import { DocumentWASM, PrivateKeyWASM } from 'pshenmic-dpp';
3
- import { IdentifierLike } from '../types';
3
+ import { IdentifierLike } from '../types.js';
4
4
  /**
5
5
  * Functions related to DPNS names (usernames)
6
6
  *
@@ -0,0 +1,102 @@
1
+ import { IdentifierWASM } from 'pshenmic-dpp';
2
+ import searchByName from './searchByName.js';
3
+ import searchByIdentity from './searchByIdentity.js';
4
+ import registerName from './registerName.js';
5
+ import validateName from './validateName.js';
6
+ import getIdentityByIdentifier from '../identities/getIdentityByIdentifier.js';
7
+ import convertToHomographSafeChars from '../utils/convertToHomographSafeChars.js';
8
+ import testNameContested from './testNameContested.js';
9
+ /**
10
+ * Functions related to DPNS names (usernames)
11
+ *
12
+ * @hideconstructor
13
+ */
14
+ export class NamesController {
15
+ /** @ignore **/
16
+ grpcPool;
17
+ constructor(grpcPool) {
18
+ this.grpcPool = grpcPool;
19
+ }
20
+ /**
21
+ * Searches for a registered DPNS name in the network
22
+ *
23
+ * Should be in a human-readable format, for example pshenmic.dash
24
+ *
25
+ * Returns a {DocumentWASM} document of type 'domain' from DPNS system data contract if found,
26
+ * returns null if not found.
27
+ *
28
+ * https://testnet.platform-explorer.com/dataContract/GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec?tab=schema
29
+ *
30
+ * @param name {string}
31
+ *
32
+ * @return Promise<DocumentWASM | null>
33
+ */
34
+ async searchByName(name) {
35
+ const validation = validateName(name);
36
+ if (validation != null) {
37
+ throw new Error(validation);
38
+ }
39
+ return await searchByName(this.grpcPool, name);
40
+ }
41
+ /**
42
+ * Tests a given username against contested names rules.
43
+ * Contested names includes an additional fee of 0.2 Dash
44
+ * as a voting resolution fee
45
+ *
46
+ * This function return boolean whether given username (f.e pshenmic.dash)
47
+ * falls under contested names rules.
48
+ * @param name
49
+ */
50
+ testNameContested(name) {
51
+ const validation = validateName(name);
52
+ if (validation != null) {
53
+ throw new Error(validation);
54
+ }
55
+ const [label] = name.split('.');
56
+ const normalizedLabel = convertToHomographSafeChars(label);
57
+ return testNameContested(normalizedLabel);
58
+ }
59
+ async searchByIdentity(identifier) {
60
+ return await searchByIdentity(this.grpcPool, new IdentifierWASM(identifier));
61
+ }
62
+ /**
63
+ * Performs a DPNS name registration sequence
64
+ * Contested names are include additional fee of 0.2 Dash
65
+ * Check your name is contested with .testNameContested(name) method to check if additional fee will be charged
66
+ *
67
+ * @param name {string} username (ex. pshenmic.dash)
68
+ * @param identityId {IdentifierLike} identity identifier
69
+ * @param privateKey {PrivateKeyWASM} Authentication / High private key from your identity
70
+ */
71
+ async registerName(name, identityId, privateKey) {
72
+ const validation = validateName(name);
73
+ if (validation != null) {
74
+ throw new Error(validation);
75
+ }
76
+ const identity = await getIdentityByIdentifier(this.grpcPool, identityId);
77
+ await registerName(this.grpcPool, name, identity, privateKey);
78
+ }
79
+ /**
80
+ * Converts DPNS name to normalized format (ex. alice.dash -> al1ce.dash)
81
+ *
82
+ * source: https://github.com/dashpay/platform/blob/master/packages/js-dash-sdk/src/utils/convertToHomographSafeChars.ts
83
+ *
84
+ *
85
+ * @param label {string}
86
+ *
87
+ * @return {string}
88
+ */
89
+ normalizeLabel(label) {
90
+ return convertToHomographSafeChars(label);
91
+ }
92
+ /**
93
+ * Validates a DPNS name that you would like to register
94
+ *
95
+ * @param fullName {string} full DPNS name (ex. pshenmic.dash)
96
+ *
97
+ * @return {string} null if valid or string with a reason
98
+ */
99
+ validateName(fullName) {
100
+ return validateName(fullName);
101
+ }
102
+ }
@@ -1,3 +1,3 @@
1
1
  import { IdentityWASM, PrivateKeyWASM } from 'pshenmic-dpp';
2
- import GRPCConnectionPool from '../grpcConnectionPool';
2
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
3
3
  export default function registerName(grpcPool: GRPCConnectionPool, name: string, identity: IdentityWASM, privateKey: PrivateKeyWASM): Promise<void>;
@@ -0,0 +1,64 @@
1
+ import convertToHomographSafeChars from '../utils/convertToHomographSafeChars.js';
2
+ import { PrefundedVotingBalanceWASM } from 'pshenmic-dpp';
3
+ import getRandomBytes from '../utils/getRandomBytes.js';
4
+ import sha256 from '../utils/sha256.js';
5
+ import createDocument from '../documents/create.js';
6
+ import createStateTransition from '../documents/createStateTransition.js';
7
+ import getIdentityContractNonce from '../identities/getIdentityContractNonce.js';
8
+ import broadcast from '../stateTransitions/broadcast.js';
9
+ import waitForStateTransitionResult from '../stateTransitions/waitForStateTransitionResult.js';
10
+ import testNameContested from './testNameContested.js';
11
+ import { DPNS_DATA_CONTRACT_ID } from '../constants.js';
12
+ export default async function registerName(grpcPool, name, identity, privateKey) {
13
+ const [identityPublicKey] = identity.getPublicKeys().filter(identityPublicKey => identityPublicKey.getPublicKeyHash() === privateKey.getPublicKeyHash());
14
+ if (identityPublicKey == null) {
15
+ throw new Error('Private key does not match the identity');
16
+ }
17
+ if (identityPublicKey.securityLevel !== 'HIGH' && identityPublicKey.purpose !== 'AUTHENTICATION') {
18
+ throw new Error('Wrong private key, must be from AUTHENTICATION HIGH identity public key');
19
+ }
20
+ const [label, parentDomainName] = name.split('.');
21
+ const salt = getRandomBytes(32);
22
+ const normalizedParentDomainName = convertToHomographSafeChars(parentDomainName);
23
+ const normalizedLabel = convertToHomographSafeChars(label);
24
+ const normalizedFullDomainName = `${normalizedLabel}.${normalizedParentDomainName}`;
25
+ const saltedDomainHash = await sha256(await sha256(new Uint8Array([
26
+ ...salt,
27
+ ...new TextEncoder().encode(normalizedFullDomainName)
28
+ ])));
29
+ let document;
30
+ let stateTransition;
31
+ // 1. Create preorder document
32
+ const preorderData = {
33
+ saltedDomainHash: Array.from(saltedDomainHash)
34
+ };
35
+ const identityContractNonce = await getIdentityContractNonce(grpcPool, identity.id, DPNS_DATA_CONTRACT_ID);
36
+ document = createDocument(DPNS_DATA_CONTRACT_ID, 'preorder', preorderData, identity.id.base58());
37
+ stateTransition = createStateTransition(document, 'create', { identityContractNonce: identityContractNonce + BigInt(1) });
38
+ await stateTransition.sign(privateKey, identityPublicKey);
39
+ await broadcast(grpcPool, stateTransition);
40
+ // wait for state transition confirmation before next broadcast
41
+ await waitForStateTransitionResult(grpcPool, stateTransition);
42
+ // 2. Create domain document
43
+ const domainData = {
44
+ label,
45
+ normalizedLabel,
46
+ parentDomainName,
47
+ normalizedParentDomainName,
48
+ preorderSalt: Array.from(salt),
49
+ records: {
50
+ identity: Array.from(identity.id.bytes())
51
+ },
52
+ subdomainRules: {
53
+ allowSubdomains: false
54
+ }
55
+ };
56
+ document = createDocument(DPNS_DATA_CONTRACT_ID, 'domain', domainData, identity.id.base58());
57
+ stateTransition = createStateTransition(document, 'create', {
58
+ identityContractNonce: identityContractNonce + BigInt(2),
59
+ // @ts-expect-error
60
+ prefundedVotingBalance: testNameContested(normalizedLabel) ? new PrefundedVotingBalanceWASM('parentNameAndLabel', BigInt(20000000000)) : undefined
61
+ });
62
+ await stateTransition.sign(privateKey, identityPublicKey);
63
+ await broadcast(grpcPool, stateTransition);
64
+ }
@@ -1,3 +1,3 @@
1
1
  import { DocumentWASM, IdentifierWASM } from 'pshenmic-dpp';
2
- import GRPCConnectionPool from '../grpcConnectionPool';
2
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
3
3
  export default function searchByIdentity(grpcPool: GRPCConnectionPool, identifier: IdentifierWASM): Promise<DocumentWASM[]>;
@@ -0,0 +1,5 @@
1
+ import query from '../documents/query.js';
2
+ const DPNS_DATA_CONTRACT_ID = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
3
+ export default async function searchByIdentity(grpcPool, identifier) {
4
+ return await query(grpcPool, DPNS_DATA_CONTRACT_ID, 'domain', [['records.identity', '=', identifier.base58()]], [['records.identity', 'asc']]);
5
+ }
@@ -1,3 +1,3 @@
1
1
  import { DocumentWASM } from 'pshenmic-dpp';
2
- import GRPCConnectionPool from '../grpcConnectionPool';
2
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
3
3
  export default function search(grpcPool: GRPCConnectionPool, name: string): Promise<DocumentWASM[]>;
@@ -0,0 +1,16 @@
1
+ import convertToHomographSafeChars from '../utils/convertToHomographSafeChars.js';
2
+ import query from '../documents/query.js';
3
+ const DPNS_DATA_CONTRACT_ID = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
4
+ export default async function search(grpcPool, name) {
5
+ const [label, parentDomainName] = name.split('.');
6
+ const normalizedParentDomainName = convertToHomographSafeChars(parentDomainName);
7
+ const normalizedLabelPrefix = convertToHomographSafeChars(label);
8
+ const where = [
9
+ ['normalizedParentDomainName', '==', normalizedParentDomainName],
10
+ ['normalizedLabel', 'startsWith', normalizedLabelPrefix]
11
+ ];
12
+ const orderBy = [
13
+ ['normalizedLabel', 'asc']
14
+ ];
15
+ return await query(grpcPool, DPNS_DATA_CONTRACT_ID, 'domain', where, orderBy);
16
+ }
@@ -0,0 +1,3 @@
1
+ export default function testNameContested(normalizedLabel) {
2
+ return /^[a-zA-Z01-]{3,19}$/.test(normalizedLabel);
3
+ }
@@ -0,0 +1,11 @@
1
+ export default function validateName(fullName) {
2
+ const chunks = fullName.split('.');
3
+ if (chunks.length !== 2) {
4
+ return 'Name to search should be a full domain name (ex. pshenmic.dash)';
5
+ }
6
+ const [label, parentDomainName] = chunks;
7
+ if (parentDomainName !== 'dash') {
8
+ return 'Root domain must be .dash';
9
+ }
10
+ return /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$/.test(label) ? null : 'Unacceptable label name';
11
+ }
@@ -1,4 +1,4 @@
1
- import GRPCConnectionPool from '../grpcConnectionPool';
1
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
2
2
  export interface EpochInfo {
3
3
  number: number;
4
4
  firstBlockHeight: number;
@@ -0,0 +1,46 @@
1
+ import { GetEpochsInfoRequest } from '../../proto/generated/platform.js';
2
+ import { PlatformVersionWASM, verifyEpochsInfoProof } from 'pshenmic-dpp';
3
+ import { getQuorumPublicKey } from '../utils/getQuorumPublicKey.js';
4
+ import bytesToHex from '../utils/bytesToHex.js';
5
+ import verifyTenderdashProof from '../utils/verifyTenderdashProof.js';
6
+ import { UInt32Value } from '../../proto/generated/google/protobuf/wrappers.js';
7
+ export default async function epochs(grpcPool, count, ascending, start) {
8
+ const getEpochsInfoRequest = GetEpochsInfoRequest.create({
9
+ version: {
10
+ oneofKind: 'v0',
11
+ v0: {
12
+ startEpoch: start != null ? UInt32Value.create({ value: start }) : undefined,
13
+ count,
14
+ ascending,
15
+ prove: true
16
+ }
17
+ }
18
+ });
19
+ const { response } = await grpcPool.getClient().getEpochsInfo(getEpochsInfoRequest);
20
+ const { version } = response;
21
+ if (version.oneofKind !== 'v0') {
22
+ throw new Error('Unexpected oneOf type returned from DAPI (must be v0)');
23
+ }
24
+ const { v0 } = version;
25
+ if (v0.result.oneofKind !== 'proof') {
26
+ throw new Error('Unexpected oneOf type returned from DAPI (must be proof)');
27
+ }
28
+ const { result: { proof }, metadata } = v0;
29
+ if (metadata == null) {
30
+ throw new Error('Metadata not found');
31
+ }
32
+ const { rootHash, epochsInfo } = verifyEpochsInfoProof(proof.grovedbProof, metadata.epoch, start, count, ascending, PlatformVersionWASM.PLATFORM_V9);
33
+ const quorumPublicKey = await getQuorumPublicKey(grpcPool.network, proof.quorumType, bytesToHex(proof.quorumHash));
34
+ const verify = await verifyTenderdashProof(proof, metadata, rootHash, quorumPublicKey);
35
+ if (!verify) {
36
+ throw new Error('Failed to verify query');
37
+ }
38
+ return epochsInfo.map(info => ({
39
+ number: info.index,
40
+ firstBlockHeight: info.firstBlockHeight,
41
+ firstCoreBlockHeight: info.firstCoreBlockHeight,
42
+ startTime: info.firstBlockTime,
43
+ feeMultiplier: info.feeMultiplierPermille,
44
+ protocolVersion: info.protocolVersion
45
+ }));
46
+ }
@@ -1,6 +1,6 @@
1
- import GRPCConnectionPool from '../grpcConnectionPool';
2
- import { Network, NodeStatus } from '../types';
3
- import { EpochInfo } from './epochs';
1
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
2
+ import { Network, NodeStatus } from '../types.js';
3
+ import { EpochInfo } from './epochs.js';
4
4
  /**
5
5
  * Node controller for requesting information about DAPI node
6
6
  *
@@ -0,0 +1,43 @@
1
+ import getStatus from './status.js';
2
+ import getEpochsInfo from './epochs.js';
3
+ import getTotalCredits from './totalCredits.js';
4
+ /**
5
+ * Node controller for requesting information about DAPI node
6
+ *
7
+ * @hideconstructor
8
+ */
9
+ export class NodeController {
10
+ /** @ignore **/
11
+ grpcPool;
12
+ network;
13
+ constructor(grpcPool, network) {
14
+ this.grpcPool = grpcPool;
15
+ this.network = network;
16
+ }
17
+ /**
18
+ * Retrieves an info about node
19
+ * Includes information about genesis, chain, software versions
20
+ *
21
+ * @return {Promise<NodeStatus>}
22
+ */
23
+ async status() {
24
+ return await getStatus(this.grpcPool);
25
+ }
26
+ /**
27
+ * Returns total credits amount in platform
28
+ *
29
+ * @return {Promise<bigint>}
30
+ */
31
+ async totalCredits() {
32
+ return await getTotalCredits(this.grpcPool, this.network);
33
+ }
34
+ /**
35
+ * Retrieves an info about epochs
36
+ * Includes information about first block height, time, fee multiplier, number
37
+ *
38
+ * @return {Promise<EpochInfo[]>}
39
+ */
40
+ async getEpochsInfo(count, ascending, start) {
41
+ return await getEpochsInfo(this.grpcPool, count, ascending, start);
42
+ }
43
+ }
@@ -1,3 +1,3 @@
1
- import { NodeStatus } from '../types';
2
- import GRPCConnectionPool from '../grpcConnectionPool';
1
+ import { NodeStatus } from '../types.js';
2
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
3
3
  export default function status(grpcPool: GRPCConnectionPool): Promise<NodeStatus>;
@@ -0,0 +1,41 @@
1
+ import { GetStatusRequest } from '../../proto/generated/platform.js';
2
+ import bytesToHex from '../utils/bytesToHex.js';
3
+ export default async function status(grpcPool) {
4
+ const getStatusRequest = GetStatusRequest.create({
5
+ version: {
6
+ oneofKind: 'v0',
7
+ v0: {}
8
+ }
9
+ });
10
+ const { response } = await grpcPool.getClient().getStatus(getStatusRequest);
11
+ const { version } = response;
12
+ if (version.oneofKind !== 'v0') {
13
+ throw new Error('Unexpected oneOf type returned from DAPI (must be v0)');
14
+ }
15
+ const { v0 } = version;
16
+ return {
17
+ node: (v0.node != null)
18
+ ? {
19
+ id: bytesToHex(v0.node.id),
20
+ proTxHash: v0.node.proTxHash != null ? bytesToHex(v0.node.proTxHash) : undefined
21
+ }
22
+ : undefined,
23
+ chain: (v0.chain != null)
24
+ ? {
25
+ catchingUp: v0.chain.catchingUp,
26
+ latestBlockHeight: v0.chain.latestBlockHeight,
27
+ earliestBlockHeight: v0.chain.earliestBlockHeight,
28
+ maxPeerBlockHeight: v0.chain.maxPeerBlockHeight,
29
+ coreChainLockedHeight: v0.chain.coreChainLockedHeight,
30
+ latestBlockHash: v0.chain?.latestBlockHash != null ? bytesToHex(v0.chain?.latestBlockHash) : '',
31
+ latestAppHash: v0.chain?.latestAppHash != null ? bytesToHex(v0.chain?.latestAppHash) : '',
32
+ earliestBlockHash: v0.chain?.earliestBlockHash != null ? bytesToHex(v0.chain?.earliestBlockHash) : '',
33
+ earliestAppHash: v0.chain?.earliestAppHash != null ? bytesToHex(v0.chain?.earliestAppHash) : ''
34
+ }
35
+ : undefined,
36
+ version: v0.version,
37
+ network: v0.network,
38
+ stateSync: v0.stateSync,
39
+ time: v0.time
40
+ };
41
+ }
@@ -1,3 +1,3 @@
1
- import GRPCConnectionPool from '../grpcConnectionPool';
2
- import { Network } from '../types';
1
+ import GRPCConnectionPool from '../grpcConnectionPool.js';
2
+ import { Network } from '../types.js';
3
3
  export default function totalCredits(grpcPool: GRPCConnectionPool, network: Network): Promise<bigint>;