diff --git a/Dockerfile b/Dockerfile index fa00d92582..6e92c59cbd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,8 +47,8 @@ COPY --from=builder /tmp/bitgo/modules/utxo-lib /var/modules/utxo-lib/ COPY --from=builder /tmp/bitgo/modules/blake2b /var/modules/blake2b/ COPY --from=builder /tmp/bitgo/modules/blake2b-wasm /var/modules/blake2b-wasm/ COPY --from=builder /tmp/bitgo/modules/bitgo /var/modules/bitgo/ -COPY --from=builder /tmp/bitgo/modules/abstract-utxo /var/modules/abstract-utxo/ COPY --from=builder /tmp/bitgo/modules/abstract-lightning /var/modules/abstract-lightning/ +COPY --from=builder /tmp/bitgo/modules/abstract-utxo /var/modules/abstract-utxo/ COPY --from=builder /tmp/bitgo/modules/blockapis /var/modules/blockapis/ COPY --from=builder /tmp/bitgo/modules/sdk-api /var/modules/sdk-api/ COPY --from=builder /tmp/bitgo/modules/unspents /var/modules/unspents/ @@ -101,6 +101,7 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-doge /var/modules/sdk-coin-doge/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-eos /var/modules/sdk-coin-eos/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-ethlike /var/modules/sdk-coin-ethlike/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-ethw /var/modules/sdk-coin-ethw/ +COPY --from=builder /tmp/bitgo/modules/sdk-coin-lnbtc /var/modules/sdk-coin-lnbtc/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-ltc /var/modules/sdk-coin-ltc/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-xlm /var/modules/sdk-coin-xlm/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-xrp /var/modules/sdk-coin-xrp/ @@ -115,8 +116,8 @@ cd /var/modules/utxo-lib && yarn link && \ cd /var/modules/blake2b && yarn link && \ cd /var/modules/blake2b-wasm && yarn link && \ cd /var/modules/bitgo && yarn link && \ -cd /var/modules/abstract-utxo && yarn link && \ cd /var/modules/abstract-lightning && yarn link && \ +cd /var/modules/abstract-utxo && yarn link && \ cd /var/modules/blockapis && yarn link && \ cd /var/modules/sdk-api && yarn link && \ cd /var/modules/unspents && yarn link && \ @@ -169,6 +170,7 @@ cd /var/modules/sdk-coin-doge && yarn link && \ cd /var/modules/sdk-coin-eos && yarn link && \ cd /var/modules/sdk-coin-ethlike && yarn link && \ cd /var/modules/sdk-coin-ethw && yarn link && \ +cd /var/modules/sdk-coin-lnbtc && yarn link && \ cd /var/modules/sdk-coin-ltc && yarn link && \ cd /var/modules/sdk-coin-xlm && yarn link && \ cd /var/modules/sdk-coin-xrp && yarn link && \ @@ -186,8 +188,8 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/blake2b && \ yarn link @bitgo/blake2b-wasm && \ yarn link bitgo && \ - yarn link @bitgo/abstract-utxo && \ yarn link @bitgo/abstract-lightning && \ + yarn link @bitgo/abstract-utxo && \ yarn link @bitgo/blockapis && \ yarn link @bitgo/sdk-api && \ yarn link @bitgo/unspents && \ @@ -240,6 +242,7 @@ RUN cd /var/bitgo-express && \ yarn link @bitgo/sdk-coin-eos && \ yarn link @bitgo/sdk-coin-ethlike && \ yarn link @bitgo/sdk-coin-ethw && \ + yarn link @bitgo/sdk-coin-lnbtc && \ yarn link @bitgo/sdk-coin-ltc && \ yarn link @bitgo/sdk-coin-xlm && \ yarn link @bitgo/sdk-coin-xrp && \ @@ -247,9 +250,9 @@ RUN cd /var/bitgo-express && \ #LINK_END #LABEL_START -LABEL created="Thu, 20 Jun 2024 08:36:08 GMT" +LABEL created="Fri, 21 Jun 2024 09:29:22 GMT" LABEL version=10.0.1 -LABEL git_hash=43ca8bc9facbe84d6dbf8cd6dc25da59a35aaf03 +LABEL git_hash=fde27b27726a42da00e57f4afaece82460737eec #LABEL_END USER node diff --git a/modules/abstract-lightning/package.json b/modules/abstract-lightning/package.json index 68e3757659..3c3f362eb4 100644 --- a/modules/abstract-lightning/package.json +++ b/modules/abstract-lightning/package.json @@ -37,6 +37,7 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^27.1.0" + "@bitgo/sdk-core": "^27.1.0", + "@bitgo/utxo-lib": "^9.38.0" } } diff --git a/modules/abstract-lightning/src/abstractLightningCoin.ts b/modules/abstract-lightning/src/abstractLightningCoin.ts index 311f72355b..c2ef02af42 100644 --- a/modules/abstract-lightning/src/abstractLightningCoin.ts +++ b/modules/abstract-lightning/src/abstractLightningCoin.ts @@ -9,10 +9,13 @@ import { VerifyAddressOptions, VerifyTransactionOptions, } from '@bitgo/sdk-core'; +import * as utxolib from '@bitgo/utxo-lib'; export abstract class AbstractLightningCoin extends BaseCoin { - protected constructor(bitgo: BitGoBase) { + private readonly _network: utxolib.Network; + protected constructor(bitgo: BitGoBase, network: utxolib.Network) { super(bitgo); + this._network = network; } getBaseFactor(): number { diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index ca21b77339..482e3da5ba 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -44,8 +44,8 @@ "gen-docs": "typedoc" }, "dependencies": { - "@bitgo/abstract-utxo": "^8.7.0", "@bitgo/abstract-lightning": "^1.0.0", + "@bitgo/abstract-utxo": "^8.7.0", "@bitgo/account-lib": "^23.0.19", "@bitgo/blockapis": "^1.9.5", "@bitgo/sdk-api": "^1.49.0", @@ -79,6 +79,7 @@ "@bitgo/sdk-coin-hbar": "^2.0.19", "@bitgo/sdk-coin-injective": "^2.0.19", "@bitgo/sdk-coin-islm": "^2.0.19", + "@bitgo/sdk-coin-lnbtc": "^1.0.0", "@bitgo/sdk-coin-ltc": "^3.0.19", "@bitgo/sdk-coin-near": "^2.0.19", "@bitgo/sdk-coin-opeth": "^18.1.4", diff --git a/modules/bitgo/src/v2/coins/index.ts b/modules/bitgo/src/v2/coins/index.ts index 8aa8029cc9..d994999d34 100644 --- a/modules/bitgo/src/v2/coins/index.ts +++ b/modules/bitgo/src/v2/coins/index.ts @@ -30,6 +30,7 @@ import { Hash, Thash } from '@bitgo/sdk-coin-hash'; import { Hbar, Thbar } from '@bitgo/sdk-coin-hbar'; import { Injective, Tinjective } from '@bitgo/sdk-coin-injective'; import { Islm, Tislm } from '@bitgo/sdk-coin-islm'; +import { Lnbtc, Tlnbtc } from '@bitgo/sdk-coin-lnbtc'; import { Ltc, Tltc } from '@bitgo/sdk-coin-ltc'; import { Opeth, Topeth, OpethToken } from '@bitgo/sdk-coin-opeth'; import { Osmo, Tosmo } from '@bitgo/sdk-coin-osmo'; @@ -78,6 +79,7 @@ export { EthLikeCoin, TethLikeCoin }; export { Etc, Tetc }; export { Hash, Thash }; export { Hbar, Thbar }; +export { Lnbtc, Tlnbtc }; export { Ltc, Tltc }; export { Opeth, Topeth, OpethToken }; export { Osmo, Tosmo }; diff --git a/modules/bitgo/tsconfig.json b/modules/bitgo/tsconfig.json index 0127629f73..02b22b9832 100644 --- a/modules/bitgo/tsconfig.json +++ b/modules/bitgo/tsconfig.json @@ -30,10 +30,10 @@ "path": "../abstract-eth" }, { - "path": "../abstract-utxo" + "path": "../abstract-lightning" }, { - "path": "../abstract-lightning" + "path": "../abstract-utxo" }, { "path": "../sdk-api" @@ -128,6 +128,9 @@ { "path": "../sdk-coin-islm" }, + { + "path": "../sdk-coin-lnbtc" + }, { "path": "../sdk-coin-ltc" }, diff --git a/modules/sdk-coin-lnbtc/.eslintignore b/modules/sdk-coin-lnbtc/.eslintignore new file mode 100644 index 0000000000..190f83e0df --- /dev/null +++ b/modules/sdk-coin-lnbtc/.eslintignore @@ -0,0 +1,5 @@ +node_modules +.idea +public +dist + diff --git a/modules/sdk-coin-lnbtc/.gitignore b/modules/sdk-coin-lnbtc/.gitignore new file mode 100644 index 0000000000..67ccce4c64 --- /dev/null +++ b/modules/sdk-coin-lnbtc/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.idea/ +dist/ diff --git a/modules/sdk-coin-lnbtc/.mocharc.yml b/modules/sdk-coin-lnbtc/.mocharc.yml new file mode 100644 index 0000000000..95814796d1 --- /dev/null +++ b/modules/sdk-coin-lnbtc/.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-lnbtc/.npmignore b/modules/sdk-coin-lnbtc/.npmignore new file mode 100644 index 0000000000..d5fb3a098c --- /dev/null +++ b/modules/sdk-coin-lnbtc/.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-lnbtc/.prettierignore b/modules/sdk-coin-lnbtc/.prettierignore new file mode 100644 index 0000000000..3a11d6af29 --- /dev/null +++ b/modules/sdk-coin-lnbtc/.prettierignore @@ -0,0 +1,2 @@ +.nyc_output/ +dist/ diff --git a/modules/sdk-coin-lnbtc/.prettierrc.yml b/modules/sdk-coin-lnbtc/.prettierrc.yml new file mode 100644 index 0000000000..7c3d8dd32a --- /dev/null +++ b/modules/sdk-coin-lnbtc/.prettierrc.yml @@ -0,0 +1,3 @@ +printWidth: 120 +singleQuote: true +trailingComma: 'es5' diff --git a/modules/sdk-coin-lnbtc/README.md b/modules/sdk-coin-lnbtc/README.md new file mode 100644 index 0000000000..1e0ade2137 --- /dev/null +++ b/modules/sdk-coin-lnbtc/README.md @@ -0,0 +1,30 @@ +# BitGo sdk-coin-lnbtc + +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-lnbtc`. + +```shell +npm i @bitgo/sdk-api @bitgo/sdk-coin-lnbtc +``` + +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 { Lnbtc } from '@bitgo/sdk-coin-lnbtc'; + +const sdk = new BitGoAPI(); + +sdk.register('lnbtc', Lnbtc.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-lnbtc/package.json b/modules/sdk-coin-lnbtc/package.json new file mode 100644 index 0000000000..7f2306e3b2 --- /dev/null +++ b/modules/sdk-coin-lnbtc/package.json @@ -0,0 +1,51 @@ +{ + "name": "@bitgo/sdk-coin-lnbtc", + "version": "1.0.0", + "description": "BitGo SDK coin library for LightningBitcoin", + "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-lnbtc" + }, + "lint-staged": { + "*.{js,ts}": [ + "yarn prettier --write", + "yarn eslint --fix" + ] + }, + "publishConfig": { + "access": "public" + }, + "nyc": { + "extension": [ + ".ts" + ] + }, + "dependencies": { + "@bitgo/abstract-lightning": "^1.0.0", + "@bitgo/sdk-core": "^27.1.0", + "@bitgo/utxo-lib": "^9.38.0" + }, + "devDependencies": { + "@bitgo/sdk-api": "^1.49.0", + "@bitgo/sdk-test": "^8.0.24" + } +} diff --git a/modules/sdk-coin-lnbtc/src/index.ts b/modules/sdk-coin-lnbtc/src/index.ts new file mode 100644 index 0000000000..c29a33077c --- /dev/null +++ b/modules/sdk-coin-lnbtc/src/index.ts @@ -0,0 +1,2 @@ +export * from './lnbtc'; +export * from './tlnbtc'; diff --git a/modules/sdk-coin-lnbtc/src/lnbtc.ts b/modules/sdk-coin-lnbtc/src/lnbtc.ts new file mode 100644 index 0000000000..bae1e3630b --- /dev/null +++ b/modules/sdk-coin-lnbtc/src/lnbtc.ts @@ -0,0 +1,25 @@ +import { AbstractLightningCoin } from '@bitgo/abstract-lightning'; +import { BitGoBase, BaseCoin } from '@bitgo/sdk-core'; +import * as utxolib from '@bitgo/utxo-lib'; + +export class Lnbtc extends AbstractLightningCoin { + constructor(bitgo: BitGoBase, network?: utxolib.Network) { + super(bitgo, network || utxolib.networks.bitcoin); + } + + static createInstance(bitgo: BitGoBase): BaseCoin { + return new Lnbtc(bitgo); + } + + getChain(): string { + return 'lnbtc'; + } + + getFamily(): string { + return 'lnbtc'; + } + + getFullName(): string { + return 'LightningBitcoin'; + } +} diff --git a/modules/sdk-coin-lnbtc/src/tlnbtc.ts b/modules/sdk-coin-lnbtc/src/tlnbtc.ts new file mode 100644 index 0000000000..c9118554f6 --- /dev/null +++ b/modules/sdk-coin-lnbtc/src/tlnbtc.ts @@ -0,0 +1,24 @@ +/** + * @prettier + */ +import { BaseCoin, BitGoBase } from '@bitgo/sdk-core'; +import { Lnbtc } from './lnbtc'; +import * as utxolib from '@bitgo/utxo-lib'; + +export class Tlnbtc extends Lnbtc { + constructor(bitgo: BitGoBase) { + super(bitgo, utxolib.networks.testnet); + } + + static createInstance(bitgo: BitGoBase): BaseCoin { + return new Tlnbtc(bitgo); + } + + getChain(): string { + return 'tlnbtc'; + } + + getFullName(): string { + return 'Testnet LightningBitcoin'; + } +} diff --git a/modules/sdk-coin-lnbtc/test/unit/index.ts b/modules/sdk-coin-lnbtc/test/unit/index.ts new file mode 100644 index 0000000000..f3ed90d35d --- /dev/null +++ b/modules/sdk-coin-lnbtc/test/unit/index.ts @@ -0,0 +1,26 @@ +import 'should'; + +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { BitGoAPI } from '@bitgo/sdk-api'; + +import { Tlnbtc } from '../../src/index'; + +describe('LightningBitcoin', function () { + let bitgo: TestBitGoAPI; + let basecoin: Tlnbtc; + + before(function () { + bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' }); + bitgo.safeRegister('tlnbtc', Tlnbtc.createInstance); + bitgo.initializeTestVars(); + basecoin = bitgo.coin('tlnbtc') as Tlnbtc; + }); + + it('should instantiate the coin', function () { + basecoin.should.be.an.instanceof(Tlnbtc); + }); + + it('should return full name', function () { + basecoin.getFullName().should.equal('Testnet LightningBitcoin'); + }); +}); diff --git a/modules/sdk-coin-lnbtc/tsconfig.json b/modules/sdk-coin-lnbtc/tsconfig.json new file mode 100644 index 0000000000..c6a9d7a1b0 --- /dev/null +++ b/modules/sdk-coin-lnbtc/tsconfig.json @@ -0,0 +1,29 @@ +{ + "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-lightning" + }, + { + "path": "../sdk-api" + }, + { + "path": "../sdk-core" + }, + { + "path": "../sdk-test" + }, + { + "path": "../utxo-lib" + } + ] +} diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index 8b99216c2b..41376d40a0 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -52,6 +52,7 @@ export enum CoinFamily { INJECTIVE = 'injective', ISLM = 'islm', KAVA = 'kava', + LNBTC = 'lnbtc', LTC = 'ltc', POLYGON = 'polygon', NEAR = 'near', @@ -128,6 +129,12 @@ export enum CoinFeature { * These are typically Bitcoin and forks of it, such as Litecoin and Bitcoin Cash. */ UNSPENT_MODEL = 'unspent-model', + /* + * Does this coin align with the Lightning Network model? + * + * These are typically Lightning Network on unspent model coins, such as BTC and LBTC. + */ + LIGHTNING_MODEL = 'lightning-model', /* * Does this coin align with the account model? * @@ -318,6 +325,7 @@ export enum UnderlyingAsset { INJECTIVE = 'injective', ISLM = 'islm', KAVA = 'kava', + LNBTC = 'lnbtc', LTC = 'ltc', NEAR = 'near', OPETH = 'opeth', @@ -1962,6 +1970,7 @@ export enum BaseUnit { SOL = 'lamport', ADA = 'lovelace', USD = 'USD', + LNBTC = 'millisatoshi', LTC = 'microlitecoins', DASH = 'duff', ZEC = 'zatoshi', @@ -2010,6 +2019,9 @@ export abstract class BaseCoin { /* Display properties */ + /** + * random uuid for a coin + */ public readonly id: string; public readonly fullName: string; public readonly name: string; diff --git a/modules/statics/src/coins.ts b/modules/statics/src/coins.ts index 05735a3a63..433d89e056 100644 --- a/modules/statics/src/coins.ts +++ b/modules/statics/src/coins.ts @@ -64,6 +64,7 @@ import { tofcPolygonErc20, } from './ofc'; import { utxoCoins } from './utxo'; +import { lightningCoins } from './lightning'; const ETH_FEATURES = [...AccountCoin.DEFAULT_FEATURES, CoinFeature.SUPPORTS_TOKENS, CoinFeature.ENTERPRISE_PAYS_FEES]; const ETH_FEATURES_WITH_MMI = [...ETH_FEATURES, CoinFeature.METAMASK_INSTITUTIONAL]; @@ -272,6 +273,7 @@ const ZKETH_FEATURES = [ CoinFeature.USES_NON_PACKED_ENCODING_FOR_TXDATA, ]; export const coins = CoinMap.fromCoins([ + ...lightningCoins, ...utxoCoins, avaxp( '5436386e-9e4d-4d82-92df-59d9720d1738', diff --git a/modules/statics/src/index.ts b/modules/statics/src/index.ts index 12f19ee0be..b77b9472a0 100644 --- a/modules/statics/src/index.ts +++ b/modules/statics/src/index.ts @@ -5,6 +5,7 @@ export * from './errors'; export * from './tokenConfig'; export { OfcCoin } from './ofc'; export { UtxoCoin } from './utxo'; +export { LightningCoin } from './lightning'; export { AccountCoin, CeloCoin, diff --git a/modules/statics/src/lightning.ts b/modules/statics/src/lightning.ts new file mode 100644 index 0000000000..9cba1a9eb9 --- /dev/null +++ b/modules/statics/src/lightning.ts @@ -0,0 +1,108 @@ +import { BaseCoin, BaseUnit, CoinFeature, CoinKind, KeyCurve, UnderlyingAsset } from './base'; +import { LightningNetwork, Networks } from './networks'; + +interface LightningConstructorOptions { + id: string; + fullName: string; + name: string; + network: LightningNetwork; + features: CoinFeature[]; + asset: UnderlyingAsset; + baseUnit: BaseUnit; + prefix?: string; + suffix?: string; + primaryKeyCurve: KeyCurve; +} + +export class LightningCoin extends BaseCoin { + public static readonly DEFAULT_FEATURES = [CoinFeature.LIGHTNING_MODEL]; + + /** + * Additional fields for lightning coins + */ + public readonly network: LightningNetwork; + + constructor(options: LightningConstructorOptions) { + super({ + ...options, + kind: CoinKind.CRYPTO, + isToken: false, + decimalPlaces: 11, + }); + + this.network = options.network; + } + + protected disallowedFeatures(): Set { + return new Set([CoinFeature.ACCOUNT_MODEL]); + } + + protected requiredFeatures(): Set { + return new Set([CoinFeature.LIGHTNING_MODEL]); + } +} + +/** + * Factory function for lightning coin instances. + * + * @param id uuid v4 of the coin + * @param name unique identifier of the coin + * @param fullName Complete human-readable name of the coin + * @param network Network object for this coin + * @param asset Asset which this coin represents. This is the same for both mainnet and testnet variants of a coin. + * @param features? Features of this coin. Defaults to the DEFAULT_FEATURES defined in `LightningCoin` + * @param prefix? Optional coin prefix. Defaults to empty string + * @param suffix? Optional coin suffix. Defaults to coin name. + * @param primaryKeyCurve The elliptic curve for this chain/token + */ +export function lightning( + id: string, + name: string, + fullName: string, + network: LightningNetwork, + asset: UnderlyingAsset, + baseUnit: BaseUnit, + features: CoinFeature[] = LightningCoin.DEFAULT_FEATURES, + prefix = '', + suffix: string = name.toUpperCase(), + /** All Lightnings BitGo supports are SECP256K1 **/ + primaryKeyCurve: KeyCurve = KeyCurve.Secp256k1 +) { + return Object.freeze( + new LightningCoin({ + id, + name, + fullName, + network, + prefix, + suffix, + features, + asset, + primaryKeyCurve, + baseUnit, + }) + ); +} + +const LNBTC_FEATURES = [...LightningCoin.DEFAULT_FEATURES]; + +export const lightningCoins: Readonly[] = [ + lightning( + '051aab40-efbc-4f58-9506-14cc95369e0a', + 'lnbtc', + 'LightningBitcoin', + Networks.main.lnbtc, + UnderlyingAsset.LNBTC, + BaseUnit.LNBTC, + LNBTC_FEATURES + ), + lightning( + '3cbabaa7-a063-4db3-b3a8-ea8cc38033e5', + 'tlnbtc', + 'Testnet LightningBitcoin', + Networks.test.lnbtc, + UnderlyingAsset.LNBTC, + BaseUnit.LNBTC, + LNBTC_FEATURES + ), +]; diff --git a/modules/statics/src/networks.ts b/modules/statics/src/networks.ts index 8a1cebe7ee..694d693b1d 100644 --- a/modules/statics/src/networks.ts +++ b/modules/statics/src/networks.ts @@ -17,6 +17,11 @@ export interface UtxoNetwork extends BaseNetwork { utxolibName: string; } +export interface LightningNetwork extends BaseNetwork { + // Network name as defined in @bitgo/utxo-lib networks.ts + utxolibName: string; +} + export interface AdaNetwork extends BaseNetwork { // Network name as defined in @bitgo/utxo-lib networks.ts // maybe add network identifier / magic network number @@ -258,6 +263,20 @@ class BinanceSmartChainTestnet extends Testnet implements EthereumNetwork { chainId = 97; } +class LightningBitcoin extends Mainnet implements LightningNetwork { + name = 'LightningBitcoin'; + family = CoinFamily.LNBTC; + utxolibName = 'bitcoin'; + explorerUrl = 'https://mempool.space/lightning'; +} + +class LightningBitcoinTestnet extends Testnet implements LightningNetwork { + name = 'TestnetLightningBitcoin'; + family = CoinFamily.LNBTC; + utxolibName = 'bitcoin'; + explorerUrl = 'https://mempool.space/lightning'; +} + class Bitcoin extends Mainnet implements UtxoNetwork { name = 'Bitcoin'; family = CoinFamily.BTC; @@ -1039,6 +1058,7 @@ export const Networks = { injective: Object.freeze(new Injective()), islm: Object.freeze(new Islm()), kava: Object.freeze(new Kava()), + lnbtc: Object.freeze(new LightningBitcoin()), litecoin: Object.freeze(new Litecoin()), polygon: Object.freeze(new Polygon()), ofc: Object.freeze(new Ofc()), @@ -1094,6 +1114,7 @@ export const Networks = { kovan: Object.freeze(new Kovan()), goerli: Object.freeze(new Goerli()), holesky: Object.freeze(new Holesky()), + lnbtc: Object.freeze(new LightningBitcoinTestnet()), litecoin: Object.freeze(new LitecoinTestnet()), polygon: Object.freeze(new PolygonTestnet()), ofc: Object.freeze(new OfcTestnet()), diff --git a/modules/statics/test/unit/coins.ts b/modules/statics/test/unit/coins.ts index 0a3f6b5da7..cf0e2bc222 100644 --- a/modules/statics/test/unit/coins.ts +++ b/modules/statics/test/unit/coins.ts @@ -333,8 +333,9 @@ coins.forEach((coin, coinName) => { }); } else { it('should return true for CUSTODY and CUSTODY_BITGO_TRUST coin feature', () => { - coin.features.includes(CoinFeature.CUSTODY).should.eql(true); - coin.features.includes(CoinFeature.CUSTODY_BITGO_TRUST).should.eql(true); + const coinSupportsCustody = coin.family !== CoinFamily.LNBTC; + coin.features.includes(CoinFeature.CUSTODY).should.eql(coinSupportsCustody); + coin.features.includes(CoinFeature.CUSTODY_BITGO_TRUST).should.eql(coinSupportsCustody); }); it('should return false for all non-SD coin feature', () => { diff --git a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts index 6425dd78ff..4b301732bb 100644 --- a/modules/statics/test/unit/fixtures/expectedColdFeatures.ts +++ b/modules/statics/test/unit/fixtures/expectedColdFeatures.ts @@ -99,6 +99,7 @@ export const expectedColdFeatures = { 'fiateur', 'fiatgbp', 'fiatusd', + 'lnbtc', 'susd', 'tbaseeth', 'tbtg', @@ -106,6 +107,7 @@ export const expectedColdFeatures = { 'tfiateur', 'tfiatgbp', 'tfiatusd', + 'tlnbtc', 'tsusd', ], }; diff --git a/tsconfig.packages.json b/tsconfig.packages.json index 20f3895ad1..184b95fa40 100644 --- a/tsconfig.packages.json +++ b/tsconfig.packages.json @@ -8,10 +8,10 @@ "path": "./modules/abstract-eth" }, { - "path": "./modules/abstract-utxo" + "path": "./modules/abstract-lightning" }, { - "path": "./modules/abstract-lightning" + "path": "./modules/abstract-utxo" }, { "path": "./modules/account-lib" @@ -124,6 +124,9 @@ { "path": "./modules/sdk-coin-islm" }, + { + "path": "./modules/sdk-coin-lnbtc" + }, { "path": "./modules/sdk-coin-ltc" },