dash-platform-sdk 1.3.0-dev.5 → 1.3.0-dev.6
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.
- package/bundle.min.js +17 -17
- package/index.js +2 -0
- package/package.json +4 -4
- package/proto/generated/google/protobuf/wrappers.js +615 -0
- package/proto/generated/platform.client.js +175 -0
- package/proto/generated/platform.js +8277 -0
- package/src/DashPlatformSDK.js +101 -0
- package/src/constants.js +10 -0
- package/src/contestedResources/createStateTransition.js +6 -0
- package/src/contestedResources/getContestedResourceVoteState.js +72 -0
- package/src/contestedResources/index.js +30 -0
- package/src/dataContracts/create.js +11 -0
- package/src/dataContracts/createStateTransition.js +19 -0
- package/src/dataContracts/getDataContractByIdentifier.js +44 -0
- package/src/dataContracts/index.js +57 -0
- package/src/documents/create.js +4 -0
- package/src/documents/createStateTransition.js +52 -0
- package/src/documents/index.js +83 -0
- package/src/documents/query.js +62 -0
- package/src/grpcConnectionPool.js +79 -0
- package/src/identities/createStateTransition.js +34 -0
- package/src/identities/getIdentityBalance.js +40 -0
- package/src/identities/getIdentityByIdentifier.js +40 -0
- package/src/identities/getIdentityByNonUniquePublicKeyHash.js +44 -0
- package/src/identities/getIdentityByPublicKeyHash.js +40 -0
- package/src/identities/getIdentityContractNonce.js +43 -0
- package/src/identities/getIdentityNonce.js +41 -0
- package/src/identities/getIdentityPublicKeys.js +47 -0
- package/src/identities/index.js +141 -0
- package/src/keyPair/deriveChild.js +3 -0
- package/src/keyPair/derivePath.js +3 -0
- package/src/keyPair/index.js +89 -0
- package/src/keyPair/mnemonicToSeed.js +4 -0
- package/src/names/index.js +102 -0
- package/src/names/registerName.js +64 -0
- package/src/names/searchByIdentity.js +5 -0
- package/src/names/searchByName.js +16 -0
- package/src/names/testNameContested.js +3 -0
- package/src/names/validateName.js +11 -0
- package/src/node/epochs.js +46 -0
- package/src/node/index.js +43 -0
- package/src/node/status.js +41 -0
- package/src/node/totalCredits.js +35 -0
- package/src/signer/AbstractSigner.js +1 -0
- package/src/signer/PrivateKeySigner.d.ts +0 -0
- package/src/signer/PrivateKeySigner.js +64 -0
- package/src/signer/setSigner.js +5 -0
- package/src/stateTransitions/broadcast.js +10 -0
- package/src/stateTransitions/index.js +34 -0
- package/src/stateTransitions/waitForStateTransitionResult.js +8 -0
- package/src/tokens/createStateTransition.js +67 -0
- package/src/tokens/getIdentitiesTokenBalances.js +43 -0
- package/src/tokens/getIdentityTokensBalances.js +43 -0
- package/src/tokens/getTokenContractInfo.js +43 -0
- package/src/tokens/getTokenDirectPurchasePrices.js +40 -0
- package/src/tokens/getTokenTotalSupply.js +41 -0
- package/src/tokens/index.js +108 -0
- package/src/types.js +15 -0
- package/src/utils/base58ToBytes.js +4 -0
- package/src/utils/bytesToHex.js +3 -0
- package/src/utils/bytesToTypedArray.js +3 -0
- package/src/utils/calculateMsgHash.js +31 -0
- package/src/utils/calculateSignHash.js +8 -0
- package/src/utils/calculateStateIdHash.js +10 -0
- package/src/utils/convertToHomographSafeChars.js +11 -0
- package/src/utils/createVoterIdentityId.js +13 -0
- package/src/utils/getEvonodeList.js +12 -0
- package/src/utils/getQuorumPublicKey.js +18 -0
- package/src/utils/getRandomArrayItem.js +3 -0
- package/src/utils/getRandomBytes.js +4 -0
- package/src/utils/hexToBytes.js +3 -0
- package/src/utils/index.js +61 -0
- package/src/utils/indexBytesToString.js +4 -0
- package/src/utils/sha256.js +15 -0
- package/src/utils/signHash.js +22 -0
- package/src/utils/signRequestId.js +19 -0
- package/src/utils/sleep.js +3 -0
- package/src/utils/stringToIndexValueBytes.js +10 -0
- package/src/utils/verifyTenderdashProof.js +26 -0
- package/src/voting/createStateTransition.js +6 -0
- package/src/voting/createVote.js +5 -0
- package/src/voting/index.js +55 -0
- package/test/unit/ContestedResources.spec.js +259 -0
- package/test/unit/DataContract.spec.js +75 -0
- package/test/unit/Document.spec.js +109 -0
- package/test/unit/Identity.spec.js +232 -0
- package/test/unit/KeyPair.spec.js +34 -0
- package/test/unit/Names.spec.js +33 -0
- package/test/unit/Node.spec.js +58 -0
- package/test/unit/SDK.spec.js +10 -0
- package/test/unit/Tokens.spec.js +121 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import createVote from './createVote';
|
|
2
|
+
import { IdentifierWASM, MasternodeVoteTransitionWASM, ResourceVoteChoiceWASM } from 'pshenmic-dpp';
|
|
3
|
+
import { createVoterIdentityId } from '../utils/createVoterIdentityId';
|
|
4
|
+
/**
|
|
5
|
+
* Voting controller for performing masternode votes
|
|
6
|
+
*
|
|
7
|
+
* @hideconstructor
|
|
8
|
+
*/
|
|
9
|
+
export class VotingController {
|
|
10
|
+
/**
|
|
11
|
+
* Creates an {IdentifierWASM} from masternode pro tx hash and voting address (public key hash)
|
|
12
|
+
*
|
|
13
|
+
* @param proTxHash {string} voter's masternode pro tx hash
|
|
14
|
+
* @param publicKeyHash {string} voter address's public key hash
|
|
15
|
+
*
|
|
16
|
+
* @return {Promise<IdentifierWASM>}
|
|
17
|
+
*/
|
|
18
|
+
async createVoterIdentityId(proTxHash, publicKeyHash) {
|
|
19
|
+
return await createVoterIdentityId(proTxHash, publicKeyHash);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a {VoteWASM} with all information about the vote, such as data contract id, choice, and target index
|
|
23
|
+
*
|
|
24
|
+
* @param dataContractId {DataContractWASM}
|
|
25
|
+
* @param documentTypeName {string}
|
|
26
|
+
* @param indexName {string}
|
|
27
|
+
* @param indexValues {string[]}
|
|
28
|
+
* @param choice {ResourceVoteChoice}
|
|
29
|
+
*/
|
|
30
|
+
createVote(dataContractId, documentTypeName, indexName, indexValues, choice) {
|
|
31
|
+
let resourceVoteChoice;
|
|
32
|
+
if (choice === 'lock') {
|
|
33
|
+
resourceVoteChoice = ResourceVoteChoiceWASM.Lock();
|
|
34
|
+
}
|
|
35
|
+
else if (choice === 'abstain') {
|
|
36
|
+
resourceVoteChoice = ResourceVoteChoiceWASM.Abstain();
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
resourceVoteChoice = ResourceVoteChoiceWASM.TowardsIdentity(new IdentifierWASM(choice));
|
|
40
|
+
}
|
|
41
|
+
return createVote(new IdentifierWASM(dataContractId), documentTypeName, indexName, indexValues, resourceVoteChoice);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Creates a {StateTransitionWASM} from masternoe protxhash and voter identity
|
|
45
|
+
*
|
|
46
|
+
* @param voteWASM {VoteWASM} vote instance from .createMsternodeVote() method
|
|
47
|
+
* @param proTxHash {string} pro tx hash of the masternode as hex
|
|
48
|
+
* @param voterIdentity {IdentifierWASM} voter identity identifier
|
|
49
|
+
* @param identityNonce {BigInt} identity nonce
|
|
50
|
+
*/
|
|
51
|
+
createStateTransition(voteWASM, proTxHash, voterIdentity, identityNonce) {
|
|
52
|
+
const transition = new MasternodeVoteTransitionWASM(IdentifierWASM.fromHex(proTxHash), new IdentifierWASM(voterIdentity), voteWASM, identityNonce);
|
|
53
|
+
return transition.toStateTransition();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { DataContractWASM, PlatformVersionWASM, PrivateKeyWASM } from 'pshenmic-dpp';
|
|
2
|
+
import stringToIndexValueBytes from '../../src/utils/stringToIndexValueBytes';
|
|
3
|
+
import { DashPlatformSDK } from '../../src/DashPlatformSDK';
|
|
4
|
+
import { ContestedStateResultType } from '../../src/types';
|
|
5
|
+
let sdk;
|
|
6
|
+
let contract;
|
|
7
|
+
describe('Contested Resources', () => {
|
|
8
|
+
beforeAll(() => {
|
|
9
|
+
sdk = new DashPlatformSDK({ network: 'testnet' });
|
|
10
|
+
contract = new DataContractWASM('11111111111111111111111111111111', BigInt(1), {
|
|
11
|
+
domain: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
indices: [
|
|
14
|
+
{
|
|
15
|
+
name: 'parentNameAndLabel',
|
|
16
|
+
unique: true,
|
|
17
|
+
contested: {
|
|
18
|
+
resolution: 0,
|
|
19
|
+
description: 'If the normalized label part of this index is less than 20 characters (all alphabet a-z, A-Z, 0, 1, and -) then a masternode vote contest takes place to give out the name',
|
|
20
|
+
fieldMatches: [
|
|
21
|
+
{
|
|
22
|
+
field: 'normalizedLabel',
|
|
23
|
+
regexPattern: '^[a-zA-Z01-]{3,19}$'
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
properties: [
|
|
28
|
+
{
|
|
29
|
+
normalizedParentDomainName: 'asc'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
normalizedLabel: 'asc'
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'identityId',
|
|
38
|
+
properties: [
|
|
39
|
+
{
|
|
40
|
+
'records.identity': 'asc'
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
nullSearchable: false
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
$comment: "In order to register a domain you need to create a preorder. The preorder step is needed to prevent man-in-the-middle attacks. normalizedLabel + '.' + normalizedParentDomain must not be longer than 253 chars length as defined by RFC 1035. Domain documents are immutable: modification and deletion are restricted",
|
|
47
|
+
required: [
|
|
48
|
+
'$createdAt',
|
|
49
|
+
'$updatedAt',
|
|
50
|
+
'$transferredAt',
|
|
51
|
+
'label',
|
|
52
|
+
'normalizedLabel',
|
|
53
|
+
'normalizedParentDomainName',
|
|
54
|
+
'preorderSalt',
|
|
55
|
+
'records',
|
|
56
|
+
'subdomainRules'
|
|
57
|
+
],
|
|
58
|
+
tradeMode: 1,
|
|
59
|
+
transient: [
|
|
60
|
+
'preorderSalt'
|
|
61
|
+
],
|
|
62
|
+
properties: {
|
|
63
|
+
label: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
pattern: '^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$',
|
|
66
|
+
position: 0,
|
|
67
|
+
maxLength: 63,
|
|
68
|
+
minLength: 3,
|
|
69
|
+
description: "Domain label. e.g. 'Bob'."
|
|
70
|
+
},
|
|
71
|
+
records: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
position: 5,
|
|
74
|
+
properties: {
|
|
75
|
+
identity: {
|
|
76
|
+
type: 'array',
|
|
77
|
+
maxItems: 32,
|
|
78
|
+
minItems: 32,
|
|
79
|
+
position: 1,
|
|
80
|
+
byteArray: true,
|
|
81
|
+
description: 'Identifier name record that refers to an Identity',
|
|
82
|
+
contentMediaType: 'application/x.dash.dpp.identifier'
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
minProperties: 1,
|
|
86
|
+
additionalProperties: false
|
|
87
|
+
},
|
|
88
|
+
preorderSalt: {
|
|
89
|
+
type: 'array',
|
|
90
|
+
maxItems: 32,
|
|
91
|
+
minItems: 32,
|
|
92
|
+
position: 4,
|
|
93
|
+
byteArray: true,
|
|
94
|
+
description: 'Salt used in the preorder document'
|
|
95
|
+
},
|
|
96
|
+
subdomainRules: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
position: 6,
|
|
99
|
+
required: [
|
|
100
|
+
'allowSubdomains'
|
|
101
|
+
],
|
|
102
|
+
properties: {
|
|
103
|
+
allowSubdomains: {
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
$comment: 'Only the domain owner is allowed to create subdomains for non top-level domains',
|
|
106
|
+
position: 0,
|
|
107
|
+
description: 'This option defines who can create subdomains: true - anyone; false - only the domain owner'
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
description: 'Subdomain rules allow domain owners to define rules for subdomains',
|
|
111
|
+
additionalProperties: false
|
|
112
|
+
},
|
|
113
|
+
normalizedLabel: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
pattern: '^[a-hj-km-np-z0-9][a-hj-km-np-z0-9-]{0,61}[a-hj-km-np-z0-9]$',
|
|
116
|
+
$comment: 'Must be equal to the label in lowercase. "o", "i" and "l" must be replaced with "0" and "1".',
|
|
117
|
+
position: 1,
|
|
118
|
+
maxLength: 63,
|
|
119
|
+
description: "Domain label converted to lowercase for case-insensitive uniqueness validation. \"o\", \"i\" and \"l\" replaced with \"0\" and \"1\" to mitigate homograph attack. e.g. 'b0b'"
|
|
120
|
+
},
|
|
121
|
+
parentDomainName: {
|
|
122
|
+
type: 'string',
|
|
123
|
+
pattern: '^$|^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$',
|
|
124
|
+
position: 2,
|
|
125
|
+
maxLength: 63,
|
|
126
|
+
minLength: 0,
|
|
127
|
+
description: "A full parent domain name. e.g. 'dash'."
|
|
128
|
+
},
|
|
129
|
+
normalizedParentDomainName: {
|
|
130
|
+
type: 'string',
|
|
131
|
+
pattern: '^$|^[a-hj-km-np-z0-9][a-hj-km-np-z0-9-\\.]{0,61}[a-hj-km-np-z0-9]$',
|
|
132
|
+
$comment: 'Must either be equal to an existing domain or empty to create a top level domain. "o", "i" and "l" must be replaced with "0" and "1". Only the data contract owner can create top level domains.',
|
|
133
|
+
position: 3,
|
|
134
|
+
maxLength: 63,
|
|
135
|
+
minLength: 0,
|
|
136
|
+
description: "A parent domain name in lowercase for case-insensitive uniqueness validation. \"o\", \"i\" and \"l\" replaced with \"0\" and \"1\" to mitigate homograph attack. e.g. 'dash'"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
canBeDeleted: true,
|
|
140
|
+
transferable: 1,
|
|
141
|
+
documentsMutable: false,
|
|
142
|
+
additionalProperties: false
|
|
143
|
+
},
|
|
144
|
+
preorder: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
indices: [
|
|
147
|
+
{
|
|
148
|
+
name: 'saltedHash',
|
|
149
|
+
unique: true,
|
|
150
|
+
properties: [
|
|
151
|
+
{
|
|
152
|
+
saltedDomainHash: 'asc'
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
$comment: 'Preorder documents are immutable: modification and deletion are restricted',
|
|
158
|
+
required: [
|
|
159
|
+
'saltedDomainHash'
|
|
160
|
+
],
|
|
161
|
+
properties: {
|
|
162
|
+
saltedDomainHash: {
|
|
163
|
+
type: 'array',
|
|
164
|
+
maxItems: 32,
|
|
165
|
+
minItems: 32,
|
|
166
|
+
position: 0,
|
|
167
|
+
byteArray: true,
|
|
168
|
+
description: 'Double sha-256 of the concatenation of a 32 byte random salt and a normalized domain name'
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
canBeDeleted: true,
|
|
172
|
+
documentsMutable: false,
|
|
173
|
+
additionalProperties: false
|
|
174
|
+
}
|
|
175
|
+
}, undefined, undefined, true, PlatformVersionWASM.PLATFORM_V9);
|
|
176
|
+
contract.id = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
177
|
+
});
|
|
178
|
+
test('should be able to get contested resource vote state with finishedVoteInfo', async () => {
|
|
179
|
+
const voteState = await sdk.contestedResources.getContestedResourceVoteState(contract, 'domain', 'parentNameAndLabel', [
|
|
180
|
+
'dash',
|
|
181
|
+
'asdmaye1ght'
|
|
182
|
+
].map(stringToIndexValueBytes), ContestedStateResultType.DOCUMENTS_AND_VOTE_TALLY, true);
|
|
183
|
+
expect(voteState.finishedVoteInfo).toBeTruthy();
|
|
184
|
+
expect(voteState.contenders).toBeTruthy();
|
|
185
|
+
expect(voteState.contenders.length).toBeGreaterThan(0);
|
|
186
|
+
expect(voteState.abstainVoteTally).toBeDefined();
|
|
187
|
+
expect(voteState.lockVoteTally).toBeDefined();
|
|
188
|
+
});
|
|
189
|
+
test('should be able to get contested resource vote state for incorrect values', async () => {
|
|
190
|
+
try {
|
|
191
|
+
await sdk.contestedResources.getContestedResourceVoteState(contract, 'domain', 'parentNameAndLabel', [
|
|
192
|
+
'dash',
|
|
193
|
+
'agreatma1n'
|
|
194
|
+
].map(stringToIndexValueBytes), ContestedStateResultType.DOCUMENTS_AND_VOTE_TALLY, false);
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
expect(true).toBeTruthy();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
expect(false).toBeTruthy();
|
|
201
|
+
});
|
|
202
|
+
test('should be able to create TowardsIdentity vote', async () => {
|
|
203
|
+
const dataContactId = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
204
|
+
const documentTypeName = 'domain';
|
|
205
|
+
const indexName = 'parentNameAndLabel';
|
|
206
|
+
const indexValues = ['dash', sdk.names.normalizeLabel('testidentity')];
|
|
207
|
+
const proTxHash = 'd9b090cfc19caf2e27d512e69c43812a274bdf29c081d0ade4fd272ad56a5f89';
|
|
208
|
+
const choice = 'CKKYnVeKoxCbvuEhiT6MDoQaRyXgDECwtxoKL5cqucZE';
|
|
209
|
+
const privateKey = PrivateKeyWASM.fromWIF('cPGCETHtoevguQoyTSdsowCEF91yqhrcikcvBNK2CuTwpSLV7m9Z');
|
|
210
|
+
const voterIdentifier = await sdk.voting.createVoterIdentityId(proTxHash, privateKey.getPublicKeyHash());
|
|
211
|
+
expect(voterIdentifier.base58()).toEqual('HqfLeB9PLg3t9CL25tRNkEDPjAnDaHAMmthRNe8ucn8q');
|
|
212
|
+
const voterIdentity = await sdk.identities.getIdentityByIdentifier(voterIdentifier);
|
|
213
|
+
const [identityPublicKey] = voterIdentity.getPublicKeys().filter(identityPublicKey => privateKey.getPublicKeyHash() === identityPublicKey.getPublicKeyHash());
|
|
214
|
+
const identityNonce = await sdk.identities.getIdentityNonce(voterIdentity.id);
|
|
215
|
+
const vote = sdk.voting.createVote(dataContactId, documentTypeName, indexName, indexValues, choice);
|
|
216
|
+
const stateTransition = sdk.voting.createStateTransition(vote, proTxHash, voterIdentity.id, identityNonce + BigInt(1));
|
|
217
|
+
// test key disabled
|
|
218
|
+
identityPublicKey.removeDisabledAt();
|
|
219
|
+
stateTransition.sign(privateKey, identityPublicKey);
|
|
220
|
+
});
|
|
221
|
+
test('should be able to create Abstain vote', async () => {
|
|
222
|
+
const dataContactId = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
223
|
+
const documentTypeName = 'domain';
|
|
224
|
+
const indexName = 'parentNameAndLabel';
|
|
225
|
+
const indexValues = ['dash', sdk.names.normalizeLabel('testidentity')];
|
|
226
|
+
const proTxHash = 'd9b090cfc19caf2e27d512e69c43812a274bdf29c081d0ade4fd272ad56a5f89';
|
|
227
|
+
const choice = 'abstain';
|
|
228
|
+
const privateKey = PrivateKeyWASM.fromWIF('cPGCETHtoevguQoyTSdsowCEF91yqhrcikcvBNK2CuTwpSLV7m9Z');
|
|
229
|
+
const voterIdentifier = await sdk.voting.createVoterIdentityId(proTxHash, privateKey.getPublicKeyHash());
|
|
230
|
+
expect(voterIdentifier.base58()).toEqual('HqfLeB9PLg3t9CL25tRNkEDPjAnDaHAMmthRNe8ucn8q');
|
|
231
|
+
const voterIdentity = await sdk.identities.getIdentityByIdentifier(voterIdentifier);
|
|
232
|
+
const [identityPublicKey] = voterIdentity.getPublicKeys().filter(identityPublicKey => privateKey.getPublicKeyHash() === identityPublicKey.getPublicKeyHash());
|
|
233
|
+
const identityNonce = await sdk.identities.getIdentityNonce(voterIdentity.id);
|
|
234
|
+
const vote = sdk.voting.createVote(dataContactId, documentTypeName, indexName, indexValues, choice);
|
|
235
|
+
const stateTransition = sdk.voting.createStateTransition(vote, proTxHash, voterIdentity.id, identityNonce + BigInt(1));
|
|
236
|
+
// test key disabled
|
|
237
|
+
identityPublicKey.removeDisabledAt();
|
|
238
|
+
stateTransition.sign(privateKey, identityPublicKey);
|
|
239
|
+
});
|
|
240
|
+
test('should be able to create Lock vote', async () => {
|
|
241
|
+
const dataContactId = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
242
|
+
const documentTypeName = 'domain';
|
|
243
|
+
const indexName = 'parentNameAndLabel';
|
|
244
|
+
const indexValues = ['dash', sdk.names.normalizeLabel('testidentity')];
|
|
245
|
+
const proTxHash = 'd9b090cfc19caf2e27d512e69c43812a274bdf29c081d0ade4fd272ad56a5f89';
|
|
246
|
+
const choice = 'lock';
|
|
247
|
+
const privateKey = PrivateKeyWASM.fromWIF('cPGCETHtoevguQoyTSdsowCEF91yqhrcikcvBNK2CuTwpSLV7m9Z');
|
|
248
|
+
const voterIdentifier = await sdk.voting.createVoterIdentityId(proTxHash, privateKey.getPublicKeyHash());
|
|
249
|
+
expect(voterIdentifier.base58()).toEqual('HqfLeB9PLg3t9CL25tRNkEDPjAnDaHAMmthRNe8ucn8q');
|
|
250
|
+
const voterIdentity = await sdk.identities.getIdentityByIdentifier(voterIdentifier);
|
|
251
|
+
const [identityPublicKey] = voterIdentity.getPublicKeys().filter(identityPublicKey => privateKey.getPublicKeyHash() === identityPublicKey.getPublicKeyHash());
|
|
252
|
+
const identityNonce = await sdk.identities.getIdentityNonce(voterIdentity.id);
|
|
253
|
+
const vote = sdk.voting.createVote(dataContactId, documentTypeName, indexName, indexValues, choice);
|
|
254
|
+
const stateTransition = sdk.voting.createStateTransition(vote, proTxHash, voterIdentity.id, identityNonce + BigInt(1));
|
|
255
|
+
// test key disabled
|
|
256
|
+
identityPublicKey.removeDisabledAt();
|
|
257
|
+
stateTransition.sign(privateKey, identityPublicKey);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { DataContractWASM, StateTransitionWASM } from 'pshenmic-dpp';
|
|
2
|
+
import { DashPlatformSDK } from '../../src/types';
|
|
3
|
+
let sdk;
|
|
4
|
+
let ownerIdentifier;
|
|
5
|
+
let identityNonce;
|
|
6
|
+
let config;
|
|
7
|
+
let schema;
|
|
8
|
+
describe('DataContract', () => {
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
sdk = new DashPlatformSDK({ network: 'testnet' });
|
|
11
|
+
ownerIdentifier = 'GARSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
12
|
+
identityNonce = BigInt(11);
|
|
13
|
+
config = {
|
|
14
|
+
$format_version: '0',
|
|
15
|
+
canBeDeleted: true,
|
|
16
|
+
readonly: true,
|
|
17
|
+
keepsHistory: false,
|
|
18
|
+
documentsKeepHistoryContractDefault: false,
|
|
19
|
+
documentsMutableContractDefault: false,
|
|
20
|
+
documentsCanBeDeletedContractDefault: true,
|
|
21
|
+
requiresIdentityEncryptionBoundedKey: null,
|
|
22
|
+
requiresIdentityDecryptionBoundedKey: null
|
|
23
|
+
};
|
|
24
|
+
schema = {
|
|
25
|
+
note: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
author: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
position: 1
|
|
31
|
+
},
|
|
32
|
+
message: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
position: 0
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
additionalProperties: false
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
test('should be able to get data contract', async () => {
|
|
42
|
+
let dataContract;
|
|
43
|
+
// System Data Contract
|
|
44
|
+
dataContract = await sdk.dataContracts.getDataContractByIdentifier('GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec');
|
|
45
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
46
|
+
// User Data Contract
|
|
47
|
+
dataContract = await sdk.dataContracts.getDataContractByIdentifier('Aukz296s36am6wKStoMbxm4YhC6kTpu3mERVrC7vHokP');
|
|
48
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
49
|
+
// User Data Contract with keep history
|
|
50
|
+
dataContract = await sdk.dataContracts.getDataContractByIdentifier('DrEhmVJz56ukHbaFt8xLVRasnNWsrx3x8dGtcu9xg6rV');
|
|
51
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
52
|
+
// Token Data Contract
|
|
53
|
+
dataContract = await sdk.dataContracts.getDataContractByIdentifier('3XtMFe9UPf75DAcLmLsX9CLTrLPNysNPMcnWCE1C39vm');
|
|
54
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
55
|
+
});
|
|
56
|
+
test('should be able to create data contract', async () => {
|
|
57
|
+
const dataContract = sdk.dataContracts.create(ownerIdentifier, identityNonce, schema);
|
|
58
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
59
|
+
});
|
|
60
|
+
test('should be able to create data contract with optional params', async () => {
|
|
61
|
+
const dataContract = sdk.dataContracts.create(ownerIdentifier, identityNonce, schema, true, undefined, config);
|
|
62
|
+
expect(dataContract).toEqual(expect.any(DataContractWASM));
|
|
63
|
+
expect(dataContract.getConfig()).toEqual(config);
|
|
64
|
+
});
|
|
65
|
+
test('should be able to create data contract create transition', async () => {
|
|
66
|
+
const dataContract = sdk.dataContracts.create(ownerIdentifier, identityNonce, schema);
|
|
67
|
+
const transition = sdk.dataContracts.createStateTransition(dataContract, 'create', identityNonce);
|
|
68
|
+
expect(transition).toEqual(expect.any(StateTransitionWASM));
|
|
69
|
+
});
|
|
70
|
+
test('should be able to create data contract update transition', async () => {
|
|
71
|
+
const dataContract = sdk.dataContracts.create(ownerIdentifier, identityNonce, schema);
|
|
72
|
+
const transition = sdk.dataContracts.createStateTransition(dataContract, 'update', identityNonce);
|
|
73
|
+
expect(transition).toEqual(expect.any(StateTransitionWASM));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { DocumentWASM, GasFeesPaidByWASM, StateTransitionWASM } from 'pshenmic-dpp';
|
|
2
|
+
import { DashPlatformSDK } from '../../src/DashPlatformSDK';
|
|
3
|
+
let sdk;
|
|
4
|
+
let dataContract;
|
|
5
|
+
let identity;
|
|
6
|
+
let documentType;
|
|
7
|
+
let revision;
|
|
8
|
+
let data;
|
|
9
|
+
describe('Document', () => {
|
|
10
|
+
beforeAll(() => {
|
|
11
|
+
sdk = new DashPlatformSDK({ network: 'testnet' });
|
|
12
|
+
dataContract = '6QMfQTdKpC3Y9uWBcTwXeY3KdzRLDqASUsDnQ4MEc9XC';
|
|
13
|
+
identity = 'QMfCRPcjXoTnZa9sA9JR2KWgGxZXMRJ4akgS3Uia1Qv';
|
|
14
|
+
revision = BigInt(1);
|
|
15
|
+
documentType = 'pool';
|
|
16
|
+
data = {
|
|
17
|
+
name: 'MyPool',
|
|
18
|
+
type: 'EVONODE',
|
|
19
|
+
status: 'INACTIVE',
|
|
20
|
+
description: 'test pool'
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
test('should be able to create document', async () => {
|
|
24
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision);
|
|
25
|
+
expect(document).toEqual(expect.any(DocumentWASM));
|
|
26
|
+
});
|
|
27
|
+
test('should be able to get documents', async () => {
|
|
28
|
+
const dataContract = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
|
|
29
|
+
const documentType = 'domain';
|
|
30
|
+
const [document] = await sdk.documents.query(dataContract, documentType);
|
|
31
|
+
expect(document.createdAtBlockHeight).toEqual(undefined);
|
|
32
|
+
expect(document.dataContractId.base58()).toEqual(dataContract);
|
|
33
|
+
expect(document).toEqual(expect.any(DocumentWASM));
|
|
34
|
+
});
|
|
35
|
+
test('should be able to get document', async () => {
|
|
36
|
+
const dataContract = '6hVQW16jyvZyGSQk2YVty4ND6bgFXozizYWnPt753uW5';
|
|
37
|
+
const documentType = 'torrent';
|
|
38
|
+
const limit = 100;
|
|
39
|
+
// @ts-expect-error
|
|
40
|
+
const [document] = await sdk.documents.query(dataContract, documentType, null, null, limit);
|
|
41
|
+
expect(document.createdAtBlockHeight).toEqual(undefined);
|
|
42
|
+
expect(document.dataContractId.base58()).toEqual(dataContract);
|
|
43
|
+
expect(document).toEqual(expect.any(DocumentWASM));
|
|
44
|
+
});
|
|
45
|
+
describe('should be able to create state transition', () => {
|
|
46
|
+
test('should be able to create a create transition', async () => {
|
|
47
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity);
|
|
48
|
+
const identityContractNonce = BigInt(1);
|
|
49
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'create', { identityContractNonce });
|
|
50
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
51
|
+
});
|
|
52
|
+
test('should be able to create a contested document transition', async () => {
|
|
53
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity);
|
|
54
|
+
const identityContractNonce = BigInt(1);
|
|
55
|
+
// 0.2 Dash typically
|
|
56
|
+
const contestedFee = BigInt(20000000000);
|
|
57
|
+
const indexName = 'parentNameAndLabel';
|
|
58
|
+
const prefundedVotingBalance = { indexName, amount: contestedFee };
|
|
59
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'create', { identityContractNonce, prefundedVotingBalance });
|
|
60
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
61
|
+
});
|
|
62
|
+
test('should be able to create a document with token payment info', async () => {
|
|
63
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity);
|
|
64
|
+
const identityContractNonce = BigInt(1);
|
|
65
|
+
const tokenPaymentInfo = {
|
|
66
|
+
tokenContractId: '6hVQW16jyvZyGSQk2YVty4ND6bgFXozizYWnPt753uW5',
|
|
67
|
+
tokenContractPosition: 0,
|
|
68
|
+
minimumTokenCost: BigInt(1000),
|
|
69
|
+
maximumTokenCost: BigInt(100000),
|
|
70
|
+
gasFeesPaidBy: GasFeesPaidByWASM.ContractOwner
|
|
71
|
+
};
|
|
72
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'create', { identityContractNonce, tokenPaymentInfo });
|
|
73
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
74
|
+
});
|
|
75
|
+
test('should be able to create a replace transition', async () => {
|
|
76
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision + BigInt(1));
|
|
77
|
+
const identityContractNonce = BigInt(1);
|
|
78
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'replace', { identityContractNonce });
|
|
79
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
80
|
+
});
|
|
81
|
+
test('should be able to create a delete transition', async () => {
|
|
82
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision + BigInt(1));
|
|
83
|
+
const identityContractNonce = BigInt(1);
|
|
84
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'delete', { identityContractNonce });
|
|
85
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
86
|
+
});
|
|
87
|
+
test('should be able to create a transfer transition', async () => {
|
|
88
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision + BigInt(1));
|
|
89
|
+
const identityContractNonce = BigInt(1);
|
|
90
|
+
const recipientId = '6hVQW16jyvZyGSQk2YVty4ND6bgFXozizYWnPt753uW5';
|
|
91
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'transfer', { identityContractNonce, recipientId });
|
|
92
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
93
|
+
});
|
|
94
|
+
test('should be able to create an updatePrice transition', async () => {
|
|
95
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision + BigInt(1));
|
|
96
|
+
const identityContractNonce = BigInt(1);
|
|
97
|
+
const price = BigInt(10000000);
|
|
98
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'updatePrice', { identityContractNonce, price });
|
|
99
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
100
|
+
});
|
|
101
|
+
test('should be able to create a purchase transition', async () => {
|
|
102
|
+
const document = sdk.documents.create(dataContract, documentType, data, identity, revision + BigInt(1));
|
|
103
|
+
const identityContractNonce = BigInt(1);
|
|
104
|
+
const amount = BigInt(10000000);
|
|
105
|
+
const stateTransition = sdk.documents.createStateTransition(document, 'purchase', { identityContractNonce, amount });
|
|
106
|
+
expect(stateTransition).toEqual(expect.any(StateTransitionWASM));
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
});
|