diff --git a/CODEOWNERS b/CODEOWNERS index 22b934f710..be1087656b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -61,6 +61,7 @@ /modules/sdk-coin-eos/ @BitGo/ethalt-team /modules/sdk-coin-ethlike/ @BitGo/ethalt-team /modules/sdk-coin-hbar/ @BitGo/ethalt-team +/modules/sdk-coin-icp/ @BitGo/ethalt-team /modules/sdk-coin-near/ @BitGo/ethalt-team /modules/sdk-coin-oas/ @BitGo/ethalt-team /modules/sdk-coin-opeth/ @BitGo/ethalt-team diff --git a/Dockerfile b/Dockerfile index f0a34b5020..8e09e8223d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,6 +76,7 @@ COPY --from=builder /tmp/bitgo/modules/sdk-coin-etc /var/modules/sdk-coin-etc/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-eth2 /var/modules/sdk-coin-eth2/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-hash /var/modules/sdk-coin-hash/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-hbar /var/modules/sdk-coin-hbar/ +COPY --from=builder /tmp/bitgo/modules/sdk-coin-icp /var/modules/sdk-coin-icp/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-injective /var/modules/sdk-coin-injective/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-islm /var/modules/sdk-coin-islm/ COPY --from=builder /tmp/bitgo/modules/sdk-coin-near /var/modules/sdk-coin-near/ diff --git a/modules/account-lib/package.json b/modules/account-lib/package.json index 094ef672e8..7a16a11d42 100644 --- a/modules/account-lib/package.json +++ b/modules/account-lib/package.json @@ -46,6 +46,7 @@ "@bitgo/sdk-coin-eth2": "^3.0.58", "@bitgo/sdk-coin-hash": "^3.0.28", "@bitgo/sdk-coin-hbar": "^2.0.59", + "@bitgo/sdk-coin-icp": "^1.0.0", "@bitgo/sdk-coin-injective": "^3.0.28", "@bitgo/sdk-coin-islm": "^2.1.9", "@bitgo/sdk-coin-near": "^2.0.59", diff --git a/modules/account-lib/src/index.ts b/modules/account-lib/src/index.ts index 6172ff6705..22f86229b6 100644 --- a/modules/account-lib/src/index.ts +++ b/modules/account-lib/src/index.ts @@ -143,6 +143,9 @@ export { Coredao }; import * as Apt from '@bitgo/sdk-coin-apt'; export { Apt }; +import * as Icp from '@bitgo/sdk-coin-icp'; +export { Icp }; + const coinBuilderMap = { trx: Trx.WrappedBuilder, ttrx: Trx.WrappedBuilder, @@ -219,6 +222,8 @@ const coinBuilderMap = { tcoredao: Coredao.TransactionBuilder, apt: Apt.TransactionBuilder, tapt: Apt.TransactionBuilder, + icp: Icp.TransactionBuilder, + ticp: Icp.TransactionBuilder, }; /** diff --git a/modules/account-lib/tsconfig.json b/modules/account-lib/tsconfig.json index fb4428fb79..e752ecdf70 100644 --- a/modules/account-lib/tsconfig.json +++ b/modules/account-lib/tsconfig.json @@ -61,6 +61,9 @@ { "path": "../sdk-coin-hbar" }, + { + "path": "../sdk-coin-icp" + }, { "path": "../sdk-coin-injective" }, diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index 92c4139ae7..707673f6a0 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -79,6 +79,7 @@ "@bitgo/sdk-coin-ethw": "^20.0.59", "@bitgo/sdk-coin-hash": "^3.0.28", "@bitgo/sdk-coin-hbar": "^2.0.59", + "@bitgo/sdk-coin-icp": "^1.0.0", "@bitgo/sdk-coin-injective": "^3.0.28", "@bitgo/sdk-coin-islm": "^2.1.9", "@bitgo/sdk-coin-lnbtc": "^1.1.37", diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index 26d364cd66..dfe7da2148 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -53,6 +53,7 @@ import { Hash, Hbar, Hteth, + Icp, Injective, Islm, Lnbtc, @@ -109,6 +110,7 @@ import { Thash, Thbar, Tia, + Ticp, Tinjective, Tislm, Tlnbtc, @@ -184,6 +186,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('hteth', Hteth.createInstance); globalCoinFactory.register('lnbtc', Lnbtc.createInstance); globalCoinFactory.register('ltc', Ltc.createInstance); + globalCoinFactory.register('icp', Icp.createInstance); globalCoinFactory.register('injective', Injective.createInstance); globalCoinFactory.register('islm', Islm.createInstance); globalCoinFactory.register('near', Near.createInstance); @@ -235,6 +238,7 @@ function registerCoinConstructors(globalCoinFactory: CoinFactory): void { globalCoinFactory.register('tfiatusd', TfiatUsd.createInstance); globalCoinFactory.register('thash', Thash.createInstance); globalCoinFactory.register('thbar', Thbar.createInstance); + globalCoinFactory.register('ticp', Ticp.createInstance); globalCoinFactory.register('tinjective', Tinjective.createInstance); globalCoinFactory.register('tislm', Tislm.createInstance); globalCoinFactory.register('tlnbtc', Tlnbtc.createInstance); diff --git a/modules/bitgo/src/v2/coins/index.ts b/modules/bitgo/src/v2/coins/index.ts index a748856d83..15ee419899 100644 --- a/modules/bitgo/src/v2/coins/index.ts +++ b/modules/bitgo/src/v2/coins/index.ts @@ -30,6 +30,7 @@ import { Ethw } from '@bitgo/sdk-coin-ethw'; import { EthLikeCoin, TethLikeCoin } from '@bitgo/sdk-coin-ethlike'; import { Hash, Thash } from '@bitgo/sdk-coin-hash'; import { Hbar, Thbar } from '@bitgo/sdk-coin-hbar'; +import { Icp, Ticp } from '@bitgo/sdk-coin-icp'; import { Injective, Tinjective } from '@bitgo/sdk-coin-injective'; import { Islm, Tislm } from '@bitgo/sdk-coin-islm'; import { Lnbtc, Tlnbtc } from '@bitgo/sdk-coin-lnbtc'; @@ -86,6 +87,7 @@ export { EthLikeCoin, TethLikeCoin }; export { Etc, Tetc }; export { Hash, Thash }; export { Hbar, Thbar }; +export { Icp, Ticp }; export { Lnbtc, Tlnbtc }; export { Ltc, Tltc }; export { Oas, Toas }; diff --git a/modules/bitgo/tsconfig.json b/modules/bitgo/tsconfig.json index d453639acf..39f8776e39 100644 --- a/modules/bitgo/tsconfig.json +++ b/modules/bitgo/tsconfig.json @@ -153,6 +153,9 @@ { "path": "../sdk-coin-hbar" }, + { + "path": "../sdk-coin-icp" + }, { "path": "../sdk-coin-injective" }, diff --git a/modules/sdk-coin-icp/.eslintignore b/modules/sdk-coin-icp/.eslintignore new file mode 100644 index 0000000000..700344c937 --- /dev/null +++ b/modules/sdk-coin-icp/.eslintignore @@ -0,0 +1,4 @@ +node_modules +.idea +public +dist \ No newline at end of file diff --git a/modules/sdk-coin-icp/.gitignore b/modules/sdk-coin-icp/.gitignore new file mode 100644 index 0000000000..bea316eb65 --- /dev/null +++ b/modules/sdk-coin-icp/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.idea/ +dist/ \ No newline at end of file diff --git a/modules/sdk-coin-icp/.mocharc.yml b/modules/sdk-coin-icp/.mocharc.yml new file mode 100644 index 0000000000..0ef74cc9fe --- /dev/null +++ b/modules/sdk-coin-icp/.mocharc.yml @@ -0,0 +1,8 @@ +require: 'ts-node/register' +timeout: 120000 +reporter: 'min' +reporter-option: + - 'cdn=true' + - 'json=false' +exit: true +spec: ['test/unit/**/*.ts'] diff --git a/modules/sdk-coin-icp/.npmignore b/modules/sdk-coin-icp/.npmignore new file mode 100644 index 0000000000..5f137fdc9e --- /dev/null +++ b/modules/sdk-coin-icp/.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 \ No newline at end of file diff --git a/modules/sdk-coin-icp/.prettierignore b/modules/sdk-coin-icp/.prettierignore new file mode 100644 index 0000000000..4ae675ed76 --- /dev/null +++ b/modules/sdk-coin-icp/.prettierignore @@ -0,0 +1,2 @@ +.nyc_output/ +dist/ \ No newline at end of file diff --git a/modules/sdk-coin-icp/.prettierrc.yml b/modules/sdk-coin-icp/.prettierrc.yml new file mode 100644 index 0000000000..7c3d8dd32a --- /dev/null +++ b/modules/sdk-coin-icp/.prettierrc.yml @@ -0,0 +1,3 @@ +printWidth: 120 +singleQuote: true +trailingComma: 'es5' diff --git a/modules/sdk-coin-icp/README.md b/modules/sdk-coin-icp/README.md new file mode 100644 index 0000000000..db68510cd5 --- /dev/null +++ b/modules/sdk-coin-icp/README.md @@ -0,0 +1,30 @@ +# BitGo sdk-coin-icp + +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-icp`. + +```shell +npm i @bitgo/sdk-api @bitgo/sdk-coin-icp +``` + +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 { Icp } from '@bitgo/sdk-coin-icp'; + +const sdk = new BitGoAPI(); + +sdk.register('icp', Icp.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-icp/package.json b/modules/sdk-coin-icp/package.json new file mode 100644 index 0000000000..d7221b498c --- /dev/null +++ b/modules/sdk-coin-icp/package.json @@ -0,0 +1,50 @@ +{ + "name": "@bitgo/sdk-coin-icp", + "version": "1.0.0", + "description": "BitGo SDK coin library for Internet Computer", + "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-icp" + }, + "lint-staged": { + "*.{js,ts}": [ + "yarn prettier --write", + "yarn eslint --fix" + ] + }, + "publishConfig": { + "access": "public" + }, + "nyc": { + "extension": [ + ".ts" + ] + }, + "dependencies": { + "@bitgo/sdk-core": "^28.19.0", + "@bitgo/statics": "^50.18.0" + }, + "devDependencies": { + "@bitgo/sdk-api": "^1.58.0", + "@bitgo/sdk-test": "^8.0.63" + } +} diff --git a/modules/sdk-coin-icp/src/icp.ts b/modules/sdk-coin-icp/src/icp.ts new file mode 100644 index 0000000000..d99fe604bf --- /dev/null +++ b/modules/sdk-coin-icp/src/icp.ts @@ -0,0 +1,92 @@ +import { + BaseCoin, + BitGoBase, + MPCAlgorithm, + VerifyTransactionOptions, + TssVerifyAddressOptions, + ParseTransactionOptions, + ParsedTransaction, + KeyPair, + SignTransactionOptions, + SignedTransaction, +} from '@bitgo/sdk-core'; +import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics'; + +export class Icp extends BaseCoin { + protected readonly _staticsCoin: Readonly; + protected constructor(bitgo: BitGoBase, staticsCoin?: Readonly) { + super(bitgo); + + if (!staticsCoin) { + throw new Error('missing required constructor parameter staticsCoin'); + } + + this._staticsCoin = staticsCoin; + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Icp(bitgo, staticsCoin); + } + + getChain(): string { + return 'icp'; + } + + getBaseChain(): string { + return 'icp'; + } + + getFamily(): string { + return 'icp'; + } + + getFullName(): string { + return 'Internet Computer'; + } + + getBaseFactor(): number { + return Math.pow(10, this._staticsCoin.decimalPlaces); + } + + async verifyTransaction(params: VerifyTransactionOptions): Promise { + return true; + } + + async isWalletAddress(params: TssVerifyAddressOptions): Promise { + return true; + } + + async parseTransaction(params: ParseTransactionOptions): Promise { + return {}; + } + + generateKeyPair(seed?: Buffer): KeyPair { + throw new Error('Method not implemented.'); + } + + isValidAddress(address: string): boolean { + throw new Error('Method not implemented.'); + } + + signTransaction(_: SignTransactionOptions): Promise { + throw new Error('Method not implemented.'); + } + + isValidPub(_: string): boolean { + throw new Error('Method not implemented.'); + } + + isValidPrv(_: string): boolean { + throw new Error('Method not implemented.'); + } + + /** @inheritDoc */ + supportsTss(): boolean { + return true; + } + + /** @inheritDoc */ + getMPCAlgorithm(): MPCAlgorithm { + return 'ecdsa'; + } +} diff --git a/modules/sdk-coin-icp/src/index.ts b/modules/sdk-coin-icp/src/index.ts new file mode 100644 index 0000000000..8886584c96 --- /dev/null +++ b/modules/sdk-coin-icp/src/index.ts @@ -0,0 +1,4 @@ +export * from './lib'; +export * from './icp'; +export * from './ticp'; +export * from './register'; diff --git a/modules/sdk-coin-icp/src/lib/index.ts b/modules/sdk-coin-icp/src/lib/index.ts new file mode 100644 index 0000000000..838a26ae4e --- /dev/null +++ b/modules/sdk-coin-icp/src/lib/index.ts @@ -0,0 +1,5 @@ +import * as Utils from './utils'; + +export { TransactionBuilder } from './transactionBuilder'; +export { TransferBuilder } from './transferBuilder'; +export { Utils }; diff --git a/modules/sdk-coin-icp/src/lib/transactionBuilder.ts b/modules/sdk-coin-icp/src/lib/transactionBuilder.ts new file mode 100644 index 0000000000..3a167ca39d --- /dev/null +++ b/modules/sdk-coin-icp/src/lib/transactionBuilder.ts @@ -0,0 +1,97 @@ +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { + BaseKey, + BaseTransaction, + PublicKey as BasePublicKey, + BaseTransactionBuilder, + BaseAddress, + Recipient, +} from '@bitgo/sdk-core'; +import { TransferBuilder } from './transferBuilder'; + +export abstract class TransactionBuilder extends BaseTransactionBuilder { + protected _transfer: TransferBuilder; + + protected constructor(_coinConfig: Readonly) { + super(_coinConfig); + } + + /** @inheritdoc */ + protected signImplementation(key: BaseKey): BaseTransaction { + throw new Error('method not implemented'); + } + + /** + * add a signature to the transaction + */ + addSignature(publicKey: BasePublicKey, signature: Buffer): void { + throw new Error('method not implemented'); + } + + /** + * Sets the sender of this transaction. + */ + sender(senderAddress: string): this { + throw new Error('method not implemented'); + } + + /** + * gets the gas data of this transaction. + */ + gasData(): this { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + validateAddress(address: BaseAddress, addressFormat?: string): void { + throw new Error('method not implemented'); + } + + /** + * validates the recipients of the transaction + */ + validateRecipients(recipients: Recipient[]): void { + throw new Error('method not implemented'); + } + + /** + * validates the gas data of the transaction + */ + validateGasData(): void { + throw new Error('method not implemented'); + } + + /** + * validates the gas price of the transaction + */ + validateGasPrice(gasPrice: number): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + validateKey(key: BaseKey): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + validateRawTransaction(rawTransaction: string): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + validateValue(): void { + throw new Error('method not implemented'); + } + + /** + * Validates the specific transaction builder internally + */ + validateDecodedTransaction(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + validateTransaction(): void { + throw new Error('method not implemented'); + } +} diff --git a/modules/sdk-coin-icp/src/lib/transactionBuilderFactory.ts b/modules/sdk-coin-icp/src/lib/transactionBuilderFactory.ts new file mode 100644 index 0000000000..c971054b91 --- /dev/null +++ b/modules/sdk-coin-icp/src/lib/transactionBuilderFactory.ts @@ -0,0 +1,50 @@ +import { BaseTransactionBuilderFactory } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; + +export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { + constructor(_coinConfig: Readonly) { + super(_coinConfig); + } + + /** @inheritdoc */ + from(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getTransferBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getStakingBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getUnstakingBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getCustomTransactionBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getTokenTransferBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + getWalletInitializationBuilder(): void { + throw new Error('method not implemented'); + } + + /** + * Parse the transaction from a raw transaction + */ + private parseTransaction(rawTransaction: string): void { + throw new Error('method not implemented'); + } +} diff --git a/modules/sdk-coin-icp/src/lib/transferBuilder.ts b/modules/sdk-coin-icp/src/lib/transferBuilder.ts new file mode 100644 index 0000000000..87dc3c05cc --- /dev/null +++ b/modules/sdk-coin-icp/src/lib/transferBuilder.ts @@ -0,0 +1,74 @@ +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { TransactionBuilder } from './transactionBuilder'; +import { BaseKey, Recipient, TransactionType, BaseTransaction } from '@bitgo/sdk-core'; + +export class TransferBuilder extends TransactionBuilder { + protected _recipients: Recipient[]; + + constructor(_coinConfig: Readonly) { + super(_coinConfig); + } + + protected get transactionType(): TransactionType { + return TransactionType.Send; + } + + send(recipients: Recipient[]): this { + this.validateRecipients(recipients); + this._recipients = recipients; + return this; + } + + /** @inheritdoc */ + validateTransaction(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + sign(key: BaseKey): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + protected async buildImplementation(): Promise { + throw new Error('method not implemented'); + } + + /** + * Initialize the transaction builder fields using the decoded transaction data + */ + initBuilder(): void { + throw new Error('method not implemented'); + } + + /** + * Validates all fields are defined + */ + private validateTransactionFields(): void { + throw new Error('method not implemented'); + } + + /** + * Build transfer programmable transaction + * + * @protected + */ + protected buildIcpTransaction(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + TransactionBuilder(): void { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + fromImplementation(): BaseTransaction { + throw new Error('method not implemented'); + } + + /** @inheritdoc */ + get transaction(): BaseTransaction { + throw new Error('method not implemented'); + } +} diff --git a/modules/sdk-coin-icp/src/lib/utils.ts b/modules/sdk-coin-icp/src/lib/utils.ts new file mode 100644 index 0000000000..2f4a177e6b --- /dev/null +++ b/modules/sdk-coin-icp/src/lib/utils.ts @@ -0,0 +1,22 @@ +import { BaseUtils } from '@bitgo/sdk-core'; + +export class Utils implements BaseUtils { + isValidAddress(address: string): boolean { + throw new Error('Method not implemented.'); + } + isValidTransactionId(txId: string): boolean { + throw new Error('Method not implemented.'); + } + isValidPublicKey(key: string): boolean { + throw new Error('Method not implemented.'); + } + isValidPrivateKey(key: string): boolean { + throw new Error('Method not implemented.'); + } + isValidSignature(signature: string): boolean { + throw new Error('Method not implemented.'); + } + isValidBlockId(hash: string): boolean { + throw new Error('Method not implemented.'); + } +} diff --git a/modules/sdk-coin-icp/src/register.ts b/modules/sdk-coin-icp/src/register.ts new file mode 100644 index 0000000000..f914d5b0ef --- /dev/null +++ b/modules/sdk-coin-icp/src/register.ts @@ -0,0 +1,8 @@ +import { BitGoBase } from '@bitgo/sdk-core'; +import { Icp } from './icp'; +import { Ticp } from './ticp'; + +export const register = (sdk: BitGoBase): void => { + sdk.register('icp', Icp.createInstance); + sdk.register('ticp', Ticp.createInstance); +}; diff --git a/modules/sdk-coin-icp/src/ticp.ts b/modules/sdk-coin-icp/src/ticp.ts new file mode 100644 index 0000000000..ce2bb5e30e --- /dev/null +++ b/modules/sdk-coin-icp/src/ticp.ts @@ -0,0 +1,55 @@ +/** + * Testnet Icp + * + * @format + */ +import { BaseCoin, BitGoBase } from '@bitgo/sdk-core'; +import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics'; +import { Icp } from './icp'; + +export class Ticp extends Icp { + 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; + } + + static createInstance(bitgo: BitGoBase, staticsCoin?: Readonly): BaseCoin { + return new Ticp(bitgo, staticsCoin); + } + + /** + * Identifier for the blockchain which supports this coin + */ + public getChain(): string { + return 'ticp'; + } + + /** + * Identifier for the blockchain family + */ + getFamily(): string { + return 'ticp'; + } + + getBaseFactor(): number { + return Math.pow(10, this._staticsCoin.decimalPlaces); + } + + /** @inheritDoc */ + supportsTss(): boolean { + return true; + } + + /** + * Complete human-readable name of this coin + */ + public getFullName(): string { + return 'testnet internet computer'; + } +} diff --git a/modules/sdk-coin-icp/test/unit/icp.ts b/modules/sdk-coin-icp/test/unit/icp.ts new file mode 100644 index 0000000000..45d9d5cf25 --- /dev/null +++ b/modules/sdk-coin-icp/test/unit/icp.ts @@ -0,0 +1,33 @@ +import 'should'; + +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { BitGoAPI } from '@bitgo/sdk-api'; + +import { Icp, Ticp } from '../../src/index'; + +const bitgo: TestBitGoAPI = TestBitGo.decorate(BitGoAPI, { env: 'test' }); + +describe('Icp', function () { + before(function () { + bitgo.safeRegister('icp', Icp.createInstance); + bitgo.safeRegister('ticp', Ticp.createInstance); + bitgo.initializeTestVars(); + }); + + it('should return the right info', function () { + const icp = bitgo.coin('icp'); + const ticp = bitgo.coin('ticp'); + + icp.getChain().should.equal('icp'); + icp.getFamily().should.equal('icp'); + icp.getFullName().should.equal('Internet Computer'); + icp.getBaseFactor().should.equal(1e8); + icp.supportsTss().should.equal(true); + + ticp.getChain().should.equal('ticp'); + ticp.getFamily().should.equal('ticp'); + ticp.getFullName().should.equal('testnet internet computer'); + ticp.getBaseFactor().should.equal(1e8); + icp.supportsTss().should.equal(true); + }); +}); diff --git a/modules/sdk-coin-icp/tsconfig.json b/modules/sdk-coin-icp/tsconfig.json new file mode 100644 index 0000000000..64aeea134a --- /dev/null +++ b/modules/sdk-coin-icp/tsconfig.json @@ -0,0 +1,26 @@ +{ + "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": "../statics" + }, + { + "path": "../sdk-test" + } + ] +} diff --git a/tsconfig.packages.json b/tsconfig.packages.json index b202994e99..4419a7c178 100644 --- a/tsconfig.packages.json +++ b/tsconfig.packages.json @@ -127,6 +127,9 @@ { "path": "./modules/sdk-coin-hbar" }, + { + "path": "./modules/sdk-coin-icp" + }, { "path": "./modules/sdk-coin-injective" },