Skip to content
Open
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
10 changes: 10 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,23 @@ Platform uses data contracts to define application data schemas:
- **Serialization**: Custom serialization with `rs-platform-serialization`
- **Value Handling**: `rs-platform-value` for cross-language data representation
- **Proof Verification**: `rs-drive-proof-verifier` for cryptographic proofs
- **State Transitions**: Documents and data contracts use state transitions for updates
- **State Transitions**: Documents and data contracts use state transitions for updates

### Platform Test Suite Issues (WASM SDK Integration)

When running the platform test suite after wasm-sdk integration:

1. **Faucet Wallet Setup**: The faucet wallet needs funded UTXOs. Generate blocks to the faucet address:
```bash
yarn dashmate core cli "generatetoaddress 100 yhvXpqQjfN9S4j5mBKbxeGxiETJrrLETg5"
```

2. **Known Issues**:
- "utxosList must contain at least 1 utxo" - This is a wallet sync timing issue, not a lack of funds
- ES module loading errors - Some tests fail to load wasm-sdk properly
- See `packages/platform-test-suite/WASM_SDK_TEST_ISSUES.md` for detailed troubleshooting

3. **Test Environment**:
- Requires running local dashmate network
- Uses `.env` file for configuration (FAUCET_1_ADDRESS, FAUCET_1_PRIVATE_KEY, etc.)
- Bootstrap.js maps FAUCET_1_* vars to FAUCET_* based on worker ID
25 changes: 25 additions & 0 deletions packages/js-dash-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,33 @@
"unpkg": "dist/dash.min.js",
"browser": "dist/dash.min.js",
"types": "build/index.d.ts",
"exports": {
".": {
"import": "./build/index.js",
"require": "./build/index.js",
"types": "./build/index.d.ts"
},
"./core": {
"import": "./build/index.core.js",
"require": "./build/index.core.js",
"types": "./build/index.core.d.ts"
},
"./platform": {
"import": "./build/index.platform.js",
"require": "./build/index.platform.js",
"types": "./build/index.platform.d.ts"
},
"./build/*": "./build/*"
},
"scripts": {
"start:dev": "nodemon --exec 'yarn run build && yarn run test:unit'",
"start:ts": "tsc -p tsconfig.build.json --watch",
"build": "yarn run build:ts && webpack --stats-error-details",
"build:ts": "tsc -p tsconfig.build.json",
"build:full": "yarn run build:ts && webpack --config webpack.config.js --env target=full",
"build:core": "yarn run build:ts && webpack --config webpack.config.js --env target=core",
"build:platform": "yarn run build:ts && webpack --config webpack.config.js --env target=platform",
"build:all": "yarn run build:ts && webpack --config webpack.config.js",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test": "yarn run test:types && yarn run test:unit && yarn run test:browsers",
Expand Down Expand Up @@ -108,5 +130,8 @@
"util": "^0.12.4",
"webpack": "^5.94.0",
"webpack-cli": "^4.9.1"
},
"optionalDependencies": {
"@dashevo/wasm-sdk": "file:../wasm-sdk/pkg"
}
}
143 changes: 87 additions & 56 deletions packages/js-dash-sdk/src/SDK/Client/Platform/Platform.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import loadWasmDpp, { DashPlatformProtocol, getLatestProtocolVersion } from '@dashevo/wasm-dpp';
import type { DPPModule } from '@dashevo/wasm-dpp';
import crypto from 'crypto';

import Client from '../Client';
import { IStateTransitionResult } from './IStateTransitionResult';
import { WasmPlatformAdapter } from './adapters/WasmPlatformAdapter';

import createAssetLockTransaction from './createAssetLockTransaction';

Expand Down Expand Up @@ -48,6 +47,7 @@ export interface PlatformOpts {
client: Client,
network: string,
driveProtocolVersion?: number,
enablePlatform?: boolean,
}

