Skip to content

Commit

Permalink
Add read Move functions to TS SDK (MystenLabs#3821)
Browse files Browse the repository at this point in the history
* Add read Move functions to TS SDK
* Fix balance parsing
Co-authored-by: Jordan Gensler <[email protected]>
  • Loading branch information
gegaowp authored Aug 10, 2022
1 parent 35468bf commit 6127393
Show file tree
Hide file tree
Showing 8 changed files with 484 additions and 31 deletions.
1 change: 1 addition & 0 deletions sdk/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.8",
"@types/bn.js": "^5.1.0",
"@types/lossless-json": "^1.0.1",
"@types/mocha": "^9.1.0",
"husky": "^7.0.4",
"mockttp": "^2.7.0",
Expand Down
250 changes: 223 additions & 27 deletions sdk/typescript/src/index.guard.ts

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions sdk/typescript/src/providers/json-rpc-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ import {
isGetOwnedObjectsResponse,
isGetTxnDigestsResponse,
isSuiTransactionResponse,
isSuiMoveFunctionArgTypes,
isSuiMoveNormalizedModules,
isSuiMoveNormalizedModule,
isSuiMoveNormalizedFunction,
isSuiMoveNormalizedStruct,
} from '../index.guard';
import {
GatewayTxSeqNumber,
GetTxnDigestsResponse,
GetObjectDataResponse,
SuiObjectInfo,
SuiMoveFunctionArgTypes,
SuiMoveNormalizedModules,
SuiMoveNormalizedModule,
SuiMoveNormalizedFunction,
SuiMoveNormalizedStruct,
TransactionDigest,
SuiTransactionResponse,
SuiObjectRef,
Expand All @@ -38,6 +48,84 @@ export class JsonRpcProvider extends Provider {
this.client = new JsonRpcClient(endpoint);
}

// Move info
async getMoveFunctionArgTypes(
objectId: string,
moduleName: string,
functionName: string
): Promise<SuiMoveFunctionArgTypes> {
try {
return await this.client.requestWithType(
'sui_getMoveFunctionArgTypes',
[objectId, moduleName, functionName],
isSuiMoveFunctionArgTypes
);
} catch (err) {
throw new Error(
`Error fetching Move function arg types with package object ID: ${objectId}, module name: ${moduleName}, function name: ${functionName}`
);
}
}

async getNormalizedMoveModulesByPackage(objectId: string,): Promise<SuiMoveNormalizedModules> {
try {
return await this.client.requestWithType(
'sui_getNormalizedMoveModulesByPackage',
[objectId],
isSuiMoveNormalizedModules,
);
} catch (err) {
throw new Error(`Error fetching package: ${err} for package ${objectId}`);
}
}

async getNormalizedMoveModule(
objectId: string,
moduleName: string,
): Promise<SuiMoveNormalizedModule> {
try {
return await this.client.requestWithType(
'sui_getNormalizedMoveModule',
[objectId, moduleName],
isSuiMoveNormalizedModule,
);
} catch (err) {
throw new Error(`Error fetching module: ${err} for package ${objectId}, module ${moduleName}}`);
}
}

async getNormalizedMoveFunction(
objectId: string,
moduleName: string,
functionName: string
): Promise<SuiMoveNormalizedFunction> {
try {
return await this.client.requestWithType(
'sui_getNormalizedMoveFunction',
[objectId, moduleName, functionName],
isSuiMoveNormalizedFunction,
);
} catch (err) {
throw new Error(`Error fetching function: ${err} for package ${objectId}, module ${moduleName} and function ${functionName}}`);
}
}

async getNormalizedMoveStruct(
objectId: string,
moduleName: string,
structName: string
): Promise<SuiMoveNormalizedStruct> {
try {
return await this.client.requestWithType(
'sui_getNormalizedMoveStruct',
[objectId, moduleName, structName],
isSuiMoveNormalizedStruct,
);
} catch (err) {
throw new Error(`Error fetching struct: ${err} for package ${objectId}, module ${moduleName} and struct ${structName}}`);
}
}

// Objects
async getObjectsOwnedByAddress(address: string): Promise<SuiObjectInfo[]> {
try {
Expand Down
47 changes: 47 additions & 0 deletions sdk/typescript/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import {
GetTxnDigestsResponse,
SuiTransactionResponse,
SuiObjectRef,
SuiMoveFunctionArgTypes,
SuiMoveNormalizedFunction,
SuiMoveNormalizedStruct,
SuiMoveNormalizedModule,
SuiMoveNormalizedModules,
} from '../types';

///////////////////////////////
Expand Down Expand Up @@ -71,6 +76,48 @@ export abstract class Provider {
pubkey: string
): Promise<SuiTransactionResponse>;

// Move info
/**
* Get Move function argument types like read, write and full access
*/
abstract getMoveFunctionArgTypes(
objectId: string,
moduleName: string,
functionName: string
): Promise<SuiMoveFunctionArgTypes>;

/**
* Get a map from module name to
* structured representations of Move modules
*/
abstract getNormalizedMoveModulesByPackage(objectId: string,): Promise<SuiMoveNormalizedModules>;

/**
* Get a structured representation of Move module
*/
abstract getNormalizedMoveModule(
objectId: string,
moduleName: string,
): Promise<SuiMoveNormalizedModule>;

/**
* Get a structured representation of Move function
*/
abstract getNormalizedMoveFunction(
objectId: string,
moduleName: string,
functionName: string
): Promise<SuiMoveNormalizedFunction>

/**
* Get a structured representation of Move struct
*/
abstract getNormalizedMoveStruct(
objectId: string,
moduleName: string,
structName: string
): Promise<SuiMoveNormalizedStruct>;

abstract syncAccountState(address: string): Promise<any>;
// TODO: add more interface methods
}
41 changes: 41 additions & 0 deletions sdk/typescript/src/providers/void-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import {
GetObjectDataResponse,
SuiTransactionResponse,
SuiObjectRef,
SuiMoveFunctionArgTypes,
SuiMoveNormalizedFunction,
SuiMoveNormalizedStruct,
SuiMoveNormalizedModule,
SuiMoveNormalizedModules,
} from '../types';
import { Provider } from './provider';

Expand Down Expand Up @@ -65,6 +70,42 @@ export class VoidProvider extends Provider {
throw this.newError('getRecentTransactions');
}

async getMoveFunctionArgTypes(
_objectId: string,
_moduleName: string,
_functionName: string
): Promise<SuiMoveFunctionArgTypes> {
throw this.newError('getMoveFunctionArgTypes');
}

async getNormalizedMoveModulesByPackage(_objectId: string,): Promise<SuiMoveNormalizedModules> {
throw this.newError('getNormalizedMoveModulesByPackage');
}

async getNormalizedMoveModule(
_objectId: string,
_moduleName: string,
): Promise<SuiMoveNormalizedModule> {
throw this.newError('getNormalizedMoveModule');
}

async getNormalizedMoveFunction(
_objectId: string,
_moduleName: string,
_functionName: string
): Promise<SuiMoveNormalizedFunction> {
throw this.newError('getNormalizedMoveFunction');
}

async getNormalizedMoveStruct(
_objectId: string,
_oduleName: string,
_structName: string
): Promise<SuiMoveNormalizedStruct> {
throw this.newError('getNormalizedMoveStruct');
}


async syncAccountState(_address: string): Promise<any> {
throw this.newError('syncAccountState');
}
Expand Down
12 changes: 8 additions & 4 deletions sdk/typescript/src/rpc/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import RpcClient from 'jayson/lib/client/browser';
import fetch from 'cross-fetch';
import { isErrorResponse, isValidResponse } from './client.guard';
const LosslessJSON = require('lossless-json');
import * as LosslessJSON from 'lossless-json';

/**
* An object defining headers to be passed to the RPC server
Expand Down Expand Up @@ -47,11 +47,16 @@ export class JsonRpcClient {
let res: Response = await fetch(url, options);
const text = await res.text();
const result = JSON.stringify(
LosslessJSON.parse(text, (key: string, value: any) => {
LosslessJSON.parse(text, (key, value) => {
if (value == null) {
return value;
}
if (key === 'balance') return value.toString();

// TODO: This is a bad hack, we really shouldn't be doing this here:
if (key === 'balance' && typeof value === 'number') {
return value.toString();
}

try {
if (value.isLosslessNumber) return value.valueOf();
} catch {
Expand Down Expand Up @@ -85,7 +90,6 @@ export class JsonRpcClient {
throw new Error(`RPC Error: ${response.error.message}`);
} else if (isValidResponse(response)) {
if (isT(response.result)) return response.result;
else
throw new Error(
`RPC Error: result not of expected type. Result received was: ${JSON.stringify(
response.result
Expand Down
71 changes: 71 additions & 0 deletions sdk/typescript/src/types/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,77 @@ export type SuiMovePackage = {
disassembled: MovePackageContent;
};

export type SuiMoveFunctionArgTypesResponse = SuiMoveFunctionArgType[];

export type SuiMoveFunctionArgType = string | { Object: string };

export type SuiMoveFunctionArgTypes = SuiMoveFunctionArgType[];

export type SuiMoveNormalizedModules = Record<string, SuiMoveNormalizedModule>;

export type SuiMoveNormalizedModule = {
file_format_version: number;
address: string;
name: string;
friends: SuiMoveModuleId[];
structs: Record<string, SuiMoveNormalizedStruct>;
exposed_functions: Record<string, SuiMoveNormalizedFunction>;
}

export type SuiMoveModuleId = {
address: string;
name: string;
};

export type SuiMoveNormalizedStruct = {
abilities: SuiMoveAbilitySet;
type_parameters: SuiMoveStructTypeParameter[];
fields: SuiMoveNormalizedField[];
}

export type SuiMoveStructTypeParameter = {
constraints: SuiMoveAbilitySet;
is_phantom: boolean;
}

export type SuiMoveNormalizedField = {
name: string;
type_: SuiMoveNormalizedType;
}

export type SuiMoveNormalizedFunction = {
visibility: SuiMoveVisibility;
is_entry: boolean;
type_parameters: SuiMoveAbilitySet[];
parameters: SuiMoveNormalizedType[];
return_: SuiMoveNormalizedType[];
};

export type SuiMoveVisibility =
| "Private"
| "Public"
| "Friend";

export type SuiMoveTypeParameterIndex = number;

export type SuiMoveAbilitySet = {
abilities: string[],
};

export type SuiMoveNormalizedType = (
| string
| {TypeParameter: SuiMoveTypeParameterIndex}
| {Reference: SuiMoveNormalizedType}
| {MutableReference: SuiMoveNormalizedType}
| {Vector: SuiMoveNormalizedType}
| {Struct: {
address: string,
module: string,
name: string,
type_arguments: SuiMoveNormalizedType[],
}}
);

export type SuiObject = {
/** The meat of the object */
data: SuiData;
Expand Down
5 changes: 5 additions & 0 deletions sdk/typescript/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,11 @@
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz"
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==

"@types/lossless-json@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/lossless-json/-/lossless-json-1.0.1.tgz#e3633ae5030d46d4e53d40c5ff9fa8c594f6f51e"
integrity sha512-zPE8kmpeL5/6L5gtTQHSOkAW/OSYYNTDRt6/2oEgLO1Zd3Rj5WVDoMloTtLJxQJhZGLGbL4pktKSh3NbzdaWdw==

"@types/minimatch@^3.0.3":
version "3.0.5"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz"
Expand Down

0 comments on commit 6127393

Please sign in to comment.