From 55033c0d1cd8823e2703dcbeaf714491034d11bc Mon Sep 17 00:00:00 2001 From: PastaClaw Date: Thu, 2 Apr 2026 09:23:03 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20car-sales=20tutorial=20=E2=80=94=20match?= =?UTF-8?q?=20actual=20evo-sdk@3.1.0-dev.1=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - contracts.publish(): construct DataContract + IdentitySigner, not simplified fields - documents.create(): construct Document object with proper properties - documents.query(): dataContractId/documentTypeName instead of contractId/documentType - documents.replace(): fetch existing doc, modify, increment revision - doc.properties instead of doc.getData() - contract.id instead of contract.getId() - Identity properties (.publicKeys) instead of methods (.getPublicKeys()) TypeScript compiles clean against @dashevo/evo-sdk@3.1.0-dev.1. Resolves #3 --- tutorials/car-sales.ts | 146 +++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 55 deletions(-) diff --git a/tutorials/car-sales.ts b/tutorials/car-sales.ts index a353559..61a3bce 100644 --- a/tutorials/car-sales.ts +++ b/tutorials/car-sales.ts @@ -1,16 +1,20 @@ /** * Tutorial: Car Sales Management * - * Original code from: https://dashpay.github.io/platform/evo-sdk/tutorials/car-sales.html - * NOTE: This code does NOT compile against @dashevo/evo-sdk@3.1.0-dev.1 + * Corrected to match the actual @dashevo/evo-sdk@3.1.0-dev.1 API. + * Original: https://dashpay.github.io/platform/evo-sdk/tutorials/car-sales.html */ -// @ts-nocheck — original tutorial code, kept verbatim for diffing - -import { EvoSDK, wallet } from '@dashevo/evo-sdk'; +import { + EvoSDK, + DataContract, + Document, + Identifier, + IdentitySigner, +} from '@dashevo/evo-sdk'; // ────────────────────────────────────────────── -// Step 1: Design the data contract +// Step 1: Design the data contract (unchanged) // ────────────────────────────────────────────── const carSalesSchema = { @@ -54,28 +58,46 @@ const identityId = 'YOUR_IDENTITY_ID'; const privateKeyWif = 'YOUR_PRIVATE_KEY_WIF'; const signingKeyIndex = 0; +// Fetch identity to get the signing key +const identity = await sdk.identities.fetch(identityId); +if (!identity) throw new Error('Identity not found'); + +const identityKey = identity.publicKeys[signingKeyIndex]; + +// Create a signer with your private key +const signer = new IdentitySigner(); +signer.addKeyFromWif(privateKeyWif); + +// Get the identity nonce for contract ID generation +const identityNonce = await sdk.identities.nonce(identityId); +if (identityNonce === undefined) throw new Error('Could not fetch nonce'); + +// Construct the DataContract object +const dataContract = new DataContract({ + ownerId: identityId, + identityNonce, + schemas: carSalesSchema, +}); + // Publish the data contract const contract = await sdk.contracts.publish({ - identityId, - documentSchemas: carSalesSchema, - privateKeyWif, - signingKeyIndex, - nonce: await sdk.identities.nonce(identityId), + dataContract, + identityKey, + signer, }); -const contractId = contract.getId().toString(); +const contractId = contract.id.toString(); console.log('Contract published:', contractId); // ────────────────────────────────────────────── // Step 3: Create a listing // ────────────────────────────────────────────── -const nonce = await sdk.identities.contractNonce(identityId, contractId); - -await sdk.documents.create({ - contractId, - documentType: 'listing', - document: { +const listingDoc = new Document({ + documentTypeName: 'listing', + dataContractId: contractId, + ownerId: identityId, + properties: { make: 'Toyota', model: 'Camry', year: 2021, @@ -84,10 +106,12 @@ await sdk.documents.create({ description: 'Well-maintained, single owner, full service history.', status: 'available', }, - identityId, - privateKeyWif, - signingKeyIndex, - nonce, +}); + +await sdk.documents.create({ + document: listingDoc, + identityKey, + signer, }); console.log('Listing created!'); @@ -98,8 +122,8 @@ console.log('Listing created!'); // Fetch all available listings const results = await sdk.documents.query({ - contractId, - documentType: 'listing', + dataContractId: contractId, + documentTypeName: 'listing', where: [['status', '==', 'available']], orderBy: [['priceUsd', 'asc']], limit: 20, @@ -107,15 +131,15 @@ const results = await sdk.documents.query({ for (const [id, doc] of results) { if (!doc) continue; - const data = doc.getData(); + const data = doc.properties as Record; console.log(`${data.year} ${data.make} ${data.model} — $${data.priceUsd}`); console.log(` ID: ${id}`); } // Search by make const toyotas = await sdk.documents.query({ - contractId, - documentType: 'listing', + dataContractId: contractId, + documentTypeName: 'listing', where: [ ['make', '==', 'Toyota'], ['status', '==', 'available'], @@ -124,28 +148,28 @@ const toyotas = await sdk.documents.query({ }); // ────────────────────────────────────────────── -// Step 5: Update a listing +// Step 5: Update a listing (mark as sold) // ────────────────────────────────────────────── const listingId = 'THE_LISTING_DOCUMENT_ID'; +// Fetch the existing document first +const existingDoc = await sdk.documents.get(contractId, 'listing', listingId); +if (!existingDoc) throw new Error('Listing not found'); + +// Update the properties +existingDoc.properties = { + ...existingDoc.properties, + status: 'sold', +}; + +// Increment the revision +existingDoc.revision = (existingDoc.revision ?? 0n) + 1n; + await sdk.documents.replace({ - contractId, - documentType: 'listing', - documentId: listingId, - document: { - make: 'Toyota', - model: 'Camry', - year: 2021, - mileageKm: 45000, - priceUsd: 22500, - description: 'Well-maintained, single owner, full service history.', - status: 'sold', - }, - identityId, - privateKeyWif, - signingKeyIndex, - nonce: await sdk.identities.contractNonce(identityId, contractId), + document: existingDoc, + identityKey, + signer, }); console.log('Listing marked as sold'); @@ -154,28 +178,39 @@ console.log('Listing marked as sold'); // Step 6: Leave a review // ────────────────────────────────────────────── +// Buyer's credentials const buyerIdentityId = 'BUYER_IDENTITY_ID'; const buyerKeyWif = 'BUYER_PRIVATE_KEY_WIF'; -await sdk.documents.create({ - contractId, - documentType: 'review', - document: { +const buyerIdentity = await sdk.identities.fetch(buyerIdentityId); +if (!buyerIdentity) throw new Error('Buyer identity not found'); + +const buyerKey = buyerIdentity.publicKeys[0]; +const buyerSigner = new IdentitySigner(); +buyerSigner.addKeyFromWif(buyerKeyWif); + +const reviewDoc = new Document({ + documentTypeName: 'review', + dataContractId: contractId, + ownerId: buyerIdentityId, + properties: { sellerId: 'SELLER_IDENTITY_ID', listingId: 'THE_LISTING_DOCUMENT_ID', rating: 5, comment: 'Great seller, car was exactly as described!', }, - identityId: buyerIdentityId, - privateKeyWif: buyerKeyWif, - signingKeyIndex: 0, - nonce: await sdk.identities.contractNonce(buyerIdentityId, contractId), +}); + +await sdk.documents.create({ + document: reviewDoc, + identityKey: buyerKey, + signer: buyerSigner, }); // Query reviews for a seller const reviews = await sdk.documents.query({ - contractId, - documentType: 'review', + dataContractId: contractId, + documentTypeName: 'review', where: [['sellerId', '==', 'SELLER_IDENTITY_ID']], orderBy: [['rating', 'desc']], limit: 50, @@ -185,7 +220,8 @@ let totalRating = 0; let count = 0; for (const [, doc] of reviews) { if (!doc) continue; - totalRating += doc.getData().rating; + const data = doc.properties as Record; + totalRating += data.rating as number; count++; } console.log(`Average rating: ${(totalRating / count).toFixed(1)} (${count} reviews)`);