From 64775caefc425df17f893fe1a5ae26d21adc7b6b Mon Sep 17 00:00:00 2001 From: Bhavi Dhingra Date: Fri, 27 Sep 2024 18:50:59 +0530 Subject: [PATCH] feat(sdk-coin-rune): new coin generation TICKET: WIN-3550 --- .gitcommitscopes | 1 + Dockerfile | 3 + modules/abstract-cosmos/.eslintignore | 2 +- modules/abstract-cosmos/package.json | 8 +- .../resources/MsgCompiled.d.ts | 1212 ++++++++ .../abstract-cosmos/resources/MsgCompiled.js | 2761 +++++++++++++++++ modules/abstract-cosmos/src/lib/constants.ts | 1 + modules/abstract-cosmos/src/lib/utils.ts | 6 +- modules/abstract-cosmos/tsconfig.json | 4 +- modules/account-lib/package.json | 1 + modules/account-lib/src/index.ts | 5 + modules/bitgo/package.json | 1 + modules/bitgo/src/v2/coinFactory.ts | 4 + modules/bitgo/src/v2/coins/index.ts | 2 + modules/bitgo/test/browser/browser.spec.ts | 3 + modules/bitgo/test/v2/unit/keychains.ts | 1 + modules/bitgo/tsconfig.json | 7 +- modules/sdk-coin-rune/.eslintignore | 5 + modules/sdk-coin-rune/.gitignore | 3 + modules/sdk-coin-rune/.mocharc.yml | 8 + modules/sdk-coin-rune/.npmignore | 14 + modules/sdk-coin-rune/.prettierignore | 2 + modules/sdk-coin-rune/.prettierrc.yml | 3 + modules/sdk-coin-rune/README.md | 30 + modules/sdk-coin-rune/package.json | 58 + modules/sdk-coin-rune/src/index.ts | 4 + modules/sdk-coin-rune/src/lib/constants.ts | 12 + modules/sdk-coin-rune/src/lib/iface.ts | 6 + modules/sdk-coin-rune/src/lib/index.ts | 10 + modules/sdk-coin-rune/src/lib/keyPair.ts | 27 + .../src/lib/transactionBuilderFactory.ts | 101 + .../sdk-coin-rune/src/lib/transferBuilder.ts | 28 + modules/sdk-coin-rune/src/lib/utils.ts | 138 + modules/sdk-coin-rune/src/register.ts | 8 + modules/sdk-coin-rune/src/rune.ts | 109 + modules/sdk-coin-rune/src/trune.ts | 39 + modules/sdk-coin-rune/test/resources/rune.ts | 49 + modules/sdk-coin-rune/test/resources/trune.ts | 95 + modules/sdk-coin-rune/test/unit/keyPair.ts | 119 + modules/sdk-coin-rune/test/unit/rune.ts | 268 ++ .../sdk-coin-rune/test/unit/transaction.ts | 138 + .../transactionBuilder/transactionBuilder.ts | 68 + .../transactionBuilder/transferBuilder.ts | 186 ++ modules/sdk-coin-rune/test/unit/utils.ts | 60 + modules/sdk-coin-rune/tsconfig.json | 23 + modules/statics/src/base.ts | 2 + modules/statics/src/coins.ts | 20 + modules/statics/src/networks.ts | 14 + modules/statics/test/unit/coins.ts | 8 +- .../unit/fixtures/expectedColdFeatures.ts | 2 + tsconfig.packages.json | 7 +- yarn.lock | 29 +- 52 files changed, 5698 insertions(+), 17 deletions(-) create mode 100644 modules/abstract-cosmos/resources/MsgCompiled.d.ts create mode 100644 modules/abstract-cosmos/resources/MsgCompiled.js create mode 100644 modules/sdk-coin-rune/.eslintignore create mode 100644 modules/sdk-coin-rune/.gitignore create mode 100644 modules/sdk-coin-rune/.mocharc.yml create mode 100644 modules/sdk-coin-rune/.npmignore create mode 100644 modules/sdk-coin-rune/.prettierignore create mode 100644 modules/sdk-coin-rune/.prettierrc.yml create mode 100644 modules/sdk-coin-rune/README.md create mode 100644 modules/sdk-coin-rune/package.json create mode 100644 modules/sdk-coin-rune/src/index.ts create mode 100644 modules/sdk-coin-rune/src/lib/constants.ts create mode 100644 modules/sdk-coin-rune/src/lib/iface.ts create mode 100644 modules/sdk-coin-rune/src/lib/index.ts create mode 100644 modules/sdk-coin-rune/src/lib/keyPair.ts create mode 100644 modules/sdk-coin-rune/src/lib/transactionBuilderFactory.ts create mode 100644 modules/sdk-coin-rune/src/lib/transferBuilder.ts create mode 100644 modules/sdk-coin-rune/src/lib/utils.ts create mode 100644 modules/sdk-coin-rune/src/register.ts create mode 100644 modules/sdk-coin-rune/src/rune.ts create mode 100644 modules/sdk-coin-rune/src/trune.ts create mode 100644 modules/sdk-coin-rune/test/resources/rune.ts create mode 100644 modules/sdk-coin-rune/test/resources/trune.ts create mode 100644 modules/sdk-coin-rune/test/unit/keyPair.ts create mode 100644 modules/sdk-coin-rune/test/unit/rune.ts create mode 100644 modules/sdk-coin-rune/test/unit/transaction.ts create mode 100644 modules/sdk-coin-rune/test/unit/transactionBuilder/transactionBuilder.ts create mode 100644 modules/sdk-coin-rune/test/unit/transactionBuilder/transferBuilder.ts create mode 100644 modules/sdk-coin-rune/test/unit/utils.ts create mode 100644 modules/sdk-coin-rune/tsconfig.json diff --git a/.gitcommitscopes b/.gitcommitscopes index 25ae314b21..e9fd273494 100644 --- a/.gitcommitscopes +++ b/.gitcommitscopes @@ -1 +1,2 @@ +sdk-coin-rune sdk-coin-sui diff --git a/Dockerfile b/Dockerfile index 1607197773..e365561933 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,6 +80,7 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-opeth /var/modules/sdk-coin-opet COPY --from=builder /tmp/bitgo/modules/sdk-coin-osmo /var/modules/sdk-coin-osmo/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-polygon /var/modules/sdk-coin-polygon/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-rbtc /var/modules/sdk-coin-rbtc/ +COPY --from=builder /tmp/bitgo/modules/sdk-coin-rune /var/modules/sdk-coin-rune/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-sei /var/modules/sdk-coin-sei/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-sol /var/modules/sdk-coin-sol/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-stx /var/modules/sdk-coin-stx/ @@ -150,6 +151,7 @@ cd /var/modules/sdk-coin-opeth && yarn link && \ cd /var/modules/sdk-coin-osmo && yarn link && \ cd /var/modules/sdk-coin-polygon && yarn link && \ cd /var/modules/sdk-coin-rbtc && yarn link && \ +cd /var/modules/sdk-coin-rune && yarn link && \ cd /var/modules/sdk-coin-sei && yarn link && \ cd /var/modules/sdk-coin-sol && yarn link && \ cd /var/modules/sdk-coin-stx && yarn link && \ @@ -223,6 +225,7 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/sdk-coin-osmo && \ yarn link @bitgo/sdk-coin-polygon && \ yarn link @bitgo/sdk-coin-rbtc && \ + yarn link @bitgo/sdk-coin-rune && \ yarn link @bitgo/sdk-coin-sei && \ yarn link @bitgo/sdk-coin-sol && \ yarn link @bitgo/sdk-coin-stx && \ diff --git a/modules/abstract-cosmos/.eslintignore b/modules/abstract-cosmos/.eslintignore index 190f83e0df..c4c8af8b66 100644 --- a/modules/abstract-cosmos/.eslintignore +++ b/modules/abstract-cosmos/.eslintignore @@ -2,4 +2,4 @@ node_modules .idea public dist - +resources diff --git a/modules/abstract-cosmos/package.json b/modules/abstract-cosmos/package.json index 2dcbdfe9c6..5f72fa5b15 100644 --- a/modules/abstract-cosmos/package.json +++ b/modules/abstract-cosmos/package.json @@ -5,12 +5,13 @@ "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "scripts": { - "build": "yarn tsc --build --incremental --verbose .", + "build": "npm run prepare", + "build-ts": "yarn tsc --build --incremental --verbose .", "fmt": "prettier --write .", "check-fmt": "prettier --check .", "clean": "rm -r ./dist", "lint": "eslint --quiet .", - "prepare": "npm run build" + "prepare": "npm run build-ts && shx cp -r ./resources ./dist" }, "author": "BitGo SDK Team ", "license": "MIT", @@ -49,7 +50,8 @@ "bignumber.js": "^9.1.1", "cosmjs-types": "^0.6.1", "lodash": "^4.17.21", - "superagent": "^9.0.1" + "superagent": "^9.0.1", + "protobufjs": "^7.4.0" }, "devDependencies": { "@types/lodash": "^4.14.183" diff --git a/modules/abstract-cosmos/resources/MsgCompiled.d.ts b/modules/abstract-cosmos/resources/MsgCompiled.d.ts new file mode 100644 index 0000000000..de4d32a5f1 --- /dev/null +++ b/modules/abstract-cosmos/resources/MsgCompiled.d.ts @@ -0,0 +1,1212 @@ +import * as $protobuf from 'protobufjs'; +/** Namespace common. */ +export namespace common { + /** Properties of an Asset. */ + interface IAsset { + /** Asset chain */ + chain?: string | null; + + /** Asset symbol */ + symbol?: string | null; + + /** Asset ticker */ + ticker?: string | null; + + /** Asset synth */ + synth?: boolean | null; + + /** Asset trade */ + trade?: boolean | null; + } + + /** Represents an Asset. */ + class Asset implements IAsset { + /** + * Constructs a new Asset. + * @param [properties] Properties to set + */ + constructor(properties?: common.IAsset); + + /** Asset chain. */ + public chain: string; + + /** Asset symbol. */ + public symbol: string; + + /** Asset ticker. */ + public ticker: string; + + /** Asset synth. */ + public synth: boolean; + + /** Asset trade. */ + public trade: boolean; + + /** + * Creates a new Asset instance using the specified properties. + * @param [properties] Properties to set + * @returns Asset instance + */ + public static create(properties?: common.IAsset): common.Asset; + + /** + * Encodes the specified Asset message. Does not implicitly {@link common.Asset.verify|verify} messages. + * @param message Asset message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.IAsset, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Asset message, length delimited. Does not implicitly {@link common.Asset.verify|verify} messages. + * @param message Asset message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.IAsset, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an Asset message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Asset + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.Asset; + + /** + * Decodes an Asset message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Asset + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.Asset; + + /** + * Verifies an Asset message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates an Asset message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Asset + */ + public static fromObject(object: { [k: string]: any }): common.Asset; + + /** + * Creates a plain object from an Asset message. Also converts values to other types if specified. + * @param message Asset + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.Asset, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Asset to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Coin. */ + interface ICoin { + /** Coin asset */ + asset?: common.IAsset | null; + + /** Coin amount */ + amount?: string | null; + + /** Coin decimals */ + decimals?: number | Long | null; + } + + /** Represents a Coin. */ + class Coin implements ICoin { + /** + * Constructs a new Coin. + * @param [properties] Properties to set + */ + constructor(properties?: common.ICoin); + + /** Coin asset. */ + public asset?: common.IAsset | null; + + /** Coin amount. */ + public amount: string; + + /** Coin decimals. */ + public decimals: number | Long; + + /** + * Creates a new Coin instance using the specified properties. + * @param [properties] Properties to set + * @returns Coin instance + */ + public static create(properties?: common.ICoin): common.Coin; + + /** + * Encodes the specified Coin message. Does not implicitly {@link common.Coin.verify|verify} messages. + * @param message Coin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.ICoin, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Coin message, length delimited. Does not implicitly {@link common.Coin.verify|verify} messages. + * @param message Coin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.ICoin, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Coin message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.Coin; + + /** + * Decodes a Coin message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.Coin; + + /** + * Verifies a Coin message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a Coin message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Coin + */ + public static fromObject(object: { [k: string]: any }): common.Coin; + + /** + * Creates a plain object from a Coin message. Also converts values to other types if specified. + * @param message Coin + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.Coin, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Coin to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a PubKeySet. */ + interface IPubKeySet { + /** PubKeySet secp256k1 */ + secp256k1?: string | null; + + /** PubKeySet ed25519 */ + ed25519?: string | null; + } + + /** Represents a PubKeySet. */ + class PubKeySet implements IPubKeySet { + /** + * Constructs a new PubKeySet. + * @param [properties] Properties to set + */ + constructor(properties?: common.IPubKeySet); + + /** PubKeySet secp256k1. */ + public secp256k1: string; + + /** PubKeySet ed25519. */ + public ed25519: string; + + /** + * Creates a new PubKeySet instance using the specified properties. + * @param [properties] Properties to set + * @returns PubKeySet instance + */ + public static create(properties?: common.IPubKeySet): common.PubKeySet; + + /** + * Encodes the specified PubKeySet message. Does not implicitly {@link common.PubKeySet.verify|verify} messages. + * @param message PubKeySet message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.IPubKeySet, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified PubKeySet message, length delimited. Does not implicitly {@link common.PubKeySet.verify|verify} messages. + * @param message PubKeySet message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.IPubKeySet, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a PubKeySet message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns PubKeySet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.PubKeySet; + + /** + * Decodes a PubKeySet message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns PubKeySet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.PubKeySet; + + /** + * Verifies a PubKeySet message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a PubKeySet message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns PubKeySet + */ + public static fromObject(object: { [k: string]: any }): common.PubKeySet; + + /** + * Creates a plain object from a PubKeySet message. Also converts values to other types if specified. + * @param message PubKeySet + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.PubKeySet, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this PubKeySet to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Tx. */ + interface ITx { + /** Tx id */ + id?: string | null; + + /** Tx chain */ + chain?: string | null; + + /** Tx fromAddress */ + fromAddress?: string | null; + + /** Tx toAddress */ + toAddress?: string | null; + + /** Tx coins */ + coins?: common.ICoin[] | null; + + /** Tx gas */ + gas?: common.ICoin[] | null; + + /** Tx memo */ + memo?: string | null; + } + + /** Represents a Tx. */ + class Tx implements ITx { + /** + * Constructs a new Tx. + * @param [properties] Properties to set + */ + constructor(properties?: common.ITx); + + /** Tx id. */ + public id: string; + + /** Tx chain. */ + public chain: string; + + /** Tx fromAddress. */ + public fromAddress: string; + + /** Tx toAddress. */ + public toAddress: string; + + /** Tx coins. */ + public coins: common.ICoin[]; + + /** Tx gas. */ + public gas: common.ICoin[]; + + /** Tx memo. */ + public memo: string; + + /** + * Creates a new Tx instance using the specified properties. + * @param [properties] Properties to set + * @returns Tx instance + */ + public static create(properties?: common.ITx): common.Tx; + + /** + * Encodes the specified Tx message. Does not implicitly {@link common.Tx.verify|verify} messages. + * @param message Tx message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.ITx, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Tx message, length delimited. Does not implicitly {@link common.Tx.verify|verify} messages. + * @param message Tx message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.ITx, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Tx message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Tx + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.Tx; + + /** + * Decodes a Tx message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Tx + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.Tx; + + /** + * Verifies a Tx message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a Tx message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Tx + */ + public static fromObject(object: { [k: string]: any }): common.Tx; + + /** + * Creates a plain object from a Tx message. Also converts values to other types if specified. + * @param message Tx + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.Tx, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Tx to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a Fee. */ + interface IFee { + /** Fee coins */ + coins?: common.ICoin[] | null; + + /** Fee poolDeduct */ + poolDeduct?: string | null; + } + + /** Represents a Fee. */ + class Fee implements IFee { + /** + * Constructs a new Fee. + * @param [properties] Properties to set + */ + constructor(properties?: common.IFee); + + /** Fee coins. */ + public coins: common.ICoin[]; + + /** Fee poolDeduct. */ + public poolDeduct: string; + + /** + * Creates a new Fee instance using the specified properties. + * @param [properties] Properties to set + * @returns Fee instance + */ + public static create(properties?: common.IFee): common.Fee; + + /** + * Encodes the specified Fee message. Does not implicitly {@link common.Fee.verify|verify} messages. + * @param message Fee message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.IFee, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Fee message, length delimited. Does not implicitly {@link common.Fee.verify|verify} messages. + * @param message Fee message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.IFee, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Fee message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Fee + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.Fee; + + /** + * Decodes a Fee message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Fee + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.Fee; + + /** + * Verifies a Fee message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a Fee message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Fee + */ + public static fromObject(object: { [k: string]: any }): common.Fee; + + /** + * Creates a plain object from a Fee message. Also converts values to other types if specified. + * @param message Fee + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.Fee, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Fee to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a ProtoUint. */ + interface IProtoUint { + /** ProtoUint value */ + value?: string | null; + } + + /** Represents a ProtoUint. */ + class ProtoUint implements IProtoUint { + /** + * Constructs a new ProtoUint. + * @param [properties] Properties to set + */ + constructor(properties?: common.IProtoUint); + + /** ProtoUint value. */ + public value: string; + + /** + * Creates a new ProtoUint instance using the specified properties. + * @param [properties] Properties to set + * @returns ProtoUint instance + */ + public static create(properties?: common.IProtoUint): common.ProtoUint; + + /** + * Encodes the specified ProtoUint message. Does not implicitly {@link common.ProtoUint.verify|verify} messages. + * @param message ProtoUint message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: common.IProtoUint, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ProtoUint message, length delimited. Does not implicitly {@link common.ProtoUint.verify|verify} messages. + * @param message ProtoUint message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: common.IProtoUint, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a ProtoUint message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ProtoUint + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): common.ProtoUint; + + /** + * Decodes a ProtoUint message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ProtoUint + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): common.ProtoUint; + + /** + * Verifies a ProtoUint message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a ProtoUint message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ProtoUint + */ + public static fromObject(object: { [k: string]: any }): common.ProtoUint; + + /** + * Creates a plain object from a ProtoUint message. Also converts values to other types if specified. + * @param message ProtoUint + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: common.ProtoUint, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ProtoUint to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } +} + +/** Namespace types. */ +export namespace types { + /** Properties of a MsgDeposit. */ + interface IMsgDeposit { + /** MsgDeposit coins */ + coins?: common.ICoin[] | null; + + /** MsgDeposit memo */ + memo?: string | null; + + /** MsgDeposit signer */ + signer?: Uint8Array | null; + } + + /** Represents a MsgDeposit. */ + class MsgDeposit implements IMsgDeposit { + /** + * Constructs a new MsgDeposit. + * @param [properties] Properties to set + */ + constructor(properties?: types.IMsgDeposit); + + /** MsgDeposit coins. */ + public coins: common.ICoin[]; + + /** MsgDeposit memo. */ + public memo: string; + + /** MsgDeposit signer. */ + public signer: Uint8Array; + + /** + * Creates a new MsgDeposit instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgDeposit instance + */ + public static create(properties?: types.IMsgDeposit): types.MsgDeposit; + + /** + * Encodes the specified MsgDeposit message. Does not implicitly {@link types.MsgDeposit.verify|verify} messages. + * @param message MsgDeposit message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: types.IMsgDeposit, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgDeposit message, length delimited. Does not implicitly {@link types.MsgDeposit.verify|verify} messages. + * @param message MsgDeposit message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: types.IMsgDeposit, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgDeposit message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgDeposit + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): types.MsgDeposit; + + /** + * Decodes a MsgDeposit message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgDeposit + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): types.MsgDeposit; + + /** + * Verifies a MsgDeposit message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a MsgDeposit message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgDeposit + */ + public static fromObject(object: { [k: string]: any }): types.MsgDeposit; + + /** + * Creates a plain object from a MsgDeposit message. Also converts values to other types if specified. + * @param message MsgDeposit + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: types.MsgDeposit, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgDeposit to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a MsgSend. */ + interface IMsgSend { + /** MsgSend fromAddress */ + fromAddress?: Uint8Array | null; + + /** MsgSend toAddress */ + toAddress?: Uint8Array | null; + + /** MsgSend amount */ + amount?: cosmos.base.v1beta1.ICoin[] | null; + } + + /** Represents a MsgSend. */ + class MsgSend implements IMsgSend { + /** + * Constructs a new MsgSend. + * @param [properties] Properties to set + */ + constructor(properties?: types.IMsgSend); + + /** MsgSend fromAddress. */ + public fromAddress: Uint8Array; + + /** MsgSend toAddress. */ + public toAddress: Uint8Array; + + /** MsgSend amount. */ + public amount: cosmos.base.v1beta1.ICoin[]; + + /** + * Creates a new MsgSend instance using the specified properties. + * @param [properties] Properties to set + * @returns MsgSend instance + */ + public static create(properties?: types.IMsgSend): types.MsgSend; + + /** + * Encodes the specified MsgSend message. Does not implicitly {@link types.MsgSend.verify|verify} messages. + * @param message MsgSend message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: types.IMsgSend, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified MsgSend message, length delimited. Does not implicitly {@link types.MsgSend.verify|verify} messages. + * @param message MsgSend message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: types.IMsgSend, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a MsgSend message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns MsgSend + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): types.MsgSend; + + /** + * Decodes a MsgSend message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns MsgSend + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): types.MsgSend; + + /** + * Verifies a MsgSend message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a MsgSend message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns MsgSend + */ + public static fromObject(object: { [k: string]: any }): types.MsgSend; + + /** + * Creates a plain object from a MsgSend message. Also converts values to other types if specified. + * @param message MsgSend + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: types.MsgSend, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this MsgSend to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } +} + +/** Namespace cosmos. */ +export namespace cosmos { + /** Namespace base. */ + namespace base { + /** Namespace v1beta1. */ + namespace v1beta1 { + /** Properties of a Coin. */ + interface ICoin { + /** Coin denom */ + denom?: string | null; + + /** Coin amount */ + amount?: string | null; + } + + /** Represents a Coin. */ + class Coin implements ICoin { + /** + * Constructs a new Coin. + * @param [properties] Properties to set + */ + constructor(properties?: cosmos.base.v1beta1.ICoin); + + /** Coin denom. */ + public denom: string; + + /** Coin amount. */ + public amount: string; + + /** + * Creates a new Coin instance using the specified properties. + * @param [properties] Properties to set + * @returns Coin instance + */ + public static create(properties?: cosmos.base.v1beta1.ICoin): cosmos.base.v1beta1.Coin; + + /** + * Encodes the specified Coin message. Does not implicitly {@link cosmos.base.v1beta1.Coin.verify|verify} messages. + * @param message Coin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: cosmos.base.v1beta1.ICoin, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Coin message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.Coin.verify|verify} messages. + * @param message Coin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: cosmos.base.v1beta1.ICoin, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Coin message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): cosmos.base.v1beta1.Coin; + + /** + * Decodes a Coin message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): cosmos.base.v1beta1.Coin; + + /** + * Verifies a Coin message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a Coin message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Coin + */ + public static fromObject(object: { [k: string]: any }): cosmos.base.v1beta1.Coin; + + /** + * Creates a plain object from a Coin message. Also converts values to other types if specified. + * @param message Coin + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject( + message: cosmos.base.v1beta1.Coin, + options?: $protobuf.IConversionOptions + ): { [k: string]: any }; + + /** + * Converts this Coin to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DecCoin. */ + interface IDecCoin { + /** DecCoin denom */ + denom?: string | null; + + /** DecCoin amount */ + amount?: string | null; + } + + /** Represents a DecCoin. */ + class DecCoin implements IDecCoin { + /** + * Constructs a new DecCoin. + * @param [properties] Properties to set + */ + constructor(properties?: cosmos.base.v1beta1.IDecCoin); + + /** DecCoin denom. */ + public denom: string; + + /** DecCoin amount. */ + public amount: string; + + /** + * Creates a new DecCoin instance using the specified properties. + * @param [properties] Properties to set + * @returns DecCoin instance + */ + public static create(properties?: cosmos.base.v1beta1.IDecCoin): cosmos.base.v1beta1.DecCoin; + + /** + * Encodes the specified DecCoin message. Does not implicitly {@link cosmos.base.v1beta1.DecCoin.verify|verify} messages. + * @param message DecCoin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: cosmos.base.v1beta1.IDecCoin, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DecCoin message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.DecCoin.verify|verify} messages. + * @param message DecCoin message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited( + message: cosmos.base.v1beta1.IDecCoin, + writer?: $protobuf.Writer + ): $protobuf.Writer; + + /** + * Decodes a DecCoin message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DecCoin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): cosmos.base.v1beta1.DecCoin; + + /** + * Decodes a DecCoin message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DecCoin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): cosmos.base.v1beta1.DecCoin; + + /** + * Verifies a DecCoin message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a DecCoin message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DecCoin + */ + public static fromObject(object: { [k: string]: any }): cosmos.base.v1beta1.DecCoin; + + /** + * Creates a plain object from a DecCoin message. Also converts values to other types if specified. + * @param message DecCoin + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject( + message: cosmos.base.v1beta1.DecCoin, + options?: $protobuf.IConversionOptions + ): { [k: string]: any }; + + /** + * Converts this DecCoin to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an IntProto. */ + interface IIntProto { + /** IntProto int */ + int?: string | null; + } + + /** Represents an IntProto. */ + class IntProto implements IIntProto { + /** + * Constructs a new IntProto. + * @param [properties] Properties to set + */ + constructor(properties?: cosmos.base.v1beta1.IIntProto); + + /** IntProto int. */ + public int: string; + + /** + * Creates a new IntProto instance using the specified properties. + * @param [properties] Properties to set + * @returns IntProto instance + */ + public static create(properties?: cosmos.base.v1beta1.IIntProto): cosmos.base.v1beta1.IntProto; + + /** + * Encodes the specified IntProto message. Does not implicitly {@link cosmos.base.v1beta1.IntProto.verify|verify} messages. + * @param message IntProto message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: cosmos.base.v1beta1.IIntProto, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified IntProto message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.IntProto.verify|verify} messages. + * @param message IntProto message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited( + message: cosmos.base.v1beta1.IIntProto, + writer?: $protobuf.Writer + ): $protobuf.Writer; + + /** + * Decodes an IntProto message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns IntProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): cosmos.base.v1beta1.IntProto; + + /** + * Decodes an IntProto message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns IntProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): cosmos.base.v1beta1.IntProto; + + /** + * Verifies an IntProto message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates an IntProto message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns IntProto + */ + public static fromObject(object: { [k: string]: any }): cosmos.base.v1beta1.IntProto; + + /** + * Creates a plain object from an IntProto message. Also converts values to other types if specified. + * @param message IntProto + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject( + message: cosmos.base.v1beta1.IntProto, + options?: $protobuf.IConversionOptions + ): { [k: string]: any }; + + /** + * Converts this IntProto to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a DecProto. */ + interface IDecProto { + /** DecProto dec */ + dec?: string | null; + } + + /** Represents a DecProto. */ + class DecProto implements IDecProto { + /** + * Constructs a new DecProto. + * @param [properties] Properties to set + */ + constructor(properties?: cosmos.base.v1beta1.IDecProto); + + /** DecProto dec. */ + public dec: string; + + /** + * Creates a new DecProto instance using the specified properties. + * @param [properties] Properties to set + * @returns DecProto instance + */ + public static create(properties?: cosmos.base.v1beta1.IDecProto): cosmos.base.v1beta1.DecProto; + + /** + * Encodes the specified DecProto message. Does not implicitly {@link cosmos.base.v1beta1.DecProto.verify|verify} messages. + * @param message DecProto message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: cosmos.base.v1beta1.IDecProto, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified DecProto message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.DecProto.verify|verify} messages. + * @param message DecProto message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited( + message: cosmos.base.v1beta1.IDecProto, + writer?: $protobuf.Writer + ): $protobuf.Writer; + + /** + * Decodes a DecProto message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns DecProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: $protobuf.Reader | Uint8Array, length?: number): cosmos.base.v1beta1.DecProto; + + /** + * Decodes a DecProto message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns DecProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: $protobuf.Reader | Uint8Array): cosmos.base.v1beta1.DecProto; + + /** + * Verifies a DecProto message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): string | null; + + /** + * Creates a DecProto message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns DecProto + */ + public static fromObject(object: { [k: string]: any }): cosmos.base.v1beta1.DecProto; + + /** + * Creates a plain object from a DecProto message. Also converts values to other types if specified. + * @param message DecProto + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject( + message: cosmos.base.v1beta1.DecProto, + options?: $protobuf.IConversionOptions + ): { [k: string]: any }; + + /** + * Converts this DecProto to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + } + } +} diff --git a/modules/abstract-cosmos/resources/MsgCompiled.js b/modules/abstract-cosmos/resources/MsgCompiled.js new file mode 100644 index 0000000000..e3e3e2b1ae --- /dev/null +++ b/modules/abstract-cosmos/resources/MsgCompiled.js @@ -0,0 +1,2761 @@ +/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ +'use strict'; + +var $protobuf = require('protobufjs/minimal'); + +// Common aliases +var $Reader = $protobuf.Reader, + $Writer = $protobuf.Writer, + $util = $protobuf.util; + +// Exported root namespace +var $root = $protobuf.roots['default'] || ($protobuf.roots['default'] = {}); + +$root.common = (function () { + /** + * Namespace common. + * @exports common + * @namespace + */ + var common = {}; + + common.Asset = (function () { + /** + * Properties of an Asset. + * @memberof common + * @interface IAsset + * @property {string|null} [chain] Asset chain + * @property {string|null} [symbol] Asset symbol + * @property {string|null} [ticker] Asset ticker + * @property {boolean|null} [synth] Asset synth + * @property {boolean|null} [trade] Asset trade + */ + + /** + * Constructs a new Asset. + * @memberof common + * @classdesc Represents an Asset. + * @implements IAsset + * @constructor + * @param {common.IAsset=} [properties] Properties to set + */ + function Asset(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * Asset chain. + * @member {string} chain + * @memberof common.Asset + * @instance + */ + Asset.prototype.chain = ''; + + /** + * Asset symbol. + * @member {string} symbol + * @memberof common.Asset + * @instance + */ + Asset.prototype.symbol = ''; + + /** + * Asset ticker. + * @member {string} ticker + * @memberof common.Asset + * @instance + */ + Asset.prototype.ticker = ''; + + /** + * Asset synth. + * @member {boolean} synth + * @memberof common.Asset + * @instance + */ + Asset.prototype.synth = false; + + /** + * Asset trade. + * @member {boolean} trade + * @memberof common.Asset + * @instance + */ + Asset.prototype.trade = false; + + /** + * Creates a new Asset instance using the specified properties. + * @function create + * @memberof common.Asset + * @static + * @param {common.IAsset=} [properties] Properties to set + * @returns {common.Asset} Asset instance + */ + Asset.create = function create(properties) { + return new Asset(properties); + }; + + /** + * Encodes the specified Asset message. Does not implicitly {@link common.Asset.verify|verify} messages. + * @function encode + * @memberof common.Asset + * @static + * @param {common.IAsset} message Asset message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Asset.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.chain != null && Object.hasOwnProperty.call(message, 'chain')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.chain); + if (message.symbol != null && Object.hasOwnProperty.call(message, 'symbol')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.symbol); + if (message.ticker != null && Object.hasOwnProperty.call(message, 'ticker')) + writer.uint32(/* id 3, wireType 2 =*/ 26).string(message.ticker); + if (message.synth != null && Object.hasOwnProperty.call(message, 'synth')) + writer.uint32(/* id 4, wireType 0 =*/ 32).bool(message.synth); + if (message.trade != null && Object.hasOwnProperty.call(message, 'trade')) + writer.uint32(/* id 5, wireType 0 =*/ 40).bool(message.trade); + return writer; + }; + + /** + * Encodes the specified Asset message, length delimited. Does not implicitly {@link common.Asset.verify|verify} messages. + * @function encodeDelimited + * @memberof common.Asset + * @static + * @param {common.IAsset} message Asset message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Asset.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an Asset message from the specified reader or buffer. + * @function decode + * @memberof common.Asset + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.Asset} Asset + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Asset.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.Asset(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.chain = reader.string(); + break; + case 2: + message.symbol = reader.string(); + break; + case 3: + message.ticker = reader.string(); + break; + case 4: + message.synth = reader.bool(); + break; + case 5: + message.trade = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an Asset message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.Asset + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.Asset} Asset + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Asset.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an Asset message. + * @function verify + * @memberof common.Asset + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Asset.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.chain != null && message.hasOwnProperty('chain')) + if (!$util.isString(message.chain)) return 'chain: string expected'; + if (message.symbol != null && message.hasOwnProperty('symbol')) + if (!$util.isString(message.symbol)) return 'symbol: string expected'; + if (message.ticker != null && message.hasOwnProperty('ticker')) + if (!$util.isString(message.ticker)) return 'ticker: string expected'; + if (message.synth != null && message.hasOwnProperty('synth')) + if (typeof message.synth !== 'boolean') return 'synth: boolean expected'; + if (message.trade != null && message.hasOwnProperty('trade')) + if (typeof message.trade !== 'boolean') return 'trade: boolean expected'; + return null; + }; + + /** + * Creates an Asset message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.Asset + * @static + * @param {Object.} object Plain object + * @returns {common.Asset} Asset + */ + Asset.fromObject = function fromObject(object) { + if (object instanceof $root.common.Asset) return object; + var message = new $root.common.Asset(); + if (object.chain != null) message.chain = String(object.chain); + if (object.symbol != null) message.symbol = String(object.symbol); + if (object.ticker != null) message.ticker = String(object.ticker); + if (object.synth != null) message.synth = Boolean(object.synth); + if (object.trade != null) message.trade = Boolean(object.trade); + return message; + }; + + /** + * Creates a plain object from an Asset message. Also converts values to other types if specified. + * @function toObject + * @memberof common.Asset + * @static + * @param {common.Asset} message Asset + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Asset.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.chain = ''; + object.symbol = ''; + object.ticker = ''; + object.synth = false; + object.trade = false; + } + if (message.chain != null && message.hasOwnProperty('chain')) object.chain = message.chain; + if (message.symbol != null && message.hasOwnProperty('symbol')) object.symbol = message.symbol; + if (message.ticker != null && message.hasOwnProperty('ticker')) object.ticker = message.ticker; + if (message.synth != null && message.hasOwnProperty('synth')) object.synth = message.synth; + if (message.trade != null && message.hasOwnProperty('trade')) object.trade = message.trade; + return object; + }; + + /** + * Converts this Asset to JSON. + * @function toJSON + * @memberof common.Asset + * @instance + * @returns {Object.} JSON object + */ + Asset.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Asset; + })(); + + common.Coin = (function () { + /** + * Properties of a Coin. + * @memberof common + * @interface ICoin + * @property {common.IAsset|null} [asset] Coin asset + * @property {string|null} [amount] Coin amount + * @property {number|Long|null} [decimals] Coin decimals + */ + + /** + * Constructs a new Coin. + * @memberof common + * @classdesc Represents a Coin. + * @implements ICoin + * @constructor + * @param {common.ICoin=} [properties] Properties to set + */ + function Coin(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * Coin asset. + * @member {common.IAsset|null|undefined} asset + * @memberof common.Coin + * @instance + */ + Coin.prototype.asset = null; + + /** + * Coin amount. + * @member {string} amount + * @memberof common.Coin + * @instance + */ + Coin.prototype.amount = ''; + + /** + * Coin decimals. + * @member {number|Long} decimals + * @memberof common.Coin + * @instance + */ + Coin.prototype.decimals = $util.Long ? $util.Long.fromBits(0, 0, false) : 0; + + /** + * Creates a new Coin instance using the specified properties. + * @function create + * @memberof common.Coin + * @static + * @param {common.ICoin=} [properties] Properties to set + * @returns {common.Coin} Coin instance + */ + Coin.create = function create(properties) { + return new Coin(properties); + }; + + /** + * Encodes the specified Coin message. Does not implicitly {@link common.Coin.verify|verify} messages. + * @function encode + * @memberof common.Coin + * @static + * @param {common.ICoin} message Coin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Coin.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.asset != null && Object.hasOwnProperty.call(message, 'asset')) + $root.common.Asset.encode(message.asset, writer.uint32(/* id 1, wireType 2 =*/ 10).fork()).ldelim(); + if (message.amount != null && Object.hasOwnProperty.call(message, 'amount')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.amount); + if (message.decimals != null && Object.hasOwnProperty.call(message, 'decimals')) + writer.uint32(/* id 3, wireType 0 =*/ 24).int64(message.decimals); + return writer; + }; + + /** + * Encodes the specified Coin message, length delimited. Does not implicitly {@link common.Coin.verify|verify} messages. + * @function encodeDelimited + * @memberof common.Coin + * @static + * @param {common.ICoin} message Coin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Coin.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Coin message from the specified reader or buffer. + * @function decode + * @memberof common.Coin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.Coin} Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Coin.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.Coin(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.asset = $root.common.Asset.decode(reader, reader.uint32()); + break; + case 2: + message.amount = reader.string(); + break; + case 3: + message.decimals = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Coin message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.Coin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.Coin} Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Coin.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Coin message. + * @function verify + * @memberof common.Coin + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Coin.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.asset != null && message.hasOwnProperty('asset')) { + var error = $root.common.Asset.verify(message.asset); + if (error) return 'asset.' + error; + } + if (message.amount != null && message.hasOwnProperty('amount')) + if (!$util.isString(message.amount)) return 'amount: string expected'; + if (message.decimals != null && message.hasOwnProperty('decimals')) + if ( + !$util.isInteger(message.decimals) && + !(message.decimals && $util.isInteger(message.decimals.low) && $util.isInteger(message.decimals.high)) + ) + return 'decimals: integer|Long expected'; + return null; + }; + + /** + * Creates a Coin message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.Coin + * @static + * @param {Object.} object Plain object + * @returns {common.Coin} Coin + */ + Coin.fromObject = function fromObject(object) { + if (object instanceof $root.common.Coin) return object; + var message = new $root.common.Coin(); + if (object.asset != null) { + if (typeof object.asset !== 'object') throw TypeError('.common.Coin.asset: object expected'); + message.asset = $root.common.Asset.fromObject(object.asset); + } + if (object.amount != null) message.amount = String(object.amount); + if (object.decimals != null) + if ($util.Long) (message.decimals = $util.Long.fromValue(object.decimals)).unsigned = false; + else if (typeof object.decimals === 'string') message.decimals = parseInt(object.decimals, 10); + else if (typeof object.decimals === 'number') message.decimals = object.decimals; + else if (typeof object.decimals === 'object') + message.decimals = new $util.LongBits(object.decimals.low >>> 0, object.decimals.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a Coin message. Also converts values to other types if specified. + * @function toObject + * @memberof common.Coin + * @static + * @param {common.Coin} message Coin + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Coin.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.asset = null; + object.amount = ''; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.decimals = + options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else object.decimals = options.longs === String ? '0' : 0; + } + if (message.asset != null && message.hasOwnProperty('asset')) + object.asset = $root.common.Asset.toObject(message.asset, options); + if (message.amount != null && message.hasOwnProperty('amount')) object.amount = message.amount; + if (message.decimals != null && message.hasOwnProperty('decimals')) + if (typeof message.decimals === 'number') + object.decimals = options.longs === String ? String(message.decimals) : message.decimals; + else + object.decimals = + options.longs === String + ? $util.Long.prototype.toString.call(message.decimals) + : options.longs === Number + ? new $util.LongBits(message.decimals.low >>> 0, message.decimals.high >>> 0).toNumber() + : message.decimals; + return object; + }; + + /** + * Converts this Coin to JSON. + * @function toJSON + * @memberof common.Coin + * @instance + * @returns {Object.} JSON object + */ + Coin.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Coin; + })(); + + common.PubKeySet = (function () { + /** + * Properties of a PubKeySet. + * @memberof common + * @interface IPubKeySet + * @property {string|null} [secp256k1] PubKeySet secp256k1 + * @property {string|null} [ed25519] PubKeySet ed25519 + */ + + /** + * Constructs a new PubKeySet. + * @memberof common + * @classdesc Represents a PubKeySet. + * @implements IPubKeySet + * @constructor + * @param {common.IPubKeySet=} [properties] Properties to set + */ + function PubKeySet(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * PubKeySet secp256k1. + * @member {string} secp256k1 + * @memberof common.PubKeySet + * @instance + */ + PubKeySet.prototype.secp256k1 = ''; + + /** + * PubKeySet ed25519. + * @member {string} ed25519 + * @memberof common.PubKeySet + * @instance + */ + PubKeySet.prototype.ed25519 = ''; + + /** + * Creates a new PubKeySet instance using the specified properties. + * @function create + * @memberof common.PubKeySet + * @static + * @param {common.IPubKeySet=} [properties] Properties to set + * @returns {common.PubKeySet} PubKeySet instance + */ + PubKeySet.create = function create(properties) { + return new PubKeySet(properties); + }; + + /** + * Encodes the specified PubKeySet message. Does not implicitly {@link common.PubKeySet.verify|verify} messages. + * @function encode + * @memberof common.PubKeySet + * @static + * @param {common.IPubKeySet} message PubKeySet message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PubKeySet.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.secp256k1 != null && Object.hasOwnProperty.call(message, 'secp256k1')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.secp256k1); + if (message.ed25519 != null && Object.hasOwnProperty.call(message, 'ed25519')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.ed25519); + return writer; + }; + + /** + * Encodes the specified PubKeySet message, length delimited. Does not implicitly {@link common.PubKeySet.verify|verify} messages. + * @function encodeDelimited + * @memberof common.PubKeySet + * @static + * @param {common.IPubKeySet} message PubKeySet message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + PubKeySet.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a PubKeySet message from the specified reader or buffer. + * @function decode + * @memberof common.PubKeySet + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.PubKeySet} PubKeySet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PubKeySet.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.PubKeySet(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.secp256k1 = reader.string(); + break; + case 2: + message.ed25519 = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a PubKeySet message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.PubKeySet + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.PubKeySet} PubKeySet + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + PubKeySet.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a PubKeySet message. + * @function verify + * @memberof common.PubKeySet + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + PubKeySet.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.secp256k1 != null && message.hasOwnProperty('secp256k1')) + if (!$util.isString(message.secp256k1)) return 'secp256k1: string expected'; + if (message.ed25519 != null && message.hasOwnProperty('ed25519')) + if (!$util.isString(message.ed25519)) return 'ed25519: string expected'; + return null; + }; + + /** + * Creates a PubKeySet message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.PubKeySet + * @static + * @param {Object.} object Plain object + * @returns {common.PubKeySet} PubKeySet + */ + PubKeySet.fromObject = function fromObject(object) { + if (object instanceof $root.common.PubKeySet) return object; + var message = new $root.common.PubKeySet(); + if (object.secp256k1 != null) message.secp256k1 = String(object.secp256k1); + if (object.ed25519 != null) message.ed25519 = String(object.ed25519); + return message; + }; + + /** + * Creates a plain object from a PubKeySet message. Also converts values to other types if specified. + * @function toObject + * @memberof common.PubKeySet + * @static + * @param {common.PubKeySet} message PubKeySet + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + PubKeySet.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.secp256k1 = ''; + object.ed25519 = ''; + } + if (message.secp256k1 != null && message.hasOwnProperty('secp256k1')) object.secp256k1 = message.secp256k1; + if (message.ed25519 != null && message.hasOwnProperty('ed25519')) object.ed25519 = message.ed25519; + return object; + }; + + /** + * Converts this PubKeySet to JSON. + * @function toJSON + * @memberof common.PubKeySet + * @instance + * @returns {Object.} JSON object + */ + PubKeySet.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return PubKeySet; + })(); + + common.Tx = (function () { + /** + * Properties of a Tx. + * @memberof common + * @interface ITx + * @property {string|null} [id] Tx id + * @property {string|null} [chain] Tx chain + * @property {string|null} [fromAddress] Tx fromAddress + * @property {string|null} [toAddress] Tx toAddress + * @property {Array.|null} [coins] Tx coins + * @property {Array.|null} [gas] Tx gas + * @property {string|null} [memo] Tx memo + */ + + /** + * Constructs a new Tx. + * @memberof common + * @classdesc Represents a Tx. + * @implements ITx + * @constructor + * @param {common.ITx=} [properties] Properties to set + */ + function Tx(properties) { + this.coins = []; + this.gas = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * Tx id. + * @member {string} id + * @memberof common.Tx + * @instance + */ + Tx.prototype.id = ''; + + /** + * Tx chain. + * @member {string} chain + * @memberof common.Tx + * @instance + */ + Tx.prototype.chain = ''; + + /** + * Tx fromAddress. + * @member {string} fromAddress + * @memberof common.Tx + * @instance + */ + Tx.prototype.fromAddress = ''; + + /** + * Tx toAddress. + * @member {string} toAddress + * @memberof common.Tx + * @instance + */ + Tx.prototype.toAddress = ''; + + /** + * Tx coins. + * @member {Array.} coins + * @memberof common.Tx + * @instance + */ + Tx.prototype.coins = $util.emptyArray; + + /** + * Tx gas. + * @member {Array.} gas + * @memberof common.Tx + * @instance + */ + Tx.prototype.gas = $util.emptyArray; + + /** + * Tx memo. + * @member {string} memo + * @memberof common.Tx + * @instance + */ + Tx.prototype.memo = ''; + + /** + * Creates a new Tx instance using the specified properties. + * @function create + * @memberof common.Tx + * @static + * @param {common.ITx=} [properties] Properties to set + * @returns {common.Tx} Tx instance + */ + Tx.create = function create(properties) { + return new Tx(properties); + }; + + /** + * Encodes the specified Tx message. Does not implicitly {@link common.Tx.verify|verify} messages. + * @function encode + * @memberof common.Tx + * @static + * @param {common.ITx} message Tx message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Tx.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, 'id')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.id); + if (message.chain != null && Object.hasOwnProperty.call(message, 'chain')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.chain); + if (message.fromAddress != null && Object.hasOwnProperty.call(message, 'fromAddress')) + writer.uint32(/* id 3, wireType 2 =*/ 26).string(message.fromAddress); + if (message.toAddress != null && Object.hasOwnProperty.call(message, 'toAddress')) + writer.uint32(/* id 4, wireType 2 =*/ 34).string(message.toAddress); + if (message.coins != null && message.coins.length) + for (var i = 0; i < message.coins.length; ++i) + $root.common.Coin.encode(message.coins[i], writer.uint32(/* id 5, wireType 2 =*/ 42).fork()).ldelim(); + if (message.gas != null && message.gas.length) + for (var i = 0; i < message.gas.length; ++i) + $root.common.Coin.encode(message.gas[i], writer.uint32(/* id 6, wireType 2 =*/ 50).fork()).ldelim(); + if (message.memo != null && Object.hasOwnProperty.call(message, 'memo')) + writer.uint32(/* id 7, wireType 2 =*/ 58).string(message.memo); + return writer; + }; + + /** + * Encodes the specified Tx message, length delimited. Does not implicitly {@link common.Tx.verify|verify} messages. + * @function encodeDelimited + * @memberof common.Tx + * @static + * @param {common.ITx} message Tx message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Tx.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Tx message from the specified reader or buffer. + * @function decode + * @memberof common.Tx + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.Tx} Tx + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Tx.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.Tx(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.string(); + break; + case 2: + message.chain = reader.string(); + break; + case 3: + message.fromAddress = reader.string(); + break; + case 4: + message.toAddress = reader.string(); + break; + case 5: + if (!(message.coins && message.coins.length)) message.coins = []; + message.coins.push($root.common.Coin.decode(reader, reader.uint32())); + break; + case 6: + if (!(message.gas && message.gas.length)) message.gas = []; + message.gas.push($root.common.Coin.decode(reader, reader.uint32())); + break; + case 7: + message.memo = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Tx message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.Tx + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.Tx} Tx + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Tx.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Tx message. + * @function verify + * @memberof common.Tx + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Tx.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.id != null && message.hasOwnProperty('id')) + if (!$util.isString(message.id)) return 'id: string expected'; + if (message.chain != null && message.hasOwnProperty('chain')) + if (!$util.isString(message.chain)) return 'chain: string expected'; + if (message.fromAddress != null && message.hasOwnProperty('fromAddress')) + if (!$util.isString(message.fromAddress)) return 'fromAddress: string expected'; + if (message.toAddress != null && message.hasOwnProperty('toAddress')) + if (!$util.isString(message.toAddress)) return 'toAddress: string expected'; + if (message.coins != null && message.hasOwnProperty('coins')) { + if (!Array.isArray(message.coins)) return 'coins: array expected'; + for (var i = 0; i < message.coins.length; ++i) { + var error = $root.common.Coin.verify(message.coins[i]); + if (error) return 'coins.' + error; + } + } + if (message.gas != null && message.hasOwnProperty('gas')) { + if (!Array.isArray(message.gas)) return 'gas: array expected'; + for (var i = 0; i < message.gas.length; ++i) { + var error = $root.common.Coin.verify(message.gas[i]); + if (error) return 'gas.' + error; + } + } + if (message.memo != null && message.hasOwnProperty('memo')) + if (!$util.isString(message.memo)) return 'memo: string expected'; + return null; + }; + + /** + * Creates a Tx message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.Tx + * @static + * @param {Object.} object Plain object + * @returns {common.Tx} Tx + */ + Tx.fromObject = function fromObject(object) { + if (object instanceof $root.common.Tx) return object; + var message = new $root.common.Tx(); + if (object.id != null) message.id = String(object.id); + if (object.chain != null) message.chain = String(object.chain); + if (object.fromAddress != null) message.fromAddress = String(object.fromAddress); + if (object.toAddress != null) message.toAddress = String(object.toAddress); + if (object.coins) { + if (!Array.isArray(object.coins)) throw TypeError('.common.Tx.coins: array expected'); + message.coins = []; + for (var i = 0; i < object.coins.length; ++i) { + if (typeof object.coins[i] !== 'object') throw TypeError('.common.Tx.coins: object expected'); + message.coins[i] = $root.common.Coin.fromObject(object.coins[i]); + } + } + if (object.gas) { + if (!Array.isArray(object.gas)) throw TypeError('.common.Tx.gas: array expected'); + message.gas = []; + for (var i = 0; i < object.gas.length; ++i) { + if (typeof object.gas[i] !== 'object') throw TypeError('.common.Tx.gas: object expected'); + message.gas[i] = $root.common.Coin.fromObject(object.gas[i]); + } + } + if (object.memo != null) message.memo = String(object.memo); + return message; + }; + + /** + * Creates a plain object from a Tx message. Also converts values to other types if specified. + * @function toObject + * @memberof common.Tx + * @static + * @param {common.Tx} message Tx + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Tx.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.coins = []; + object.gas = []; + } + if (options.defaults) { + object.id = ''; + object.chain = ''; + object.fromAddress = ''; + object.toAddress = ''; + object.memo = ''; + } + if (message.id != null && message.hasOwnProperty('id')) object.id = message.id; + if (message.chain != null && message.hasOwnProperty('chain')) object.chain = message.chain; + if (message.fromAddress != null && message.hasOwnProperty('fromAddress')) + object.fromAddress = message.fromAddress; + if (message.toAddress != null && message.hasOwnProperty('toAddress')) object.toAddress = message.toAddress; + if (message.coins && message.coins.length) { + object.coins = []; + for (var j = 0; j < message.coins.length; ++j) + object.coins[j] = $root.common.Coin.toObject(message.coins[j], options); + } + if (message.gas && message.gas.length) { + object.gas = []; + for (var j = 0; j < message.gas.length; ++j) + object.gas[j] = $root.common.Coin.toObject(message.gas[j], options); + } + if (message.memo != null && message.hasOwnProperty('memo')) object.memo = message.memo; + return object; + }; + + /** + * Converts this Tx to JSON. + * @function toJSON + * @memberof common.Tx + * @instance + * @returns {Object.} JSON object + */ + Tx.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Tx; + })(); + + common.Fee = (function () { + /** + * Properties of a Fee. + * @memberof common + * @interface IFee + * @property {Array.|null} [coins] Fee coins + * @property {string|null} [poolDeduct] Fee poolDeduct + */ + + /** + * Constructs a new Fee. + * @memberof common + * @classdesc Represents a Fee. + * @implements IFee + * @constructor + * @param {common.IFee=} [properties] Properties to set + */ + function Fee(properties) { + this.coins = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * Fee coins. + * @member {Array.} coins + * @memberof common.Fee + * @instance + */ + Fee.prototype.coins = $util.emptyArray; + + /** + * Fee poolDeduct. + * @member {string} poolDeduct + * @memberof common.Fee + * @instance + */ + Fee.prototype.poolDeduct = ''; + + /** + * Creates a new Fee instance using the specified properties. + * @function create + * @memberof common.Fee + * @static + * @param {common.IFee=} [properties] Properties to set + * @returns {common.Fee} Fee instance + */ + Fee.create = function create(properties) { + return new Fee(properties); + }; + + /** + * Encodes the specified Fee message. Does not implicitly {@link common.Fee.verify|verify} messages. + * @function encode + * @memberof common.Fee + * @static + * @param {common.IFee} message Fee message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Fee.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.coins != null && message.coins.length) + for (var i = 0; i < message.coins.length; ++i) + $root.common.Coin.encode(message.coins[i], writer.uint32(/* id 1, wireType 2 =*/ 10).fork()).ldelim(); + if (message.poolDeduct != null && Object.hasOwnProperty.call(message, 'poolDeduct')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.poolDeduct); + return writer; + }; + + /** + * Encodes the specified Fee message, length delimited. Does not implicitly {@link common.Fee.verify|verify} messages. + * @function encodeDelimited + * @memberof common.Fee + * @static + * @param {common.IFee} message Fee message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Fee.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Fee message from the specified reader or buffer. + * @function decode + * @memberof common.Fee + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.Fee} Fee + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Fee.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.Fee(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.coins && message.coins.length)) message.coins = []; + message.coins.push($root.common.Coin.decode(reader, reader.uint32())); + break; + case 2: + message.poolDeduct = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Fee message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.Fee + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.Fee} Fee + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Fee.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Fee message. + * @function verify + * @memberof common.Fee + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Fee.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.coins != null && message.hasOwnProperty('coins')) { + if (!Array.isArray(message.coins)) return 'coins: array expected'; + for (var i = 0; i < message.coins.length; ++i) { + var error = $root.common.Coin.verify(message.coins[i]); + if (error) return 'coins.' + error; + } + } + if (message.poolDeduct != null && message.hasOwnProperty('poolDeduct')) + if (!$util.isString(message.poolDeduct)) return 'poolDeduct: string expected'; + return null; + }; + + /** + * Creates a Fee message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.Fee + * @static + * @param {Object.} object Plain object + * @returns {common.Fee} Fee + */ + Fee.fromObject = function fromObject(object) { + if (object instanceof $root.common.Fee) return object; + var message = new $root.common.Fee(); + if (object.coins) { + if (!Array.isArray(object.coins)) throw TypeError('.common.Fee.coins: array expected'); + message.coins = []; + for (var i = 0; i < object.coins.length; ++i) { + if (typeof object.coins[i] !== 'object') throw TypeError('.common.Fee.coins: object expected'); + message.coins[i] = $root.common.Coin.fromObject(object.coins[i]); + } + } + if (object.poolDeduct != null) message.poolDeduct = String(object.poolDeduct); + return message; + }; + + /** + * Creates a plain object from a Fee message. Also converts values to other types if specified. + * @function toObject + * @memberof common.Fee + * @static + * @param {common.Fee} message Fee + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Fee.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.coins = []; + if (options.defaults) object.poolDeduct = ''; + if (message.coins && message.coins.length) { + object.coins = []; + for (var j = 0; j < message.coins.length; ++j) + object.coins[j] = $root.common.Coin.toObject(message.coins[j], options); + } + if (message.poolDeduct != null && message.hasOwnProperty('poolDeduct')) object.poolDeduct = message.poolDeduct; + return object; + }; + + /** + * Converts this Fee to JSON. + * @function toJSON + * @memberof common.Fee + * @instance + * @returns {Object.} JSON object + */ + Fee.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Fee; + })(); + + common.ProtoUint = (function () { + /** + * Properties of a ProtoUint. + * @memberof common + * @interface IProtoUint + * @property {string|null} [value] ProtoUint value + */ + + /** + * Constructs a new ProtoUint. + * @memberof common + * @classdesc Represents a ProtoUint. + * @implements IProtoUint + * @constructor + * @param {common.IProtoUint=} [properties] Properties to set + */ + function ProtoUint(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * ProtoUint value. + * @member {string} value + * @memberof common.ProtoUint + * @instance + */ + ProtoUint.prototype.value = ''; + + /** + * Creates a new ProtoUint instance using the specified properties. + * @function create + * @memberof common.ProtoUint + * @static + * @param {common.IProtoUint=} [properties] Properties to set + * @returns {common.ProtoUint} ProtoUint instance + */ + ProtoUint.create = function create(properties) { + return new ProtoUint(properties); + }; + + /** + * Encodes the specified ProtoUint message. Does not implicitly {@link common.ProtoUint.verify|verify} messages. + * @function encode + * @memberof common.ProtoUint + * @static + * @param {common.IProtoUint} message ProtoUint message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProtoUint.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.value != null && Object.hasOwnProperty.call(message, 'value')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.value); + return writer; + }; + + /** + * Encodes the specified ProtoUint message, length delimited. Does not implicitly {@link common.ProtoUint.verify|verify} messages. + * @function encodeDelimited + * @memberof common.ProtoUint + * @static + * @param {common.IProtoUint} message ProtoUint message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ProtoUint.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a ProtoUint message from the specified reader or buffer. + * @function decode + * @memberof common.ProtoUint + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {common.ProtoUint} ProtoUint + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProtoUint.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.common.ProtoUint(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.value = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a ProtoUint message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof common.ProtoUint + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {common.ProtoUint} ProtoUint + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ProtoUint.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a ProtoUint message. + * @function verify + * @memberof common.ProtoUint + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ProtoUint.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.value != null && message.hasOwnProperty('value')) + if (!$util.isString(message.value)) return 'value: string expected'; + return null; + }; + + /** + * Creates a ProtoUint message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof common.ProtoUint + * @static + * @param {Object.} object Plain object + * @returns {common.ProtoUint} ProtoUint + */ + ProtoUint.fromObject = function fromObject(object) { + if (object instanceof $root.common.ProtoUint) return object; + var message = new $root.common.ProtoUint(); + if (object.value != null) message.value = String(object.value); + return message; + }; + + /** + * Creates a plain object from a ProtoUint message. Also converts values to other types if specified. + * @function toObject + * @memberof common.ProtoUint + * @static + * @param {common.ProtoUint} message ProtoUint + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ProtoUint.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.value = ''; + if (message.value != null && message.hasOwnProperty('value')) object.value = message.value; + return object; + }; + + /** + * Converts this ProtoUint to JSON. + * @function toJSON + * @memberof common.ProtoUint + * @instance + * @returns {Object.} JSON object + */ + ProtoUint.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ProtoUint; + })(); + + return common; +})(); + +$root.types = (function () { + /** + * Namespace types. + * @exports types + * @namespace + */ + var types = {}; + + types.MsgDeposit = (function () { + /** + * Properties of a MsgDeposit. + * @memberof types + * @interface IMsgDeposit + * @property {Array.|null} [coins] MsgDeposit coins + * @property {string|null} [memo] MsgDeposit memo + * @property {Uint8Array|null} [signer] MsgDeposit signer + */ + + /** + * Constructs a new MsgDeposit. + * @memberof types + * @classdesc Represents a MsgDeposit. + * @implements IMsgDeposit + * @constructor + * @param {types.IMsgDeposit=} [properties] Properties to set + */ + function MsgDeposit(properties) { + this.coins = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgDeposit coins. + * @member {Array.} coins + * @memberof types.MsgDeposit + * @instance + */ + MsgDeposit.prototype.coins = $util.emptyArray; + + /** + * MsgDeposit memo. + * @member {string} memo + * @memberof types.MsgDeposit + * @instance + */ + MsgDeposit.prototype.memo = ''; + + /** + * MsgDeposit signer. + * @member {Uint8Array} signer + * @memberof types.MsgDeposit + * @instance + */ + MsgDeposit.prototype.signer = $util.newBuffer([]); + + /** + * Creates a new MsgDeposit instance using the specified properties. + * @function create + * @memberof types.MsgDeposit + * @static + * @param {types.IMsgDeposit=} [properties] Properties to set + * @returns {types.MsgDeposit} MsgDeposit instance + */ + MsgDeposit.create = function create(properties) { + return new MsgDeposit(properties); + }; + + /** + * Encodes the specified MsgDeposit message. Does not implicitly {@link types.MsgDeposit.verify|verify} messages. + * @function encode + * @memberof types.MsgDeposit + * @static + * @param {types.IMsgDeposit} message MsgDeposit message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgDeposit.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.coins != null && message.coins.length) + for (var i = 0; i < message.coins.length; ++i) + $root.common.Coin.encode(message.coins[i], writer.uint32(/* id 1, wireType 2 =*/ 10).fork()).ldelim(); + if (message.memo != null && Object.hasOwnProperty.call(message, 'memo')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.memo); + if (message.signer != null && Object.hasOwnProperty.call(message, 'signer')) + writer.uint32(/* id 3, wireType 2 =*/ 26).bytes(message.signer); + return writer; + }; + + /** + * Encodes the specified MsgDeposit message, length delimited. Does not implicitly {@link types.MsgDeposit.verify|verify} messages. + * @function encodeDelimited + * @memberof types.MsgDeposit + * @static + * @param {types.IMsgDeposit} message MsgDeposit message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgDeposit.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgDeposit message from the specified reader or buffer. + * @function decode + * @memberof types.MsgDeposit + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {types.MsgDeposit} MsgDeposit + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgDeposit.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.types.MsgDeposit(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (!(message.coins && message.coins.length)) message.coins = []; + message.coins.push($root.common.Coin.decode(reader, reader.uint32())); + break; + case 2: + message.memo = reader.string(); + break; + case 3: + message.signer = reader.bytes(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgDeposit message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof types.MsgDeposit + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {types.MsgDeposit} MsgDeposit + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgDeposit.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgDeposit message. + * @function verify + * @memberof types.MsgDeposit + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgDeposit.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.coins != null && message.hasOwnProperty('coins')) { + if (!Array.isArray(message.coins)) return 'coins: array expected'; + for (var i = 0; i < message.coins.length; ++i) { + var error = $root.common.Coin.verify(message.coins[i]); + if (error) return 'coins.' + error; + } + } + if (message.memo != null && message.hasOwnProperty('memo')) + if (!$util.isString(message.memo)) return 'memo: string expected'; + if (message.signer != null && message.hasOwnProperty('signer')) + if (!((message.signer && typeof message.signer.length === 'number') || $util.isString(message.signer))) + return 'signer: buffer expected'; + return null; + }; + + /** + * Creates a MsgDeposit message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof types.MsgDeposit + * @static + * @param {Object.} object Plain object + * @returns {types.MsgDeposit} MsgDeposit + */ + MsgDeposit.fromObject = function fromObject(object) { + if (object instanceof $root.types.MsgDeposit) return object; + var message = new $root.types.MsgDeposit(); + if (object.coins) { + if (!Array.isArray(object.coins)) throw TypeError('.types.MsgDeposit.coins: array expected'); + message.coins = []; + for (var i = 0; i < object.coins.length; ++i) { + if (typeof object.coins[i] !== 'object') throw TypeError('.types.MsgDeposit.coins: object expected'); + message.coins[i] = $root.common.Coin.fromObject(object.coins[i]); + } + } + if (object.memo != null) message.memo = String(object.memo); + if (object.signer != null) + if (typeof object.signer === 'string') + $util.base64.decode(object.signer, (message.signer = $util.newBuffer($util.base64.length(object.signer))), 0); + else if (object.signer.length) message.signer = object.signer; + return message; + }; + + /** + * Creates a plain object from a MsgDeposit message. Also converts values to other types if specified. + * @function toObject + * @memberof types.MsgDeposit + * @static + * @param {types.MsgDeposit} message MsgDeposit + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgDeposit.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.coins = []; + if (options.defaults) { + object.memo = ''; + if (options.bytes === String) object.signer = ''; + else { + object.signer = []; + if (options.bytes !== Array) object.signer = $util.newBuffer(object.signer); + } + } + if (message.coins && message.coins.length) { + object.coins = []; + for (var j = 0; j < message.coins.length; ++j) + object.coins[j] = $root.common.Coin.toObject(message.coins[j], options); + } + if (message.memo != null && message.hasOwnProperty('memo')) object.memo = message.memo; + if (message.signer != null && message.hasOwnProperty('signer')) + object.signer = + options.bytes === String + ? $util.base64.encode(message.signer, 0, message.signer.length) + : options.bytes === Array + ? Array.prototype.slice.call(message.signer) + : message.signer; + return object; + }; + + /** + * Converts this MsgDeposit to JSON. + * @function toJSON + * @memberof types.MsgDeposit + * @instance + * @returns {Object.} JSON object + */ + MsgDeposit.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgDeposit; + })(); + + types.MsgSend = (function () { + /** + * Properties of a MsgSend. + * @memberof types + * @interface IMsgSend + * @property {Uint8Array|null} [fromAddress] MsgSend fromAddress + * @property {Uint8Array|null} [toAddress] MsgSend toAddress + * @property {Array.|null} [amount] MsgSend amount + */ + + /** + * Constructs a new MsgSend. + * @memberof types + * @classdesc Represents a MsgSend. + * @implements IMsgSend + * @constructor + * @param {types.IMsgSend=} [properties] Properties to set + */ + function MsgSend(properties) { + this.amount = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * MsgSend fromAddress. + * @member {Uint8Array} fromAddress + * @memberof types.MsgSend + * @instance + */ + MsgSend.prototype.fromAddress = $util.newBuffer([]); + + /** + * MsgSend toAddress. + * @member {Uint8Array} toAddress + * @memberof types.MsgSend + * @instance + */ + MsgSend.prototype.toAddress = $util.newBuffer([]); + + /** + * MsgSend amount. + * @member {Array.} amount + * @memberof types.MsgSend + * @instance + */ + MsgSend.prototype.amount = $util.emptyArray; + + /** + * Creates a new MsgSend instance using the specified properties. + * @function create + * @memberof types.MsgSend + * @static + * @param {types.IMsgSend=} [properties] Properties to set + * @returns {types.MsgSend} MsgSend instance + */ + MsgSend.create = function create(properties) { + return new MsgSend(properties); + }; + + /** + * Encodes the specified MsgSend message. Does not implicitly {@link types.MsgSend.verify|verify} messages. + * @function encode + * @memberof types.MsgSend + * @static + * @param {types.IMsgSend} message MsgSend message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgSend.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.fromAddress != null && Object.hasOwnProperty.call(message, 'fromAddress')) + writer.uint32(/* id 1, wireType 2 =*/ 10).bytes(message.fromAddress); + if (message.toAddress != null && Object.hasOwnProperty.call(message, 'toAddress')) + writer.uint32(/* id 2, wireType 2 =*/ 18).bytes(message.toAddress); + if (message.amount != null && message.amount.length) + for (var i = 0; i < message.amount.length; ++i) + $root.cosmos.base.v1beta1.Coin.encode( + message.amount[i], + writer.uint32(/* id 3, wireType 2 =*/ 26).fork() + ).ldelim(); + return writer; + }; + + /** + * Encodes the specified MsgSend message, length delimited. Does not implicitly {@link types.MsgSend.verify|verify} messages. + * @function encodeDelimited + * @memberof types.MsgSend + * @static + * @param {types.IMsgSend} message MsgSend message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + MsgSend.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a MsgSend message from the specified reader or buffer. + * @function decode + * @memberof types.MsgSend + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {types.MsgSend} MsgSend + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgSend.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.types.MsgSend(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.fromAddress = reader.bytes(); + break; + case 2: + message.toAddress = reader.bytes(); + break; + case 3: + if (!(message.amount && message.amount.length)) message.amount = []; + message.amount.push($root.cosmos.base.v1beta1.Coin.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a MsgSend message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof types.MsgSend + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {types.MsgSend} MsgSend + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + MsgSend.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a MsgSend message. + * @function verify + * @memberof types.MsgSend + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + MsgSend.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.fromAddress != null && message.hasOwnProperty('fromAddress')) + if ( + !( + (message.fromAddress && typeof message.fromAddress.length === 'number') || + $util.isString(message.fromAddress) + ) + ) + return 'fromAddress: buffer expected'; + if (message.toAddress != null && message.hasOwnProperty('toAddress')) + if (!((message.toAddress && typeof message.toAddress.length === 'number') || $util.isString(message.toAddress))) + return 'toAddress: buffer expected'; + if (message.amount != null && message.hasOwnProperty('amount')) { + if (!Array.isArray(message.amount)) return 'amount: array expected'; + for (var i = 0; i < message.amount.length; ++i) { + var error = $root.cosmos.base.v1beta1.Coin.verify(message.amount[i]); + if (error) return 'amount.' + error; + } + } + return null; + }; + + /** + * Creates a MsgSend message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof types.MsgSend + * @static + * @param {Object.} object Plain object + * @returns {types.MsgSend} MsgSend + */ + MsgSend.fromObject = function fromObject(object) { + if (object instanceof $root.types.MsgSend) return object; + var message = new $root.types.MsgSend(); + if (object.fromAddress != null) + if (typeof object.fromAddress === 'string') + $util.base64.decode( + object.fromAddress, + (message.fromAddress = $util.newBuffer($util.base64.length(object.fromAddress))), + 0 + ); + else if (object.fromAddress.length) message.fromAddress = object.fromAddress; + if (object.toAddress != null) + if (typeof object.toAddress === 'string') + $util.base64.decode( + object.toAddress, + (message.toAddress = $util.newBuffer($util.base64.length(object.toAddress))), + 0 + ); + else if (object.toAddress.length) message.toAddress = object.toAddress; + if (object.amount) { + if (!Array.isArray(object.amount)) throw TypeError('.types.MsgSend.amount: array expected'); + message.amount = []; + for (var i = 0; i < object.amount.length; ++i) { + if (typeof object.amount[i] !== 'object') throw TypeError('.types.MsgSend.amount: object expected'); + message.amount[i] = $root.cosmos.base.v1beta1.Coin.fromObject(object.amount[i]); + } + } + return message; + }; + + /** + * Creates a plain object from a MsgSend message. Also converts values to other types if specified. + * @function toObject + * @memberof types.MsgSend + * @static + * @param {types.MsgSend} message MsgSend + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + MsgSend.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.amount = []; + if (options.defaults) { + if (options.bytes === String) object.fromAddress = ''; + else { + object.fromAddress = []; + if (options.bytes !== Array) object.fromAddress = $util.newBuffer(object.fromAddress); + } + if (options.bytes === String) object.toAddress = ''; + else { + object.toAddress = []; + if (options.bytes !== Array) object.toAddress = $util.newBuffer(object.toAddress); + } + } + if (message.fromAddress != null && message.hasOwnProperty('fromAddress')) + object.fromAddress = + options.bytes === String + ? $util.base64.encode(message.fromAddress, 0, message.fromAddress.length) + : options.bytes === Array + ? Array.prototype.slice.call(message.fromAddress) + : message.fromAddress; + if (message.toAddress != null && message.hasOwnProperty('toAddress')) + object.toAddress = + options.bytes === String + ? $util.base64.encode(message.toAddress, 0, message.toAddress.length) + : options.bytes === Array + ? Array.prototype.slice.call(message.toAddress) + : message.toAddress; + if (message.amount && message.amount.length) { + object.amount = []; + for (var j = 0; j < message.amount.length; ++j) + object.amount[j] = $root.cosmos.base.v1beta1.Coin.toObject(message.amount[j], options); + } + return object; + }; + + /** + * Converts this MsgSend to JSON. + * @function toJSON + * @memberof types.MsgSend + * @instance + * @returns {Object.} JSON object + */ + MsgSend.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return MsgSend; + })(); + + return types; +})(); + +$root.cosmos = (function () { + /** + * Namespace cosmos. + * @exports cosmos + * @namespace + */ + var cosmos = {}; + + cosmos.base = (function () { + /** + * Namespace base. + * @memberof cosmos + * @namespace + */ + var base = {}; + + base.v1beta1 = (function () { + /** + * Namespace v1beta1. + * @memberof cosmos.base + * @namespace + */ + var v1beta1 = {}; + + v1beta1.Coin = (function () { + /** + * Properties of a Coin. + * @memberof cosmos.base.v1beta1 + * @interface ICoin + * @property {string|null} [denom] Coin denom + * @property {string|null} [amount] Coin amount + */ + + /** + * Constructs a new Coin. + * @memberof cosmos.base.v1beta1 + * @classdesc Represents a Coin. + * @implements ICoin + * @constructor + * @param {cosmos.base.v1beta1.ICoin=} [properties] Properties to set + */ + function Coin(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * Coin denom. + * @member {string} denom + * @memberof cosmos.base.v1beta1.Coin + * @instance + */ + Coin.prototype.denom = ''; + + /** + * Coin amount. + * @member {string} amount + * @memberof cosmos.base.v1beta1.Coin + * @instance + */ + Coin.prototype.amount = ''; + + /** + * Creates a new Coin instance using the specified properties. + * @function create + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {cosmos.base.v1beta1.ICoin=} [properties] Properties to set + * @returns {cosmos.base.v1beta1.Coin} Coin instance + */ + Coin.create = function create(properties) { + return new Coin(properties); + }; + + /** + * Encodes the specified Coin message. Does not implicitly {@link cosmos.base.v1beta1.Coin.verify|verify} messages. + * @function encode + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {cosmos.base.v1beta1.ICoin} message Coin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Coin.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.denom != null && Object.hasOwnProperty.call(message, 'denom')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.denom); + if (message.amount != null && Object.hasOwnProperty.call(message, 'amount')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.amount); + return writer; + }; + + /** + * Encodes the specified Coin message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.Coin.verify|verify} messages. + * @function encodeDelimited + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {cosmos.base.v1beta1.ICoin} message Coin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Coin.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Coin message from the specified reader or buffer. + * @function decode + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {cosmos.base.v1beta1.Coin} Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Coin.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.cosmos.base.v1beta1.Coin(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denom = reader.string(); + break; + case 2: + message.amount = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Coin message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {cosmos.base.v1beta1.Coin} Coin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Coin.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Coin message. + * @function verify + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Coin.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.denom != null && message.hasOwnProperty('denom')) + if (!$util.isString(message.denom)) return 'denom: string expected'; + if (message.amount != null && message.hasOwnProperty('amount')) + if (!$util.isString(message.amount)) return 'amount: string expected'; + return null; + }; + + /** + * Creates a Coin message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {Object.} object Plain object + * @returns {cosmos.base.v1beta1.Coin} Coin + */ + Coin.fromObject = function fromObject(object) { + if (object instanceof $root.cosmos.base.v1beta1.Coin) return object; + var message = new $root.cosmos.base.v1beta1.Coin(); + if (object.denom != null) message.denom = String(object.denom); + if (object.amount != null) message.amount = String(object.amount); + return message; + }; + + /** + * Creates a plain object from a Coin message. Also converts values to other types if specified. + * @function toObject + * @memberof cosmos.base.v1beta1.Coin + * @static + * @param {cosmos.base.v1beta1.Coin} message Coin + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Coin.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.denom = ''; + object.amount = ''; + } + if (message.denom != null && message.hasOwnProperty('denom')) object.denom = message.denom; + if (message.amount != null && message.hasOwnProperty('amount')) object.amount = message.amount; + return object; + }; + + /** + * Converts this Coin to JSON. + * @function toJSON + * @memberof cosmos.base.v1beta1.Coin + * @instance + * @returns {Object.} JSON object + */ + Coin.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Coin; + })(); + + v1beta1.DecCoin = (function () { + /** + * Properties of a DecCoin. + * @memberof cosmos.base.v1beta1 + * @interface IDecCoin + * @property {string|null} [denom] DecCoin denom + * @property {string|null} [amount] DecCoin amount + */ + + /** + * Constructs a new DecCoin. + * @memberof cosmos.base.v1beta1 + * @classdesc Represents a DecCoin. + * @implements IDecCoin + * @constructor + * @param {cosmos.base.v1beta1.IDecCoin=} [properties] Properties to set + */ + function DecCoin(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * DecCoin denom. + * @member {string} denom + * @memberof cosmos.base.v1beta1.DecCoin + * @instance + */ + DecCoin.prototype.denom = ''; + + /** + * DecCoin amount. + * @member {string} amount + * @memberof cosmos.base.v1beta1.DecCoin + * @instance + */ + DecCoin.prototype.amount = ''; + + /** + * Creates a new DecCoin instance using the specified properties. + * @function create + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {cosmos.base.v1beta1.IDecCoin=} [properties] Properties to set + * @returns {cosmos.base.v1beta1.DecCoin} DecCoin instance + */ + DecCoin.create = function create(properties) { + return new DecCoin(properties); + }; + + /** + * Encodes the specified DecCoin message. Does not implicitly {@link cosmos.base.v1beta1.DecCoin.verify|verify} messages. + * @function encode + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {cosmos.base.v1beta1.IDecCoin} message DecCoin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DecCoin.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.denom != null && Object.hasOwnProperty.call(message, 'denom')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.denom); + if (message.amount != null && Object.hasOwnProperty.call(message, 'amount')) + writer.uint32(/* id 2, wireType 2 =*/ 18).string(message.amount); + return writer; + }; + + /** + * Encodes the specified DecCoin message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.DecCoin.verify|verify} messages. + * @function encodeDelimited + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {cosmos.base.v1beta1.IDecCoin} message DecCoin message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DecCoin.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DecCoin message from the specified reader or buffer. + * @function decode + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {cosmos.base.v1beta1.DecCoin} DecCoin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DecCoin.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.cosmos.base.v1beta1.DecCoin(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.denom = reader.string(); + break; + case 2: + message.amount = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DecCoin message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {cosmos.base.v1beta1.DecCoin} DecCoin + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DecCoin.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DecCoin message. + * @function verify + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DecCoin.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.denom != null && message.hasOwnProperty('denom')) + if (!$util.isString(message.denom)) return 'denom: string expected'; + if (message.amount != null && message.hasOwnProperty('amount')) + if (!$util.isString(message.amount)) return 'amount: string expected'; + return null; + }; + + /** + * Creates a DecCoin message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {Object.} object Plain object + * @returns {cosmos.base.v1beta1.DecCoin} DecCoin + */ + DecCoin.fromObject = function fromObject(object) { + if (object instanceof $root.cosmos.base.v1beta1.DecCoin) return object; + var message = new $root.cosmos.base.v1beta1.DecCoin(); + if (object.denom != null) message.denom = String(object.denom); + if (object.amount != null) message.amount = String(object.amount); + return message; + }; + + /** + * Creates a plain object from a DecCoin message. Also converts values to other types if specified. + * @function toObject + * @memberof cosmos.base.v1beta1.DecCoin + * @static + * @param {cosmos.base.v1beta1.DecCoin} message DecCoin + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DecCoin.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.denom = ''; + object.amount = ''; + } + if (message.denom != null && message.hasOwnProperty('denom')) object.denom = message.denom; + if (message.amount != null && message.hasOwnProperty('amount')) object.amount = message.amount; + return object; + }; + + /** + * Converts this DecCoin to JSON. + * @function toJSON + * @memberof cosmos.base.v1beta1.DecCoin + * @instance + * @returns {Object.} JSON object + */ + DecCoin.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DecCoin; + })(); + + v1beta1.IntProto = (function () { + /** + * Properties of an IntProto. + * @memberof cosmos.base.v1beta1 + * @interface IIntProto + * @property {string|null} [int] IntProto int + */ + + /** + * Constructs a new IntProto. + * @memberof cosmos.base.v1beta1 + * @classdesc Represents an IntProto. + * @implements IIntProto + * @constructor + * @param {cosmos.base.v1beta1.IIntProto=} [properties] Properties to set + */ + function IntProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * IntProto int. + * @member {string} int + * @memberof cosmos.base.v1beta1.IntProto + * @instance + */ + IntProto.prototype.int = ''; + + /** + * Creates a new IntProto instance using the specified properties. + * @function create + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {cosmos.base.v1beta1.IIntProto=} [properties] Properties to set + * @returns {cosmos.base.v1beta1.IntProto} IntProto instance + */ + IntProto.create = function create(properties) { + return new IntProto(properties); + }; + + /** + * Encodes the specified IntProto message. Does not implicitly {@link cosmos.base.v1beta1.IntProto.verify|verify} messages. + * @function encode + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {cosmos.base.v1beta1.IIntProto} message IntProto message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + IntProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.int != null && Object.hasOwnProperty.call(message, 'int')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.int); + return writer; + }; + + /** + * Encodes the specified IntProto message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.IntProto.verify|verify} messages. + * @function encodeDelimited + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {cosmos.base.v1beta1.IIntProto} message IntProto message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + IntProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an IntProto message from the specified reader or buffer. + * @function decode + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {cosmos.base.v1beta1.IntProto} IntProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + IntProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.cosmos.base.v1beta1.IntProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.int = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an IntProto message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {cosmos.base.v1beta1.IntProto} IntProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + IntProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an IntProto message. + * @function verify + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + IntProto.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.int != null && message.hasOwnProperty('int')) + if (!$util.isString(message.int)) return 'int: string expected'; + return null; + }; + + /** + * Creates an IntProto message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {Object.} object Plain object + * @returns {cosmos.base.v1beta1.IntProto} IntProto + */ + IntProto.fromObject = function fromObject(object) { + if (object instanceof $root.cosmos.base.v1beta1.IntProto) return object; + var message = new $root.cosmos.base.v1beta1.IntProto(); + if (object.int != null) message.int = String(object.int); + return message; + }; + + /** + * Creates a plain object from an IntProto message. Also converts values to other types if specified. + * @function toObject + * @memberof cosmos.base.v1beta1.IntProto + * @static + * @param {cosmos.base.v1beta1.IntProto} message IntProto + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + IntProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.int = ''; + if (message.int != null && message.hasOwnProperty('int')) object.int = message.int; + return object; + }; + + /** + * Converts this IntProto to JSON. + * @function toJSON + * @memberof cosmos.base.v1beta1.IntProto + * @instance + * @returns {Object.} JSON object + */ + IntProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return IntProto; + })(); + + v1beta1.DecProto = (function () { + /** + * Properties of a DecProto. + * @memberof cosmos.base.v1beta1 + * @interface IDecProto + * @property {string|null} [dec] DecProto dec + */ + + /** + * Constructs a new DecProto. + * @memberof cosmos.base.v1beta1 + * @classdesc Represents a DecProto. + * @implements IDecProto + * @constructor + * @param {cosmos.base.v1beta1.IDecProto=} [properties] Properties to set + */ + function DecProto(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } + + /** + * DecProto dec. + * @member {string} dec + * @memberof cosmos.base.v1beta1.DecProto + * @instance + */ + DecProto.prototype.dec = ''; + + /** + * Creates a new DecProto instance using the specified properties. + * @function create + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {cosmos.base.v1beta1.IDecProto=} [properties] Properties to set + * @returns {cosmos.base.v1beta1.DecProto} DecProto instance + */ + DecProto.create = function create(properties) { + return new DecProto(properties); + }; + + /** + * Encodes the specified DecProto message. Does not implicitly {@link cosmos.base.v1beta1.DecProto.verify|verify} messages. + * @function encode + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {cosmos.base.v1beta1.IDecProto} message DecProto message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DecProto.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.dec != null && Object.hasOwnProperty.call(message, 'dec')) + writer.uint32(/* id 1, wireType 2 =*/ 10).string(message.dec); + return writer; + }; + + /** + * Encodes the specified DecProto message, length delimited. Does not implicitly {@link cosmos.base.v1beta1.DecProto.verify|verify} messages. + * @function encodeDelimited + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {cosmos.base.v1beta1.IDecProto} message DecProto message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + DecProto.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a DecProto message from the specified reader or buffer. + * @function decode + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {cosmos.base.v1beta1.DecProto} DecProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DecProto.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, + message = new $root.cosmos.base.v1beta1.DecProto(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.dec = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a DecProto message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {cosmos.base.v1beta1.DecProto} DecProto + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + DecProto.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a DecProto message. + * @function verify + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + DecProto.verify = function verify(message) { + if (typeof message !== 'object' || message === null) return 'object expected'; + if (message.dec != null && message.hasOwnProperty('dec')) + if (!$util.isString(message.dec)) return 'dec: string expected'; + return null; + }; + + /** + * Creates a DecProto message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {Object.} object Plain object + * @returns {cosmos.base.v1beta1.DecProto} DecProto + */ + DecProto.fromObject = function fromObject(object) { + if (object instanceof $root.cosmos.base.v1beta1.DecProto) return object; + var message = new $root.cosmos.base.v1beta1.DecProto(); + if (object.dec != null) message.dec = String(object.dec); + return message; + }; + + /** + * Creates a plain object from a DecProto message. Also converts values to other types if specified. + * @function toObject + * @memberof cosmos.base.v1beta1.DecProto + * @static + * @param {cosmos.base.v1beta1.DecProto} message DecProto + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + DecProto.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) object.dec = ''; + if (message.dec != null && message.hasOwnProperty('dec')) object.dec = message.dec; + return object; + }; + + /** + * Converts this DecProto to JSON. + * @function toJSON + * @memberof cosmos.base.v1beta1.DecProto + * @instance + * @returns {Object.} JSON object + */ + DecProto.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return DecProto; + })(); + + return v1beta1; + })(); + + return base; + })(); + + return cosmos; +})(); + +module.exports = $root; diff --git a/modules/abstract-cosmos/src/lib/constants.ts b/modules/abstract-cosmos/src/lib/constants.ts index ed8dd0f2c3..b8c7b233aa 100644 --- a/modules/abstract-cosmos/src/lib/constants.ts +++ b/modules/abstract-cosmos/src/lib/constants.ts @@ -7,3 +7,4 @@ export const withdrawDelegatorRewardMsgTypeUrl = '/cosmos.distribution.v1beta1.M export const executeContractMsgTypeUrl = '/cosmwasm.wasm.v1.MsgExecuteContract'; export const UNAVAILABLE_TEXT = 'UNAVAILABLE'; export const ROOT_PATH = 'm/0'; +export const sendMsgType = '/types.MsgSend'; // thorchain uses this custom message type diff --git a/modules/abstract-cosmos/src/lib/utils.ts b/modules/abstract-cosmos/src/lib/utils.ts index b2ccb7baf3..c84b0055f4 100644 --- a/modules/abstract-cosmos/src/lib/utils.ts +++ b/modules/abstract-cosmos/src/lib/utils.ts @@ -22,6 +22,7 @@ import BigNumber from 'bignumber.js'; import { SignDoc, TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'; import { Any } from 'cosmjs-types/google/protobuf/any'; import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; +const { MsgSend } = require('../../resources/MsgCompiled').types; import { Hash, createHash } from 'crypto'; import * as constants from './constants'; @@ -38,11 +39,12 @@ import { import { CosmosKeyPair as KeyPair } from './keyPair'; export class CosmosUtils implements BaseUtils { - private registry; + protected registry; constructor() { this.registry = new Registry([...defaultRegistryTypes]); this.registry.register(constants.executeContractMsgTypeUrl, MsgExecuteContract); + this.registry.register('/types.MsgSend', MsgSend); } /** @inheritdoc */ @@ -340,6 +342,8 @@ export class CosmosUtils implements BaseUtils { switch (typeUrl) { case constants.sendMsgTypeUrl: return TransactionType.Send; + case constants.sendMsgType: + return TransactionType.Send; case constants.delegateMsgTypeUrl: return TransactionType.StakingActivate; case constants.undelegateMsgTypeUrl: diff --git a/modules/abstract-cosmos/tsconfig.json b/modules/abstract-cosmos/tsconfig.json index 7850cc8778..cb6a620eb2 100644 --- a/modules/abstract-cosmos/tsconfig.json +++ b/modules/abstract-cosmos/tsconfig.json @@ -4,10 +4,10 @@ "outDir": "./dist", "rootDir": "./", "strictPropertyInitialization": false, - "esModuleInterop": false, + "esModuleInterop": true, "typeRoots": ["../../types", "./node_modules/@types", "../../node_modules/@types"] }, - "include": ["src/**/*"], + "include": ["src/**/*", "resources/**/*"], "exclude": ["node_modules"], "references": [ { diff --git a/modules/account-lib/package.json b/modules/account-lib/package.json index 9322cb4f3b..64db4ac187 100644 --- a/modules/account-lib/package.json +++ b/modules/account-lib/package.json @@ -51,6 +51,7 @@ "@bitgo/sdk-coin-osmo": "^3.0.11", "@bitgo/sdk-coin-polygon": "^21.0.11", "@bitgo/sdk-coin-rbtc": "^2.0.42", + "@bitgo/sdk-coin-rune": "^1.0.0", "@bitgo/sdk-coin-sei": "^3.0.11", "@bitgo/sdk-coin-sol": "^4.6.1", "@bitgo/sdk-coin-stx": "^3.2.27", diff --git a/modules/account-lib/src/index.ts b/modules/account-lib/src/index.ts index 18f7dbd611..be46e0aa78 100644 --- a/modules/account-lib/src/index.ts +++ b/modules/account-lib/src/index.ts @@ -101,6 +101,9 @@ export { Zeta }; import * as Coreum from '@bitgo/sdk-coin-coreum'; export { Coreum }; +import * as Rune from '@bitgo/sdk-coin-rune'; +export { Rune }; + import * as Sol from '@bitgo/sdk-coin-sol'; export { Sol }; @@ -196,6 +199,8 @@ const coinBuilderMap = { tzketh: zkEth.TransactionBuilder, bera: Bera.TransactionBuilder, tbera: Bera.TransactionBuilder, + rune: Rune.TransactionBuilderFactory, + trune: Rune.TransactionBuilderFactory, }; /** diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index 3635df5d90..dddb97fe41 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -90,6 +90,7 @@ "@bitgo/sdk-coin-sol": "^4.6.1", "@bitgo/sdk-coin-stx": "^3.2.27", "@bitgo/sdk-coin-sui": "^5.8.1", + "@bitgo/sdk-coin-rune": "^1.0.0", "@bitgo/sdk-coin-tia": "^3.0.11", "@bitgo/sdk-coin-ton": "^3.3.3", "@bitgo/sdk-coin-trx": "^2.0.42", diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index b30ef05404..cc5344303a 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -62,6 +62,7 @@ import { Osmo, Polygon, PolygonToken, + Rune, Rbtc, Sei, Sol, @@ -110,6 +111,7 @@ import { Topeth, Tpolygon, Trbtc, + Trune, Trx, Tsei, Tsol, @@ -180,6 +182,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('osmo', Osmo.createInstance); globalCoinFactory.register('polygon', Polygon.createInstance); globalCoinFactory.register('rbtc', Rbtc.createInstance); + globalCoinFactory.register('thorchain:rune', Rune.createInstance); globalCoinFactory.register('sei', Sei.createInstance); globalCoinFactory.register('sol', Sol.createInstance); globalCoinFactory.register('stx', Stx.createInstance); @@ -227,6 +230,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('tosmo', Tosmo.createInstance); globalCoinFactory.register('tpolygon', Tpolygon.createInstance); globalCoinFactory.register('trbtc', Trbtc.createInstance); + globalCoinFactory.register('thorchain:trune', Trune.createInstance); globalCoinFactory.register('trx', Trx.createInstance); globalCoinFactory.register('tsei', Tsei.createInstance); globalCoinFactory.register('tsol', Tsol.createInstance); diff --git a/modules/bitgo/src/v2/coins/index.ts b/modules/bitgo/src/v2/coins/index.ts index a0b4cc139c..23fe90dcb4 100644 --- a/modules/bitgo/src/v2/coins/index.ts +++ b/modules/bitgo/src/v2/coins/index.ts @@ -36,6 +36,7 @@ import { Opeth, Topeth, OpethToken } from '@bitgo/sdk-coin-opeth'; import { Osmo, Tosmo } from '@bitgo/sdk-coin-osmo'; import { Polygon, PolygonToken, Tpolygon } from '@bitgo/sdk-coin-polygon'; import { Rbtc, Trbtc } from '@bitgo/sdk-coin-rbtc'; +import { Rune, Trune } from '@bitgo/sdk-coin-rune'; import { Sei, Tsei } from '@bitgo/sdk-coin-sei'; import { Sol, Tsol } from '@bitgo/sdk-coin-sol'; import { Stx, Tstx } from '@bitgo/sdk-coin-stx'; @@ -85,6 +86,7 @@ export { Opeth, Topeth, OpethToken }; export { Osmo, Tosmo }; export { Polygon, PolygonToken, Tpolygon }; export { Rbtc, Trbtc }; +export { Rune, Trune }; export { Sol, Tsol }; export { Stx, Tstx }; export { Sui, Tsui, SuiToken }; diff --git a/modules/bitgo/test/browser/browser.spec.ts b/modules/bitgo/test/browser/browser.spec.ts index 5bd67cea65..a74539120e 100644 --- a/modules/bitgo/test/browser/browser.spec.ts +++ b/modules/bitgo/test/browser/browser.spec.ts @@ -10,6 +10,7 @@ describe('Coins', () => { const BitGoJS = window['BitGoJS']; const bitgo = new BitGoJS.BitGo({ env: 'test' }); // these objects are defined in BitGoJS.Coin, but are not coins in the traditional sense + // or if statics coins name ("thorchain:rune") doesn't match with class name (Rune) const excludedKeys = { AbstractUtxoCoin: 1, AbstractLightningCoin: 1, @@ -30,6 +31,8 @@ describe('Coins', () => { SuiToken: 1, BeraToken: 1, XrpToken: 1, + Rune: 1, + Trune: 1, }; Object.keys(BitGoJS.Coin) .filter((coinName) => !excludedKeys[coinName]) diff --git a/modules/bitgo/test/v2/unit/keychains.ts b/modules/bitgo/test/v2/unit/keychains.ts index 8c42301f24..88512fc82b 100644 --- a/modules/bitgo/test/v2/unit/keychains.ts +++ b/modules/bitgo/test/v2/unit/keychains.ts @@ -75,6 +75,7 @@ describe('V2 Keychains', function () { n.asset !== UnderlyingAsset.ARBETH && // TODO(WIN-692): remove this once coin-specific module for arbeth is added n.asset !== UnderlyingAsset.OPETH && // TODO(WIN-692): remove this once coin-specific module for opeth is added n.asset !== UnderlyingAsset.ZKETH && // TODO(WIN-1427): remove this once coin-specific module for zketh is added + n.asset !== UnderlyingAsset.RUNE && coinFamilyValues.includes(n.name) ); diff --git a/modules/bitgo/tsconfig.json b/modules/bitgo/tsconfig.json index 02b22b9832..cb41ab01da 100644 --- a/modules/bitgo/tsconfig.json +++ b/modules/bitgo/tsconfig.json @@ -111,10 +111,10 @@ "path": "../sdk-coin-eth2" }, { - "path": "../sdk-coin-ethw" + "path": "../sdk-coin-ethlike" }, { - "path": "../sdk-coin-ethlike" + "path": "../sdk-coin-ethw" }, { "path": "../sdk-coin-hash" @@ -149,6 +149,9 @@ { "path": "../sdk-coin-rbtc" }, + { + "path": "../sdk-coin-rune" + }, { "path": "../sdk-coin-sei" }, diff --git a/modules/sdk-coin-rune/.eslintignore b/modules/sdk-coin-rune/.eslintignore new file mode 100644 index 0000000000..190f83e0df --- /dev/null +++ b/modules/sdk-coin-rune/.eslintignore @@ -0,0 +1,5 @@ +node_modules +.idea +public +dist + diff --git a/modules/sdk-coin-rune/.gitignore b/modules/sdk-coin-rune/.gitignore new file mode 100644 index 0000000000..67ccce4c64 --- /dev/null +++ b/modules/sdk-coin-rune/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.idea/ +dist/ diff --git a/modules/sdk-coin-rune/.mocharc.yml b/modules/sdk-coin-rune/.mocharc.yml new file mode 100644 index 0000000000..95814796d1 --- /dev/null +++ b/modules/sdk-coin-rune/.mocharc.yml @@ -0,0 +1,8 @@ +require: 'ts-node/register' +timeout: '60000' +reporter: 'min' +reporter-option: + - 'cdn=true' + - 'json=false' +exit: true +spec: ['test/unit/**/*.ts'] diff --git a/modules/sdk-coin-rune/.npmignore b/modules/sdk-coin-rune/.npmignore new file mode 100644 index 0000000000..d5fb3a098c --- /dev/null +++ b/modules/sdk-coin-rune/.npmignore @@ -0,0 +1,14 @@ +!dist/ +dist/test/ +dist/tsconfig.tsbuildinfo +.idea/ +.prettierrc.yml +tsconfig.json +src/ +test/ +scripts/ +.nyc_output +CODEOWNERS +node_modules/ +.prettierignore +.mocharc.js diff --git a/modules/sdk-coin-rune/.prettierignore b/modules/sdk-coin-rune/.prettierignore new file mode 100644 index 0000000000..3a11d6af29 --- /dev/null +++ b/modules/sdk-coin-rune/.prettierignore @@ -0,0 +1,2 @@ +.nyc_output/ +dist/ diff --git a/modules/sdk-coin-rune/.prettierrc.yml b/modules/sdk-coin-rune/.prettierrc.yml new file mode 100644 index 0000000000..7c3d8dd32a --- /dev/null +++ b/modules/sdk-coin-rune/.prettierrc.yml @@ -0,0 +1,3 @@ +printWidth: 120 +singleQuote: true +trailingComma: 'es5' diff --git a/modules/sdk-coin-rune/README.md b/modules/sdk-coin-rune/README.md new file mode 100644 index 0000000000..c36463db9d --- /dev/null +++ b/modules/sdk-coin-rune/README.md @@ -0,0 +1,30 @@ +# BitGo sdk-coin-rune + +SDK coins provide a modular approach to a monolithic architecture. This and all BitGoJS SDK coins allow developers to use only the coins needed for a given project. + +## Installation + +All coins are loaded traditionally through the `bitgo` package. If you are using coins individually, you will be accessing the coin via the `@bitgo/sdk-api` package. + +In your project install both `@bitgo/sdk-api` and `@bitgo/sdk-coin-rune`. + +```shell +npm i @bitgo/sdk-api @bitgo/sdk-coin-rune +``` + +Next, you will be able to initialize an instance of "bitgo" through `@bitgo/sdk-api` instead of `bitgo`. + +```javascript +import { BitGoAPI } from '@bitgo/sdk-api'; +import { Rune } from '@bitgo/sdk-coin-rune'; + +const sdk = new BitGoAPI(); + +sdk.register('thorchain:rune', Rune.createInstance); +``` + +## Development + +Most of the coin implementations are derived from `@bitgo/sdk-core`, `@bitgo/statics`, and coin specific packages. These implementations are used to interact with the BitGo API and BitGo platform services. + +You will notice that the basic version of common class extensions have been provided to you and must be resolved before the package build will succeed. Upon initiation of a given SDK coin, you will need to verify that your coin has been included in the root `tsconfig.packages.json` and that the linting, formatting, and testing succeeds when run both within the coin and from the root of BitGoJS. diff --git a/modules/sdk-coin-rune/package.json b/modules/sdk-coin-rune/package.json new file mode 100644 index 0000000000..ec61df2015 --- /dev/null +++ b/modules/sdk-coin-rune/package.json @@ -0,0 +1,58 @@ +{ + "name": "@bitgo/sdk-coin-rune", + "version": "1.0.0", + "description": "BitGo SDK coin library for Thorchain", + "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts", + "scripts": { + "build": "yarn tsc --build --incremental --verbose .", + "fmt": "prettier --write .", + "check-fmt": "prettier --check .", + "clean": "rm -r ./dist", + "lint": "eslint --quiet .", + "prepare": "npm run build", + "test": "npm run coverage", + "coverage": "nyc -- npm run unit-test", + "unit-test": "mocha" + }, + "author": "BitGo SDK Team ", + "license": "MIT", + "engines": { + "node": ">=18 <21" + }, + "repository": { + "type": "git", + "url": "https://github.com/BitGo/BitGoJS.git", + "directory": "modules/sdk-coin-rune" + }, + "lint-staged": { + "*.{js,ts}": [ + "yarn prettier --write", + "yarn eslint --fix" + ] + }, + "publishConfig": { + "access": "public" + }, + "nyc": { + "extension": [ + ".ts" + ] + }, + "dependencies": { + "@bitgo/abstract-cosmos": "^11.0.11", + "@bitgo/sdk-core": "^28.11.0", + "@bitgo/statics": "^50.4.0", + "@cosmjs/amino": "^0.29.5", + "@cosmjs/encoding": "^0.29.5", + "@cosmjs/proto-signing": "^0.29.5", + "@cosmjs/stargate": "^0.29.5", + "bech32-buffer": "^0.2.1", + "bignumber.js": "^9.1.1", + "lodash": "^4.17.21" + }, + "devDependencies": { + "@bitgo/sdk-api": "^1.56.0", + "@bitgo/sdk-test": "^8.0.47" + } +} diff --git a/modules/sdk-coin-rune/src/index.ts b/modules/sdk-coin-rune/src/index.ts new file mode 100644 index 0000000000..7d1754b520 --- /dev/null +++ b/modules/sdk-coin-rune/src/index.ts @@ -0,0 +1,4 @@ +export * from './rune'; +export * from './trune'; +export * from './lib'; +export * from './register'; diff --git a/modules/sdk-coin-rune/src/lib/constants.ts b/modules/sdk-coin-rune/src/lib/constants.ts new file mode 100644 index 0000000000..2d161b65ac --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/constants.ts @@ -0,0 +1,12 @@ +export const mainnetValidDenoms = ['rune']; +export const mainnetAccountAddressRegex = /^(thor)1(['qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38})$/; +export const mainnetValidatorAddressRegex = /^(thor)1(['qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38})$/; +export const MAINNET_ADDRESS_PREFIX = 'thor'; + +export const testnetValidDenoms = ['rune']; +export const testnetAccountAddressRegex = /^(sthor)1(['qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38})$/; +export const testnetValidatorAddressRegex = /^(sthor)1(['qpzry9x8gf2tvdw0s3jn54khce6mua7l]{38})$/; +export const TESTNET_ADDRESS_PREFIX = 'sthor'; + +export const GAS_LIMIT = 200000; +export const GAS_AMOUNT = '150000'; diff --git a/modules/sdk-coin-rune/src/lib/iface.ts b/modules/sdk-coin-rune/src/lib/iface.ts new file mode 100644 index 0000000000..1ce7eb32d0 --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/iface.ts @@ -0,0 +1,6 @@ +import { CosmosTransactionMessage } from '@bitgo/abstract-cosmos'; + +export interface MessageData { + typeUrl: string; + value: CosmosTransactionMessage; +} diff --git a/modules/sdk-coin-rune/src/lib/index.ts b/modules/sdk-coin-rune/src/lib/index.ts new file mode 100644 index 0000000000..87cc346db5 --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/index.ts @@ -0,0 +1,10 @@ +import * as Constants from './constants'; +import * as Utils from './utils'; + +export { + CosmosTransaction as Transaction, + CosmosTransactionBuilder as TransactionBuilder, +} from '@bitgo/abstract-cosmos'; +export { KeyPair } from './keyPair'; +export { TransactionBuilderFactory } from './transactionBuilderFactory'; +export { Constants, Utils }; diff --git a/modules/sdk-coin-rune/src/lib/keyPair.ts b/modules/sdk-coin-rune/src/lib/keyPair.ts new file mode 100644 index 0000000000..4311f9b767 --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/keyPair.ts @@ -0,0 +1,27 @@ +import { KeyPairOptions, AddressFormat } from '@bitgo/sdk-core'; +import { pubkeyToAddress } from '@cosmjs/amino'; + +import { CosmosKeyPair } from '@bitgo/abstract-cosmos'; +import { MAINNET_ADDRESS_PREFIX, TESTNET_ADDRESS_PREFIX } from './constants'; + +/** + * Rune keys and address management. + */ +export class KeyPair extends CosmosKeyPair { + constructor(source?: KeyPairOptions) { + super(source); + } + + /** @inheritdoc */ + getAddress(format: AddressFormat = AddressFormat.mainnet): string { + const base64String = Buffer.from(this.getKeys().pub.slice(0, 66), 'hex').toString('base64'); + const address_prefix = format === AddressFormat.testnet ? TESTNET_ADDRESS_PREFIX : MAINNET_ADDRESS_PREFIX; + return pubkeyToAddress( + { + type: 'tendermint/PubKeySecp256k1', + value: base64String, + }, + address_prefix + ); + } +} diff --git a/modules/sdk-coin-rune/src/lib/transactionBuilderFactory.ts b/modules/sdk-coin-rune/src/lib/transactionBuilderFactory.ts new file mode 100644 index 0000000000..16e3a537fe --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/transactionBuilderFactory.ts @@ -0,0 +1,101 @@ +import { + CosmosTransaction, + CosmosTransactionBuilder, + CosmosTransferBuilder, + StakingActivateBuilder, + StakingDeactivateBuilder, + StakingWithdrawRewardsBuilder, + StakingRedelegateBuilder, +} from '@bitgo/abstract-cosmos'; +import { BaseTransactionBuilderFactory, InvalidTransactionError, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { RuneTransferBuilder } from './transferBuilder'; +import { RuneUtils } from './utils'; + +export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { + constructor(_coinConfig: Readonly) { + super(_coinConfig); + } + + /** @inheritdoc */ + from(raw: string): CosmosTransactionBuilder { + const tx = new CosmosTransaction(this._coinConfig, new RuneUtils(this._coinConfig.network.type)); + tx.enrichTransactionDetailsFromRawTransaction(raw); + try { + switch (tx.type) { + case TransactionType.Send: + return this.getTransferBuilder(tx); + case TransactionType.StakingActivate: + return this.getStakingActivateBuilder(tx); + case TransactionType.StakingDeactivate: + return this.getStakingDeactivateBuilder(tx); + case TransactionType.StakingWithdraw: + return this.getStakingWithdrawRewardsBuilder(tx); + case TransactionType.StakingRedelegate: + return this.getStakingRedelegateBuilder(tx); + default: + throw new InvalidTransactionError('Invalid transaction'); + } + } catch (e) { + throw new InvalidTransactionError('Invalid transaction: ' + e.message); + } + } + + /** @inheritdoc */ + getTransferBuilder(tx?: CosmosTransaction): CosmosTransferBuilder { + return this.initializeBuilder( + tx, + new RuneTransferBuilder(this._coinConfig, new RuneUtils(this._coinConfig.network.type)) + ); + } + + /** @inheritdoc */ + getStakingActivateBuilder(tx?: CosmosTransaction): StakingActivateBuilder { + return this.initializeBuilder( + tx, + new StakingActivateBuilder(this._coinConfig, new RuneUtils(this._coinConfig.network.type)) + ); + } + + /** @inheritdoc */ + getStakingDeactivateBuilder(tx?: CosmosTransaction): StakingDeactivateBuilder { + return this.initializeBuilder( + tx, + new StakingDeactivateBuilder(this._coinConfig, new RuneUtils(this._coinConfig.network.type)) + ); + } + + /** @inheritdoc */ + getStakingWithdrawRewardsBuilder(tx?: CosmosTransaction): StakingWithdrawRewardsBuilder { + return this.initializeBuilder( + tx, + new StakingWithdrawRewardsBuilder(this._coinConfig, new RuneUtils(this._coinConfig.network.type)) + ); + } + + getStakingRedelegateBuilder(tx?: CosmosTransaction): StakingRedelegateBuilder { + return this.initializeBuilder( + tx, + new StakingRedelegateBuilder(this._coinConfig, new RuneUtils(this._coinConfig.network.type)) + ); + } + + /** @inheritdoc */ + getWalletInitializationBuilder(): void { + throw new Error('Method not implemented.'); + } + + /** + * Initialize the builder with the given transaction + * + * @param {CosmosTransaction | undefined} tx - the transaction used to initialize the builder + * @param {CosmosTransactionBuilder} builder - the builder to be initialized + * @returns {CosmosTransactionBuilder} the builder initialized + */ + protected initializeBuilder(tx: CosmosTransaction | undefined, builder: T): T { + if (tx) { + builder.initBuilder(tx); + } + return builder; + } +} diff --git a/modules/sdk-coin-rune/src/lib/transferBuilder.ts b/modules/sdk-coin-rune/src/lib/transferBuilder.ts new file mode 100644 index 0000000000..a83cb715d2 --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/transferBuilder.ts @@ -0,0 +1,28 @@ +import { TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { CosmosTransferBuilder, CosmosUtils, SendMessage } from '@bitgo/abstract-cosmos'; + +export class RuneTransferBuilder extends CosmosTransferBuilder { + protected _utils: CosmosUtils; + + constructor(_coinConfig: Readonly, utils: CosmosUtils) { + super(_coinConfig, utils); + this._utils = utils; + } + + protected get transactionType(): TransactionType { + return TransactionType.Send; + } + + /** @inheritdoc */ + messages(sendMessages: SendMessage[]): this { + this._messages = sendMessages.map((sendMessage) => { + this._utils.validateSendMessage(sendMessage); + return { + typeUrl: '/types.MsgSend', + value: sendMessage, + }; + }); + return this; + } +} diff --git a/modules/sdk-coin-rune/src/lib/utils.ts b/modules/sdk-coin-rune/src/lib/utils.ts new file mode 100644 index 0000000000..848bc47f2b --- /dev/null +++ b/modules/sdk-coin-rune/src/lib/utils.ts @@ -0,0 +1,138 @@ +import { InvalidTransactionError } from '@bitgo/sdk-core'; +import { Coin } from '@cosmjs/stargate'; +import BigNumber from 'bignumber.js'; + +import { CosmosLikeTransaction, CosmosUtils, FeeData } from '@bitgo/abstract-cosmos'; +import { MessageData } from './iface'; +import * as constants from './constants'; +import { NetworkType } from '@bitgo/statics'; +import { DecodedTxRaw } from '@cosmjs/proto-signing'; +import { MAINNET_ADDRESS_PREFIX, TESTNET_ADDRESS_PREFIX } from './constants'; +const bech32 = require('bech32-buffer'); + +export class RuneUtils extends CosmosUtils { + private networkType: NetworkType; + constructor(networkType: NetworkType = NetworkType.MAINNET) { + super(); + this.networkType = networkType; + } + + getSendMessageDataFromDecodedTx(decodedTx: DecodedTxRaw): MessageData[] { + return decodedTx.body.messages.map((message) => { + const value = this.registry.decode(message); + return { + value: { + fromAddress: + this.networkType === NetworkType.TESTNET + ? bech32.encode(TESTNET_ADDRESS_PREFIX, value.fromAddress) + : bech32.encode(MAINNET_ADDRESS_PREFIX, value.fromAddress), + toAddress: + this.networkType === NetworkType.TESTNET + ? bech32.encode(TESTNET_ADDRESS_PREFIX, value.toAddress) + : bech32.encode(MAINNET_ADDRESS_PREFIX, value.toAddress), + amount: value.amount, + }, + typeUrl: message.typeUrl, + }; + }); + } + + /** @inheritdoc */ + isValidAddress(address: string | Buffer): boolean { + if (address === undefined) { + return false; + } + if (typeof address !== 'string') { + const encodedAddress = + this.networkType === NetworkType.TESTNET + ? bech32.encode(TESTNET_ADDRESS_PREFIX, address) + : bech32.encode(MAINNET_ADDRESS_PREFIX, address); + if (this.networkType === NetworkType.TESTNET) { + return this.isValidCosmosLikeAddressWithMemoId(encodedAddress, constants.testnetAccountAddressRegex); + } + return this.isValidCosmosLikeAddressWithMemoId(encodedAddress, constants.mainnetAccountAddressRegex); + } else { + if (this.networkType === NetworkType.TESTNET) { + return this.isValidCosmosLikeAddressWithMemoId(address, constants.testnetAccountAddressRegex); + } + return this.isValidCosmosLikeAddressWithMemoId(address, constants.mainnetAccountAddressRegex); + } + } + + /** @inheritdoc */ + isValidValidatorAddress(address: string): boolean { + if (this.networkType === NetworkType.TESTNET) { + return this.isValidBech32AddressMatchingRegex(address, constants.testnetValidatorAddressRegex); + } + return this.isValidBech32AddressMatchingRegex(address, constants.mainnetValidatorAddressRegex); + } + + /** @inheritdoc */ + validateAmount(amount: Coin): void { + const amountBig = BigNumber(amount.amount); + if (amountBig.isLessThanOrEqualTo(0)) { + throw new InvalidTransactionError('transactionBuilder: validateAmount: Invalid amount: ' + amount.amount); + } + if ( + (this.networkType === NetworkType.TESTNET && + !constants.testnetValidDenoms.find((denom) => denom === amount.denom)) || + (this.networkType === NetworkType.MAINNET && + !constants.mainnetValidDenoms.find((denom) => denom === amount.denom)) + ) { + throw new InvalidTransactionError('transactionBuilder: validateAmount: Invalid denom: ' + amount.denom); + } + } + + convertMessageAddressToBuffer(messages: MessageData[]): MessageData[] { + return messages.map((message) => { + if ('fromAddress' in message.value && 'toAddress' in message.value) { + const sendMessage = message.value; + + const decodedFrom = + typeof sendMessage.fromAddress === 'string' + ? bech32.decode(sendMessage.fromAddress).data + : sendMessage.fromAddress; + const decodedTo = + typeof sendMessage.toAddress === 'string' ? bech32.decode(sendMessage.toAddress).data : sendMessage.toAddress; + + return { + ...message, + value: { + ...sendMessage, + fromAddress: decodedFrom, + toAddress: decodedTo, + }, + }; + } + + return message; + }); + } + + createTransaction( + sequence: number, + messages: MessageData[], + gasBudget: FeeData, + publicKey?: string, + memo?: string + ): CosmosLikeTransaction { + messages = this.convertMessageAddressToBuffer(messages); + const cosmosLikeTxn = { + sequence: sequence, + sendMessages: messages, + gasBudget: gasBudget, + publicKey: publicKey, + memo: memo, + }; + this.validateTransaction(cosmosLikeTxn); + return cosmosLikeTxn; + } + + getNetworkPrefix() { + return this.networkType === NetworkType.TESTNET ? TESTNET_ADDRESS_PREFIX : MAINNET_ADDRESS_PREFIX; + } +} + +const runeUtils = new RuneUtils(); + +export default runeUtils; diff --git a/modules/sdk-coin-rune/src/register.ts b/modules/sdk-coin-rune/src/register.ts new file mode 100644 index 0000000000..56648cba8d --- /dev/null +++ b/modules/sdk-coin-rune/src/register.ts @@ -0,0 +1,8 @@ +import { BitGoBase } from '@bitgo/sdk-core'; +import { Rune } from './rune'; +import { Trune } from './trune'; + +export const register = (sdk: BitGoBase): void => { + sdk.register('thorchain:rune', Rune.createInstance); + sdk.register('thorchain:trune', Trune.createInstance); +}; diff --git a/modules/sdk-coin-rune/src/rune.ts b/modules/sdk-coin-rune/src/rune.ts new file mode 100644 index 0000000000..137b9f01b6 --- /dev/null +++ b/modules/sdk-coin-rune/src/rune.ts @@ -0,0 +1,109 @@ +import { CosmosCoin, CosmosKeyPair, GasAmountDetails } from '@bitgo/abstract-cosmos'; +import { BaseCoin, BitGoBase, Environments, TransactionType, VerifyTransactionOptions } from '@bitgo/sdk-core'; +import { BaseCoin as StaticsBaseCoin, BaseUnit, coins } from '@bitgo/statics'; +import { KeyPair, TransactionBuilderFactory } from './lib'; +import { GAS_AMOUNT, GAS_LIMIT } from './lib/constants'; +import { RuneUtils } from './lib/utils'; +import { BigNumber } from 'bignumber.js'; +const bech32 = require('bech32-buffer'); +import * as _ from 'lodash'; + +export class Rune extends CosmosCoin { + protected readonly _utils: RuneUtils; + protected readonly _staticsCoin: Readonly; + protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly) { + super(bitgo, staticsCoin); + if (!staticsCoin) { + throw new Error('missing required constructor parameter staticsCoin'); + } + this._staticsCoin = staticsCoin; + this._utils = new RuneUtils(); + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Rune(bitgo, staticsCoin); + } + + /** @inheritDoc **/ + getBuilder(): TransactionBuilderFactory { + return new TransactionBuilderFactory(coins.get(this.getChain())); + } + + /** + * Factor between the coin's base unit and its smallest subdivison + */ + public getBaseFactor(): number { + return 1e8; + } + + isValidAddress(address: string): boolean { + return this._utils.isValidAddress(address) || this._utils.isValidValidatorAddress(address); + } + + /** @inheritDoc **/ + protected getPublicNodeUrl(): string { + return Environments[this.bitgo.getEnv()].coreumNodeUrl; + } + + /** @inheritDoc **/ + getDenomination(): string { + return BaseUnit.RUNE; + } + + /** @inheritDoc **/ + getGasAmountDetails(): GasAmountDetails { + return { + gasAmount: GAS_AMOUNT, + gasLimit: GAS_LIMIT, + }; + } + + /** @inheritDoc **/ + getKeyPair(publicKey: string): CosmosKeyPair { + return new KeyPair({ pub: publicKey }); + } + + /** @inheritDoc **/ + getAddressFromPublicKey(publicKey: string): string { + return new KeyPair({ pub: publicKey }).getAddress(); + } + + async verifyTransaction(params: VerifyTransactionOptions): Promise { + let totalAmount = new BigNumber(0); + const { txPrebuild, txParams } = params; + const rawTx = txPrebuild.txHex; + if (!rawTx) { + throw new Error('missing required tx prebuild property txHex'); + } + const transaction = await this.getBuilder().from(rawTx).build(); + const explainedTx = transaction.explainTransaction(); + + if (txParams.recipients && txParams.recipients.length > 0) { + const filteredRecipients = txParams.recipients?.map((recipient) => _.pick(recipient, ['address', 'amount'])); + let filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount'])); + + filteredOutputs = filteredOutputs.map((output) => { + const prefix = this._utils.getNetworkPrefix(); + const convertedAddress = bech32.encode(prefix, output.address); + return { + ...output, + address: convertedAddress, + }; + }); + + if (!_.isEqual(filteredOutputs, filteredRecipients)) { + throw new Error('Tx outputs does not match with expected txParams recipients'); + } + // WithdrawDelegatorRewards and ContractCall transaction don't have amount + if (transaction.type !== TransactionType.StakingWithdraw && transaction.type !== TransactionType.ContractCall) { + for (const recipients of txParams.recipients) { + totalAmount = totalAmount.plus(recipients.amount); + } + if (!totalAmount.isEqualTo(explainedTx.outputAmount)) { + throw new Error('Tx total amount does not match with expected total amount field'); + } + } + } + return true; + } +} diff --git a/modules/sdk-coin-rune/src/trune.ts b/modules/sdk-coin-rune/src/trune.ts new file mode 100644 index 0000000000..69e4e8fb4e --- /dev/null +++ b/modules/sdk-coin-rune/src/trune.ts @@ -0,0 +1,39 @@ +/** + * Testnet Rune + * + * @format + */ +import { AddressFormat, BaseCoin, BitGoBase } from '@bitgo/sdk-core'; +import { BaseUnit, NetworkType, BaseCoin as StaticsBaseCoin } from '@bitgo/statics'; +import { Rune } from './rune'; +import { KeyPair } from './lib'; +import { RuneUtils } from './lib/utils'; + +export class Trune extends Rune { + protected readonly _utils: RuneUtils; + protected readonly _staticsCoin: Readonly; + protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly) { + super(bitgo, staticsCoin); + + if (!staticsCoin) { + throw new Error('missing required constructor parameter staticsCoin'); + } + + this._staticsCoin = staticsCoin; + this._utils = new RuneUtils(NetworkType.TESTNET); + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Trune(bitgo, staticsCoin); + } + + /** @inheritDoc **/ + getDenomination(): string { + return BaseUnit.RUNE; + } + + /** @inheritDoc **/ + getAddressFromPublicKey(publicKey: string): string { + return new KeyPair({ pub: publicKey }).getAddress(AddressFormat.testnet); + } +} diff --git a/modules/sdk-coin-rune/test/resources/rune.ts b/modules/sdk-coin-rune/test/resources/rune.ts new file mode 100644 index 0000000000..73f8e20dab --- /dev/null +++ b/modules/sdk-coin-rune/test/resources/rune.ts @@ -0,0 +1,49 @@ +// Get the test data by running the scripts for the particular coin from coin-sandbox repo. + +export const TEST_ACCOUNT = { + pubAddress: 'thor1xrh89ced02ea6928kcwectgtkk7k4954dags7v', + testnetPubAddress: 'sthor1xrh89ced02ea6928kcwectgtkk7k4954ey5xgj', + compressedPublicKey: '0371b155f21bf4426d9adeda30c858f523da3d20ca9c2a1c27b83baeac3ed6f184', + compressedPublicKeyTwo: '02e04ea328d98de663224a126a1c64740e341976f0360d45511c954e61fba30466', + uncompressedPublicKey: + '0471b155f21bf4426d9adeda30c858f523da3d20ca9c2a1c27b83baeac3ed6f1843a0b64237e638ba7129d2dbe86a5c5cbd1e85f6e5ba6606b6c1f98e1b5d23b87', + privateKey: 'c9cfbf9d86f86d55ce358b15402bd4f9e274b5249ff9be1b852553a36681a798', + extendedPrv: + 'xprv9s21ZrQH143K4CFciZ9dkVK2gyAj8ag8PUPm7vVZhbUhA9mQPK9f4BhzqkDsKojLhJWQndiRKPbwFaEy6dGv6eDBZkMimpiDX8ZvNN2kCVH', + extendedPub: + 'xpub661MyMwAqRbcGgL5page7dFmF11DY3PykhKMvJuBFw1g2x6YvrTubz2Uh2Xa4qmBvtxVPxy2YCpRAQQCQQYz5MctWsCdWvDwybRJvaGubjL', +}; + +export const mainnetAddress = { + address1: 'thor1fwk9jl6kfflurj9p0wt098kxl02gle4yhnm687', + address2: 'thor17hwqt302e5f2xm4h95ma8wuggqkvfzgvsnh5z9', + address3: 'thor17hwqt302e5f2xm4h95ma8wuggqkvfzgvsnh5', + address4: 'tho166n4w5039meulfa3p6ydg60ve6ueac7tlt0jws', + validatorAddress1: 'thor1v882x92avxcmkaucm2h6cp6j2qc4lhll0vfsex', + validatorAddress2: 'thor1nl0hc33pllze4athmvyaj9ky35le30vvhx3a25', + validatorAddress3: 'tho140wms8h9pm5dmj832lwnhw45qvt25v0ps888sf', + validatorAddress4: 'thor1hjpct8pd9d48vyqltaqunltwx9twm57l3qmay', + noMemoIdAddress: 'thor1pxfnmdjc0esuswlx8uxguqhgywchhuv4k9ntna', + validMemoIdAddress: 'thor1pxfnmdjc0esuswlx8uxguqhgywchhuv4k9ntna?memoId=2', + invalidMemoIdAddress: 'thor1pxfnmdjc0esuswlx8uxguqhgywchhuv4k9ntna?memoId=xyz', + multipleMemoIdAddress: 'thor1pxfnmdjc0esuswlx8uxguqhgywchhuv4k9ntna?memoId=3&memoId=12', +}; + +export const blockHash = { + hash1: '10D155BC67CD47A75BA53D5EF92A69721D56D81DEB350D3AE5F3CC7876B14F1B', + hash2: '6F17E7913CF87E6D167767D4E4167FBFB643BFFCB2571AEA6FA22566E4FBD1B5', +}; + +export const txIds = { + hash1: '7CDB56BA820B5A93014A0382014205F3BE18BF4916FE16963B35A4E9B541FA71', + hash2: 'F2A1A5F434D389BACE737A1A57C1797C35A6DF7450B550955F03380D07BF136A', + hash3: '2FBB379F11573583155E6F61301F7B00050417411732BF46F6CF354520077F25', +}; + +export const mainnetCoinAmounts = { + amount1: { amount: '100000', denom: 'rune' }, + amount2: { amount: '1000000', denom: 'rune' }, + amount3: { amount: '10000000', denom: 'rune' }, + amount4: { amount: '-1', denom: 'rune' }, + amount5: { amount: '1000000000', denom: 'arune' }, +}; diff --git a/modules/sdk-coin-rune/test/resources/trune.ts b/modules/sdk-coin-rune/test/resources/trune.ts new file mode 100644 index 0000000000..3a296ec053 --- /dev/null +++ b/modules/sdk-coin-rune/test/resources/trune.ts @@ -0,0 +1,95 @@ +// Get the test data by running the scripts for the particular coin from coin-sandbox repo. +export const TEST_TX_WITH_MEMO = { + hash: 'B0C1C424ABA63C7401691F7AC777D080A1C4E59594CCBC74DC4B213D747AA1F1', + signature: 'E4PZxdeEGQJ8In+cjPiEd979mXuQlDesucLoivVt0wljx9/0bXNeL5+2ecRironf0Fo3pa1vsBpp7wM0UNWM7A==', + pubKey: 'AxLtvJO7WCAT1uNYriwGyxu678ck7+0ag5Pd589dtydC', + privateKey: 'uz2P7K8xhtoHM1QAbXXWBx83uvyA/ulQTx4tM2qGXAE=', + signedTxBase64: + 'ClMKTgoOL3R5cGVzLk1zZ1NlbmQSPAoUX+ummTeIOBAZHQ0YsPb1CZ040lQSFID5ph0o2N3lj2qmLDH59qRQag14Gg4KBHJ1bmUSBjEwMDAwMBIBMRJpClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDEu28k7tYIBPW41iuLAbLG7rvxyTv7RqDk93nz123J0ISBAoCCAEYAxIVCg4KBHJ1bmUSBjEwMDAwMBCA4esXGkATg9nF14QZAnwif5yM+IR33v2Ze5CUN6y5wuiK9W3TCWPH3/Rtc14vn7Z5xGKuid/QWjelrW+wGmnvAzRQ1Yzs', + sender: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls', + recipient: 'sthor1sru6v8fgmrw7trm25ckrr70k53gx5rtc4xhfgf', + chainId: 'thorchain-stagenet-2', + accountNumber: 15, + sequence: 3, + memo: '1', + sendAmount: '100000', + feeAmount: '100000', + sendMessage: { + typeUrl: '/types.MsgSend', + value: { + amount: [ + { + denom: 'rune', + amount: '100000', + }, + ], + fromAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls', + toAddress: 'sthor1sru6v8fgmrw7trm25ckrr70k53gx5rtc4xhfgf', + }, + }, + gasBudget: { + amount: [{ denom: 'rune', amount: '100000' }], + gasLimit: 50000000, + }, +}; + +export const TEST_SEND_TX = { + hash: 'FA4635875A1A0E9175126AA6FF5D50B943F74C23B9A1C952808F1274ABC690C8', + signature: 'aFAUTspGfdniC1x2Uia9VByLzSjtzzTSZKVZ7s45Otcp9cfx+kMxmjfd0VPIATKjoAOs55koaUPO3USdzVVkaQ==', + pubKey: 'AxLtvJO7WCAT1uNYriwGyxu678ck7+0ag5Pd589dtydC', + privateKey: 'uz2P7K8xhtoHM1QAbXXWBx83uvyA/ulQTx4tM2qGXAE=', + signedTxBase64: + 'ClAKTgoOL3R5cGVzLk1zZ1NlbmQSPAoUX+ummTeIOBAZHQ0YsPb1CZ040lQSFID5ph0o2N3lj2qmLDH59qRQag14Gg4KBHJ1bmUSBjEwMDAwMBJpClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDEu28k7tYIBPW41iuLAbLG7rvxyTv7RqDk93nz123J0ISBAoCCAEYBBIVCg4KBHJ1bmUSBjEwMDAwMBCA4esXGkBoUBROykZ92eILXHZSJr1UHIvNKO3PNNJkpVnuzjk61yn1x/H6QzGaN93RU8gBMqOgA6znmShpQ87dRJ3NVWRp', + sender: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls', + recipient: 'sthor1sru6v8fgmrw7trm25ckrr70k53gx5rtc4xhfgf', + chainId: 'thorchain-stagenet-2', + accountNumber: 15, + sequence: 4, + sendAmount: '100000', + feeAmount: '100000', + sendMessage: { + typeUrl: '/types.MsgSend', + value: { + amount: [ + { + denom: 'rune', + amount: '100000', + }, + ], + fromAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls', + toAddress: 'sthor1sru6v8fgmrw7trm25ckrr70k53gx5rtc4xhfgf', + }, + }, + gasBudget: { + amount: [ + { + denom: 'rune', + amount: '100000', + }, + ], + gasLimit: 50000000, + }, +}; + +export const testnetAddress = { + address1: 'sthor19phfqh3ce3nnjhh0cssn433nydq9shx76s8qgg', + address2: 'sthor1cghgr0dneyymxx6fjq3e72q83z0qz7c3sjhtmc', + address3: 'sthor1cghgr0dneyymxx6fjq3e72q83z0qz7c3sjhtm', + address4: 'stho1cghgr0dneyymxx6fjq3e72q83z0qz7c3sjhtmc', + validatorAddress1: 'sthor1skucxdq0fkwpx4hjkzn4g303hlzcf30nqduln0', + validatorAddress2: 'sthor1z6z5v9xgzwxd9gytdkpve0g63mcfffjdzkpwue', + validatorAddress3: 'sthor19k46y3nkra9q9a48wjgwac65ms385pcgpueue', + validatorAddress4: 'stho1x9ths2nevz0e002hq93jfdpdt7rtmxwdq07fp5', + noMemoIdAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls', + validMemoIdAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls?memoId=2', + invalidMemoIdAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls?memoId=xyz', + multipleMemoIdAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls?memoId=3&memoId=12', +}; + +export const testnetCoinAmounts = { + amount1: { amount: '100000', denom: 'rune' }, + amount2: { amount: '1000000', denom: 'rune' }, + amount3: { amount: '10000000', denom: 'rune' }, + amount4: { amount: '-1', denom: 'rune' }, + amount5: { amount: '1000000000', denom: 'arune' }, +}; diff --git a/modules/sdk-coin-rune/test/unit/keyPair.ts b/modules/sdk-coin-rune/test/unit/keyPair.ts new file mode 100644 index 0000000000..162b54e8b2 --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/keyPair.ts @@ -0,0 +1,119 @@ +import { AddressFormat } from '@bitgo/sdk-core'; +import assert from 'assert'; +import should from 'should'; +import { KeyPair } from '../../src'; +import { TEST_ACCOUNT } from '../resources/rune'; + +describe('Rune Key Pair', () => { + describe('should create a valid KeyPair', () => { + it('from an empty value', () => { + const keyPairObj = new KeyPair(); + const keys = keyPairObj.getKeys(); + should.exists(keys.prv); + should.exists(keys.pub); + should.equal(keys.prv?.length, 64); + should.equal(keys.pub.length, 66); + + const extendedKeys = keyPairObj.getExtendedKeys(); + should.exists(extendedKeys.xprv); + should.exists(extendedKeys.xpub); + }); + + it('from a private key', () => { + const privateKey = TEST_ACCOUNT.privateKey; + const keyPairObj = new KeyPair({ prv: privateKey }); + const keys = keyPairObj.getKeys(); + should.exists(keys.prv); + should.exists(keys.pub); + should.equal(keys.prv, TEST_ACCOUNT.privateKey); + should.equal(keys.pub, TEST_ACCOUNT.compressedPublicKey); + should.equal(keyPairObj.getAddress(), TEST_ACCOUNT.pubAddress); + should.equal(keyPairObj.getAddress(AddressFormat.testnet), TEST_ACCOUNT.testnetPubAddress); + + assert.throws(() => keyPairObj.getExtendedKeys()); + }); + + it('from a compressed public key', () => { + const publicKey = TEST_ACCOUNT.compressedPublicKey; + const keyPairObj = new KeyPair({ pub: publicKey }); + const keys = keyPairObj.getKeys(); + should.not.exist(keys.prv); + should.exists(keys.pub); + should.equal(keys.pub, TEST_ACCOUNT.compressedPublicKey); + + assert.throws(() => keyPairObj.getExtendedKeys()); + }); + + it('from an uncompressed public key', () => { + // Input is uncompressed, but we output the compressed key to keep + // parity with coreum network expectations. + const publicKey = TEST_ACCOUNT.uncompressedPublicKey; + const keyPairObj = new KeyPair({ pub: publicKey }); + const keys = keyPairObj.getKeys(); + should.not.exist(keys.prv); + should.exists(keys.pub); + should.notEqual(keys.pub, publicKey); + should.equal(keys.pub, TEST_ACCOUNT.compressedPublicKey); + + assert.throws(() => keyPairObj.getExtendedKeys()); + }); + }); + + describe('should fail to create a KeyPair', () => { + it('from an invalid privateKey', () => { + assert.throws( + () => new KeyPair({ prv: '' }), + (e: any) => e.message === 'Unsupported private key' + ); + }); + + it('from an invalid publicKey', () => { + assert.throws( + () => new KeyPair({ pub: '' }), + (e: any) => e.message.startsWith('Unsupported public key') + ); + }); + + it('from an undefined seed', () => { + const undefinedBuffer = undefined as unknown as Buffer; + assert.throws( + () => new KeyPair({ seed: undefinedBuffer }), + (e: any) => e.message.startsWith('Invalid key pair options') + ); + }); + + it('from an undefined private key', () => { + const undefinedStr: string = undefined as unknown as string; + assert.throws( + () => new KeyPair({ prv: undefinedStr }), + (e: any) => e.message.startsWith('Invalid key pair options') + ); + }); + + it('from an undefined public key', () => { + const undefinedStr: string = undefined as unknown as string; + assert.throws( + () => new KeyPair({ pub: undefinedStr }), + (e: any) => e.message.startsWith('Invalid key pair options') + ); + }); + }); + + describe('should get unique address', () => { + it('from a private key', () => { + const keyPair = new KeyPair({ prv: TEST_ACCOUNT.privateKey }); + should.equal(keyPair.getAddress(), TEST_ACCOUNT.pubAddress); + }); + + it('from a compressed public key', () => { + const keyPair = new KeyPair({ pub: TEST_ACCOUNT.compressedPublicKey }); + should.equal(keyPair.getAddress(), TEST_ACCOUNT.pubAddress); + }); + + it('should be different for different public keys', () => { + const keyPairOne = new KeyPair({ pub: TEST_ACCOUNT.compressedPublicKey }); + const keyPairTwo = new KeyPair({ pub: TEST_ACCOUNT.compressedPublicKeyTwo }); + should.notEqual(keyPairOne.getAddress(), keyPairTwo.getAddress()); + }); + }); +}); diff --git a/modules/sdk-coin-rune/test/unit/rune.ts b/modules/sdk-coin-rune/test/unit/rune.ts new file mode 100644 index 0000000000..6c40dcb3f4 --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/rune.ts @@ -0,0 +1,268 @@ +import { BitGoAPI } from '@bitgo/sdk-api'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { NetworkType } from '@bitgo/statics'; +import BigNumber from 'bignumber.js'; +import sinon from 'sinon'; +import { Rune, Trune } from '../../src'; +import { RuneUtils } from '../../src/lib/utils'; +import { mainnetAddress } from '../resources/rune'; +import { TEST_SEND_TX, TEST_TX_WITH_MEMO, testnetAddress } from '../resources/trune'; +const bech32 = require('bech32-buffer'); +import should = require('should'); + +describe('Rune', function () { + let bitgo: TestBitGoAPI; + let rune; + let trune; + let mainnetUtils: RuneUtils; + let testnetUtils: RuneUtils; + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' }); + bitgo.safeRegister('thorchain:rune', Rune.createInstance); + bitgo.safeRegister('thorchain:trune', Trune.createInstance); + bitgo.initializeTestVars(); + rune = bitgo.coin('thorchain:rune'); + trune = bitgo.coin('thorchain:trune'); + mainnetUtils = new RuneUtils(NetworkType.MAINNET); + testnetUtils = new RuneUtils(NetworkType.TESTNET); + }); + + it('should return the right info', function () { + rune.getChain().should.equal('thorchain:rune'); + rune.getFamily().should.equal('thor'); + rune.getFullName().should.equal('Rune'); + rune.getBaseFactor().should.equal(1e8); + + trune.getChain().should.equal('thorchain:trune'); + trune.getFamily().should.equal('thor'); + trune.getFullName().should.equal('Testnet Rune'); + trune.getBaseFactor().should.equal(1e8); + }); + + describe('Address Validation', () => { + it('should get address details without memoId', function () { + const mainnetAddressDetails = rune.getAddressDetails(mainnetAddress.noMemoIdAddress); + mainnetAddressDetails.address.should.equal(mainnetAddress.noMemoIdAddress); + should.not.exist(mainnetAddressDetails.memoId); + + const testnetAddressDetails = trune.getAddressDetails(testnetAddress.noMemoIdAddress); + testnetAddressDetails.address.should.equal(testnetAddress.noMemoIdAddress); + should.not.exist(testnetAddressDetails.memoId); + }); + + it('should get address details with memoId', function () { + const mainnetAddressDetails = rune.getAddressDetails(mainnetAddress.validMemoIdAddress); + mainnetAddressDetails.address.should.equal(mainnetAddress.validMemoIdAddress.split('?')[0]); + mainnetAddressDetails.memoId.should.equal('2'); + + const testnetAddressDetails = rune.getAddressDetails(testnetAddress.validMemoIdAddress); + testnetAddressDetails.address.should.equal(testnetAddress.validMemoIdAddress.split('?')[0]); + testnetAddressDetails.memoId.should.equal('2'); + }); + + it('should throw on invalid memo id address', () => { + (() => { + rune.getAddressDetails(mainnetAddress.invalidMemoIdAddress); + }).should.throw(); + (() => { + trune.getAddressDetails(testnetAddress.invalidMemoIdAddress); + }).should.throw(); + }); + + it('should throw on multiple memo id address', () => { + (() => { + rune.getAddressDetails(mainnetAddress.multipleMemoIdAddress); + }).should.throw(); + (() => { + trune.getAddressDetails(testnetAddress.multipleMemoIdAddress); + }).should.throw(); + }); + + it('should validate wallet receive address', async function () { + const mainnetReceiveAddress = { + address: 'thor1fwk9jl6kfflurj9p0wt098kxl02gle4yhnm687?memoId=7', + coinSpecific: { + rootAddress: 'thor1fwk9jl6kfflurj9p0wt098kxl02gle4yhnm687', + memoID: '7', + }, + }; + const testnetReceiveAddress = { + address: 'sthor19phfqh3ce3nnjhh0cssn433nydq9shx76s8qgg?memoId=7', + coinSpecific: { + rootAddress: 'sthor19phfqh3ce3nnjhh0cssn433nydq9shx76s8qgg', + memoID: '7', + }, + }; + + const isValidMainnetReceiveAddress = await rune.isWalletAddress(mainnetReceiveAddress); + const isValidTestnetReceiveAddress = await trune.isWalletAddress(testnetReceiveAddress); + + isValidMainnetReceiveAddress.should.equal(true); + isValidTestnetReceiveAddress.should.equal(true); + }); + + it('should validate account addresses correctly', () => { + should.equal(mainnetUtils.isValidAddress(mainnetAddress.address1), true); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.address2), true); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.address3), false); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.address4), false); + should.equal(mainnetUtils.isValidAddress('dfjk35y'), false); + should.equal(mainnetUtils.isValidAddress(undefined as unknown as string), false); + should.equal(mainnetUtils.isValidAddress(''), false); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.validMemoIdAddress), true); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.invalidMemoIdAddress), false); + should.equal(mainnetUtils.isValidAddress(mainnetAddress.multipleMemoIdAddress), false); + + should.equal(testnetUtils.isValidAddress(testnetAddress.address1), true); + should.equal(testnetUtils.isValidAddress(testnetAddress.address2), true); + should.equal(testnetUtils.isValidAddress(testnetAddress.address3), false); + should.equal(testnetUtils.isValidAddress(testnetAddress.address4), false); + should.equal(testnetUtils.isValidAddress('dfjk35y'), false); + should.equal(testnetUtils.isValidAddress(undefined as unknown as string), false); + should.equal(testnetUtils.isValidAddress(''), false); + should.equal(testnetUtils.isValidAddress(testnetAddress.validMemoIdAddress), true); + should.equal(testnetUtils.isValidAddress(testnetAddress.invalidMemoIdAddress), false); + should.equal(testnetUtils.isValidAddress(testnetAddress.multipleMemoIdAddress), false); + }); + + it('should validate validator addresses correctly', () => { + should.equal(mainnetUtils.isValidValidatorAddress(mainnetAddress.validatorAddress1), true); + should.equal(mainnetUtils.isValidValidatorAddress(mainnetAddress.validatorAddress2), true); + should.equal(mainnetUtils.isValidValidatorAddress(mainnetAddress.validatorAddress3), false); + should.equal(mainnetUtils.isValidValidatorAddress(mainnetAddress.validatorAddress4), false); + should.equal(mainnetUtils.isValidValidatorAddress('dfjk35y'), false); + should.equal(mainnetUtils.isValidValidatorAddress(undefined as unknown as string), false); + should.equal(mainnetUtils.isValidValidatorAddress(''), false); + + should.equal(testnetUtils.isValidValidatorAddress(testnetAddress.validatorAddress1), true); + should.equal(testnetUtils.isValidValidatorAddress(testnetAddress.validatorAddress2), true); + should.equal(testnetUtils.isValidValidatorAddress(testnetAddress.validatorAddress3), false); + should.equal(testnetUtils.isValidValidatorAddress(testnetAddress.validatorAddress4), false); + should.equal(testnetUtils.isValidValidatorAddress('dfjk35y'), false); + should.equal(testnetUtils.isValidValidatorAddress(undefined as unknown as string), false); + should.equal(testnetUtils.isValidValidatorAddress(''), false); + }); + }); + + describe('Verify transaction: ', () => { + it('should succeed to verify transaction', async function () { + const txPrebuild = { + txHex: TEST_SEND_TX.signedTxBase64, + txInfo: {}, + }; + const txParams = { + recipients: [ + { + address: TEST_SEND_TX.recipient, + amount: TEST_SEND_TX.sendAmount, + }, + ], + }; + const verification = {}; + const isTransactionVerified = await trune.verifyTransaction({ txParams, txPrebuild, verification }); + isTransactionVerified.should.equal(true); + }); + + it('should fail to verify transaction with invalid param', async function () { + const txPrebuild = {}; + const txParams = { recipients: undefined }; + await trune + .verifyTransaction({ + txParams, + txPrebuild, + }) + .should.rejectedWith('missing required tx prebuild property txHex'); + }); + }); + + describe('Explain Transaction: ', () => { + it('should explain a transfer transaction', async function () { + const explainedTransaction = await trune.explainTransaction({ + txHex: TEST_SEND_TX.signedTxBase64, + }); + explainedTransaction.should.deepEqual({ + displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'], + id: TEST_SEND_TX.hash, + outputs: [ + { + address: bech32.decode(TEST_SEND_TX.recipient).data, + amount: TEST_SEND_TX.sendAmount, + }, + ], + outputAmount: TEST_SEND_TX.sendAmount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: TEST_SEND_TX.gasBudget.amount[0].amount }, + type: 0, + }); + }); + + it('should explain a transfer transaction with memo', async function () { + const explainedTransaction = await trune.explainTransaction({ + txHex: TEST_TX_WITH_MEMO.signedTxBase64, + }); + explainedTransaction.should.deepEqual({ + displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'], + id: TEST_TX_WITH_MEMO.hash, + outputs: [ + { + address: bech32.decode(TEST_TX_WITH_MEMO.recipient).data, + amount: TEST_TX_WITH_MEMO.sendAmount, + memo: TEST_TX_WITH_MEMO.memo, + }, + ], + outputAmount: TEST_TX_WITH_MEMO.sendAmount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: TEST_TX_WITH_MEMO.gasBudget.amount[0].amount }, + type: 0, + }); + }); + + it('should fail to explain transaction with missing params', async function () { + try { + await trune.explainTransaction({}); + } catch (error) { + should.equal(error.message, 'missing required txHex parameter'); + } + }); + + it('should fail to explain transaction with invalid params', async function () { + try { + await trune.explainTransaction({ txHex: 'randomString' }); + } catch (error) { + should.equal(error.message.startsWith('Invalid transaction:'), true); + } + }); + }); + + describe('Parse Transactions: ', () => { + it('should parse a transfer transaction', async function () { + const transferInputsResponse = { + address: bech32.decode(TEST_SEND_TX.recipient).data, + amount: new BigNumber(TEST_SEND_TX.sendAmount).plus(TEST_SEND_TX.gasBudget.amount[0].amount).toFixed(), + }; + + const transferOutputsResponse = { + address: bech32.decode(TEST_SEND_TX.recipient).data, + amount: TEST_SEND_TX.sendAmount, + }; + + const parsedTransaction = await trune.parseTransaction({ txHex: TEST_SEND_TX.signedTxBase64 }); + + parsedTransaction.should.deepEqual({ + inputs: [transferInputsResponse], + outputs: [transferOutputsResponse], + }); + }); + + it('should fail to parse a transfer transaction when explainTransaction response is undefined', async function () { + const stub = sinon.stub(Rune.prototype, 'explainTransaction'); + stub.resolves(undefined); + await trune + .parseTransaction({ txHex: TEST_SEND_TX.signedTxBase64 }) + .should.be.rejectedWith('Invalid transaction'); + stub.restore(); + }); + }); +}); diff --git a/modules/sdk-coin-rune/test/unit/transaction.ts b/modules/sdk-coin-rune/test/unit/transaction.ts new file mode 100644 index 0000000000..ad0ac9af39 --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/transaction.ts @@ -0,0 +1,138 @@ +import { toHex, TransactionType } from '@bitgo/sdk-core'; +import { coins } from '@bitgo/statics'; +import { fromBase64 } from '@cosmjs/encoding'; +import should from 'should'; +const bech32 = require('bech32-buffer'); + +import { CosmosTransaction, SendMessage } from '@bitgo/abstract-cosmos'; +import { RuneUtils } from '../../src/lib/utils'; +import * as testData from '../resources/trune'; + +describe('Rune Transaction', () => { + let tx: CosmosTransaction; + const config = coins.get('thorchain:trune'); + const utils = new RuneUtils(config.network.type); + + beforeEach(() => { + tx = new CosmosTransaction(config, utils); + }); + + describe('Empty transaction', () => { + it('should throw empty transaction', function () { + should.throws(() => tx.toBroadcastFormat(), 'Empty transaction'); + }); + }); + + describe('From raw transaction', () => { + it('should build a transfer from raw signed base64', function () { + tx.enrichTransactionDetailsFromRawTransaction(testData.TEST_SEND_TX.signedTxBase64); + const json = tx.toJson(); + should.equal(json.sequence, testData.TEST_SEND_TX.sequence); + should.deepEqual(json.gasBudget, testData.TEST_SEND_TX.gasBudget); + should.equal(json.publicKey, toHex(fromBase64(testData.TEST_SEND_TX.pubKey))); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).toAddress, + bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data + ); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).amount[0].denom, + testData.TEST_SEND_TX.sendMessage.value.amount[0].denom + ); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).amount[0].amount, + testData.TEST_SEND_TX.sendMessage.value.amount[0].amount + ); + should.equal(Buffer.from(json.signature as any).toString('base64'), testData.TEST_SEND_TX.signature); + should.equal(tx.type, TransactionType.Send); + tx.loadInputsAndOutputs(); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sender).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: 'thorchain:trune', + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: 'thorchain:trune', + }, + ]); + }); + + it('should build a transfer from raw signed hex', function () { + tx.enrichTransactionDetailsFromRawTransaction(toHex(fromBase64(testData.TEST_SEND_TX.signedTxBase64))); + const json = tx.toJson(); + should.equal(json.sequence, testData.TEST_SEND_TX.sequence); + should.deepEqual(json.gasBudget, testData.TEST_SEND_TX.gasBudget); + should.equal(json.publicKey, toHex(fromBase64(testData.TEST_SEND_TX.pubKey))); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).toAddress, + bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data + ); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).amount[0].denom, + testData.TEST_SEND_TX.sendMessage.value.amount[0].denom + ); + should.deepEqual( + (json.sendMessages[0].value as SendMessage).amount[0].amount, + testData.TEST_SEND_TX.sendMessage.value.amount[0].amount + ); + should.equal(Buffer.from(json.signature as any).toString('base64'), testData.TEST_SEND_TX.signature); + should.equal(tx.type, TransactionType.Send); + tx.loadInputsAndOutputs(); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sender).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: 'thorchain:trune', + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: 'thorchain:trune', + }, + ]); + }); + + it('should fail to build a transfer from incorrect raw hex', function () { + should.throws( + () => tx.enrichTransactionDetailsFromRawTransaction('random' + testData.TEST_SEND_TX.signedTxBase64), + 'incorrect raw data' + ); + }); + + it('should fail to explain transaction with invalid raw hex', function () { + should.throws(() => tx.enrichTransactionDetailsFromRawTransaction('randomString'), 'Invalid transaction'); + }); + }); + + describe('Explain transaction', () => { + it('should explain a transfer pay transaction', function () { + tx.enrichTransactionDetailsFromRawTransaction(testData.TEST_SEND_TX.signedTxBase64); + const explainedTransaction = tx.explainTransaction(); + explainedTransaction.should.deepEqual({ + displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'], + id: testData.TEST_SEND_TX.hash, + outputs: [ + { + address: bech32.decode(testData.TEST_SEND_TX.recipient).data, + amount: testData.TEST_SEND_TX.sendAmount, + }, + ], + outputAmount: testData.TEST_SEND_TX.sendAmount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: testData.TEST_SEND_TX.feeAmount }, + type: 0, + }); + }); + + it('should fail to explain transaction with invalid raw base64 string', function () { + should.throws(() => tx.enrichTransactionDetailsFromRawTransaction('randomString'), 'Invalid transaction'); + }); + }); +}); diff --git a/modules/sdk-coin-rune/test/unit/transactionBuilder/transactionBuilder.ts b/modules/sdk-coin-rune/test/unit/transactionBuilder/transactionBuilder.ts new file mode 100644 index 0000000000..64485a3ef1 --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/transactionBuilder/transactionBuilder.ts @@ -0,0 +1,68 @@ +import { TransactionType } from '@bitgo/sdk-core'; +import should from 'should'; + +import { BitGoAPI } from '@bitgo/sdk-api'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { Rune, Trune } from '../../../src'; +import * as testData from '../../resources/trune'; + +describe('Rune Transaction Builder', async () => { + let bitgo: TestBitGoAPI; + let basecoin; + let factory; + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' }); + bitgo.safeRegister('thorchain:rune', Rune.createInstance); + bitgo.safeRegister('thorchain:trune', Trune.createInstance); + bitgo.initializeTestVars(); + basecoin = bitgo.coin('thorchain:trune'); + factory = basecoin.getBuilder(); + }); + + const testTxData = testData.TEST_SEND_TX; + let data; + + beforeEach(() => { + data = [ + { + type: TransactionType.Send, + testTx: testData.TEST_SEND_TX, + builder: factory.getTransferBuilder(), + }, + ]; + }); + + it('should build a signed tx from signed tx data', async function () { + const txBuilder = factory.from(testTxData.signedTxBase64); + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.Send); + // Should recreate the same raw tx data when re-build and turned to broadcast format + const rawTx = tx.toBroadcastFormat(); + should.equal(rawTx, testTxData.signedTxBase64); + }); + + describe('gasBudget tests', async () => { + it('should succeed for valid gasBudget', function () { + for (const { builder } of data) { + should.doesNotThrow(() => builder.gasBudget(testTxData.gasBudget)); + } + }); + + it('should throw for invalid gasBudget', function () { + const invalidGasBudget = 0; + for (const { builder } of data) { + should(() => builder.gasBudget({ gasLimit: invalidGasBudget })).throw('Invalid gas limit ' + invalidGasBudget); + } + }); + }); + + it('validateAddress', function () { + const invalidAddress = { address: 'randomString' }; + for (const { builder } of data) { + should.doesNotThrow(() => builder.validateAddress({ address: testTxData.sender })); + should(() => builder.validateAddress(invalidAddress)).throwError( + 'transactionBuilder: address isValidAddress check failed: ' + invalidAddress.address + ); + } + }); +}); diff --git a/modules/sdk-coin-rune/test/unit/transactionBuilder/transferBuilder.ts b/modules/sdk-coin-rune/test/unit/transactionBuilder/transferBuilder.ts new file mode 100644 index 0000000000..dffe1634e6 --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/transactionBuilder/transferBuilder.ts @@ -0,0 +1,186 @@ +import { BitGoAPI } from '@bitgo/sdk-api'; +import { TransactionType } from '@bitgo/sdk-core'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { fromBase64, toHex } from '@cosmjs/encoding'; +import should from 'should'; +import { Rune, Trune } from '../../../src'; +import * as testData from '../../resources/trune'; +const bech32 = require('bech32-buffer'); + +describe('Rune Transfer Builder', () => { + let bitgo: TestBitGoAPI; + let basecoin; + let factory; + let testTx; + let testTxWithMemo; + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' }); + bitgo.safeRegister('thorchain:rune', Rune.createInstance); + bitgo.safeRegister('thorchain:trune', Trune.createInstance); + bitgo.initializeTestVars(); + basecoin = bitgo.coin('thorchain:trune'); + factory = basecoin.getBuilder(); + testTx = testData.TEST_SEND_TX; + testTxWithMemo = testData.TEST_TX_WITH_MEMO; + }); + + it('should build a Transfer tx with signature', async function () { + const txBuilder = factory.getTransferBuilder(); + txBuilder.sequence(testTx.sequence); + txBuilder.gasBudget(testTx.gasBudget); + txBuilder.messages([testTx.sendMessage.value]); + txBuilder.publicKey(toHex(fromBase64(testTx.pubKey))); + txBuilder.addSignature({ pub: toHex(fromBase64(testTx.pubKey)) }, Buffer.from(testTx.signature, 'base64')); + + const tx = await txBuilder.build(); + const json = await (await txBuilder.build()).toJson(); + should.equal(tx.type, TransactionType.Send); + should.deepEqual(json.gasBudget, testTx.gasBudget); + should.deepEqual(json.sendMessages[0].typeUrl, testTx.sendMessage.typeUrl); + should.deepEqual(json.sendMessages[0].value.amount, testTx.sendMessage.value.amount); + should.deepEqual( + bech32.encode('sthor', json.sendMessages[0].value.fromAddress), + testTx.sendMessage.value.fromAddress + ); + should.deepEqual(bech32.encode('sthor', json.sendMessages[0].value.toAddress), testTx.sendMessage.value.toAddress); + should.deepEqual(json.publicKey, toHex(fromBase64(testTx.pubKey))); + should.deepEqual(json.sequence, testTx.sequence); + const rawTx = tx.toBroadcastFormat(); + should.equal(rawTx, testTx.signedTxBase64); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sender).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + }); + + it('should build a Transfer tx with signature and memo', async function () { + const txBuilder = factory.getTransferBuilder(); + txBuilder.sequence(testTxWithMemo.sequence); + txBuilder.gasBudget(testTxWithMemo.gasBudget); + txBuilder.messages([testTxWithMemo.sendMessage.value]); + txBuilder.publicKey(toHex(fromBase64(testTxWithMemo.pubKey))); + txBuilder.memo(testTxWithMemo.memo); + txBuilder.addSignature( + { pub: toHex(fromBase64(testTxWithMemo.pubKey)) }, + Buffer.from(testTxWithMemo.signature, 'base64') + ); + + const tx = await txBuilder.build(); + const json = await (await txBuilder.build()).toJson(); + should.equal(tx.type, TransactionType.Send); + should.deepEqual(json.gasBudget, testTxWithMemo.gasBudget); + should.deepEqual(json.sendMessages[0].typeUrl, testTx.sendMessage.typeUrl); + should.deepEqual(json.sendMessages[0].value.amount, testTx.sendMessage.value.amount); + should.deepEqual( + bech32.encode('sthor', json.sendMessages[0].value.fromAddress), + testTx.sendMessage.value.fromAddress + ); + should.deepEqual(bech32.encode('sthor', json.sendMessages[0].value.toAddress), testTx.sendMessage.value.toAddress); + should.deepEqual(json.publicKey, toHex(fromBase64(testTxWithMemo.pubKey))); + should.deepEqual(json.sequence, testTxWithMemo.sequence); + should.equal(json.memo, testTxWithMemo.memo); + const rawTx = tx.toBroadcastFormat(); + should.equal(rawTx, testTxWithMemo.signedTxBase64); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testTxWithMemo.sendMessage.value.fromAddress).data, + value: testTxWithMemo.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testTxWithMemo.sendMessage.value.toAddress).data, + value: testTxWithMemo.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + }); + + it('should build a Transfer tx without signature', async function () { + const txBuilder = factory.getTransferBuilder(); + txBuilder.sequence(testTx.sequence); + txBuilder.gasBudget(testTx.gasBudget); + txBuilder.messages([testTx.sendMessage.value]); + txBuilder.publicKey(toHex(fromBase64(testTx.pubKey))); + const tx = await txBuilder.build(); + const json = await (await txBuilder.build()).toJson(); + should.equal(tx.type, TransactionType.Send); + should.deepEqual(json.gasBudget, testTx.gasBudget); + should.deepEqual(json.sendMessages[0].typeUrl, testTx.sendMessage.typeUrl); + should.deepEqual(json.sendMessages[0].value.amount, testTx.sendMessage.value.amount); + should.deepEqual( + bech32.encode('sthor', json.sendMessages[0].value.fromAddress), + testTx.sendMessage.value.fromAddress + ); + should.deepEqual(bech32.encode('sthor', json.sendMessages[0].value.toAddress), testTx.sendMessage.value.toAddress); + + should.deepEqual(json.publicKey, toHex(fromBase64(testTx.pubKey))); + should.deepEqual(json.sequence, testTx.sequence); + tx.toBroadcastFormat(); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sender).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + }); + + it('should sign a Transfer tx', async function () { + const txBuilder = factory.getTransferBuilder(); + txBuilder.sequence(testTx.sequence); + txBuilder.gasBudget(testTx.gasBudget); + txBuilder.messages([testTx.sendMessage.value]); + txBuilder.accountNumber(testTx.accountNumber); + txBuilder.chainId(testTx.chainId); + txBuilder.sign({ key: toHex(fromBase64(testTx.privateKey)) }); + const tx = await txBuilder.build(); + const json = await (await txBuilder.build()).toJson(); + should.equal(tx.type, TransactionType.Send); + should.deepEqual(json.gasBudget, testTx.gasBudget); + should.deepEqual(json.sendMessages[0].typeUrl, testTx.sendMessage.typeUrl); + should.deepEqual(json.sendMessages[0].value.amount, testTx.sendMessage.value.amount); + should.deepEqual( + bech32.encode('sthor', json.sendMessages[0].value.fromAddress), + testTx.sendMessage.value.fromAddress + ); + should.deepEqual(bech32.encode('sthor', json.sendMessages[0].value.toAddress), testTx.sendMessage.value.toAddress); + should.deepEqual(json.publicKey, toHex(fromBase64(testTx.pubKey))); + should.deepEqual(json.sequence, testTx.sequence); + const rawTx = tx.toBroadcastFormat(); + should.equal(tx.signature[0], toHex(fromBase64(testTx.signature))); + should.equal(rawTx, testTx.signedTxBase64); + should.deepEqual(tx.inputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sender).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + should.deepEqual(tx.outputs, [ + { + address: bech32.decode(testData.TEST_SEND_TX.sendMessage.value.toAddress).data, + value: testData.TEST_SEND_TX.sendMessage.value.amount[0].amount, + coin: basecoin.getChain(), + }, + ]); + }); +}); diff --git a/modules/sdk-coin-rune/test/unit/utils.ts b/modules/sdk-coin-rune/test/unit/utils.ts new file mode 100644 index 0000000000..65ea031d8d --- /dev/null +++ b/modules/sdk-coin-rune/test/unit/utils.ts @@ -0,0 +1,60 @@ +import { NetworkType } from '@bitgo/statics'; +import should from 'should'; +import { RuneUtils } from '../../src/lib/utils'; +import { blockHash, mainnetCoinAmounts, txIds } from '../resources/rune'; +import { testnetCoinAmounts } from '../resources/trune'; + +describe('utils', () => { + const mainnetUtils = new RuneUtils(NetworkType.MAINNET); + const testnetUtils = new RuneUtils(NetworkType.TESTNET); + + it('should validate block hash correctly', () => { + should.equal(mainnetUtils.isValidBlockId(blockHash.hash1), true); + should.equal(mainnetUtils.isValidBlockId(blockHash.hash2), true); + // param is coming as undefined so it was causing an issue + should.equal(mainnetUtils.isValidBlockId(undefined as unknown as string), false); + should.equal(mainnetUtils.isValidBlockId(''), false); + }); + + it('should validate invalid block hash correctly', () => { + should.equal(mainnetUtils.isValidBlockId(''), false); + should.equal(mainnetUtils.isValidBlockId('0xade35465gfvdcsxsz24300'), false); + should.equal(mainnetUtils.isValidBlockId(blockHash.hash2 + 'ff'), false); + should.equal(mainnetUtils.isValidBlockId('latest'), false); + }); + + it('should validate transaction id correctly', () => { + should.equal(mainnetUtils.isValidTransactionId(txIds.hash1), true); + should.equal(mainnetUtils.isValidTransactionId(txIds.hash2), true); + should.equal(mainnetUtils.isValidTransactionId(txIds.hash3), true); + }); + + it('should validate invalid transaction id correctly', () => { + should.equal(mainnetUtils.isValidTransactionId(''), false); + should.equal(mainnetUtils.isValidTransactionId(txIds.hash1.slice(3)), false); + should.equal(mainnetUtils.isValidTransactionId(txIds.hash3 + '00'), false); + should.equal(mainnetUtils.isValidTransactionId('dalij43ta0ga2dadda02'), false); + }); + + it('validateAmount', function () { + should.doesNotThrow(() => mainnetUtils.validateAmountData([mainnetCoinAmounts.amount1])); + should.doesNotThrow(() => mainnetUtils.validateAmountData([mainnetCoinAmounts.amount2])); + should.doesNotThrow(() => mainnetUtils.validateAmountData([mainnetCoinAmounts.amount3])); + should(() => mainnetUtils.validateAmountData([mainnetCoinAmounts.amount4])).throwError( + 'transactionBuilder: validateAmount: Invalid amount: ' + mainnetCoinAmounts.amount4.amount + ); + should(() => mainnetUtils.validateAmountData([mainnetCoinAmounts.amount5])).throwError( + 'transactionBuilder: validateAmount: Invalid denom: ' + mainnetCoinAmounts.amount5.denom + ); + + should.doesNotThrow(() => testnetUtils.validateAmountData([testnetCoinAmounts.amount1])); + should.doesNotThrow(() => testnetUtils.validateAmountData([testnetCoinAmounts.amount2])); + should.doesNotThrow(() => testnetUtils.validateAmountData([testnetCoinAmounts.amount3])); + should(() => testnetUtils.validateAmountData([testnetCoinAmounts.amount4])).throwError( + 'transactionBuilder: validateAmount: Invalid amount: ' + testnetCoinAmounts.amount4.amount + ); + should(() => testnetUtils.validateAmountData([testnetCoinAmounts.amount5])).throwError( + 'transactionBuilder: validateAmount: Invalid denom: ' + testnetCoinAmounts.amount5.denom + ); + }); +}); diff --git a/modules/sdk-coin-rune/tsconfig.json b/modules/sdk-coin-rune/tsconfig.json new file mode 100644 index 0000000000..339ace24a2 --- /dev/null +++ b/modules/sdk-coin-rune/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./", + "strictPropertyInitialization": false, + "esModuleInterop": true, + "typeRoots": ["../../types", "./node_modules/@types", "../../node_modules/@types"] + }, + "include": ["src/**/*", "test/**/*"], + "exclude": ["node_modules"], + "references": [ + { + "path": "../sdk-api" + }, + { + "path": "../sdk-core" + }, + { + "path": "../sdk-test" + } + ] +} diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index 6a3b22b56a..3464f1b13e 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -65,6 +65,7 @@ export enum CoinFamily { SUI = 'sui', STX = 'stx', SUSD = 'susd', + THOR = 'thor', TIA = 'tia', // Celestia TON = 'ton', TRX = 'trx', @@ -2348,6 +2349,7 @@ export enum BaseUnit { COREUM = 'ucore', TCOREUM = 'utestcore', // Coreum testnet uses different name for native coin ISLM = 'aISLM', + RUNE = 'rune', } export interface BaseCoinConstructorOptions { diff --git a/modules/statics/src/coins.ts b/modules/statics/src/coins.ts index eb75fbe076..3ef250194c 100644 --- a/modules/statics/src/coins.ts +++ b/modules/statics/src/coins.ts @@ -1006,6 +1006,26 @@ export const coins = CoinMap.fromCoins([ BaseUnit.TCOREUM, COSMOS_SIDECHAIN_FEATURES ), + account( + '9fa0f191-4eed-4030-864a-d14bbd98c8af', + 'thorchain:rune', + 'Rune', + Networks.main.rune, + 8, + UnderlyingAsset.RUNE, + BaseUnit.RUNE, + COSMOS_SIDECHAIN_FEATURES + ), + account( + '7281ab3b-0451-4ef9-b367-8623d9bcfd87', + 'thorchain:trune', + 'Testnet Rune', + Networks.test.rune, + 8, + UnderlyingAsset.RUNE, + BaseUnit.RUNE, + COSMOS_SIDECHAIN_FEATURES + ), account( 'b473d5f0-1590-4edf-bc9f-813aff515a23', 'islm', diff --git a/modules/statics/src/networks.ts b/modules/statics/src/networks.ts index 5ec741456f..c28533d3f3 100644 --- a/modules/statics/src/networks.ts +++ b/modules/statics/src/networks.ts @@ -811,6 +811,18 @@ class CoreumTestnet extends Testnet implements AccountNetwork { explorerUrl = 'https://explorer.testnet-1.coreum.dev/coreum/transactions/'; } +class Rune extends Mainnet implements AccountNetwork { + name = 'Rune'; + family = CoinFamily.THOR; + explorerUrl = 'https://runescan.io/txs'; +} + +class RuneTestNet extends Testnet implements AccountNetwork { + name = 'RuneTestNet'; + family = CoinFamily.THOR; + explorerUrl = 'https://runescan.io/txs?network=stagenet'; +} + class Islm extends Mainnet implements AccountNetwork { name = 'Haqq'; family = CoinFamily.ISLM; @@ -1113,6 +1125,7 @@ export const Networks = { optimism: Object.freeze(new Optimism()), osmo: Object.freeze(new Osmo()), rbtc: Object.freeze(new Rbtc()), + rune: Object.freeze(new Rune()), stellar: Object.freeze(new Stellar()), sei: Object.freeze(new Sei()), sol: Object.freeze(new Sol()), @@ -1172,6 +1185,7 @@ export const Networks = { optimism: Object.freeze(new OptimismTestnet()), osmo: Object.freeze(new OsmoTestnet()), rbtc: Object.freeze(new RbtcTestnet()), + rune: Object.freeze(new RuneTestNet()), stellar: Object.freeze(new StellarTestnet()), sei: Object.freeze(new SeiTestnet()), sol: Object.freeze(new SolTestnet()), diff --git a/modules/statics/test/unit/coins.ts b/modules/statics/test/unit/coins.ts index 84b9426ea4..ac7fda4749 100644 --- a/modules/statics/test/unit/coins.ts +++ b/modules/statics/test/unit/coins.ts @@ -368,9 +368,11 @@ coins.forEach((coin, coinName) => { }); if (!coin.isToken && coin.family !== CoinFamily.FIAT) { - it(`has expected network type`, function () { - coin.network.type.should.eql(coin.name === coin.family ? NetworkType.MAINNET : NetworkType.TESTNET); - }); + if (coin.family !== CoinFamily.THOR) { + it(`has expected network type`, function () { + coin.network.type.should.eql(coin.name === coin.family ? NetworkType.MAINNET : NetworkType.TESTNET); + }); + } } it('expect base unit', function () { diff --git a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts index f285531a53..07bf6ca117 100644 --- a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts +++ b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts @@ -71,6 +71,7 @@ export const expectedColdFeatures = { 'kava', 'near', 'osmo', + 'thorchain:rune', 'sei', 'sol', 'sui', @@ -88,6 +89,7 @@ export const expectedColdFeatures = { 'tkava', 'tnear', 'tosmo', + 'thorchain:trune', 'tsei', 'tsol', 'tsui', diff --git a/tsconfig.packages.json b/tsconfig.packages.json index 0578c6d1bd..add1de9760 100644 --- a/tsconfig.packages.json +++ b/tsconfig.packages.json @@ -104,10 +104,10 @@ "path": "./modules/sdk-coin-eth" }, { - "path": "./modules/sdk-coin-ethlike" + "path": "./modules/sdk-coin-eth2" }, { - "path": "./modules/sdk-coin-eth2" + "path": "./modules/sdk-coin-ethlike" }, { "path": "./modules/sdk-coin-ethw" @@ -145,6 +145,9 @@ { "path": "./modules/sdk-coin-rbtc" }, + { + "path": "./modules/sdk-coin-rune" + }, { "path": "./modules/sdk-coin-sei" }, diff --git a/yarn.lock b/yarn.lock index 95682d6663..65cea92943 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6942,6 +6942,11 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bech32-buffer@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/bech32-buffer/-/bech32-buffer-0.2.1.tgz#8106f2f51bcb2ba1d9fb7718905c3042c5be2fcd" + integrity sha512-fCG1TyZuCN48Sdw97p/IR39fvqpFlWDVpG7qnuU1Uc3+Xtc/0uqAp8U7bMW/bGuVF5CcNVIXwxQsWwUr6un6FQ== + bech32@1.1.4, bech32@^1.1.2, bech32@^1.1.3, bech32@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" @@ -16492,6 +16497,24 @@ protobufjs@^7.1.2, protobufjs@^7.2.5: "@types/node" ">=13.7.0" long "^5.0.0" +protobufjs@^7.4.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" + integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + protocols@^2.0.0, protocols@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" @@ -20018,9 +20041,9 @@ web3-shh@1.3.6: web3-net "1.3.6" web3-types@^1.5.0, web3-types@^1.6.0, web3-types@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.8.0.tgz#d2151fd9e87d711ef5a13079885665b458243e46" - integrity sha512-Z51wFLPGhZM/1uDxrxE8gzju3t2aEdRGn+YmLX463id5UjTuMEmP/9in1GFjqrsPB3m86czs8RnGBUt3ovueMw== + version "1.8.1" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.8.1.tgz#6379aca0f99330eb0f8f6ca80a3de93129b58339" + integrity sha512-isspsvQbBJFUkJYz2Badb7dz/BrLLLpOop/WmnL5InyYMr7kYYc8038NYO7Vkp1M7Bupa/wg+yALvBm7EGbyoQ== web3-utils@1.3.6, web3-utils@4.2.1: version "4.2.1"