Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
61c749d
fix: update state transition docs examples to v4 option shapes
thepastaclaw Jul 20, 2026
15403cd
docs: regenerate AI_REFERENCE with v4 state transition examples
thepastaclaw Jul 20, 2026
3f07171
test: guard generated docs against pre-v4 transition call shapes
thepastaclaw Jul 20, 2026
5da6ab7
refactor: drop obsolete identity create/top-up param name overrides
thepastaclaw Jul 20, 2026
7d1cdf3
refactor: share v4 transition example signer/key helpers
thepastaclaw Jul 20, 2026
edeb92f
fix: use concrete CoreScript/PoolingWasm in withdraw example
thepastaclaw Jul 20, 2026
fa1e6e7
fix: align Platform Address sdk_params with v4 option types
thepastaclaw Jul 20, 2026
c09ef02
test: guard Platform Address required options and metadata
thepastaclaw Jul 20, 2026
f279c3f
docs: regenerate AI_REFERENCE for Platform Address v4 metadata
thepastaclaw Jul 20, 2026
26f2952
test: cache declaration property extraction in transition examples
thepastaclaw Jul 20, 2026
2f75884
fix: make identity creation example functional
thepastaclaw Jul 20, 2026
5f8447d
fix: use token contract in transition examples
thepastaclaw Jul 20, 2026
3d20427
fix: require withdrawal destination hash
thepastaclaw Jul 20, 2026
22e046b
docs: refresh documentation check report
thepastaclaw Jul 20, 2026
78cf826
fix: require PlatformAddressInput/Output arrays in address metadata
thepastaclaw Jul 20, 2026
c108c44
fix: format multiline AI query examples as const result
thepastaclaw Jul 20, 2026
8f46940
test: guard Platform Address arrays and AI query formatting
thepastaclaw Jul 20, 2026
959b8df
fix: avoid timestamp-only documentation check report churn
thepastaclaw Jul 20, 2026
83211bd
fix: auto-select TRANSFER/OWNER keys for credit examples
thepastaclaw Jul 20, 2026
3b30b2b
test: guard credit transfer key purpose semantics
thepastaclaw Jul 20, 2026
279b81c
Merge master into fix-v4-transition-examples
thepastaclaw Jul 23, 2026
fe02d5e
chore: merge origin/master into transition examples
thepastaclaw Jul 31, 2026
6f4050c
fix: enforce transition signing key purposes
thepastaclaw Jul 31, 2026
baf93a6
docs: regenerate transition key examples
thepastaclaw Jul 31, 2026
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
86 changes: 83 additions & 3 deletions public/AI_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2248,7 +2248,34 @@ Returns:

Example:
```javascript
const result = await sdk.dpns.registerName({ label, identity, identityKey, signer, preorderCallback });
import { IdentitySigner } from '@dashevo/evo-sdk';

const identityId = '5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk';
const identity = await sdk.identities.fetch(identityId);

const signer = new IdentitySigner();
signer.addKeyFromWif('L1ExamplePrivateKeyWifGoesHere');

// DPNS registration requires a strong authentication key.
const identityKey = identity.publicKeys.find(
k => k.purpose === 'AUTHENTICATION'
&& ['CRITICAL', 'HIGH'].includes(k.securityLevel),
);
if (!identityKey) {
throw new Error(
'DPNS registration requires an AUTHENTICATION key with CRITICAL or HIGH security level',
);
}

const result = await sdk.dpns.registerName({
label: 'alice',
identity,
identityKey,
signer,
preorderCallback: (preorderDocument) => {
console.log('preorder submitted', preorderDocument.id?.toString?.());
},
});
```

#### Token Transitions
Expand Down Expand Up @@ -2926,7 +2953,34 @@ Returns:

Example:
```javascript
const result = await sdk.voting.masternodeVote({ masternodeProTxHash, votePoll, voteChoice, votingKey, signer });
import { IdentitySigner, ResourceVoteChoice, VotePoll } from '@dashevo/evo-sdk';

const masternodeProTxHash = '143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113';

const signer = new IdentitySigner();
signer.addKeyFromWif('L1ExampleVotingKeyWifGoesHere');

// Voting key must match the masternode voting public key on the identity.
const votingIdentity = await sdk.identities.fetch(masternodeProTxHash);
const votingKey = votingIdentity.publicKeys.find(k => k.purpose === 'VOTING');
if (!votingKey) {
throw new Error('Masternode voting requires a VOTING-purpose identity key');
}

const votePoll = new VotePoll({
contractId: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
documentTypeName: 'domain',
indexName: 'parentNameAndLabel',
indexValues: ['dash', 'alice'],
});

await sdk.voting.masternodeVote({
masternodeProTxHash,
votePoll,
voteChoice: ResourceVoteChoice.TowardsIdentity('5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk'),
votingKey,
signer,
});
```

