Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sdk): add NFT actions in the JS Dash SDK #2444

Open
wants to merge 51 commits into
base: v2.0-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f9a5f04
feat(wasm-dpp): add transfer transition to documents batch wip
pshenmic Oct 5, 2024
1d7159a
feat(js-dash-sk): add transfer to document broadcast
pshenmic Oct 5, 2024
1d1a505
fix(dpp): add missing import
pshenmic Oct 5, 2024
ad94fa6
feat(js-dash-sdk): add transfer function wip
pshenmic Oct 5, 2024
f3b04f2
feat(js-sdk): implement working document transfers
pshenmic Dec 24, 2024
7011e09
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
0197581
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
9abbd8f
chore(wasm-dpp): cleanup
pshenmic Dec 24, 2024
5ddc68c
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
7411a01
chore(js-sdk): revert
pshenmic Dec 24, 2024
79842cd
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
995918f
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
1c2d730
chore(js-sdk): cleanup
pshenmic Dec 24, 2024
d23c2d3
chore(js-sdk): update doc
pshenmic Dec 24, 2024
ee75036
chore(wasm-dpp): cleanup
pshenmic Dec 24, 2024
63cf68e
feat(wasm-dpp): add nft operations
pshenmic Jan 20, 2025
d14e296
feat(js-sdk): add transfer def in Platform.ts
pshenmic Jan 20, 2025
94b60a7
feat(js-dash-sdk): uncomment
pshenmic Jan 26, 2025
b4181be
feat(wasm-dpp): move nft create state transition from extended docume…
pshenmic Jan 30, 2025
f195f87
fix(js-dash-sdk): fix types
pshenmic Jan 30, 2025
a704629
fix(js-dash-sdk): finalize nft transitions
pshenmic Jan 31, 2025
03204f3
fix(wasm-dpp): lint fix
pshenmic Jan 31, 2025
5484b65
chore(wasm-dpp): remove unused
pshenmic Jan 31, 2025
e96b20a
feat(js-dash-sdk): add NFT state transitions docs
pshenmic Jan 31, 2025
7cdf3c6
fix(wasm-dpp): lint fix
pshenmic Feb 14, 2025
9471b11
fix(js-dash-sdk): doc fix
pshenmic Feb 14, 2025
5cc1922
fix(wasm-dpp): feature error
pshenmic Feb 17, 2025
db2cc9a
fix(wasm-dpp): lint fix
pshenmic Feb 17, 2025
322a3e3
feat(wasm-dpp): implement document transition params
pshenmic Feb 24, 2025
8831379
feat(wasm-dpp): fix cargo lint
pshenmic Feb 24, 2025
8438237
chore(sdk): fix audit
pshenmic Feb 24, 2025
134f86d
fix(rs-dpp): fmt lint fix
pshenmic Feb 24, 2025
e17ddda
fix(rs-dpp): clippy
pshenmic Feb 24, 2025
0e207f7
fix(rs-dpp): fmt check
pshenmic Feb 24, 2025
5704573
fix(rs-dpp): fix test
pshenmic Feb 24, 2025
50b2a39
chore(sdk): cleanup
pshenmic Feb 24, 2025
3b91adf
fix(wasm-dpp): fix unit test
pshenmic Feb 24, 2025
de035d5
fix(wasm-dpp): get back clone
pshenmic Feb 24, 2025
c225f9f
fix(rs-drive-abci): fix tests
pshenmic Feb 24, 2025
a579bd5
fix(rs-drive-abci): fix formatting
pshenmic Feb 24, 2025
4ac03e1
fix(js-dash-sdk): fix test
pshenmic Feb 24, 2025
f19a9a4
fix(js-dash-sdk): fix broadcast condition
pshenmic Feb 24, 2025
857a446
fix(platform-test-suite): fix e2e tests
pshenmic Feb 25, 2025
ae66fd2
Merge branch 'refs/heads/v2.0-dev' into feat/wasm-dpp-nft
pshenmic Feb 27, 2025
5fc6eb4
fix(wasm-dpp): merge fixes
pshenmic Feb 27, 2025
05b6f66
fix(rs-dpp): missing import
pshenmic Feb 27, 2025
fb363c9
fix(rs-dpp): fix features
pshenmic Feb 27, 2025
9a75938
fix(rs-dpp): fix features
pshenmic Feb 27, 2025
c15202b
fix(rs-dpp): lint fix
pshenmic Feb 27, 2025
d4f62e7
fix(js-dash-sdk): fix logging name
pshenmic Feb 27, 2025
51d1ee8
fix(dapi): fix unit test
pshenmic Feb 27, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ describe('fetchProofForStateTransition', () => {
const contractId = documents[0].getDataContractId();

const transition = dpp.document.createStateTransition({
create: documents,
create: documents.map((d) => ({ document: d })),
}, {
[identityId.toString()]: {
[contractId.toString()]: '1',
Expand Down
18 changes: 11 additions & 7 deletions packages/js-dash-sdk/docs/platform/documents/broadcast.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@

Parameters:

| parameters | type | required | Description |
|----------------------------|------------|----------|------------------------------------------------------------------------------|
| **documents** | Object | yes | |
| **documents.create** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to create |
| **documents.replace** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to replace |
| **documents.delete** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to delete |
| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) |
| parameters | type | required | Description |
|---------------------------|--------------------|----------|----------------------------------------------------------------------------------------|
| **documents** | Object | yes | |
| **documents.create** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to create |
| **documents.replace** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to replace |
| **documents.delete** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to delete |
| **documents.transfer** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to transfer |
| **documents.updatePrice** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to set price |
| **documents.purchase** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to purchase |
| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) |
| **options** | DocumentTransitionParams | no | An object with two optional fields `price` and `receiver` that is used for NFT actions |


**Example**:
Expand Down
33 changes: 33 additions & 0 deletions packages/js-dash-sdk/docs/platform/documents/purchase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
**Usage**: `client.platform.documents.broadcast(documents, identity, options)`
**Description**: This method will broadcast a purchase state transition that buys the given document from other Identity.

Parameters:

| parameters | type | required | Description |
|------------------------|---------|------------------ |-------------------------------------------------------------------|
| **documents.purchase** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to buy |
| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) |
| **options** | DocumentTransitionParams | no | An object with field `price` (BigInt) and `receiver` (Identifier) |

**Example**:
```js
const identityId = '';// Your identity identifier
const receiverId = ''; // Receiver identity identifier
const documentId = '' // Your document id
const price = BigInt(1000000)

const identity = await client.platform.identities.get(identityId);
const receiverIdentity = await client.platform.identities.get(receiverId);

const identity = await client.platform.identities.get(identityId);

const [document] = await dash.platform.documents.get(
'helloWorldContract.note',
{ where: [['$id', '==', documentId]] },
);

await dash.platform.documents.broadcast({ purchase: [document], }, identity, { price, receiver: receiverIdentity.getId() });
```
**Note**: This method will change the ownership of the document to your identity, and seller identity will be credited with the amount specified in the updatePrice deducted from your balance.

Returns: DocumentsBatchTransition
31 changes: 31 additions & 0 deletions packages/js-dash-sdk/docs/platform/documents/transfer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
**Usage**: `client.platform.documents.broadcast(documents, identity, options)`
**Description**: This method will broadcast a document transfer

Parameters:

| parameters | type | required | Description |
|-------------------|---------|------------------ |-----------------------------------------------------------------------|
| **documents.transfer** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to transfer |
| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) |
| **options** | DocumentTransitionParams | no | An object with `receiver` field |

**Example**:
```js
const identityId = '';// Your identity identifier
const receiverId = ''; // Receiver identity identifier
const documentId = '' // Your document id

const identity = await client.platform.identities.get(identityId);
const receiverIdentity = await client.platform.identities.get(receiverId);

const [document] = await dash.platform.documents.get(
'helloWorldContract.note',
{ where: [['$id', '==', documentId]] },
);

await dash.platform.documents.broadcast({ transfer: [document], }, identity, { receiver: receiverIdentity.getId() });
```

**Note**: Transfer transition changes the ownership of the given document to the receiver identity

Returns: DocumentsBatchTransition
29 changes: 29 additions & 0 deletions packages/js-dash-sdk/docs/platform/documents/updatePrice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
**Usage**: `client.platform.documents.broadcast(documents, identity, options)`
**Description**: This method will broadcast an update price state transition that sets a price for the given document.

Parameters:

| parameters | type | required | Description |
|---------------------------|---------|------------------ |---------------------------------------------------------------------------|
| **documents.updatePrice** | ExtendedDocument[] | no | array of valid [created document](../documents/create.md) to update price |
| **identity** | Identity | yes | A valid [registered identity](../identities/register.md) |
| **options** | DocumentTransitionParams | no | An object with field `price` (BigInt) |

**Example**:
```js
const identityId = '';// Your identity identifier
const documentId = '' // Your document id
const price = BigInt(1000000)

const identity = await client.platform.identities.get(identityId);

const [document] = await dash.platform.documents.get(
'helloWorldContract.note',
{ where: [['$id', '==', documentId]] },
);

await dash.platform.documents.broadcast({ updatePrice: [document], }, identity, { price });
```
**Note**: This method sets the same price on all documents in the batch (only one is possible right now)

Returns: DocumentsBatchTransition
4 changes: 2 additions & 2 deletions packages/js-dash-sdk/src/SDK/Client/Client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ describe('Dash - Client', function suite() {
let error;
try {
await client.platform.documents.broadcast({
create: documentsFixture,
create: documentsFixture.map((d) => ({ document: d, params: null })),
}, identityFixture);
} catch (e) {
error = e;
Expand All @@ -332,7 +332,7 @@ describe('Dash - Client', function suite() {
dapiClientMock.platform.waitForStateTransitionResult.resolves(proofResponse);

await client.platform.documents.broadcast({
create: documentsFixture,
create: documentsFixture.map((d) => ({ document: d, params: null })),
}, identityFixture);

const serializedSt = dapiClientMock.platform.broadcastStateTransition.getCall(0).args[0];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
import { ExtendedDocument } from '@dashevo/wasm-dpp';
import { ExtendedDocument, Identifier } from '@dashevo/wasm-dpp';
import { Platform } from '../../Platform';
import broadcastStateTransition from '../../broadcastStateTransition';
import { signStateTransition } from '../../signStateTransition';

interface DocumentTransitionParams {
receiver?: Identifier;
price?: bigint;
}

interface DocumentSubmittable {
document: ExtendedDocument;
params?: DocumentTransitionParams;
}

/**
* Broadcast document onto the platform
*
* @param {Platform} this - bound instance class
* @param {Object} documents
* @param {ExtendedDocument[]} [documents.create]
* @param {ExtendedDocument[]} [documents.replace]
* @param {ExtendedDocument[]} [documents.delete]
* @param identity - identity
* @param {DocumentSubmittable[]} [documents.create]
* @param {DocumentSubmittable[]} [documents.replace]
* @param {DocumentSubmittable[]} [documents.delete]
* @param {DocumentSubmittable[]} [documents.transfer]
* @param {DocumentSubmittable[]} [documents.updatePrice]
* @param {DocumentSubmittable[]} [documents.purchase]
* @param {Identity} identity
*/
export default async function broadcast(
this: Platform,
documents: {
create?: ExtendedDocument[],
replace?: ExtendedDocument[],
delete?: ExtendedDocument[]
create?: DocumentSubmittable[],
replace?: DocumentSubmittable[],
delete?: DocumentSubmittable[],
transfer?: DocumentSubmittable[],
updatePrice?: DocumentSubmittable[],
purchase?: DocumentSubmittable[],
},
identity: any,
): Promise<any> {
this.logger.debug('[Document#broadcast] Broadcast documents', {
create: documents.create?.length || 0,
replace: documents.replace?.length || 0,
delete: documents.delete?.length || 0,
transfer: documents.transfer?.length || 0,
updatePrice: documents.updatePrice?.length || 0,
purchase: documents.purchase?.length || 0,
});
await this.initialize();

Expand All @@ -36,20 +54,47 @@ export default async function broadcast(
...(documents.create || []),
...(documents.replace || []),
...(documents.delete || []),
][0]?.getDataContractId();
...(documents.transfer || []),
...(documents.updatePrice || []),
...(documents.purchase || []),
][0]?.document.getDataContractId();

if (!dataContractId) {
throw new Error('Data contract ID is not found');
}

if (documents.transfer?.length && documents.transfer
.some(({ params }) => !params?.receiver)) {
throw new Error('Receiver Identity is not found for Transfer transition');
}

if (documents.updatePrice?.length && documents.updatePrice
.some(({ params }) => !params?.price)) {
throw new Error('Price must be provided for UpdatePrice operation');
}

if (documents.purchase?.length) {
if (documents.purchase
.some(({ params }) => !params?.price || !params?.receiver)) {
throw new Error('Receiver and Price must be provided for Purchase operation');
} else {
documents.purchase.forEach(({ document, params }) => document.setOwnerId(params!.receiver));
}
}

const identityContractNonce = await this.nonceManager
.bumpIdentityContractNonce(identityId, dataContractId);

const documentsBatchTransition = dpp.document.createStateTransition(documents, {
const identityNonceObj = {
[identityId.toString()]: {
[dataContractId.toString()]: identityContractNonce.toString(),
},
});
};

const documentsBatchTransition = dpp.document.createStateTransition(
documents,
identityNonceObj,
);

this.logger.silly('[Document#broadcast] Created documents batch transition');

Expand All @@ -61,15 +106,15 @@ export default async function broadcast(
// Acknowledge documents identifiers to handle retry attempts to mitigate
// state transition propagation lag
if (documents.create) {
documents.create.forEach((document) => {
documents.create.forEach(({ document }) => {
const documentLocator = `${document.getDataContractId().toString()}/${document.getType()}`;
this.fetcher.acknowledgeKey(documentLocator);
});
}

// Forget documents identifiers to not retry on them anymore
if (documents.delete) {
documents.delete.forEach((document) => {
documents.delete.forEach(({ document }) => {
const documentLocator = `${document.getDataContractId().toString()}/${document.getType()}`;
this.fetcher.forgetKey(documentLocator);
});
Expand All @@ -79,6 +124,7 @@ export default async function broadcast(
create: documents.create?.length || 0,
replace: documents.replace?.length || 0,
delete: documents.delete?.length || 0,
transfer: documents.transfer?.length || 0,
});

return documentsBatchTransition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export async function register(

await this.documents.broadcast(
{
create: [preorderDocument],
create: [{ document: preorderDocument }],
},
identity,
);
Expand All @@ -99,7 +99,7 @@ export async function register(
// 4. Create and send domain state transition
await this.documents.broadcast(
{
create: [domainDocument],
create: [{ document: domainDocument }],
},
identity,
);
Expand Down
12 changes: 6 additions & 6 deletions packages/platform-test-suite/test/e2e/contacts.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ describe('e2e', () => {
});

await bobClient.platform.documents.broadcast({
create: [profile],
create: [{ document: profile }],
}, bobIdentity);

// Additional wait time to mitigate testnet latency
Expand Down Expand Up @@ -244,7 +244,7 @@ describe('e2e', () => {
});

await aliceClient.platform.documents.broadcast({
create: [aliceProfile],
create: [{ document: aliceProfile }],
}, aliceIdentity);

// Additional wait time to mitigate testnet latency
Expand All @@ -265,7 +265,7 @@ describe('e2e', () => {

// 2. Broadcast change
await aliceClient.platform.documents.broadcast({
replace: [aliceProfile],
replace: [{ document: aliceProfile }],
}, aliceIdentity);

// Additional wait time to mitigate testnet latency
Expand Down Expand Up @@ -299,7 +299,7 @@ describe('e2e', () => {
});

await bobClient.platform.documents.broadcast({
create: [bobContactRequest],
create: [{ document: bobContactRequest }],
}, bobIdentity);

// Additional wait time to mitigate testnet latency
Expand All @@ -324,7 +324,7 @@ describe('e2e', () => {
});

await aliceClient.platform.documents.broadcast({
create: [aliceContactAcceptance],
create: [{ document: aliceContactAcceptance }],
}, aliceIdentity);

// Additional wait time to mitigate testnet latency
Expand All @@ -344,7 +344,7 @@ describe('e2e', () => {
it('should be able to remove contact approval', async () => {
// 1. Broadcast document deletion
await aliceClient.platform.documents.broadcast({
delete: [aliceContactAcceptance],
delete: [{ document: aliceContactAcceptance }],
}, aliceIdentity);

// Additional wait time to mitigate testnet latency
Expand Down
2 changes: 1 addition & 1 deletion packages/platform-test-suite/test/e2e/dpns.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ describe('DPNS', () => {

try {
await client.platform.documents.broadcast({
delete: [registeredDomain],
delete: [{ document: registeredDomain }],
}, identity);
} catch (e) {
broadcastError = e;
Expand Down
Loading
Loading