├── .prettierignore ├── src ├── provider │ ├── types │ │ ├── index.ts │ │ └── vm.ts │ ├── websocket │ │ ├── index.ts │ │ └── ws.ts │ ├── jsonrpc │ │ ├── index.ts │ │ └── jsonrpc.ts │ ├── utility │ │ ├── index.ts │ │ └── provider.utility.ts │ ├── endpoints.ts │ ├── index.ts │ └── provider.ts ├── wallet │ ├── utility │ │ ├── index.ts │ │ └── utility.ts │ ├── index.ts │ ├── endpoints.ts │ └── wallet.ts ├── index.ts ├── proto │ ├── index.ts │ ├── gno │ │ ├── bank.ts │ │ └── vm.ts │ └── google │ │ └── protobuf │ │ ├── any.ts │ │ └── struct.ts └── __tests__ │ └── e2e.ts ├── .yarnrc.yml ├── jest.config.json ├── .prettierrc ├── .gitignore ├── .github ├── CODEOWNERS ├── workflows │ ├── main.yaml │ ├── lint.yaml │ └── test.yaml └── dependabot.yaml ├── proto └── gno │ ├── bank.proto │ └── vm.proto ├── tsconfig.json ├── eslint.config.mjs ├── scripts └── generate.sh ├── README.md ├── package.json └── LICENSE.md /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bin 3 | yarn.lock -------------------------------------------------------------------------------- /src/provider/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './vm'; 2 | -------------------------------------------------------------------------------- /src/provider/websocket/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ws'; 2 | -------------------------------------------------------------------------------- /src/wallet/utility/index.ts: -------------------------------------------------------------------------------- 1 | export * from './utility'; 2 | -------------------------------------------------------------------------------- /src/provider/jsonrpc/index.ts: -------------------------------------------------------------------------------- 1 | export * from './jsonrpc'; 2 | -------------------------------------------------------------------------------- /src/provider/utility/index.ts: -------------------------------------------------------------------------------- 1 | export * from './provider.utility'; 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './proto'; 2 | export * from './provider'; 3 | export * from './wallet'; 4 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | -------------------------------------------------------------------------------- /src/wallet/index.ts: -------------------------------------------------------------------------------- 1 | export * from './endpoints'; 2 | export * from './wallet'; 3 | export * from './utility'; 4 | -------------------------------------------------------------------------------- /jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "ts-jest", 3 | "testEnvironment": "node", 4 | "modulePathIgnorePatterns": ["bin", "node_modules"] 5 | } 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "bracketSpacing": true, 6 | "singleQuote": true 7 | } 8 | -------------------------------------------------------------------------------- /src/provider/endpoints.ts: -------------------------------------------------------------------------------- 1 | export enum VMEndpoint { 2 | RENDER = 'qrender', 3 | FUNCTION_SIGNATURES = 'qfuncs', 4 | EVALUATE = 'qeval', 5 | FILE_CONTENT = 'qfile', 6 | } 7 | -------------------------------------------------------------------------------- /src/proto/index.ts: -------------------------------------------------------------------------------- 1 | export { MsgSend } from './gno/bank'; 2 | export { MemFile, MemPackage, MsgAddPackage, MsgCall, MsgRun } from './gno/vm'; 3 | export { Any } from './google/protobuf/any'; 4 | -------------------------------------------------------------------------------- /src/wallet/endpoints.ts: -------------------------------------------------------------------------------- 1 | export enum MsgEndpoint { 2 | MSG_SEND = '/bank.MsgSend', 3 | MSG_ADD_PKG = '/vm.m_addpkg', 4 | MSG_CALL = '/vm.m_call', 5 | MSG_RUN = '/vm.m_run', 6 | } 7 | -------------------------------------------------------------------------------- /src/provider/index.ts: -------------------------------------------------------------------------------- 1 | export * from './jsonrpc'; 2 | export * from './types'; 3 | export * from './utility'; 4 | export * from './websocket'; 5 | export * from './endpoints'; 6 | export * from './provider'; 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules 3 | 4 | # Build files 5 | bin 6 | 7 | # Dev environment metadata 8 | .idea 9 | .DS_Store 10 | *.log 11 | 12 | # Yarn leftovers 13 | .yarn/cache 14 | .pnp.* 15 | .yarn/install-state.gz 16 | .yarn/unplugged -------------------------------------------------------------------------------- /src/provider/types/vm.ts: -------------------------------------------------------------------------------- 1 | export interface FunctionSignature { 2 | FuncName: string; 3 | Params: NamedType[]; 4 | Results: NamedType[]; 5 | } 6 | 7 | export interface NamedType { 8 | Name: string; 9 | Type: string; 10 | Value: string; 11 | } 12 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS: https://help.github.com/articles/about-codeowners/ 2 | 3 | # Primary repo maintainers 4 | * @zivkovicmilos 5 | 6 | # Special files 7 | LICENSE.md @jaekwon @moul 8 | .github/CODEOWNERS @jaekwon @moul -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | 7 | jobs: 8 | lint: 9 | name: Linter 10 | uses: ./.github/workflows/lint.yaml 11 | 12 | test: 13 | name: Tests 14 | uses: ./.github/workflows/test.yaml 15 | -------------------------------------------------------------------------------- /proto/gno/bank.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package gno.bank; 4 | 5 | // MsgSend is the fund transfer tx message 6 | message MsgSend { 7 | // the bech32 address of the fund sender 8 | string from_address = 1; 9 | // the bech32 address of the fund receiver 10 | string to_address = 2; 11 | // the denomination and amount of fund sent ("") 12 | string amount = 3; 13 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "outDir": "./bin", 7 | "rootDir": "./src", 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "declaration": true, 13 | "strictPropertyInitialization": false 14 | }, 15 | "include": ["./src/**/*.ts"], 16 | "exclude": ["./node_modules"] 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout code 10 | uses: actions/checkout@v5 11 | 12 | - name: Cache dependencies 13 | uses: actions/cache@v4 14 | with: 15 | path: ~/.yarn 16 | key: yarn-${{ hashFiles('yarn.lock') }} 17 | restore-keys: yarn- 18 | 19 | - name: Install modules 20 | run: yarn install 21 | 22 | - name: ESLint 23 | run: ./node_modules/.bin/eslint '**/*.ts' --fix 24 | 25 | - name: Prettier 26 | run: ./node_modules/.bin/prettier --check . 27 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from 'globals'; 2 | import pluginJs from '@eslint/js'; 3 | import tsEslint from 'typescript-eslint'; 4 | import tsParser from '@typescript-eslint/parser'; 5 | import eslintConfigPrettier from 'eslint-config-prettier'; 6 | 7 | export default [ 8 | eslintConfigPrettier, 9 | pluginJs.configs.recommended, 10 | ...tsEslint.configs.recommended, 11 | { 12 | ignores: ['bin/**/*'], 13 | }, 14 | { 15 | languageOptions: { globals: globals.browser, parser: tsParser }, 16 | rules: { 17 | '@typescript-eslint/no-explicit-any': 'warn', 18 | '@typescript-eslint/no-unused-vars': 'warn', 19 | 'no-async-promise-executor': 'warn', 20 | }, 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /scripts/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROTO_PATH=./proto 4 | OUT_DIR=./src/proto 5 | PRETTIER=./node_modules/.bin/prettier 6 | 7 | FILES=$(find proto -type f -name "*.proto") 8 | 9 | mkdir -p ${OUT_DIR} 10 | 11 | echo "Generating TypeScript files from proto definitions..." 12 | for x in ${FILES}; do 13 | protoc \ 14 | --plugin="./node_modules/.bin/protoc-gen-ts_proto" \ 15 | --ts_proto_out="${OUT_DIR}" \ 16 | --proto_path="${PROTO_PATH}" \ 17 | --ts_proto_opt="esModuleInterop=true,forceLong=long,useOptionals=messages,useDate=false,snakeToCamel=false,emitDefaultValues=json-methods" \ 18 | ${x} 19 | done 20 | 21 | echo "Prettifying generated files..." 22 | if [ $? -eq 0 ]; then 23 | find ${OUT_DIR} -name "*.ts" -exec ${PRETTIER} --write {} + 24 | fi 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

⚛️ GNO JS/TS Client ⚛️