**Contested Resource** - `voting.masternodeVote`
Expand Down Expand Up @@ -2969,7 +3023,33 @@ Returns:

Example:
```javascript
const result = await sdk.voting.masternodeVote({ masternodeProTxHash, votePoll, voteChoice, votingKey, signer });
import { IdentitySigner, ResourceVoteChoice, VotePoll } from '@dashevo/evo-sdk';

const masternodeProTxHash = '143dcd6a6b7684fde01e88a10e5d65de9a29244c5ecd586d14a342657025f113';

const signer = new IdentitySigner();
signer.addKeyFromWif('L1ExampleVotingKeyWifGoesHere');

const votingIdentity = await sdk.identities.fetch(masternodeProTxHash);
const votingKey = votingIdentity.publicKeys.find(k => k.purpose === 'VOTING');
if (!votingKey) {
throw new Error('Masternode voting requires a VOTING-purpose identity key');
}

const votePoll = new VotePoll({
contractId: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
documentTypeName: 'domain',
indexName: 'parentNameAndLabel',
indexValues: ['dash', 'alice'],
});

await sdk.voting.masternodeVote({
masternodeProTxHash,
votePoll,
voteChoice: ResourceVoteChoice.TowardsIdentity('5DbLwAxGBzUzo81VewMUwn4b5P4bpv9FNFybi25XB5Bk'),
votingKey,
signer,
});
```

#### Platform Address Transitions
Expand Down
2 changes: 1 addition & 1 deletion public/api-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@
"type": "text",
"label": "Label",
"required": true,
"placeholder": "ąlice"
"placeholder": "\u0105lice"
}
],
"sdk_method": "dpns.convertToHomographSafe"
Expand Down
47 changes: 46 additions & 1 deletion scripts/check_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,42 @@ def main():
if missing_anchors:
errors.append(f"ERROR: Missing HTML return type anchors: {', '.join(missing_anchors)}")

# Guard against pre-v4 privateKeyWif-in-call examples (issue #63).
if not errors:
classic_patterns = [
(
r'documents\.create\(\{\s*contractId,\s*type:\s*documentType,\s*ownerId,\s*data,\s*entropyHex,\s*privateKeyWif\s*\}',
'pre-v4 documents.create(... privateKeyWif) example',
),
(
r'identities\.topUp\(\{\s*identityId,\s*assetLockProof,\s*assetLockPrivateKeyWif\s*\}',
'pre-v4 identities.topUp(... assetLockPrivateKeyWif) example',
),
(
r'identities\.create\(\{\s*assetLockProof,\s*assetLockPrivateKeyWif,\s*publicKeys\s*\}',
'pre-v4 identities.create(... assetLockPrivateKeyWif, publicKeys) example',
),
(
r'sdk\.<namespace>\.<transition>\(\{\s*\.\.\.params,\s*privateKeyWif\s*\}',
'pre-v4 state-transition pattern with privateKeyWif in call',
),
(
r'\bprivateKeyWif\s*:',
'privateKeyWif object property; use IdentitySigner.addKeyFromWif / PrivateKey.fromWIF',
),
]
for label, file_path in (('docs.html', docs_file), ('AI_REFERENCE.md', ai_file)):
if not file_path.exists():
continue
content = file_path.read_text(encoding='utf-8')
for pattern, description in classic_patterns:
if re.search(pattern, content):
errors.append(f'ERROR: {label} still contains {description}')
if 'IdentitySigner' not in content:
errors.append(f'ERROR: {label} is missing IdentitySigner usage expected for v4 write examples')

# Compose report

lines = [
'=' * 80,
'Evo SDK Documentation Check',
Expand All @@ -145,7 +180,17 @@ def main():

report = '\n'.join(lines)
print(report)
(PUBLIC_DIR / 'documentation-check-report.txt').write_text(report, encoding='utf-8')

# Avoid timestamp-only churn in git: keep the previous report when the
# status body is unchanged, rewriting only when warnings/errors change.
report_path = PUBLIC_DIR / 'documentation-check-report.txt'
previous = report_path.read_text(encoding='utf-8') if report_path.exists() else ''

def body_without_timestamp(text: str) -> str:
return re.sub(r'^Timestamp:.*$', 'Timestamp:', text, count=1, flags=re.M)

if body_without_timestamp(previous) != body_without_timestamp(report):
report_path.write_text(report, encoding='utf-8')

sys.exit(1 if errors else 0)

Expand Down
Loading