diff --git a/sdk/typescript/.gitignore b/sdk/typescript/.gitignore index 4c9d7c35a40d3..5a315a86487f5 100644 --- a/sdk/typescript/.gitignore +++ b/sdk/typescript/.gitignore @@ -2,3 +2,4 @@ .DS_Store node_modules dist +doc diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index 177cc5afaba9c..741348d117454 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -2,21 +2,51 @@ This is the Sui TypeScript SDK built on the Sui [JSON RPC API](https://github.com/MystenLabs/sui/blob/main/doc/src/build/json-rpc.md). It provides utility classes and functions for applications to sign transactions and interact with the Sui network. -Note that the SDK is still in development mode and some API functions are subject to change. +WARNING: Note that we are still iterating on the RPC and SDK API before TestNet, therefore please expect frequent breaking changes in the short-term. We expect the API to stabilize after the upcoming TestNet launch. -## Installation +## Working with DevNet + +The SDK will be published to [npm registry](https://www.npmjs.com/package/@mysten/sui.js) with the same bi-weekly release cycle as the DevNet validators and [RPC Server](https://github.com/MystenLabs/sui/blob/main/doc/src/build/json-rpc.md). To use the SDK in your project, you can do: ```bash $ yarn add @mysten/sui.js ``` -## Local Development Environment Setup +## Working with local network + +Note that the [published SDK](https://www.npmjs.com/package/@mysten/sui.js) might go out of sync with the RPC server on the `main` branch until the next bi-weekly release, therefore it's recommended to build the SDK locally if you want to test against the local network. + +Run the following command in the `sui/sdk/typescript` directory to build the SDK and [create a symlink](https://docs.npmjs.com/cli/v8/commands/npm-link) in the global folder. + +```bash +$ cd /sdk/typescript +$ yarn && yarn build +$ npm link +``` + +Next, go to your project directory and create a symbolic link from globally-installed `@mysten/sui.js` to the `node_modules/` of your project directory. + +```bash +cd +npm link @mysten/sui.js +``` + +Refer to the [JSON RPC doc](https://github.com/MystenLabs/sui/blob/main/doc/src/build/json-rpc.md) for instructions about how to start a local network and local RPC server + +## Type Doc + +You can view the generated [Type Doc](https://typedoc.org/) for the [current release of the SDK](https://www.npmjs.com/package/@mysten/sui.js) at http://typescript-sdk-docs.s3-website-us-east-1.amazonaws.com/. -Follow the [JSON RPC doc](https://github.com/MystenLabs/sui/blob/main/doc/src/build/json-rpc.md) to start a local network and local RPC server +For the latest docs for the `main` branch, run `yarn doc` and open the [doc/index.html](doc/index.html) in your browser. ## Usage -The `JsonRpcProvider` class provides a connection to the JSON-RPC Server and should be used for all read-only operations. For example: +The `JsonRpcProvider` class provides a connection to the JSON-RPC Server and should be used for all read-only operations. The default URLs to connect with the RPC server are: + +- local: http://127.0.0.1:5001 +- DevNet: https://gateway.devnet.sui.io:443 + +Examples: Fetch objects owned by the address `0xbff6ccc8707aa517b4f1b95750a2a8c666012df3` @@ -40,7 +70,7 @@ const txn = await provider.getTransaction( For any operations that involves signing or submitting transactions, you should use the `Signer` API. For example: -To transfer a Coin: +To transfer a `0x2::Coin::Coin`: ```typescript import { Ed25519Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js'; @@ -50,14 +80,74 @@ const signer = new RawSigner( keypair, new JsonRpcProvider('https://gateway.devnet.sui.io:443') ); -const txn = await signer.transferCoin({ - signer: keypair.getPublicKey().toSuiAddress(), +const transferTxn = await signer.transferCoin({ objectId: '0x5015b016ab570df14c87649eda918e09e5cc61e0', - gasPayment: '0x0a8c2a0fd59bf41678b2e22c3dd2b84425fb3673', - gasBudget: 10000, - recipient: '0xBFF6CCC8707AA517B4F1B95750A2A8C666012DF3', + gasBudget: 1000, + recipient: '0xd84058cb73bdeabe123b56632713dcd65e1a6c92', +}); +console.log('transferTxn', transferTxn); +``` + +To split a `0x2::Coin::Coin` into multiple coins + +```typescript +import { Ed25519Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js'; +// Generate a new Keypair +const keypair = new Ed25519Keypair(); +const signer = new RawSigner( + keypair, + new JsonRpcProvider('https://gateway.devnet.sui.io:443') +); +const splitTxn = await signer..splitCoin({ + coinObjectId: '0x5015b016ab570df14c87649eda918e09e5cc61e0', + // Say if the original coin has a balance of 100, + // This function will create three new coins of amount 10, 20, 30, + // respectively, the original coin will retain the remaining balance(40). + splitAmounts: [10, 20, 30], + gasBudget: 1000, +}); +console.log('SplitCoin txn', splitTxn); +``` + +To merge two coins: + +```typescript +import { Ed25519Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js'; +// Generate a new Keypair +const keypair = new Ed25519Keypair(); +const signer = new RawSigner( + keypair, + new JsonRpcProvider('https://gateway.devnet.sui.io:443') +); +const mergeTxn = await signer.mergeCoin({ + primaryCoin: '0x5015b016ab570df14c87649eda918e09e5cc61e0', + coinToMerge: '0xcc460051569bfb888dedaf5182e76f473ee351af', + gasBudget: 1000, }); +console.log('MergeCoin txn', mergeTxn); ``` -To sign a raw message: -TODO +To make a move call: + +```typescript +import { Ed25519Keypair, JsonRpcProvider, RawSigner } from '@mysten/sui.js'; +// Generate a new Keypair +const keypair = new Ed25519Keypair(); +const signer = new RawSigner( + keypair, + new JsonRpcProvider('https://gateway.devnet.sui.io:443') +); +const moveCallTxn = await signer.executeMoveCall({ + packageObjectId: '0x2', + module: 'DevNetNFT', + function: 'mint', + typeArguments: [], + arguments: [ + 'Example NFT', + 'An NFT created by the wallet Command Line Tool', + 'ipfs://bafkreibngqhl3gaa7daob4i2vccziay2jjlp435cf66vhono7nrvww53ty', + ], + gasBudget: 10000, +}); +console.log('moveCallTxn', moveCallTxn); +``` diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index f326db1bc7794..2a4e226c1e6a3 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -1,5 +1,5 @@ { - "version": "0.1.2", + "version": "0.3.0", "license": "Apache-2.0", "main": "dist/index.js", "typings": "dist/index.d.ts", @@ -13,6 +13,7 @@ "scripts": { "start": "./type_guards.sh; tsdx watch", "build": "./type_guards.sh; tsdx build", + "doc": "typedoc", "test": "tsdx test", "lint": "tsdx lint", "prepare": "tsdx build", @@ -60,6 +61,7 @@ "ts-auto-guard": "^2.4.1", "tsdx": "^0.14.1", "tslib": "^2.3.1", + "typedoc": "^0.22.17", "typescript": "^4.6.3" }, "dependencies": { diff --git a/sdk/typescript/src/index.guard.ts b/sdk/typescript/src/index.guard.ts index 7f572d56e0e41..9a574136baab9 100644 --- a/sdk/typescript/src/index.guard.ts +++ b/sdk/typescript/src/index.guard.ts @@ -5,8 +5,10 @@ * Generated type guards for "index.ts". * WARNING: Do not manually change this file. */ -import { Ed25519KeypairData, Keypair, PublicKeyInitData, PublicKeyData, TransferCoinTransaction, MergeCoinTransaction, SplitCoinTransaction, MoveCallTransaction, TxnDataSerializer, TransactionDigest, SuiAddress, ObjectOwner, SuiObjectRef, SuiObjectInfo, ObjectContentFields, MovePackageContent, SuiData, SuiMoveObject, SuiMovePackage, SuiObject, ObjectStatus, ObjectType, GetOwnedObjectsResponse, GetObjectDataResponse, ObjectDigest, ObjectId, SequenceNumber, TransferCoin, RawAuthoritySignInfo, TransactionKindName, SuiTransactionKind, TransactionData, EpochId, AuthorityQuorumSignInfo, CertifiedTransaction, GasCostSummary, ExecutionStatusType, ExecutionStatus, OwnedObjectRef, TransactionEffects, TransactionEffectsResponse, GatewayTxSeqNumber, GetTxnDigestsResponse, Event, MoveCall, SuiJsonValue, EmptySignInfo, AuthorityName, AuthoritySignature, TransactionBytes, MergeCoinResponse, SplitCoinResponse, TransactionResponse } from "./index"; +import { Ed25519KeypairData, Keypair, PublicKeyInitData, PublicKeyData, TransferCoinTransaction, MergeCoinTransaction, SplitCoinTransaction, MoveCallTransaction, TxnDataSerializer, SignaturePubkeyPair, Signer, TransactionDigest, SuiAddress, ObjectOwner, SuiObjectRef, SuiObjectInfo, ObjectContentFields, MovePackageContent, SuiData, SuiMoveObject, SuiMovePackage, SuiObject, ObjectStatus, ObjectType, GetOwnedObjectsResponse, GetObjectDataResponse, ObjectDigest, ObjectId, SequenceNumber, TransferCoin, RawAuthoritySignInfo, TransactionKindName, SuiTransactionKind, TransactionData, EpochId, AuthorityQuorumSignInfo, CertifiedTransaction, GasCostSummary, ExecutionStatusType, ExecutionStatus, OwnedObjectRef, TransactionEffects, TransactionEffectsResponse, GatewayTxSeqNumber, GetTxnDigestsResponse, Event, MoveCall, SuiJsonValue, EmptySignInfo, AuthorityName, AuthoritySignature, TransactionBytes, MergeCoinResponse, SplitCoinResponse, TransactionResponse } from "./index"; import { BN } from "bn.js"; +import { Base64DataBuffer } from "./serialization/base64"; +import { PublicKey } from "./cryptography/publickey"; export function isEd25519KeypairData(obj: any, _argumentName?: string): obj is Ed25519KeypairData { return ( @@ -127,6 +129,26 @@ export function isTxnDataSerializer(obj: any, _argumentName?: string): obj is Tx ) } +export function isSignaturePubkeyPair(obj: any, _argumentName?: string): obj is SignaturePubkeyPair { + return ( + (obj !== null && + typeof obj === "object" || + typeof obj === "function") && + obj.signature instanceof Base64DataBuffer && + obj.pubKey instanceof PublicKey + ) +} + +export function isSigner(obj: any, _argumentName?: string): obj is Signer { + return ( + (obj !== null && + typeof obj === "object" || + typeof obj === "function") && + typeof obj.getAddress === "function" && + typeof obj.signData === "function" + ) +} + export function isTransactionDigest(obj: any, _argumentName?: string): obj is TransactionDigest { return ( typeof obj === "string" diff --git a/sdk/typescript/src/index.ts b/sdk/typescript/src/index.ts index 151b0655cd6a6..389137afa4318 100644 --- a/sdk/typescript/src/index.ts +++ b/sdk/typescript/src/index.ts @@ -14,6 +14,7 @@ export * from './serialization/hex'; export * from './signers/txn-data-serializers/rpc-txn-data-serializer'; export * from './signers/txn-data-serializers/txn-data-serializer'; +export * from './signers/signer'; export * from './signers/raw-signer'; export * from './signers/signer-with-provider'; diff --git a/sdk/typescript/typedoc.json b/sdk/typescript/typedoc.json new file mode 100644 index 0000000000000..ee8995e2e4a83 --- /dev/null +++ b/sdk/typescript/typedoc.json @@ -0,0 +1,7 @@ +{ + "entryPoints": ["src/index.ts"], + "excludeInternal": true, + "excludePrivate": true, + "intentionallyNotExported": [], + "out": "doc" +} diff --git a/sdk/typescript/yarn.lock b/sdk/typescript/yarn.lock index bccc4dd3cd0e8..b7e794e5068f6 100644 --- a/sdk/typescript/yarn.lock +++ b/sdk/typescript/yarn.lock @@ -2179,6 +2179,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^2.3.1: version "2.3.2" resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" @@ -3892,6 +3899,17 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" + integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" @@ -5163,6 +5181,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" @@ -5367,6 +5390,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + magic-string@^0.25.2, magic-string@^0.25.7: version "0.25.9" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" @@ -5405,6 +5433,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marked@^4.0.16: + version "4.0.16" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.16.tgz#9ec18fc1a723032eb28666100344d9428cf7a264" + integrity sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" @@ -5491,6 +5524,13 @@ minimatch@^3.0.4, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1, minimatch@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" @@ -6781,6 +6821,15 @@ shellwords@^0.1.1: resolved "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +shiki@^0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14" + integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng== + dependencies: + jsonc-parser "^3.0.0" + vscode-oniguruma "^1.6.1" + vscode-textmate "5.2.0" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" @@ -7563,6 +7612,17 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typedoc@^0.22.17: + version "0.22.17" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.17.tgz#bc51cc95f569040112504300831cdac4f8089b7b" + integrity sha512-h6+uXHVVCPDaANzjwzdsj9aePBjZiBTpiMpBBeyh1zcN2odVsDCNajz8zyKnixF93HJeGpl34j/70yoEE5BfNg== + dependencies: + glob "^8.0.3" + lunr "^2.3.9" + marked "^4.0.16" + minimatch "^5.1.0" + shiki "^0.10.1" + typescript@^3.7.3: version "3.9.10" resolved "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz" @@ -7757,6 +7817,16 @@ vm2@^3.9.8: acorn "^8.7.0" acorn-walk "^8.2.0" +vscode-oniguruma@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607" + integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA== + +vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== + w3c-hr-time@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz"