Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions packages/wasm-sdk/AI_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -763,31 +763,33 @@ Parameters:
- `assetLockProofPrivateKey` (string, required) - Asset Lock Proof Private Key
- WIF format private key
- `publicKeys` (string, required) - Public Keys
- JSON array of public keys
- JSON array of public keys. Key requirements: ECDSA_SECP256K1 requires privateKeyHex or privateKeyWif for signing, BLS12_381 requires privateKeyHex for signing, ECDSA_HASH160 requires either the data field (base64-encoded 20-byte public key hash) or privateKeyHex (produces empty signatures).

Example:
```javascript
// Asset lock proof is a hex-encoded JSON object
const assetLockProof = "a9147d3b... (hex-encoded)";
const assetLockProofPrivateKey = "XFfpaSbZq52HPy3WWwe1dXsZMiU1bQn8vQd34HNXkSZThevBWRn1"; // WIF format

// Public keys array with proper key types
// Public keys array with proper key types and private keys for signing/hashing
const publicKeys = JSON.stringify([
{
id: 0,
type: 0, // ECDSA_SECP256K1 = 0, BLS12_381 = 1, ECDSA_HASH160 = 2
purpose: 0, // AUTHENTICATION = 0, ENCRYPTION = 1, DECRYPTION = 2, TRANSFER = 3, etc.
securityLevel: 0, // MASTER = 0, CRITICAL = 1, HIGH = 2, MEDIUM = 3
keyType: "ECDSA_SECP256K1",
purpose: "AUTHENTICATION",
securityLevel: "MASTER",
data: "A5GzYHPIolbHkFrp5l+s9IvF2lWMuuuSu3oWZB8vWHNJ", // Base64-encoded public key
readOnly: false
readOnly: false,
privateKeyWif: "XBrZJKcW4ajWVNAU6yP87WQog6CjFnpbqyAKgNTZRqmhYvPgMNV2"
},
{
id: 1,
type: 0,
purpose: 0,
securityLevel: 2,
data: "AnotherBase64EncodedPublicKeyHere", // Base64-encoded public key
readOnly: false
keyType: "ECDSA_HASH160",
purpose: "AUTHENTICATION",
securityLevel: "HIGH",
data: "ripemd160hash20bytes1234", // Base64-encoded 20-byte RIPEMD160 hash
readOnly: false,
// ECDSA_HASH160 keys produce empty signatures (not required/used for signing)
}
]);

Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ token_reward_explanations = ["dash-sdk/token_reward_explanations"]

[dependencies]
dash-sdk = { path = "../rs-sdk", default-features = false }
simple-signer = { path = "../simple-signer" }
simple-signer = { path = "../simple-signer", features = ["state-transitions"] }
drive = { path = "../rs-drive", default-features = false, features = ["verify"] }
console_error_panic_hook = { version = "0.1.6" }
thiserror = { version = "2.0.12" }
Expand Down
22 changes: 20 additions & 2 deletions packages/wasm-sdk/api-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,24 @@
],
"help": "Default adds standard keys for most Platform operations. Advanced allows custom key configuration."
},
{
"name": "keyType",
"type": "select",
"label": "Key Type",
"required": true,
"value": "ECDSA_HASH160",
"options": [
{
"value": "ECDSA_HASH160",
"label": "ECDSA_HASH160 (Dash Evo Tool default)"
},
{
"value": "ECDSA_SECP256K1",
"label": "ECDSA_SECP256K1 (Dash mobile wallet default)"
}
],
"help": "Choose key type"
},
{
"name": "keyPreview",
"type": "keyPreview",
Expand Down Expand Up @@ -1261,10 +1279,10 @@
"type": "string",
"label": "Public Keys",
"required": true,
"description": "JSON array of public keys"
"description": "JSON array of public keys. Key requirements: ECDSA_SECP256K1 requires privateKeyHex or privateKeyWif for signing, BLS12_381 requires privateKeyHex for signing, ECDSA_HASH160 requires either the data field (base64-encoded 20-byte public key hash) or privateKeyHex (produces empty signatures)."
}
],
"sdk_example": "// Asset lock proof is a hex-encoded JSON object\nconst assetLockProof = \"a9147d3b... (hex-encoded)\";\nconst assetLockProofPrivateKey = \"XFfpaSbZq52HPy3WWwe1dXsZMiU1bQn8vQd34HNXkSZThevBWRn1\"; // WIF format\n\n// Public keys array with proper key types\nconst publicKeys = JSON.stringify([\n {\n id: 0,\n type: 0, // ECDSA_SECP256K1 = 0, BLS12_381 = 1, ECDSA_HASH160 = 2\n purpose: 0, // AUTHENTICATION = 0, ENCRYPTION = 1, DECRYPTION = 2, TRANSFER = 3, etc.\n securityLevel: 0, // MASTER = 0, CRITICAL = 1, HIGH = 2, MEDIUM = 3\n data: \"A5GzYHPIolbHkFrp5l+s9IvF2lWMuuuSu3oWZB8vWHNJ\", // Base64-encoded public key\n readOnly: false\n },\n {\n id: 1,\n type: 0,\n purpose: 0,\n securityLevel: 2,\n data: \"AnotherBase64EncodedPublicKeyHere\", // Base64-encoded public key\n readOnly: false\n }\n]);\n\nconst result = await sdk.identityCreate(assetLockProof, assetLockProofPrivateKey, publicKeys);"
"sdk_example": "// Asset lock proof is a hex-encoded JSON object\nconst assetLockProof = \"a9147d3b... (hex-encoded)\";\nconst assetLockProofPrivateKey = \"XFfpaSbZq52HPy3WWwe1dXsZMiU1bQn8vQd34HNXkSZThevBWRn1\"; // WIF format\n\n// Public keys array with proper key types and private keys for signing/hashing\nconst publicKeys = JSON.stringify([\n {\n id: 0,\n keyType: \"ECDSA_SECP256K1\",\n purpose: \"AUTHENTICATION\",\n securityLevel: \"MASTER\",\n data: \"A5GzYHPIolbHkFrp5l+s9IvF2lWMuuuSu3oWZB8vWHNJ\", // Base64-encoded public key\n readOnly: false,\n privateKeyWif: \"XBrZJKcW4ajWVNAU6yP87WQog6CjFnpbqyAKgNTZRqmhYvPgMNV2\"\n },\n {\n id: 1,\n keyType: \"ECDSA_HASH160\",\n purpose: \"AUTHENTICATION\",\n securityLevel: \"HIGH\",\n data: \"ripemd160hash20bytes1234\", // Base64-encoded 20-byte RIPEMD160 hash\n readOnly: false,\n // ECDSA_HASH160 keys produce empty signatures (not required/used for signing)\n }\n]);\n\nconst result = await sdk.identityCreate(assetLockProof, assetLockProofPrivateKey, publicKeys);"
Comment thread
thephez marked this conversation as resolved.
},
"identityTopUp": {
"label": "Identity Top Up",
Expand Down
24 changes: 13 additions & 11 deletions packages/wasm-sdk/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,7 @@ <h5>Parameters:</h5>
<span class="param-name">Public Keys</span>
<span class="param-type">string</span>
<span class="param-required">(required)</span>
<br><small>JSON array of public keys</small>
<br><small>JSON array of public keys. Key requirements: ECDSA_SECP256K1 requires privateKeyHex or privateKeyWif for signing, BLS12_381 requires privateKeyHex for signing, ECDSA_HASH160 requires either the data field (base64-encoded 20-byte public key hash) or privateKeyHex (produces empty signatures).</small>
</div>
</div>

Expand All @@ -1977,23 +1977,25 @@ <h5>Example</h5>
const assetLockProof = "a9147d3b... (hex-encoded)";
const assetLockProofPrivateKey = "XFfpaSbZq52HPy3WWwe1dXsZMiU1bQn8vQd34HNXkSZThevBWRn1"; // WIF format

// Public keys array with proper key types
// Public keys array with proper key types and private keys for signing/hashing
const publicKeys = JSON.stringify([
{
id: 0,
type: 0, // ECDSA_SECP256K1 = 0, BLS12_381 = 1, ECDSA_HASH160 = 2
purpose: 0, // AUTHENTICATION = 0, ENCRYPTION = 1, DECRYPTION = 2, TRANSFER = 3, etc.
securityLevel: 0, // MASTER = 0, CRITICAL = 1, HIGH = 2, MEDIUM = 3
keyType: "ECDSA_SECP256K1",
purpose: "AUTHENTICATION",
securityLevel: "MASTER",
data: "A5GzYHPIolbHkFrp5l+s9IvF2lWMuuuSu3oWZB8vWHNJ", // Base64-encoded public key
readOnly: false
readOnly: false,
privateKeyWif: "XBrZJKcW4ajWVNAU6yP87WQog6CjFnpbqyAKgNTZRqmhYvPgMNV2"
},
{
id: 1,
type: 0,
purpose: 0,
securityLevel: 2,
data: "AnotherBase64EncodedPublicKeyHere", // Base64-encoded public key
readOnly: false
keyType: "ECDSA_HASH160",
purpose: "AUTHENTICATION",
securityLevel: "HIGH",
data: "ripemd160hash20bytes1234", // Base64-encoded 20-byte RIPEMD160 hash
readOnly: false,
// ECDSA_HASH160 keys produce empty signatures (not required/used for signing)
}
]);

Expand Down
22 changes: 16 additions & 6 deletions packages/wasm-sdk/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3062,6 +3062,7 @@ <h2>Results</h2>
const seedPhrase = values.seedPhrase?.trim();
const identityIndex = parseInt(values.identityIndex || '0');
const keySelectionMode = values.keySelectionMode || 'default';
const selectedKeyType = values.keyType || 'ECDSA_HASH160';

if (!seedPhrase || !validate_mnemonic(seedPhrase)) {
throw new Error('Invalid seed phrase');
Expand Down Expand Up @@ -3089,26 +3090,27 @@ <h2>Results</h2>

// Create public key objects for the SDK
// Pass private keys so the SDK can derive the correct public key data using DPP
// Use the selected key type for all keys
publicKeys = [
{
id: 0,
keyType: "ECDSA_HASH160",
keyType: selectedKeyType,
purpose: "AUTHENTICATION",
securityLevel: "MASTER",
privateKeyHex: masterKey.private_key_hex,
readOnly: false
},
{
id: 1,
keyType: "ECDSA_HASH160",
keyType: selectedKeyType,
purpose: "AUTHENTICATION",
securityLevel: "HIGH",
privateKeyHex: authKey.private_key_hex,
readOnly: false
},
{
id: 2,
keyType: "ECDSA_HASH160",
keyType: selectedKeyType,
purpose: "TRANSFER",
securityLevel: "CRITICAL",
privateKeyHex: transferKey.private_key_hex,
Expand Down Expand Up @@ -4293,6 +4295,7 @@ <h2>Results</h2>
const seedPhrase = dynamicInputs.querySelector('[name="seedPhrase"]')?.value?.trim();
const identityIndex = parseInt(dynamicInputs.querySelector('[name="identityIndex"]')?.value || '0');
const keySelectionMode = dynamicInputs.querySelector('[name="keySelectionMode"]')?.value || 'default';
const selectedKeyType = dynamicInputs.querySelector('[name="keyType"]')?.value || 'ECDSA_HASH160';
const previewContainer = document.getElementById('keyPreviewContainer');

if (!seedPhrase || !previewContainer) return;
Expand Down Expand Up @@ -4320,21 +4323,26 @@ <h2>Results</h2>
const transferKeyPath = `m/9'/${currentNetwork === 'mainnet' ? 5 : 1}'/5'/0'/0'/${identityIndex}'/2'`;
const transferKey = derive_key_from_seed_with_path(seedPhrase, undefined, transferKeyPath, currentNetwork);

