From 080e78931d2ec4c464912189a08bfc295de88e39 Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Wed, 5 Jul 2023 16:44:44 -0500 Subject: [PATCH] chore(sdk-coin-bnb): create new bnb module Ticket: EA-709 --- Dockerfile | 13 ++- modules/account-lib/package.json | 1 + modules/account-lib/src/index.ts | 5 + modules/account-lib/tsconfig.json | 3 + modules/bitgo/package.json | 1 + modules/bitgo/src/v2/coinFactory.ts | 9 ++ modules/bitgo/src/v2/coins/index.ts | 2 + modules/bitgo/test/browser/browser.spec.ts | 1 + modules/bitgo/test/v2/unit/keychains.ts | 2 +- modules/bitgo/tsconfig.json | 3 + modules/sdk-coin-bnb/.eslintignore | 5 + modules/sdk-coin-bnb/.gitignore | 3 + modules/sdk-coin-bnb/.mocharc.yml | 8 ++ modules/sdk-coin-bnb/.npmignore | 14 +++ modules/sdk-coin-bnb/.prettierignore | 2 + modules/sdk-coin-bnb/.prettierrc.yml | 3 + modules/sdk-coin-bnb/README.md | 30 +++++ modules/sdk-coin-bnb/package.json | 53 +++++++++ modules/sdk-coin-bnb/src/bnb.ts | 29 +++++ modules/sdk-coin-bnb/src/bnbToken.ts | 39 +++++++ modules/sdk-coin-bnb/src/index.ts | 5 + modules/sdk-coin-bnb/src/lib/index.ts | 6 + modules/sdk-coin-bnb/src/lib/resources.ts | 22 ++++ .../src/lib/transactionBuilder.ts | 30 +++++ .../sdk-coin-bnb/src/lib/transferBuilder.ts | 8 ++ modules/sdk-coin-bnb/src/lib/utils.ts | 21 ++++ modules/sdk-coin-bnb/src/register.ts | 12 ++ modules/sdk-coin-bnb/src/tbnb.ts | 22 ++++ modules/sdk-coin-bnb/test/fixtures/ecdsa.ts | 106 ++++++++++++++++++ modules/sdk-coin-bnb/test/resources/bnb.ts | 12 ++ modules/sdk-coin-bnb/test/unit/bnb.ts | 41 +++++++ modules/sdk-coin-bnb/test/unit/bnbToken.ts | 32 ++++++ modules/sdk-coin-bnb/test/unit/getBuilder.ts | 6 + .../test/unit/transactionBuilder/send.ts | 16 +++ modules/sdk-coin-bnb/test/unit/utils.ts | 29 +++++ modules/sdk-coin-bnb/tsconfig.json | 32 ++++++ modules/sdk-core/src/bitgo/utils/mpcUtils.ts | 7 +- modules/statics/src/account.ts | 51 ++++++++- modules/statics/src/base.ts | 13 +++ modules/statics/src/coins.ts | 86 +++++++++++++- modules/statics/src/networks.ts | 18 +++ modules/statics/src/tokenConfig.ts | 27 +++++ .../unit/fixtures/expectedColdFeatures.ts | 2 + modules/web-demo/package.json | 1 + .../src/components/Coins/coinFactory.ts | 5 + tsconfig.packages.json | 3 + 46 files changed, 829 insertions(+), 10 deletions(-) create mode 100644 modules/sdk-coin-bnb/.eslintignore create mode 100644 modules/sdk-coin-bnb/.gitignore create mode 100644 modules/sdk-coin-bnb/.mocharc.yml create mode 100644 modules/sdk-coin-bnb/.npmignore create mode 100644 modules/sdk-coin-bnb/.prettierignore create mode 100644 modules/sdk-coin-bnb/.prettierrc.yml create mode 100644 modules/sdk-coin-bnb/README.md create mode 100644 modules/sdk-coin-bnb/package.json create mode 100644 modules/sdk-coin-bnb/src/bnb.ts create mode 100644 modules/sdk-coin-bnb/src/bnbToken.ts create mode 100644 modules/sdk-coin-bnb/src/index.ts create mode 100644 modules/sdk-coin-bnb/src/lib/index.ts create mode 100644 modules/sdk-coin-bnb/src/lib/resources.ts create mode 100644 modules/sdk-coin-bnb/src/lib/transactionBuilder.ts create mode 100644 modules/sdk-coin-bnb/src/lib/transferBuilder.ts create mode 100644 modules/sdk-coin-bnb/src/lib/utils.ts create mode 100644 modules/sdk-coin-bnb/src/register.ts create mode 100644 modules/sdk-coin-bnb/src/tbnb.ts create mode 100644 modules/sdk-coin-bnb/test/fixtures/ecdsa.ts create mode 100644 modules/sdk-coin-bnb/test/resources/bnb.ts create mode 100644 modules/sdk-coin-bnb/test/unit/bnb.ts create mode 100644 modules/sdk-coin-bnb/test/unit/bnbToken.ts create mode 100644 modules/sdk-coin-bnb/test/unit/getBuilder.ts create mode 100644 modules/sdk-coin-bnb/test/unit/transactionBuilder/send.ts create mode 100644 modules/sdk-coin-bnb/test/unit/utils.ts create mode 100644 modules/sdk-coin-bnb/tsconfig.json diff --git a/Dockerfile b/Dockerfile index 66cf3e1045..40eafb3f36 100644 --- a/Dockerfile +++ b/Dockerfile @@ -98,6 +98,8 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-hash /var/modules/sdk-coin-hash/ RUN cd /var/modules/sdk-coin-hash && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-hbar /var/modules/sdk-coin-hbar/ RUN cd /var/modules/sdk-coin-hbar && yarn link +COPY --from=builder /tmp/bitgo/modules/sdk-coin-injective /var/modules/sdk-coin-injective/ +RUN cd /var/modules/sdk-coin-injective && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-near /var/modules/sdk-coin-near/ RUN cd /var/modules/sdk-coin-near && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-osmo /var/modules/sdk-coin-osmo/ @@ -126,6 +128,8 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-bch /var/modules/sdk-coin-bch/ RUN cd /var/modules/sdk-coin-bch && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-bcha /var/modules/sdk-coin-bcha/ RUN cd /var/modules/sdk-coin-bcha && yarn link +COPY --from=builder /tmp/bitgo/modules/sdk-coin-bnb /var/modules/sdk-coin-bnb/ +RUN cd /var/modules/sdk-coin-bnb && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-bsv /var/modules/sdk-coin-bsv/ RUN cd /var/modules/sdk-coin-bsv && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-btc /var/modules/sdk-coin-btc/ @@ -142,8 +146,6 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-eos /var/modules/sdk-coin-eos/ RUN cd /var/modules/sdk-coin-eos && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-ethw /var/modules/sdk-coin-ethw/ RUN cd /var/modules/sdk-coin-ethw && yarn link -COPY --from=builder /tmp/bitgo/modules/sdk-coin-injective /var/modules/sdk-coin-injective/ -RUN cd /var/modules/sdk-coin-injective && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-ltc /var/modules/sdk-coin-ltc/ RUN cd /var/modules/sdk-coin-ltc && yarn link COPY --from=builder /tmp/bitgo/modules/sdk-coin-xlm /var/modules/sdk-coin-xlm/ @@ -186,6 +188,7 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/sdk-coin-eth2 && \ yarn link @bitgo/sdk-coin-hash && \ yarn link @bitgo/sdk-coin-hbar && \ + yarn link @bitgo/sdk-coin-injective && \ yarn link @bitgo/sdk-coin-near && \ yarn link @bitgo/sdk-coin-osmo && \ yarn link @bitgo/sdk-coin-polygon && \ @@ -200,6 +203,7 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/sdk-coin-ada && \ yarn link @bitgo/sdk-coin-bch && \ yarn link @bitgo/sdk-coin-bcha && \ + yarn link @bitgo/sdk-coin-bnb && \ yarn link @bitgo/sdk-coin-bsv && \ yarn link @bitgo/sdk-coin-btc && \ yarn link @bitgo/utxo-ord && \ @@ -208,7 +212,6 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/sdk-coin-doge && \ yarn link @bitgo/sdk-coin-eos && \ yarn link @bitgo/sdk-coin-ethw && \ - yarn link @bitgo/sdk-coin-injective && \ yarn link @bitgo/sdk-coin-ltc && \ yarn link @bitgo/sdk-coin-xlm && \ yarn link @bitgo/sdk-coin-xrp && \ @@ -216,9 +219,9 @@ RUN cd /var/bitgo-express && \ #LINK_END #LABEL_START -LABEL created="Thu, 22 Jun 2023 18:10:16 GMT" +LABEL created="Mon, 03 Jul 2023 18:46:35 GMT" LABEL version=9.29.0 -LABEL git_hash=e8bf1cceea1bff0ee05a38b6f8bbe04c4c4b5588 +LABEL git_hash=b33c2ed4c1d1d66c510d468d7969b4402d8361c8 #LABEL_END USER node diff --git a/modules/account-lib/package.json b/modules/account-lib/package.json index af967c756e..b77ae24914 100644 --- a/modules/account-lib/package.json +++ b/modules/account-lib/package.json @@ -32,6 +32,7 @@ "@bitgo/sdk-coin-avaxc": "^2.4.18", "@bitgo/sdk-coin-avaxp": "^3.5.18", "@bitgo/sdk-coin-bld": "^1.1.0", + "@bitgo/sdk-coin-bnb": "^1.0.0", "@bitgo/sdk-coin-bsc": "^3.6.4", "@bitgo/sdk-coin-celo": "^1.3.27", "@bitgo/sdk-coin-cspr": "^1.2.27", diff --git a/modules/account-lib/src/index.ts b/modules/account-lib/src/index.ts index c1352800d3..ef254cf627 100644 --- a/modules/account-lib/src/index.ts +++ b/modules/account-lib/src/index.ts @@ -98,6 +98,9 @@ export { Near }; import * as Bsc from '@bitgo/sdk-coin-bsc'; export { Bsc }; +import * as Bnb from '@bitgo/sdk-coin-bnb'; +export { Bnb }; + import * as Polygon from '@bitgo/sdk-coin-polygon'; export { Polygon }; @@ -122,6 +125,8 @@ const coinBuilderMap = { tavaxc: AvaxC.TransactionBuilder, bsc: Bsc.TransactionBuilder, tbsc: Bsc.TransactionBuilder, + bnb: Bnb.TransactionBuilder, + tbnb: Bnb.TransactionBuilder, avaxp: AvaxP.TransactionBuilderFactory, tavaxp: AvaxP.TransactionBuilderFactory, hbar: Hbar.TransactionBuilderFactory, diff --git a/modules/account-lib/tsconfig.json b/modules/account-lib/tsconfig.json index 3c2df2a97e..5a0fcee25b 100644 --- a/modules/account-lib/tsconfig.json +++ b/modules/account-lib/tsconfig.json @@ -25,6 +25,9 @@ { "path": "../sdk-coin-bsc" }, + { + "path": "../sdk-coin-bnb" + }, { "path": "../sdk-coin-celo" }, diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index 1c5efa9d53..021bd45b70 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -56,6 +56,7 @@ "@bitgo/sdk-coin-bch": "^1.3.27", "@bitgo/sdk-coin-bcha": "^1.5.22", "@bitgo/sdk-coin-bld": "^1.1.0", + "@bitgo/sdk-coin-bnb": "^1.0.0", "@bitgo/sdk-coin-bsc": "^3.6.4", "@bitgo/sdk-coin-bsv": "^1.3.27", "@bitgo/sdk-coin-btc": "^1.5.7", diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index b7772f8d69..ebdfb2b43a 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -21,6 +21,8 @@ import { Bld, Bsc, BscToken, + Bnb, + BnbToken, Bsv, Btc, Btg, @@ -65,6 +67,7 @@ import { Tbch, Tbld, Tbsc, + Tbnb, Tbsv, Tbtc, Tcelo, @@ -115,6 +118,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('bcha', Bcha.createInstance); globalCoinFactory.register('bld', Bld.createInstance); globalCoinFactory.register('bsc', Bsc.createInstance); + globalCoinFactory.register('bnb', Bnb.createInstance); globalCoinFactory.register('bsv', Bsv.createInstance); globalCoinFactory.register('btc', Btc.createInstance); globalCoinFactory.register('btg', Btg.createInstance); @@ -156,6 +160,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('tbcha', Tbcha.createInstance); globalCoinFactory.register('tbld', Tbld.createInstance); globalCoinFactory.register('tbsc', Tbsc.createInstance); + globalCoinFactory.register('tbnb', Tbnb.createInstance); globalCoinFactory.register('tbsv', Tbsv.createInstance); globalCoinFactory.register('tbtc', Tbtc.createInstance); globalCoinFactory.register('tcelo', Tcelo.createInstance); @@ -216,6 +221,10 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register(name, coinConstructor); }); + BnbToken.createTokenConstructors().forEach(({ name, coinConstructor }) => { + globalCoinFactory.register(name, coinConstructor); + }); + EosToken.createTokenConstructors().forEach(({ name, coinConstructor }) => { globalCoinFactory.register(name, coinConstructor); }); diff --git a/modules/bitgo/src/v2/coins/index.ts b/modules/bitgo/src/v2/coins/index.ts index 042c5f3c06..41f33d5b95 100644 --- a/modules/bitgo/src/v2/coins/index.ts +++ b/modules/bitgo/src/v2/coins/index.ts @@ -8,6 +8,7 @@ import { Bch, Tbch } from '@bitgo/sdk-coin-bch'; import { Bcha, Tbcha } from '@bitgo/sdk-coin-bcha'; import { Bld, Tbld } from '@bitgo/sdk-coin-bld'; import { Bsc, BscToken, Tbsc } from '@bitgo/sdk-coin-bsc'; +import { Bnb, BnbToken, Tbnb } from '@bitgo/sdk-coin-bnb'; import { Bsv, Tbsv } from '@bitgo/sdk-coin-bsv'; import { Btc, Tbtc } from '@bitgo/sdk-coin-btc'; import { Btg } from '@bitgo/sdk-coin-btg'; @@ -46,6 +47,7 @@ export { AvaxC, AvaxCToken, TavaxC }; export { AvaxP, TavaxP }; export { Bch, Tbch }; export { Bsc, BscToken, Tbsc }; +export { Bnb, BnbToken, Tbnb }; export { Bsv, Tbsv }; export { Btc, Tbtc }; export { Btg }; diff --git a/modules/bitgo/test/browser/browser.spec.ts b/modules/bitgo/test/browser/browser.spec.ts index 27cb43b92e..328706c31b 100644 --- a/modules/bitgo/test/browser/browser.spec.ts +++ b/modules/bitgo/test/browser/browser.spec.ts @@ -21,6 +21,7 @@ describe('Coins', () => { AvaxCToken: 1, PolygonToken: 1, BscToken: 1, + BnbToken: 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 d085967b96..6c781a32a7 100644 --- a/modules/bitgo/test/v2/unit/keychains.ts +++ b/modules/bitgo/test/v2/unit/keychains.ts @@ -299,7 +299,7 @@ describe('V2 Keychains', function () { }); }); - ['tbsc'].forEach((coin) => { + ['tbsc', 'tbnb'].forEach((coin) => { it('should create ECDSA TSS Keychains', async function () { sandbox.stub(ECDSAUtils.EcdsaUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet); const keychains = await bitgo.coin(coin).keychains().createMpc({ diff --git a/modules/bitgo/tsconfig.json b/modules/bitgo/tsconfig.json index eba8381b18..32039899d0 100644 --- a/modules/bitgo/tsconfig.json +++ b/modules/bitgo/tsconfig.json @@ -62,6 +62,9 @@ { "path": "../sdk-coin-bsc" }, + { + "path": "../sdk-coin-bnb" + }, { "path": "../sdk-coin-bsv" }, diff --git a/modules/sdk-coin-bnb/.eslintignore b/modules/sdk-coin-bnb/.eslintignore new file mode 100644 index 0000000000..190f83e0df --- /dev/null +++ b/modules/sdk-coin-bnb/.eslintignore @@ -0,0 +1,5 @@ +node_modules +.idea +public +dist + diff --git a/modules/sdk-coin-bnb/.gitignore b/modules/sdk-coin-bnb/.gitignore new file mode 100644 index 0000000000..67ccce4c64 --- /dev/null +++ b/modules/sdk-coin-bnb/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.idea/ +dist/ diff --git a/modules/sdk-coin-bnb/.mocharc.yml b/modules/sdk-coin-bnb/.mocharc.yml new file mode 100644 index 0000000000..95814796d1 --- /dev/null +++ b/modules/sdk-coin-bnb/.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-bnb/.npmignore b/modules/sdk-coin-bnb/.npmignore new file mode 100644 index 0000000000..d5fb3a098c --- /dev/null +++ b/modules/sdk-coin-bnb/.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-bnb/.prettierignore b/modules/sdk-coin-bnb/.prettierignore new file mode 100644 index 0000000000..3a11d6af29 --- /dev/null +++ b/modules/sdk-coin-bnb/.prettierignore @@ -0,0 +1,2 @@ +.nyc_output/ +dist/ diff --git a/modules/sdk-coin-bnb/.prettierrc.yml b/modules/sdk-coin-bnb/.prettierrc.yml new file mode 100644 index 0000000000..7c3d8dd32a --- /dev/null +++ b/modules/sdk-coin-bnb/.prettierrc.yml @@ -0,0 +1,3 @@ +printWidth: 120 +singleQuote: true +trailingComma: 'es5' diff --git a/modules/sdk-coin-bnb/README.md b/modules/sdk-coin-bnb/README.md new file mode 100644 index 0000000000..8f33532dab --- /dev/null +++ b/modules/sdk-coin-bnb/README.md @@ -0,0 +1,30 @@ +# BitGo sdk-coin-bnb + +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-bnb`. + +```shell +npm i @bitgo/sdk-api @bitgo/sdk-coin-bnb +``` + +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 { Bnb } from '@bitgo/sdk-coin-bnb'; + +const sdk = new BitGoAPI(); + +sdk.register('bnb', Bnb.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-bnb/package.json b/modules/sdk-coin-bnb/package.json new file mode 100644 index 0000000000..fbb6906ef2 --- /dev/null +++ b/modules/sdk-coin-bnb/package.json @@ -0,0 +1,53 @@ +{ + "name": "@bitgo/sdk-coin-bnb", + "version": "1.0.0", + "description": "BitGo SDK coin library for Bnb smart chain", + "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": ">=14 <17" + }, + "repository": { + "type": "git", + "url": "https://github.com/BitGo/BitGoJS.git", + "directory": "modules/sdk-coin-bnb" + }, + "lint-staged": { + "*.{js,ts}": [ + "yarn prettier --write", + "yarn eslint --fix" + ] + }, + "publishConfig": { + "access": "public" + }, + "nyc": { + "extension": [ + ".ts" + ] + }, + "dependencies": { + "@bitgo/abstract-eth": "^1.2.27", + "@bitgo/sdk-coin-eth": "^4.5.4", + "@bitgo/sdk-core": "^8.10.0", + "@bitgo/statics": "^17.0.1", + "@ethereumjs/common": "^2.4.0" + }, + "devDependencies": { + "@bitgo/sdk-api": "^1.11.2", + "@bitgo/sdk-test": "^1.2.27" + } +} diff --git a/modules/sdk-coin-bnb/src/bnb.ts b/modules/sdk-coin-bnb/src/bnb.ts new file mode 100644 index 0000000000..03b75d6e1a --- /dev/null +++ b/modules/sdk-coin-bnb/src/bnb.ts @@ -0,0 +1,29 @@ +import { BaseCoin, BitGoBase, MPCAlgorithm } from '@bitgo/sdk-core'; +import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics'; +import { AbstractEthLikeCoin } from '@bitgo/abstract-eth'; +import { TransactionBuilder as EthTransactionBuilder } from '@bitgo/sdk-coin-eth'; +import { TransactionBuilder } from './lib'; + +export class Bnb extends AbstractEthLikeCoin { + protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly) { + super(bitgo, staticsCoin); + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Bnb(bitgo, staticsCoin); + } + + protected getTransactionBuilder(): EthTransactionBuilder { + return new TransactionBuilder(coins.get(this.getBaseChain())); + } + + /** @inheritDoc */ + supportsTss(): boolean { + return true; + } + + /** @inheritDoc */ + getMPCAlgorithm(): MPCAlgorithm { + return 'ecdsa'; + } +} diff --git a/modules/sdk-coin-bnb/src/bnbToken.ts b/modules/sdk-coin-bnb/src/bnbToken.ts new file mode 100644 index 0000000000..226766638a --- /dev/null +++ b/modules/sdk-coin-bnb/src/bnbToken.ts @@ -0,0 +1,39 @@ +/** + * @prettier + */ + +import { EthLikeTokenConfig } from '@bitgo/statics'; +import { BitGoBase, CoinConstructor, MPCAlgorithm, NamedCoinConstructor } from '@bitgo/sdk-core'; +import { CoinNames, EthLikeToken } from '@bitgo/abstract-eth'; + +export { EthLikeTokenConfig }; + +export class BnbToken extends EthLikeToken { + public readonly tokenConfig: EthLikeTokenConfig; + static coinNames: CoinNames = { + Mainnet: 'bnb', + Testnet: 'tbnb', + }; + constructor(bitgo: BitGoBase, tokenConfig: EthLikeTokenConfig) { + super(bitgo, tokenConfig, BnbToken.coinNames); + } + static createTokenConstructor(config: EthLikeTokenConfig): CoinConstructor { + return super.createTokenConstructor(config, BnbToken.coinNames); + } + + static createTokenConstructors(): NamedCoinConstructor[] { + return super.createTokenConstructors(BnbToken.coinNames); + } + + getFullName(): string { + return 'Bnb Token'; + } + + supportsTss(): boolean { + return true; + } + + getMPCAlgorithm(): MPCAlgorithm { + return 'ecdsa'; + } +} diff --git a/modules/sdk-coin-bnb/src/index.ts b/modules/sdk-coin-bnb/src/index.ts new file mode 100644 index 0000000000..7727ed8edb --- /dev/null +++ b/modules/sdk-coin-bnb/src/index.ts @@ -0,0 +1,5 @@ +export * from './lib'; +export * from './bnb'; +export * from './tbnb'; +export * from './bnbToken'; +export * from './register'; diff --git a/modules/sdk-coin-bnb/src/lib/index.ts b/modules/sdk-coin-bnb/src/lib/index.ts new file mode 100644 index 0000000000..79473f2f5a --- /dev/null +++ b/modules/sdk-coin-bnb/src/lib/index.ts @@ -0,0 +1,6 @@ +import * as Utils from './utils'; + +export { TransactionBuilder } from './transactionBuilder'; +export { TransferBuilder } from './transferBuilder'; +export { Transaction, KeyPair } from '@bitgo/sdk-coin-eth'; +export { Utils }; diff --git a/modules/sdk-coin-bnb/src/lib/resources.ts b/modules/sdk-coin-bnb/src/lib/resources.ts new file mode 100644 index 0000000000..3f7cfe1a62 --- /dev/null +++ b/modules/sdk-coin-bnb/src/lib/resources.ts @@ -0,0 +1,22 @@ +import EthereumCommon from '@ethereumjs/common'; +import { coins, EthereumNetwork } from '@bitgo/statics'; + +export const testnetCommon = EthereumCommon.forCustomChain( + 'mainnet', + { + name: 'testnet', + networkId: (coins.get('tbnb').network as EthereumNetwork).chainId, + chainId: (coins.get('tbnb').network as EthereumNetwork).chainId, + }, + 'petersburg' +); + +export const mainnetCommon = EthereumCommon.forCustomChain( + 'mainnet', + { + name: 'mainnet', + networkId: (coins.get('bnb').network as EthereumNetwork).chainId, + chainId: (coins.get('bnb').network as EthereumNetwork).chainId, + }, + 'petersburg' +); diff --git a/modules/sdk-coin-bnb/src/lib/transactionBuilder.ts b/modules/sdk-coin-bnb/src/lib/transactionBuilder.ts new file mode 100644 index 0000000000..debdb55ea1 --- /dev/null +++ b/modules/sdk-coin-bnb/src/lib/transactionBuilder.ts @@ -0,0 +1,30 @@ +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { BuildTransactionError, TransactionType } from '@bitgo/sdk-core'; +import { KeyPair, Transaction, TransactionBuilder as EthTransactionBuilder } from '@bitgo/sdk-coin-eth'; +import { getCommon } from './utils'; +import { TransferBuilder } from './transferBuilder'; + +export class TransactionBuilder extends EthTransactionBuilder { + protected _transfer: TransferBuilder; + + constructor(_coinConfig: Readonly) { + super(_coinConfig); + this._common = getCommon(this._coinConfig.network.type); + this.transaction = new Transaction(this._coinConfig, this._common); + } + + /** @inheritdoc */ + transfer(data?: string): TransferBuilder { + if (this._type !== TransactionType.Send) { + throw new BuildTransactionError('Transfers can only be set for send transactions'); + } + if (!this._transfer) { + this._transfer = new TransferBuilder(data); + } + return this._transfer; + } + + publicKey(key: string): void { + this._sourceKeyPair = new KeyPair({ pub: key }); + } +} diff --git a/modules/sdk-coin-bnb/src/lib/transferBuilder.ts b/modules/sdk-coin-bnb/src/lib/transferBuilder.ts new file mode 100644 index 0000000000..31acf01286 --- /dev/null +++ b/modules/sdk-coin-bnb/src/lib/transferBuilder.ts @@ -0,0 +1,8 @@ +import { TransferBuilder as EthTransferBuilder } from '@bitgo/sdk-coin-eth'; + +export class TransferBuilder extends EthTransferBuilder { + /** @inheritdoc */ + protected getNativeOperationHashPrefix(): string { + return 'BNB'; + } +} diff --git a/modules/sdk-coin-bnb/src/lib/utils.ts b/modules/sdk-coin-bnb/src/lib/utils.ts new file mode 100644 index 0000000000..dc81fa08f9 --- /dev/null +++ b/modules/sdk-coin-bnb/src/lib/utils.ts @@ -0,0 +1,21 @@ +import { NetworkType } from '@bitgo/statics'; +import EthereumCommon from '@ethereumjs/common'; +import { InvalidTransactionError } from '@bitgo/sdk-core'; +import { testnetCommon, mainnetCommon } from './resources'; + +const commons: Map = new Map([ + [NetworkType.MAINNET, mainnetCommon], + [NetworkType.TESTNET, testnetCommon], +]); + +/** + * @param {NetworkType} network either mainnet or testnet + * @returns {EthereumCommon} Ethereum common configuration object + */ +export function getCommon(network: NetworkType): EthereumCommon { + const common = commons.get(network); + if (!common) { + throw new InvalidTransactionError('Missing network common configuration'); + } + return common; +} diff --git a/modules/sdk-coin-bnb/src/register.ts b/modules/sdk-coin-bnb/src/register.ts new file mode 100644 index 0000000000..e2ba416235 --- /dev/null +++ b/modules/sdk-coin-bnb/src/register.ts @@ -0,0 +1,12 @@ +import { BitGoBase } from '@bitgo/sdk-core'; +import { Bnb } from './bnb'; +import { BnbToken } from './bnbToken'; +import { Tbnb } from './tbnb'; + +export const register = (sdk: BitGoBase): void => { + sdk.register('bnb', Bnb.createInstance); + sdk.register('tbnb', Tbnb.createInstance); + BnbToken.createTokenConstructors().forEach(({ name, coinConstructor }) => { + sdk.register(name, coinConstructor); + }); +}; diff --git a/modules/sdk-coin-bnb/src/tbnb.ts b/modules/sdk-coin-bnb/src/tbnb.ts new file mode 100644 index 0000000000..0bff51941a --- /dev/null +++ b/modules/sdk-coin-bnb/src/tbnb.ts @@ -0,0 +1,22 @@ +/** + * Testnet Bnb + */ +import { BaseCoin, BitGoBase } from '@bitgo/sdk-core'; +import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics'; + +import { Bnb } from './bnb'; + +export class Tbnb extends Bnb { + protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly) { + super(bitgo, staticsCoin); + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Tbnb(bitgo, staticsCoin); + } + + /** @inheritDoc */ + allowsAccountConsolidations(): boolean { + return true; + } +} diff --git a/modules/sdk-coin-bnb/test/fixtures/ecdsa.ts b/modules/sdk-coin-bnb/test/fixtures/ecdsa.ts new file mode 100644 index 0000000000..af3ec4b075 --- /dev/null +++ b/modules/sdk-coin-bnb/test/fixtures/ecdsa.ts @@ -0,0 +1,106 @@ +export const keyShares = { + A: { + pShare: { + i: 1, + t: 2, + c: 3, + l: 'e8ade89d248c10cda89063852841bf8a0da216e3cf29e1bb8323c1411f1d440a7e696edf2eda0d41d67f9e7e7f07df2f2d4839f133819fd2eb30366fdd08da68d25c8b8f24f42d8e25277a44a522f0ad8bf3bba8dbea075b484b8cdea38af9830b8233e60184fb5a09955ba8f742f925e24d5cb2890a64a04c643dc09063c924716288deb8a68d2fc7f5fd847fa6e1f27280c00140f42c9ab32ccc044ff0f571dc2354c1423840fb29b6ac4a33fce555af85a02df1b0a1af44d696797cb5ccda227866a6475a533cd8c6545924c95e948f0ab34fbd1c6775f444bd6d210338ee5fb292cdb8075c077f15accbb5f61840fecb5c721332ac6c8de86f21de70d251a66a2919b83e4c2de77f19dee7c8d1f29416b87faec311e59e7acf085cf6ed678f4aab7a99080baad57147ed216bc44fd6e3c43d88c50fb0395af175092a8cd0dd0c991785ee072d98993f6086931c46f644661ac7a161a29d47402e6ad0dfb23a905da113bc918045b09f228687ed74b626f4cfab450b9b39ba1aee20285100', + m: '67eda115fee32f93cbb120ceec526a3abd5f1c6749a939e99db4309244abfccd5fb30f4dfa383dca071f69c68bc812f5e7b90901e9b53ef3a5b7cf6a740d7162688435c497ca06a2eac8586847f15f14af095bc45fa63a6844ba1a9ea3f26b5597d0c443def85c076984359eed5067fa6f8afe56287119c7bcf945ad062b5aae1f8a5796496c77f58cf72f057a7d4d4c35af6c5740d699ccf6640f30b3280fe3d0eed25fd4129bfae20be3e65182ea2fa82c6c35febf55e6aada42c5e2707be580623fd44819176c99e97989a6de0a34e55d5d1217f1fc95a9bc600207122d55d436a2d2e545ee60bf6ad1ac8f158ee075da910cb231bef824bf7e5eae302d30538524d3b383d641d94ce1e17656a8c5219f0a4735c3019f437ad875cb4585e2f3f0aab925eb1ba34510a8b868d167212ab08df8ad5affaf42e5d6fb6355e5400b4f35fd53805f50ec21b9b04dbbe855f0856675d999bb1c21c668e44ce1c89eb7cddecb14e6668a4e73330f833fb9aa0c541f33ef7ee7c72e3c2eb238585fcd', + n: 'e8ade89d248c10cda89063852841bf8a0da216e3cf29e1bb8323c1411f1d440a7e696edf2eda0d41d67f9e7e7f07df2f2d4839f133819fd2eb30366fdd08da68d25c8b8f24f42d8e25277a44a522f0ad8bf3bba8dbea075b484b8cdea38af9830b8233e60184fb5a09955ba8f742f925e24d5cb2890a64a04c643dc09063c924716288deb8a68d2fc7f5fd847fa6e1f27280c00140f42c9ab32ccc044ff0f571dc2354c1423840fb29b6ac4a33fce555af85a02df1b0a1af44d696797cb5ccdc5857f09e74b106e1e4138a7683c26cb35d7c84c503dee237f702fd694a47a09b80dc788dc5b3434160c42fb539b5d99468080675c0243650a8255e95e472a1c2548f0da4e0454f28841f28f8641ff00fb2292a0a1445d5c787aa91ebee80753abcc966ddcc66c2f192aedae1e3eb00343d13186b4e370d76097224f3203f674082e50020ad8b2a779a327bc1aa1e22cdabecbe53f24811255cc5f39e4261920394038e951cd8933aae4a8a5c7dd93da87dc0c5217aae655dab314838ff509167', + y: '03917f30cfc8996a29a73c15afa9ac16c9721ccda49f5d7be1fb7cd9fd37802041', + u: '329ca306fad9ac1b57d47f96006c07d7d712abf19749ee78c9cdc144299fd5b9', + uu: '105036727311400273505444835419054587647981890852554899724393648565849274495754', + chaincode: '75d9266a58c752afab1db0f977cc7d9550974e374983565f620ffa704b1c185b', + }, + nShares: { + 2: { + i: 2, + j: 1, + n: 'e8ade89d248c10cda89063852841bf8a0da216e3cf29e1bb8323c1411f1d440a7e696edf2eda0d41d67f9e7e7f07df2f2d4839f133819fd2eb30366fdd08da68d25c8b8f24f42d8e25277a44a522f0ad8bf3bba8dbea075b484b8cdea38af9830b8233e60184fb5a09955ba8f742f925e24d5cb2890a64a04c643dc09063c924716288deb8a68d2fc7f5fd847fa6e1f27280c00140f42c9ab32ccc044ff0f571dc2354c1423840fb29b6ac4a33fce555af85a02df1b0a1af44d696797cb5ccdc5857f09e74b106e1e4138a7683c26cb35d7c84c503dee237f702fd694a47a09b80dc788dc5b3434160c42fb539b5d99468080675c0243650a8255e95e472a1c2548f0da4e0454f28841f28f8641ff00fb2292a0a1445d5c787aa91ebee80753abcc966ddcc66c2f192aedae1e3eb00343d13186b4e370d76097224f3203f674082e50020ad8b2a779a327bc1aa1e22cdabecbe53f24811255cc5f39e4261920394038e951cd8933aae4a8a5c7dd93da87dc0c5217aae655dab314838ff509167', + y: '03917f30cfc8996a29a73c15afa9ac16c9721ccda49f5d7be1fb7cd9fd37802041', + v: '0209b8d30fda121bfef84ede2895884719d7235b573bd10d234c3d51df4eed1e9f', + u: '7d0097c00b6699b7cf30d0411166d926d1ad808b318b3cacec5b9bfff7fd39a9', + chaincode: '75d9266a58c752afab1db0f977cc7d9550974e374983565f620ffa704b1c185b', + }, + 3: { + i: 3, + j: 1, + n: 'e8ade89d248c10cda89063852841bf8a0da216e3cf29e1bb8323c1411f1d440a7e696edf2eda0d41d67f9e7e7f07df2f2d4839f133819fd2eb30366fdd08da68d25c8b8f24f42d8e25277a44a522f0ad8bf3bba8dbea075b484b8cdea38af9830b8233e60184fb5a09955ba8f742f925e24d5cb2890a64a04c643dc09063c924716288deb8a68d2fc7f5fd847fa6e1f27280c00140f42c9ab32ccc044ff0f571dc2354c1423840fb29b6ac4a33fce555af85a02df1b0a1af44d696797cb5ccdc5857f09e74b106e1e4138a7683c26cb35d7c84c503dee237f702fd694a47a09b80dc788dc5b3434160c42fb539b5d99468080675c0243650a8255e95e472a1c2548f0da4e0454f28841f28f8641ff00fb2292a0a1445d5c787aa91ebee80753abcc966ddcc66c2f192aedae1e3eb00343d13186b4e370d76097224f3203f674082e50020ad8b2a779a327bc1aa1e22cdabecbe53f24811255cc5f39e4261920394038e951cd8933aae4a8a5c7dd93da87dc0c5217aae655dab314838ff509167', + y: '03917f30cfc8996a29a73c15afa9ac16c9721ccda49f5d7be1fb7cd9fd37802041', + v: '0209b8d30fda121bfef84ede2895884719d7235b573bd10d234c3d51df4eed1e9f', + u: 'c7648c791bf38754468d20ec2261aa75cc485524cbcc8ae10ee976bbc65a9d99', + chaincode: '75d9266a58c752afab1db0f977cc7d9550974e374983565f620ffa704b1c185b', + }, + }, + }, + + B: { + pShare: { + i: 2, + t: 2, + c: 3, + l: 'e3c66fb7ed957c58787aae6d68eadfb21c58d69fc895b7abb74caf544c8fd0470802036105cef1685d58cd832498a4b12ce9294453d75cf06a004e335171d012dbba25408d68951d08c5bb3796eabf2e7c944367d82142f59b9f87d32e93944b6ce22519771f0ed860ce70748bef239204044800a4e62ddf841b6b8cd7198bb947921abd13cc38c400346ee4afff797fce91cda3612b1a2bcd893878772e06efd68c3f01b5872bbf23ca8887c4f97dc92475b6a8299d3fb6b1f6e2b935c250b462e95d7b61e91dde02ea3ad8540c6c9b88a1dca3eac1b591fc185dd92848fb6a0ef4e9f902580ff07592654e9313d65c2ff2ef5c7faebf1995861e158e2e1a4a742a2fb6020027daf140ee8b9f7144207188eb6a45d7d3363de695b1a151f6b47fbed832740c07db82a3df59bf04edd64bbd6cdf3ee627738c07933d3fcd94d60b1fc974a0826f4ab3136b1c5210b6c54f905a62da7b0a45d6cd2c33b58db214b933eceb05da1a9278709e8d60d352cefcd6ab0e29cfe6017a0f543f794e5a60', + m: 'c4e60ac80322dbeb362a0f6ff6af3b497b339935ae189050c4ef45fcf09d60868b8278b088d5cb2a5c4d570b02284275edbbf5b1f5a56e91f66812a37ad0db9fd9c04b123eddb5f2a2755ee8432da20a2d9d1cc074360391a9e66d9e14960072ca58ff8b3871350c18fc0afe1d51687cf2d017a790522ce80541aa1b4240fab4e059b347861064b59f4bb76b0d7c4c5e7f827f4f54988d933e9bef51ec7dbb163c3f8bf720fd31027eebf6c9659f3980c4d86a5bc6fe14b1a78988b656557a2c5a588ec416af18c2118e01d358362d5ec4d80d25cbbc1f400ec98773433f4145d5e3f27b74973d96df58a61a0603aa06c713e441c8e699cdcc531d7260b0532205991c894de822b436d9501af58bee7c59f55ce2d0a9a30d408a9af7c66eeafcbd2373b2d33897820d934bd3d7819bf933157f7551ac50684d41da4ee0dbd1dae77a866a1fb1e4d12146eb7b7294437ddbd6c60af68e34a6c6d50639c4b22cb1db3adda3f3e36468a57d3084a59656d05a04302dc845ebee6bbf791e8a6a85dc', + n: 'e3c66fb7ed957c58787aae6d68eadfb21c58d69fc895b7abb74caf544c8fd0470802036105cef1685d58cd832498a4b12ce9294453d75cf06a004e335171d012dbba25408d68951d08c5bb3796eabf2e7c944367d82142f59b9f87d32e93944b6ce22519771f0ed860ce70748bef239204044800a4e62ddf841b6b8cd7198bb947921abd13cc38c400346ee4afff797fce91cda3612b1a2bcd893878772e06efd68c3f01b5872bbf23ca8887c4f97dc92475b6a8299d3fb6b1f6e2b935c250b66944b41e6b9ecaea681deb868cff7e71674b23693b193f15dc7b6f6948f1d683042a7f8250de0698c5940c8553aca4c0f2c40079f5c858463b2d7bbcf810b357ee400e2abca1451bc3d686f55f7a46154f0b9321595881acd3d47555a45f8f236d7b1546ec06b18d19a51c64acf28d029f2a3cadb0017cd57d8852ccaea3926dfd15ed70a18e6373ec77b1fe4c8291312442a719a574acc9460a08de2c27c9ae16306f986c607d5ae5689d203a9e8444b71560518e4f3b436ed033943b962acd', + y: '038ec7d86c5b6e5d123a3d26076ee6fd6d055f3fc7c05e1c9c32d4aedb3eb40425', + u: '78059cd78e4ce7d959bd76417dd8d6da6ee1d4ca4b6324f020a9a72e60709ae0', + uu: '55162782419389545869324912620122890654277956309120999578068634639986351700257', + chaincode: '8c3c104d2ced61750dd728723eb85ff2e0a09df8d9de1b13aa1f92f21da2c855', + }, + nShares: { + 1: { + i: 1, + j: 2, + n: 'e3c66fb7ed957c58787aae6d68eadfb21c58d69fc895b7abb74caf544c8fd0470802036105cef1685d58cd832498a4b12ce9294453d75cf06a004e335171d012dbba25408d68951d08c5bb3796eabf2e7c944367d82142f59b9f87d32e93944b6ce22519771f0ed860ce70748bef239204044800a4e62ddf841b6b8cd7198bb947921abd13cc38c400346ee4afff797fce91cda3612b1a2bcd893878772e06efd68c3f01b5872bbf23ca8887c4f97dc92475b6a8299d3fb6b1f6e2b935c250b66944b41e6b9ecaea681deb868cff7e71674b23693b193f15dc7b6f6948f1d683042a7f8250de0698c5940c8553aca4c0f2c40079f5c858463b2d7bbcf810b357ee400e2abca1451bc3d686f55f7a46154f0b9321595881acd3d47555a45f8f236d7b1546ec06b18d19a51c64acf28d029f2a3cadb0017cd57d8852ccaea3926dfd15ed70a18e6373ec77b1fe4c8291312442a719a574acc9460a08de2c27c9ae16306f986c607d5ae5689d203a9e8444b71560518e4f3b436ed033943b962acd', + y: '038ec7d86c5b6e5d123a3d26076ee6fd6d055f3fc7c05e1c9c32d4aedb3eb40425', + v: '020ef26f3e96018da06a8f12efecf100215ea3501764879cc2caa308a9ff180d1f', + u: 'f8fd520ef91c58cdbab7a272d96efa94cde6f54b82d4e0f519f5c6160b1baaa1', + chaincode: '8c3c104d2ced61750dd728723eb85ff2e0a09df8d9de1b13aa1f92f21da2c855', + }, + 3: { + i: 3, + j: 2, + n: 'e3c66fb7ed957c58787aae6d68eadfb21c58d69fc895b7abb74caf544c8fd0470802036105cef1685d58cd832498a4b12ce9294453d75cf06a004e335171d012dbba25408d68951d08c5bb3796eabf2e7c944367d82142f59b9f87d32e93944b6ce22519771f0ed860ce70748bef239204044800a4e62ddf841b6b8cd7198bb947921abd13cc38c400346ee4afff797fce91cda3612b1a2bcd893878772e06efd68c3f01b5872bbf23ca8887c4f97dc92475b6a8299d3fb6b1f6e2b935c250b66944b41e6b9ecaea681deb868cff7e71674b23693b193f15dc7b6f6948f1d683042a7f8250de0698c5940c8553aca4c0f2c40079f5c858463b2d7bbcf810b357ee400e2abca1451bc3d686f55f7a46154f0b9321595881acd3d47555a45f8f236d7b1546ec06b18d19a51c64acf28d029f2a3cadb0017cd57d8852ccaea3926dfd15ed70a18e6373ec77b1fe4c8291312442a719a574acc9460a08de2c27c9ae16306f986c607d5ae5689d203a9e8444b71560518e4f3b436ed033943b962acd', + y: '038ec7d86c5b6e5d123a3d26076ee6fd6d055f3fc7c05e1c9c32d4aedb3eb40425', + v: '020ef26f3e96018da06a8f12efecf100215ea3501764879cc2caa308a9ff180d1f', + u: 'f70de7a0237d76e4f8c34a102242b31eca8b912fc33a0926e72fe6d385fbcc60', + chaincode: '8c3c104d2ced61750dd728723eb85ff2e0a09df8d9de1b13aa1f92f21da2c855', + }, + }, + }, + + C: { + pShare: { + i: 3, + t: 2, + c: 3, + l: 'b6dbb186434ce2126ed8e32d6bc273603d05e973e9c3fd2978cc8e1e70bca14d4c4fd2c4713f5002f95845faef74c5f7198fa7abfd9ea1faac8be0a4df6aa26048c6747afb3a2ee31504d9b3aa0d6aae19707a2431251f419abf5d4204d2d891b7ea17b487efca1255c768b5537b34efcb223e9cac679329da9a7e78401d9935cb7849d3b5f163b0f2a9344e39d800860ca6d3c9dee941d7f13389901c2f659aa3e6c32f09399941bb9db86c843d3069f99f10baf0c53cbcc78deb950a815e1be3ef1e605aa63f83164c3a50799aaca22341f60484519f109bb075cdfb08e73c5056bf43830e50076a2977b900b2cbdad91c6e70a537d353d0ce3c3697fa10c649286f565df6491bad9407d8def460a7245a8fedb249fb6c85aa14384db2d8b261186e0d277de05b13ee0ab35fc4fa0396d16e3fbea1d639524822a7ce85e9cbb29c9d8c5c30b7895a00b5e89611e488cf98498fc0355ebd2a23f7449a53f7b477cece028812c20cabf27fa897e569e0cc2aeff84af8f0570ded9f037284f260', + m: 'adb4f98a1dd1bd7f6bcd3830e44b554b4ba4179c52eb52e70bc9736396d20fba6a66041c03e188e7662cbdcdee75034096fb514d93d790e2f094c39c70482fc36a5171a0e114a4b9d44b2b30aaa64e881b20a839d863fd61d835efaf055e9d9b008c0b7ce680f51c9dea18ff8d2f12b848f916952d8bb520db60e502c2496b6b68d936daaa475e2a21848c59186078edc2d822dce06c374809212a0ca3e48f4ad352157fb5eb52dd5b6f68b9530d092f5b2d4d990d358b80b1a721be86711e51524f4e38f9cbe34dcae714f303864207759cd7f3fe73504cdbad99e3829de1db86bfc24b1dbbf3cf8e9354f18c4c52181be83e569a96f4c6b13f7b00391a03233eca8be0f25ccb50b6b9702a3f7a035beb7efe18f10d600b88f5a5baccfd822784404483c51a867bdb2c70f2fe8ed2afe0a01bdb3dd3b0fc66125f66e46209550a7a09d3f17f7fe3839bb12d8890ad436012ed1d2e6547c048a253e95aa01a618c60e5828fe32262fdc03ac4dc600780a90323c2f61edf3b0f531e294fa43b7f', + n: 'b6dbb186434ce2126ed8e32d6bc273603d05e973e9c3fd2978cc8e1e70bca14d4c4fd2c4713f5002f95845faef74c5f7198fa7abfd9ea1faac8be0a4df6aa26048c6747afb3a2ee31504d9b3aa0d6aae19707a2431251f419abf5d4204d2d891b7ea17b487efca1255c768b5537b34efcb223e9cac679329da9a7e78401d9935cb7849d3b5f163b0f2a9344e39d800860ca6d3c9dee941d7f13389901c2f659aa3e6c32f09399941bb9db86c843d3069f99f10baf0c53cbcc78deb950a815e1dce71db43eb81ea740339c3605aab8ea5d0b250dc712a0d1c0807a9706a64cb66bb334f8866ac83696a0e09ff8f06103d7d4a5f439cb7db29499414a6693313cf39a90a76deca6cf8a13acc9e625b4b3aad4ebc7ea76ee322df769812851309514809560925514b36ea63e2e10810f270417b67c54d9cffab0dcf9a5fa6845bba5066165ab9dd757dbe4ff2a5c531e5c6e5757e195f15cb6b97081fd8e978de896449830c166e328989e39942d608bb5c4a0016ec68d393469db057120df7b0c5', + y: '02d4f1017912951163a39c065585adc3528fbb87474b943a9410ca96dbc9f5613c', + u: '4d651c7e2744f8cfb1d78fe84ad6a186465997007e3b7f4df130102d72c4638a', + uu: '4331251667263128721421568396470993046620211356746458367310802710199575757499', + chaincode: '440e9c550d1154df71ea3c5af1e5affb9e57a72fbb63e32b8e80c3ab395fdeef', + }, + nShares: { + 1: { + i: 1, + j: 3, + n: 'b6dbb186434ce2126ed8e32d6bc273603d05e973e9c3fd2978cc8e1e70bca14d4c4fd2c4713f5002f95845faef74c5f7198fa7abfd9ea1faac8be0a4df6aa26048c6747afb3a2ee31504d9b3aa0d6aae19707a2431251f419abf5d4204d2d891b7ea17b487efca1255c768b5537b34efcb223e9cac679329da9a7e78401d9935cb7849d3b5f163b0f2a9344e39d800860ca6d3c9dee941d7f13389901c2f659aa3e6c32f09399941bb9db86c843d3069f99f10baf0c53cbcc78deb950a815e1dce71db43eb81ea740339c3605aab8ea5d0b250dc712a0d1c0807a9706a64cb66bb334f8866ac83696a0e09ff8f06103d7d4a5f439cb7db29499414a6693313cf39a90a76deca6cf8a13acc9e625b4b3aad4ebc7ea76ee322df769812851309514809560925514b36ea63e2e10810f270417b67c54d9cffab0dcf9a5fa6845bba5066165ab9dd757dbe4ff2a5c531e5c6e5757e195f15cb6b97081fd8e978de896449830c166e328989e39942d608bb5c4a0016ec68d393469db057120df7b0c5', + y: '02d4f1017912951163a39c065585adc3528fbb87474b943a9410ca96dbc9f5613c', + v: '027d3f2e23cf7ccce5bd2876a8be5e52e78ece86bf720e8827e98cf2461b9b3e99', + u: '7583f8b2e160bd1696cd7356d391922a35927a0b3ce5051b84b65513ae2b636b', + chaincode: '440e9c550d1154df71ea3c5af1e5affb9e57a72fbb63e32b8e80c3ab395fdeef', + }, + 2: { + i: 2, + j: 3, + n: 'b6dbb186434ce2126ed8e32d6bc273603d05e973e9c3fd2978cc8e1e70bca14d4c4fd2c4713f5002f95845faef74c5f7198fa7abfd9ea1faac8be0a4df6aa26048c6747afb3a2ee31504d9b3aa0d6aae19707a2431251f419abf5d4204d2d891b7ea17b487efca1255c768b5537b34efcb223e9cac679329da9a7e78401d9935cb7849d3b5f163b0f2a9344e39d800860ca6d3c9dee941d7f13389901c2f659aa3e6c32f09399941bb9db86c843d3069f99f10baf0c53cbcc78deb950a815e1dce71db43eb81ea740339c3605aab8ea5d0b250dc712a0d1c0807a9706a64cb66bb334f8866ac83696a0e09ff8f06103d7d4a5f439cb7db29499414a6693313cf39a90a76deca6cf8a13acc9e625b4b3aad4ebc7ea76ee322df769812851309514809560925514b36ea63e2e10810f270417b67c54d9cffab0dcf9a5fa6845bba5066165ab9dd757dbe4ff2a5c531e5c6e5757e195f15cb6b97081fd8e978de896449830c166e328989e39942d608bb5c4a0016ec68d393469db057120df7b0c5', + y: '02d4f1017912951163a39c065585adc3528fbb87474b943a9410ca96dbc9f5613c', + v: '027d3f2e23cf7ccce5bd2876a8be5e52e78ece86bf720e8827e98cf2461b9b3e99', + u: 'e1748a988452daf32452819f8f3419d79b4d76f9353492529adc61e6f893041b', + chaincode: '440e9c550d1154df71ea3c5af1e5affb9e57a72fbb63e32b8e80c3ab395fdeef', + }, + }, + }, +}; diff --git a/modules/sdk-coin-bnb/test/resources/bnb.ts b/modules/sdk-coin-bnb/test/resources/bnb.ts new file mode 100644 index 0000000000..435387a118 --- /dev/null +++ b/modules/sdk-coin-bnb/test/resources/bnb.ts @@ -0,0 +1,12 @@ +export const TEST_ACCOUNT = { + seed: '4b3b89f6ca897cb729d2146913877f71', + ethPrivateKey: 'ABAF3CD623F5353A143AB5E2EF47CEBD94877460D3C6F5A273313DE98F96DBBC', + ethCompressedPublicKey: '023BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E2', + ethUncompressedPublicKey: + '043BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E227874E8075353564D83047566EEA6CF5A7313816AF004DDA8CA529DE8C94BC6A', + ethExtendedPublicKey: + 'xpub661MyMwAqRbcEqNh81TVVceUDNF6yg7F63H9j3xMQj8GDdDVRLCFoPughSdgGs4X1n89iPXFKPMy3f45Y7E63kXGAZKuZ1fhLqsKtkoB3yZ', + ethExtendedPrivateKey: + 'xprv9s21ZrQH143K2MJE1yvV8UhjfLQcaDPPipMYvfYjrPbHLptLsnt1FbbCrCT9E5LCmRrS593YZ1CKgf3rf3C2hYTynZN5au3VvBvLcWh8sV2', + ethAddress: '0x1374a2046661f914d1687d85dbbceb9ac7910a29', +}; diff --git a/modules/sdk-coin-bnb/test/unit/bnb.ts b/modules/sdk-coin-bnb/test/unit/bnb.ts new file mode 100644 index 0000000000..8b8c737ab8 --- /dev/null +++ b/modules/sdk-coin-bnb/test/unit/bnb.ts @@ -0,0 +1,41 @@ +import 'should'; + +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { BitGoAPI } from '@bitgo/sdk-api'; + +import { Bnb, Tbnb } from '../../src/index'; + +const bitgo: TestBitGoAPI = TestBitGo.decorate(BitGoAPI, { env: 'test' }); + +describe('BNB Smart Chain', function () { + before(function () { + bitgo.safeRegister('bnb', Bnb.createInstance); + bitgo.safeRegister('tbnb', Tbnb.createInstance); + bitgo.initializeTestVars(); + }); + + describe('Basic Coin Info', function () { + it('should return the right info for bnb', function () { + const bnb = bitgo.coin('bnb'); + + bnb.should.be.an.instanceof(Bnb); + bnb.getChain().should.equal('bnb'); + bnb.getFamily().should.equal('bnb'); + bnb.getFullName().should.equal('BNB Smart Chain'); + bnb.getBaseFactor().should.equal(1e18); + bnb.supportsTss().should.equal(true); + }); + + it('should return the right info for tbnb', function () { + const tbnb = bitgo.coin('tbnb'); + + tbnb.should.be.an.instanceof(Tbnb); + tbnb.getChain().should.equal('tbnb'); + tbnb.getFamily().should.equal('bnb'); + tbnb.getFullName().should.equal('Testnet BNB Smart Chain'); + tbnb.getBaseFactor().should.equal(1e18); + tbnb.supportsTss().should.equal(true); + tbnb.allowsAccountConsolidations().should.equal(true); + }); + }); +}); diff --git a/modules/sdk-coin-bnb/test/unit/bnbToken.ts b/modules/sdk-coin-bnb/test/unit/bnbToken.ts new file mode 100644 index 0000000000..e4fe01f652 --- /dev/null +++ b/modules/sdk-coin-bnb/test/unit/bnbToken.ts @@ -0,0 +1,32 @@ +import 'should'; + +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { BnbToken } from '../../src'; +import { BitGoAPI } from '@bitgo/sdk-api'; + +describe('Bnb Token:', function () { + let bitgo: TestBitGoAPI; + let bnbTokenCoin; + const tokenName = 'tbnb:busd'; + + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' }); + BnbToken.createTokenConstructors().forEach(({ name, coinConstructor }) => { + bitgo.safeRegister(name, coinConstructor); + }); + bitgo.initializeTestVars(); + bnbTokenCoin = bitgo.coin(tokenName); + }); + + it('should return constants', function () { + bnbTokenCoin.getChain().should.equal('tbnb:busd'); + bnbTokenCoin.getBaseChain().should.equal('tbnb'); + bnbTokenCoin.getFullName().should.equal('Bnb Token'); + bnbTokenCoin.getBaseFactor().should.equal(1e18); + bnbTokenCoin.type.should.equal(tokenName); + bnbTokenCoin.name.should.equal('Test BNB USD Token'); + bnbTokenCoin.coin.should.equal('tbnb'); + bnbTokenCoin.network.should.equal('Testnet'); + bnbTokenCoin.decimalPlaces.should.equal(18); + }); +}); diff --git a/modules/sdk-coin-bnb/test/unit/getBuilder.ts b/modules/sdk-coin-bnb/test/unit/getBuilder.ts new file mode 100644 index 0000000000..261b490989 --- /dev/null +++ b/modules/sdk-coin-bnb/test/unit/getBuilder.ts @@ -0,0 +1,6 @@ +import { TransactionBuilder } from '../../src'; +import { coins } from '@bitgo/statics'; + +export const getBuilder = (coin: string): TransactionBuilder => { + return new TransactionBuilder(coins.get(coin)); +}; diff --git a/modules/sdk-coin-bnb/test/unit/transactionBuilder/send.ts b/modules/sdk-coin-bnb/test/unit/transactionBuilder/send.ts new file mode 100644 index 0000000000..88c46587ae --- /dev/null +++ b/modules/sdk-coin-bnb/test/unit/transactionBuilder/send.ts @@ -0,0 +1,16 @@ +import { getBuilder } from '../getBuilder'; +import should from 'should'; + +describe('BNB Transfer Builder', () => { + describe('Build from TxHex', function () { + it('Should successfully build from txHex', async function () { + const txBuilder = getBuilder('tbnb'); + const txHex = + '0xf8ad82026d85059f73c1808303d09094f5caa5e3e93afbc21bd19ef4f2691a37121f791780b844fb90b32000000000000000000000000090a4693ee469ac4f04bb9bb8ccf955e6cf4cf875000000000000000000000000000000000000000000000000000000000000000181e5a08d37159dab62ce1f450cab33c932603505952e351f5da8da70023cdc9275be57a034be4eac6c2d636c6f1f0762ab0390fc8aa2fc541a968c911f8ef05a3422f44f'; + txBuilder.from(txHex); + const parsedTx = await txBuilder.build(); + + should.exist(parsedTx.toJson()); + }); + }); +}); diff --git a/modules/sdk-coin-bnb/test/unit/utils.ts b/modules/sdk-coin-bnb/test/unit/utils.ts new file mode 100644 index 0000000000..24f3fb4c2b --- /dev/null +++ b/modules/sdk-coin-bnb/test/unit/utils.ts @@ -0,0 +1,29 @@ +import assert from 'assert'; +import should from 'should'; +import { NetworkType } from '@bitgo/statics'; +import { getCommon } from '../../src/lib/utils'; + +describe('Network Common Configuration', () => { + it('getCommon for mainnet', () => { + const common = getCommon(NetworkType.MAINNET); + should.equal(common.chainName(), 'mainnet'); + should.equal(common.hardfork(), 'petersburg'); + should.equal(common.chainIdBN().toString(), '56'); + should.equal(common.networkIdBN().toString(), '56'); + }); + + it('getCommon for testnet', () => { + const common = getCommon(NetworkType.TESTNET); + should.equal(common.chainName(), 'testnet'); + should.equal(common.hardfork(), 'petersburg'); + should.equal(common.chainIdBN().toString(), '97'); + should.equal(common.networkIdBN().toString(), '97'); + }); + + it('getCommon for invalid network', () => { + assert.throws( + () => getCommon('invalidNetwork' as NetworkType), + (e) => e.message === 'Missing network common configuration' + ); + }); +}); diff --git a/modules/sdk-coin-bnb/tsconfig.json b/modules/sdk-coin-bnb/tsconfig.json new file mode 100644 index 0000000000..2862c10c0e --- /dev/null +++ b/modules/sdk-coin-bnb/tsconfig.json @@ -0,0 +1,32 @@ +{ + "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": "../abstract-eth" + }, + { + "path": "../sdk-api" + }, + { + "path": "../sdk-coin-eth" + }, + { + "path": "../sdk-core" + }, + { + "path": "../statics" + }, + { + "path": "../sdk-test" + } + ] +} diff --git a/modules/sdk-core/src/bitgo/utils/mpcUtils.ts b/modules/sdk-core/src/bitgo/utils/mpcUtils.ts index 4bbd3087ae..a62eb1c4ba 100644 --- a/modules/sdk-core/src/bitgo/utils/mpcUtils.ts +++ b/modules/sdk-core/src/bitgo/utils/mpcUtils.ts @@ -142,7 +142,12 @@ export abstract class MpcUtils { recipients: intentRecipients, }; - if (baseCoin.getFamily() === 'eth' || baseCoin.getFamily() === 'polygon' || baseCoin.getFamily() === 'bsc') { + if ( + baseCoin.getFamily() === 'eth' || + baseCoin.getFamily() === 'polygon' || + baseCoin.getFamily() === 'bsc' || + baseCoin.getFamily() === 'bnb' + ) { switch (params.intentType) { case 'payment': case 'transferToken': diff --git a/modules/statics/src/account.ts b/modules/statics/src/account.ts index a22141ace0..5b4eb8c55f 100644 --- a/modules/statics/src/account.ts +++ b/modules/statics/src/account.ts @@ -202,6 +202,8 @@ export class CeloCoin extends ContractAddressDefinedToken {} */ export class BscCoin extends ContractAddressDefinedToken {} +export class BnbCoin extends ContractAddressDefinedToken {} + /** * The Stellar network supports tokens (non-native assets) * XLM is also known as the native asset. @@ -841,7 +843,7 @@ export function tceloToken( } /** - * Factory function for celo token instances. + * Factory function for bsc token instances. * * @param id uuid v4 * @param name unique identifier of the token @@ -887,6 +889,38 @@ export function bscToken( ); } +export function bnbToken( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + contractAddress: string, + asset: UnderlyingAsset, + features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES, + prefix = '', + suffix: string = name.toUpperCase(), + network: EthereumNetwork = Networks.main.bsc, + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + return Object.freeze( + new BnbCoin({ + id, + name, + fullName, + network, + contractAddress, + prefix, + suffix, + features, + decimalPlaces, + asset, + isToken: true, + primaryKeyCurve, + baseUnit: BaseUnit.BSC, + }) + ); +} + /** * Factory function for testnet bsc token instances. * @@ -916,6 +950,21 @@ export function tbscToken( return bscToken(id, name, fullName, decimalPlaces, contractAddress, asset, features, prefix, suffix, network); } +export function tbnbToken( + id: string, + name: string, + fullName: string, + decimalPlaces: number, + contractAddress: string, + asset: UnderlyingAsset, + features: CoinFeature[] = AccountCoin.DEFAULT_FEATURES, + prefix = '', + suffix: string = name.toUpperCase(), + network: EthereumNetwork = Networks.test.bsc +) { + return bnbToken(id, name, fullName, decimalPlaces, contractAddress, asset, features, prefix, suffix, network); +} + /** * Factory function for Stellar token instances. * diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index a0e04052d2..fc89b6328f 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -29,6 +29,7 @@ export enum CoinFamily { BCHA = 'bcha', BLD = 'bld', // Agoric BSC = 'bsc', + BNB = 'bnb', BSV = 'bsv', BTC = 'btc', BTG = 'btg', @@ -1224,6 +1225,17 @@ export enum UnderlyingAsset { 'terc721:bsctoken' = 'terc721:bsctoken', 'terc1155:bsctoken' = 'terc1155:bsctoken', + // BNB Token BEP-20 + 'bnb:busd' = 'bnb:busd', + 'tbnb:busd' = 'tbnb:busd', + // BNB NFTs + // generic NFTs + 'erc721:bnbtoken' = 'erc721:bnbtoken', + 'erc1155:bnbtoken' = 'erc1155:bnbtoken', + // Test BNB NFTs + 'terc721:bnbtoken' = 'terc721:bnbtoken', + 'terc1155:bnbtoken' = 'terc1155:bnbtoken', + // Polygon testnet tokens 'tpolygon:derc20' = 'tpolygon:derc20', 'tpolygon:link' = 'tpolygon:link', @@ -1260,6 +1272,7 @@ export enum BaseUnit { ETH = 'wei', BTC = 'satoshi', BSC = 'jager', + BNB = 'jager', XLM = 'stroop', TRX = 'sun', HBAR = 'tinybar', diff --git a/modules/statics/src/coins.ts b/modules/statics/src/coins.ts index a38e54afb7..5a0da155e6 100644 --- a/modules/statics/src/coins.ts +++ b/modules/statics/src/coins.ts @@ -4,6 +4,7 @@ import { algoToken, avaxErc20, bscToken, + bnbToken, celoToken, eosToken, erc1155, @@ -20,6 +21,7 @@ import { talgoToken, tavaxErc20, tbscToken, + tbnbToken, tceloToken, teosToken, terc1155, @@ -953,6 +955,16 @@ export const coins = CoinMap.fromCoins([ BaseUnit.BSC, [...ETH_FEATURES_WITH_MMI, CoinFeature.TSS, CoinFeature.TSS_COLD, CoinFeature.EVM_WALLET] ), + account( + '0c6eb16f-31dc-4383-86c4-e6af69c9cf99', + 'bnb', + 'BNB Smart Chain', + Networks.main.bnb, + 18, + UnderlyingAsset.BNB, + BaseUnit.BNB, + [...ETH_FEATURES_WITH_MMI, CoinFeature.TSS, CoinFeature.TSS_COLD, CoinFeature.EVM_WALLET] + ), account( '0a205427-f7c9-48a4-a238-c4b33ba6384d', 'tbsc', @@ -963,6 +975,16 @@ export const coins = CoinMap.fromCoins([ BaseUnit.BSC, [...ETH_FEATURES_WITH_MMI, CoinFeature.TSS, CoinFeature.TSS_COLD, CoinFeature.EVM_WALLET] ), + account( + '355fcaac-e6f4-4446-8d14-eaad0084f0eb', + 'tbnb', + 'Testnet BNB Smart Chain', + Networks.test.bnb, + 18, + UnderlyingAsset.BNB, + BaseUnit.BNB, + [...ETH_FEATURES_WITH_MMI, CoinFeature.TSS, CoinFeature.TSS_COLD, CoinFeature.EVM_WALLET] + ), account( 'f0e226b6-6cd8-4384-b0a5-ba8e4148a049', 'polygon', @@ -1714,7 +1736,7 @@ export const coins = CoinMap.fromCoins([ ), erc20( '462e1878-68eb-4c2b-9346-cee992195cdc', - 'bnb', + 'bnberc20', 'BNB Token', 18, '0xb8c77482e45f1f44de1745f52c74426c631bdd52', @@ -1851,7 +1873,7 @@ export const coins = CoinMap.fromCoins([ erc20( 'e9ba7fec-7824-40ad-9d51-2b973585325c', 'busd', - 'Binance USD', + 'BNB USD', 18, '0x4fabb145d64652a948d72533023f6e7a623c7c53', UnderlyingAsset.BUSD @@ -6964,6 +6986,36 @@ export const coins = CoinMap.fromCoins([ Networks.main.bsc, KeyCurve.Secp256k1 ), + bnbToken( + 'd1560a2f-80a7-4504-a9c3-9bbeeed74f4d', + 'bnb:busd', + 'BNB USD Token', + 18, + '0xe9e7cea3dedca5984780bafc599bd69add087d56', + UnderlyingAsset['bnb:busd'] + ), + erc721( + '60914343-d147-46e7-8958-ab809302472e', + 'erc721:bnbtoken', + 'Generic BNB ERC721', + '0xerc721:bnbtoken', + GENERIC_TOKEN_FEATURES, + '', + '', + Networks.main.bnb, + KeyCurve.Secp256k1 + ), + erc1155( + '0cb642a8-bad9-4b5b-9f2b-1d1c724f29fe', + 'erc1155:bnbtoken', + 'Generic BNB ERC1155', + '0xerc1155:bnbtoken', + GENERIC_TOKEN_FEATURES, + '', + '', + Networks.main.bnb, + KeyCurve.Secp256k1 + ), ofcerc20('8304c497-523d-4f3f-8744-65e2e5ebd5a5', 'ofc1inch', '1Inch Token', 18, UnderlyingAsset['1INCH']), ofcerc20('28024a59-6fbb-4156-96e4-2ba7747e8581', 'ofcusdc', 'USD Coin', 6, UnderlyingAsset.USDC), ofcerc20('f790e63d-9785-4e98-b323-897fdc489613', 'ofcaave', 'Aave', 18, UnderlyingAsset.AAVE), @@ -8068,6 +8120,36 @@ export const coins = CoinMap.fromCoins([ Networks.test.bsc, KeyCurve.Secp256k1 ), + tbnbToken( + 'a9b37869-13d4-4a42-9a17-18a6f185e31c', + 'tbnb:busd', + 'Test BNB USD Token', + 18, + '0xed24fc36d5ee211ea25a80239fb8c4cfd80f12ee', + UnderlyingAsset['tbnb:busd'] + ), + terc721( + '86ca7ef9-9134-48ac-8965-fcd06034b74c', + 'terc721:bnbtoken', + 'Generic BNB ERC721', + '0xterc721:bnbtoken', + GENERIC_TOKEN_FEATURES, + '', + '', + Networks.test.bnb, + KeyCurve.Secp256k1 + ), + terc721( + 'a444cbce-18ab-4c0e-b172-eab866d86c85', + 'terc1155:bnbtoken', + 'Generic BNB ERC1155', + '0xterc1155:bnbctoken', + GENERIC_TOKEN_FEATURES, + '', + '', + Networks.test.bnb, + KeyCurve.Secp256k1 + ), erc721( '0745cd72-9108-4ac0-80db-7c9418d55b79', 'erc721:witch', diff --git a/modules/statics/src/networks.ts b/modules/statics/src/networks.ts index f707dc9c14..2e1753fe5b 100644 --- a/modules/statics/src/networks.ts +++ b/modules/statics/src/networks.ts @@ -224,6 +224,22 @@ class BinanceSmartChainTestnet extends Testnet implements EthereumNetwork { chainId = 97; } +class BNBSmartChain extends Mainnet implements EthereumNetwork { + name = 'BNBSmartChain'; + family = CoinFamily.BNB; + explorerUrl = 'https://www.bscscan.com/tx/'; + accountExplorerUrl = 'https://www.bscscan.com/address/'; + chainId = 56; +} + +class BNBSmartChainTestnet extends Testnet implements EthereumNetwork { + name = 'BBNSmartChainTestnet'; + family = CoinFamily.BNB; + explorerUrl = 'https://testnet.bscscan.com/tx/'; + accountExplorerUrl = 'https://testnet.bscscan.com/address/'; + chainId = 97; +} + class Bitcoin extends Mainnet implements UtxoNetwork { name = 'Bitcoin'; family = CoinFamily.BTC; @@ -790,6 +806,7 @@ export const Networks = { bitcoinSV: Object.freeze(new BitcoinSV()), bld: Object.freeze(new Bld()), bsc: Object.freeze(new BinanceSmartChain()), + bnb: Object.freeze(new BNBSmartChain()), casper: Object.freeze(new Casper()), celo: Object.freeze(new Celo()), dash: Object.freeze(new Dash()), @@ -835,6 +852,7 @@ export const Networks = { bitcoinSV: Object.freeze(new BitcoinSVTestnet()), bld: Object.freeze(new BldTestnet()), bsc: Object.freeze(new BinanceSmartChainTestnet()), + bnb: Object.freeze(new BNBSmartChainTestnet()), casper: Object.freeze(new CasperTestnet()), celo: Object.freeze(new CeloTestnet()), dash: Object.freeze(new DashTestnet()), diff --git a/modules/statics/src/tokenConfig.ts b/modules/statics/src/tokenConfig.ts index 8c9e13db9d..2eb592e616 100644 --- a/modules/statics/src/tokenConfig.ts +++ b/modules/statics/src/tokenConfig.ts @@ -9,6 +9,7 @@ import { HederaToken, PolygonERC20Token, BscCoin, + BnbCoin, AdaCoin, Erc721Coin, Erc1155Coin, @@ -98,6 +99,9 @@ export interface Tokens { bsc: { tokens: EthLikeTokenConfig[]; }; + bnb: { + tokens: EthLikeTokenConfig[]; + }; sol: { tokens: SolTokenConfig[]; }; @@ -133,6 +137,9 @@ export interface Tokens { bsc: { tokens: EthLikeTokenConfig[]; }; + bnb: { + tokens: EthLikeTokenConfig[]; + }; eos: { tokens: EosTokenConfig[]; }; @@ -256,6 +263,20 @@ const formattedBscTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) => { return acc; }, []); +const formattedBnbTokens = coins.reduce((acc: EthLikeTokenConfig[], coin) => { + if (coin instanceof BnbCoin) { + acc.push({ + type: coin.name, + coin: coin.network.type === NetworkType.MAINNET ? 'bnb' : 'tbnb', + network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet', + name: coin.fullName, + tokenContractAddress: coin.contractAddress.toString().toLowerCase(), + decimalPlaces: coin.decimalPlaces, + }); + } + return acc; +}, []); + const formattedEosTokens = coins.reduce((acc: EosTokenConfig[], coin) => { if (coin instanceof EosCoin) { acc.push({ @@ -408,6 +429,9 @@ export const tokens: Tokens = { bsc: { tokens: formattedBscTokens.filter((token) => token.network === 'Mainnet'), }, + bnb: { + tokens: formattedBnbTokens.filter((token) => token.network === 'Mainnet'), + }, eos: { tokens: formattedEosTokens.filter((token) => token.network === 'Mainnet'), }, @@ -453,6 +477,9 @@ export const tokens: Tokens = { bsc: { tokens: formattedBscTokens.filter((token) => token.network === 'Testnet'), }, + bnb: { + tokens: formattedBnbTokens.filter((token) => token.network === 'Testnet'), + }, eos: { tokens: formattedEosTokens.filter((token) => token.network === 'Testnet'), }, diff --git a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts index 4aa7725192..b8f1d79bf4 100644 --- a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts +++ b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts @@ -52,6 +52,7 @@ export const expectedColdFeatures = { 'atom', 'bld', 'bsc', + 'bnb', 'dot', 'hash', 'injective', @@ -64,6 +65,7 @@ export const expectedColdFeatures = { 'tatom', 'tbld', 'tbsc', + 'tbnb', 'tdot', 'thash', 'tia', diff --git a/modules/web-demo/package.json b/modules/web-demo/package.json index 055c2520b4..afb5ed0bcb 100644 --- a/modules/web-demo/package.json +++ b/modules/web-demo/package.json @@ -32,6 +32,7 @@ "@bitgo/sdk-coin-avaxp": "^3.5.18", "@bitgo/sdk-coin-bch": "^1.3.27", "@bitgo/sdk-coin-bcha": "^1.5.22", + "@bitgo/sdk-coin-bnb": "^1.0.0", "@bitgo/sdk-coin-bsc": "^3.6.4", "@bitgo/sdk-coin-bsv": "^1.3.27", "@bitgo/sdk-coin-btc": "^1.5.7", diff --git a/modules/web-demo/src/components/Coins/coinFactory.ts b/modules/web-demo/src/components/Coins/coinFactory.ts index d996571beb..9ef61443fa 100644 --- a/modules/web-demo/src/components/Coins/coinFactory.ts +++ b/modules/web-demo/src/components/Coins/coinFactory.ts @@ -60,6 +60,11 @@ class CoinFactory { const { register } = await import('@bitgo/sdk-coin-bsc'); return this.cacheAndRegister(name, sdk, register); } + case 'bnb': + case 'tbnb': { + const { register } = await import('@bitgo/sdk-coin-bnb'); + return this.cacheAndRegister(name, sdk, register); + } case 'bsv': case 'tbsv': { const { register } = await import('@bitgo/sdk-coin-bsv'); diff --git a/tsconfig.packages.json b/tsconfig.packages.json index 86a71062b8..5425f55958 100644 --- a/tsconfig.packages.json +++ b/tsconfig.packages.json @@ -52,6 +52,9 @@ { "path": "./modules/sdk-coin-bld" }, + { + "path": "./modules/sdk-coin-bnb" + }, { "path": "./modules/sdk-coin-bsc" },