From 97690e2e188b9aca673d7ca8407ca77dbbf08aaf Mon Sep 17 00:00:00 2001 From: Ben Guidarelli Date: Wed, 15 Nov 2023 03:58:56 -0500 Subject: [PATCH] add sui platform skeleton --- package-lock.json | 319 ++++++++++++------ package.json | 14 +- platforms/sui/eslintrc.json | 20 ++ platforms/sui/package.json | 48 +++ platforms/sui/protocols/core/package.json | 48 +++ platforms/sui/protocols/core/src/core.ts | 69 ++++ platforms/sui/protocols/core/src/index.ts | 15 + .../sui/protocols/core/tsconfig.cjs.json | 8 + .../sui/protocols/core/tsconfig.esm.json | 8 + platforms/sui/protocols/core/typedoc.json | 4 + .../sui/protocols/tokenBridge/package.json | 48 +++ .../sui/protocols/tokenBridge/src/index.ts | 15 + .../protocols/tokenBridge/src/tokenBridge.ts | 159 +++++++++ .../protocols/tokenBridge/tsconfig.cjs.json | 8 + .../protocols/tokenBridge/tsconfig.esm.json | 8 + .../sui/protocols/tokenBridge/typedoc.json | 4 + platforms/sui/src/address.ts | 59 ++++ platforms/sui/src/chain.ts | 7 + platforms/sui/src/index.ts | 7 + platforms/sui/src/platform.ts | 134 ++++++++ platforms/sui/src/testing/index.ts | 1 + platforms/sui/src/testing/signer.ts | 36 ++ platforms/sui/src/types.ts | 8 + platforms/sui/src/unsignedTransaction.ts | 15 + platforms/sui/tsconfig.cjs.json | 8 + platforms/sui/tsconfig.esm.json | 8 + platforms/sui/typedoc.json | 4 + 27 files changed, 982 insertions(+), 100 deletions(-) create mode 100644 platforms/sui/eslintrc.json create mode 100644 platforms/sui/package.json create mode 100644 platforms/sui/protocols/core/package.json create mode 100644 platforms/sui/protocols/core/src/core.ts create mode 100644 platforms/sui/protocols/core/src/index.ts create mode 100644 platforms/sui/protocols/core/tsconfig.cjs.json create mode 100644 platforms/sui/protocols/core/tsconfig.esm.json create mode 100644 platforms/sui/protocols/core/typedoc.json create mode 100644 platforms/sui/protocols/tokenBridge/package.json create mode 100644 platforms/sui/protocols/tokenBridge/src/index.ts create mode 100644 platforms/sui/protocols/tokenBridge/src/tokenBridge.ts create mode 100644 platforms/sui/protocols/tokenBridge/tsconfig.cjs.json create mode 100644 platforms/sui/protocols/tokenBridge/tsconfig.esm.json create mode 100644 platforms/sui/protocols/tokenBridge/typedoc.json create mode 100644 platforms/sui/src/address.ts create mode 100644 platforms/sui/src/chain.ts create mode 100644 platforms/sui/src/index.ts create mode 100644 platforms/sui/src/platform.ts create mode 100644 platforms/sui/src/testing/index.ts create mode 100644 platforms/sui/src/testing/signer.ts create mode 100644 platforms/sui/src/types.ts create mode 100644 platforms/sui/src/unsignedTransaction.ts create mode 100644 platforms/sui/tsconfig.cjs.json create mode 100644 platforms/sui/tsconfig.esm.json create mode 100644 platforms/sui/typedoc.json diff --git a/package-lock.json b/package-lock.json index cd00b46ba4..9a2009bf97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,18 +12,9 @@ "core/base", "core/definitions", "connect", - "platforms/evm", - "platforms/evm/protocols/core", - "platforms/evm/protocols/tokenBridge", - "platforms/evm/protocols/cctp", - "platforms/solana", - "platforms/solana/protocols/core", - "platforms/solana/protocols/tokenBridge", - "platforms/solana/protocols/cctp", - "platforms/cosmwasm", - "platforms/cosmwasm/protocols/core", - "platforms/cosmwasm/protocols/tokenBridge", - "platforms/cosmwasm/protocols/ibc", + "platforms/sui", + "platforms/sui/protocols/core", + "platforms/sui/protocols/tokenBridge", "examples" ], "devDependencies": { @@ -73,23 +64,6 @@ "@wormhole-foundation/sdk-base": "^0.3.0-beta.3" } }, - "core/tokenRegistry": { - "name": "@wormhole-foundation/sdk-token-registry", - "version": "0.2.6-beta.1", - "extraneous": true, - "dependencies": { - "@wormhole-foundation/connect-sdk": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm-tokenbridge": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm-tokenbridge": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana-tokenbridge": "^0.2.6-beta.1" - } - }, "examples": { "name": "@wormhole-foundation/connect-sdk-examples", "version": "0.3.0-beta.3", @@ -1737,6 +1711,9 @@ "shx": "^0.3.2" } }, + "node_modules/@injectivelabs/exceptions/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/grpc-web": { "version": "0.0.1", "license": "Apache-2.0", @@ -1845,6 +1822,9 @@ "shx": "^0.3.2" } }, + "node_modules/@injectivelabs/networks/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/sdk-ts": { "version": "1.14.4", "hasInstallScript": true, @@ -1890,6 +1870,9 @@ "snakecase-keys": "^5.4.1" } }, + "node_modules/@injectivelabs/sdk-ts/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/amino": { "version": "0.30.1", "license": "Apache-2.0", @@ -2068,6 +2051,9 @@ "store2": "^2.12.0" } }, + "node_modules/@injectivelabs/test-utils/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/test-utils/node_modules/axios": { "version": "0.21.4", "license": "MIT", @@ -2093,6 +2079,9 @@ "shx": "^0.3.2" } }, + "node_modules/@injectivelabs/token-metadata/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/ts-types": { "version": "1.14.4", "hasInstallScript": true, @@ -2102,6 +2091,9 @@ "shx": "^0.3.2" } }, + "node_modules/@injectivelabs/ts-types/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/utils": { "version": "1.14.4", "hasInstallScript": true, @@ -2118,6 +2110,9 @@ "store2": "^2.12.0" } }, + "node_modules/@injectivelabs/utils/dist": { + "extraneous": true + }, "node_modules/@injectivelabs/utils/node_modules/axios": { "version": "0.21.4", "license": "MIT", @@ -2569,6 +2564,105 @@ "rlp": "^2.2.3" } }, + "node_modules/@mysten/bcs": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@mysten/bcs/-/bcs-0.7.1.tgz", + "integrity": "sha512-wFPb8bkhwrbiStfZMV5rFM7J+umpke59/dNjDp+UYJKykNlW23LCk2ePyEUvGdb62HGJM1jyOJ8g4egE3OmdKA==", + "dependencies": { + "bs58": "^5.0.0" + } + }, + "node_modules/@mysten/bcs/node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, + "node_modules/@mysten/bcs/node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/@mysten/sui.js": { + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.32.2.tgz", + "integrity": "sha512-/Hm4xkGolJhqj8FvQr7QSHDTlxIvL52mtbOao9f75YjrBh7y1Uh9kbJSY7xiTF1NY9sv6p5hUVlYRJuM0Hvn9A==", + "dependencies": { + "@mysten/bcs": "0.7.1", + "@noble/curves": "^1.0.0", + "@noble/hashes": "^1.3.0", + "@scure/bip32": "^1.3.0", + "@scure/bip39": "^1.2.0", + "@suchipi/femver": "^1.0.0", + "jayson": "^4.0.0", + "rpc-websockets": "^7.5.1", + "superstruct": "^1.0.3", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@mysten/sui.js/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/@mysten/sui.js/node_modules/jayson": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jayson/-/jayson-4.1.0.tgz", + "integrity": "sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==", + "dependencies": { + "@types/connect": "^3.4.33", + "@types/node": "^12.12.54", + "@types/ws": "^7.4.4", + "commander": "^2.20.3", + "delay": "^5.0.0", + "es6-promisify": "^5.0.0", + "eyes": "^0.1.8", + "isomorphic-ws": "^4.0.1", + "json-stringify-safe": "^5.0.1", + "JSONStream": "^1.3.5", + "uuid": "^8.3.2", + "ws": "^7.4.5" + }, + "bin": { + "jayson": "bin/jayson.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@mysten/sui.js/node_modules/superstruct": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.3.tgz", + "integrity": "sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@mysten/sui.js/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/@noble/curves": { "version": "1.2.0", "license": "MIT", @@ -2724,8 +2818,56 @@ "license": "BSD-3-Clause" }, "node_modules/@scure/base": { - "version": "1.1.3", - "license": "MIT", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", + "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", + "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", + "dependencies": { + "@noble/curves": "~1.3.0", + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", + "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", + "dependencies": { + "@noble/hashes": "~1.3.2", + "@scure/base": "~1.1.4" + }, "funding": { "url": "https://paulmillr.com/funding/" } @@ -2839,6 +2981,11 @@ "version": "0.14.2", "license": "MIT" }, + "node_modules/@suchipi/femver": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@suchipi/femver/-/femver-1.0.0.tgz", + "integrity": "sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "dev": true, @@ -3119,6 +3266,18 @@ "resolved": "platforms/solana/protocols/tokenBridge", "link": true }, + "node_modules/@wormhole-foundation/connect-sdk-sui": { + "resolved": "platforms/sui", + "link": true + }, + "node_modules/@wormhole-foundation/connect-sdk-sui-core": { + "resolved": "platforms/sui/protocols/core", + "link": true + }, + "node_modules/@wormhole-foundation/connect-sdk-sui-tokenbridge": { + "resolved": "platforms/sui/protocols/tokenBridge", + "link": true + }, "node_modules/@wormhole-foundation/sdk-base": { "resolved": "core/base", "link": true @@ -4358,9 +4517,8 @@ }, "node_modules/dotenv": { "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -8786,52 +8944,6 @@ "zen-observable": "0.8.15" } }, - "platforms/aptos": { - "name": "@wormhole-foundation/connect-sdk-aptos", - "version": "0.2.6", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@wormhole-foundation/connect-sdk": "^0.2.6", - "aptos": "1.5.0" - }, - "engines": { - "node": ">=16" - } - }, - "platforms/aptos/protocols/core": { - "name": "@wormhole-foundation/connect-sdk-aptos-core", - "version": "0.2.6", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@wormhole-foundation/connect-sdk": "^0.2.6", - "@wormhole-foundation/connect-sdk-aptos": "^0.2.6" - }, - "devDependencies": { - "nock": "^13.3.3" - }, - "engines": { - "node": ">=16" - } - }, - "platforms/aptos/protocols/tokenBridge": { - "name": "@wormhole-foundation/connect-sdk-aptos-tokenbridge", - "version": "0.2.6", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@wormhole-foundation/connect-sdk": "^0.2.6", - "@wormhole-foundation/connect-sdk-solana": "^0.2.6", - "@wormhole-foundation/connect-sdk-solana-core": "^0.2.6" - }, - "devDependencies": { - "nock": "^13.3.3" - }, - "engines": { - "node": ">=16" - } - }, "platforms/cosmwasm": { "name": "@wormhole-foundation/connect-sdk-cosmwasm", "version": "0.3.0-beta.3", @@ -9093,21 +9205,40 @@ "node": ">=16" } }, - "tokenRegistry": { - "name": "@wormhole-foundation/sdk-token-registry", - "version": "0.2.6-beta.1", - "extraneous": true, - "dependencies": { - "@wormhole-foundation/connect-sdk": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-cosmwasm-tokenbridge": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-evm-tokenbridge": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana-core": "^0.2.6-beta.1", - "@wormhole-foundation/connect-sdk-solana-tokenbridge": "^0.2.6-beta.1" + "platforms/sui": { + "name": "@wormhole-foundation/connect-sdk-sui", + "version": "0.3.0-beta.3", + "license": "Apache-2.0", + "dependencies": { + "@mysten/sui.js": "^0.32.2", + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3" + }, + "engines": { + "node": ">=16" + } + }, + "platforms/sui/protocols/core": { + "name": "@wormhole-foundation/connect-sdk-sui-core", + "version": "0.3.0-beta.3", + "license": "Apache-2.0", + "dependencies": { + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3", + "@wormhole-foundation/connect-sdk-sui": "^0.3.0-beta.3" + }, + "engines": { + "node": ">=16" + } + }, + "platforms/sui/protocols/tokenBridge": { + "name": "@wormhole-foundation/connect-sdk-sui-tokenbridge", + "version": "0.3.0-beta.3", + "license": "Apache-2.0", + "dependencies": { + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3", + "@wormhole-foundation/connect-sdk-sui": "^0.3.0-beta.3" + }, + "engines": { + "node": ">=16" } } } diff --git a/package.json b/package.json index 659b5fd4f3..534199357b 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,12 @@ "core/base", "core/definitions", "connect", + "platforms/sui", + "platforms/sui/protocols/core", + "platforms/sui/protocols/tokenBridge", + "examples" + ], + "nothing": [ "platforms/evm", "platforms/evm/protocols/core", "platforms/evm/protocols/tokenBridge", @@ -54,13 +60,9 @@ "platforms/cosmwasm/protocols/core", "platforms/cosmwasm/protocols/tokenBridge", "platforms/cosmwasm/protocols/ibc", - "examples" - ], - "unreleased": [ - "tokenRegistry", - "examples", "platforms/aptos", "platforms/aptos/protocols/core", - "platforms/aptos/protocols/tokenBridge" + "platforms/aptos/protocols/tokenBridge", + "tokenRegistry" ] } \ No newline at end of file diff --git a/platforms/sui/eslintrc.json b/platforms/sui/eslintrc.json new file mode 100644 index 0000000000..94b97befc8 --- /dev/null +++ b/platforms/sui/eslintrc.json @@ -0,0 +1,20 @@ +{ + "env": { + "node": true + }, + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "rules": { + "comma-dangle": ["error", "always-multiline"], + "semi": ["error", "always"], + "@typescript-eslint/explicit-module-boundary-types": ["error"], + "@typescript-eslint/no-non-null-assertion": ["error"], + "@typescript-eslint/no-explicit-any": ["error", { "ignoreRestArgs": true }] + } +} diff --git a/platforms/sui/package.json b/platforms/sui/package.json new file mode 100644 index 0000000000..60ec440c15 --- /dev/null +++ b/platforms/sui/package.json @@ -0,0 +1,48 @@ +{ + "name": "@wormhole-foundation/connect-sdk-sui", + "version": "0.3.0-beta.3", + "repository": { + "type": "git", + "url": "git+https://github.com/wormhole-foundation/connect-sdk.git" + }, + "bugs": { + "url": "https://github.com/wormhole-foundation/connect-sdk/issues" + }, + "homepage": "https://github.com/wormhole-foundation/connect-sdk#readme", + "directories": { + "test": "tests" + }, + "license": "Apache-2.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/esm/index.d.ts", + "author": "", + "description": "SDK for EVM chains, used in conjunction with @wormhole-foundation/connect-sdk", + "files": [ + "dist/**/*" + ], + "keywords": [ + "wormhole", + "sdk", + "typescript", + "connect", + "sui" + ], + "engines": { + "node": ">=16" + }, + "sideEffects": false, + "scripts": { + "build:cjs": "tsc -p ./tsconfig.cjs.json", + "build:esm": "tsc -p ./tsconfig.esm.json", + "build": "npm run build:cjs && npm run build:esm", + "rebuild": "npm run clean && npm run build:cjs && npm run build:esm", + "clean": "rm -rf ./dist && rm -f ./*.tsbuildinfo", + "lint": "npm run prettier && eslint --fix", + "prettier": "prettier --write ./src" + }, + "dependencies": { + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3", + "@mysten/sui.js": "^0.32.2" + } +} \ No newline at end of file diff --git a/platforms/sui/protocols/core/package.json b/platforms/sui/protocols/core/package.json new file mode 100644 index 0000000000..e02ace87e7 --- /dev/null +++ b/platforms/sui/protocols/core/package.json @@ -0,0 +1,48 @@ +{ + "name": "@wormhole-foundation/connect-sdk-sui-core", + "version": "0.3.0-beta.3", + "repository": { + "type": "git", + "url": "git+https://github.com/wormhole-foundation/connect-sdk.git" + }, + "bugs": { + "url": "https://github.com/wormhole-foundation/connect-sdk/issues" + }, + "homepage": "https://github.com/wormhole-foundation/connect-sdk#readme", + "directories": { + "test": "tests" + }, + "license": "Apache-2.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/esm/index.d.ts", + "author": "", + "description": "SDK for Sui chains, used in conjunction with @wormhole-foundation/connect-sdk", + "files": [ + "dist/**/*" + ], + "keywords": [ + "wormhole", + "sdk", + "typescript", + "connect", + "sui" + ], + "engines": { + "node": ">=16" + }, + "sideEffects": false, + "scripts": { + "build:cjs": "tsc -p ./tsconfig.cjs.json", + "build:esm": "tsc -p ./tsconfig.esm.json", + "build": "npm run build:cjs && npm run build:esm", + "rebuild": "npm run clean && npm run build:cjs && npm run build:esm", + "clean": "rm -rf ./dist && rm -f ./*.tsbuildinfo", + "lint": "npm run prettier && eslint --fix", + "prettier": "prettier --write ./src" + }, + "dependencies": { + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3", + "@wormhole-foundation/connect-sdk-sui": "^0.3.0-beta.3" + } +} \ No newline at end of file diff --git a/platforms/sui/protocols/core/src/core.ts b/platforms/sui/protocols/core/src/core.ts new file mode 100644 index 0000000000..5af3229034 --- /dev/null +++ b/platforms/sui/protocols/core/src/core.ts @@ -0,0 +1,69 @@ +import { JsonRpcProvider } from "@mysten/sui.js"; +import { + AccountAddress, + ChainId, + ChainsConfig, + Contracts, + Network, + PayloadLiteral, + VAA, + WormholeCore, + WormholeMessageId, + toChainId, +} from "@wormhole-foundation/connect-sdk"; +import { + AnySuiAddress, + SuiChains, + SuiPlatform, + SuiPlatformType, + SuiUnsignedTransaction, +} from "@wormhole-foundation/connect-sdk-sui"; + +export class SuiWormholeCore + implements WormholeCore +{ + readonly chainId: ChainId; + readonly coreBridge: string; + + private constructor( + readonly network: N, + readonly chain: C, + readonly connection: JsonRpcProvider, + readonly contracts: Contracts, + ) { + this.chainId = toChainId(chain); + const coreBridgeAddress = contracts.coreBridge; + if (!coreBridgeAddress) + throw new Error(`CoreBridge contract Address for chain ${chain} not found`); + this.coreBridge = coreBridgeAddress; + } + + static async fromRpc( + connection: JsonRpcProvider, + config: ChainsConfig, + ) { + const [network, chain] = await SuiPlatform.chainFromRpc(connection); + const conf = config[chain]!; + if (conf.network !== network) + throw new Error(`Network mismatch: ${conf.network} !== ${network}`); + return new SuiWormholeCore(network as N, chain, connection, conf.contracts); + } + + async *verifyMessage( + sender: AccountAddress, + vaa: VAA, + ): AsyncGenerator> { + throw new Error("Method not implemented."); + } + + async *publishMessage( + sender: AnySuiAddress, + message: string | Uint8Array, + ): AsyncGenerator> { + throw new Error("Method not implemented."); + } + + async parseTransaction(txid: string): Promise { + throw new Error("Not implemented"); + } +} diff --git a/platforms/sui/protocols/core/src/index.ts b/platforms/sui/protocols/core/src/index.ts new file mode 100644 index 0000000000..32641c6fac --- /dev/null +++ b/platforms/sui/protocols/core/src/index.ts @@ -0,0 +1,15 @@ +import { _platform } from "@wormhole-foundation/connect-sdk-sui"; +import { registerProtocol } from "@wormhole-foundation/connect-sdk"; +import { SuiWormholeCore } from "./core"; + +declare global { + namespace WormholeNamespace { + export interface PlatformToProtocolMapping { + Sui: {}; + } + } +} + +registerProtocol(_platform, "WormholeCore", SuiWormholeCore); + +export * from "./core"; diff --git a/platforms/sui/protocols/core/tsconfig.cjs.json b/platforms/sui/protocols/core/tsconfig.cjs.json new file mode 100644 index 0000000000..73a0e681f1 --- /dev/null +++ b/platforms/sui/protocols/core/tsconfig.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.cjs.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/cjs", + "rootDir": "src" + } +} diff --git a/platforms/sui/protocols/core/tsconfig.esm.json b/platforms/sui/protocols/core/tsconfig.esm.json new file mode 100644 index 0000000000..a9c110d372 --- /dev/null +++ b/platforms/sui/protocols/core/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.esm.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/esm", + "rootDir": "src" + } +} diff --git a/platforms/sui/protocols/core/typedoc.json b/platforms/sui/protocols/core/typedoc.json new file mode 100644 index 0000000000..f2fbd427cc --- /dev/null +++ b/platforms/sui/protocols/core/typedoc.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../../../typedoc.base.json"], + "entryPoints": ["src/index.ts"], + } \ No newline at end of file diff --git a/platforms/sui/protocols/tokenBridge/package.json b/platforms/sui/protocols/tokenBridge/package.json new file mode 100644 index 0000000000..d8c98f7d6a --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/package.json @@ -0,0 +1,48 @@ +{ + "name": "@wormhole-foundation/connect-sdk-sui-tokenbridge", + "version": "0.3.0-beta.3", + "repository": { + "type": "git", + "url": "git+https://github.com/wormhole-foundation/connect-sdk.git" + }, + "bugs": { + "url": "https://github.com/wormhole-foundation/connect-sdk/issues" + }, + "homepage": "https://github.com/wormhole-foundation/connect-sdk#readme", + "directories": { + "test": "tests" + }, + "license": "Apache-2.0", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.js", + "types": "./dist/esm/index.d.ts", + "author": "", + "description": "SDK for Sui chains, used in conjunction with @wormhole-foundation/connect-sdk", + "files": [ + "dist/**/*" + ], + "keywords": [ + "wormhole", + "sdk", + "typescript", + "connect", + "sui" + ], + "engines": { + "node": ">=16" + }, + "sideEffects": false, + "scripts": { + "build:cjs": "tsc -p ./tsconfig.cjs.json", + "build:esm": "tsc -p ./tsconfig.esm.json", + "build": "npm run build:cjs && npm run build:esm", + "rebuild": "npm run clean && npm run build:cjs && npm run build:esm", + "clean": "rm -rf ./dist && rm -f ./*.tsbuildinfo", + "lint": "npm run prettier && eslint --fix", + "prettier": "prettier --write ./src" + }, + "dependencies": { + "@wormhole-foundation/connect-sdk": "^0.3.0-beta.3", + "@wormhole-foundation/connect-sdk-sui": "^0.3.0-beta.3" + } +} \ No newline at end of file diff --git a/platforms/sui/protocols/tokenBridge/src/index.ts b/platforms/sui/protocols/tokenBridge/src/index.ts new file mode 100644 index 0000000000..da933f2edf --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/src/index.ts @@ -0,0 +1,15 @@ +import { _platform } from "@wormhole-foundation/connect-sdk-sui"; +import { registerProtocol } from "@wormhole-foundation/connect-sdk"; +import { SuiTokenBridge } from "./tokenBridge"; + +declare global { + namespace WormholeNamespace { + export interface PlatformToProtocolMapping { + Sui: {}; + } + } +} + +registerProtocol(_platform, "TokenBridge", SuiTokenBridge); + +export * from "./tokenBridge"; diff --git a/platforms/sui/protocols/tokenBridge/src/tokenBridge.ts b/platforms/sui/protocols/tokenBridge/src/tokenBridge.ts new file mode 100644 index 0000000000..40ba4e312c --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/src/tokenBridge.ts @@ -0,0 +1,159 @@ +import { JsonRpcProvider, SUI_CLOCK_OBJECT_ID, TransactionBlock } from "@mysten/sui.js"; +import { + AccountAddress, + Chain, + ChainAddress, + ChainsConfig, + Contracts, + NativeAddress, + Network, + Platform, + TokenAddress, + TokenBridge, + TokenId, + nativeChainIds, +} from "@wormhole-foundation/connect-sdk"; + +import { + SuiChains, + SuiPlatform, + SuiPlatformType, + SuiUnsignedTransaction, +} from "@wormhole-foundation/connect-sdk-sui"; + +export class SuiTokenBridge + implements TokenBridge +{ + readonly coreBridgePackageId: string; + readonly tokenBridgePackageId: string; + readonly chainId: bigint; + + private constructor( + readonly network: N, + readonly chain: C, + readonly provider: JsonRpcProvider, + readonly contracts: Contracts, + ) { + this.chainId = nativeChainIds.networkChainToNativeChainId.get(network, chain) as bigint; + + const tokenBridgeAddress = this.contracts.tokenBridge!; + if (!tokenBridgeAddress) + throw new Error(`Wormhole Token Bridge contract for domain ${chain} not found`); + + const coreBridgeAddress = this.contracts.coreBridge!; + if (!coreBridgeAddress) + throw new Error(`Wormhole Token Bridge contract for domain ${chain} not found`); + + this.tokenBridgePackageId = tokenBridgeAddress; + this.coreBridgePackageId = coreBridgeAddress; + } + + static async fromRpc( + provider: JsonRpcProvider, + config: ChainsConfig, + ): Promise> { + const [network, chain] = await SuiPlatform.chainFromRpc(provider); + + const conf = config[chain]!; + if (conf.network !== network) + throw new Error(`Network mismatch: ${conf.network} != ${network}`); + + return new SuiTokenBridge(network as N, chain, provider, conf.contracts); + } + + async isWrappedAsset(token: TokenAddress): Promise { + throw new Error("Not implemented"); + } + + async getOriginalAsset(token: TokenAddress): Promise { + throw new Error("Not implemented"); + } + + async hasWrappedAsset(token: TokenId): Promise { + try { + await this.getWrappedAsset(token); + return true; + } catch (e) {} + return false; + } + + async getWrappedAsset(token: TokenId): Promise> { + throw new Error("Not implemented"); + } + + async isTransferCompleted( + vaa: TokenBridge.VAA<"Transfer" | "TransferWithPayload">, + ): Promise { + throw new Error("Not implemented"); + } + + async *createAttestation(token: TokenAddress): AsyncGenerator> { + const feeAmount = 0n; + const nonce = 0n; + const coinType = token.toString(); + + const tokenBridgeStateObjectId = "todo"; + const coreBridgeStateObjectId = "todo"; + + const metadata = await this.provider.getCoinMetadata({ coinType }); + + if (metadata === null || metadata.id === null) + throw new Error(`Coin metadata ID for type ${coinType} not found`); + + const tx = new TransactionBlock(); + const [feeCoin] = tx.splitCoins(tx.gas, [tx.pure(feeAmount)]); + const [messageTicket] = tx.moveCall({ + target: `${this.tokenBridgePackageId}::attest_token::attest_token`, + arguments: [tx.object(tokenBridgeStateObjectId), tx.object(metadata.id), tx.pure(nonce)], + typeArguments: [coinType], + }); + tx.moveCall({ + target: `${this.coreBridgePackageId}::publish_message::publish_message`, + arguments: [ + tx.object(coreBridgeStateObjectId), + feeCoin!, + messageTicket!, + tx.object(SUI_CLOCK_OBJECT_ID), + ], + }); + + yield this.createUnsignedTx(tx, "Sui.CreateAttestation"); + } + + async *submitAttestation( + vaa: TokenBridge.VAA<"AttestMeta">, + ): AsyncGenerator> { + throw new Error("Not implemented"); + } + + async *transfer( + sender: AccountAddress, + recipient: ChainAddress, + token: TokenAddress, + amount: bigint, + payload?: Uint8Array, + ): AsyncGenerator> { + throw new Error("Not implemented"); + } + + async *redeem( + sender: AccountAddress, + vaa: TokenBridge.VAA<"Transfer" | "TransferWithPayload">, + unwrapNative: boolean = true, + ): AsyncGenerator> { + throw new Error("Not implemented"); + } + + async getWrappedNative(): Promise> { + throw new Error("Not implemented"); + } + + // @ts-ignore + private createUnsignedTx( + txReq: TransactionBlock, + description: string, + parallelizable: boolean = false, + ): SuiUnsignedTransaction { + throw new Error("Not implemented"); + } +} diff --git a/platforms/sui/protocols/tokenBridge/tsconfig.cjs.json b/platforms/sui/protocols/tokenBridge/tsconfig.cjs.json new file mode 100644 index 0000000000..73a0e681f1 --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/tsconfig.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.cjs.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/cjs", + "rootDir": "src" + } +} diff --git a/platforms/sui/protocols/tokenBridge/tsconfig.esm.json b/platforms/sui/protocols/tokenBridge/tsconfig.esm.json new file mode 100644 index 0000000000..a9c110d372 --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.esm.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/esm", + "rootDir": "src" + } +} diff --git a/platforms/sui/protocols/tokenBridge/typedoc.json b/platforms/sui/protocols/tokenBridge/typedoc.json new file mode 100644 index 0000000000..f2fbd427cc --- /dev/null +++ b/platforms/sui/protocols/tokenBridge/typedoc.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../../../typedoc.base.json"], + "entryPoints": ["src/index.ts"], + } \ No newline at end of file diff --git a/platforms/sui/src/address.ts b/platforms/sui/src/address.ts new file mode 100644 index 0000000000..f12c018aab --- /dev/null +++ b/platforms/sui/src/address.ts @@ -0,0 +1,59 @@ +import { Address, UniversalAddress, registerNative } from "@wormhole-foundation/connect-sdk"; + +import { SuiPlatform } from "./platform"; +import { _platform, AnySuiAddress } from "./types"; +import { isValidSuiAddress } from "@mysten/sui.js"; + +export class SuiAddress implements Address { + static readonly byteSize = 32; + + // stored as checksum address + private readonly address: string; + + constructor(address: AnySuiAddress) { + this.address = "TODO"; + // + } + + unwrap(): string { + return this.address; + } + toString() { + return this.address; + } + toNative() { + return this; + } + toUint8Array() { + return new Uint8Array(); + } + toUniversalAddress() { + return new UniversalAddress(this.address); + } + + static isValidAddress(address: string) { + return isValidSuiAddress(address); + } + + static instanceof(address: any): address is SuiAddress { + return address.platform === SuiPlatform._platform; + } + equals(other: SuiAddress | UniversalAddress): boolean { + if (SuiAddress.instanceof(other)) { + return other.address === this.address; + } else { + return other.equals(this.toUniversalAddress()); + } + } +} + +declare global { + namespace Wormhole { + interface PlatformToNativeAddressMapping { + // @ts-ignore + Sui: SuiAddress; + } + } +} + +registerNative(_platform, SuiAddress); diff --git a/platforms/sui/src/chain.ts b/platforms/sui/src/chain.ts new file mode 100644 index 0000000000..11d26aab27 --- /dev/null +++ b/platforms/sui/src/chain.ts @@ -0,0 +1,7 @@ +import { Chain, ChainContext, Network } from "@wormhole-foundation/connect-sdk"; +import { SuiChains, SuiPlatformType } from "./types"; + +export class SuiChain< + N extends Network = Network, + C extends Chain = SuiChains, +> extends ChainContext {} diff --git a/platforms/sui/src/index.ts b/platforms/sui/src/index.ts new file mode 100644 index 0000000000..f3da4f124c --- /dev/null +++ b/platforms/sui/src/index.ts @@ -0,0 +1,7 @@ +export * from './address'; +export * from './unsignedTransaction'; +export * from './platform'; +export * from './types'; +export * from './chain'; + +export * as testing from './testing'; diff --git a/platforms/sui/src/platform.ts b/platforms/sui/src/platform.ts new file mode 100644 index 0000000000..811dd30e21 --- /dev/null +++ b/platforms/sui/src/platform.ts @@ -0,0 +1,134 @@ +import { + Balances, + Chain, + ChainsConfig, + Network, + PlatformContext, + ProtocolInitializer, + ProtocolName, + SignedTx, + TokenId, + TxHash, + WormholeCore, + WormholeMessageId, + chainToPlatform, + getProtocolInitializer, + nativeChainIds, + networkPlatformConfigs, +} from "@wormhole-foundation/connect-sdk"; + +import { Connection, JsonRpcProvider } from "@mysten/sui.js"; +import { SuiChain } from "./chain"; +import { AnySuiAddress, SuiChains, SuiPlatformType, _platform } from "./types"; + +/** + * @category Sui + */ + +export class SuiPlatform extends PlatformContext { + static _platform: SuiPlatformType = _platform; + + constructor(network: N, _config?: ChainsConfig) { + super(network, _config ?? networkPlatformConfigs(network, SuiPlatform._platform)); + } + + getRpc(chain: C): JsonRpcProvider { + if (chain in this.config) + return new JsonRpcProvider(new Connection({ fullnode: this.config[chain]!.rpc })); + throw new Error("No configuration available for chain: " + chain); + } + + getChain(chain: C): SuiChain { + if (chain in this.config) return new SuiChain(chain, this); + throw new Error("No configuration available for chain: " + chain); + } + + async parseTransaction( + chain: C, + rpc: JsonRpcProvider, + txid: TxHash, + ): Promise { + const wc: WormholeCore = await this.getProtocol("WormholeCore", rpc); + return wc.parseTransaction(txid); + } + + static nativeTokenId(network: N, chain: C): TokenId { + if (!SuiPlatform.isSupportedChain(chain)) + throw new Error(`invalid chain for ${_platform}: ${chain}`); + throw new Error("Not implemented"); + } + + static isNativeTokenId( + network: N, + chain: C, + tokenId: TokenId, + ): boolean { + if (!SuiPlatform.isSupportedChain(chain)) return false; + if (tokenId.chain !== chain) return false; + throw new Error("Not implemented"); + } + + static isSupportedChain(chain: Chain): boolean { + const platform = chainToPlatform(chain); + return platform === SuiPlatform._platform; + } + + static async getDecimals( + chain: Chain, + rpc: JsonRpcProvider, + token: AnySuiAddress | "native", + ): Promise { + throw new Error("Not implemented"); + } + + static async getBalance( + chain: Chain, + rpc: JsonRpcProvider, + walletAddr: string, + token: AnySuiAddress | "native", + ): Promise { + throw new Error("Not implemented"); + } + + static async getBalances( + chain: Chain, + rpc: JsonRpcProvider, + walletAddr: string, + tokens: (AnySuiAddress | "native")[], + ): Promise { + throw new Error("Not implemented"); + } + + static async sendWait(chain: Chain, rpc: JsonRpcProvider, stxns: SignedTx[]): Promise { + throw new Error("Not implemented"); + } + + static async getLatestBlock(rpc: JsonRpcProvider): Promise { + throw new Error("Not implemented"); + } + static async getLatestFinalizedBlock(rpc: JsonRpcProvider): Promise { + throw new Error("Not implemented"); + } + + static chainFromChainId(genesisHash: string): [Network, SuiChains] { + const networkChainPair = nativeChainIds.platformNativeChainIdToNetworkChain( + SuiPlatform._platform, + genesisHash, + ); + + if (networkChainPair === undefined) throw new Error(`Unknown native chain id ${genesisHash}`); + + const [network, chain] = networkChainPair; + return [network, chain]; + } + + static async chainFromRpc(rpc: JsonRpcProvider): Promise<[Network, SuiChains]> { + throw new Error("Not implemented"); + } + + static getProtocolInitializer( + protocol: PN, + ): ProtocolInitializer { + return getProtocolInitializer(this._platform, protocol); + } +} diff --git a/platforms/sui/src/testing/index.ts b/platforms/sui/src/testing/index.ts new file mode 100644 index 0000000000..5282af6850 --- /dev/null +++ b/platforms/sui/src/testing/index.ts @@ -0,0 +1 @@ +export * from "./signer"; diff --git a/platforms/sui/src/testing/signer.ts b/platforms/sui/src/testing/signer.ts new file mode 100644 index 0000000000..e60f27ee72 --- /dev/null +++ b/platforms/sui/src/testing/signer.ts @@ -0,0 +1,36 @@ +import { + Chain, + Network, + SignOnlySigner, + SignedTx, + Signer, + UnsignedTransaction, +} from "@wormhole-foundation/connect-sdk"; +import { JsonRpcProvider } from "@mysten/sui.js"; +import { SuiPlatform } from "../platform"; + +export async function getSuiSigner(rpc: JsonRpcProvider, privateKey: string): Promise { + const [network, chain] = await SuiPlatform.chainFromRpc(rpc); + return new SuiSigner(chain, rpc, privateKey); +} + +// SuiSigner implements SignOnlySender +export class SuiSigner implements SignOnlySigner { + constructor( + private _chain: C, + _rpc: JsonRpcProvider, + privateKey: string, + ) {} + + chain(): C { + return this._chain; + } + + address(): string { + return ""; + } + + async sign(tx: UnsignedTransaction[]): Promise { + throw new Error("Not implemented"); + } +} diff --git a/platforms/sui/src/types.ts b/platforms/sui/src/types.ts new file mode 100644 index 0000000000..17ddbe89a2 --- /dev/null +++ b/platforms/sui/src/types.ts @@ -0,0 +1,8 @@ +import { PlatformToChains, UniversalOrNative } from "@wormhole-foundation/connect-sdk"; + +export const _platform: "Sui" = "Sui"; +export type SuiPlatformType = typeof _platform; + +export type SuiChains = PlatformToChains; +export type UniversalOrSui = UniversalOrNative; +export type AnySuiAddress = UniversalOrSui | string | Uint8Array; diff --git a/platforms/sui/src/unsignedTransaction.ts b/platforms/sui/src/unsignedTransaction.ts new file mode 100644 index 0000000000..2e5f3658bb --- /dev/null +++ b/platforms/sui/src/unsignedTransaction.ts @@ -0,0 +1,15 @@ +import { Network, UnsignedTransaction } from "@wormhole-foundation/connect-sdk"; +import { TransactionBlock } from "@mysten/sui.js"; +import { SuiChains } from "./types"; + +export class SuiUnsignedTransaction + implements UnsignedTransaction +{ + constructor( + readonly transaction: TransactionBlock, + readonly network: N, + readonly chain: C, + readonly description: string, + readonly parallelizable: boolean = false, + ) {} +} diff --git a/platforms/sui/tsconfig.cjs.json b/platforms/sui/tsconfig.cjs.json new file mode 100644 index 0000000000..b5ef75178b --- /dev/null +++ b/platforms/sui/tsconfig.cjs.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.cjs.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/cjs", + "rootDir": "src" + } +} diff --git a/platforms/sui/tsconfig.esm.json b/platforms/sui/tsconfig.esm.json new file mode 100644 index 0000000000..84bbdce2d1 --- /dev/null +++ b/platforms/sui/tsconfig.esm.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.esm.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist/esm", + "rootDir": "src" + } +} diff --git a/platforms/sui/typedoc.json b/platforms/sui/typedoc.json new file mode 100644 index 0000000000..e12797d62a --- /dev/null +++ b/platforms/sui/typedoc.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../typedoc.base.json"], + "entryPoints": ["src/index.ts"], + } \ No newline at end of file