// Show signature requirement info
const signatureInfo = selectedKeyType === 'ECDSA_SECP256K1'
? ' (Individual signatures required)'
: ' (No individual signatures required)';

Comment thread
thephez marked this conversation as resolved.
keysHtml += `
<div style="margin-bottom: 10px;">
<strong>Master Key:</strong><br>
<span style="font-family: monospace; font-size: 0.9em;">${masterKey.private_key_wif}</span><br>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Authentication | Security: Master | Type: ECDSA_HASH160</span>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Authentication | Security: Master | Type: ${selectedKeyType}${signatureInfo}</span>
</div>
<div style="margin-bottom: 10px;">
<strong>Key 1:</strong><br>
<span style="font-family: monospace; font-size: 0.9em;">${authKey.private_key_wif}</span><br>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Authentication | Security: High | Type: ECDSA_HASH160</span>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Authentication | Security: High | Type: ${selectedKeyType}${signatureInfo}</span>
</div>
<div style="margin-bottom: 10px;">
<strong>Key 2:</strong><br>
<span style="font-family: monospace; font-size: 0.9em;">${transferKey.private_key_wif}</span><br>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Transfer | Security: Critical | Type: ECDSA_HASH160</span>
<span style="color: #6c757d; font-size: 0.85em;">Purpose: Transfer | Security: Critical | Type: ${selectedKeyType}${signatureInfo}</span>
</div>
`;

Expand All @@ -4353,10 +4361,12 @@ <h2>Results</h2>
const seedInput = dynamicInputs.querySelector('[name="seedPhrase"]');
const indexInput = dynamicInputs.querySelector('[name="identityIndex"]');
const modeSelect = dynamicInputs.querySelector('[name="keySelectionMode"]');
const keyTypeSelect = dynamicInputs.querySelector('[name="keyType"]');

if (seedInput) seedInput.addEventListener('input', updateKeyPreview);
if (indexInput) indexInput.addEventListener('input', updateKeyPreview);
if (modeSelect) modeSelect.addEventListener('change', updateKeyPreview);
if (keyTypeSelect) keyTypeSelect.addEventListener('change', updateKeyPreview);

// Initial update
updateKeyPreview();
Expand Down
Loading
Loading