2 | 3 | ## Overview 4 | 5 | `@gnolang/gno-js-client` is a JavaScript/TypeScript client implementation for Gno chains. It is an extension of the 6 | [tm2-js-client](https://github.com/gnolang/tm2-js-client), but with Gno-specific functionality. 7 | 8 | ## Key Features 9 | 10 | - Provides the ability to interact with Gno Realms / Packages 11 | - Easy interaction with VM-specific ABCI queries 12 | 13 | ## Installation 14 | 15 | To install `@gnolang/gno-js-client`, use your preferred package manager: 16 | 17 | ```bash 18 | yarn add @gnolang/gno-js-client 19 | ``` 20 | 21 | ```bash 22 | npm install @gnolang/gno-js-client 23 | ``` 24 | 25 | ## Documentation 26 | 27 | For the sake of keeping the README short and sweet, you can find the documentation and usage examples 28 | for the package [here](https://docs.gno.land/reference/gno-js-client/). 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | workflow_dispatch: 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout code 10 | uses: actions/checkout@v5 11 | 12 | - name: Cache dependencies 13 | uses: actions/cache@v4 14 | with: 15 | path: ~/.yarn 16 | key: yarn-${{ hashFiles('yarn.lock') }} 17 | restore-keys: yarn- 18 | 19 | - name: Install modules 20 | run: yarn install 21 | 22 | - name: Install Go 23 | uses: actions/setup-go@v6 24 | with: 25 | go-version: '1.23' 26 | 27 | # Install gnodev only when this PR will be merged: https://github.com/gnolang/gno/pull/4763 28 | - name: Install gnodev 29 | run: curl -sSL https://raw.githubusercontent.com/gnolang/gno/master/misc/install.sh | bash 30 | 31 | - name: Tests 32 | run: ./node_modules/.bin/jest 33 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # GitHub actions updates 4 | - package-ecosystem: 'github-actions' 5 | directory: '/' 6 | schedule: 7 | interval: 'daily' 8 | groups: 9 | actions: 10 | patterns: 11 | - '*' 12 | 13 | # Dependency updates 14 | - package-ecosystem: npm 15 | directory: / 16 | target-branch: 'main' 17 | schedule: 18 | interval: weekly 19 | ignore: 20 | # ignore all patch upgrades 21 | - dependency-name: '*' 22 | update-types: ['version-update:semver-patch'] 23 | open-pull-requests-limit: 10 24 | versioning-strategy: increase 25 | pull-request-branch-name: 26 | separator: '-' 27 | groups: 28 | eslint: 29 | patterns: 30 | - 'eslint' 31 | - 'eslint-config-prettier' 32 | - '@typescript-eslint/*' 33 | types: 34 | patterns: 35 | - '@types/*' 36 | prettier: 37 | patterns: 38 | - 'prettier' 39 | everything-else: 40 | patterns: 41 | - '*' 42 | reviewers: 43 | - 'zivkovicmilos' 44 | -------------------------------------------------------------------------------- /src/provider/provider.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from '@gnolang/tm2-js-client'; 2 | import { FunctionSignature } from './types'; 3 | 4 | /** 5 | * GnoProvider is the Provider interface for Gno-specific functionality 6 | */ 7 | export interface GnoProvider extends Provider { 8 | /** 9 | * Executes the Render() method in read-only mode 10 | * @param {string} packagePath the gno package path 11 | * @param {string} path the render path 12 | * @param {number} [height=0] the height for querying. 13 | */ 14 | getRenderOutput( 15 | packagePath: string, 16 | path: string, 17 | height?: number 18 | ): Promise; 19 | 20 | /** 21 | * Fetches public facing function signatures 22 | * @param {string} packagePath the gno package path 23 | * @param {number} [height=0] the height for querying. 24 | */ 25 | getFunctionSignatures( 26 | packagePath: string, 27 | height?: number 28 | ): Promise; 29 | 30 | /** 31 | * Evaluates any expression in readonly mode and returns the results 32 | * @param {string} packagePath the gno package path 33 | * @param {string} expression the expression to be evaluated 34 | * @param {number} [height=0] the height for querying. 35 | */ 36 | evaluateExpression( 37 | packagePath: string, 38 | expression: string, 39 | height?: number 40 | ): Promise; 41 | 42 | /** 43 | * Fetches the file content, or the list of files if the path is a directory 44 | * @param {string} packagePath the gno package path 45 | * @param {number} [height=0] the height for querying. 46 | */ 47 | getFileContent(packagePath: string, height?: number): Promise; 48 | } 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gnolang/gno-js-client", 3 | "version": "1.4.5", 4 | "description": "Gno JS / TS Client", 5 | "main": "./bin/index.js", 6 | "author": "Milos Zivkovic ", 7 | "license": "Apache-2.0", 8 | "homepage": "https://gno.land/", 9 | "files": [ 10 | "bin/**/*" 11 | ], 12 | "publishConfig": { 13 | "access": "public", 14 | "registry": "https://registry.npmjs.org/" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/gnolang/gno-js-client.git" 19 | }, 20 | "keywords": [ 21 | "gno", 22 | "sdk", 23 | "client", 24 | "js" 25 | ], 26 | "devDependencies": { 27 | "@eslint/js": "^9.37.0", 28 | "@types/jest": "^30.0.0", 29 | "@types/node": "^24.7.0", 30 | "@typescript-eslint/eslint-plugin": "^8.46.0", 31 | "@typescript-eslint/parser": "^8.46.0", 32 | "eslint": "^9.37.0", 33 | "eslint-config-prettier": "^10.1.5", 34 | "eslint-plugin-prettier": "^5.5.1", 35 | "globals": "^16.4.0", 36 | "jest": "^30.2.0", 37 | "prettier": "^3.6.2", 38 | "ts-jest": "^29.4.0", 39 | "ts-proto": "^2.7.5", 40 | "typescript": "^5.9.2", 41 | "typescript-eslint": "^8.46.0" 42 | }, 43 | "scripts": { 44 | "tsc": "tsc", 45 | "lint": "eslint '**/*.ts' --fix", 46 | "prettier": "prettier --write .", 47 | "build": "yarn tsc", 48 | "test": "jest", 49 | "prepare": "yarn build", 50 | "prepublishOnly": "yarn lint && yarn prettier" 51 | }, 52 | "dependencies": { 53 | "@cosmjs/ledger-amino": "^0.36.0", 54 | "@gnolang/tm2-js-client": "^1.3.3", 55 | "long": "^5.3.2", 56 | "protobufjs": "^7.5.3" 57 | }, 58 | "resolutions": { 59 | "@noble/hashes": "^1.8.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/provider/utility/provider.utility.ts: -------------------------------------------------------------------------------- 1 | import { stringToBase64 } from '@gnolang/tm2-js-client'; 2 | 3 | /** 4 | * Prepares the VM ABCI query params by concatenating them 5 | * with characters separation and encoding them to base64 6 | * `evaluateExpression` uses the "." character to separate parameters. 7 | * `getRenderOutput` uses the ":" character to separate parameters. 8 | * @param {string[]} params the params for the ABCI call 9 | * @param {string} separator the separator for ABCI call parameters (default: "") 10 | */ 11 | export const prepareVMABCIQueryWithSeparator = ( 12 | params: string[], 13 | separator: string 14 | ): string => { 15 | if (params.length == 1) { 16 | return stringToBase64(params[0]); 17 | } 18 | 19 | return stringToBase64(params.join(separator)); 20 | }; 21 | 22 | /** 23 | * Prepares the VM ABCI query parameters by concatenating characters and encoding them with base64. 24 | * @param {string[]} params the params for the ABCI call 25 | */ 26 | export const prepareVMABCIQuery = (params: string[]): string => { 27 | return prepareVMABCIQueryWithSeparator(params, ''); 28 | }; 29 | 30 | /** 31 | * Prepare the VM ABCI `evaluateExpression` query parameters by concatenating them 32 | * with the "." character delimiter and encoding them with base64. 33 | * @param {string[]} params the params for the ABCI call 34 | */ 35 | export const prepareVMABCIEvaluateExpressionQuery = ( 36 | params: string[] 37 | ): string => { 38 | return prepareVMABCIQueryWithSeparator(params, '.'); 39 | }; 40 | 41 | /** 42 | * Prepare the VM ABCI `render` query parameters by concatenating them 43 | * with the ":" character delimiter and encoding them with base64. 44 | * @param {string[]} params the params for the ABCI call 45 | */ 46 | export const prepareVMABCIRenderQuery = (params: string[]): string => { 47 | return prepareVMABCIQueryWithSeparator(params, ':'); 48 | }; 49 | 50 | export const extractStringFromResponse = (abciData: string | null): string => { 51 | // Make sure the response is initialized 52 | if (!abciData) { 53 | throw new Error('ABCI response is not initialized'); 54 | } 55 | 56 | // Extract the balances 57 | return Buffer.from(abciData, 'base64').toString(); 58 | }; 59 | -------------------------------------------------------------------------------- /proto/gno/vm.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package gno.vm; 4 | 5 | import "google/protobuf/any.proto"; 6 | 7 | // MsgCall is the method invocation tx message, 8 | // denoted as "m_call" 9 | message MsgCall { 10 | // the bech32 address of the caller 11 | string caller = 1; 12 | // the amount of funds to be deposited to the package, if any ("") 13 | string send = 2; 14 | // the amount of funds to lock for the storage, if any ("") 15 | string max_deposit = 3; 16 | // the gno package path 17 | string pkg_path = 4; 18 | // the function name being invoked 19 | string func = 5; 20 | // the function arguments 21 | repeated string args = 6; // null | string[] 22 | } 23 | 24 | // MsgAddPackage is the package deployment tx message, 25 | // denoted as "m_addpkg" 26 | message MsgAddPackage { 27 | // the package deployer 28 | string creator = 1; 29 | // the package being deployed 30 | MemPackage package = 2; 31 | // the amount of funds to be deposited at deployment, if any ("") 32 | string send = 3; 33 | // the amount of funds to put down for the storage fee, if any ("") 34 | string max_deposit = 4; 35 | } 36 | 37 | // MsgRun is the execute arbitrary Gno code tx message, 38 | // denoted as "m_run" 39 | message MsgRun { 40 | // the bech32 address of the caller 41 | string caller = 1; 42 | // the amount of funds to be deposited to the package, if any ("") 43 | string send = 2; 44 | // the amount of funds to put down for the storage fee, if any ("") 45 | string max_deposit = 3; 46 | // the package being executed 47 | MemPackage package = 4; 48 | } 49 | 50 | // MemPackage is the metadata information tied to 51 | // package / realm deployment 52 | message MemPackage { 53 | // the name of the package 54 | string name = 1; 55 | // the gno path of the package 56 | string path = 2; 57 | // the associated package gno source 58 | repeated MemFile files = 3; 59 | // the (user defined) package type 60 | google.protobuf.Any type = 4; 61 | // the (user defined) extra information 62 | google.protobuf.Any info = 5; 63 | } 64 | 65 | // MemFile is the metadata information tied to 66 | // a single gno package / realm file 67 | message MemFile { 68 | // the name of the source gno file 69 | string name = 1; 70 | // the content of the source gno file 71 | string body = 2; 72 | } -------------------------------------------------------------------------------- /src/wallet/utility/utility.ts: -------------------------------------------------------------------------------- 1 | import { Any, MsgAddPackage, MsgCall, MsgSend } from '../../proto'; 2 | import { MsgRun } from '../../proto/gno/vm'; 3 | import { MsgEndpoint } from '../endpoints'; 4 | 5 | /** 6 | * Converts a fund map to a concatenated string representation ("") 7 | * @param funds 8 | */ 9 | export const fundsToCoins = (funds?: Map): string => { 10 | if (!funds) { 11 | return ''; 12 | } 13 | 14 | const result: string[] = []; 15 | 16 | funds.forEach((value: number, denomination: string) => { 17 | result.push(`${value}${denomination}`); 18 | }); 19 | 20 | return result.join(','); 21 | }; 22 | 23 | /** 24 | * This is constant for now, 25 | * but should be fetched as an estimation 26 | * from the Tendermint node once this functionality 27 | * is available. 28 | * 29 | * Each package call / deployment 30 | * costs a fixed 1 GNOT 31 | * https://github.com/gnolang/gno/issues/649 32 | */ 33 | export const defaultTxFee = '1000000ugnot'; // 1 GNOT 34 | 35 | /** 36 | * Decodes (and unrolls) Transaction messages into full objects 37 | * @param {Any[]} messages the encoded transaction messages 38 | */ 39 | export const decodeTxMessages = (messages: Any[]): any[] => { 40 | return messages.map((m: Any) => { 41 | switch (m.type_url) { 42 | case MsgEndpoint.MSG_CALL: { 43 | const decodedMessage = MsgCall.decode(m.value); 44 | const messageJson = MsgCall.toJSON(decodedMessage) as object; 45 | return { 46 | '@type': m.type_url, 47 | send: '', 48 | ...messageJson, 49 | }; 50 | } 51 | case MsgEndpoint.MSG_SEND: { 52 | const decodedMessage = MsgSend.decode(m.value); 53 | const messageJson = MsgSend.toJSON(decodedMessage) as object; 54 | return { 55 | '@type': m.type_url, 56 | ...messageJson, 57 | }; 58 | } 59 | case MsgEndpoint.MSG_ADD_PKG: { 60 | const decodedMessage = MsgAddPackage.decode(m.value); 61 | const messageJson = MsgAddPackage.toJSON(decodedMessage) as object; 62 | return { 63 | '@type': m.type_url, 64 | ...messageJson, 65 | }; 66 | } 67 | case MsgEndpoint.MSG_RUN: { 68 | const decodedMessage = MsgRun.decode(m.value); 69 | const messageJson = MsgRun.toJSON(decodedMessage) as object; 70 | return { 71 | '@type': m.type_url, 72 | ...messageJson, 73 | }; 74 | } 75 | default: 76 | throw new Error(`unsupported message type ${m.type_url}`); 77 | } 78 | }); 79 | }; 80 | -------------------------------------------------------------------------------- /src/provider/jsonrpc/jsonrpc.ts: -------------------------------------------------------------------------------- 1 | import { GnoProvider } from '../provider'; 2 | import { 3 | ABCIEndpoint, 4 | ABCIResponse, 5 | JSONRPCProvider, 6 | newRequest, 7 | RestService, 8 | } from '@gnolang/tm2-js-client'; 9 | import { FunctionSignature } from '../types'; 10 | import { VMEndpoint } from '../endpoints'; 11 | import { 12 | extractStringFromResponse, 13 | prepareVMABCIEvaluateExpressionQuery, 14 | prepareVMABCIQuery, 15 | prepareVMABCIRenderQuery, 16 | } from '../utility'; 17 | 18 | /** 19 | * Provider based on JSON-RPC HTTP requests 20 | */ 21 | export class GnoJSONRPCProvider extends JSONRPCProvider implements GnoProvider { 22 | /** 23 | * Creates a new instance of the GNO JSON-RPC Provider 24 | * @param {string} baseURL the JSON-RPC URL of the node 25 | */ 26 | constructor(baseURL: string) { 27 | super(baseURL); 28 | } 29 | 30 | async evaluateExpression( 31 | packagePath: string, 32 | expression: string, 33 | height?: number 34 | ): Promise { 35 | const abciResponse: ABCIResponse = await RestService.post( 36 | this.baseURL, 37 | { 38 | request: newRequest(ABCIEndpoint.ABCI_QUERY, [ 39 | `vm/${VMEndpoint.EVALUATE}`, 40 | prepareVMABCIEvaluateExpressionQuery([packagePath, expression]), 41 | '0', // Height; not supported > 0 for now 42 | false, 43 | ]), 44 | } 45 | ); 46 | 47 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 48 | } 49 | 50 | async getFileContent(packagePath: string, height?: number): Promise { 51 | const abciResponse: ABCIResponse = await RestService.post( 52 | this.baseURL, 53 | { 54 | request: newRequest(ABCIEndpoint.ABCI_QUERY, [ 55 | `vm/${VMEndpoint.FILE_CONTENT}`, 56 | prepareVMABCIQuery([packagePath]), 57 | '0', // Height; not supported > 0 for now 58 | false, 59 | ]), 60 | } 61 | ); 62 | 63 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 64 | } 65 | 66 | async getFunctionSignatures( 67 | packagePath: string, 68 | height?: number 69 | ): Promise { 70 | const abciResponse: ABCIResponse = await RestService.post( 71 | this.baseURL, 72 | { 73 | request: newRequest(ABCIEndpoint.ABCI_QUERY, [ 74 | `vm/${VMEndpoint.FUNCTION_SIGNATURES}`, 75 | prepareVMABCIQuery([packagePath]), 76 | '0', // Height; not supported > 0 for now 77 | false, 78 | ]), 79 | } 80 | ); 81 | 82 | // Function signatures encoded in JSON 83 | const responseRaw: string = extractStringFromResponse( 84 | abciResponse.response.ResponseBase.Data 85 | ); 86 | 87 | return JSON.parse(responseRaw); 88 | } 89 | 90 | async getRenderOutput( 91 | packagePath: string, 92 | path: string, 93 | height?: number 94 | ): Promise { 95 | const abciResponse: ABCIResponse = await RestService.post( 96 | this.baseURL, 97 | { 98 | request: newRequest(ABCIEndpoint.ABCI_QUERY, [ 99 | `vm/${VMEndpoint.RENDER}`, 100 | prepareVMABCIRenderQuery([packagePath, path]), 101 | '0', // Height; not supported > 0 for now 102 | false, 103 | ]), 104 | } 105 | ); 106 | 107 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/provider/websocket/ws.ts: -------------------------------------------------------------------------------- 1 | import { GnoProvider } from '../provider'; 2 | import { 3 | ABCIEndpoint, 4 | ABCIResponse, 5 | newRequest, 6 | WSProvider, 7 | } from '@gnolang/tm2-js-client'; 8 | import { FunctionSignature } from '../types'; 9 | import { VMEndpoint } from '../endpoints'; 10 | import { 11 | extractStringFromResponse, 12 | prepareVMABCIEvaluateExpressionQuery, 13 | prepareVMABCIQuery, 14 | prepareVMABCIRenderQuery, 15 | } from '../utility'; 16 | 17 | export class GnoWSProvider extends WSProvider implements GnoProvider { 18 | /** 19 | * Creates a new instance of the {@link GnoWSProvider} 20 | * @param {string} baseURL the WS URL of the node 21 | * @param {number} requestTimeout the timeout for the WS request (in MS) 22 | */ 23 | constructor(baseURL: string, requestTimeout?: number) { 24 | super(baseURL, requestTimeout); 25 | } 26 | 27 | async evaluateExpression( 28 | packagePath: string, 29 | expression: string, 30 | height?: number 31 | ): Promise { 32 | const response = await this.sendRequest( 33 | newRequest(ABCIEndpoint.ABCI_QUERY, [ 34 | `vm/${VMEndpoint.EVALUATE}`, 35 | prepareVMABCIEvaluateExpressionQuery([packagePath, expression]), 36 | '0', // Height; not supported > 0 for now 37 | false, 38 | ]) 39 | ); 40 | 41 | // Parse the response 42 | const abciResponse = this.parseResponse(response); 43 | 44 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 45 | } 46 | 47 | async getFileContent(packagePath: string, height?: number): Promise { 48 | const response = await this.sendRequest( 49 | newRequest(ABCIEndpoint.ABCI_QUERY, [ 50 | `vm/${VMEndpoint.FILE_CONTENT}`, 51 | prepareVMABCIQuery([packagePath]), 52 | '0', // Height; not supported > 0 for now 53 | false, 54 | ]) 55 | ); 56 | 57 | // Parse the response 58 | const abciResponse = this.parseResponse(response); 59 | 60 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 61 | } 62 | 63 | async getFunctionSignatures( 64 | packagePath: string, 65 | height?: number 66 | ): Promise { 67 | const response = await this.sendRequest( 68 | newRequest(ABCIEndpoint.ABCI_QUERY, [ 69 | `vm/${VMEndpoint.FUNCTION_SIGNATURES}`, 70 | prepareVMABCIQuery([packagePath]), 71 | '0', // Height; not supported > 0 for now 72 | false, 73 | ]) 74 | ); 75 | 76 | // Parse the response 77 | const abciResponse = this.parseResponse(response); 78 | 79 | // Function signatures encoded in JSON 80 | const responseRaw: string = extractStringFromResponse( 81 | abciResponse.response.ResponseBase.Data 82 | ); 83 | 84 | return JSON.parse(responseRaw); 85 | } 86 | 87 | async getRenderOutput( 88 | packagePath: string, 89 | path: string, 90 | height?: number 91 | ): Promise { 92 | const response = await this.sendRequest( 93 | newRequest(ABCIEndpoint.ABCI_QUERY, [ 94 | `vm/${VMEndpoint.RENDER}`, 95 | prepareVMABCIRenderQuery([packagePath, path]), 96 | '0', // Height; not supported > 0 for now 97 | false, 98 | ]) 99 | ); 100 | 101 | // Parse the response 102 | const abciResponse = this.parseResponse(response); 103 | 104 | return extractStringFromResponse(abciResponse.response.ResponseBase.Data); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/__tests__/e2e.ts: -------------------------------------------------------------------------------- 1 | import { TransactionEndpoint, TxFee } from '@gnolang/tm2-js-client'; 2 | import { 3 | GnoWallet, 4 | GnoJSONRPCProvider, 5 | defaultTxFee, 6 | MemFile, 7 | MemPackage, 8 | } from '..'; 9 | import Long from 'long'; 10 | import { spawn, ChildProcess } from 'child_process'; 11 | 12 | describe('E2E Tests', () => { 13 | const txFee: TxFee = { 14 | gas_wanted: new Long(50000000), 15 | gas_fee: defaultTxFee, 16 | }; 17 | 18 | let provider: GnoJSONRPCProvider; 19 | let gnoWallet: GnoWallet; 20 | let gnodevProcess: ChildProcess; 21 | 22 | beforeAll(async () => { 23 | // Start gnodev server 24 | gnodevProcess = spawn('gnodev', ['local', '-paths', 'gno.land/r/tests/vm']); 25 | 26 | // Wait for server to be ready 27 | await new Promise((resolve, reject) => { 28 | const timeout = setTimeout(() => { 29 | reject(new Error('Server startup timeout')); 30 | }, 30000); 31 | 32 | gnodevProcess.stdout?.on('data', (data) => { 33 | if (data.toString().includes('node is ready')) { 34 | clearTimeout(timeout); 35 | resolve(); 36 | } 37 | }); 38 | 39 | gnodevProcess.stderr?.on('data', (data) => { 40 | console.error('gnodev error:', data.toString()); 41 | }); 42 | 43 | gnodevProcess.on('error', (error) => { 44 | clearTimeout(timeout); 45 | reject(error); 46 | }); 47 | }); 48 | 49 | provider = new GnoJSONRPCProvider('http://127.0.0.1:26657'); 50 | 51 | // test1 already has an account balance 52 | gnoWallet = await GnoWallet.fromMnemonic( 53 | 'source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast' 54 | ); 55 | gnoWallet.connect(provider); 56 | }, 40000); 57 | 58 | test('MsgCall with omitted empty args list and max_deposit as empty string', async () => { 59 | await expect( 60 | gnoWallet.callMethod( 61 | 'gno.land/r/tests/vm', 62 | 'IncCounter', 63 | [], 64 | TransactionEndpoint.BROADCAST_TX_COMMIT, 65 | undefined, 66 | undefined, 67 | txFee 68 | ) 69 | ).resolves.not.toThrow(); 70 | 71 | const result = await gnoWallet.callMethod( 72 | 'gno.land/r/tests/vm', 73 | 'Counter', 74 | [], 75 | TransactionEndpoint.BROADCAST_TX_COMMIT, 76 | undefined, 77 | undefined, 78 | txFee 79 | ); 80 | 81 | const data = result.deliver_tx.ResponseBase.Data; 82 | expect(data).toBeTruthy(); 83 | const decodedData = Buffer.from(data!, 'base64').toString(); 84 | expect(decodedData).toBe('(1 int)\n\n'); 85 | }); 86 | 87 | test('MemPackage with omitted type and info', async () => { 88 | const pkgName = 'hello' + Math.floor(Math.random() * 1000); 89 | const gnomodtoml: MemFile = { 90 | name: 'gnomod.toml', 91 | body: 92 | 'module = "gno.land/p/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5/' + 93 | pkgName + 94 | '"\ngno = "0.9"\n', 95 | }; 96 | const hello: MemFile = { 97 | name: pkgName + '.gno', 98 | body: 99 | 'package ' + 100 | pkgName + 101 | '\n\nfunc Hello() string {\n return "Hello, world!"\n}\n', 102 | }; 103 | const memPackage: MemPackage = { 104 | name: pkgName, 105 | path: 'gno.land/p/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5/' + pkgName, 106 | files: [gnomodtoml, hello], 107 | }; 108 | 109 | await expect( 110 | gnoWallet.deployPackage( 111 | memPackage, 112 | TransactionEndpoint.BROADCAST_TX_COMMIT, 113 | undefined, 114 | undefined, 115 | txFee 116 | ) 117 | ).resolves.not.toThrow(); 118 | }); 119 | 120 | afterAll(async () => { 121 | // Stop gnodev server 122 | if (gnodevProcess) { 123 | // Try to exit gracefully 124 | if (!gnodevProcess.kill('SIGINT')) { 125 | // Force kill if it doesn't exit 126 | gnodevProcess.kill('SIGKILL'); 127 | } 128 | } 129 | }); 130 | }); 131 | -------------------------------------------------------------------------------- /src/proto/gno/bank.ts: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-ts_proto v2.7.5 4 | // protoc v5.29.3 5 | // source: gno/bank.proto 6 | 7 | /* eslint-disable */ 8 | import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire'; 9 | import Long from 'long'; 10 | 11 | export const protobufPackage = 'gno.bank'; 12 | 13 | /** MsgSend is the fund transfer tx message */ 14 | export interface MsgSend { 15 | /** the bech32 address of the fund sender */ 16 | from_address: string; 17 | /** the bech32 address of the fund receiver */ 18 | to_address: string; 19 | /** the denomination and amount of fund sent ("") */ 20 | amount: string; 21 | } 22 | 23 | function createBaseMsgSend(): MsgSend { 24 | return { from_address: '', to_address: '', amount: '' }; 25 | } 26 | 27 | export const MsgSend: MessageFns = { 28 | encode( 29 | message: MsgSend, 30 | writer: BinaryWriter = new BinaryWriter() 31 | ): BinaryWriter { 32 | if (message.from_address !== '') { 33 | writer.uint32(10).string(message.from_address); 34 | } 35 | if (message.to_address !== '') { 36 | writer.uint32(18).string(message.to_address); 37 | } 38 | if (message.amount !== '') { 39 | writer.uint32(26).string(message.amount); 40 | } 41 | return writer; 42 | }, 43 | 44 | decode(input: BinaryReader | Uint8Array, length?: number): MsgSend { 45 | const reader = 46 | input instanceof BinaryReader ? input : new BinaryReader(input); 47 | const end = length === undefined ? reader.len : reader.pos + length; 48 | const message = createBaseMsgSend(); 49 | while (reader.pos < end) { 50 | const tag = reader.uint32(); 51 | switch (tag >>> 3) { 52 | case 1: { 53 | if (tag !== 10) { 54 | break; 55 | } 56 | 57 | message.from_address = reader.string(); 58 | continue; 59 | } 60 | case 2: { 61 | if (tag !== 18) { 62 | break; 63 | } 64 | 65 | message.to_address = reader.string(); 66 | continue; 67 | } 68 | case 3: { 69 | if (tag !== 26) { 70 | break; 71 | } 72 | 73 | message.amount = reader.string(); 74 | continue; 75 | } 76 | } 77 | if ((tag & 7) === 4 || tag === 0) { 78 | break; 79 | } 80 | reader.skip(tag & 7); 81 | } 82 | return message; 83 | }, 84 | 85 | fromJSON(object: any): MsgSend { 86 | return { 87 | from_address: isSet(object.from_address) 88 | ? globalThis.String(object.from_address) 89 | : '', 90 | to_address: isSet(object.to_address) 91 | ? globalThis.String(object.to_address) 92 | : '', 93 | amount: isSet(object.amount) ? globalThis.String(object.amount) : '', 94 | }; 95 | }, 96 | 97 | toJSON(message: MsgSend): unknown { 98 | const obj: any = {}; 99 | if (message.from_address !== undefined) { 100 | obj.from_address = message.from_address; 101 | } 102 | if (message.to_address !== undefined) { 103 | obj.to_address = message.to_address; 104 | } 105 | if (message.amount !== undefined) { 106 | obj.amount = message.amount; 107 | } 108 | return obj; 109 | }, 110 | 111 | create, I>>(base?: I): MsgSend { 112 | return MsgSend.fromPartial(base ?? ({} as any)); 113 | }, 114 | fromPartial, I>>(object: I): MsgSend { 115 | const message = createBaseMsgSend(); 116 | message.from_address = object.from_address ?? ''; 117 | message.to_address = object.to_address ?? ''; 118 | message.amount = object.amount ?? ''; 119 | return message; 120 | }, 121 | }; 122 | 123 | type Builtin = 124 | | Date 125 | | Function 126 | | Uint8Array 127 | | string 128 | | number 129 | | boolean 130 | | undefined; 131 | 132 | export type DeepPartial = T extends Builtin 133 | ? T 134 | : T extends Long 135 | ? string | number | Long 136 | : T extends globalThis.Array 137 | ? globalThis.Array> 138 | : T extends ReadonlyArray 139 | ? ReadonlyArray> 140 | : T extends {} 141 | ? { [K in keyof T]?: DeepPartial } 142 | : Partial; 143 | 144 | type KeysOfUnion = T extends T ? keyof T : never; 145 | export type Exact = P extends Builtin 146 | ? P 147 | : P & { [K in keyof P]: Exact } & { 148 | [K in Exclude>]: never; 149 | }; 150 | 151 | function isSet(value: any): boolean { 152 | return value !== null && value !== undefined; 153 | } 154 | 155 | export interface MessageFns { 156 | encode(message: T, writer?: BinaryWriter): BinaryWriter; 157 | decode(input: BinaryReader | Uint8Array, length?: number): T; 158 | fromJSON(object: any): T; 159 | toJSON(message: T): unknown; 160 | create, I>>(base?: I): T; 161 | fromPartial, I>>(object: I): T; 162 | } 163 | -------------------------------------------------------------------------------- /src/proto/google/protobuf/any.ts: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-ts_proto v2.7.5 4 | // protoc v5.29.3 5 | // source: google/protobuf/any.proto 6 | 7 | /* eslint-disable */ 8 | import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire'; 9 | import Long from 'long'; 10 | 11 | export const protobufPackage = 'google.protobuf'; 12 | 13 | /** 14 | * `Any` contains an arbitrary serialized protocol buffer message along with a 15 | * URL that describes the type of the serialized message. 16 | * 17 | * Protobuf library provides support to pack/unpack Any values in the form 18 | * of utility functions or additional generated methods of the Any type. 19 | * 20 | * Example 1: Pack and unpack a message in C++. 21 | * 22 | * Foo foo = ...; 23 | * Any any; 24 | * any.PackFrom(foo); 25 | * ... 26 | * if (any.UnpackTo(&foo)) { 27 | * ... 28 | * } 29 | * 30 | * Example 2: Pack and unpack a message in Java. 31 | * 32 | * Foo foo = ...; 33 | * Any any = Any.pack(foo); 34 | * ... 35 | * if (any.is(Foo.class)) { 36 | * foo = any.unpack(Foo.class); 37 | * } 38 | * // or ... 39 | * if (any.isSameTypeAs(Foo.getDefaultInstance())) { 40 | * foo = any.unpack(Foo.getDefaultInstance()); 41 | * } 42 | * 43 | * Example 3: Pack and unpack a message in Python. 44 | * 45 | * foo = Foo(...) 46 | * any = Any() 47 | * any.Pack(foo) 48 | * ... 49 | * if any.Is(Foo.DESCRIPTOR): 50 | * any.Unpack(foo) 51 | * ... 52 | * 53 | * Example 4: Pack and unpack a message in Go 54 | * 55 | * foo := &pb.Foo{...} 56 | * any, err := anypb.New(foo) 57 | * if err != nil { 58 | * ... 59 | * } 60 | * ... 61 | * foo := &pb.Foo{} 62 | * if err := any.UnmarshalTo(foo); err != nil { 63 | * ... 64 | * } 65 | * 66 | * The pack methods provided by protobuf library will by default use 67 | * 'type.googleapis.com/full.type.name' as the type URL and the unpack 68 | * methods only use the fully qualified type name after the last '/' 69 | * in the type URL, for example "foo.bar.com/x/y.z" will yield type 70 | * name "y.z". 71 | * 72 | * JSON 73 | * ==== 74 | * The JSON representation of an `Any` value uses the regular 75 | * representation of the deserialized, embedded message, with an 76 | * additional field `@type` which contains the type URL. Example: 77 | * 78 | * package google.profile; 79 | * message Person { 80 | * string first_name = 1; 81 | * string last_name = 2; 82 | * } 83 | * 84 | * { 85 | * "@type": "type.googleapis.com/google.profile.Person", 86 | * "firstName": , 87 | * "lastName": 88 | * } 89 | * 90 | * If the embedded message type is well-known and has a custom JSON 91 | * representation, that representation will be embedded adding a field 92 | * `value` which holds the custom JSON in addition to the `@type` 93 | * field. Example (for message [google.protobuf.Duration][]): 94 | * 95 | * { 96 | * "@type": "type.googleapis.com/google.protobuf.Duration", 97 | * "value": "1.212s" 98 | * } 99 | */ 100 | export interface Any { 101 | /** 102 | * A URL/resource name that uniquely identifies the type of the serialized 103 | * protocol buffer message. This string must contain at least 104 | * one "/" character. The last segment of the URL's path must represent 105 | * the fully qualified name of the type (as in 106 | * `path/google.protobuf.Duration`). The name should be in a canonical form 107 | * (e.g., leading "." is not accepted). 108 | * 109 | * In practice, teams usually precompile into the binary all types that they 110 | * expect it to use in the context of Any. However, for URLs which use the 111 | * scheme `http`, `https`, or no scheme, one can optionally set up a type 112 | * server that maps type URLs to message definitions as follows: 113 | * 114 | * * If no scheme is provided, `https` is assumed. 115 | * * An HTTP GET on the URL must yield a [google.protobuf.Type][] 116 | * value in binary format, or produce an error. 117 | * * Applications are allowed to cache lookup results based on the 118 | * URL, or have them precompiled into a binary to avoid any 119 | * lookup. Therefore, binary compatibility needs to be preserved 120 | * on changes to types. (Use versioned type names to manage 121 | * breaking changes.) 122 | * 123 | * Note: this functionality is not currently available in the official 124 | * protobuf release, and it is not used for type URLs beginning with 125 | * type.googleapis.com. As of May 2023, there are no widely used type server 126 | * implementations and no plans to implement one. 127 | * 128 | * Schemes other than `http`, `https` (or the empty scheme) might be 129 | * used with implementation specific semantics. 130 | */ 131 | type_url: string; 132 | /** Must be a valid serialized protocol buffer of the above specified type. */ 133 | value: Uint8Array; 134 | } 135 | 136 | function createBaseAny(): Any { 137 | return { type_url: '', value: new Uint8Array(0) }; 138 | } 139 | 140 | export const Any: MessageFns = { 141 | encode( 142 | message: Any, 143 | writer: BinaryWriter = new BinaryWriter() 144 | ): BinaryWriter { 145 | if (message.type_url !== '') { 146 | writer.uint32(10).string(message.type_url); 147 | } 148 | if (message.value.length !== 0) { 149 | writer.uint32(18).bytes(message.value); 150 | } 151 | return writer; 152 | }, 153 | 154 | decode(input: BinaryReader | Uint8Array, length?: number): Any { 155 | const reader = 156 | input instanceof BinaryReader ? input : new BinaryReader(input); 157 | const end = length === undefined ? reader.len : reader.pos + length; 158 | const message = createBaseAny(); 159 | while (reader.pos < end) { 160 | const tag = reader.uint32(); 161 | switch (tag >>> 3) { 162 | case 1: { 163 | if (tag !== 10) { 164 | break; 165 | } 166 | 167 | message.type_url = reader.string(); 168 | continue; 169 | } 170 | case 2: { 171 | if (tag !== 18) { 172 | break; 173 | } 174 | 175 | message.value = reader.bytes(); 176 | continue; 177 | } 178 | } 179 | if ((tag & 7) === 4 || tag === 0) { 180 | break; 181 | } 182 | reader.skip(tag & 7); 183 | } 184 | return message; 185 | }, 186 | 187 | fromJSON(object: any): Any { 188 | return { 189 | type_url: isSet(object.type_url) 190 | ? globalThis.String(object.type_url) 191 | : '', 192 | value: isSet(object.value) 193 | ? bytesFromBase64(object.value) 194 | : new Uint8Array(0), 195 | }; 196 | }, 197 | 198 | toJSON(message: Any): unknown { 199 | const obj: any = {}; 200 | if (message.type_url !== undefined) { 201 | obj.type_url = message.type_url; 202 | } 203 | if (message.value !== undefined) { 204 | obj.value = base64FromBytes(message.value); 205 | } 206 | return obj; 207 | }, 208 | 209 | create, I>>(base?: I): Any { 210 | return Any.fromPartial(base ?? ({} as any)); 211 | }, 212 | fromPartial, I>>(object: I): Any { 213 | const message = createBaseAny(); 214 | message.type_url = object.type_url ?? ''; 215 | message.value = object.value ?? new Uint8Array(0); 216 | return message; 217 | }, 218 | }; 219 | 220 | function bytesFromBase64(b64: string): Uint8Array { 221 | if ((globalThis as any).Buffer) { 222 | return Uint8Array.from(globalThis.Buffer.from(b64, 'base64')); 223 | } else { 224 | const bin = globalThis.atob(b64); 225 | const arr = new Uint8Array(bin.length); 226 | for (let i = 0; i < bin.length; ++i) { 227 | arr[i] = bin.charCodeAt(i); 228 | } 229 | return arr; 230 | } 231 | } 232 | 233 | function base64FromBytes(arr: Uint8Array): string { 234 | if ((globalThis as any).Buffer) { 235 | return globalThis.Buffer.from(arr).toString('base64'); 236 | } else { 237 | const bin: string[] = []; 238 | arr.forEach((byte) => { 239 | bin.push(globalThis.String.fromCharCode(byte)); 240 | }); 241 | return globalThis.btoa(bin.join('')); 242 | } 243 | } 244 | 245 | type Builtin = 246 | | Date 247 | | Function 248 | | Uint8Array 249 | | string 250 | | number 251 | | boolean 252 | | undefined; 253 | 254 | export type DeepPartial = T extends Builtin 255 | ? T 256 | : T extends Long 257 | ? string | number | Long 258 | : T extends globalThis.Array 259 | ? globalThis.Array> 260 | : T extends ReadonlyArray 261 | ? ReadonlyArray> 262 | : T extends {} 263 | ? { [K in keyof T]?: DeepPartial } 264 | : Partial; 265 | 266 | type KeysOfUnion = T extends T ? keyof T : never; 267 | export type Exact = P extends Builtin 268 | ? P 269 | : P & { [K in keyof P]: Exact } & { 270 | [K in Exclude>]: never; 271 | }; 272 | 273 | function isSet(value: any): boolean { 274 | return value !== null && value !== undefined; 275 | } 276 | 277 | export interface MessageFns { 278 | encode(message: T, writer?: BinaryWriter): BinaryWriter; 279 | decode(input: BinaryReader | Uint8Array, length?: number): T; 280 | fromJSON(object: any): T; 281 | toJSON(message: T): unknown; 282 | create, I>>(base?: I): T; 283 | fromPartial, I>>(object: I): T; 284 | } 285 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/wallet/wallet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AccountWalletOption, 3 | BroadcastTransactionMap, 4 | CreateWalletOptions, 5 | Signer, 6 | Tx, 7 | TxFee, 8 | Wallet, 9 | } from '@gnolang/tm2-js-client'; 10 | import { decodeTxMessages, defaultTxFee, fundsToCoins } from './utility'; 11 | import Long from 'long'; 12 | import { MemPackage, MsgAddPackage, MsgCall, MsgSend } from '../proto'; 13 | import { MsgEndpoint } from './endpoints'; 14 | import { LedgerConnector } from '@cosmjs/ledger-amino'; 15 | import { MsgRun } from '../proto/gno/vm'; 16 | 17 | /** 18 | * GnoWallet is an extension of the TM2 wallet with 19 | * specific functionality for Gno chains 20 | */ 21 | export class GnoWallet extends Wallet { 22 | constructor() { 23 | super(); 24 | } 25 | 26 | /** 27 | * Generates a private key-based wallet, using a random seed 28 | * @param {AccountWalletOption} options the account options 29 | */ 30 | static override createRandom = async ( 31 | options?: AccountWalletOption 32 | ): Promise => { 33 | const wallet = await Wallet.createRandom(options); 34 | 35 | const gnoWallet: GnoWallet = new GnoWallet(); 36 | gnoWallet.signer = wallet.getSigner(); 37 | 38 | return gnoWallet; 39 | }; 40 | 41 | /** 42 | * Generates a custom signer-based wallet 43 | * @param {Signer} signer the custom signer implementing the Signer interface 44 | * @param {CreateWalletOptions} options the wallet generation options 45 | */ 46 | static override fromSigner = async (signer: Signer): Promise => { 47 | const wallet = await Wallet.fromSigner(signer); 48 | 49 | const gnoWallet: GnoWallet = new GnoWallet(); 50 | gnoWallet.signer = wallet.getSigner(); 51 | 52 | return gnoWallet; 53 | }; 54 | 55 | /** 56 | * Generates a bip39 mnemonic-based wallet 57 | * @param {string} mnemonic the bip39 mnemonic 58 | * @param {CreateWalletOptions} options the wallet generation options 59 | */ 60 | static override fromMnemonic = async ( 61 | mnemonic: string, 62 | options?: CreateWalletOptions 63 | ): Promise => { 64 | const wallet = await Wallet.fromMnemonic(mnemonic, options); 65 | 66 | const gnoWallet: GnoWallet = new GnoWallet(); 67 | gnoWallet.signer = wallet.getSigner(); 68 | 69 | return gnoWallet; 70 | }; 71 | 72 | /** 73 | * Generates a private key-based wallet 74 | * @param {string} privateKey the private key 75 | * @param {AccountWalletOption} options the account options 76 | */ 77 | static override fromPrivateKey = async ( 78 | privateKey: Uint8Array, 79 | options?: AccountWalletOption 80 | ): Promise => { 81 | const wallet = await Wallet.fromPrivateKey(privateKey, options); 82 | 83 | const gnoWallet: GnoWallet = new GnoWallet(); 84 | gnoWallet.signer = wallet.getSigner(); 85 | 86 | return gnoWallet; 87 | }; 88 | 89 | /** 90 | * Creates a Ledger-based wallet 91 | * @param {LedgerConnector} connector the Ledger device connector 92 | * @param {CreateWalletOptions} options the wallet generation options 93 | */ 94 | static override fromLedger = ( 95 | connector: LedgerConnector, 96 | options?: CreateWalletOptions 97 | ): GnoWallet => { 98 | const wallet = Wallet.fromLedger(connector, options); 99 | 100 | const gnoWallet: GnoWallet = new GnoWallet(); 101 | gnoWallet.signer = wallet.getSigner(); 102 | 103 | return gnoWallet; 104 | }; 105 | 106 | /** 107 | * Initiates a native currency transfer transaction between accounts 108 | * @param {string} to the bech32 address of the receiver 109 | * @param {Map} funds the denomination -> value map for funds 110 | * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit) 111 | * @param {TxFee} [fee] the custom transaction fee, if any 112 | */ 113 | transferFunds = async ( 114 | to: string, 115 | funds: Map, 116 | endpoint: K, 117 | fee?: TxFee 118 | ): Promise => { 119 | // Convert the funds into the correct representation 120 | const amount: string = fundsToCoins(funds); 121 | 122 | // Fetch the wallet address 123 | const sender: string = await this.getAddress(); 124 | 125 | // Construct the transaction fee 126 | const txFee: TxFee = fee 127 | ? fee 128 | : { 129 | gas_wanted: new Long(60000), 130 | gas_fee: defaultTxFee, 131 | }; 132 | 133 | // Prepare the Msg 134 | const sendMsg: MsgSend = { 135 | from_address: sender, 136 | to_address: to, 137 | amount: amount, 138 | }; 139 | 140 | // Construct the transfer transaction 141 | const tx: Tx = { 142 | messages: [ 143 | { 144 | type_url: MsgEndpoint.MSG_SEND, 145 | value: MsgSend.encode(sendMsg).finish(), 146 | }, 147 | ], 148 | fee: txFee, 149 | memo: '', 150 | signatures: [], // No signature yet 151 | }; 152 | 153 | // Sign the transaction 154 | const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages); 155 | 156 | // Send the transaction 157 | return this.sendTransaction(signedTx, endpoint); 158 | }; 159 | 160 | /** 161 | * Invokes the specified method on a GNO contract 162 | * @param {string} path the gno package / realm path 163 | * @param {string} method the method name 164 | * @param {string[]} args the method arguments, if any 165 | * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit) 166 | * @param {Map} [funds] the denomination -> value map for funds, if any 167 | * @param {Map} [maxDeposit] the denomination -> value map for max storage deposit, if any 168 | * @param {TxFee} [fee] the custom transaction fee, if any 169 | */ 170 | callMethod = async ( 171 | path: string, 172 | method: string, 173 | args: string[] | null, 174 | endpoint: K, 175 | funds?: Map, 176 | maxDeposit?: Map, 177 | fee?: TxFee 178 | ): Promise => { 179 | // Convert the funds into the correct representation 180 | const amount: string = fundsToCoins(funds); 181 | const maxDepositAmount: string = fundsToCoins(maxDeposit); 182 | 183 | // Fetch the wallet address 184 | const caller: string = await this.getAddress(); 185 | 186 | // Construct the transaction fee 187 | const txFee: TxFee = fee 188 | ? fee 189 | : { 190 | gas_wanted: new Long(60000), 191 | gas_fee: defaultTxFee, 192 | }; 193 | 194 | // Prepare the Msg 195 | const callMsg: MsgCall = { 196 | caller: caller, 197 | send: amount, 198 | max_deposit: maxDepositAmount, 199 | pkg_path: path, 200 | func: method, 201 | args: args || [], 202 | }; 203 | 204 | // Construct the transfer transaction 205 | const tx: Tx = { 206 | messages: [ 207 | { 208 | type_url: MsgEndpoint.MSG_CALL, 209 | value: MsgCall.encode(callMsg).finish(), 210 | }, 211 | ], 212 | fee: txFee, 213 | memo: '', 214 | signatures: [], // No signature yet 215 | }; 216 | 217 | // Sign the transaction 218 | const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages); 219 | 220 | // Send the transaction 221 | return this.sendTransaction(signedTx, endpoint); 222 | }; 223 | 224 | /** 225 | * Deploys the specified package / realm 226 | * @param {MemPackage} gnoPackage the package / realm to be deployed 227 | * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit) 228 | * @param {Map} [funds] the denomination -> value map for funds, if any 229 | * @param {Map} [maxDeposit] the denomination -> value map for max storage deposit, if any 230 | * @param {TxFee} [fee] the custom transaction fee, if any 231 | */ 232 | deployPackage = async ( 233 | gnoPackage: MemPackage, 234 | endpoint: K, 235 | funds?: Map, 236 | maxDeposit?: Map, 237 | fee?: TxFee 238 | ): Promise => { 239 | // Convert the funds into the correct representation 240 | const amount: string = fundsToCoins(funds); 241 | const maxDepositAmount: string = fundsToCoins(maxDeposit); 242 | 243 | // Fetch the wallet address 244 | const caller: string = await this.getAddress(); 245 | 246 | // Construct the transaction fee 247 | const txFee: TxFee = fee 248 | ? fee 249 | : { 250 | gas_wanted: new Long(60000), 251 | gas_fee: defaultTxFee, 252 | }; 253 | 254 | // Prepare the Msg 255 | const addPkgMsg: MsgAddPackage = { 256 | creator: caller, 257 | package: gnoPackage, 258 | send: amount, 259 | max_deposit: maxDepositAmount, 260 | }; 261 | 262 | // Construct the transfer transaction 263 | const tx: Tx = { 264 | messages: [ 265 | { 266 | type_url: MsgEndpoint.MSG_ADD_PKG, 267 | value: MsgAddPackage.encode(addPkgMsg).finish(), 268 | }, 269 | ], 270 | fee: txFee, 271 | memo: '', 272 | signatures: [], // No signature yet 273 | }; 274 | 275 | // Sign the transaction 276 | const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages); 277 | 278 | // Send the transaction 279 | return this.sendTransaction(signedTx, endpoint); 280 | }; 281 | 282 | /** 283 | * Executes arbitrary Gno code 284 | * @param {MemPackage} gnoPackage the gno package being executed 285 | * @param {TransactionEndpoint} endpoint the transaction broadcast type (sync / commit) 286 | * @param {Map} [funds] the denomination -> value map for funds, if any 287 | * @param {Map} [maxDeposit] the denomination -> value map for max storage deposit, if any 288 | * @param {TxFee} [fee] the custom transaction fee, if any 289 | */ 290 | executePackage = async ( 291 | gnoPackage: MemPackage, 292 | endpoint: K, 293 | funds?: Map, 294 | maxDeposit?: Map, 295 | fee?: TxFee 296 | ): Promise => { 297 | // Convert the funds into the correct representation 298 | const amount: string = fundsToCoins(funds); 299 | const maxDepositAmount: string = fundsToCoins(maxDeposit); 300 | 301 | // Fetch the wallet address 302 | const caller: string = await this.getAddress(); 303 | 304 | // Construct the transaction fee 305 | const txFee: TxFee = fee 306 | ? fee 307 | : { 308 | gas_wanted: new Long(60000), 309 | gas_fee: defaultTxFee, 310 | }; 311 | 312 | // Prepare the Msg 313 | const runMsg: MsgRun = { 314 | caller, 315 | send: amount, 316 | package: gnoPackage, 317 | max_deposit: maxDepositAmount, 318 | }; 319 | 320 | // Construct the transfer transaction 321 | const tx: Tx = { 322 | messages: [ 323 | { 324 | type_url: MsgEndpoint.MSG_RUN, 325 | value: MsgRun.encode(runMsg).finish(), 326 | }, 327 | ], 328 | fee: txFee, 329 | memo: '', 330 | signatures: [], // No signature yet 331 | }; 332 | 333 | // Sign the transaction 334 | const signedTx: Tx = await this.signTransaction(tx, decodeTxMessages); 335 | 336 | // Send the transaction 337 | return this.sendTransaction(signedTx, endpoint); 338 | }; 339 | } 340 | -------------------------------------------------------------------------------- /src/proto/google/protobuf/struct.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import Long from 'long'; 3 | import _m0 from 'protobufjs/minimal'; 4 | 5 | export const protobufPackage = 'google.protobuf'; 6 | 7 | /** 8 | * `NullValue` is a singleton enumeration to represent the null value for the 9 | * `Value` type union. 10 | * 11 | * The JSON representation for `NullValue` is JSON `null`. 12 | */ 13 | export enum NullValue { 14 | /** NULL_VALUE - Null value. */ 15 | NULL_VALUE = 0, 16 | UNRECOGNIZED = -1, 17 | } 18 | 19 | export function nullValueFromJSON(object: any): NullValue { 20 | switch (object) { 21 | case 0: 22 | case 'NULL_VALUE': 23 | return NullValue.NULL_VALUE; 24 | case -1: 25 | case 'UNRECOGNIZED': 26 | default: 27 | return NullValue.UNRECOGNIZED; 28 | } 29 | } 30 | 31 | export function nullValueToJSON(object: NullValue): string { 32 | switch (object) { 33 | case NullValue.NULL_VALUE: 34 | return 'NULL_VALUE'; 35 | case NullValue.UNRECOGNIZED: 36 | default: 37 | return 'UNRECOGNIZED'; 38 | } 39 | } 40 | 41 | /** 42 | * `Struct` represents a structured data value, consisting of fields 43 | * which map to dynamically typed values. In some languages, `Struct` 44 | * might be supported by a native representation. For example, in 45 | * scripting languages like JS a struct is represented as an 46 | * object. The details of that representation are described together 47 | * with the proto support for the language. 48 | * 49 | * The JSON representation for `Struct` is JSON object. 50 | */ 51 | export interface Struct { 52 | /** Unordered map of dynamically typed values. */ 53 | fields: { [key: string]: any | undefined }; 54 | } 55 | 56 | export interface Struct_FieldsEntry { 57 | key: string; 58 | value?: any | undefined; 59 | } 60 | 61 | /** 62 | * `Value` represents a dynamically typed value which can be either 63 | * null, a number, a string, a boolean, a recursive struct value, or a 64 | * list of values. A producer of value is expected to set one of these 65 | * variants. Absence of any variant indicates an error. 66 | * 67 | * The JSON representation for `Value` is JSON value. 68 | */ 69 | export interface Value { 70 | /** Represents a null value. */ 71 | null_value?: NullValue | undefined; 72 | /** Represents a double value. */ 73 | number_value?: number | undefined; 74 | /** Represents a string value. */ 75 | string_value?: string | undefined; 76 | /** Represents a boolean value. */ 77 | bool_value?: boolean | undefined; 78 | /** Represents a structured value. */ 79 | struct_value?: { [key: string]: any } | undefined; 80 | /** Represents a repeated `Value`. */ 81 | list_value?: Array | undefined; 82 | } 83 | 84 | /** 85 | * `ListValue` is a wrapper around a repeated field of values. 86 | * 87 | * The JSON representation for `ListValue` is JSON array. 88 | */ 89 | export interface ListValue { 90 | /** Repeated field of dynamically typed values. */ 91 | values: any[]; 92 | } 93 | 94 | function createBaseStruct(): Struct { 95 | return { fields: {} }; 96 | } 97 | 98 | export const Struct = { 99 | encode( 100 | message: Struct, 101 | writer: _m0.Writer = _m0.Writer.create() 102 | ): _m0.Writer { 103 | Object.entries(message.fields).forEach(([key, value]) => { 104 | if (value !== undefined) { 105 | Struct_FieldsEntry.encode( 106 | { key: key as any, value }, 107 | writer.uint32(10).fork() 108 | ).ldelim(); 109 | } 110 | }); 111 | return writer; 112 | }, 113 | 114 | decode(input: _m0.Reader | Uint8Array, length?: number): Struct { 115 | const reader = 116 | input instanceof _m0.Reader ? input : _m0.Reader.create(input); 117 | let end = length === undefined ? reader.len : reader.pos + length; 118 | const message = createBaseStruct(); 119 | while (reader.pos < end) { 120 | const tag = reader.uint32(); 121 | switch (tag >>> 3) { 122 | case 1: 123 | if (tag !== 10) { 124 | break; 125 | } 126 | 127 | const entry1 = Struct_FieldsEntry.decode(reader, reader.uint32()); 128 | if (entry1.value !== undefined) { 129 | message.fields[entry1.key] = entry1.value; 130 | } 131 | continue; 132 | } 133 | if ((tag & 7) === 4 || tag === 0) { 134 | break; 135 | } 136 | reader.skipType(tag & 7); 137 | } 138 | return message; 139 | }, 140 | 141 | fromJSON(object: any): Struct { 142 | return { 143 | fields: isObject(object.fields) 144 | ? Object.entries(object.fields).reduce<{ 145 | [key: string]: any | undefined; 146 | }>((acc, [key, value]) => { 147 | acc[key] = value as any | undefined; 148 | return acc; 149 | }, {}) 150 | : {}, 151 | }; 152 | }, 153 | 154 | toJSON(message: Struct): unknown { 155 | const obj: any = {}; 156 | if (message.fields) { 157 | const entries = Object.entries(message.fields); 158 | if (entries.length > 0) { 159 | obj.fields = {}; 160 | entries.forEach(([k, v]) => { 161 | obj.fields[k] = v; 162 | }); 163 | } 164 | } 165 | return obj; 166 | }, 167 | 168 | create, I>>(base?: I): Struct { 169 | return Struct.fromPartial(base ?? ({} as any)); 170 | }, 171 | fromPartial, I>>(object: I): Struct { 172 | const message = createBaseStruct(); 173 | message.fields = Object.entries(object.fields ?? {}).reduce<{ 174 | [key: string]: any | undefined; 175 | }>((acc, [key, value]) => { 176 | if (value !== undefined) { 177 | acc[key] = value; 178 | } 179 | return acc; 180 | }, {}); 181 | return message; 182 | }, 183 | 184 | wrap(object: { [key: string]: any } | undefined): Struct { 185 | const struct = createBaseStruct(); 186 | if (object !== undefined) { 187 | Object.keys(object).forEach((key) => { 188 | struct.fields[key] = object[key]; 189 | }); 190 | } 191 | return struct; 192 | }, 193 | 194 | unwrap(message: Struct): { [key: string]: any } { 195 | const object: { [key: string]: any } = {}; 196 | if (message.fields) { 197 | Object.keys(message.fields).forEach((key) => { 198 | object[key] = message.fields[key]; 199 | }); 200 | } 201 | return object; 202 | }, 203 | }; 204 | 205 | function createBaseStruct_FieldsEntry(): Struct_FieldsEntry { 206 | return { key: '', value: undefined }; 207 | } 208 | 209 | export const Struct_FieldsEntry = { 210 | encode( 211 | message: Struct_FieldsEntry, 212 | writer: _m0.Writer = _m0.Writer.create() 213 | ): _m0.Writer { 214 | if (message.key !== '') { 215 | writer.uint32(10).string(message.key); 216 | } 217 | if (message.value !== undefined) { 218 | Value.encode( 219 | Value.wrap(message.value), 220 | writer.uint32(18).fork() 221 | ).ldelim(); 222 | } 223 | return writer; 224 | }, 225 | 226 | decode(input: _m0.Reader | Uint8Array, length?: number): Struct_FieldsEntry { 227 | const reader = 228 | input instanceof _m0.Reader ? input : _m0.Reader.create(input); 229 | let end = length === undefined ? reader.len : reader.pos + length; 230 | const message = createBaseStruct_FieldsEntry(); 231 | while (reader.pos < end) { 232 | const tag = reader.uint32(); 233 | switch (tag >>> 3) { 234 | case 1: 235 | if (tag !== 10) { 236 | break; 237 | } 238 | 239 | message.key = reader.string(); 240 | continue; 241 | case 2: 242 | if (tag !== 18) { 243 | break; 244 | } 245 | 246 | message.value = Value.unwrap(Value.decode(reader, reader.uint32())); 247 | continue; 248 | } 249 | if ((tag & 7) === 4 || tag === 0) { 250 | break; 251 | } 252 | reader.skipType(tag & 7); 253 | } 254 | return message; 255 | }, 256 | 257 | fromJSON(object: any): Struct_FieldsEntry { 258 | return { 259 | key: isSet(object.key) ? String(object.key) : '', 260 | value: isSet(object?.value) ? object.value : undefined, 261 | }; 262 | }, 263 | 264 | toJSON(message: Struct_FieldsEntry): unknown { 265 | const obj: any = {}; 266 | if (message.key !== '') { 267 | obj.key = message.key; 268 | } 269 | if (message.value !== undefined) { 270 | obj.value = message.value; 271 | } 272 | return obj; 273 | }, 274 | 275 | create, I>>( 276 | base?: I 277 | ): Struct_FieldsEntry { 278 | return Struct_FieldsEntry.fromPartial(base ?? ({} as any)); 279 | }, 280 | fromPartial, I>>( 281 | object: I 282 | ): Struct_FieldsEntry { 283 | const message = createBaseStruct_FieldsEntry(); 284 | message.key = object.key ?? ''; 285 | message.value = object.value ?? undefined; 286 | return message; 287 | }, 288 | }; 289 | 290 | function createBaseValue(): Value { 291 | return { 292 | null_value: undefined, 293 | number_value: undefined, 294 | string_value: undefined, 295 | bool_value: undefined, 296 | struct_value: undefined, 297 | list_value: undefined, 298 | }; 299 | } 300 | 301 | export const Value = { 302 | encode(message: Value, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { 303 | if (message.null_value !== undefined) { 304 | writer.uint32(8).int32(message.null_value); 305 | } 306 | if (message.number_value !== undefined) { 307 | writer.uint32(17).double(message.number_value); 308 | } 309 | if (message.string_value !== undefined) { 310 | writer.uint32(26).string(message.string_value); 311 | } 312 | if (message.bool_value !== undefined) { 313 | writer.uint32(32).bool(message.bool_value); 314 | } 315 | if (message.struct_value !== undefined) { 316 | Struct.encode( 317 | Struct.wrap(message.struct_value), 318 | writer.uint32(42).fork() 319 | ).ldelim(); 320 | } 321 | if (message.list_value !== undefined) { 322 | ListValue.encode( 323 | ListValue.wrap(message.list_value), 324 | writer.uint32(50).fork() 325 | ).ldelim(); 326 | } 327 | return writer; 328 | }, 329 | 330 | decode(input: _m0.Reader | Uint8Array, length?: number): Value { 331 | const reader = 332 | input instanceof _m0.Reader ? input : _m0.Reader.create(input); 333 | let end = length === undefined ? reader.len : reader.pos + length; 334 | const message = createBaseValue(); 335 | while (reader.pos < end) { 336 | const tag = reader.uint32(); 337 | switch (tag >>> 3) { 338 | case 1: 339 | if (tag !== 8) { 340 | break; 341 | } 342 | 343 | message.null_value = reader.int32() as any; 344 | continue; 345 | case 2: 346 | if (tag !== 17) { 347 | break; 348 | } 349 | 350 | message.number_value = reader.double(); 351 | continue; 352 | case 3: 353 | if (tag !== 26) { 354 | break; 355 | } 356 | 357 | message.string_value = reader.string(); 358 | continue; 359 | case 4: 360 | if (tag !== 32) { 361 | break; 362 | } 363 | 364 | message.bool_value = reader.bool(); 365 | continue; 366 | case 5: 367 | if (tag !== 42) { 368 | break; 369 | } 370 | 371 | message.struct_value = Struct.unwrap( 372 | Struct.decode(reader, reader.uint32()) 373 | ); 374 | continue; 375 | case 6: 376 | if (tag !== 50) { 377 | break; 378 | } 379 | 380 | message.list_value = ListValue.unwrap( 381 | ListValue.decode(reader, reader.uint32()) 382 | ); 383 | continue; 384 | } 385 | if ((tag & 7) === 4 || tag === 0) { 386 | break; 387 | } 388 | reader.skipType(tag & 7); 389 | } 390 | return message; 391 | }, 392 | 393 | fromJSON(object: any): Value { 394 | return { 395 | null_value: isSet(object.null_value) 396 | ? nullValueFromJSON(object.null_value) 397 | : undefined, 398 | number_value: isSet(object.number_value) 399 | ? Number(object.number_value) 400 | : undefined, 401 | string_value: isSet(object.string_value) 402 | ? String(object.string_value) 403 | : undefined, 404 | bool_value: isSet(object.bool_value) 405 | ? Boolean(object.bool_value) 406 | : undefined, 407 | struct_value: isObject(object.struct_value) 408 | ? object.struct_value 409 | : undefined, 410 | list_value: Array.isArray(object.list_value) 411 | ? [...object.list_value] 412 | : undefined, 413 | }; 414 | }, 415 | 416 | toJSON(message: Value): unknown { 417 | const obj: any = {}; 418 | if (message.null_value !== undefined) { 419 | obj.null_value = nullValueToJSON(message.null_value); 420 | } 421 | if (message.number_value !== undefined) { 422 | obj.number_value = message.number_value; 423 | } 424 | if (message.string_value !== undefined) { 425 | obj.string_value = message.string_value; 426 | } 427 | if (message.bool_value !== undefined) { 428 | obj.bool_value = message.bool_value; 429 | } 430 | if (message.struct_value !== undefined) { 431 | obj.struct_value = message.struct_value; 432 | } 433 | if (message.list_value !== undefined) { 434 | obj.list_value = message.list_value; 435 | } 436 | return obj; 437 | }, 438 | 439 | create, I>>(base?: I): Value { 440 | return Value.fromPartial(base ?? ({} as any)); 441 | }, 442 | fromPartial, I>>(object: I): Value { 443 | const message = createBaseValue(); 444 | message.null_value = object.null_value ?? undefined; 445 | message.number_value = object.number_value ?? undefined; 446 | message.string_value = object.string_value ?? undefined; 447 | message.bool_value = object.bool_value ?? undefined; 448 | message.struct_value = object.struct_value ?? undefined; 449 | message.list_value = object.list_value ?? undefined; 450 | return message; 451 | }, 452 | 453 | wrap(value: any): Value { 454 | const result = createBaseValue(); 455 | if (value === null) { 456 | result.null_value = NullValue.NULL_VALUE; 457 | } else if (typeof value === 'boolean') { 458 | result.bool_value = value; 459 | } else if (typeof value === 'number') { 460 | result.number_value = value; 461 | } else if (typeof value === 'string') { 462 | result.string_value = value; 463 | } else if (Array.isArray(value)) { 464 | result.list_value = value; 465 | } else if (typeof value === 'object') { 466 | result.struct_value = value; 467 | } else if (typeof value !== 'undefined') { 468 | throw new Error('Unsupported any value type: ' + typeof value); 469 | } 470 | return result; 471 | }, 472 | 473 | unwrap( 474 | message: any 475 | ): string | number | boolean | Object | null | Array | undefined { 476 | if (message.string_value !== undefined) { 477 | return message.string_value; 478 | } else if (message?.number_value !== undefined) { 479 | return message.number_value; 480 | } else if (message?.bool_value !== undefined) { 481 | return message.bool_value; 482 | } else if (message?.struct_value !== undefined) { 483 | return message.struct_value as any; 484 | } else if (message?.list_value !== undefined) { 485 | return message.list_value; 486 | } else if (message?.null_value !== undefined) { 487 | return null; 488 | } 489 | return undefined; 490 | }, 491 | }; 492 | 493 | function createBaseListValue(): ListValue { 494 | return { values: [] }; 495 | } 496 | 497 | export const ListValue = { 498 | encode( 499 | message: ListValue, 500 | writer: _m0.Writer = _m0.Writer.create() 501 | ): _m0.Writer { 502 | for (const v of message.values) { 503 | Value.encode(Value.wrap(v!), writer.uint32(10).fork()).ldelim(); 504 | } 505 | return writer; 506 | }, 507 | 508 | decode(input: _m0.Reader | Uint8Array, length?: number): ListValue { 509 | const reader = 510 | input instanceof _m0.Reader ? input : _m0.Reader.create(input); 511 | let end = length === undefined ? reader.len : reader.pos + length; 512 | const message = createBaseListValue(); 513 | while (reader.pos < end) { 514 | const tag = reader.uint32(); 515 | switch (tag >>> 3) { 516 | case 1: 517 | if (tag !== 10) { 518 | break; 519 | } 520 | 521 | message.values.push( 522 | Value.unwrap(Value.decode(reader, reader.uint32())) 523 | ); 524 | continue; 525 | } 526 | if ((tag & 7) === 4 || tag === 0) { 527 | break; 528 | } 529 | reader.skipType(tag & 7); 530 | } 531 | return message; 532 | }, 533 | 534 | fromJSON(object: any): ListValue { 535 | return { values: Array.isArray(object?.values) ? [...object.values] : [] }; 536 | }, 537 | 538 | toJSON(message: ListValue): unknown { 539 | const obj: any = {}; 540 | if (message.values?.length) { 541 | obj.values = message.values; 542 | } 543 | return obj; 544 | }, 545 | 546 | create, I>>(base?: I): ListValue { 547 | return ListValue.fromPartial(base ?? ({} as any)); 548 | }, 549 | fromPartial, I>>( 550 | object: I 551 | ): ListValue { 552 | const message = createBaseListValue(); 553 | message.values = object.values?.map((e) => e) || []; 554 | return message; 555 | }, 556 | 557 | wrap(array: Array | undefined): ListValue { 558 | const result = createBaseListValue(); 559 | result.values = array ?? []; 560 | return result; 561 | }, 562 | 563 | unwrap(message: ListValue): Array { 564 | if (message?.hasOwnProperty('values') && Array.isArray(message.values)) { 565 | return message.values; 566 | } else { 567 | return message as any; 568 | } 569 | }, 570 | }; 571 | 572 | type Builtin = 573 | | Date 574 | | Function 575 | | Uint8Array 576 | | string 577 | | number 578 | | boolean 579 | | undefined; 580 | 581 | export type DeepPartial = T extends Builtin 582 | ? T 583 | : T extends Long 584 | ? string | number | Long 585 | : T extends Array 586 | ? Array> 587 | : T extends ReadonlyArray 588 | ? ReadonlyArray> 589 | : T extends {} 590 | ? { [K in keyof T]?: DeepPartial } 591 | : Partial; 592 | 593 | type KeysOfUnion = T extends T ? keyof T : never; 594 | export type Exact = P extends Builtin 595 | ? P 596 | : P & { [K in keyof P]: Exact } & { 597 | [K in Exclude>]: never; 598 | }; 599 | 600 | if (_m0.util.Long !== Long) { 601 | _m0.util.Long = Long as any; 602 | _m0.configure(); 603 | } 604 | 605 | function isObject(value: any): boolean { 606 | return typeof value === 'object' && value !== null; 607 | } 608 | 609 | function isSet(value: any): boolean { 610 | return value !== null && value !== undefined; 611 | } 612 | -------------------------------------------------------------------------------- /src/proto/gno/vm.ts: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-ts_proto. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-ts_proto v2.7.5 4 | // protoc v5.29.3 5 | // source: gno/vm.proto 6 | 7 | /* eslint-disable */ 8 | import { BinaryReader, BinaryWriter } from '@bufbuild/protobuf/wire'; 9 | import Long from 'long'; 10 | import { Any } from '../google/protobuf/any'; 11 | 12 | export const protobufPackage = 'gno.vm'; 13 | 14 | /** 15 | * MsgCall is the method invocation tx message, 16 | * denoted as "m_call" 17 | */ 18 | export interface MsgCall { 19 | /** the bech32 address of the caller */ 20 | caller: string; 21 | /** the amount of funds to be deposited to the package, if any ("") */ 22 | send: string; 23 | /** the amount of funds to lock for the storage, if any ("") */ 24 | max_deposit: string; 25 | /** the gno package path */ 26 | pkg_path: string; 27 | /** the function name being invoked */ 28 | func: string; 29 | /** the function arguments */ 30 | args: string[]; 31 | } 32 | 33 | /** 34 | * MsgAddPackage is the package deployment tx message, 35 | * denoted as "m_addpkg" 36 | */ 37 | export interface MsgAddPackage { 38 | /** the package deployer */ 39 | creator: string; 40 | /** the package being deployed */ 41 | package?: MemPackage | undefined; 42 | /** the amount of funds to be deposited at deployment, if any ("") */ 43 | send: string; 44 | /** the amount of funds to put down for the storage fee, if any ("") */ 45 | max_deposit: string; 46 | } 47 | 48 | /** 49 | * MsgRun is the execute arbitrary Gno code tx message, 50 | * denoted as "m_run" 51 | */ 52 | export interface MsgRun { 53 | /** the bech32 address of the caller */ 54 | caller: string; 55 | /** the amount of funds to be deposited to the package, if any ("") */ 56 | send: string; 57 | /** the amount of funds to put down for the storage fee, if any ("") */ 58 | max_deposit: string; 59 | /** the package being executed */ 60 | package?: MemPackage | undefined; 61 | } 62 | 63 | /** 64 | * MemPackage is the metadata information tied to 65 | * package / realm deployment 66 | */ 67 | export interface MemPackage { 68 | /** the name of the package */ 69 | name: string; 70 | /** the gno path of the package */ 71 | path: string; 72 | /** the associated package gno source */ 73 | files: MemFile[]; 74 | /** the (user defined) package type */ 75 | type?: Any | undefined; 76 | /** the (user defined) extra information */ 77 | info?: Any | undefined; 78 | } 79 | 80 | /** 81 | * MemFile is the metadata information tied to 82 | * a single gno package / realm file 83 | */ 84 | export interface MemFile { 85 | /** the name of the source gno file */ 86 | name: string; 87 | /** the content of the source gno file */ 88 | body: string; 89 | } 90 | 91 | function createBaseMsgCall(): MsgCall { 92 | return { 93 | caller: '', 94 | send: '', 95 | max_deposit: '', 96 | pkg_path: '', 97 | func: '', 98 | args: [], 99 | }; 100 | } 101 | 102 | export const MsgCall: MessageFns = { 103 | encode( 104 | message: MsgCall, 105 | writer: BinaryWriter = new BinaryWriter() 106 | ): BinaryWriter { 107 | if (message.caller !== '') { 108 | writer.uint32(10).string(message.caller); 109 | } 110 | if (message.send !== '') { 111 | writer.uint32(18).string(message.send); 112 | } 113 | if (message.max_deposit !== '') { 114 | writer.uint32(26).string(message.max_deposit); 115 | } 116 | if (message.pkg_path !== '') { 117 | writer.uint32(34).string(message.pkg_path); 118 | } 119 | if (message.func !== '') { 120 | writer.uint32(42).string(message.func); 121 | } 122 | for (const v of message.args) { 123 | writer.uint32(50).string(v!); 124 | } 125 | return writer; 126 | }, 127 | 128 | decode(input: BinaryReader | Uint8Array, length?: number): MsgCall { 129 | const reader = 130 | input instanceof BinaryReader ? input : new BinaryReader(input); 131 | const end = length === undefined ? reader.len : reader.pos + length; 132 | const message = createBaseMsgCall(); 133 | while (reader.pos < end) { 134 | const tag = reader.uint32(); 135 | switch (tag >>> 3) { 136 | case 1: { 137 | if (tag !== 10) { 138 | break; 139 | } 140 | 141 | message.caller = reader.string(); 142 | continue; 143 | } 144 | case 2: { 145 | if (tag !== 18) { 146 | break; 147 | } 148 | 149 | message.send = reader.string(); 150 | continue; 151 | } 152 | case 3: { 153 | if (tag !== 26) { 154 | break; 155 | } 156 | 157 | message.max_deposit = reader.string(); 158 | continue; 159 | } 160 | case 4: { 161 | if (tag !== 34) { 162 | break; 163 | } 164 | 165 | message.pkg_path = reader.string(); 166 | continue; 167 | } 168 | case 5: { 169 | if (tag !== 42) { 170 | break; 171 | } 172 | 173 | message.func = reader.string(); 174 | continue; 175 | } 176 | case 6: { 177 | if (tag !== 50) { 178 | break; 179 | } 180 | 181 | message.args.push(reader.string()); 182 | continue; 183 | } 184 | } 185 | if ((tag & 7) === 4 || tag === 0) { 186 | break; 187 | } 188 | reader.skip(tag & 7); 189 | } 190 | return message; 191 | }, 192 | 193 | fromJSON(object: any): MsgCall { 194 | return { 195 | caller: isSet(object.caller) ? globalThis.String(object.caller) : '', 196 | send: isSet(object.send) ? globalThis.String(object.send) : '', 197 | max_deposit: isSet(object.max_deposit) 198 | ? globalThis.String(object.max_deposit) 199 | : '', 200 | pkg_path: isSet(object.pkg_path) 201 | ? globalThis.String(object.pkg_path) 202 | : '', 203 | func: isSet(object.func) ? globalThis.String(object.func) : '', 204 | args: globalThis.Array.isArray(object?.args) 205 | ? object.args.map((e: any) => globalThis.String(e)) 206 | : [], 207 | }; 208 | }, 209 | 210 | toJSON(message: MsgCall): unknown { 211 | const obj: any = {}; 212 | if (message.caller !== undefined) { 213 | obj.caller = message.caller; 214 | } 215 | if (message.send !== undefined) { 216 | obj.send = message.send; 217 | } 218 | if (message.max_deposit !== undefined) { 219 | obj.max_deposit = message.max_deposit; 220 | } 221 | if (message.pkg_path !== undefined) { 222 | obj.pkg_path = message.pkg_path; 223 | } 224 | if (message.func !== undefined) { 225 | obj.func = message.func; 226 | } 227 | if (message.args?.length) { 228 | obj.args = message.args; 229 | } 230 | return obj; 231 | }, 232 | 233 | create, I>>(base?: I): MsgCall { 234 | return MsgCall.fromPartial(base ?? ({} as any)); 235 | }, 236 | fromPartial, I>>(object: I): MsgCall { 237 | const message = createBaseMsgCall(); 238 | message.caller = object.caller ?? ''; 239 | message.send = object.send ?? ''; 240 | message.max_deposit = object.max_deposit ?? ''; 241 | message.pkg_path = object.pkg_path ?? ''; 242 | message.func = object.func ?? ''; 243 | message.args = object.args?.map((e) => e) || []; 244 | return message; 245 | }, 246 | }; 247 | 248 | function createBaseMsgAddPackage(): MsgAddPackage { 249 | return { creator: '', package: undefined, send: '', max_deposit: '' }; 250 | } 251 | 252 | export const MsgAddPackage: MessageFns = { 253 | encode( 254 | message: MsgAddPackage, 255 | writer: BinaryWriter = new BinaryWriter() 256 | ): BinaryWriter { 257 | if (message.creator !== '') { 258 | writer.uint32(10).string(message.creator); 259 | } 260 | if (message.package !== undefined) { 261 | MemPackage.encode(message.package, writer.uint32(18).fork()).join(); 262 | } 263 | if (message.send !== '') { 264 | writer.uint32(26).string(message.send); 265 | } 266 | if (message.max_deposit !== '') { 267 | writer.uint32(34).string(message.max_deposit); 268 | } 269 | return writer; 270 | }, 271 | 272 | decode(input: BinaryReader | Uint8Array, length?: number): MsgAddPackage { 273 | const reader = 274 | input instanceof BinaryReader ? input : new BinaryReader(input); 275 | const end = length === undefined ? reader.len : reader.pos + length; 276 | const message = createBaseMsgAddPackage(); 277 | while (reader.pos < end) { 278 | const tag = reader.uint32(); 279 | switch (tag >>> 3) { 280 | case 1: { 281 | if (tag !== 10) { 282 | break; 283 | } 284 | 285 | message.creator = reader.string(); 286 | continue; 287 | } 288 | case 2: { 289 | if (tag !== 18) { 290 | break; 291 | } 292 | 293 | message.package = MemPackage.decode(reader, reader.uint32()); 294 | continue; 295 | } 296 | case 3: { 297 | if (tag !== 26) { 298 | break; 299 | } 300 | 301 | message.send = reader.string(); 302 | continue; 303 | } 304 | case 4: { 305 | if (tag !== 34) { 306 | break; 307 | } 308 | 309 | message.max_deposit = reader.string(); 310 | continue; 311 | } 312 | } 313 | if ((tag & 7) === 4 || tag === 0) { 314 | break; 315 | } 316 | reader.skip(tag & 7); 317 | } 318 | return message; 319 | }, 320 | 321 | fromJSON(object: any): MsgAddPackage { 322 | return { 323 | creator: isSet(object.creator) ? globalThis.String(object.creator) : '', 324 | package: isSet(object.package) 325 | ? MemPackage.fromJSON(object.package) 326 | : undefined, 327 | send: isSet(object.send) ? globalThis.String(object.send) : '', 328 | max_deposit: isSet(object.max_deposit) 329 | ? globalThis.String(object.max_deposit) 330 | : '', 331 | }; 332 | }, 333 | 334 | toJSON(message: MsgAddPackage): unknown { 335 | const obj: any = {}; 336 | if (message.creator !== undefined) { 337 | obj.creator = message.creator; 338 | } 339 | if (message.package !== undefined) { 340 | obj.package = MemPackage.toJSON(message.package); 341 | } 342 | if (message.send !== undefined) { 343 | obj.send = message.send; 344 | } 345 | if (message.max_deposit !== undefined) { 346 | obj.max_deposit = message.max_deposit; 347 | } 348 | return obj; 349 | }, 350 | 351 | create, I>>( 352 | base?: I 353 | ): MsgAddPackage { 354 | return MsgAddPackage.fromPartial(base ?? ({} as any)); 355 | }, 356 | fromPartial, I>>( 357 | object: I 358 | ): MsgAddPackage { 359 | const message = createBaseMsgAddPackage(); 360 | message.creator = object.creator ?? ''; 361 | message.package = 362 | object.package !== undefined && object.package !== null 363 | ? MemPackage.fromPartial(object.package) 364 | : undefined; 365 | message.send = object.send ?? ''; 366 | message.max_deposit = object.max_deposit ?? ''; 367 | return message; 368 | }, 369 | }; 370 | 371 | function createBaseMsgRun(): MsgRun { 372 | return { caller: '', send: '', max_deposit: '', package: undefined }; 373 | } 374 | 375 | export const MsgRun: MessageFns = { 376 | encode( 377 | message: MsgRun, 378 | writer: BinaryWriter = new BinaryWriter() 379 | ): BinaryWriter { 380 | if (message.caller !== '') { 381 | writer.uint32(10).string(message.caller); 382 | } 383 | if (message.send !== '') { 384 | writer.uint32(18).string(message.send); 385 | } 386 | if (message.max_deposit !== '') { 387 | writer.uint32(26).string(message.max_deposit); 388 | } 389 | if (message.package !== undefined) { 390 | MemPackage.encode(message.package, writer.uint32(34).fork()).join(); 391 | } 392 | return writer; 393 | }, 394 | 395 | decode(input: BinaryReader | Uint8Array, length?: number): MsgRun { 396 | const reader = 397 | input instanceof BinaryReader ? input : new BinaryReader(input); 398 | const end = length === undefined ? reader.len : reader.pos + length; 399 | const message = createBaseMsgRun(); 400 | while (reader.pos < end) { 401 | const tag = reader.uint32(); 402 | switch (tag >>> 3) { 403 | case 1: { 404 | if (tag !== 10) { 405 | break; 406 | } 407 | 408 | message.caller = reader.string(); 409 | continue; 410 | } 411 | case 2: { 412 | if (tag !== 18) { 413 | break; 414 | } 415 | 416 | message.send = reader.string(); 417 | continue; 418 | } 419 | case 3: { 420 | if (tag !== 26) { 421 | break; 422 | } 423 | 424 | message.max_deposit = reader.string(); 425 | continue; 426 | } 427 | case 4: { 428 | if (tag !== 34) { 429 | break; 430 | } 431 | 432 | message.package = MemPackage.decode(reader, reader.uint32()); 433 | continue; 434 | } 435 | } 436 | if ((tag & 7) === 4 || tag === 0) { 437 | break; 438 | } 439 | reader.skip(tag & 7); 440 | } 441 | return message; 442 | }, 443 | 444 | fromJSON(object: any): MsgRun { 445 | return { 446 | caller: isSet(object.caller) ? globalThis.String(object.caller) : '', 447 | send: isSet(object.send) ? globalThis.String(object.send) : '', 448 | max_deposit: isSet(object.max_deposit) 449 | ? globalThis.String(object.max_deposit) 450 | : '', 451 | package: isSet(object.package) 452 | ? MemPackage.fromJSON(object.package) 453 | : undefined, 454 | }; 455 | }, 456 | 457 | toJSON(message: MsgRun): unknown { 458 | const obj: any = {}; 459 | if (message.caller !== undefined) { 460 | obj.caller = message.caller; 461 | } 462 | if (message.send !== undefined) { 463 | obj.send = message.send; 464 | } 465 | if (message.max_deposit !== undefined) { 466 | obj.max_deposit = message.max_deposit; 467 | } 468 | if (message.package !== undefined) { 469 | obj.package = MemPackage.toJSON(message.package); 470 | } 471 | return obj; 472 | }, 473 | 474 | create, I>>(base?: I): MsgRun { 475 | return MsgRun.fromPartial(base ?? ({} as any)); 476 | }, 477 | fromPartial, I>>(object: I): MsgRun { 478 | const message = createBaseMsgRun(); 479 | message.caller = object.caller ?? ''; 480 | message.send = object.send ?? ''; 481 | message.max_deposit = object.max_deposit ?? ''; 482 | message.package = 483 | object.package !== undefined && object.package !== null 484 | ? MemPackage.fromPartial(object.package) 485 | : undefined; 486 | return message; 487 | }, 488 | }; 489 | 490 | function createBaseMemPackage(): MemPackage { 491 | return { name: '', path: '', files: [], type: undefined, info: undefined }; 492 | } 493 | 494 | export const MemPackage: MessageFns = { 495 | encode( 496 | message: MemPackage, 497 | writer: BinaryWriter = new BinaryWriter() 498 | ): BinaryWriter { 499 | if (message.name !== '') { 500 | writer.uint32(10).string(message.name); 501 | } 502 | if (message.path !== '') { 503 | writer.uint32(18).string(message.path); 504 | } 505 | for (const v of message.files) { 506 | MemFile.encode(v!, writer.uint32(26).fork()).join(); 507 | } 508 | if (message.type !== undefined) { 509 | Any.encode(message.type, writer.uint32(34).fork()).join(); 510 | } 511 | if (message.info !== undefined) { 512 | Any.encode(message.info, writer.uint32(42).fork()).join(); 513 | } 514 | return writer; 515 | }, 516 | 517 | decode(input: BinaryReader | Uint8Array, length?: number): MemPackage { 518 | const reader = 519 | input instanceof BinaryReader ? input : new BinaryReader(input); 520 | const end = length === undefined ? reader.len : reader.pos + length; 521 | const message = createBaseMemPackage(); 522 | while (reader.pos < end) { 523 | const tag = reader.uint32(); 524 | switch (tag >>> 3) { 525 | case 1: { 526 | if (tag !== 10) { 527 | break; 528 | } 529 | 530 | message.name = reader.string(); 531 | continue; 532 | } 533 | case 2: { 534 | if (tag !== 18) { 535 | break; 536 | } 537 | 538 | message.path = reader.string(); 539 | continue; 540 | } 541 | case 3: { 542 | if (tag !== 26) { 543 | break; 544 | } 545 | 546 | message.files.push(MemFile.decode(reader, reader.uint32())); 547 | continue; 548 | } 549 | case 4: { 550 | if (tag !== 34) { 551 | break; 552 | } 553 | 554 | message.type = Any.decode(reader, reader.uint32()); 555 | continue; 556 | } 557 | case 5: { 558 | if (tag !== 42) { 559 | break; 560 | } 561 | 562 | message.info = Any.decode(reader, reader.uint32()); 563 | continue; 564 | } 565 | } 566 | if ((tag & 7) === 4 || tag === 0) { 567 | break; 568 | } 569 | reader.skip(tag & 7); 570 | } 571 | return message; 572 | }, 573 | 574 | fromJSON(object: any): MemPackage { 575 | return { 576 | name: isSet(object.name) ? globalThis.String(object.name) : '', 577 | path: isSet(object.path) ? globalThis.String(object.path) : '', 578 | files: globalThis.Array.isArray(object?.files) 579 | ? object.files.map((e: any) => MemFile.fromJSON(e)) 580 | : [], 581 | type: isSet(object.type) ? Any.fromJSON(object.type) : undefined, 582 | info: isSet(object.info) ? Any.fromJSON(object.info) : undefined, 583 | }; 584 | }, 585 | 586 | toJSON(message: MemPackage): unknown { 587 | const obj: any = {}; 588 | if (message.name !== undefined) { 589 | obj.name = message.name; 590 | } 591 | if (message.path !== undefined) { 592 | obj.path = message.path; 593 | } 594 | if (message.files?.length) { 595 | obj.files = message.files.map((e) => MemFile.toJSON(e)); 596 | } 597 | if (message.type !== undefined) { 598 | obj.type = Any.toJSON(message.type); 599 | } 600 | if (message.info !== undefined) { 601 | obj.info = Any.toJSON(message.info); 602 | } 603 | return obj; 604 | }, 605 | 606 | create, I>>(base?: I): MemPackage { 607 | return MemPackage.fromPartial(base ?? ({} as any)); 608 | }, 609 | fromPartial, I>>( 610 | object: I 611 | ): MemPackage { 612 | const message = createBaseMemPackage(); 613 | message.name = object.name ?? ''; 614 | message.path = object.path ?? ''; 615 | message.files = object.files?.map((e) => MemFile.fromPartial(e)) || []; 616 | message.type = 617 | object.type !== undefined && object.type !== null 618 | ? Any.fromPartial(object.type) 619 | : undefined; 620 | message.info = 621 | object.info !== undefined && object.info !== null 622 | ? Any.fromPartial(object.info) 623 | : undefined; 624 | return message; 625 | }, 626 | }; 627 | 628 | function createBaseMemFile(): MemFile { 629 | return { name: '', body: '' }; 630 | } 631 | 632 | export const MemFile: MessageFns = { 633 | encode( 634 | message: MemFile, 635 | writer: BinaryWriter = new BinaryWriter() 636 | ): BinaryWriter { 637 | if (message.name !== '') { 638 | writer.uint32(10).string(message.name); 639 | } 640 | if (message.body !== '') { 641 | writer.uint32(18).string(message.body); 642 | } 643 | return writer; 644 | }, 645 | 646 | decode(input: BinaryReader | Uint8Array, length?: number): MemFile { 647 | const reader = 648 | input instanceof BinaryReader ? input : new BinaryReader(input); 649 | const end = length === undefined ? reader.len : reader.pos + length; 650 | const message = createBaseMemFile(); 651 | while (reader.pos < end) { 652 | const tag = reader.uint32(); 653 | switch (tag >>> 3) { 654 | case 1: { 655 | if (tag !== 10) { 656 | break; 657 | } 658 | 659 | message.name = reader.string(); 660 | continue; 661 | } 662 | case 2: { 663 | if (tag !== 18) { 664 | break; 665 | } 666 | 667 | message.body = reader.string(); 668 | continue; 669 | } 670 | } 671 | if ((tag & 7) === 4 || tag === 0) { 672 | break; 673 | } 674 | reader.skip(tag & 7); 675 | } 676 | return message; 677 | }, 678 | 679 | fromJSON(object: any): MemFile { 680 | return { 681 | name: isSet(object.name) ? globalThis.String(object.name) : '', 682 | body: isSet(object.body) ? globalThis.String(object.body) : '', 683 | }; 684 | }, 685 | 686 | toJSON(message: MemFile): unknown { 687 | const obj: any = {}; 688 | if (message.name !== undefined) { 689 | obj.name = message.name; 690 | } 691 | if (message.body !== undefined) { 692 | obj.body = message.body; 693 | } 694 | return obj; 695 | }, 696 | 697 | create, I>>(base?: I): MemFile { 698 | return MemFile.fromPartial(base ?? ({} as any)); 699 | }, 700 | fromPartial, I>>(object: I): MemFile { 701 | const message = createBaseMemFile(); 702 | message.name = object.name ?? ''; 703 | message.body = object.body ?? ''; 704 | return message; 705 | }, 706 | }; 707 | 708 | type Builtin = 709 | | Date 710 | | Function 711 | | Uint8Array 712 | | string 713 | | number 714 | | boolean 715 | | undefined; 716 | 717 | export type DeepPartial = T extends Builtin 718 | ? T 719 | : T extends Long 720 | ? string | number | Long 721 | : T extends globalThis.Array 722 | ? globalThis.Array> 723 | : T extends ReadonlyArray 724 | ? ReadonlyArray> 725 | : T extends {} 726 | ? { [K in keyof T]?: DeepPartial } 727 | : Partial; 728 | 729 | type KeysOfUnion = T extends T ? keyof T : never; 730 | export type Exact = P extends Builtin 731 | ? P 732 | : P & { [K in keyof P]: Exact } & { 733 | [K in Exclude>]: never; 734 | }; 735 | 736 | function isSet(value: any): boolean { 737 | return value !== null && value !== undefined; 738 | } 739 | 740 | export interface MessageFns { 741 | encode(message: T, writer?: BinaryWriter): BinaryWriter; 742 | decode(input: BinaryReader | Uint8Array, length?: number): T; 743 | fromJSON(object: any): T; 744 | toJSON(message: T): unknown; 745 | create, I>>(base?: I): T; 746 | fromPartial, I>>(object: I): T; 747 | } 748 | --------------------------------------------------------------------------------