/**
Expand Down Expand Up @@ -107,41 +107,43 @@ interface DataContracts {
* @param contracts - contracts
*/
export class Platform {
// TODO: Address in further type system improvements
// Do we want to refactor all methods to check
// whether dpp is initialized instead of ts-ignoring?
// @ts-ignore
dpp: DashPlatformProtocol;

// WASM SDK adapter for platform operations
private adapter?: WasmPlatformAdapter;
// Direct access to wasm-sdk instance for method delegation
public wasmSdk?: any;

// Legacy DPP - will be removed once migration is complete
dpp?: any;

protocolVersion?: number;

public documents: Records;

/**
* @param {Function} get - get identities from the platform
* @param {Function} register - register identities on the platform
*/
* @param {Function} get - get identities from the platform
* @param {Function} register - register identities on the platform
*/
public identities: Identities;

/**
* @param {Function} get - get names from the platform
* @param {Function} register - register names on the platform
*/
* @param {Function} get - get names from the platform
* @param {Function} register - register names on the platform
*/
public names: DomainNames;

/**
* @param {Function} get - get contracts from the platform
* @param {Function} create - create contracts which can be broadcasted
* @param {Function} register - register contracts on the platform
*/
* @param {Function} get - get contracts from the platform
* @param {Function} create - create contracts which can be broadcasted
* @param {Function} register - register contracts on the platform
*/
public contracts: DataContracts;

public logger: ConfigurableLogger;

/**
* Broadcasts state transition
* @param {Object} stateTransition
*/
* Broadcasts state transition
* @param {Object} stateTransition
*/
public broadcastStateTransition(stateTransition: any): Promise<IStateTransitionResult | void> {
return broadcastStateTransition(this, stateTransition);
}
Expand All @@ -156,12 +158,17 @@ export class Platform {

public nonceManager: NonceManager;

private platformEnabled: boolean;

/**
* Construct some instance of Platform
*
* @param {PlatformOpts} options - options for Platform
*/
* Construct some instance of Platform
*
* @param {PlatformOpts} options - options for Platform
*/
constructor(options: PlatformOpts) {
// Platform functionality can be disabled for core-only builds
this.platformEnabled = options.enablePlatform !== false;

this.documents = {
broadcast: broadcastDocument.bind(this),
create: createDocument.bind(this),
Expand Down Expand Up @@ -207,45 +214,69 @@ export class Platform {

this.fetcher = new Fetcher(this.client.getDAPIClient());
this.nonceManager = new NonceManager(this.client.getDAPIClient());

// Initialize adapter if platform is enabled
if (this.platformEnabled) {
this.adapter = new WasmPlatformAdapter(
this.client.getDAPIClient(),
this.client.network,
true // proofs enabled by default
);
// Set the platform reference in the adapter
this.adapter.setPlatform(this);
}
}

async initialize() {
if (!this.dpp) {
await Platform.initializeDppModule();

if (this.protocolVersion === undefined) {
// use mapped protocol version otherwise
// fallback to one that set in dpp as the last option

const mappedProtocolVersion = Platform.networkToProtocolVersion.get(
this.client.network,
);
if (!this.platformEnabled) {
throw new Error('Platform functionality is disabled. Use full SDK build or enable platform.');
}

this.protocolVersion = mappedProtocolVersion !== undefined
? mappedProtocolVersion : getLatestProtocolVersion();
if (!this.wasmSdk && this.adapter) {
try {
await this.adapter.initialize();
this.wasmSdk = await this.adapter.getSdk();

// Set protocol version if not already set
if (this.protocolVersion === undefined) {
const mappedProtocolVersion = Platform.networkToProtocolVersion.get(
this.client.network,
);

this.protocolVersion = mappedProtocolVersion !== undefined
? mappedProtocolVersion : 1; // Default to 1
}
} catch (error) {
this.logger.error('Failed to initialize wasm-sdk:', error);
throw error;
}
}
}

// eslint-disable-next-line
/**
* Get the platform adapter for advanced usage
*/
getAdapter(): WasmPlatformAdapter | undefined {
return this.adapter;
}

this.dpp = new DashPlatformProtocol(
{
generate: () => crypto.randomBytes(32),
},
this.protocolVersion,
);
/**
* Dispose of platform resources
*/
async dispose(): Promise<void> {
if (this.adapter) {
await this.adapter.dispose();
}
this.wasmSdk = undefined;
}

// Explicitly provide DPPModule as return type.
// If we don't do it, typescript behaves weird and in compiled Platform.d.ts
// this code looks like this.
//
// ```
// static initializeDppModule(): Promise<typeof import("@dashevo/wasm-dppdist/dpp")>;
// ```
//
// Slash is missing before `dist` and TS compilation in consumers is breaking
static async initializeDppModule(): Promise<DPPModule> {
return loadWasmDpp();
/**
* Legacy method for backward compatibility during migration
* Will be removed once migration is complete
*/
static async initializeDppModule(): Promise<any> {
// This is now a no-op as we use wasm-sdk
console.warn('Platform.initializeDppModule() is deprecated. Platform now uses wasm-sdk.');
return {};
}
}
}
Loading
Loading