From 34f8c8f97306265764f303f66b37dc022919c4a5 Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Wed, 10 Sep 2025 15:38:36 -0400 Subject: [PATCH 01/35] feat(express): migrate signpayload to typed routes TICKET: WP-5443 --- modules/express/src/clientRoutes.ts | 23 +++++-------- modules/express/src/typedRoutes/api/index.ts | 4 +++ .../src/typedRoutes/api/v2/ofcSignPayload.ts | 31 +++++++++++++++++ .../express/test/unit/typedRoutes/decode.ts | 33 +++++++++++++++++++ 4 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 362969f4f6..8dd6e6c87b 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -597,10 +597,10 @@ export async function handleV2OFCSignPayloadInExtSigningMode( } } -export async function handleV2OFCSignPayload(req: express.Request): Promise<{ payload: string; signature: string }> { - const walletId = req.body.walletId; - const payload = req.body.payload; - const bodyWalletPassphrase = req.body.walletPassphrase; +export async function handleV2OFCSignPayload( + req: ExpressApiRouteRequest<'express.ofc.signPayload', 'post'> +): Promise<{ payload: string; signature: string }> { + const { walletId, payload, walletPassphrase: bodyWalletPassphrase } = req.decoded; const ofcCoinName = 'ofc'; // If the externalSignerUrl is set, forward the request to the express server hosted on the externalSignerUrl @@ -619,14 +619,6 @@ export async function handleV2OFCSignPayload(req: express.Request): Promise<{ pa return payloadWithSignature; } - if (!payload) { - throw new ApiResponseError('Missing required field: payload', 400); - } - - if (!walletId) { - throw new ApiResponseError('Missing required field: walletId', 400); - } - const bitgo = req.bitgo; // This is to set us up for multiple trading accounts per enterprise @@ -638,7 +630,7 @@ export async function handleV2OFCSignPayload(req: express.Request): Promise<{ pa const walletPassphrase = bodyWalletPassphrase || getWalletPwFromEnv(wallet.id()); const tradingAccount = wallet.toTradingAccount(); - const stringifiedPayload = JSON.stringify(req.body.payload); + const stringifiedPayload = JSON.stringify(payload); const signature = await tradingAccount.signPayload({ payload: stringifiedPayload, walletPassphrase, @@ -1566,6 +1558,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { router.post('express.decrypt', [prepareBitGo(config), typedPromiseWrapper(handleDecrypt)]); router.post('express.encrypt', [prepareBitGo(config), typedPromiseWrapper(handleEncrypt)]); router.post('express.verifyaddress', [prepareBitGo(config), typedPromiseWrapper(handleVerifyAddress)]); + router.post('express.ofc.signPayload', [prepareBitGo(config), typedPromiseWrapper(handleV2OFCSignPayload)]); app.post( '/api/v[12]/calculateminerfeeinfo', parseBody, @@ -1649,8 +1642,8 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { promiseWrapper(handleV2AcceptWalletShare) ); - // sign arbitrary payloads w/ trading account key - app.post(`/api/v2/ofc/signPayload`, parseBody, prepareBitGo(config), promiseWrapper(handleV2OFCSignPayload)); + // sign arbitrary payloads w/ trading account key (migrated to typed route express.ofc.signPayload) + // app.post(`/api/v2/ofc/signPayload`, parseBody, prepareBitGo(config), promiseWrapper(handleV2OFCSignPayload)); // sign transaction app.post('/api/v2/:coin/signtx', parseBody, prepareBitGo(config), promiseWrapper(handleV2SignTx)); diff --git a/modules/express/src/typedRoutes/api/index.ts b/modules/express/src/typedRoutes/api/index.ts index 4a45375e0d..06ca632c52 100644 --- a/modules/express/src/typedRoutes/api/index.ts +++ b/modules/express/src/typedRoutes/api/index.ts @@ -12,6 +12,7 @@ import { PostAcceptShare } from './v1/acceptShare'; import { PostSimpleCreate } from './v1/simpleCreate'; import { PutPendingApproval } from './v1/pendingApproval'; import { PostSignTransaction } from './v1/signTransaction'; +import { PostOfcSignPayload } from './v2/ofcSignPayload'; export const ExpressApi = apiSpec({ 'express.ping': { @@ -44,6 +45,9 @@ export const ExpressApi = apiSpec({ 'express.v1.wallet.signTransaction': { post: PostSignTransaction, }, + 'express.ofc.signPayload': { + post: PostOfcSignPayload, + }, }); export type ExpressApi = typeof ExpressApi; diff --git a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts new file mode 100644 index 0000000000..f80fcb3328 --- /dev/null +++ b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts @@ -0,0 +1,31 @@ +import * as t from 'io-ts'; +import { Json, NonEmptyString } from 'io-ts-types'; +import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; + +/** + * Sign an arbitrary payload using an OFC trading account key. + * @operationId express.ofc.signPayload + * POST /api/v2/ofc/signPayload + */ +export const OfcSignPayloadBody = { + walletId: NonEmptyString, + payload: Json, + walletPassphrase: optional(t.string), +}; + +/** + * Request body for signing an arbitrary payload with an OFC wallet key. + * @property walletId – non-empty string identifying the OFC wallet + * @property payload – JSON value to sign + * @property walletPassphrase – optional passphrase used to decrypt the user key (string) + */ +export const PostOfcSignPayload = httpRoute({ + path: '/api/v2/ofc/signPayload', + method: 'POST', + request: httpRequest({ body: OfcSignPayloadBody }), + response: { + 200: t.type({ payload: t.string, signature: t.string }), + }, +}); + +export type PostOfcSignPayload = typeof PostOfcSignPayload; diff --git a/modules/express/test/unit/typedRoutes/decode.ts b/modules/express/test/unit/typedRoutes/decode.ts index 57641f6338..70302cac0b 100644 --- a/modules/express/test/unit/typedRoutes/decode.ts +++ b/modules/express/test/unit/typedRoutes/decode.ts @@ -5,6 +5,7 @@ import { EncryptRequestBody } from '../../../src/typedRoutes/api/common/encrypt' import { LoginRequest } from '../../../src/typedRoutes/api/common/login'; import { VerifyAddressBody } from '../../../src/typedRoutes/api/common/verifyAddress'; import { SimpleCreateRequestBody } from '../../../src/typedRoutes/api/v1/simpleCreate'; +import { OfcSignPayloadBody } from '../../../src/typedRoutes/api/v2/ofcSignPayload'; export function assertDecode(codec: t.Type, input: unknown): T { const result = codec.decode(input); @@ -92,6 +93,38 @@ describe('io-ts decode tests', function () { address: 'some-address', }); }); + it('express.ofc.signPayload', function () { + // missing walletId + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + payload: { a: 1 }, + }) + ); + // empty walletId + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + walletId: '', + payload: { a: 1 }, + }) + ); + // missing payload + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + }) + ); + // valid minimal + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + payload: { a: 1 }, + }); + // valid with nested and optional passphrase + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + payload: { nested: ['x', { y: true }] }, + walletPassphrase: 'secret', + }); + }); it('express.v1.wallet.simplecreate', function () { // passphrase is required assert.throws(() => assertDecode(t.type(SimpleCreateRequestBody), {})); From 075b35c8542860538411bcd5ebdc662be549850b Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Wed, 10 Sep 2025 17:50:36 -0400 Subject: [PATCH 02/35] refactor: code Added UT to test/unit/clientRoutes/signPayload.tsAlso it seems like this migration makes the UT for `Sign an arbitrary payload with trading account key` (ticket: https://bitgoinc.atlassian.net/browse/GO-1015) to pass. TICKET: WP-5443 --- modules/express/src/clientRoutes.ts | 3 -- .../src/typedRoutes/api/v2/ofcSignPayload.ts | 12 ++++++- .../test/unit/clientRoutes/signPayload.ts | 32 +++++++++++++------ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 8dd6e6c87b..546c12df0b 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -1642,9 +1642,6 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { promiseWrapper(handleV2AcceptWalletShare) ); - // sign arbitrary payloads w/ trading account key (migrated to typed route express.ofc.signPayload) - // app.post(`/api/v2/ofc/signPayload`, parseBody, prepareBitGo(config), promiseWrapper(handleV2OFCSignPayload)); - // sign transaction app.post('/api/v2/:coin/signtx', parseBody, prepareBitGo(config), promiseWrapper(handleV2SignTx)); app.post('/api/v2/:coin/wallet/:id/signtx', parseBody, prepareBitGo(config), promiseWrapper(handleV2SignTxWallet)); diff --git a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts index f80fcb3328..933aaed354 100644 --- a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts +++ b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts @@ -13,6 +13,16 @@ export const OfcSignPayloadBody = { walletPassphrase: optional(t.string), }; +/** + * Successful response body for signing an OFC payload. + * @property payload - The canonical string form of the JSON payload that was signed. Objects are JSON.stringify'ed. + * @property signature - Hex-encoded signature generated by the trading account key. + */ +export const OfcSignPayloadResponse = t.type({ + payload: t.string, + signature: t.string, +}); + /** * Request body for signing an arbitrary payload with an OFC wallet key. * @property walletId – non-empty string identifying the OFC wallet @@ -24,7 +34,7 @@ export const PostOfcSignPayload = httpRoute({ method: 'POST', request: httpRequest({ body: OfcSignPayloadBody }), response: { - 200: t.type({ payload: t.string, signature: t.string }), + 200: OfcSignPayloadResponse, }, }); diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index 8f06ada33b..dcd41c5066 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -8,6 +8,8 @@ import { BitGo, Coin, BaseCoin, Wallet, Wallets } from 'bitgo'; import '../../lib/asserts'; import { handleV2OFCSignPayload, handleV2OFCSignPayloadInExtSigningMode } from '../../../src/clientRoutes'; +import { ExpressApiRouteRequest } from '../../../src/typedRoutes/api'; +import { OfcSignPayloadResponse } from '../../../src/typedRoutes/api/v2/ofcSignPayload'; describe('Sign an arbitrary payload with trading account key', function () { const coin = 'ofc'; @@ -22,7 +24,7 @@ describe('Sign an arbitrary payload with trading account key', function () { const walletId = 'myWalletId'; const walletStub = sinon.createStubInstance(Wallet as any, { - id: walletId, + id: sinon.stub().returns(walletId), coin: sinon.stub().returns(coin), toTradingAccount: sinon.stub().returns({ signPayload: sinon.stub().returns(signature), @@ -42,24 +44,36 @@ describe('Sign an arbitrary payload with trading account key', function () { }); it('should return a signed payload', async function () { - // TODO(GO-1015): unskip test - return; - - // eslint-disable-next-line no-unreachable const expectedResponse = { payload: JSON.stringify(payload), signature, }; const req = { bitgo: bitGoStub, - body: { - payload, + decoded: { walletId, + payload, }, - query: {}, - } as unknown as Request; + } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); }); + + it('should decode handler response with OfcSignPayloadResponse codec', async function () { + const expected = { + payload: JSON.stringify(payload), + signature, + }; + const req = { + bitgo: bitGoStub, + decoded: { + walletId, + payload, + }, + } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; + const result = await handleV2OFCSignPayload(req); + result.should.eql(expected); + OfcSignPayloadResponse.is(result).should.be.true(); + }); }); describe('With the handler to sign an arbitrary payload in external signing mode', () => { From ad4507824caab11a69aa3e6ca6615859d4bcf2ca Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Wed, 10 Sep 2025 18:08:17 -0400 Subject: [PATCH 03/35] refactor: added dependency io-ts-type to package.json TICKET: WP-5443 --- modules/express/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/express/package.json b/modules/express/package.json index 9e05e08817..b6ae89dab0 100644 --- a/modules/express/package.json +++ b/modules/express/package.json @@ -51,6 +51,7 @@ "dotenv": "^16.0.0", "express": "4.21.2", "io-ts": "npm:@bitgo-forks/io-ts@2.1.4", + "io-ts-types": "^0.5.19", "lodash": "^4.17.20", "morgan": "^1.9.1", "proxy-agent": "6.4.0", From 2d51487ff45ddd08fb2d20e4532ebc1d03266e5a Mon Sep 17 00:00:00 2001 From: "asset-metadata-bot[bot]" <226385837+asset-metadata-bot[bot]@users.noreply.github.com> Date: Thu, 11 Sep 2025 13:33:01 +0000 Subject: [PATCH 04/35] feat: add new tokens for WIN-7171 --- modules/statics/src/coins/botTokens.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/statics/src/coins/botTokens.ts b/modules/statics/src/coins/botTokens.ts index fc6d69a6d9..54faef726f 100644 --- a/modules/statics/src/coins/botTokens.ts +++ b/modules/statics/src/coins/botTokens.ts @@ -1 +1,19 @@ -export const botTokens = []; +import { UnderlyingAsset } from '../base'; +import { networkFeatureMapForTokens } from '../networkFeatureMapForTokens'; +import { Networks } from '../networks'; +import * as AccountCtors from '../account'; + +export const botTokens = [ + AccountCtors.terc20( + '6430cc83-077f-4927-b7cf-222db880bb58', + 'hteth:ams', + 'AMS Token v2', + 1, + '0x8c7a17ef8e00f2f31cff598206d7fc5a8cb41111', + 'hteth:ams' as unknown as UnderlyingAsset, + networkFeatureMapForTokens['eth'], + undefined, + undefined, + Networks.test.hoodi + ), +]; From fd693d9725722400f98347a3aba113d39aabf1c6 Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Mon, 15 Sep 2025 15:09:18 -0400 Subject: [PATCH 05/35] feat(express): migrate keychainlocal to typed routes TICKET: WP-5414 --- modules/express/src/clientRoutes.ts | 7 +--- modules/express/src/typedRoutes/api/index.ts | 4 +++ .../src/typedRoutes/api/v2/keychainLocal.ts | 34 +++++++++++++++++++ .../express/test/unit/typedRoutes/decode.ts | 23 +++++++++++++ 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 modules/express/src/typedRoutes/api/v2/keychainLocal.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 362969f4f6..6f28106b73 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -1617,12 +1617,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { // API v2 // create keychain - app.post( - '/api/v2/:coin/keychain/local', - parseBody, - prepareBitGo(config), - promiseWrapper(handleV2CreateLocalKeyChain) - ); + router.post('express.keychain.local', [prepareBitGo(config), typedPromiseWrapper(handleV2CreateLocalKeyChain)]); // generate wallet app.post('/api/v2/:coin/wallet/generate', parseBody, prepareBitGo(config), promiseWrapper(handleV2GenerateWallet)); diff --git a/modules/express/src/typedRoutes/api/index.ts b/modules/express/src/typedRoutes/api/index.ts index 4a45375e0d..6953783ff6 100644 --- a/modules/express/src/typedRoutes/api/index.ts +++ b/modules/express/src/typedRoutes/api/index.ts @@ -12,6 +12,7 @@ import { PostAcceptShare } from './v1/acceptShare'; import { PostSimpleCreate } from './v1/simpleCreate'; import { PutPendingApproval } from './v1/pendingApproval'; import { PostSignTransaction } from './v1/signTransaction'; +import { PostKeychainLocal } from './v2/keychainLocal'; export const ExpressApi = apiSpec({ 'express.ping': { @@ -44,6 +45,9 @@ export const ExpressApi = apiSpec({ 'express.v1.wallet.signTransaction': { post: PostSignTransaction, }, + 'express.keychain.local': { + post: PostKeychainLocal, + }, }); export type ExpressApi = typeof ExpressApi; diff --git a/modules/express/src/typedRoutes/api/v2/keychainLocal.ts b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts new file mode 100644 index 0000000000..3dc78fd8f5 --- /dev/null +++ b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts @@ -0,0 +1,34 @@ +import * as t from 'io-ts'; +import { httpRoute, httpRequest } from '@api-ts/io-ts-http'; +import { BitgoExpressError } from '../../schemas/error'; + +/** + * @property {string} coin - Coin identifier (e.g. btc, tbtc, eth) + */ +export const KeychainLocalRequestParams = { + coin: t.string, +}; + +/** + * Local client-side function to create a new keychain. + * Creating your keychains is a critical step for safely securing your Bitcoin. When generating new keychains, this API uses a random number generator that adheres to industry standards. If you provide your own seed, you must take extreme caution when creating it. + * Returns an object containing the xprv and xpub for the new chain. The created keychain is not known to the BitGo service. To use it with the BitGo service, use the ‘Store Keychain’ API call. + * + * For security reasons, it is highly recommended that you encrypt and destroy the original xprv immediately to prevent theft. + * + * @operationId express.keychain.local + */ +export const PostKeychainLocal = httpRoute({ + path: '/api/v2/{coin}/keychain/local', + method: 'POST', + request: httpRequest({ + params: KeychainLocalRequestParams, + }), + response: { + 200: t.type({ + prv: t.string, + pub: t.string, + }), + 400: BitgoExpressError, + }, +}); diff --git a/modules/express/test/unit/typedRoutes/decode.ts b/modules/express/test/unit/typedRoutes/decode.ts index 57641f6338..ecd4c92047 100644 --- a/modules/express/test/unit/typedRoutes/decode.ts +++ b/modules/express/test/unit/typedRoutes/decode.ts @@ -5,6 +5,7 @@ import { EncryptRequestBody } from '../../../src/typedRoutes/api/common/encrypt' import { LoginRequest } from '../../../src/typedRoutes/api/common/login'; import { VerifyAddressBody } from '../../../src/typedRoutes/api/common/verifyAddress'; import { SimpleCreateRequestBody } from '../../../src/typedRoutes/api/v1/simpleCreate'; +import { KeychainLocalRequestParams } from '../../../src/typedRoutes/api/v2/keychainLocal'; export function assertDecode(codec: t.Type, input: unknown): T { const result = codec.decode(input); @@ -100,4 +101,26 @@ describe('io-ts decode tests', function () { passphrase: 'pass', }); }); + it('express.keychain.local', function () { + // coin parameter is required + assert.throws(() => assertDecode(t.type(KeychainLocalRequestParams), {})); + // coin must be a string + assert.throws(() => + assertDecode(t.type(KeychainLocalRequestParams), { + coin: 123, + }) + ); + // valid with coin parameter + assertDecode(t.type(KeychainLocalRequestParams), { + coin: 'btc', + }); + // valid with different coin + assertDecode(t.type(KeychainLocalRequestParams), { + coin: 'eth', + }); + // valid with testnet coin + assertDecode(t.type(KeychainLocalRequestParams), { + coin: 'tbtc', + }); + }); }); From 755f8eeca5aa845df967ec43396616cd3a599771 Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Thu, 18 Sep 2025 11:48:18 -0400 Subject: [PATCH 06/35] refactor: added docs and updated req type TICKET: WP-5414 --- modules/express/src/clientRoutes.ts | 2 +- .../src/typedRoutes/api/v2/keychainLocal.ts | 25 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index be41fb58da..371307c9a6 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -685,7 +685,7 @@ async function handleV2PendingApproval(req: express.Request): Promise { * create a keychain * @param req */ -function handleV2CreateLocalKeyChain(req: express.Request) { +function handleV2CreateLocalKeyChain(req: ExpressApiRouteRequest<'express.keychain.local', 'post'>) { const bitgo = req.bitgo; const coin = bitgo.coin(req.params.coin); return coin.keychains().create(req.body); diff --git a/modules/express/src/typedRoutes/api/v2/keychainLocal.ts b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts index 3dc78fd8f5..c527d7f1ee 100644 --- a/modules/express/src/typedRoutes/api/v2/keychainLocal.ts +++ b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts @@ -3,11 +3,26 @@ import { httpRoute, httpRequest } from '@api-ts/io-ts-http'; import { BitgoExpressError } from '../../schemas/error'; /** + * Request parameters for creating a local keychain * @property {string} coin - Coin identifier (e.g. btc, tbtc, eth) */ export const KeychainLocalRequestParams = { + /** Coin identifier (e.g. btc, tbtc, eth) */ coin: t.string, -}; +} as const; + +/** + * Response for creating a local keychain + */ +export const KeychainLocalResponse = { + /** Newly generated local keychain. */ + 200: t.type({ + prv: t.string, + pub: t.string, + }), + /** Invalid request or key generation fails. */ + 400: BitgoExpressError, +} as const; /** * Local client-side function to create a new keychain. @@ -24,11 +39,5 @@ export const PostKeychainLocal = httpRoute({ request: httpRequest({ params: KeychainLocalRequestParams, }), - response: { - 200: t.type({ - prv: t.string, - pub: t.string, - }), - 400: BitgoExpressError, - }, + response: KeychainLocalResponse, }); From 80a9c3e7e1f0e9bd9e0b5ef93f687d5748a2e9fe Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Fri, 19 Sep 2025 12:35:03 -0400 Subject: [PATCH 07/35] refactor: added express unit test for keychainLocal TICKET: WP-5414 --- modules/express/src/clientRoutes.ts | 2 +- .../src/typedRoutes/api/v2/keychainLocal.ts | 10 ++-- .../test/unit/clientRoutes/keychainLocal.ts | 60 +++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 modules/express/test/unit/clientRoutes/keychainLocal.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 371307c9a6..bf8ea15185 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -685,7 +685,7 @@ async function handleV2PendingApproval(req: express.Request): Promise { * create a keychain * @param req */ -function handleV2CreateLocalKeyChain(req: ExpressApiRouteRequest<'express.keychain.local', 'post'>) { +export function handleV2CreateLocalKeyChain(req: ExpressApiRouteRequest<'express.keychain.local', 'post'>) { const bitgo = req.bitgo; const coin = bitgo.coin(req.params.coin); return coin.keychains().create(req.body); diff --git a/modules/express/src/typedRoutes/api/v2/keychainLocal.ts b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts index c527d7f1ee..a903755057 100644 --- a/modules/express/src/typedRoutes/api/v2/keychainLocal.ts +++ b/modules/express/src/typedRoutes/api/v2/keychainLocal.ts @@ -11,15 +11,17 @@ export const KeychainLocalRequestParams = { coin: t.string, } as const; +export const KeychainLocalRequestResponse200 = t.type({ + prv: t.string, + pub: t.string, +}); + /** * Response for creating a local keychain */ export const KeychainLocalResponse = { /** Newly generated local keychain. */ - 200: t.type({ - prv: t.string, - pub: t.string, - }), + 200: KeychainLocalRequestResponse200, /** Invalid request or key generation fails. */ 400: BitgoExpressError, } as const; diff --git a/modules/express/test/unit/clientRoutes/keychainLocal.ts b/modules/express/test/unit/clientRoutes/keychainLocal.ts new file mode 100644 index 0000000000..b5a60faa2e --- /dev/null +++ b/modules/express/test/unit/clientRoutes/keychainLocal.ts @@ -0,0 +1,60 @@ +import * as sinon from 'sinon'; + +import 'should-http'; +import 'should-sinon'; +import '../../lib/asserts'; + +import nock from 'nock'; +import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test'; +import { BitGo } from 'bitgo'; +import { BaseCoin, decodeOrElse } from '@bitgo/sdk-core'; + +import { ExpressApiRouteRequest } from '../../../src/typedRoutes/api'; +import { handleV2CreateLocalKeyChain } from '../../../src/clientRoutes'; +import { KeychainLocalResponse } from '../../../src/typedRoutes/api/v2/keychainLocal'; + +describe('Create Local Keychain', () => { + let bitgo: TestBitGoAPI; + + before(async function () { + if (!nock.isActive()) { + nock.activate(); + } + + bitgo = TestBitGo.decorate(BitGo, { env: 'test' }); + bitgo.initializeTestVars(); + + nock.disableNetConnect(); + nock.enableNetConnect('127.0.0.1'); + }); + + after(() => { + if (nock.isActive()) { + nock.restore(); + } + }); + + it('should create a local keychain and return the keypair', async () => { + const createdKeypair = { prv: 'prv-example', pub: 'pub-example' }; + const keychainsInstance = { create: sinon.stub().returns(createdKeypair) } as const; + const coinStub = { + keychains: sinon.stub<[], typeof keychainsInstance>().returns(keychainsInstance), + } as unknown as BaseCoin; + const coinMethodStub = sinon.stub(bitgo, 'coin').returns(coinStub as any); + + const req = { + bitgo: bitgo, + params: { coin: 'tbtc' }, + body: {}, + } as unknown as ExpressApiRouteRequest<'express.keychain.local', 'post'>; + + const res = await handleV2CreateLocalKeyChain(req); + + decodeOrElse('KeychainLocalResponse200', KeychainLocalResponse[200], res, (errors) => { + throw new Error(`Response did not match expected codec: ${errors}`); + }); + + sinon.assert.calledOnce(keychainsInstance.create); + coinMethodStub.restore(); + }); +}); From 1423d8b7663c1890afc58995e6febbdec374e39d Mon Sep 17 00:00:00 2001 From: Parva Parikh Date: Thu, 18 Sep 2025 14:58:21 -0700 Subject: [PATCH 08/35] fix(express): signPayload API to handle stringified payload as req Ticket: GNA-2162 --- modules/express/src/clientRoutes.ts | 3 ++- modules/express/src/utils.ts | 8 +++++++ .../test/unit/clientRoutes/signPayload.ts | 22 ++++++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 modules/express/src/utils.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 9d75314bb6..dda4c50805 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -62,6 +62,7 @@ import { handleLightningWithdraw } from './lightning/lightningWithdrawRoutes'; import createExpressRouter from './typedRoutes'; import { ExpressApiRouteRequest } from './typedRoutes/api'; import { TypedRequestHandler, WrappedRequest, WrappedResponse } from '@api-ts/typed-express-router'; +import { isJsonString } from './utils'; const { version } = require('bitgo/package.json'); const pjson = require('../package.json'); @@ -630,7 +631,7 @@ export async function handleV2OFCSignPayload(req: express.Request): Promise<{ pa const walletPassphrase = bodyWalletPassphrase || getWalletPwFromEnv(wallet.id()); const tradingAccount = wallet.toTradingAccount(); - const stringifiedPayload = JSON.stringify(req.body.payload); + const stringifiedPayload = isJsonString(req.body.payload) ? req.body.payload : JSON.stringify(req.body.payload); const signature = await tradingAccount.signPayload({ payload: stringifiedPayload, walletPassphrase, diff --git a/modules/express/src/utils.ts b/modules/express/src/utils.ts new file mode 100644 index 0000000000..65160a9eb3 --- /dev/null +++ b/modules/express/src/utils.ts @@ -0,0 +1,8 @@ +export const isJsonString = (str: any): boolean => { + try { + JSON.parse(str); + return true; + } catch { + return false; + } +}; diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index 8f06ada33b..67a997f518 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -18,6 +18,7 @@ describe('Sign an arbitrary payload with trading account key', function () { }, }, }; + const stringifiedPayload = JSON.stringify(payload); const signature = 'signedPayload123'; const walletId = 'myWalletId'; @@ -41,11 +42,7 @@ describe('Sign an arbitrary payload with trading account key', function () { process.env['WALLET_myWalletId_PASSPHRASE'] = 'mypass'; }); - it('should return a signed payload', async function () { - // TODO(GO-1015): unskip test - return; - - // eslint-disable-next-line no-unreachable + it('should return a signed payload with type as object', async function () { const expectedResponse = { payload: JSON.stringify(payload), signature, @@ -60,6 +57,21 @@ describe('Sign an arbitrary payload with trading account key', function () { } as unknown as Request; await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); }); + it('should return a signed payload with type as json string', async function () { + const expectedResponse = { + payload: stringifiedPayload, + signature, + }; + const req = { + bitgo: bitGoStub, + body: { + payload: stringifiedPayload, + walletId, + }, + query: {}, + } as unknown as Request; + await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); + }); }); describe('With the handler to sign an arbitrary payload in external signing mode', () => { From 6faab4ce89b2753e7c189bbfda279351f4cacd00 Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Mon, 22 Sep 2025 18:21:01 -0400 Subject: [PATCH 09/35] refactor: fixed merge conflict error TICKET: WP-5414 --- modules/express/test/unit/typedRoutes/decode.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/express/test/unit/typedRoutes/decode.ts b/modules/express/test/unit/typedRoutes/decode.ts index cbbb32cd99..ccbf4ea02d 100644 --- a/modules/express/test/unit/typedRoutes/decode.ts +++ b/modules/express/test/unit/typedRoutes/decode.ts @@ -155,6 +155,7 @@ describe('io-ts decode tests', function () { assertDecode(t.type(KeychainLocalRequestParams), { coin: 'tbtc', }); + }); it('express.lightning.initWallet params', function () { // missing walletId assert.throws(() => assertDecode(t.type(LightningInitWalletParams), { coin: 'ltc' })); From 2640873bebfc19e46e4652361ec049f394523906 Mon Sep 17 00:00:00 2001 From: Krupananda Reddy Date: Tue, 23 Sep 2025 15:23:08 +0530 Subject: [PATCH 10/35] feat(sdk-coin-sol): onboarding sol 2022 token with transfer hook onboarding new sol 2022 standard token with transfer hook extension in tesnet Ticket: WIN-7258 --- modules/statics/src/base.ts | 2 ++ modules/statics/src/coins/solTokens.ts | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index 157687e8fe..f524a57f4e 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -1074,6 +1074,8 @@ export enum UnderlyingAsset { 'tsol:usdt' = 'tsol:usdt', 'tsol:srm' = 'tsol:srm', 'tsol:gari' = 'tsol:gari', + 'tsol:t22mint' = 'tsol:t22mint', + 'tsol:t1test' = 'tsol:t1test', GAS = 'gas', GATE = 'gate', GBPT = 'gbpt', diff --git a/modules/statics/src/coins/solTokens.ts b/modules/statics/src/coins/solTokens.ts index f0e60d5544..b7888810e2 100644 --- a/modules/statics/src/coins/solTokens.ts +++ b/modules/statics/src/coins/solTokens.ts @@ -3164,7 +3164,18 @@ export const solTokens = [ 9, '5NR1bQwLWqjbkhbQ1hx72HKJybbuvwkDnUZNoAZ2VhW6', '5NR1bQwLWqjbkhbQ1hx72HKJybbuvwkDnUZNoAZ2VhW6', - UnderlyingAsset['tsol:slnd'], + UnderlyingAsset['tsol:t22mint'], + SOL_TOKEN_FEATURES, + ProgramID.Token2022ProgramId + ), + tsolToken( + '50a59f79-033b-4bd0-aae1-49270f97cae2', + 'tsol:t1test', + 'T1TEST', + 9, + '3BW95VLH2za2eUQ1PGfjxwMbpsnDFnmkA7m5LDgMKbX7', + '3BW95VLH2za2eUQ1PGfjxwMbpsnDFnmkA7m5LDgMKbX7', + UnderlyingAsset['tsol:t1test'], SOL_TOKEN_FEATURES, ProgramID.Token2022ProgramId ), From 93eb7cad2f9f08283a4c1067d86c6f3dd1c0af30 Mon Sep 17 00:00:00 2001 From: Nayan Das Date: Tue, 23 Sep 2025 15:59:56 +0530 Subject: [PATCH 11/35] feat: gate tokens for BitGo Singapore TICKET: WIN-6923 --- modules/statics/src/allCoinsAndTokens.ts | 5 +++-- modules/statics/src/coinFeatures.ts | 3 +++ modules/statics/src/coins/bscTokens.ts | 2 +- modules/statics/src/coins/erc20Coins.ts | 9 ++++++--- modules/statics/src/coins/solTokens.ts | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index 16c8dc7f1a..bd572fc278 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -110,6 +110,7 @@ import { STX_FEATURES, SUI_FEATURES, SUI_TOKEN_FEATURES, + SUI_TOKEN_FEATURES_EXCLUDE_SINGAPORE, SUI_TOKEN_FEATURES_STAKING, TAO_FEATURES, TAO_TOKEN_FEATURES, @@ -4335,7 +4336,7 @@ export const allCoinsAndTokens = [ 'AFSUI', '0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc::afsui::AFSUI', UnderlyingAsset['sui:afsui'], - SUI_TOKEN_FEATURES.filter((feature) => feature !== CoinFeature.CUSTODY_BITGO_SINGAPORE) + SUI_TOKEN_FEATURES_EXCLUDE_SINGAPORE ), suiToken( 'af864118-e9ec-47b2-896c-735f0530fb8f', @@ -4431,7 +4432,7 @@ export const allCoinsAndTokens = [ 'ALKIMI', '0x1a8f4bc33f8ef7fbc851f156857aa65d397a6a6fd27a7ac2ca717b51f2fd9489::alkimi::ALKIMI', UnderlyingAsset['sui:alkimi'], - SUI_TOKEN_FEATURES + SUI_TOKEN_FEATURES_EXCLUDE_SINGAPORE ), tsuiToken( '0b8a7919-c37e-4be8-8338-7fc13c6c875e', diff --git a/modules/statics/src/coinFeatures.ts b/modules/statics/src/coinFeatures.ts index 08440c10dc..e9a3b917a2 100644 --- a/modules/statics/src/coinFeatures.ts +++ b/modules/statics/src/coinFeatures.ts @@ -361,6 +361,9 @@ export const SUI_TOKEN_FEATURES = [ CoinFeature.TSS_COLD, CoinFeature.BULK_TRANSACTION, ]; +export const SUI_TOKEN_FEATURES_EXCLUDE_SINGAPORE = SUI_TOKEN_FEATURES.filter( + (feature) => feature !== CoinFeature.CUSTODY_BITGO_SINGAPORE +); export const SUI_TOKEN_FEATURES_STAKING = [ ...SUI_TOKEN_FEATURES, CoinFeature.STAKING, diff --git a/modules/statics/src/coins/bscTokens.ts b/modules/statics/src/coins/bscTokens.ts index 5e6fd8c341..58e4c440d9 100644 --- a/modules/statics/src/coins/bscTokens.ts +++ b/modules/statics/src/coins/bscTokens.ts @@ -1309,7 +1309,7 @@ export const bscTokens = [ 6, '0xfc5a743271672e91d77f0176e5cea581fbd5d834', UnderlyingAsset['bsc:slay'], - BSC_TOKEN_FEATURES + BSC_TOKEN_FEATURES_EXCLUDE_SINGAPORE ), bscToken( 'de4424d5-b119-4220-899f-a48727c58a80', diff --git a/modules/statics/src/coins/erc20Coins.ts b/modules/statics/src/coins/erc20Coins.ts index 4cf43c6bac..e0c4cf4382 100644 --- a/modules/statics/src/coins/erc20Coins.ts +++ b/modules/statics/src/coins/erc20Coins.ts @@ -7799,7 +7799,8 @@ export const erc20Coins = [ 'GATENet', 18, '0x9d7630adf7ab0b0cb00af747db76864df0ec82e4', - UnderlyingAsset.GATE + UnderlyingAsset.GATE, + AccountCoin.DEFAULT_FEATURES_EXCLUDE_SINGAPORE ), erc20( 'e173c7c3-106b-4572-9c6c-e56c2f06c9c4', @@ -11534,7 +11535,8 @@ export const erc20Coins = [ 'Vision', 18, '0x699ccf919c1dfdfa4c374292f42cadc9899bf753', - UnderlyingAsset['eth:vsn'] + UnderlyingAsset['eth:vsn'], + AccountCoin.DEFAULT_FEATURES_EXCLUDE_SINGAPORE ), erc20( 'c51774c4-c9fd-4cfc-886e-36e084ce7b48', @@ -11550,7 +11552,8 @@ export const erc20Coins = [ 'SatLayer', 6, '0x51477a3002ee04b7542adfe63ccdb50c00ee5147', - UnderlyingAsset['eth:slay'] + UnderlyingAsset['eth:slay'], + AccountCoin.DEFAULT_FEATURES_EXCLUDE_SINGAPORE ), erc20( '0eb44459-7e38-4974-8847-e2fa8a510478', diff --git a/modules/statics/src/coins/solTokens.ts b/modules/statics/src/coins/solTokens.ts index f0e60d5544..848283744b 100644 --- a/modules/statics/src/coins/solTokens.ts +++ b/modules/statics/src/coins/solTokens.ts @@ -3035,7 +3035,7 @@ export const solTokens = [ 'DYNoyS3x5qgbccZg7RPXagm4xQzfnm5iwd9o8pMyJtdE', 'DYNoyS3x5qgbccZg7RPXagm4xQzfnm5iwd9o8pMyJtdE', UnderlyingAsset['sol:dynosol'], - SOL_TOKEN_FEATURES + SOL_TOKEN_FEATURES_EXCLUDE_SINGAPORE ), solToken( '51983e8f-8218-49d4-a2b4-6a6e6b147b36', From bf4ec32dd76e6c56e49889e3841656295e84421d Mon Sep 17 00:00:00 2001 From: Manas Ladha Date: Tue, 23 Sep 2025 16:02:36 +0530 Subject: [PATCH 12/35] fix: modify codeowners for ams token export files TICKET: WIN-7317 TICKET: WIN-7317 --- CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 27f994d64c..49f67187a7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -108,10 +108,6 @@ /modules/sdk-core/src/bitgo/address-book/ @BitGo/prime /modules/sdk-core/src/bitgo/trading/ @BitGo/prime -# Asset Metadata Service -/modules/statics/src/coins/botTokens.ts @BitGo/ams -/modules/statics/src/coins/botOfcTokens.ts @BitGo/ams - # Core Modules /modules/bitgo/ @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform /modules/bitgo/test/v2/unit/lightning/ @BitGo/btc-team @@ -140,6 +136,10 @@ /types/ @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform /webpack/ @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform +# Asset Metadata Service +/modules/statics/src/coins/botTokens.ts @BitGo/ams +/modules/statics/src/coins/botOfcTokens.ts @BitGo/ams + /.eslintrc.json @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform @BitGo/developer-experience /.prettierrc.yml @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform @BitGo/developer-experience /check-package-versions.js @BitGo/coins @BitGo/web-experience @BitGo/wallet-platform @BitGo/developer-experience From 2ac078c0336e7fab4e90846a104150bdfc93c9bc Mon Sep 17 00:00:00 2001 From: Paras Garg Date: Tue, 23 Sep 2025 17:13:44 +0530 Subject: [PATCH 13/35] feat: adding iota coin construction in coin factory Ticket: WIN-6873 TICKET: WIN-6873 --- modules/bitgo/src/v2/coinFactory.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index 7bd0f6cd49..41e46a7953 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -663,6 +663,8 @@ export function getCoinConstructor(coinName: string): CoinConstructor | undefine return Initia.createInstance; case 'injective': return Injective.createInstance; + case 'iota': + return Iota.createInstance; case 'islm': return Islm.createInstance; case 'near': @@ -789,6 +791,8 @@ export function getCoinConstructor(coinName: string): CoinConstructor | undefine return Tinitia.createInstance; case 'tinjective': return Tinjective.createInstance; + case 'tiota': + return Iota.createInstance; case 'tislm': return Tislm.createInstance; case 'tlnbtc': From e2befa7cca34f553e355e02450626ad6eee08f86 Mon Sep 17 00:00:00 2001 From: Parv Tiwari Date: Fri, 19 Sep 2025 19:14:13 +0530 Subject: [PATCH 14/35] feat: verify psbt withdraw lightning TICKET: BTC-2470 --- .../src/codecs/api/withdraw.ts | 8 + .../abstract-lightning/src/lightning/index.ts | 1 + .../src/lightning/parseWithdrawPsbt.ts | 145 ++++++++++++++++++ .../src/wallet/lightning.ts | 34 +++- 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 modules/abstract-lightning/src/lightning/parseWithdrawPsbt.ts diff --git a/modules/abstract-lightning/src/codecs/api/withdraw.ts b/modules/abstract-lightning/src/codecs/api/withdraw.ts index 96af50f76e..0e2e7662b6 100644 --- a/modules/abstract-lightning/src/codecs/api/withdraw.ts +++ b/modules/abstract-lightning/src/codecs/api/withdraw.ts @@ -1,6 +1,7 @@ import * as t from 'io-ts'; import { LightningOnchainRequest, optionalString } from '@bitgo/public-types'; import { PendingApprovalData, TxRequestState } from '@bitgo/sdk-core'; +import { Bip32Derivation } from 'bip174/src/lib/interfaces'; export const WithdrawStatusDelivered = 'delivered'; export const WithdrawStatusFailed = 'failed'; @@ -124,3 +125,10 @@ export const SendPsbtResponse = t.intersection( 'SendPsbtResponse' ); export type SendPsbtResponse = t.TypeOf; + +export type WithdrawBaseOutputUTXO = { + value: TNumber; + change: boolean; + address: string; + bip32Derivation?: Bip32Derivation; +}; diff --git a/modules/abstract-lightning/src/lightning/index.ts b/modules/abstract-lightning/src/lightning/index.ts index 77016d2dc5..770ebf103c 100644 --- a/modules/abstract-lightning/src/lightning/index.ts +++ b/modules/abstract-lightning/src/lightning/index.ts @@ -1,3 +1,4 @@ export * from './signableJson'; export * from './signature'; export * from './lightningUtils'; +export * from './parseWithdrawPsbt'; diff --git a/modules/abstract-lightning/src/lightning/parseWithdrawPsbt.ts b/modules/abstract-lightning/src/lightning/parseWithdrawPsbt.ts new file mode 100644 index 0000000000..857acbb25e --- /dev/null +++ b/modules/abstract-lightning/src/lightning/parseWithdrawPsbt.ts @@ -0,0 +1,145 @@ +import * as utxolib from '@bitgo/utxo-lib'; +import { Psbt } from '@bitgo/utxo-lib'; +import { WatchOnlyAccount, WithdrawBaseOutputUTXO } from '../codecs'; +import { LightningOnchainRecipient } from '@bitgo/public-types'; +import { Bip32Derivation } from 'bip174/src/lib/interfaces'; + +function parseDerivationPath(derivationPath: string): { + purpose: number; + change: number; + addressIndex: number; +} { + const pathSegments = derivationPath.split('/'); + const purpose = Number(pathSegments[1].replace(/'/g, '')); + const change = Number(pathSegments[pathSegments.length - 2]); + const addressIndex = Number(pathSegments[pathSegments.length - 1]); + return { purpose, change, addressIndex }; +} + +function parsePsbtOutputs(psbt: Psbt, network: utxolib.Network): WithdrawBaseOutputUTXO[] { + const parsedOutputs: WithdrawBaseOutputUTXO[] = []; + let bip32Derivation: Bip32Derivation | undefined; + + for (let i = 0; i < psbt.data.outputs.length; i++) { + const output = psbt.data.outputs[i]; + const txOutput = psbt.txOutputs[i]; + + let address = ''; + const value = txOutput.value; + let isChange = false; + + if (output.bip32Derivation && output.bip32Derivation.length > 0) { + isChange = true; + bip32Derivation = output.bip32Derivation[0]; + } + if (txOutput.script) { + address = utxolib.address.fromOutputScript(txOutput.script, network); + } + const valueBigInt = BigInt(value); + + parsedOutputs.push({ + address, + value: valueBigInt, + change: isChange, + bip32Derivation, + }); + } + + return parsedOutputs; +} + +function verifyChangeAddress( + output: WithdrawBaseOutputUTXO, + accounts: WatchOnlyAccount[], + network: utxolib.Network +): void { + if (!output.bip32Derivation || !output.bip32Derivation.path) { + throw new Error(`bip32Derivation path not found for change address`); + } + // derivation path example: m/84'/0'/0'/1/0 + const { purpose, change, addressIndex } = parseDerivationPath(output.bip32Derivation.path); + + // Find the corresponding account using the purpose + const account = accounts.find((acc) => acc.purpose === purpose); + if (!account) { + throw new Error(`Account not found for purpose: ${purpose}`); + } + + // Create a BIP32 node from the xpub + const xpubNode = utxolib.bip32.fromBase58(account.xpub, network); + + // Derive the public key from the xpub using the change and address index + const derivedPubkey = xpubNode.derive(change).derive(addressIndex).publicKey; + + if (derivedPubkey.toString('hex') !== output.bip32Derivation.pubkey.toString('hex')) { + throw new Error( + `Derived pubkey does not match for address: ${output.address}, derived: ${derivedPubkey.toString( + 'hex' + )}, expected: ${output.bip32Derivation.pubkey.toString('hex')}` + ); + } + + // Determine the correct payment type based on the purpose + let derivedAddress: string | undefined; + switch (purpose) { + case 49: // P2SH-P2WPKH (Nested SegWit) + derivedAddress = utxolib.payments.p2sh({ + redeem: utxolib.payments.p2wpkh({ + pubkey: derivedPubkey, + network, + }), + network, + }).address; + break; + case 84: // P2WPKH (Native SegWit) + derivedAddress = utxolib.payments.p2wpkh({ + pubkey: derivedPubkey, + network, + }).address; + break; + case 86: // P2TR (Taproot) + derivedAddress = utxolib.payments.p2tr({ + pubkey: derivedPubkey, + network, + }).address; + break; + default: + throw new Error(`Unsupported purpose: ${purpose}`); + } + + if (derivedAddress !== output.address) { + throw new Error(`invalid change address: expected ${derivedAddress}, got ${output.address}`); + } +} + +/** + * Validates the funded psbt before creating the signatures for withdraw. + */ +export function validatePsbtForWithdraw( + psbtHex: string, + network: utxolib.Network, + recipients: LightningOnchainRecipient[], + accounts: WatchOnlyAccount[] +): void { + const parsedPsbt = Psbt.fromHex(psbtHex, { network: network }); + const outputs = parsePsbtOutputs(parsedPsbt, network); + outputs.forEach((output) => { + if (output.change) { + try { + verifyChangeAddress(output, accounts, network); + } catch (e: any) { + throw new Error(`Unable to verify change address: ${e}`); + } + } else { + let match = false; + recipients.forEach((recipient) => { + if (recipient.address === output.address && BigInt(recipient.amountSat) === output.value) { + match = true; + } + }); + if (!match) { + throw new Error(`PSBT output ${output.address} with value ${output.value} does not match any recipient`); + } + } + }); +} diff --git a/modules/abstract-lightning/src/wallet/lightning.ts b/modules/abstract-lightning/src/wallet/lightning.ts index 1dd7840e4c..352916865c 100644 --- a/modules/abstract-lightning/src/wallet/lightning.ts +++ b/modules/abstract-lightning/src/wallet/lightning.ts @@ -10,7 +10,12 @@ import { decodeOrElse, } from '@bitgo/sdk-core'; import * as t from 'io-ts'; -import { createMessageSignature, unwrapLightningCoinSpecific } from '../lightning'; +import { + createMessageSignature, + getUtxolibNetwork, + unwrapLightningCoinSpecific, + validatePsbtForWithdraw, +} from '../lightning'; import { CreateInvoiceBody, Invoice, @@ -28,6 +33,7 @@ import { ListInvoicesResponse, ListPaymentsResponse, LndCreateWithdrawResponse, + WatchOnly, } from '../codecs'; import { LightningPaymentIntent, LightningPaymentRequest } from '@bitgo/public-types'; @@ -364,6 +370,32 @@ export class LightningWallet implements ILightningWallet { throw new Error(`serialized txHex is missing`); } + const walletData = this.wallet.toJSON(); + if (!walletData.coinSpecific.watchOnlyAccounts) { + throw new Error(`wallet is missing watch only accounts`); + } + + const watchOnlyAccountDetails = decodeOrElse( + WatchOnly.name, + WatchOnly, + walletData.coinSpecific.watchOnlyAccounts, + (errors) => { + throw new Error(`invalid watch only accounts, error: ${errors}`); + } + ); + const network = getUtxolibNetwork(this.wallet.coin()); + + try { + validatePsbtForWithdraw( + transactionRequestCreate.transactions[0].unsignedTx.serializedTxHex, + network, + params.recipients, + watchOnlyAccountDetails.accounts + ); + } catch (err: any) { + throw new Error(`error validating withdraw psbt: ${err}`); + } + const { userAuthKey } = await getLightningAuthKeychains(this.wallet); const userAuthKeyEncryptedPrv = userAuthKey.encryptedPrv; if (!userAuthKeyEncryptedPrv) { From aa745d8cb1521553667bb01bbf0f14693f11723c Mon Sep 17 00:00:00 2001 From: Parv Tiwari Date: Tue, 23 Sep 2025 18:43:59 +0530 Subject: [PATCH 15/35] test: withdraw lightning psbt verification tests TICKET: BTC-2470 --- .../test/unit/lightning/parseWithdrawPsbt.ts | 88 +++++++++++++++++++ .../v2/unit/lightning/lightningWallets.ts | 42 ++++++--- 2 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 modules/abstract-lightning/test/unit/lightning/parseWithdrawPsbt.ts diff --git a/modules/abstract-lightning/test/unit/lightning/parseWithdrawPsbt.ts b/modules/abstract-lightning/test/unit/lightning/parseWithdrawPsbt.ts new file mode 100644 index 0000000000..1a85d56948 --- /dev/null +++ b/modules/abstract-lightning/test/unit/lightning/parseWithdrawPsbt.ts @@ -0,0 +1,88 @@ +import { validatePsbtForWithdraw } from '../../../src'; +import * as utxolib from '@bitgo/utxo-lib'; +import assert from 'assert'; + +describe('parseWithdrawPsbt', () => { + const unsignedPsbtHex = + '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000'; + const network = utxolib.networks.testnet; + const recipients = [ + { + amountSat: 100000n, + address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k', + }, + ]; + const accounts = [ + { + xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA', + purpose: 49, + coin_type: 0, + account: 0, + }, + { + xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP', + purpose: 84, + coin_type: 0, + account: 0, + }, + ]; + it('should parse a valid withdraw PSBT', () => { + validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, accounts); + }); + it('should throw for invalid PSBT', () => { + assert.throws(() => { + validatePsbtForWithdraw('asdasd', network, recipients, accounts); + }, /ERR_BUFFER_OUT_OF_BOUNDS/); + }); + it('should throw for invalid recipient address', () => { + const differentRecipients = [ + { + ...recipients[0], + address: 'tb1qxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyzxyz', + }, + ]; + assert.throws(() => { + validatePsbtForWithdraw(unsignedPsbtHex, network, differentRecipients, accounts); + }, /PSBT output tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k with value 100000 does not match any recipient/); + }); + it('should throw for invalid recipient value', () => { + const differentRecipients = [ + { + ...recipients[0], + amountSat: 99999n, + }, + ]; + assert.throws(() => { + validatePsbtForWithdraw(unsignedPsbtHex, network, differentRecipients, accounts); + }, /PSBT output tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k with value 100000 does not match any recipient/); + }); + it('should throw for account not found', () => { + const incompatibleAccounts = []; + assert.throws(() => { + validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, incompatibleAccounts); + }, /Account not found for purpose/); + }); + it('should throw for invalid pubkey', () => { + const incompatibleAccounts = [ + { + ...accounts[1], + xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA', + }, + ]; + assert.throws(() => { + validatePsbtForWithdraw(unsignedPsbtHex, network, recipients, incompatibleAccounts); + }, /Derived pubkey does not match for address/); + }); + it('should throw for invalid purpose', () => { + const incompatibleAccounts = [ + { + ...accounts[1], + purpose: 1017, + }, + ]; + const incompatiblePsbt = `70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000f90300800000008000000080010000005000000000`; + assert.throws(() => { + validatePsbtForWithdraw(incompatiblePsbt, network, recipients, incompatibleAccounts); + }, /Unsupported purpose/); + }); +}); diff --git a/modules/bitgo/test/v2/unit/lightning/lightningWallets.ts b/modules/bitgo/test/v2/unit/lightning/lightningWallets.ts index 60587a17bc..b9cb1d070f 100644 --- a/modules/bitgo/test/v2/unit/lightning/lightningWallets.ts +++ b/modules/bitgo/test/v2/unit/lightning/lightningWallets.ts @@ -807,12 +807,30 @@ describe('Lightning wallets', function () { describe('On chain withdrawal', function () { let wallet: LightningWallet; beforeEach(function () { + const watchOnlyAccounts = { + master_key_birthday_timestamp: 'dummy', + master_key_fingerprint: 'dummy', + accounts: [ + { + xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA', + purpose: 49, + coin_type: 0, + account: 0, + }, + { + xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP', + purpose: 84, + coin_type: 0, + account: 0, + }, + ], + }; wallet = getLightningWallet( new Wallet(bitgo, basecoin, { id: 'walletId', coin: 'tlnbtc', subType: 'lightningCustody', - coinSpecific: { keys: ['def', 'ghi'] }, + coinSpecific: { keys: ['def', 'ghi'], watchOnlyAccounts }, }) ) as LightningWallet; }); @@ -820,13 +838,15 @@ describe('Lightning wallets', function () { const params: LightningOnchainWithdrawParams = { recipients: [ { - amountSat: 500000n, - address: 'bcrt1qjq48cqk2u80hewdcndf539m8nnnvt845nl68x7', + amountSat: 100000n, + address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k', }, ], satsPerVbyte: 15n, passphrase: 'password123', }; + const unsignedPsbtHex = + '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000'; const txRequestResponse = { txRequestId: 'txReq123', @@ -834,7 +854,7 @@ describe('Lightning wallets', function () { transactions: [ { unsignedTx: { - serializedTxHex: 'unsignedTx123', + serializedTxHex: unsignedPsbtHex, }, }, ], @@ -846,7 +866,7 @@ describe('Lightning wallets', function () { transactions: [ { unsignedTx: { - serializedTxHex: 'unsignedTx123', + serializedTxHex: unsignedPsbtHex, coinSpecific: { signature: 'someSignature', }, @@ -861,7 +881,7 @@ describe('Lightning wallets', function () { transactions: [ { unsignedTx: { - serializedTxHex: 'unsignedTx123', + serializedTxHex: unsignedPsbtHex, coinSpecific: { signature: 'someSignature', status: 'delivered', @@ -1008,13 +1028,15 @@ describe('Lightning wallets', function () { const params: LightningOnchainWithdrawParams = { recipients: [ { - amountSat: 500000n, - address: 'bcrt1qjq48cqk2u80hewdcndf539m8nnnvt845nl68x7', + amountSat: 100000n, + address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k', }, ], satsPerVbyte: 15n, passphrase: 'password123', }; + const unsignedPsbtHex = + '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000'; const txRequestResponse = { txRequestId: 'txReq123', @@ -1023,7 +1045,7 @@ describe('Lightning wallets', function () { transactions: [ { unsignedTx: { - serializedTxHex: 'unsignedTx123', + serializedTxHex: unsignedPsbtHex, }, }, ], @@ -1035,7 +1057,7 @@ describe('Lightning wallets', function () { transactions: [ { unsignedTx: { - serializedTxHex: 'unsignedTx123', + serializedTxHex: unsignedPsbtHex, coinSpecific: { signature: 'someSignature', }, From 6031d762c1b27e79a50c87e342a562297f8455ce Mon Sep 17 00:00:00 2001 From: Parv Tiwari Date: Tue, 23 Sep 2025 19:32:57 +0530 Subject: [PATCH 16/35] feat: added bip174 to abstract lightning TICKET: BTC-2470 --- modules/abstract-lightning/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/abstract-lightning/package.json b/modules/abstract-lightning/package.json index b5fbe506d5..a39a3938da 100644 --- a/modules/abstract-lightning/package.json +++ b/modules/abstract-lightning/package.json @@ -43,6 +43,7 @@ "@bitgo/sdk-core": "^36.8.0", "@bitgo/statics": "^57.8.0", "@bitgo/utxo-lib": "^11.10.0", + "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", "bs58check": "^2.1.2", "fp-ts": "^2.12.2", "io-ts": "npm:@bitgo-forks/io-ts@2.1.4", From 536be8ae1ec957e7f86f82462c202fc19f43f0b8 Mon Sep 17 00:00:00 2001 From: Alex Tse Date: Mon, 22 Sep 2025 10:13:22 -0400 Subject: [PATCH 17/35] feat: add advanced wallet type Ticket: WP-6028 --- modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts | 2 +- modules/sdk-core/src/bitgo/wallet/iWallet.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts index c4efbbd6a9..95c958dbea 100644 --- a/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts +++ b/modules/sdk-core/src/bitgo/baseCoin/iBaseCoin.ts @@ -216,7 +216,7 @@ export interface SupplementGenerateWalletOptions { rootPrivateKey?: string; disableKRSEmail?: boolean; multisigType?: 'tss' | 'onchain' | 'blsdkg'; - type: 'hot' | 'cold' | 'custodial'; + type: 'hot' | 'cold' | 'custodial' | 'advanced'; subType?: 'lightningCustody' | 'lightningSelfCustody' | 'onPrem'; coinSpecific?: { [coinName: string]: unknown }; evmKeyRingReferenceWalletId?: string; diff --git a/modules/sdk-core/src/bitgo/wallet/iWallet.ts b/modules/sdk-core/src/bitgo/wallet/iWallet.ts index 725979b058..8e5aa37d4c 100644 --- a/modules/sdk-core/src/bitgo/wallet/iWallet.ts +++ b/modules/sdk-core/src/bitgo/wallet/iWallet.ts @@ -737,7 +737,7 @@ export interface CrossChainUTXO { toAddress: string; } -export type WalletType = 'backing' | 'cold' | 'custodial' | 'custodialPaired' | 'hot' | 'trading'; +export type WalletType = 'backing' | 'cold' | 'custodial' | 'custodialPaired' | 'hot' | 'trading' | 'advanced'; export type SubWalletType = 'distributedCustody' | 'lightningCustody' | 'lightningSelfCustody' | 'onPrem'; export interface WalletData { From 939bf47e89f7dca69d7a86ed776c54c535f77101 Mon Sep 17 00:00:00 2001 From: danielzhao122 Date: Tue, 23 Sep 2025 11:16:12 -0400 Subject: [PATCH 18/35] refactor: added decoding to unit tests and addressed missing jsdocs TICKET: WP-5443 --- .../src/typedRoutes/api/v2/ofcSignPayload.ts | 33 +++++++++++-------- .../test/unit/clientRoutes/signPayload.ts | 15 +++++++-- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts index 933aaed354..8c80f315ac 100644 --- a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts +++ b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts @@ -1,41 +1,48 @@ import * as t from 'io-ts'; import { Json, NonEmptyString } from 'io-ts-types'; import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; +import { BitgoExpressError } from '../../schemas/error'; /** * Sign an arbitrary payload using an OFC trading account key. - * @operationId express.ofc.signPayload * POST /api/v2/ofc/signPayload */ export const OfcSignPayloadBody = { + /** The ID of the wallet to use for signing. */ walletId: NonEmptyString, + /** The JSON payload to sign. */ payload: Json, + /** The passphrase for the wallet (optional). */ walletPassphrase: optional(t.string), }; -/** - * Successful response body for signing an OFC payload. - * @property payload - The canonical string form of the JSON payload that was signed. Objects are JSON.stringify'ed. - * @property signature - Hex-encoded signature generated by the trading account key. - */ -export const OfcSignPayloadResponse = t.type({ +export const OfcSignPayloadResponse200 = t.type({ + /** The canonical string form of the JSON payload that was signed. */ payload: t.string, + /** Hex-encoded signature generated by the trading account key. */ signature: t.string, }); +/** + * Response for signPayload request. + */ +export const OfcSignPayloadResponse = { + /** The canonical string form of the JSON payload that was signed and the hex-encoded signature generated by the trading account key. */ + 200: OfcSignPayloadResponse200, + /** BitGo Express error payload. */ + 400: BitgoExpressError, +} as const; + /** * Request body for signing an arbitrary payload with an OFC wallet key. - * @property walletId – non-empty string identifying the OFC wallet - * @property payload – JSON value to sign - * @property walletPassphrase – optional passphrase used to decrypt the user key (string) + * + * @operationId express.ofc.signPayload */ export const PostOfcSignPayload = httpRoute({ path: '/api/v2/ofc/signPayload', method: 'POST', request: httpRequest({ body: OfcSignPayloadBody }), - response: { - 200: OfcSignPayloadResponse, - }, + response: OfcSignPayloadResponse, }); export type PostOfcSignPayload = typeof PostOfcSignPayload; diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index dcd41c5066..36b8acee26 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -4,7 +4,7 @@ import 'should-sinon'; import 'should'; import * as fs from 'fs'; import { Request } from 'express'; -import { BitGo, Coin, BaseCoin, Wallet, Wallets } from 'bitgo'; +import { BitGo, Coin, BaseCoin, Wallet, Wallets, decodeOrElse } from 'bitgo'; import '../../lib/asserts'; import { handleV2OFCSignPayload, handleV2OFCSignPayloadInExtSigningMode } from '../../../src/clientRoutes'; @@ -55,7 +55,12 @@ describe('Sign an arbitrary payload with trading account key', function () { payload, }, } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; - await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); + + const res = await handleV2OFCSignPayload(req); + decodeOrElse('OfcSignPayloadResponse200', OfcSignPayloadResponse[200], res, (_) => { + throw new Error(`Response did not match expected codec`); + }); + res.should.deepEqual(expectedResponse); }); it('should decode handler response with OfcSignPayloadResponse codec', async function () { @@ -70,9 +75,13 @@ describe('Sign an arbitrary payload with trading account key', function () { payload, }, } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; + const result = await handleV2OFCSignPayload(req); + decodeOrElse('OfcSignPayloadResponse200', OfcSignPayloadResponse[200], result, (_) => { + throw new Error(`Response did not match expected codec`); + }); result.should.eql(expected); - OfcSignPayloadResponse.is(result).should.be.true(); + OfcSignPayloadResponse[200].is(result).should.be.true(); }); }); From ef5121fb9108e120701405dd34b0d9149f6e2f42 Mon Sep 17 00:00:00 2001 From: Yan Date: Mon, 22 Sep 2025 14:48:57 -0700 Subject: [PATCH 19/35] fix: replaced vulnerable request package by using axios TICKET: DX-1558 --- modules/bitgo/package.json | 4 +--- modules/bitgo/test/unit/bitgo.ts | 41 ++++++++++++++++---------------- yarn.lock | 40 +++++++------------------------ 3 files changed, 30 insertions(+), 55 deletions(-) diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index e13b845672..b492f529dc 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -154,9 +154,7 @@ "keccak": "3.0.3", "libsodium-wrappers-sumo": "^0.7.9", "puppeteer": "2.1.1", - "q": "^1.1.2", - "request": "^2.88.0", - "request-promise": "^4.2.2" + "q": "^1.1.2" }, "optionalDependencies": { "@ethereumjs/common": "^2.6.5", diff --git a/modules/bitgo/test/unit/bitgo.ts b/modules/bitgo/test/unit/bitgo.ts index f11c5cbc55..56e3faac4f 100644 --- a/modules/bitgo/test/unit/bitgo.ts +++ b/modules/bitgo/test/unit/bitgo.ts @@ -11,7 +11,7 @@ import { common, generateGPGKeyPair } from '@bitgo/sdk-core'; import { bip32, ECPair } from '@bitgo/utxo-lib'; import * as _ from 'lodash'; import * as BitGoJS from '../../src/index'; -const rp = require('request-promise'); +import axios from 'axios'; import { TestBitGo } from '@bitgo/sdk-test'; import { BitGo } from '../../src/bitgo'; @@ -473,27 +473,26 @@ describe('BitGo Prototype Methods', function () { timestamp: '1521590532925', }); - const responseData = (await rp({ - uri: url, - method: 'GET', + const response = await axios.get(url, { headers: requestHeaders, - transform: (body, response) => { - // verify the response headers - const url = response.request.href; - const hmac = response.headers.hmac; - const timestamp = response.headers.timestamp; - const statusCode = response.statusCode; - const verificationParams = { - url, - hmac, - timestamp, - token, - statusCode, - text: body, - }; - return bitgo.verifyResponse(verificationParams); - }, - })) as any; + transformResponse: [], + }); + + const finalUrl = response.request.responseURL || url; + const hmac = response.headers.hmac; + const timestamp = response.headers.timestamp; + const statusCode = response.status; + + const verificationParams = { + url: finalUrl, + hmac, + timestamp, + token, + statusCode, + text: response.data, + }; + + const responseData = bitgo.verifyResponse(verificationParams) as any; responseData.signatureSubject.should.equal( '1521590532925|/api/v2/tltc/wallet/5941b202b42fcbc707170d5b597491d9/address/QNc4RFAcbvqmtrR1kR2wbGLCx6tEvojFYE?segwit=1|200|{"id":"5a7ca8bcaf52c8e807c575fb692609ec","address":"QNc4RFAcbvqmtrR1kR2wbGLCx6tEvojFYE","chain":0,"index":2,"coin":"tltc","wallet":"5941b202b42fcbc707170d5b597491d9","coinSpecific":{"redeemScript":"522102835bcfd130f7a56f72c905b782d90b66e22f88ad3309cf72af5138a7d44be8b3210322c7f42a1eb212868eab78db7ba64846075d98c7f4c7aa25a02e57871039e0cd210265825be0d5bf957fb72abd7c23bf0836a78a15f951a073467cd5c99e03ce7ab753ae"},"balance":{"updated":"2018-02-28T23:48:07.341Z","numTx":1,"numUnspents":1,"totalReceived":20000000}}' ); diff --git a/yarn.lock b/yarn.lock index e4df106c98..d8e2fa37f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18046,24 +18046,7 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise@^4.2.2: - version "4.2.6" - resolved "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz" - integrity sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ== - dependencies: - bluebird "^3.5.0" - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.79.0, request@^2.88.0: +request@^2.79.0: version "2.88.2" resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -19197,11 +19180,6 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== - stellar-base@^8.2.2: version "8.2.2" resolved "https://registry.npmjs.org/stellar-base/-/stellar-base-8.2.2.tgz" @@ -19988,14 +19966,6 @@ tonweb@^0.0.62: node-fetch "2.6.7" tweetnacl "1.0.3" -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^5.0.0: version "5.1.2" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz" @@ -20003,6 +19973,14 @@ tough-cookie@^5.0.0: dependencies: tldts "^6.1.32" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@~0.0.3: version "0.0.3" resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" From ee3a6220496476aa7f4545b5f4a9a3bf97d9bdb9 Mon Sep 17 00:00:00 2001 From: Louis Varin Date: Mon, 22 Sep 2025 16:03:46 -0400 Subject: [PATCH 20/35] feat: configure learn to skip git operations Ticket: VL-3486 --- .github/workflows/ci.yml | 3 - check-package-versions.js | 109 ----------- lerna.json | 8 +- modules/abstract-cosmos/package.json | 10 +- modules/abstract-eth/package.json | 14 +- modules/abstract-lightning/package.json | 8 +- modules/abstract-substrate/package.json | 8 +- modules/abstract-utxo/package.json | 14 +- modules/account-lib/package.json | 124 ++++++------- .../package.json | 2 +- modules/bitgo/package.json | 174 +++++++++--------- modules/blake2b-wasm/package.json | 2 +- modules/blake2b/package.json | 4 +- modules/blockapis/package.json | 4 +- modules/deser-lib/package.json | 2 +- modules/express/package.json | 14 +- modules/key-card/package.json | 8 +- modules/sdk-api/package.json | 12 +- modules/sdk-coin-ada/package.json | 12 +- modules/sdk-coin-algo/package.json | 10 +- modules/sdk-coin-apechain/package.json | 12 +- modules/sdk-coin-apt/package.json | 12 +- modules/sdk-coin-arbeth/package.json | 14 +- modules/sdk-coin-asi/package.json | 12 +- modules/sdk-coin-atom/package.json | 14 +- modules/sdk-coin-avaxc/package.json | 18 +- modules/sdk-coin-avaxp/package.json | 12 +- modules/sdk-coin-baby/package.json | 12 +- modules/sdk-coin-bch/package.json | 12 +- modules/sdk-coin-bcha/package.json | 14 +- modules/sdk-coin-bera/package.json | 14 +- modules/sdk-coin-bld/package.json | 14 +- modules/sdk-coin-bsc/package.json | 14 +- modules/sdk-coin-bsv/package.json | 14 +- modules/sdk-coin-btc/package.json | 14 +- modules/sdk-coin-btg/package.json | 12 +- modules/sdk-coin-celo/package.json | 14 +- modules/sdk-coin-coredao/package.json | 12 +- modules/sdk-coin-coreum/package.json | 14 +- modules/sdk-coin-cosmos/package.json | 12 +- modules/sdk-coin-cronos/package.json | 12 +- modules/sdk-coin-cspr/package.json | 12 +- modules/sdk-coin-dash/package.json | 12 +- modules/sdk-coin-doge/package.json | 12 +- modules/sdk-coin-dot/package.json | 12 +- modules/sdk-coin-eos/package.json | 12 +- modules/sdk-coin-etc/package.json | 16 +- modules/sdk-coin-eth/package.json | 14 +- modules/sdk-coin-ethlike/package.json | 14 +- modules/sdk-coin-ethw/package.json | 12 +- modules/sdk-coin-evm/package.json | 8 +- modules/sdk-coin-flr/package.json | 12 +- modules/sdk-coin-flrp/package.json | 12 +- modules/sdk-coin-hash/package.json | 14 +- modules/sdk-coin-hbar/package.json | 12 +- modules/sdk-coin-icp/package.json | 14 +- modules/sdk-coin-initia/package.json | 12 +- modules/sdk-coin-injective/package.json | 14 +- modules/sdk-coin-iota/package.json | 12 +- modules/sdk-coin-islm/package.json | 12 +- modules/sdk-coin-lnbtc/package.json | 12 +- modules/sdk-coin-ltc/package.json | 12 +- modules/sdk-coin-mantra/package.json | 12 +- modules/sdk-coin-mon/package.json | 12 +- modules/sdk-coin-near/package.json | 12 +- modules/sdk-coin-oas/package.json | 12 +- modules/sdk-coin-opeth/package.json | 14 +- modules/sdk-coin-osmo/package.json | 14 +- modules/sdk-coin-polygon/package.json | 16 +- modules/sdk-coin-polyx/package.json | 14 +- modules/sdk-coin-rbtc/package.json | 14 +- modules/sdk-coin-rune/package.json | 12 +- modules/sdk-coin-sei/package.json | 14 +- modules/sdk-coin-sgb/package.json | 12 +- modules/sdk-coin-sol/package.json | 12 +- modules/sdk-coin-soneium/package.json | 12 +- modules/sdk-coin-stt/package.json | 12 +- modules/sdk-coin-stx/package.json | 12 +- modules/sdk-coin-sui/package.json | 14 +- modules/sdk-coin-tao/package.json | 12 +- modules/sdk-coin-tia/package.json | 14 +- modules/sdk-coin-ton/package.json | 12 +- modules/sdk-coin-trx/package.json | 12 +- modules/sdk-coin-vet/package.json | 16 +- modules/sdk-coin-wemix/package.json | 12 +- modules/sdk-coin-world/package.json | 12 +- modules/sdk-coin-xdc/package.json | 12 +- modules/sdk-coin-xlm/package.json | 10 +- modules/sdk-coin-xrp/package.json | 12 +- modules/sdk-coin-xtz/package.json | 14 +- modules/sdk-coin-zec/package.json | 10 +- modules/sdk-coin-zeta/package.json | 14 +- modules/sdk-coin-zketh/package.json | 14 +- modules/sdk-core/package.json | 16 +- modules/sdk-hmac/package.json | 4 +- modules/sdk-lib-mpc/package.json | 4 +- modules/sdk-opensslbytes/package.json | 2 +- modules/sdk-rpc-wrapper/package.json | 10 +- modules/sdk-test/package.json | 6 +- modules/secp256k1/package.json | 2 +- modules/sjcl/package.json | 2 +- modules/statics/package.json | 2 +- modules/unspents/package.json | 4 +- modules/utxo-bin/package.json | 12 +- modules/utxo-core/package.json | 6 +- modules/utxo-lib/package.json | 4 +- modules/utxo-ord/package.json | 8 +- modules/utxo-staking/package.json | 8 +- modules/web-demo/package.json | 91 ++++----- package.json | 1 - 110 files changed, 779 insertions(+), 881 deletions(-) delete mode 100755 check-package-versions.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c420cd59f..e043501154 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,9 +60,6 @@ jobs: if: steps.lerna-cache.outputs.cache-hit != 'true' || contains( github.event.pull_request.labels.*.name, 'SKIP_CACHE') run: yarn install --with-frozen-lockfile --ignore-scripts - - name: Check In-Repo Package Versions - run: yarn run check-versions - - name: build packages env: # Workaround for https://github.com/nodejs/node/issues/51555 diff --git a/check-package-versions.js b/check-package-versions.js deleted file mode 100755 index 31fea2bfff..0000000000 --- a/check-package-versions.js +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env node - -// Check versions of in-repo packages to make sure they match with the package.json version. -// This is to prevent inadvertent updates of dependency versions for packages which are symlinked -// by lerna. The dependency versions of these packages should only ever be updated in the release branch. - -const execa = require('execa'); -const path = require('path'); - -/** - * Create a function which can run lerna commands - * @param lernaPath {string} path to lerna binary - * @returns {function(string, string[], Object.): Promise} - */ -function getLernaRunner(lernaPath) { - return async (command, args = [], options = {}) => { - const { stdout } = await execa(lernaPath, [command, ...args], options); - return stdout; - }; -} - -/** - * Get information on the modules in this repo that are managed by lerna. - * @param lerna {function} - * @returns {Promise<{path: *, name: *, deps: *, version: *}[]>} - */ -async function getLernaManagedModules(lerna) { - const depGraph = JSON.parse(await lerna('list', ['--loglevel', 'silent', '--graph', '--all'])); - const managedModules = JSON.parse(await lerna('list', ['--loglevel', 'silent', '--json', '--all'])); - const managedModuleNames = managedModules.map(({ name }) => name); - return Object.entries(depGraph).map(([name, deps]) => { - const mod = managedModules.find((mod) => mod.name === name); - return { - name, - deps: deps.filter((d) => managedModuleNames.includes(d)), - path: mod.location, - version: mod.version, - }; - }); -} - -/** - * Build a dictionary from package name to the expected version of that package. - * @param modules - * @returns {Object.} - */ -function getExpectedVersions(modules) { - return Object.values(modules).reduce((acc, mod) => { - return Object.assign(acc, { [mod.name]: mod.version }); - }, {}); -} - -/** - * For the module at `modPath`, get the version of the dependency `depName`. - * If the version is prefixed with a carat or tilde, it will be stripped. - * @param modPath {string} - * @param depName {string} - * @returns {string | undefined} - */ -function getDependencyVersion(modPath, depName) { - const packageJsonPath = path.join(modPath, 'package.json'); - const { - dependencies = {}, - devDependencies = {}, - optionalDependencies = {}, - peerDependencies = {}, - } = require(packageJsonPath); - - const deps = { ...dependencies, ...devDependencies, ...optionalDependencies, ...peerDependencies }; - if (deps[depName]) { - const matches = deps[depName].match(/^([^~])?(.*)$/); - return matches[matches.length - 1]; - } -} - -async function main() { - const { stdout: lernaBinary } = await execa('yarn', ['bin', 'lerna'], { cwd: process.cwd() }); - - const lerna = getLernaRunner(lernaBinary); - - const modules = await getLernaManagedModules(lerna); - const expectedVersions = getExpectedVersions(modules); - - let exitCode = 0; - - for (const mod of modules) { - for (const dep of mod.deps) { - const depVersion = getDependencyVersion(mod.path, dep); - if (depVersion && depVersion !== expectedVersions[dep]) { - // Handle pre-release versions by checking if the base version matches - const baseDepVersion = depVersion.split('-')[0]; - const baseExpectedVersion = expectedVersions[dep].split('-')[0]; - - if (baseDepVersion !== baseExpectedVersion) { - console.log( - `error: expected lerna-managed module ${mod.name} to depend on package ${dep} using version ${expectedVersions[dep]}, but found version ${depVersion} instead` - ); - exitCode = 1; - } - } - } - } - - return exitCode; -} - -main() - .then(process.exit) - .catch((e) => console.error(e)); diff --git a/lerna.json b/lerna.json index ba3c75058c..453af2ac87 100644 --- a/lerna.json +++ b/lerna.json @@ -4,7 +4,13 @@ "useWorkspaces": true, "command": { "version": { - "message": "chore(root): publish modules" + "message": "chore(root): publish modules", + "allowBranch": "master", + "skipGit": true + }, + "publish": { + "skipGit": true, + "allowBranch": "master" } }, "$schema": "node_modules/lerna/schemas/lerna-schema.json", diff --git a/modules/abstract-cosmos/package.json b/modules/abstract-cosmos/package.json index 0131b204ac..fd3bcf40d7 100644 --- a/modules/abstract-cosmos/package.json +++ b/modules/abstract-cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/abstract-cosmos", - "version": "11.14.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for COSMOS base implementation", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -38,10 +38,10 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/crypto": "^0.30.1", "@cosmjs/encoding": "^0.29.5", diff --git a/modules/abstract-eth/package.json b/modules/abstract-eth/package.json index 445c1449ca..670f61c432 100644 --- a/modules/abstract-eth/package.json +++ b/modules/abstract-eth/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/abstract-eth", - "version": "24.12.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for ETH base implementation", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/rlp": "^4.0.0", "@ethereumjs/tx": "^3.3.0", @@ -60,8 +60,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/keccak": "^3.0.5" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/abstract-lightning/package.json b/modules/abstract-lightning/package.json index a39a3938da..2b3faa0435 100644 --- a/modules/abstract-lightning/package.json +++ b/modules/abstract-lightning/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/abstract-lightning", - "version": "7.0.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for base Lightning Network coin implementation", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ }, "dependencies": { "@bitgo/public-types": "5.22.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", - "@bitgo/utxo-lib": "^11.10.0", "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "bs58check": "^2.1.2", "fp-ts": "^2.12.2", "io-ts": "npm:@bitgo-forks/io-ts@2.1.4", diff --git a/modules/abstract-substrate/package.json b/modules/abstract-substrate/package.json index 9276fd9b4e..a14247da31 100644 --- a/modules/abstract-substrate/package.json +++ b/modules/abstract-substrate/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/abstract-substrate", - "version": "1.10.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Substrate base implementation", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -38,9 +38,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@polkadot/api": "14.1.1", "@polkadot/keyring": "13.3.1", "@polkadot/types": "14.1.1", diff --git a/modules/abstract-utxo/package.json b/modules/abstract-utxo/package.json index d2437dbaa3..f1a1a0f6a8 100644 --- a/modules/abstract-utxo/package.json +++ b/modules/abstract-utxo/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/abstract-utxo", - "version": "9.26.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for UTXO base implementation", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -42,12 +42,12 @@ ] }, "dependencies": { - "@bitgo/blockapis": "^1.11.0", - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-core": "^1.19.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/blockapis": "0.0.0-semantic-release-managed", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@bitgo/wasm-miniscript": "2.0.0-beta.7", "@types/lodash": "^4.14.121", "@types/superagent": "4.1.15", diff --git a/modules/account-lib/package.json b/modules/account-lib/package.json index c3a41a6e5d..a673e0d78f 100644 --- a/modules/account-lib/package.json +++ b/modules/account-lib/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/account-lib", - "version": "27.10.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo's account library functions", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -27,67 +27,67 @@ "node": ">=20 <23" }, "dependencies": { - "@bitgo/sdk-coin-ada": "^4.14.0", - "@bitgo/sdk-coin-algo": "^2.4.4", - "@bitgo/sdk-coin-apechain": "^1.2.4", - "@bitgo/sdk-coin-apt": "^2.5.4", - "@bitgo/sdk-coin-arbeth": "^21.8.4", - "@bitgo/sdk-coin-asi": "^1.4.4", - "@bitgo/sdk-coin-atom": "^13.8.2", - "@bitgo/sdk-coin-avaxc": "^6.3.4", - "@bitgo/sdk-coin-avaxp": "^5.3.4", - "@bitgo/sdk-coin-baby": "^1.7.4", - "@bitgo/sdk-coin-bera": "^2.5.4", - "@bitgo/sdk-coin-bld": "^3.4.2", - "@bitgo/sdk-coin-bsc": "^22.7.2", - "@bitgo/sdk-coin-celo": "^5.2.4", - "@bitgo/sdk-coin-coredao": "^2.5.4", - "@bitgo/sdk-coin-coreum": "^21.4.2", - "@bitgo/sdk-coin-cosmos": "^1.5.4", - "@bitgo/sdk-coin-cronos": "^1.5.4", - "@bitgo/sdk-coin-cspr": "^2.3.4", - "@bitgo/sdk-coin-dot": "^4.4.4", - "@bitgo/sdk-coin-etc": "^2.4.4", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-coin-evm": "^1.6.4", - "@bitgo/sdk-coin-flr": "^1.5.4", - "@bitgo/sdk-coin-hash": "^3.5.2", - "@bitgo/sdk-coin-hbar": "^2.3.4", - "@bitgo/sdk-coin-icp": "^1.18.4", - "@bitgo/sdk-coin-initia": "^2.3.4", - "@bitgo/sdk-coin-injective": "^3.4.2", - "@bitgo/sdk-coin-islm": "^2.3.4", - "@bitgo/sdk-coin-mon": "^1.3.4", - "@bitgo/sdk-coin-near": "^2.10.4", - "@bitgo/sdk-coin-oas": "^2.4.4", - "@bitgo/sdk-coin-opeth": "^18.6.4", - "@bitgo/sdk-coin-osmo": "^3.4.2", - "@bitgo/sdk-coin-polygon": "^21.4.4", - "@bitgo/sdk-coin-polyx": "^1.9.3", - "@bitgo/sdk-coin-rbtc": "^2.2.4", - "@bitgo/sdk-coin-rune": "^1.5.2", - "@bitgo/sdk-coin-sei": "^3.4.2", - "@bitgo/sdk-coin-sgb": "^1.5.4", - "@bitgo/sdk-coin-sol": "^6.1.4", - "@bitgo/sdk-coin-soneium": "^1.7.4", - "@bitgo/sdk-coin-stt": "^1.3.4", - "@bitgo/sdk-coin-stx": "^3.9.4", - "@bitgo/sdk-coin-sui": "^5.18.4", - "@bitgo/sdk-coin-tao": "^1.11.4", - "@bitgo/sdk-coin-tia": "^3.4.2", - "@bitgo/sdk-coin-ton": "^3.8.4", - "@bitgo/sdk-coin-trx": "^3.5.4", - "@bitgo/sdk-coin-vet": "^2.5.3", - "@bitgo/sdk-coin-wemix": "^1.4.4", - "@bitgo/sdk-coin-world": "^1.5.4", - "@bitgo/sdk-coin-xdc": "^1.4.4", - "@bitgo/sdk-coin-xrp": "^3.10.4", - "@bitgo/sdk-coin-xtz": "^2.7.4", - "@bitgo/sdk-coin-zeta": "^3.4.2", - "@bitgo/sdk-coin-zketh": "^2.3.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-coin-ada": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-algo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-apechain": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-apt": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-arbeth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-asi": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-atom": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-baby": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bera": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bld": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bsc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-celo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-coredao": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-coreum": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cronos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cspr": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-dot": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-etc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-evm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-flr": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-hash": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-hbar": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-icp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-initia": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-injective": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-islm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-mon": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-near": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-oas": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-opeth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-osmo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-polygon": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-polyx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-rbtc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-rune": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sei": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sgb": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sol": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-soneium": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-stt": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-stx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sui": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-tao": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-tia": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ton": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-trx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-vet": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-wemix": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-world": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xdc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xrp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xtz": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zeta": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zketh": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.1.1", "bs58": "^4.0.1" }, diff --git a/modules/babylonlabs-io-btc-staking-ts/package.json b/modules/babylonlabs-io-btc-staking-ts/package.json index af54fd71a8..8dcca09722 100644 --- a/modules/babylonlabs-io-btc-staking-ts/package.json +++ b/modules/babylonlabs-io-btc-staking-ts/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/babylonlabs-io-btc-staking-ts", - "version": "2.4.1", + "version": "0.0.0-semantic-release-managed", "description": "Library exposing methods for the creation and consumption of Bitcoin transactions pertaining to Babylon's Bitcoin Staking protocol.", "module": "dist/index.js", "main": "dist/index.cjs", diff --git a/modules/bitgo/package.json b/modules/bitgo/package.json index e13b845672..9e1a8c9f55 100644 --- a/modules/bitgo/package.json +++ b/modules/bitgo/package.json @@ -1,6 +1,6 @@ { "name": "bitgo", - "version": "50.0.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo JavaScript SDK", "main": "./dist/src/index.js", "types": "./dist/types/src/index.d.ts", @@ -44,90 +44,90 @@ "gen-docs": "typedoc" }, "dependencies": { - "@bitgo/abstract-lightning": "^7.0.0", - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/account-lib": "^27.10.4", - "@bitgo/blockapis": "^1.11.0", - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-coin-ada": "^4.14.0", - "@bitgo/sdk-coin-algo": "^2.4.4", - "@bitgo/sdk-coin-apechain": "^1.2.4", - "@bitgo/sdk-coin-apt": "^2.5.4", - "@bitgo/sdk-coin-arbeth": "^21.8.4", - "@bitgo/sdk-coin-asi": "^1.4.4", - "@bitgo/sdk-coin-atom": "^13.8.2", - "@bitgo/sdk-coin-avaxc": "^6.3.4", - "@bitgo/sdk-coin-avaxp": "^5.3.4", - "@bitgo/sdk-coin-baby": "^1.7.4", - "@bitgo/sdk-coin-bch": "^2.3.4", - "@bitgo/sdk-coin-bcha": "^2.4.4", - "@bitgo/sdk-coin-bera": "^2.5.4", - "@bitgo/sdk-coin-bld": "^3.4.2", - "@bitgo/sdk-coin-bsc": "^22.7.2", - "@bitgo/sdk-coin-bsv": "^2.3.4", - "@bitgo/sdk-coin-btc": "^2.7.4", - "@bitgo/sdk-coin-btg": "^2.3.4", - "@bitgo/sdk-coin-celo": "^5.2.4", - "@bitgo/sdk-coin-coredao": "^2.5.4", - "@bitgo/sdk-coin-coreum": "^21.4.2", - "@bitgo/sdk-coin-cosmos": "^1.5.4", - "@bitgo/sdk-coin-cronos": "^1.5.4", - "@bitgo/sdk-coin-cspr": "^2.3.4", - "@bitgo/sdk-coin-dash": "^2.3.4", - "@bitgo/sdk-coin-doge": "^2.3.4", - "@bitgo/sdk-coin-dot": "^4.4.4", - "@bitgo/sdk-coin-eos": "^3.4.4", - "@bitgo/sdk-coin-etc": "^2.4.4", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-coin-ethlike": "^2.1.4", - "@bitgo/sdk-coin-ethw": "^20.2.4", - "@bitgo/sdk-coin-evm": "^1.6.4", - "@bitgo/sdk-coin-flr": "^1.5.4", - "@bitgo/sdk-coin-hash": "^3.5.2", - "@bitgo/sdk-coin-hbar": "^2.3.4", - "@bitgo/sdk-coin-icp": "^1.18.4", - "@bitgo/sdk-coin-initia": "^2.3.4", - "@bitgo/sdk-coin-injective": "^3.4.2", - "@bitgo/sdk-coin-iota": "^1.2.0", - "@bitgo/sdk-coin-islm": "^2.3.4", - "@bitgo/sdk-coin-lnbtc": "^1.4.4", - "@bitgo/sdk-coin-ltc": "^3.3.4", - "@bitgo/sdk-coin-mon": "^1.3.4", - "@bitgo/sdk-coin-near": "^2.10.4", - "@bitgo/sdk-coin-oas": "^2.4.4", - "@bitgo/sdk-coin-opeth": "^18.6.4", - "@bitgo/sdk-coin-osmo": "^3.4.2", - "@bitgo/sdk-coin-polygon": "^21.4.4", - "@bitgo/sdk-coin-polyx": "^1.9.3", - "@bitgo/sdk-coin-rbtc": "^2.2.4", - "@bitgo/sdk-coin-rune": "^1.5.2", - "@bitgo/sdk-coin-sei": "^3.4.2", - "@bitgo/sdk-coin-sgb": "^1.5.4", - "@bitgo/sdk-coin-sol": "^6.1.4", - "@bitgo/sdk-coin-soneium": "^1.7.4", - "@bitgo/sdk-coin-stt": "^1.3.4", - "@bitgo/sdk-coin-stx": "^3.9.4", - "@bitgo/sdk-coin-sui": "^5.18.4", - "@bitgo/sdk-coin-tao": "^1.11.4", - "@bitgo/sdk-coin-tia": "^3.4.2", - "@bitgo/sdk-coin-ton": "^3.8.4", - "@bitgo/sdk-coin-trx": "^3.5.4", - "@bitgo/sdk-coin-vet": "^2.5.3", - "@bitgo/sdk-coin-wemix": "^1.4.4", - "@bitgo/sdk-coin-world": "^1.5.4", - "@bitgo/sdk-coin-xdc": "^1.4.4", - "@bitgo/sdk-coin-xlm": "^3.5.4", - "@bitgo/sdk-coin-xrp": "^3.10.4", - "@bitgo/sdk-coin-xtz": "^2.7.4", - "@bitgo/sdk-coin-zec": "^2.3.4", - "@bitgo/sdk-coin-zeta": "^3.4.2", - "@bitgo/sdk-coin-zketh": "^2.3.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/sjcl": "^1.0.1", - "@bitgo/statics": "^57.8.0", - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/abstract-lightning": "0.0.0-semantic-release-managed", + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/account-lib": "0.0.0-semantic-release-managed", + "@bitgo/blockapis": "0.0.0-semantic-release-managed", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ada": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-algo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-apechain": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-apt": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-arbeth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-asi": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-atom": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-baby": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bch": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bcha": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bera": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bld": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bsc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bsv": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-btc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-btg": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-celo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-coredao": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-coreum": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cronos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cspr": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-dash": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-doge": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-dot": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-etc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ethlike": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ethw": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-evm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-flr": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-hash": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-hbar": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-icp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-initia": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-injective": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-iota": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-islm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-lnbtc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ltc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-mon": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-near": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-oas": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-opeth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-osmo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-polygon": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-polyx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-rbtc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-rune": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sei": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sgb": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sol": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-soneium": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-stt": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-stx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sui": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-tao": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-tia": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ton": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-trx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-vet": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-wemix": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-world": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xdc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xlm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xrp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xtz": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zec": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zeta": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zketh": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/sjcl": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@types/superagent": "^4.1.3", "bignumber.js": "^9.1.1", "fs-extra": "^9.1.0", @@ -138,8 +138,8 @@ }, "devDependencies": { "@bitgo/public-types": "5.22.0", - "@bitgo/sdk-opensslbytes": "^2.0.0", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-opensslbytes": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@openpgp/web-stream-tools": "0.0.14", "@types/create-hmac": "^1.1.0", "@types/debug": "^4.1.4", diff --git a/modules/blake2b-wasm/package.json b/modules/blake2b-wasm/package.json index 73b617acd5..1f9039f0ea 100644 --- a/modules/blake2b-wasm/package.json +++ b/modules/blake2b-wasm/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/blake2b-wasm", - "version": "3.2.3", + "version": "0.0.0-semantic-release-managed", "description": "Blake2b implemented in WASM", "main": "index.js", "dependencies": { diff --git a/modules/blake2b/package.json b/modules/blake2b/package.json index 14e19292fc..b9f6c8fdd7 100644 --- a/modules/blake2b/package.json +++ b/modules/blake2b/package.json @@ -1,10 +1,10 @@ { "name": "@bitgo/blake2b", - "version": "3.2.4", + "version": "0.0.0-semantic-release-managed", "description": "Blake2b (64-bit version) in pure JavaScript", "main": "index.js", "dependencies": { - "@bitgo/blake2b-wasm": "^3.2.3", + "@bitgo/blake2b-wasm": "0.0.0-semantic-release-managed", "nanoassert": "^2.0.0" }, "publishConfig": { diff --git a/modules/blockapis/package.json b/modules/blockapis/package.json index 8f9f9f2539..7229bc7318 100644 --- a/modules/blockapis/package.json +++ b/modules/blockapis/package.json @@ -1,7 +1,7 @@ { "name": "@bitgo/blockapis", "description": "Access public block explorer APIs for a variety of coins", - "version": "1.11.0", + "version": "0.0.0-semantic-release-managed", "main": "dist/src/index.js", "files": [ "dist/src/**/*" @@ -22,7 +22,7 @@ "directory": "modules/blockapis" }, "dependencies": { - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@types/superagent": "4.1.16", "superagent": "^9.0.1" }, diff --git a/modules/deser-lib/package.json b/modules/deser-lib/package.json index 390e14a173..12b558e405 100644 --- a/modules/deser-lib/package.json +++ b/modules/deser-lib/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/deser-lib", - "version": "1.8.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo serialization and deseralization library", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", diff --git a/modules/express/package.json b/modules/express/package.json index 9e05e08817..7589dc0444 100644 --- a/modules/express/package.json +++ b/modules/express/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/express", - "version": "15.0.0", + "version": "0.0.0-semantic-release-managed", "private": true, "description": "Local signing server and proxy for the BitGo platform", "main": "./dist/src/index.js", @@ -39,12 +39,12 @@ "dependencies": { "@api-ts/io-ts-http": "^3.2.1", "@api-ts/typed-express-router": "2.0.0", - "@bitgo/abstract-lightning": "^7.0.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/abstract-lightning": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@types/proxyquire": "^1.3.31", "argparse": "^1.0.10", - "bitgo": "^50.0.0", + "bitgo": "0.0.0-semantic-release-managed", "body-parser": "^1.20.3", "connect-timeout": "^1.9.0", "debug": "^3.1.0", @@ -59,8 +59,8 @@ }, "devDependencies": { "@bitgo/public-types": "5.22.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/argparse": "^1.0.36", "@types/body-parser": "^1.17.0", "@types/express": "4.17.13", diff --git a/modules/key-card/package.json b/modules/key-card/package.json index d15c93e893..50262a2677 100644 --- a/modules/key-card/package.json +++ b/modules/key-card/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/key-card", - "version": "0.27.4", + "version": "0.0.0-semantic-release-managed", "description": "key card generator for BitGo wallets", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -33,9 +33,9 @@ ] }, "dependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "jspdf": "^3.0.2", "qrcode": "^1.5.1" }, diff --git a/modules/sdk-api/package.json b/modules/sdk-api/package.json index 19e80a1191..4b0a1aabb1 100644 --- a/modules/sdk-api/package.json +++ b/modules/sdk-api/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-api", - "version": "1.68.3", + "version": "0.0.0-semantic-release-managed", "description": "REST wrapper for BitGoJS", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,11 +40,11 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-hmac": "^1.2.0", - "@bitgo/sjcl": "^1.0.1", - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-hmac": "0.0.0-semantic-release-managed", + "@bitgo/sjcl": "0.0.0-semantic-release-managed", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@types/superagent": "4.1.15", "bitcoinjs-message": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.3", "debug": "3.1.0", diff --git a/modules/sdk-coin-ada/package.json b/modules/sdk-coin-ada/package.json index 1256ca423c..b7cacc37c3 100644 --- a/modules/sdk-coin-ada/package.json +++ b/modules/sdk-coin-ada/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-ada", - "version": "4.14.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ada", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@emurgo/cardano-serialization-lib-browser": "^12.0.1", "@emurgo/cardano-serialization-lib-nodejs": "^12.0.1", "bech32": "^2.0.0", @@ -54,8 +54,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-algo/package.json b/modules/sdk-coin-algo/package.json index 616db1f7ee..b9ff7f70f4 100644 --- a/modules/sdk-coin-algo/package.json +++ b/modules/sdk-coin-algo/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-algo", - "version": "2.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Algorand", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,8 +40,8 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@hashgraph/cryptography": "1.1.2", "@stablelib/hex": "^1.0.0", "algosdk": "1.23.1", @@ -54,8 +54,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "should": "^13.1.3", "sinon": "^7.5.0" }, diff --git a/modules/sdk-coin-apechain/package.json b/modules/sdk-coin-apechain/package.json index 22cfc4c7a9..aa4fdeecbc 100644 --- a/modules/sdk-coin-apechain/package.json +++ b/modules/sdk-coin-apechain/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-apechain", - "version": "1.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Apechain", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-apt/package.json b/modules/sdk-coin-apt/package.json index 9c1663dea1..f1f56de1ed 100644 --- a/modules/sdk-coin-apt/package.json +++ b/modules/sdk-coin-apt/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-apt", - "version": "2.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for APT (Aptos) coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -41,15 +41,15 @@ }, "dependencies": { "@aptos-labs/ts-sdk": "1.33.1", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.1.2", "lodash": "^4.17.21" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-arbeth/package.json b/modules/sdk-coin-arbeth/package.json index 8fb31541b9..73215fa704 100644 --- a/modules/sdk-coin-arbeth/package.json +++ b/modules/sdk-coin-arbeth/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-arbeth", - "version": "21.8.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Arbitrum", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,17 +40,17 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "ethereumjs-abi": "^0.6.5", "ethereumjs-util": "7.1.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "secp256k1": "5.0.1" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-asi/package.json b/modules/sdk-coin-asi/package.json index 93422a8efa..a435e01ae7 100644 --- a/modules/sdk-coin-asi/package.json +++ b/modules/sdk-coin-asi/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-asi", - "version": "1.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Fetch Native (ASI)", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-atom/package.json b/modules/sdk-coin-atom/package.json index fbce22e8c8..e2f64aaa0a 100644 --- a/modules/sdk-coin-atom/package.json +++ b/modules/sdk-coin-atom/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-atom", - "version": "13.8.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Cosmos", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183", "axios": "^1.12.0" }, diff --git a/modules/sdk-coin-avaxc/package.json b/modules/sdk-coin-avaxc/package.json index 475d99af2c..1b6b803ac2 100644 --- a/modules/sdk-coin-avaxc/package.json +++ b/modules/sdk-coin-avaxc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-avaxc", - "version": "6.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Avalanche c-chain", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,12 +40,12 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-coin-avaxp": "^5.3.4", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "bignumber.js": "^9.1.1", "ethereumjs-abi": "^0.6.5", @@ -56,8 +56,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/keccak": "^3.0.5", "ethers": "^5.1.3" }, diff --git a/modules/sdk-coin-avaxp/package.json b/modules/sdk-coin-avaxp/package.json index 330a84aa71..064713743d 100644 --- a/modules/sdk-coin-avaxp/package.json +++ b/modules/sdk-coin-avaxp/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-avaxp", - "version": "5.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo's SDK coin library for avaxp coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -43,14 +43,14 @@ ] }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "dependencies": { "@bitgo-forks/avalanchejs": "4.1.0-alpha.1", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@noble/curves": "1.8.1", "avalanche": "3.15.3", "bignumber.js": "^9.0.0", diff --git a/modules/sdk-coin-baby/package.json b/modules/sdk-coin-baby/package.json index 56b1df3540..74ac391f0c 100644 --- a/modules/sdk-coin-baby/package.json +++ b/modules/sdk-coin-baby/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-baby", - "version": "1.7.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Babylon", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -41,9 +41,9 @@ }, "dependencies": { "@babylonlabs-io/babylon-proto-ts": "1.0.0", - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", @@ -52,8 +52,8 @@ "cosmjs-types": "^0.6.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-bch/package.json b/modules/sdk-coin-bch/package.json index 8a8442e78b..831eab27cd 100644 --- a/modules/sdk-coin-bch/package.json +++ b/modules/sdk-coin-bch/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bch", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bitcoin Cash", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-bcha/package.json b/modules/sdk-coin-bcha/package.json index 36bd879be6..870fb7ad60 100644 --- a/modules/sdk-coin-bcha/package.json +++ b/modules/sdk-coin-bcha/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bcha", - "version": "2.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bitcoin abc", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-coin-bch": "^2.3.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bch": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-bera/package.json b/modules/sdk-coin-bera/package.json index a8eb83fa7b..65c6ca5f2a 100644 --- a/modules/sdk-coin-bera/package.json +++ b/modules/sdk-coin-bera/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bera", - "version": "2.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bera", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-bld/package.json b/modules/sdk-coin-bld/package.json index fdce79aa1d..d871ad0d2e 100644 --- a/modules/sdk-coin-bld/package.json +++ b/modules/sdk-coin-bld/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bld", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Agoric", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-bsc/package.json b/modules/sdk-coin-bsc/package.json index 37f13621ef..be2a897aa7 100644 --- a/modules/sdk-coin-bsc/package.json +++ b/modules/sdk-coin-bsc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bsc", - "version": "22.7.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Binance Smart Chain", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-bsv/package.json b/modules/sdk-coin-bsv/package.json index 826e21c5cb..053e70e375 100644 --- a/modules/sdk-coin-bsv/package.json +++ b/modules/sdk-coin-bsv/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-bsv", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bitcoin sv", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-coin-bch": "^2.3.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bch": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-btc/package.json b/modules/sdk-coin-btc/package.json index 322c7b0751..856553f597 100644 --- a/modules/sdk-coin-btc/package.json +++ b/modules/sdk-coin-btc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-btc", - "version": "2.7.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bitcoin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0", - "@bitgo/utxo-ord": "^1.21.4" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", + "@bitgo/utxo-ord": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-btg/package.json b/modules/sdk-coin-btg/package.json index 7aafd3d07c..7084a55247 100644 --- a/modules/sdk-coin-btg/package.json +++ b/modules/sdk-coin-btg/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-btg", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Bitcoin Gold", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-celo/package.json b/modules/sdk-coin-celo/package.json index 27c3ae0483..1031dd2e0d 100644 --- a/modules/sdk-coin-celo/package.json +++ b/modules/sdk-coin-celo/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-celo", - "version": "5.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Celo", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@celo/connect": "^2.0.0", "@celo/contractkit": "^2.0.0", "@celo/wallet-base": "^2.0.0", @@ -55,8 +55,8 @@ "ethers": "^5.1.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "resolutions": { "form-data": "^4.0.4" diff --git a/modules/sdk-coin-coredao/package.json b/modules/sdk-coin-coredao/package.json index 5b2e5228d1..c733b475b9 100644 --- a/modules/sdk-coin-coredao/package.json +++ b/modules/sdk-coin-coredao/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-coredao", - "version": "2.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Coredao", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/tx": "^3.3.0", "bn.js": "^5.2.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-coreum/package.json b/modules/sdk-coin-coreum/package.json index 2d212ef110..fc6891e35c 100644 --- a/modules/sdk-coin-coreum/package.json +++ b/modules/sdk-coin-coreum/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-coreum", - "version": "21.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Coreum", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-cosmos/package.json b/modules/sdk-coin-cosmos/package.json index 6baf848ae3..df94ab7225 100644 --- a/modules/sdk-coin-cosmos/package.json +++ b/modules/sdk-coin-cosmos/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-cosmos", - "version": "1.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Cosmos", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-cronos/package.json b/modules/sdk-coin-cronos/package.json index 114d27338d..65def27293 100644 --- a/modules/sdk-coin-cronos/package.json +++ b/modules/sdk-coin-cronos/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-cronos", - "version": "1.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Cronos", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-cspr/package.json b/modules/sdk-coin-cspr/package.json index 49becbaf70..e0d2832f1c 100644 --- a/modules/sdk-coin-cspr/package.json +++ b/modules/sdk-coin-cspr/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-cspr", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Casper", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethersproject/bignumber": "^5.6.0", "@stablelib/hex": "^1.0.0", "bignumber.js": "^9.0.0", @@ -51,8 +51,8 @@ "secp256k1": "5.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "tweetnacl": "^1.0.3" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-dash/package.json b/modules/sdk-coin-dash/package.json index a61b9a0b9f..ebf3269da0 100644 --- a/modules/sdk-coin-dash/package.json +++ b/modules/sdk-coin-dash/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-dash", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Dash", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-doge/package.json b/modules/sdk-coin-doge/package.json index 0a0a2764c6..ac694b742a 100644 --- a/modules/sdk-coin-doge/package.json +++ b/modules/sdk-coin-doge/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-doge", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Dogecoin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-dot/package.json b/modules/sdk-coin-dot/package.json index 2223aaad26..e2f9b81bb3 100644 --- a/modules/sdk-coin-dot/package.json +++ b/modules/sdk-coin-dot/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-dot", - "version": "4.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Polkadot", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@polkadot/api": "14.1.1", "@polkadot/api-augment": "14.1.1", "@polkadot/keyring": "13.3.1", @@ -59,8 +59,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.151" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-eos/package.json b/modules/sdk-coin-eos/package.json index ea70f02a25..17d22a42e6 100644 --- a/modules/sdk-coin-eos/package.json +++ b/modules/sdk-coin-eos/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-eos", - "version": "3.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Eos", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.0.2", "eosjs": "^21.0.2", "eosjs-ecc": "^4.0.4", @@ -50,8 +50,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.121" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-etc/package.json b/modules/sdk-coin-etc/package.json index b34175e863..77062064ce 100644 --- a/modules/sdk-coin-etc/package.json +++ b/modules/sdk-coin-etc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-etc", - "version": "2.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ethereum classic", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,11 +40,11 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "bignumber.js": "^9.1.1", "ethereumjs-abi": "^0.6.5", @@ -53,8 +53,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-eth/package.json b/modules/sdk-coin-eth/package.json index 088acd2f0a..5ca608784f 100644 --- a/modules/sdk-coin-eth/package.json +++ b/modules/sdk-coin-eth/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-eth", - "version": "25.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ethereum", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/tx": "^3.3.0", "@ethereumjs/util": "8.0.3", "bignumber.js": "^9.1.1", @@ -55,8 +55,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "tweetnacl": "^1.0.3" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-ethlike/package.json b/modules/sdk-coin-ethlike/package.json index ae8df80995..dff496aabe 100644 --- a/modules/sdk-coin-ethlike/package.json +++ b/modules/sdk-coin-ethlike/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-ethlike", - "version": "2.1.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for EthLike coins", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "2.6.5", "ethereumjs-util": "7.1.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-ethw/package.json b/modules/sdk-coin-ethw/package.json index 390e307ac2..f400b62787 100644 --- a/modules/sdk-coin-ethw/package.json +++ b/modules/sdk-coin-ethw/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-ethw", - "version": "20.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ethereum pow", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "ethereumjs-util": "7.1.5", "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-evm/package.json b/modules/sdk-coin-evm/package.json index f7e881bb05..ca1249e917 100644 --- a/modules/sdk-coin-evm/package.json +++ b/modules/sdk-coin-evm/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-evm", - "version": "1.6.4", + "version": "0.0.0-semantic-release-managed", "description": "Configurable common module for EVM assets, using @bitgo/abstract-eth for reduced coin integration boilerplate.", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -16,9 +16,9 @@ "prepare": "npm run build" }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "author": "BitGo SDK Team ", diff --git a/modules/sdk-coin-flr/package.json b/modules/sdk-coin-flr/package.json index 21496946a3..3cd23e9fbe 100644 --- a/modules/sdk-coin-flr/package.json +++ b/modules/sdk-coin-flr/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-flr", - "version": "1.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Flr", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/tx": "^3.3.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-flrp/package.json b/modules/sdk-coin-flrp/package.json index c884e496be..2573897cbc 100644 --- a/modules/sdk-coin-flrp/package.json +++ b/modules/sdk-coin-flrp/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-flrp", - "version": "1.0.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo's SDK coin library for flrp coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -43,13 +43,13 @@ ] }, "devDependencies": { - "@bitgo/sdk-test": "^9.0.9", - "@bitgo/sdk-api": "^1.68.3" + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed" }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@flarenetwork/flarejs": "4.1.0-rc0", "bignumber.js": "9.0.0" }, diff --git a/modules/sdk-coin-hash/package.json b/modules/sdk-coin-hash/package.json index 0a1c1dfff0..2d5707f880 100644 --- a/modules/sdk-coin-hash/package.json +++ b/modules/sdk-coin-hash/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-hash", - "version": "3.5.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Provenance", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-hbar/package.json b/modules/sdk-coin-hbar/package.json index 23b141635f..f3dbe64640 100644 --- a/modules/sdk-coin-hbar/package.json +++ b/modules/sdk-coin-hbar/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-hbar", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Hbar", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-coin-algo": "^2.4.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-coin-algo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@hashgraph/proto": "2.12.0", "@hashgraph/sdk": "2.72.0", "@stablelib/sha384": "^1.0.0", @@ -54,8 +54,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-icp/package.json b/modules/sdk-coin-icp/package.json index cd746784e7..0a94aad63b 100644 --- a/modules/sdk-coin-icp/package.json +++ b/modules/sdk-coin-icp/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-icp", - "version": "1.18.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Internet Computer", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -41,10 +41,10 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@dfinity/agent": "^2.2.0", "@dfinity/candid": "^2.2.0", "@dfinity/principal": "^2.2.0", @@ -58,8 +58,8 @@ "protobufjs": "^7.5.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-initia/package.json b/modules/sdk-coin-initia/package.json index 4b258094de..22f95693c8 100644 --- a/modules/sdk-coin-initia/package.json +++ b/modules/sdk-coin-initia/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-initia", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Initia", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-injective/package.json b/modules/sdk-coin-injective/package.json index 88a441cca7..e91a96c289 100644 --- a/modules/sdk-coin-injective/package.json +++ b/modules/sdk-coin-injective/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-injective", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Injective", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-iota/package.json b/modules/sdk-coin-iota/package.json index 50673095f6..f2af18fe7d 100644 --- a/modules/sdk-coin-iota/package.json +++ b/modules/sdk-coin-iota/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-iota", - "version": "1.2.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for IOTA coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@iota/iota-sdk": "^1.6.0", "bignumber.js": "^9.1.2" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-islm/package.json b/modules/sdk-coin-islm/package.json index 0fae4f40ee..26e8e58e8b 100644 --- a/modules/sdk-coin-islm/package.json +++ b/modules/sdk-coin-islm/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-islm", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Islm", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", @@ -54,8 +54,8 @@ "protobufjs": "7.2.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/keccak": "^3.0.5" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-lnbtc/package.json b/modules/sdk-coin-lnbtc/package.json index 0689669cd6..3b090caf45 100644 --- a/modules/sdk-coin-lnbtc/package.json +++ b/modules/sdk-coin-lnbtc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-lnbtc", - "version": "1.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Lightning Bitcoin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-lightning": "^7.0.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-lightning": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-ltc/package.json b/modules/sdk-coin-ltc/package.json index 7d2b4240fd..e39fdc7ebe 100644 --- a/modules/sdk-coin-ltc/package.json +++ b/modules/sdk-coin-ltc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-ltc", - "version": "3.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Litecoin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-mantra/package.json b/modules/sdk-coin-mantra/package.json index b4929be8c1..b3608be0ed 100644 --- a/modules/sdk-coin-mantra/package.json +++ b/modules/sdk-coin-mantra/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-mantra", - "version": "1.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Mantra", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-mon/package.json b/modules/sdk-coin-mon/package.json index ddd78d664f..84344b2dd7 100644 --- a/modules/sdk-coin-mon/package.json +++ b/modules/sdk-coin-mon/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-mon", - "version": "1.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Mon", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-near/package.json b/modules/sdk-coin-near/package.json index a5f9769a07..046ec3b11c 100644 --- a/modules/sdk-coin-near/package.json +++ b/modules/sdk-coin-near/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-near", - "version": "2.10.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Near", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@near-js/crypto": "^2.0.1", "@near-js/transactions": "^2.0.1", "@stablelib/hex": "^1.0.0", @@ -55,8 +55,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.121" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-oas/package.json b/modules/sdk-coin-oas/package.json index e058998129..19629fadc9 100644 --- a/modules/sdk-coin-oas/package.json +++ b/modules/sdk-coin-oas/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-oas", - "version": "2.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Oasys", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-opeth/package.json b/modules/sdk-coin-opeth/package.json index 16dedb888a..8a458355b7 100644 --- a/modules/sdk-coin-opeth/package.json +++ b/modules/sdk-coin-opeth/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-opeth", - "version": "18.6.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Optimism", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,17 +40,17 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "ethereumjs-abi": "^0.6.5", "ethereumjs-util": "7.1.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "secp256k1": "5.0.1" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-osmo/package.json b/modules/sdk-coin-osmo/package.json index 0ec51019e1..46b92df4a1 100644 --- a/modules/sdk-coin-osmo/package.json +++ b/modules/sdk-coin-osmo/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-osmo", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Osmosis", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-polygon/package.json b/modules/sdk-coin-polygon/package.json index 8bad2a63f0..f2b3abbf24 100644 --- a/modules/sdk-coin-polygon/package.json +++ b/modules/sdk-coin-polygon/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-polygon", - "version": "21.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Polygon", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,11 +40,11 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/sjcl": "^1.0.1", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/sjcl": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "bignumber.js": "^9.1.2", "ethereumjs-abi": "^0.6.5", @@ -52,8 +52,8 @@ "ethers": "^5.1.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "secp256k1": "5.0.1" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-polyx/package.json b/modules/sdk-coin-polyx/package.json index 85fdac6de2..f19680cd2b 100644 --- a/modules/sdk-coin-polyx/package.json +++ b/modules/sdk-coin-polyx/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-polyx", - "version": "1.9.3", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for POLYX (Polymesh) coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/abstract-substrate": "^1.10.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-substrate": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@polkadot/api": "14.1.1", "@polkadot/keyring": "13.3.1", "@substrate/txwrapper-core": "7.5.2", @@ -52,7 +52,7 @@ "joi": "^17.4.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-rbtc/package.json b/modules/sdk-coin-rbtc/package.json index aa929119fd..e0c6a2e352 100644 --- a/modules/sdk-coin-rbtc/package.json +++ b/modules/sdk-coin-rbtc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-rbtc", - "version": "2.2.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Rootstock rsk", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "ethereumjs-abi": "^0.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-rune/package.json b/modules/sdk-coin-rune/package.json index f1be3b2440..9aec745ed4 100644 --- a/modules/sdk-coin-rune/package.json +++ b/modules/sdk-coin-rune/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-rune", - "version": "1.5.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Thorchain", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", @@ -52,8 +52,8 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-sei/package.json b/modules/sdk-coin-sei/package.json index 482db47b46..8ba1112e5c 100644 --- a/modules/sdk-coin-sei/package.json +++ b/modules/sdk-coin-sei/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-sei", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Sei", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-sgb/package.json b/modules/sdk-coin-sgb/package.json index addb361e7b..fd19b03426 100644 --- a/modules/sdk-coin-sgb/package.json +++ b/modules/sdk-coin-sgb/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-sgb", - "version": "1.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Sgb", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/tx": "^3.3.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-sol/package.json b/modules/sdk-coin-sol/package.json index ef28ecd595..8fa6a01d46 100644 --- a/modules/sdk-coin-sol/package.json +++ b/modules/sdk-coin-sol/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-sol", - "version": "6.1.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Sol", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -41,9 +41,9 @@ }, "dependencies": { "@bitgo/public-types": "5.18.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@solana/spl-stake-pool": "1.1.8", "@solana/spl-token": "0.3.1", "@solana/web3.js": "1.92.1", @@ -54,8 +54,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.121" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-soneium/package.json b/modules/sdk-coin-soneium/package.json index e72266d071..a956022a99 100644 --- a/modules/sdk-coin-soneium/package.json +++ b/modules/sdk-coin-soneium/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-soneium", - "version": "1.7.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Soneium", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "ethereumjs-util": "^7.1.5", "superagent": "^10.2.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-stt/package.json b/modules/sdk-coin-stt/package.json index 942c098faa..7b5f6667ab 100644 --- a/modules/sdk-coin-stt/package.json +++ b/modules/sdk-coin-stt/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-stt", - "version": "1.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Somnia", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-stx/package.json b/modules/sdk-coin-stx/package.json index b96e235525..95ff72ab73 100644 --- a/modules/sdk-coin-stx/package.json +++ b/modules/sdk-coin-stx/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-stx", - "version": "3.9.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Stacks", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@noble/curves": "1.8.1", "@stacks/network": "^4.3.0", "@stacks/transactions": "2.0.1", @@ -52,8 +52,8 @@ "lodash": "^4.17.15" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-sui/package.json b/modules/sdk-coin-sui/package.json index e94eeb639f..d353a27dba 100644 --- a/modules/sdk-coin-sui/package.json +++ b/modules/sdk-coin-sui/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-sui", - "version": "5.18.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Sui", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/blake2b": "^3.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/blake2b": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@mysten/bcs": "^0.7.0", "bignumber.js": "^9.0.0", "bs58": "^4.0.1", @@ -53,8 +53,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183", "axios": "^1.12.0", "debug": "^4.3.4" diff --git a/modules/sdk-coin-tao/package.json b/modules/sdk-coin-tao/package.json index 5db68f1aad..776cb7af40 100644 --- a/modules/sdk-coin-tao/package.json +++ b/modules/sdk-coin-tao/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-tao", - "version": "1.11.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for TAO (Bittensor) coin", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,17 +40,17 @@ ] }, "dependencies": { - "@bitgo/abstract-substrate": "^1.10.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-substrate": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@polkadot/api": "14.1.1", "@substrate/txwrapper-core": "7.5.2", "@substrate/txwrapper-polkadot": "7.5.2", "bignumber.js": "^9.0.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-tia/package.json b/modules/sdk-coin-tia/package.json index c19b687d56..c3b56d4965 100644 --- a/modules/sdk-coin-tia/package.json +++ b/modules/sdk-coin-tia/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-tia", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Celestia", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-ton/package.json b/modules/sdk-coin-ton/package.json index c740571e21..f73fcd7087 100644 --- a/modules/sdk-coin-ton/package.json +++ b/modules/sdk-coin-ton/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-ton", - "version": "3.8.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ton", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.0.0", "bn.js": "^5.2.1", "lodash": "^4.17.21", @@ -50,8 +50,8 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-trx/package.json b/modules/sdk-coin-trx/package.json index 1f08e2c067..90f3efe402 100644 --- a/modules/sdk-coin-trx/package.json +++ b/modules/sdk-coin-trx/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-trx", - "version": "3.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Tron", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -46,9 +46,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@stablelib/hex": "^1.0.0", "bignumber.js": "^9.0.0", "ethers": "^5.7.2", @@ -60,8 +60,8 @@ "tronweb": "5.1.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "shx": "^0.3.4" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-vet/package.json b/modules/sdk-coin-vet/package.json index 11779354f9..911305df7a 100644 --- a/modules/sdk-coin-vet/package.json +++ b/modules/sdk-coin-vet/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-vet", - "version": "2.5.3", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for VeChain", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,11 +40,11 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/blake2b": "^3.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/blake2b": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@noble/curves": "1.8.1", "@vechain/sdk-core": "^1.2.0-rc.3", "bignumber.js": "^9.1.1", @@ -54,7 +54,7 @@ "tweetnacl": "^1.0.3" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-wemix/package.json b/modules/sdk-coin-wemix/package.json index b31a9405b1..4c7b7149b7 100644 --- a/modules/sdk-coin-wemix/package.json +++ b/modules/sdk-coin-wemix/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-wemix", - "version": "1.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Wemix", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,14 +40,14 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/tx": "^3.3.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-world/package.json b/modules/sdk-coin-world/package.json index 66242398a5..62ae1c26dc 100644 --- a/modules/sdk-coin-world/package.json +++ b/modules/sdk-coin-world/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-world", - "version": "1.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for World", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,13 +40,13 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" } } diff --git a/modules/sdk-coin-xdc/package.json b/modules/sdk-coin-xdc/package.json index 32edb5b8e3..aec74e3fd0 100644 --- a/modules/sdk-coin-xdc/package.json +++ b/modules/sdk-coin-xdc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-xdc", - "version": "1.4.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Xdc", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5", "@ethereumjs/tx": "^3.3.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-xlm/package.json b/modules/sdk-coin-xlm/package.json index 956be63803..ca4f46f5f5 100644 --- a/modules/sdk-coin-xlm/package.json +++ b/modules/sdk-coin-xlm/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-xlm", - "version": "3.5.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Xlm", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,16 +40,16 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.1.1", "lodash": "^4.17.14", "stellar-sdk": "^10.0.1", "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-xrp/package.json b/modules/sdk-coin-xrp/package.json index 86b70b1d06..534a9df052 100644 --- a/modules/sdk-coin-xrp/package.json +++ b/modules/sdk-coin-xrp/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-xrp", - "version": "3.10.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Ripple", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,9 +40,9 @@ ] }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "bignumber.js": "^9.0.0", "lodash": "^4.17.14", "ripple-binary-codec": "2.1.0", @@ -50,8 +50,8 @@ "xrpl": "4.0.0" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-xtz/package.json b/modules/sdk-coin-xtz/package.json index c6dd5f1e8c..c711f2183f 100644 --- a/modules/sdk-coin-xtz/package.json +++ b/modules/sdk-coin-xtz/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-xtz", - "version": "2.7.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Tezos", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,10 +40,10 @@ ] }, "dependencies": { - "@bitgo/blake2b": "^3.2.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/blake2b": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@noble/curves": "1.8.1", "@taquito/local-forging": "6.3.5-beta.0", "@taquito/signer": "6.3.5-beta.0", @@ -54,8 +54,8 @@ "superagent": "^9.0.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-zec/package.json b/modules/sdk-coin-zec/package.json index 7c5b6194e6..c3d2775bae 100644 --- a/modules/sdk-coin-zec/package.json +++ b/modules/sdk-coin-zec/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-zec", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Zcash", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,12 +40,12 @@ ] }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" } diff --git a/modules/sdk-coin-zeta/package.json b/modules/sdk-coin-zeta/package.json index 1ce42a2fdf..a5d4be8cc2 100644 --- a/modules/sdk-coin-zeta/package.json +++ b/modules/sdk-coin-zeta/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-zeta", - "version": "3.4.2", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for Zeta", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,18 +40,18 @@ ] }, "dependencies": { - "@bitgo/abstract-cosmos": "^11.14.2", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-cosmos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@cosmjs/amino": "^0.29.5", "@cosmjs/encoding": "^0.29.5", "@cosmjs/stargate": "^0.29.5", "bignumber.js": "^9.1.1" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "@types/lodash": "^4.14.183" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-coin-zketh/package.json b/modules/sdk-coin-zketh/package.json index db6159c3b0..5235e56928 100644 --- a/modules/sdk-coin-zketh/package.json +++ b/modules/sdk-coin-zketh/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-coin-zketh", - "version": "2.3.4", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK coin library for zkSync", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -40,15 +40,15 @@ ] }, "dependencies": { - "@bitgo/abstract-eth": "^24.12.0", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/statics": "^57.8.0", + "@bitgo/abstract-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", "@ethereumjs/common": "^2.6.5" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-test": "^9.0.9", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed", "secp256k1": "5.0.1" }, "gitHead": "18e460ddf02de2dbf13c2aa243478188fb539f0c" diff --git a/modules/sdk-core/package.json b/modules/sdk-core/package.json index 76c55232c0..4841f80f0e 100644 --- a/modules/sdk-core/package.json +++ b/modules/sdk-core/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-core", - "version": "36.8.0", + "version": "0.0.0-semantic-release-managed", "description": "core library functions for BitGoJS", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -38,12 +38,12 @@ }, "dependencies": { "@bitgo/public-types": "5.22.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/secp256k1": "^1.5.0", - "@bitgo/sjcl": "^1.0.1", - "@bitgo/statics": "^57.8.0", - "@bitgo/utxo-core": "^1.19.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/secp256k1": "0.0.0-semantic-release-managed", + "@bitgo/sjcl": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", + "@bitgo/utxo-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@noble/curves": "1.8.1", "@stablelib/hex": "^1.0.0", "@types/superagent": "4.1.15", @@ -70,7 +70,7 @@ "uuid": "^8.3.2" }, "devDependencies": { - "@bitgo/sdk-opensslbytes": "^2.0.0", + "@bitgo/sdk-opensslbytes": "0.0.0-semantic-release-managed", "@openpgp/web-stream-tools": "0.0.14", "@types/keccak": "^3.0.5", "@types/lodash": "^4.14.151", diff --git a/modules/sdk-hmac/package.json b/modules/sdk-hmac/package.json index 1bc62bc557..86ec3affa7 100644 --- a/modules/sdk-hmac/package.json +++ b/modules/sdk-hmac/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-hmac", - "version": "1.2.0", + "version": "0.0.0-semantic-release-managed", "description": "HMAC module for the BitGo SDK", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -16,7 +16,7 @@ "prepare": "npm run build" }, "dependencies": { - "@bitgo/sjcl": "^1.0.1" + "@bitgo/sjcl": "0.0.0-semantic-release-managed" }, "devDependencies": { "chai": "^4.3.6", diff --git a/modules/sdk-lib-mpc/package.json b/modules/sdk-lib-mpc/package.json index c7d206a810..2156882063 100644 --- a/modules/sdk-lib-mpc/package.json +++ b/modules/sdk-lib-mpc/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-lib-mpc", - "version": "10.7.0", + "version": "0.0.0-semantic-release-managed", "description": "library functions for BitGo's MPC solution", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -52,7 +52,7 @@ "secp256k1": "5.0.1" }, "devDependencies": { - "@bitgo/sdk-opensslbytes": "^2.0.0", + "@bitgo/sdk-opensslbytes": "0.0.0-semantic-release-managed", "@silencelaboratories/dkls-wasm-ll-bundler": "1.2.0-pre.4", "@types/lodash": "^4.14.151", "@types/node": "^22.15.29", diff --git a/modules/sdk-opensslbytes/package.json b/modules/sdk-opensslbytes/package.json index a7bf97dea5..1510bd4147 100644 --- a/modules/sdk-opensslbytes/package.json +++ b/modules/sdk-opensslbytes/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-opensslbytes", - "version": "2.0.0", + "version": "0.0.0-semantic-release-managed", "description": "Split package for WASM code needed by sdk-lib-mpc", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", diff --git a/modules/sdk-rpc-wrapper/package.json b/modules/sdk-rpc-wrapper/package.json index fb2b3b0dd2..e06ce22341 100644 --- a/modules/sdk-rpc-wrapper/package.json +++ b/modules/sdk-rpc-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-rpc-wrapper", - "version": "2.2.4", + "version": "0.0.0-semantic-release-managed", "description": "Bitgo SDK wrapper to handle EVM RPC events", "main": "./dist/src/index.js", "type": "./dist/src/index.d.ts", @@ -13,12 +13,12 @@ "fmt": "prettier --write '{src,test}/**/*.{ts,js,json}'" }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0" + "@bitgo/sdk-core": "0.0.0-semantic-release-managed" }, "devDependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-test": "^9.0.9" + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-test": "0.0.0-semantic-release-managed" }, "author": "Bitgo DEFI Team ", "license": "MIT", diff --git a/modules/sdk-test/package.json b/modules/sdk-test/package.json index 3b0955c9fd..62c04a775d 100644 --- a/modules/sdk-test/package.json +++ b/modules/sdk-test/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sdk-test", - "version": "9.0.9", + "version": "0.0.0-semantic-release-managed", "private": "true", "description": "coin test libary for BitGoJS", "main": "./dist/src/index.js", @@ -27,8 +27,8 @@ ] }, "dependencies": { - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-core": "^36.8.0", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", "bignumber.js": "^9.1.1", "should-http": "^0.1.1" } diff --git a/modules/secp256k1/package.json b/modules/secp256k1/package.json index 2221fb99db..400a608b90 100644 --- a/modules/secp256k1/package.json +++ b/modules/secp256k1/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/secp256k1", - "version": "1.5.0", + "version": "0.0.0-semantic-release-managed", "description": "Low-level cryptographic methods used in BitGo packages for the secp256k1 curve", "main": "./dist/src/index.js", "engines": { diff --git a/modules/sjcl/package.json b/modules/sjcl/package.json index 7b63019ca7..5365cfd251 100644 --- a/modules/sjcl/package.json +++ b/modules/sjcl/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/sjcl", - "version": "1.0.1", + "version": "0.0.0-semantic-release-managed", "description": "fork of Stanford Javascript Crypto Library", "main": "sjcl.min.js", "author": "BitGo SDK Team ", diff --git a/modules/statics/package.json b/modules/statics/package.json index 0151b4b36d..4f7ede208c 100644 --- a/modules/statics/package.json +++ b/modules/statics/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/statics", - "version": "57.8.0", + "version": "0.0.0-semantic-release-managed", "description": "dependency-free static configuration for the bitgo platform", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", diff --git a/modules/unspents/package.json b/modules/unspents/package.json index 0e97701351..8831d5c9da 100644 --- a/modules/unspents/package.json +++ b/modules/unspents/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/unspents", - "version": "0.49.0", + "version": "0.0.0-semantic-release-managed", "description": "Defines the chain codes used for different unspent types and methods to calculate bitcoin transaction sizes", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -36,7 +36,7 @@ "should": "~13.2.3" }, "dependencies": { - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "lodash": "~4.17.21", "tcomb": "~3.2.29", "varuint-bitcoin": "^1.0.4" diff --git a/modules/utxo-bin/package.json b/modules/utxo-bin/package.json index f50bfeeba4..35393e692f 100644 --- a/modules/utxo-bin/package.json +++ b/modules/utxo-bin/package.json @@ -1,7 +1,7 @@ { "name": "@bitgo/utxo-bin", "description": "Command-line utility for BitGo UTXO transactions", - "version": "3.9.3", + "version": "0.0.0-semantic-release-managed", "files": [ "dist/**/*" ], @@ -26,11 +26,11 @@ }, "bin": "./dist/bin/index.js", "dependencies": { - "@bitgo/blockapis": "^1.11.0", - "@bitgo/statics": "^57.8.0", - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-core": "^1.19.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/blockapis": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@bitgo/wasm-miniscript": "2.0.0-beta.7", "@noble/curves": "1.8.1", "archy": "^1.0.0", diff --git a/modules/utxo-core/package.json b/modules/utxo-core/package.json index a1e90153ee..cdff9fe961 100644 --- a/modules/utxo-core/package.json +++ b/modules/utxo-core/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/utxo-core", - "version": "1.19.0", + "version": "0.0.0-semantic-release-managed", "description": "BitGo UTXO Core types", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -52,8 +52,8 @@ ] }, "dependencies": { - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@bitgo/wasm-miniscript": "2.0.0-beta.7", "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", "bitcoinjs-message": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.3", diff --git a/modules/utxo-lib/package.json b/modules/utxo-lib/package.json index bc4baec55b..9eae604874 100644 --- a/modules/utxo-lib/package.json +++ b/modules/utxo-lib/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/utxo-lib", - "version": "11.10.0", + "version": "0.0.0-semantic-release-managed", "description": "Client-side Bitcoin JavaScript library", "main": "./dist/src/index.js", "engines": { @@ -46,7 +46,7 @@ "dist/src" ], "dependencies": { - "@bitgo/blake2b": "^3.2.4", + "@bitgo/blake2b": "0.0.0-semantic-release-managed", "@brandonblack/musig": "^0.0.1-alpha.0", "@noble/curves": "1.8.1", "@noble/secp256k1": "1.6.3", diff --git a/modules/utxo-ord/package.json b/modules/utxo-ord/package.json index 106c714119..8a7572ace6 100644 --- a/modules/utxo-ord/package.json +++ b/modules/utxo-ord/package.json @@ -3,7 +3,7 @@ "description": "Utilities for building ordinals with BitGo utxo-lib", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", - "version": "1.21.4", + "version": "0.0.0-semantic-release-managed", "files": [ "dist/**/*" ], @@ -28,9 +28,9 @@ "directory": "modules/utxo-ord" }, "dependencies": { - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/unspents": "^0.49.0", - "@bitgo/utxo-lib": "^11.10.0" + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/unspents": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed" }, "lint-staged": { "*.{js,ts}": [ diff --git a/modules/utxo-staking/package.json b/modules/utxo-staking/package.json index 4686a91e65..d304c3b6f9 100644 --- a/modules/utxo-staking/package.json +++ b/modules/utxo-staking/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/utxo-staking", - "version": "1.21.3", + "version": "0.0.0-semantic-release-managed", "description": "BitGo SDK for build UTXO staking transactions", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", @@ -44,9 +44,9 @@ "type": "commonjs", "dependencies": { "@babylonlabs-io/babylon-proto-ts": "1.0.0", - "@bitgo/babylonlabs-io-btc-staking-ts": "^2.4.1", - "@bitgo/utxo-core": "^1.19.0", - "@bitgo/utxo-lib": "^11.10.0", + "@bitgo/babylonlabs-io-btc-staking-ts": "0.0.0-semantic-release-managed", + "@bitgo/utxo-core": "0.0.0-semantic-release-managed", + "@bitgo/utxo-lib": "0.0.0-semantic-release-managed", "@bitgo/wasm-miniscript": "2.0.0-beta.7", "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", "bip322-js": "^2.0.0", diff --git a/modules/web-demo/package.json b/modules/web-demo/package.json index 1b69402dbc..3828baaf03 100644 --- a/modules/web-demo/package.json +++ b/modules/web-demo/package.json @@ -1,6 +1,6 @@ { "name": "@bitgo/web-demo", - "version": "3.2.11", + "version": "0.0.0-semantic-release-managed", "description": "BitGoJS Web demo package", "repository": { "type": "git", @@ -24,46 +24,46 @@ "precommit": "yarn lint-staged" }, "dependencies": { - "@bitgo/abstract-utxo": "^9.26.0", - "@bitgo/key-card": "^0.27.4", - "@bitgo/sdk-api": "^1.68.3", - "@bitgo/sdk-coin-ada": "^4.14.0", - "@bitgo/sdk-coin-algo": "^2.4.4", - "@bitgo/sdk-coin-avaxc": "^6.3.4", - "@bitgo/sdk-coin-avaxp": "^5.3.4", - "@bitgo/sdk-coin-bch": "^2.3.4", - "@bitgo/sdk-coin-bcha": "^2.4.4", - "@bitgo/sdk-coin-bsc": "^22.7.2", - "@bitgo/sdk-coin-bsv": "^2.3.4", - "@bitgo/sdk-coin-btc": "^2.7.4", - "@bitgo/sdk-coin-btg": "^2.3.4", - "@bitgo/sdk-coin-celo": "^5.2.4", - "@bitgo/sdk-coin-cspr": "^2.3.4", - "@bitgo/sdk-coin-dash": "^2.3.4", - "@bitgo/sdk-coin-doge": "^2.3.4", - "@bitgo/sdk-coin-dot": "^4.4.4", - "@bitgo/sdk-coin-eos": "^3.4.4", - "@bitgo/sdk-coin-etc": "^2.4.4", - "@bitgo/sdk-coin-eth": "^25.2.4", - "@bitgo/sdk-coin-ethw": "^20.2.4", - "@bitgo/sdk-coin-hbar": "^2.3.4", - "@bitgo/sdk-coin-ltc": "^3.3.4", - "@bitgo/sdk-coin-near": "^2.10.4", - "@bitgo/sdk-coin-polygon": "^21.4.4", - "@bitgo/sdk-coin-rbtc": "^2.2.4", - "@bitgo/sdk-coin-sol": "^6.1.4", - "@bitgo/sdk-coin-stx": "^3.9.4", - "@bitgo/sdk-coin-sui": "^5.18.4", - "@bitgo/sdk-coin-trx": "^3.5.4", - "@bitgo/sdk-coin-xlm": "^3.5.4", - "@bitgo/sdk-coin-xrp": "^3.10.4", - "@bitgo/sdk-coin-xtz": "^2.7.4", - "@bitgo/sdk-coin-zec": "^2.3.4", - "@bitgo/sdk-core": "^36.8.0", - "@bitgo/sdk-lib-mpc": "^10.7.0", - "@bitgo/sdk-opensslbytes": "^2.0.0", - "@bitgo/statics": "^57.8.0", - "bitgo": "^50.0.0", + "@bitgo/abstract-utxo": "0.0.0-semantic-release-managed", + "@bitgo/key-card": "0.0.0-semantic-release-managed", + "@bitgo/sdk-api": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ada": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-algo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-avaxp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bch": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bcha": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bsc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-bsv": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-btc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-btg": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-celo": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-cspr": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-dash": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-doge": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-dot": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eos": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-etc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-eth": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ethw": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-hbar": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-ltc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-near": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-polygon": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-rbtc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sol": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-stx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-sui": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-trx": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xlm": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xrp": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-xtz": "0.0.0-semantic-release-managed", + "@bitgo/sdk-coin-zec": "0.0.0-semantic-release-managed", + "@bitgo/sdk-core": "0.0.0-semantic-release-managed", + "@bitgo/sdk-lib-mpc": "0.0.0-semantic-release-managed", + "@bitgo/sdk-opensslbytes": "0.0.0-semantic-release-managed", + "@bitgo/statics": "0.0.0-semantic-release-managed", + "bitgo": "0.0.0-semantic-release-managed", "lodash": "^4.17.15", "react": "^17.0.2", "react-dom": "^17.0.2", @@ -96,10 +96,15 @@ "ts-loader": "^9.1.2" }, "lint-staged": { - "*.{js,ts,tsx}": ["yarn prettier --write", "yarn eslint --fix"] + "*.{js,ts,tsx}": [ + "yarn prettier --write", + "yarn eslint --fix" + ] }, "nyc": { - "extension": [".ts"] + "extension": [ + ".ts" + ] }, "resolutions": { "@types/react": "17.0.24", diff --git a/package.json b/package.json index 384f69b77e..8834c12d60 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,6 @@ "check-fmt": "lerna run check-fmt --stream --parallel", "check-commits": "yarn commitlint --from=origin/${GITHUB_REPO_BRANCH:-master} -V", "check-deps": "tsx ./scripts/check-package-dependencies.ts", - "check-versions": "node ./check-package-versions.js", "dev": "tsc -b ./tsconfig.packages.json -w", "prepare": "husky install", "sdk-coin:new": "yo ./scripts/sdk-coin-generator", From 7eeac071a0e6b7930a4eb0578049509bc260e0b2 Mon Sep 17 00:00:00 2001 From: Zahin Mohammad Date: Mon, 22 Sep 2025 19:02:04 -0400 Subject: [PATCH 21/35] fix: prepare-release should work with latest preid This commit updates the prepare-release script to work with the `@bitgo` stable relase org as well as the latest preid. The script will use conventional commits for a specific module to generate the next increment to use for the next version. TICKET: WP-6047 --- .github/workflows/publish.yml | 2 +- .gitignore | 1 + package.json | 2 + scripts/pack-scoped.ts | 13 +- scripts/prepare-release.ts | 211 +++--------------- scripts/prepareRelease/changePackageJson.ts | 16 -- scripts/prepareRelease/changeScopeInFile.ts | 22 -- scripts/prepareRelease/distTags.ts | 118 ++++++++-- scripts/prepareRelease/getLernaModules.ts | 29 --- scripts/prepareRelease/incrementVersions.ts | 164 ++++++++++++++ scripts/prepareRelease/index.ts | 6 +- scripts/prepareRelease/lernaModules.ts | 85 +++++++ scripts/prepareRelease/mutateScope.ts | 81 +++++++ .../prepareRelease/validateTransformations.ts | 28 +++ scripts/verify-release.ts | 16 +- yarn.lock | 40 ++++ 16 files changed, 545 insertions(+), 289 deletions(-) delete mode 100644 scripts/prepareRelease/changePackageJson.ts delete mode 100644 scripts/prepareRelease/changeScopeInFile.ts delete mode 100644 scripts/prepareRelease/getLernaModules.ts create mode 100644 scripts/prepareRelease/incrementVersions.ts create mode 100644 scripts/prepareRelease/lernaModules.ts create mode 100644 scripts/prepareRelease/mutateScope.ts create mode 100644 scripts/prepareRelease/validateTransformations.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8f02bc6c71..8c522e2b8c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,7 +26,7 @@ jobs: node-version-file: .nvmrc - name: Install BitGoJS - run: yarn install --with-frozen-lockfile + run: yarn install --with-frozen-lockfile --ignore-scripts - name: Set Environment Variable for Alpha if: github.ref != 'refs/heads/master' # only publish changes if on feature branches diff --git a/.gitignore b/.gitignore index ea25569120..1bec7be5a9 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ modules/**/pack-scoped/ coverage /.direnv/ .claude/ +scripts/cache/ diff --git a/package.json b/package.json index 8834c12d60..d86a19f2fc 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@typescript-eslint/parser": "^4.23.0", "babel-loader": "^9.1.0", "buffer": "^6.0.3", + "conventional-commits-parser": "6.2.0", "cross-env": "^7.0.3", "crypto-browserify": "^3.12.0", "depcheck": "^1.4.3", @@ -45,6 +46,7 @@ "should": "^13.1.3", "should-http": "^0.1.1", "should-sinon": "^0.0.6", + "simple-git": "^3.28.0", "sinon": "^6.3.5", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", diff --git a/scripts/pack-scoped.ts b/scripts/pack-scoped.ts index 4259622868..5273af5e9b 100644 --- a/scripts/pack-scoped.ts +++ b/scripts/pack-scoped.ts @@ -9,19 +9,20 @@ import execa from 'execa'; import mpath from 'path'; import yargs from 'yargs'; import { + LernaModule, walk, - getLernaModules, changeScopeInFile, - getDistTagsForModuleNames, + DistTags, updateModuleNames, + getDistTagsForModuleNames, setDependencyVersion, - DistTags, - LernaModule, + getLernaModules, getNewModuleName, } from './prepareRelease'; /** The directory to pack the module into */ const scopedPackageDir = 'pack-scoped'; +const uninitializedModules = process.env.UNINITIALIZED_MODULES ? process.env.UNINITIALIZED_MODULES.split(',') : []; async function changeModuleScope(dir: string, params: { lernaModules: LernaModule[]; scope: string }) { console.log(`Changing scope of module at ${dir} to ${params.scope}`); @@ -43,7 +44,7 @@ async function changeModuleVersions( } ) { const newModuleNames = params.moduleNames.map((m) => updateModuleNames(m, params.moduleNames, params.scope)); - const { distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames) } = params; + const { distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames, uninitializedModules, 'beta') } = params; const packageJsonPath = mpath.join(dir, 'package.json'); const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, 'utf-8')); newModuleNames.forEach((m) => { @@ -104,7 +105,7 @@ async function getDistTagsForModuleNamesCached( } } - const distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames); + const distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames, uninitializedModules, 'beta'); if (params.cache) { console.log(`Caching dist tags to ${params.cache}`); await fs.promises.writeFile(params.cache, JSON.stringify([...distTagsByModuleName.entries()], null, 2) + '\n'); diff --git a/scripts/prepare-release.ts b/scripts/prepare-release.ts index 235ca086b9..1c4f563688 100644 --- a/scripts/prepare-release.ts +++ b/scripts/prepare-release.ts @@ -1,171 +1,27 @@ -import assert from 'node:assert'; -import { readFileSync, writeFileSync } from 'fs'; -import path from 'path'; -import { inc, lt } from 'semver'; -import yargs from 'yargs'; -import { hideBin } from 'yargs/helpers'; - -import { - walk, - getDistTagsForModules, - getLernaModules, - changeScopeInFile, - setDependencyVersion, - DistTags, - LernaModule, -} from './prepareRelease'; - -function replacePackageScopes( - rootDir: string, - lernaModules: LernaModule[], - targetScope: string, -): number { - let filesChanged = 0; - // replace all @bitgo packages & source code with alternate SCOPE - const filePaths = [ - ...walk(path.join(rootDir, 'modules')), - ...walk(path.join(rootDir, 'webpack')), - ]; - const moduleNames = lernaModules.map(({ name }) => name); - - filePaths.forEach((file) => { - filesChanged += changeScopeInFile(file, moduleNames, targetScope); - }); - return filesChanged; -} - -// modules/bitgo is the only package we publish without an `@bitgo` prefix, so -// we must manually set one -function replaceBitGoPackageScope(rootDir: string, targetScope: string): void { - const cwd = path.join(rootDir, 'modules', 'bitgo'); - const json = JSON.parse( - readFileSync(path.join(cwd, 'package.json'), { encoding: 'utf-8' }), - ); - json.name = `${targetScope}/bitgo`; - writeFileSync( - path.join(cwd, 'package.json'), - JSON.stringify(json, null, 2) + '\n', - ); -} - -/** - * Read package.json for a module - * @param module The module to read package.json from - * @returns The parsed package.json content - */ -function readModulePackageJson(module: LernaModule): any { - return JSON.parse( - readFileSync(path.join(module.location, 'package.json'), { - encoding: 'utf-8', - }), - ); -} - -/** - * Write package.json for a module - * @param module The module to write package.json to - * @param json The content to write - */ -function writeModulePackageJson(module: LernaModule, json: any): void { - writeFileSync( - path.join(module.location, 'package.json'), - JSON.stringify(json, null, 2) + '\n', - ); -} - /** - * Increment the version for a single module based on the preid. + * Usage: + * # to prepare a stable release on the stable channel + * npx tsx ./scripts/prepare-release.ts latest --scope @bitgo * - * @param {String} preid - The prerelease identifier - * @param {LernaModule} module - The module to update - * @param {DistTags|undefined} tags - The dist tags for the module - * @param {LernaModule[]} allModules - All modules for dependency updates - * @returns {String|undefined} - The new version if set, undefined otherwise + * # to prepare a beta release in the beta organization + * npx tsx ./scripts/prepare-release.ts beta --scope @bitgo-beta + * + * # to skip uninitialized modules, set the UNINITIALIZED_MODULES env var + * # if modules are not initialized and are not skipped, they will fail + * UNINITIALIZED_MODULES=@bitgo/sdk-coin-flrp npx tsx ./scripts/prepare-release.ts latest --scope @bitgo */ -function incrementVersionsForModuleLocation( - preid: string, - module: LernaModule, - tags: DistTags | undefined, - allModules: LernaModule[], -): string | undefined { - const json = readModulePackageJson(module); - - let prevTag: string | undefined = undefined; - - if (tags) { - if (tags[preid]) { - const version = tags[preid].split('-'); - const latest = tags?.latest?.split('-') ?? ['0.0.0']; - prevTag = lt(version[0], latest[0]) - ? `${tags.latest}-${preid}` - : tags[preid]; - } else { - prevTag = `${tags.latest}-${preid}`; - } - } - if (prevTag) { - const next = inc(prevTag, 'prerelease', undefined, preid); - assert( - typeof next === 'string', - `Failed to increment version for ${json.name} prevTag=${prevTag}`, - ); - console.log(`Setting next version for ${json.name} to ${next}`); - json.version = next; - writeModulePackageJson(module, json); - - // since we're manually setting new versions, we must also reconcile all other lerna packages to use the 'next' version for this module - allModules.forEach((otherModule) => { - // skip it for the current version - if (otherModule.location === module.location) { - return; - } - - // Use readModulePackageJson here instead of direct readFileSync - const otherJson = readModulePackageJson(otherModule); - - // Check if this module depends on the one we're updating - const otherJsonString = JSON.stringify(otherJson); - if (otherJsonString.includes(json.name)) { - setDependencyVersion(otherJson, json.name, next); - writeModulePackageJson(otherModule, otherJson); - } - }); - - return next; - } - return undefined; -} +import path from 'path'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; -/** - * increment the version based on the preid. - * - * @param {String} preid - The prerelease identifier - * @param {LernaModule[]} lernaModules - The modules to update - */ -async function incrementVersions( - preid: string, - lernaModules: LernaModule[], -): Promise { - const distTags = await getDistTagsForModules(lernaModules); +import { getLernaModules, validateReleaseTransformations } from './prepareRelease'; +import { replacePackageScopes } from './prepareRelease/mutateScope'; +import { incrementVersions } from './prepareRelease/incrementVersions'; - for (const m of lernaModules) { - try { - incrementVersionsForModuleLocation( - preid, - m, - distTags.get(m), - lernaModules, - ); - } catch (e) { - // it's not necessarily a blocking error. Let lerna try and publish anyways - console.warn( - `Couldn't set next version for ${m.name} at ${m.location}`, - e, - ); - } - } -} +export const uninitializedModules = process.env.UNINITIALIZED_MODULES + ? process.env.UNINITIALIZED_MODULES.split(',') + : []; yargs(hideBin(process.argv)) .command( @@ -186,9 +42,7 @@ yargs(hideBin(process.argv)) .option('root-dir', { type: 'string', description: 'Root directory of the repository', - default: - process.env.BITGO_PREPARE_RELEASE_ROOT_DIR || - path.join(__dirname, '..'), + default: process.env.BITGO_PREPARE_RELEASE_ROOT_DIR || path.join(__dirname, '..'), }); }, async (argv) => { @@ -201,34 +55,19 @@ yargs(hideBin(process.argv)) try { // Get lerna modules directly const lernaModules = await getLernaModules(); - // Replace package scopes - const filesChanged = replacePackageScopes( - rootDir, - lernaModules, - targetScope, - ); - - // Replace BitGo package scope - replaceBitGoPackageScope(rootDir, targetScope); - + await replacePackageScopes(rootDir, lernaModules, targetScope); // Increment versions - await incrementVersions(preid, lernaModules); + await incrementVersions(preid, lernaModules, uninitializedModules); + await validateReleaseTransformations(lernaModules, preid, targetScope); - if (filesChanged) { - console.log(`Successfully re-targeted ${filesChanged} files.`); - process.exit(0); - } else { - console.error( - 'No files were changed, something must have gone wrong.', - ); - process.exit(1); - } + console.log(`Successfully re-targeted module scopes and versions.`); + process.exit(0); } catch (error) { console.error('Error in prepare-release script:', error); process.exit(1); } - }, + } ) .help() .alias('help', 'h') diff --git a/scripts/prepareRelease/changePackageJson.ts b/scripts/prepareRelease/changePackageJson.ts deleted file mode 100644 index 69dc3dbf05..0000000000 --- a/scripts/prepareRelease/changePackageJson.ts +++ /dev/null @@ -1,16 +0,0 @@ -export function setDependencyVersion( - packageJson: { - dependencies?: Record; - devDependencies?: Record; - }, - dependencyName: string, - version: string -): void { - if (packageJson.dependencies && packageJson.dependencies[dependencyName]) { - packageJson.dependencies[dependencyName] = version; - } - if (packageJson.devDependencies && packageJson.devDependencies[dependencyName]) { - packageJson.devDependencies[dependencyName] = version; - } - // FIXME: also update the peerDependencies, buildDependencies, etc. -} diff --git a/scripts/prepareRelease/changeScopeInFile.ts b/scripts/prepareRelease/changeScopeInFile.ts deleted file mode 100644 index 0e1e8162a4..0000000000 --- a/scripts/prepareRelease/changeScopeInFile.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { readFileSync, writeFileSync } from 'fs'; - -export function getNewModuleName(moduleName: string, targetScope: string): string { - return moduleName.replace('@bitgo/', `${targetScope}/`); -} - -export function updateModuleNames(input: string, moduleNames: string[], targetScope: string): string { - moduleNames.forEach((moduleName) => { - input = input.replace(new RegExp(moduleName, 'g'), getNewModuleName(moduleName, targetScope)); - }); - return input; -} - -export function changeScopeInFile(filePath: string, moduleNames: string[], targetScope: string): number { - const oldContent = readFileSync(filePath, { encoding: 'utf8' }); - const newContent = updateModuleNames(oldContent, moduleNames, targetScope); - if (newContent !== oldContent) { - writeFileSync(filePath, newContent, { encoding: 'utf-8' }); - return 1; - } - return 0; -} diff --git a/scripts/prepareRelease/distTags.ts b/scripts/prepareRelease/distTags.ts index 46c4dad9a9..f4986143aa 100644 --- a/scripts/prepareRelease/distTags.ts +++ b/scripts/prepareRelease/distTags.ts @@ -1,20 +1,67 @@ -import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; import path from 'path'; -import { LernaModule } from './getLernaModules'; +import { LernaModule } from './lernaModules'; export type DistTags = Record; /** * Makes an HTTP request to fetch all the dist tags for a given package. */ -export async function getDistTags(packageName: string): Promise { +export async function getDistTags(packageName: string, targetPreId: string): Promise { console.log(`Fetching dist tags for ${packageName}`); const url = `https://registry.npmjs.org/-/package/${packageName}/dist-tags`; const response = await fetch(url); if (!response.ok) { throw new Error(`Failed ${url}: ${response.status} ${response.statusText} ${await response.text()}`); } - return response.json(); + let responseJson = await response.json(); + responseJson = await fixInvalidDistTag(responseJson, packageName, targetPreId); + responseJson = await fixInvalidDistTag(responseJson, packageName, 'latest'); + return responseJson; +} + +/** + * Modifies distTags in place if the targetPreId points to a semantic-release-managed version instead + * of a real version. This is mainly used to self-repair in the case that a beta release pushed a bad version number. + * @param distTags + * @param packageName + * @param targetPreId + */ +async function fixInvalidDistTag(distTags: DistTags, packageName: string, targetPreId: string): Promise { + if (distTags[targetPreId].includes('semantic-release-managed')) { + console.log( + `Found semantic-release-managed version for ${packageName}, searching for latest version from releases...` + ); + const latestReleaseVersion = await getLatestReleaseVersion(packageName, targetPreId); + if (!latestReleaseVersion) { + throw new Error(`Failed to get latest version for ${packageName}`); + } + console.log(`Found latest release version for ${packageName}: ${latestReleaseVersion}`); + distTags[targetPreId] = latestReleaseVersion; + } + return distTags; +} + +/** + * Fetches the latest release version for a given package and preid. + * @returns The latest version string or undefined if not found. + * @param packageName + * @param targetPreId + */ +async function getLatestReleaseVersion(packageName: string, targetPreId: string): Promise { + const url = `https://registry.npmjs.org/${packageName}`; + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed ${url}: ${response.status} ${response.statusText} ${await response.text()}`); + } + const responseJson = await response.json(); + const versions = Object.keys(responseJson.versions).reverse(); + return versions.find((v) => { + if (targetPreId === 'latest') { + return !v.includes('-'); + } + return v.includes(`-${targetPreId}`); + }); } // Add this function to read from cache @@ -22,7 +69,19 @@ export function getDistTagsCache(): string | undefined { return process.env.BITGO_PREPARE_RELEASE_CACHE_DIST_TAGS; } -export async function getDistTagsForModuleNames(moduleNames: string[]): Promise> { +/** + * Get NPM dist tags for a list of module names. + * + * @param moduleNames + * @param uninitializedModules + * @param preid + * @returns Map, key is the updated scoped module name, value is the dist tags object + */ +export async function getDistTagsForModuleNames( + moduleNames: string[], + uninitializedModules: string[], + preid: string +): Promise> { const cachePath = getDistTagsCache(); // If cache path is set and file exists, read from cache @@ -39,18 +98,38 @@ export async function getDistTagsForModuleNames(moduleNames: string[]): Promise< await Promise.all( moduleNames.map(async (moduleName): Promise<[string, DistTags][]> => { switch (moduleName) { + case '@bitgo/express': case '@bitgo-beta/express': + case '@bitgo/web-demo': case '@bitgo-beta/web-demo': + case '@bitgo/sdk-test': case '@bitgo-beta/sdk-test': console.warn(`Skipping ${moduleName} as it's not published to npm`); - return []; + return [ + [ + moduleName, + { + latest: '0.0.0-semantic-release-managed', + alpha: '0.0.0-semantic-release-managed', + beta: '0.0.0-semantic-release-managed', + }, + ], + ]; } - try { - return [[moduleName, await getDistTags(moduleName)]]; - } catch (e) { - console.warn(`Failed to fetch dist tags for ${moduleName}`, e); - return []; + if (uninitializedModules.includes(moduleName)) { + console.warn(`Skipping ${moduleName} as uninitialized module. Setting default version.`); + return [ + [ + moduleName, + { + latest: 'v0.0.0', + alpha: 'v0.0.0', + beta: 'v0.0.0', + }, + ], + ]; } + return [[moduleName, await getDistTags(moduleName, preid)]]; }) ) ).flat() @@ -70,10 +149,21 @@ export async function getDistTagsForModuleNames(moduleNames: string[]): Promise< return tagsMap; } -export async function getDistTagsForModules(modules: LernaModule[]): Promise> { +/** + * Get NPM dist tags for a list of lerna modules. + * Private modules are ignored as they are not published to NPM. + * @param modules + * @param uninitializedModules + * @param preid + * @returns A map where the key is module name and the value is the dist tags object or undefined if the module is private. + */ +export async function getDistTagsForModules( + modules: LernaModule[], + uninitializedModules: string[], + preid: string +): Promise> { const names: string[] = modules.map( (m) => JSON.parse(readFileSync(path.join(m.location, 'package.json'), { encoding: 'utf-8' })).name ); - const nameMap = await getDistTagsForModuleNames(names); - return new Map(modules.map((m, i) => [m, nameMap.get(names[i])])); + return await getDistTagsForModuleNames(names, uninitializedModules, preid); } diff --git a/scripts/prepareRelease/getLernaModules.ts b/scripts/prepareRelease/getLernaModules.ts deleted file mode 100644 index 433a210243..0000000000 --- a/scripts/prepareRelease/getLernaModules.ts +++ /dev/null @@ -1,29 +0,0 @@ -import execa from 'execa'; - -export type LernaModule = { - name: string; - location: string; - version: string; -}; - -/** - * Create a function which can run lerna commands - * @param {String} lernaPath - path to lerna binary - * @returns {function(string, string[], Object.): Promise} - */ -function getLernaRunner(lernaPath: string) { - return async (command: string, args: string[] = [], options = {}) => { - const { stdout } = await execa(lernaPath, [command, ...args], options); - return stdout; - }; -} - -export async function getLernaModules(): Promise { - const { stdout: lernaBinary } = await execa('yarn', ['bin', 'lerna'], { - cwd: process.cwd(), - }); - const lerna = getLernaRunner(lernaBinary); - return JSON.parse( - await lerna('list', ['--loglevel', 'silent', '--json', '--all']), - ); -} diff --git a/scripts/prepareRelease/incrementVersions.ts b/scripts/prepareRelease/incrementVersions.ts new file mode 100644 index 0000000000..d806928e82 --- /dev/null +++ b/scripts/prepareRelease/incrementVersions.ts @@ -0,0 +1,164 @@ +import { DistTags, getDistTagsForModules } from './distTags'; +import { LernaModule, readModulePackageJson, setDependencyVersion, writeModulePackageJson } from './lernaModules'; +import assert from 'node:assert'; +import { inc, lt } from 'semver'; +import simpleGit from 'simple-git'; + +/** + * increment the version based on the preid. + * + * @param {String} preid - The prerelease identifier + * @param {LernaModule[]} lernaModules - The modules to update + * @param {String[]} uninitializedModules + */ +export async function incrementVersions( + preid: string, + lernaModules: LernaModule[], + uninitializedModules: string[] +): Promise { + const distTags = await getDistTagsForModules(lernaModules, uninitializedModules, preid); + console.log(`incrementing version for ${lernaModules.length} modules...`); + for (const m of lernaModules) { + try { + // Dist tags are mapped to the renamed module (i.e. after changing scope) + // so we need to fetch the name from the package.json + const json = readModulePackageJson(m); + await incrementVersionsForModuleLocation(preid, m, json, distTags.get(json.name), lernaModules); + } catch (e) { + // it's not necessarily a blocking error. + // If we fail to increment the version, NPM will block a publishing if the version already exists + // so we can just warn and move on + console.warn(`Couldn't set next version for ${m.name} at ${m.location}`, e); + } + } +} + +/** + * Increment the version for a single module based on the preid. + * + * @param {String} preid - The prerelease identifier + * @param {LernaModule} lernaModule - The module to update + * @param packageJson + * @param {DistTags|undefined} tags - The dist tags for the module + * @param {LernaModule[]} allModules - All modules for dependency updates + * @returns {String|undefined} - The new version if set, undefined otherwise + */ +async function incrementVersionsForModuleLocation( + preid: string, + lernaModule: LernaModule, + packageJson: { + name: string; + version: string; + }, + tags: DistTags | undefined, + allModules: LernaModule[] +): Promise { + let prevTag: string | undefined = undefined; + if (tags) { + // FIXME: for the @bitgo-beta scope, the "latest" should technically be fetched from the @bitgo scope + // as we never update the "latest" preid distag in the @bitgo-beta scope. + // In the future we should consider using the beta preid in the @bitgo scope and use @bitgo-beta only + // to test releases + const latestWithoutDist = tags?.latest?.split('-')[0] ?? '0.0.0'; + if (tags[preid]) { + if (preid === 'latest') { + prevTag = latestWithoutDist; + } else { + const version = tags[preid].split('-'); + // If there has been a new latest release in this scope, use that as the base version + prevTag = lt(version[0], latestWithoutDist) ? `${latestWithoutDist}-${preid}` : tags[preid]; + } + } else { + prevTag = preid !== 'latest' ? `${tags.latest}-${preid}` : 'v0.0.0'; + } + } + if (!prevTag) { + console.warn(`No previous tag found for ${packageJson.name}, skipping version increment`); + return undefined; + } + + let next: string | null = null; + if (preid === 'latest') { + const incrementType = await getIncrementType(lernaModule); + next = inc(prevTag, incrementType); + } else { + // FIXME: have beta and alpha releases use conventional commit to determine increment type + next = inc(prevTag, 'prerelease', undefined, preid); + } + + assert(typeof next === 'string', `Failed to increment version for ${packageJson.name} prevTag=${prevTag}`); + console.log(`${packageJson.name.padEnd(50)}${prevTag.padEnd(22)}-> ${next.padEnd(22)}`); + packageJson.version = next; + writeModulePackageJson(lernaModule, packageJson); + + // since we're manually setting new versions, we must also reconcile all other lerna packages to use the 'next' version for this module + allModules.forEach((otherModule) => { + // skip it for the current version + if (otherModule.location === lernaModule.location) { + return; + } + + // Use readModulePackageJson here instead of direct readFileSync + const otherJson = readModulePackageJson(otherModule); + + // Check if this module depends on the one we're updating + const otherJsonString = JSON.stringify(otherJson); + if (otherJsonString.includes(packageJson.name)) { + setDependencyVersion(otherJson, packageJson.name, next); + writeModulePackageJson(otherModule, otherJson); + } + }); + + return next; +} + +/** + * Get the increment type (major, minor, patch) based on conventional commits since the last tag for the module. + * If no last git tag is found, then default to 'patch'. + * @param lernaModule - original lerna module before modifications + */ +async function getIncrementType(lernaModule: LernaModule): Promise<'major' | 'minor' | 'patch'> { + const git = simpleGit(); + const tags = await git.tags(); + const lastTag = tags.all.filter((tag) => tag.includes(lernaModule.name)).pop(); + if (!lastTag) return 'patch'; + + // Dynamic import for ESM module + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const { CommitParser } = await import('conventional-commits-parser'); + const parser = new CommitParser(); + const gitLogSeparator = '---END---'; + const rawLog = await git.raw([ + 'log', + `${lastTag}..HEAD`, + `--pretty=%B${gitLogSeparator}`, + '--', + lernaModule.location, + ]); + const commitMessages = rawLog + .split(gitLogSeparator) + .map((msg) => msg.trim()) + .filter((msg) => msg.length > 0); + + let increment: 'patch' | 'minor' | 'major' = 'patch'; + for (const commit of commitMessages) { + const parsed = parser.parse(commit.trim()); + if (parsed.notes && parsed.notes.some((note: { title?: string }) => note.title === 'BREAKING CHANGE')) { + increment = 'major'; + break; + } else if (parsed.footer && parsed.footer.includes('BREAKING CHANGE:')) { + increment = 'major'; + break; + } else if (parsed.header && parsed.header.includes('!')) { + increment = 'major'; + break; + } else if (parsed.type === 'feat') { + increment = 'minor'; + } + } + if (increment === 'major') { + console.warn(`Breaking change for module ${lernaModule.name}, incrementing major version`); + } + return increment; +} diff --git a/scripts/prepareRelease/index.ts b/scripts/prepareRelease/index.ts index ea0242a927..be275e0fda 100644 --- a/scripts/prepareRelease/index.ts +++ b/scripts/prepareRelease/index.ts @@ -1,5 +1,5 @@ -export * from './changeScopeInFile'; -export * from './changePackageJson'; export * from './distTags'; -export * from './getLernaModules'; +export * from './lernaModules'; export * from './walk'; +export * from './validateTransformations'; +export * from './mutateScope'; diff --git a/scripts/prepareRelease/lernaModules.ts b/scripts/prepareRelease/lernaModules.ts new file mode 100644 index 0000000000..956371851a --- /dev/null +++ b/scripts/prepareRelease/lernaModules.ts @@ -0,0 +1,85 @@ +import execa from 'execa'; +import { readFileSync, writeFileSync } from 'fs'; +import path from 'path'; + +export type LernaModule = { + name: string; + location: string; + version: string; + private?: boolean; +}; + +/** + * Create a function which can run lerna commands + * @param {String} lernaPath - path to lerna binary + * @returns {function(string, string[], Object.): Promise} + */ +function getLernaRunner(lernaPath: string) { + return async (command: string, args: string[] = [], options = {}) => { + const { stdout } = await execa(lernaPath, [command, ...args], options); + return stdout; + }; +} + +/** + * Get all lerna modules in the monorepo + */ +export async function getLernaModules(): Promise { + const { stdout: lernaBinary } = await execa('yarn', ['bin', 'lerna'], { + cwd: process.cwd(), + }); + const lerna = getLernaRunner(lernaBinary); + return JSON.parse(await lerna('list', ['--loglevel', 'silent', '--json', '--all'])); +} + +/** + * Read package.json for a module + * @param lernaModule The module to read package.json from + * @returns The parsed package.json content + */ +export function readModulePackageJson(lernaModule: Pick): any { + return JSON.parse( + readFileSync(path.join(lernaModule.location, 'package.json'), { + encoding: 'utf-8', + }) + ); +} + +/** + * Write package.json for a module + * @param lernaModule The module to write package.json to + * @param json The content to write + */ +export function writeModulePackageJson(lernaModule: LernaModule, json: any): void { + writeFileSync(path.join(lernaModule.location, 'package.json'), JSON.stringify(json, null, 2) + '\n'); +} + +/** + * Updates the version for a package in a package.json object if it exists in any of the dependency fields. + * @param packageJson + * @param dependencyName + * @param version + */ +export function setDependencyVersion( + packageJson: { + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; + buildDependencies?: Record; + }, + dependencyName: string, + version: string +): void { + if (packageJson.dependencies && packageJson.dependencies[dependencyName]) { + packageJson.dependencies[dependencyName] = version; + } + if (packageJson.devDependencies && packageJson.devDependencies[dependencyName]) { + packageJson.devDependencies[dependencyName] = version; + } + if (packageJson.peerDependencies && packageJson.peerDependencies[dependencyName]) { + packageJson.peerDependencies[dependencyName] = version; + } + if (packageJson.buildDependencies && packageJson.buildDependencies[dependencyName]) { + packageJson.buildDependencies[dependencyName] = version; + } +} diff --git a/scripts/prepareRelease/mutateScope.ts b/scripts/prepareRelease/mutateScope.ts new file mode 100644 index 0000000000..945cdb23b0 --- /dev/null +++ b/scripts/prepareRelease/mutateScope.ts @@ -0,0 +1,81 @@ +import { LernaModule } from './lernaModules'; +import { walk } from './walk'; +import path from 'path'; +import { readFileSync, writeFileSync } from 'fs'; + +/** + * Update all package references from the original scopes to the new scope + * @example updates @bitgo/sdk-coin-eth to @bitgo-beta/sdk-coin-eth + * @param rootDir + * @param lernaModules + * @param targetScope + */ +export async function replacePackageScopes( + rootDir: string, + lernaModules: LernaModule[], + targetScope: string +): Promise { + if (targetScope === '@bitgo') { + // stable release should not change the scope + console.log('No scope change needed for modules/* for stable release'); + return; + } + // replace all @bitgo packages & source code with alternate SCOPE + const filePaths = [...walk(path.join(rootDir, 'modules')), ...walk(path.join(rootDir, 'webpack'))]; + // Note: the bitgo umbrella package is only imported by private modules that do not get published + // We ignore its replacement to simplify the regex and avoid potential issues + const moduleNames = lernaModules.map(({ name }) => name).filter((name) => name !== 'bitgo'); + + filePaths.forEach((file) => { + changeScopeInFile(file, moduleNames, targetScope); + }); + + const bitgoWorkingDir = path.join(rootDir, 'modules', 'bitgo'); + const bitgoModuleJson = JSON.parse(readFileSync(path.join(bitgoWorkingDir, 'package.json'), { encoding: 'utf-8' })); + bitgoModuleJson.name = `${targetScope}/bitgo`; + writeFileSync(path.join(bitgoWorkingDir, 'package.json'), JSON.stringify(bitgoModuleJson, null, 2) + '\n'); + return; +} + +/** + * Given the existing module name and the target scope, return the new module name + * Note: ignores the bitgo umbrella package + * @param moduleName + * @param targetScope + */ +export function getNewModuleName(moduleName: string, targetScope: string): string { + if (moduleName === 'bitgo') { + // We handle the 'bitgo' umbrella package separately + return moduleName; + } + return moduleName.replace('@bitgo/', `${targetScope}/`); +} + +/** + * Given an input string, replace all occurrences of the module names with the new scoped names + * @param input - file content (all module file content) + * @param moduleNames - list of original module names + * @param targetScope - target scope to change original modual name with + */ +export function updateModuleNames(input: string, moduleNames: string[], targetScope: string): string { + moduleNames.forEach((moduleName) => { + input = input.replace(new RegExp(moduleName, 'g'), getNewModuleName(moduleName, targetScope)); + }); + return input; +} + +/** + * Given a file path, read the file content, replace all occurrences of the module names with the new scoped names + * @param filePath + * @param moduleNames + * @param targetScope + */ +export function changeScopeInFile(filePath: string, moduleNames: string[], targetScope: string): number { + const oldContent = readFileSync(filePath, { encoding: 'utf8' }); + const newContent = updateModuleNames(oldContent, moduleNames, targetScope); + if (newContent !== oldContent) { + writeFileSync(filePath, newContent, { encoding: 'utf-8' }); + return 1; + } + return 0; +} diff --git a/scripts/prepareRelease/validateTransformations.ts b/scripts/prepareRelease/validateTransformations.ts new file mode 100644 index 0000000000..900c82094c --- /dev/null +++ b/scripts/prepareRelease/validateTransformations.ts @@ -0,0 +1,28 @@ +import { LernaModule, readModulePackageJson } from './lernaModules'; + +/** + * Validates that package json files have the correct scope and preid in their versions + * and names + * @param lernaModules + * @param preid + * @param scope + */ +export function validateReleaseTransformations(lernaModules: LernaModule[], preid: string, scope: string): void { + lernaModules + .filter((m) => !m.private) + .forEach((m) => { + const packageJSON = readModulePackageJson(m); + if (packageJSON.name === 'bitgo' && scope !== '@bitgo') { + throw new Error(`Module ${packageJSON.name} should have been renamed to ${scope}/bitgo`); + } + if (packageJSON.name !== 'bitgo' && !packageJSON.name?.startsWith(scope)) { + throw new Error(`Module ${packageJSON.name} does not have the correct scope ${scope}`); + } + if (preid !== 'latest' && !packageJSON.version?.includes(preid)) { + throw new Error( + `Module ${packageJSON.name} does not have the correct preid ${preid} in version ${packageJSON.version}` + ); + } + }); + console.log(`Successfully validated module scopes and versions for ${lernaModules.length} modules.`); +} diff --git a/scripts/verify-release.ts b/scripts/verify-release.ts index 14702f97be..4fe122793a 100644 --- a/scripts/verify-release.ts +++ b/scripts/verify-release.ts @@ -12,24 +12,16 @@ async function getLernaModuleLocations(): Promise { async function verifyPackage(dir: string, preid = 'beta'): Promise { const cwd = dir; - const json = JSON.parse( - readFileSync(path.join(cwd, 'package.json'), { encoding: 'utf-8' }), - ); + const json = JSON.parse(readFileSync(path.join(cwd, 'package.json'), { encoding: 'utf-8' })); if (json.private) { return true; } try { - const distTags = await getDistTags(json.name); + const distTags = await getDistTags(json.name, preid); if (json.version !== distTags[preid]) { - console.log( - `${json.name} missing. Expected ${json.version}, latest is ${distTags[preid]}`, - ); - const { stdout, exitCode } = await execa( - 'npm', - ['publish', '--tag', preid], - { cwd }, - ); + console.log(`${json.name} missing. Expected ${json.version}, latest is ${distTags[preid]}`); + const { stdout, exitCode } = await execa('npm', ['publish', '--tag', preid], { cwd }); console.log(stdout); return exitCode === 0; } else { diff --git a/yarn.lock b/yarn.lock index 5fbb67cfd4..3d30e30898 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2916,6 +2916,18 @@ dependencies: lodash "^4.17.21" +"@kwsites/file-exists@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99" + integrity sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw== + dependencies: + debug "^4.1.1" + +"@kwsites/promise-deferred@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" + integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== + "@ledgerhq/devices@^5.48.0", "@ledgerhq/devices@^5.51.1": version "5.51.1" resolved "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.51.1.tgz" @@ -9149,6 +9161,13 @@ conventional-commits-filter@^2.0.7: lodash.ismatch "^4.4.0" modify-values "^1.0.0" +conventional-commits-parser@6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.2.0.tgz#1a2159471896f43101b8817e5709b8da78334aaa" + integrity sha512-uLnoLeIW4XaoFtH37qEcg/SXMJmKF4vi7V0H2rnPueg+VEtFGA/asSCNTcq4M/GQ6QmlzchAEtOoDTtKqWeHag== + dependencies: + meow "^13.0.0" + conventional-commits-parser@^3.2.0: version "3.2.4" resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz" @@ -9697,6 +9716,13 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.4.0: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" @@ -14969,6 +14995,11 @@ meow@^12.0.1: resolved "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz" integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== +meow@^13.0.0: + version "13.2.0" + resolved "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f" + integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA== + meow@^8.0.0: version "8.1.2" resolved "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz" @@ -18859,6 +18890,15 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" +simple-git@^3.28.0: + version "3.28.0" + resolved "https://registry.npmjs.org/simple-git/-/simple-git-3.28.0.tgz#c6345b2e387880f8450788a1e388573366ae48ac" + integrity sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w== + dependencies: + "@kwsites/file-exists" "^1.1.1" + "@kwsites/promise-deferred" "^1.1.1" + debug "^4.4.0" + sinon@^13.0.1: version "13.0.2" resolved "https://registry.npmjs.org/sinon/-/sinon-13.0.2.tgz" From ee1b69665a96ae9a72d060a983755c48a2d36ebd Mon Sep 17 00:00:00 2001 From: Mohammed Ryaan Date: Wed, 24 Sep 2025 08:51:04 +0530 Subject: [PATCH 22/35] feat(sdk-coin-ton): add jetton transaction support TICKET: COIN-5626 --- modules/sdk-coin-ton/src/lib/constants.ts | 3 + .../src/lib/singleNominatorWithdrawBuilder.ts | 4 +- .../sdk-coin-ton/src/lib/tokenTransaction.ts | 121 ++++++++ .../src/lib/tokenTransferBuilder.ts | 71 +++++ modules/sdk-coin-ton/src/lib/transaction.ts | 67 ++-- .../src/lib/transactionBuilder.ts | 7 +- .../src/lib/transactionBuilderFactory.ts | 18 +- .../sdk-coin-ton/src/lib/transferBuilder.ts | 4 +- modules/sdk-coin-ton/src/ton.ts | 12 +- modules/sdk-coin-ton/test/resources/ton.ts | 38 +++ .../test/unit/tokenTransaction.ts | 286 ++++++++++++++++++ .../test/unit/tokenTransferBuilder.ts | 243 +++++++++++++++ .../sdk-coin-ton/test/unit/transferBuilder.ts | 5 +- 13 files changed, 843 insertions(+), 36 deletions(-) create mode 100644 modules/sdk-coin-ton/src/lib/constants.ts create mode 100644 modules/sdk-coin-ton/src/lib/tokenTransaction.ts create mode 100644 modules/sdk-coin-ton/src/lib/tokenTransferBuilder.ts create mode 100644 modules/sdk-coin-ton/test/unit/tokenTransaction.ts create mode 100644 modules/sdk-coin-ton/test/unit/tokenTransferBuilder.ts diff --git a/modules/sdk-coin-ton/src/lib/constants.ts b/modules/sdk-coin-ton/src/lib/constants.ts new file mode 100644 index 0000000000..ce72e4903c --- /dev/null +++ b/modules/sdk-coin-ton/src/lib/constants.ts @@ -0,0 +1,3 @@ +export const WALLET_ID = 698983191; +export const JETTON_TRANSFER_OPCODE = 0x0f8a7ea5; +export const WITHDRAW_OPCODE = '00001000'; diff --git a/modules/sdk-coin-ton/src/lib/singleNominatorWithdrawBuilder.ts b/modules/sdk-coin-ton/src/lib/singleNominatorWithdrawBuilder.ts index 14ebc58e80..6ecc38e68d 100644 --- a/modules/sdk-coin-ton/src/lib/singleNominatorWithdrawBuilder.ts +++ b/modules/sdk-coin-ton/src/lib/singleNominatorWithdrawBuilder.ts @@ -1,10 +1,12 @@ -import { TransactionBuilder } from './transactionBuilder'; import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { Recipient, TransactionType } from '@bitgo/sdk-core'; +import { TransactionBuilder } from './transactionBuilder'; +import { Transaction } from './transaction'; export class SingleNominatorWithdrawBuilder extends TransactionBuilder { constructor(_coinConfig: Readonly) { super(_coinConfig); + this._transaction = new Transaction(_coinConfig); } protected get transactionType(): TransactionType { diff --git a/modules/sdk-coin-ton/src/lib/tokenTransaction.ts b/modules/sdk-coin-ton/src/lib/tokenTransaction.ts new file mode 100644 index 0000000000..c55b1aa674 --- /dev/null +++ b/modules/sdk-coin-ton/src/lib/tokenTransaction.ts @@ -0,0 +1,121 @@ +import TonWeb from 'tonweb'; +import { BN } from 'bn.js'; +import { Cell } from 'tonweb/dist/types/boc/cell'; +import { TransactionRecipient, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { TransactionExplanation, TxData } from './iface'; +import { Transaction } from './transaction'; +import { JETTON_TRANSFER_OPCODE, WALLET_ID } from './constants'; + +export class TokenTransaction extends Transaction { + public forwardTonAmount: string; // for covering forward fees for notify transfer + public senderJettonWalletAddress: string; // the sender's Jetton wallet address + public tonAmount: string; // amount of TON sent to the sender's Jetton wallet + + constructor(coinConfig: Readonly) { + super(coinConfig); + } + + toJson(): TxData { + const json = super.toJson(); + return { + ...json, + forwardTonAmount: this.forwardTonAmount, + senderJettonWalletAddress: this.senderJettonWalletAddress, + tonAmount: this.tonAmount, + } as TxData; + } + + private createJettonTransferPayload( + jettonAmount: string, + toAddress: string, + forwardTonAmount: string, + comment?: string + ): Cell { + const forwardPayload = new TonWeb.boc.Cell(); + if (comment) { + forwardPayload.bits.writeUint(0, 32); + forwardPayload.bits.writeString(comment); + } + + const payload = new TonWeb.boc.Cell(); + payload.bits.writeUint(JETTON_TRANSFER_OPCODE, 32); // Store Jetton transfer op code + payload.bits.writeUint(0, 64); // query_id + payload.bits.writeCoins(new BN(jettonAmount)); // Jetton amount to transfer + payload.bits.writeAddress(new TonWeb.Address(toAddress)); // recipient's TON wallet address + payload.bits.writeAddress(new TonWeb.Address(this.sender)); // response_destination for sending excess TON (excess is returned back to the sender) + payload.bits.writeBit(false); // No custom payload + payload.bits.writeCoins(new BN(forwardTonAmount)); // forward_ton_amount to pay fees + payload.bits.writeBit(true); // Forward payload exists as a reference + payload.refs.push(forwardPayload); // Add forward payload as a reference + + return payload; + } + + async build(): Promise { + const jettonTransferPayload = this.createJettonTransferPayload( + this.recipient.amount, + this.recipient.address, + this.forwardTonAmount, + this.message + ); + + const signingMessage = this.createSigningMessage(WALLET_ID, this.seqno, this.expireTime); + const sendMode = 3; + signingMessage.bits.writeUint8(sendMode); + const outMsg = this.createOutMsg(this.senderJettonWalletAddress, this.tonAmount, jettonTransferPayload); + + signingMessage.refs.push(outMsg); + this.unsignedMessage = Buffer.from(await signingMessage.hash()).toString('hex'); + + const signature = + this._signatures.length > 0 ? this._signatures[0] : Buffer.from(new Uint8Array(64)).toString('hex'); + const finalMessage = await this.createExternalMessage(signingMessage, this.seqno, signature); + + this.finalMessage = TonWeb.utils.bytesToBase64(await finalMessage.toBoc(false)); + + const originalTxId = TonWeb.utils.bytesToBase64(await finalMessage.hash()); + this._id = originalTxId.replace(/\//g, '_').replace(/\+/g, '-'); + } + + fromRawTransaction(rawTransaction: string): void { + try { + const cell = TonWeb.boc.Cell.oneFromBoc(TonWeb.utils.base64ToBytes(rawTransaction)); + const parsed = this.parseTransaction(cell); + + this.transactionType = TransactionType.SendToken; + this.sender = parsed.fromAddress; + this.recipient = { address: parsed.payload.jettonRecipient, amount: parsed.payload.jettonAmount }; + this.tonAmount = parsed.value; + this.forwardTonAmount = parsed.payload.forwardTonAmount; + this.senderJettonWalletAddress = parsed.toAddress; + this.seqno = parsed.seqno; + this.publicKey = parsed.publicKey as string; + this.expireTime = parsed.expireAt; + this.message = parsed.payload.message; + this._signatures.push(parsed.signature); + this.bounceable = parsed.bounce; + } catch (e) { + throw new Error('invalid raw transaction'); + } + } + + /** @inheritDoc */ + explainTransaction(): TransactionExplanation { + const displayOrder = ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount']; + + const outputs: TransactionRecipient[] = [this.recipient]; + const outputAmount = this.recipient.amount; + const withdrawAmount = this.withdrawAmount; + return { + displayOrder, + id: this.id, + outputs, + outputAmount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: 'UNKNOWN' }, + withdrawAmount, + }; + } +} diff --git a/modules/sdk-coin-ton/src/lib/tokenTransferBuilder.ts b/modules/sdk-coin-ton/src/lib/tokenTransferBuilder.ts new file mode 100644 index 0000000000..8facf2be72 --- /dev/null +++ b/modules/sdk-coin-ton/src/lib/tokenTransferBuilder.ts @@ -0,0 +1,71 @@ +import { TransactionType, Recipient } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { TransactionBuilder } from './transactionBuilder'; +import { TokenTransaction } from './tokenTransaction'; +import { Transaction } from './transaction'; + +export class TokenTransferBuilder extends TransactionBuilder { + protected _transaction: TokenTransaction; + + constructor(coinConfig: Readonly) { + super(coinConfig); + this._transaction = new TokenTransaction(coinConfig); + } + + protected get transactionType(): TransactionType { + return TransactionType.SendToken; + } + + /** @inheritdoc */ + protected fromImplementation(rawTransaction: string): Transaction { + this.transaction.transactionType = TransactionType.SendToken; + this.transaction.fromRawTransaction(rawTransaction); + return this.transaction; + } + + /** @inheritdoc */ + protected async buildImplementation(): Promise { + this.transaction.transactionType = TransactionType.SendToken; + await this.transaction.build(); + this.transaction.loadInputsAndOutputs(); + return this.transaction; + } + + setForwardTonAmount(amount: string): TokenTransferBuilder { + (this.transaction as TokenTransaction).forwardTonAmount = amount; + return this; + } + + setSenderJettonWalletAddress(address: string): TokenTransferBuilder { + (this.transaction as TokenTransaction).senderJettonWalletAddress = address; + return this; + } + + setTonAmount(amount: string): TokenTransferBuilder { + (this.transaction as TokenTransaction).tonAmount = amount; + return this; + } + + // recipient method to handle both TON and token amounts + recipient( + address: string, + senderJettonWalletAddress: string, + tonAmount: string, + jettonAmount: string, + forwardTonAmount: string + ): TokenTransferBuilder { + this._transaction.recipient = { + address: address, + amount: jettonAmount, // Jetton amount to be transferred + }; + (this._transaction as TokenTransaction).senderJettonWalletAddress = senderJettonWalletAddress; // The sender's Jetton wallet address + (this._transaction as TokenTransaction).tonAmount = tonAmount; // TON amount sent to the sender's Jetton wallet + (this._transaction as TokenTransaction).forwardTonAmount = forwardTonAmount; // TON amount to cover forward fees in case of notify transfer + return this; + } + + send(recipient: Recipient): TokenTransferBuilder { + this.transaction.recipient = recipient; + return this; + } +} diff --git a/modules/sdk-coin-ton/src/lib/transaction.ts b/modules/sdk-coin-ton/src/lib/transaction.ts index de99aa4dad..eb460d63c3 100644 --- a/modules/sdk-coin-ton/src/lib/transaction.ts +++ b/modules/sdk-coin-ton/src/lib/transaction.ts @@ -1,12 +1,11 @@ -import { BaseKey, BaseTransaction, Entry, Recipient, TransactionRecipient, TransactionType } from '@bitgo/sdk-core'; -import { TxData, TransactionExplanation } from './iface'; -import { BaseCoin as CoinConfig } from '@bitgo/statics'; import TonWeb from 'tonweb'; import { BN } from 'bn.js'; import { Cell } from 'tonweb/dist/types/boc/cell'; -import { WITHDRAW_OPCODE } from './transactionBuilder'; -const WALLET_ID = 698983191; +import { BaseKey, BaseTransaction, Entry, Recipient, TransactionRecipient, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; +import { TransactionExplanation, TxData } from './iface'; +import { WITHDRAW_OPCODE, WALLET_ID, JETTON_TRANSFER_OPCODE } from './constants'; export class Transaction extends BaseTransaction { public recipient: Recipient; @@ -19,8 +18,8 @@ export class Transaction extends BaseTransaction { expireTime: number; sender: string; publicKey: string; - private unsignedMessage: string; - private finalMessage: string; + protected unsignedMessage: string; + protected finalMessage: string; constructor(coinConfig: Readonly) { super(coinConfig); @@ -88,7 +87,7 @@ export class Transaction extends BaseTransaction { this._id = originalTxId.replace(/\//g, '_').replace(/\+/g, '-'); } - private createSigningMessage(walletId, seqno, expireAt) { + protected createSigningMessage(walletId, seqno, expireAt) { const message = new TonWeb.boc.Cell(); message.bits.writeUint(walletId, 32); // expireAt should be set as per the provided arg value, regardless of the seqno @@ -98,7 +97,7 @@ export class Transaction extends BaseTransaction { return message; } - private createOutMsg(address, amount, payload) { + protected createOutMsg(address, amount, payload) { let payloadCell = new TonWeb.boc.Cell(); if (payload) { if (payload.refs) { @@ -152,8 +151,7 @@ export class Transaction extends BaseTransaction { } const header = TonWeb.Contract.createExternalMessageHeader(this.sender); - const resultMessage = TonWeb.Contract.createCommonMsgInfo(header, stateInit, body); - return resultMessage; + return TonWeb.Contract.createCommonMsgInfo(header, stateInit, body); } loadInputsAndOutputs(): void { @@ -176,11 +174,8 @@ export class Transaction extends BaseTransaction { fromRawTransaction(rawTransaction: string): void { try { const cell = TonWeb.boc.Cell.oneFromBoc(TonWeb.utils.base64ToBytes(rawTransaction)); - const parsed = this.parseTransaction(cell); - parsed.value = parsed.value.toString(); - parsed.fromAddress = parsed.fromAddress.toString(true, true, this.fromAddressBounceable); - parsed.toAddress = parsed.toAddress.toString(true, true, this.toAddressBounceable); + this.sender = parsed.fromAddress; this.recipient = { address: parsed.toAddress, amount: parsed.value }; this.withdrawAmount = parsed.withdrawAmount; @@ -214,7 +209,7 @@ export class Transaction extends BaseTransaction { }; } - private parseTransaction(cell: Cell): any { + protected parseTransaction(cell: Cell): any { const slice = (cell as any).beginParse(); // header @@ -253,7 +248,7 @@ export class Transaction extends BaseTransaction { const bodySlice = slice.loadBit() ? slice.loadRef() : slice; return { - fromAddress: externalDestAddress, + fromAddress: externalDestAddress.toString(true, true, this.fromAddressBounceable), publicKey, ...this.parseTransactionBody(bodySlice), }; @@ -285,7 +280,7 @@ export class Transaction extends BaseTransaction { const sourceAddress = order.loadAddress(); if (sourceAddress !== null) throw Error('invalid externalSourceAddress'); const destAddress = order.loadAddress(); - const value = order.loadCoins(); + const value = order.loadCoins().toString(); if (order.loadBit()) throw Error('invalid currencyCollection'); const ihrFees = order.loadCoins(); @@ -321,13 +316,47 @@ export class Transaction extends BaseTransaction { withdrawAmount = order.loadCoins().toNumber().toString(); payload = WITHDRAW_OPCODE + queryId.toString(16).padStart(16, '0') + withdrawAmount; this.transactionType = TransactionType.SingleNominatorWithdraw; + } else if (opcode === JETTON_TRANSFER_OPCODE) { + const queryId = order.loadUint(64).toNumber(); + if (queryId !== 0) throw new Error('invalid queryId for jetton transfer'); + + const jettonAmount = order.loadCoins(); + if (!jettonAmount.gt(new BN(0))) throw new Error('invalid jettonAmount'); + + const jettonRecipient = order.loadAddress(); + if (!jettonRecipient) throw new Error('invalid jettonRecipient'); + + const forwarderAddress = order.loadAddress(); + if (!forwarderAddress) throw new Error('invalid forwarderAddress'); + + order.loadBit(); // skip bit + + const forwardTonAmount = order.loadCoins(); + if (!forwardTonAmount.gt(new BN(0))) throw new Error('invalid forwardTonAmount'); + + let message = ''; + if (order.loadBit()) { + order = order.loadRef(); + const messageOpcode = order.loadUint(32).toNumber(); + if (messageOpcode !== 0) throw new Error('invalid message opcode'); + const messageBytes = order.loadBits(order.getFreeBits()); + message = new TextDecoder().decode(messageBytes); + } + + payload = { + jettonAmount: jettonAmount.toString(), + jettonRecipient: jettonRecipient.toString(true, true, this.toAddressBounceable), + forwarderAddress: forwarderAddress.toString(true, true, this.fromAddressBounceable), + forwardTonAmount: forwardTonAmount.toString(), + message: message, + }; } else { payload = ''; } } } return { - toAddress: destAddress, + toAddress: destAddress.toString(true, true, this.fromAddressBounceable), value, bounce, seqno, diff --git a/modules/sdk-coin-ton/src/lib/transactionBuilder.ts b/modules/sdk-coin-ton/src/lib/transactionBuilder.ts index 95c6bbdcb7..757218fe27 100644 --- a/modules/sdk-coin-ton/src/lib/transactionBuilder.ts +++ b/modules/sdk-coin-ton/src/lib/transactionBuilder.ts @@ -1,3 +1,6 @@ +import BigNumber from 'bignumber.js'; +import TonWeb from 'tonweb'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { BaseAddress, BaseKey, @@ -10,9 +13,6 @@ import { } from '@bitgo/sdk-core'; import { Transaction } from './transaction'; import utils from './utils'; -import BigNumber from 'bignumber.js'; -import { BaseCoin as CoinConfig } from '@bitgo/statics'; -import TonWeb from 'tonweb'; export const WITHDRAW_OPCODE = '00001000'; @@ -22,7 +22,6 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { constructor(coinConfig: Readonly) { super(coinConfig); - this._transaction = new Transaction(coinConfig); } // get and set region diff --git a/modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts b/modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts index 0081e1e3cd..e86509e55c 100644 --- a/modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts +++ b/modules/sdk-coin-ton/src/lib/transactionBuilderFactory.ts @@ -1,9 +1,11 @@ import { BaseTransactionBuilderFactory, InvalidTransactionError, TransactionType } from '@bitgo/sdk-core'; +import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { TransactionBuilder } from './transactionBuilder'; import { TransferBuilder } from './transferBuilder'; -import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { SingleNominatorWithdrawBuilder } from './singleNominatorWithdrawBuilder'; import { Transaction } from './transaction'; +import { TokenTransferBuilder } from './tokenTransferBuilder'; +import { TokenTransaction } from './tokenTransaction'; export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { constructor(_coinConfig: Readonly) { @@ -12,9 +14,9 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { /** @inheritdoc */ from(raw: string): TransactionBuilder { let builder: TransactionBuilder; - const tx = new Transaction(this._coinConfig); - tx.fromRawTransaction(raw); try { + const tx = this._coinConfig.isToken ? new TokenTransaction(this._coinConfig) : new Transaction(this._coinConfig); + tx.fromRawTransaction(raw); switch (tx.type) { case TransactionType.Send: builder = this.getTransferBuilder(); @@ -22,6 +24,9 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { case TransactionType.SingleNominatorWithdraw: builder = this.getSingleNominatorWithdrawBuilder(); break; + case TransactionType.SendToken: + builder = this.getTokenTransferBuilder(); + break; default: throw new InvalidTransactionError('unsupported transaction'); } @@ -44,6 +49,13 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory { return new SingleNominatorWithdrawBuilder(this._coinConfig); } + /** + * Returns a specific builder to create a TON token transfer transaction + */ + getTokenTransferBuilder(): TokenTransferBuilder { + return new TokenTransferBuilder(this._coinConfig); + } + /** @inheritdoc */ getWalletInitializationBuilder(): void { throw new Error('Method not implemented.'); diff --git a/modules/sdk-coin-ton/src/lib/transferBuilder.ts b/modules/sdk-coin-ton/src/lib/transferBuilder.ts index d4a2ab5ba5..73d325830c 100644 --- a/modules/sdk-coin-ton/src/lib/transferBuilder.ts +++ b/modules/sdk-coin-ton/src/lib/transferBuilder.ts @@ -1,10 +1,12 @@ -import { TransactionBuilder } from './transactionBuilder'; import { BaseCoin as CoinConfig } from '@bitgo/statics'; import { Recipient, TransactionType } from '@bitgo/sdk-core'; +import { TransactionBuilder } from './transactionBuilder'; +import { Transaction } from './transaction'; export class TransferBuilder extends TransactionBuilder { constructor(_coinConfig: Readonly) { super(_coinConfig); + this._transaction = new Transaction(_coinConfig); } protected get transactionType(): TransactionType { diff --git a/modules/sdk-coin-ton/src/ton.ts b/modules/sdk-coin-ton/src/ton.ts index f9c8886574..ffe7629120 100644 --- a/modules/sdk-coin-ton/src/ton.ts +++ b/modules/sdk-coin-ton/src/ton.ts @@ -1,3 +1,6 @@ +import BigNumber from 'bignumber.js'; +import * as _ from 'lodash'; +import TonWeb from 'tonweb'; import { BaseCoin, BitGoBase, @@ -28,14 +31,12 @@ import { MPCSweepRecoveryOptions, AuditDecryptedKeyParams, } from '@bitgo/sdk-core'; +import { auditEddsaPrivateKey, getDerivationPath } from '@bitgo/sdk-lib-mpc'; import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics'; import { KeyPair as TonKeyPair } from './lib/keyPair'; -import BigNumber from 'bignumber.js'; -import * as _ from 'lodash'; import { Transaction, TransactionBuilderFactory, Utils, TransferBuilder } from './lib'; -import TonWeb from 'tonweb'; -import { auditEddsaPrivateKey, getDerivationPath } from '@bitgo/sdk-lib-mpc'; import { getFeeEstimate } from './lib/utils'; +import { TokenTransaction } from './lib/tokenTransaction'; export interface TonParseTransactionOptions extends ParseTransactionOptions { txHex: string; @@ -114,7 +115,8 @@ export class Ton extends BaseCoin { async verifyTransaction(params: VerifyTransactionOptions): Promise { const coinConfig = coins.get(this.getChain()); const { txPrebuild: txPrebuild, txParams: txParams } = params; - const transaction = new Transaction(coinConfig); + + const transaction = coinConfig.isToken ? new TokenTransaction(coinConfig) : new Transaction(coinConfig); const rawTx = txPrebuild.txHex; if (!rawTx) { throw new Error('missing required tx prebuild property txHex'); diff --git a/modules/sdk-coin-ton/test/resources/ton.ts b/modules/sdk-coin-ton/test/resources/ton.ts index 66c955cb1a..25309e5f50 100644 --- a/modules/sdk-coin-ton/test/resources/ton.ts +++ b/modules/sdk-coin-ton/test/resources/ton.ts @@ -2,12 +2,14 @@ import { Recipient } from '@bitgo/sdk-core'; export const AMOUNT = 123400000; +// Can get the private keys from sandboxing if you know the seed export const privateKeys = { prvKey1: '43e8594854cb53947c4a1a2fab926af11e123f6251dcd5bd0dfb100604186430', prvKey2: 'c0c3b9dc09932121ee351b2448c50a3ae2571b12951245c85f3bd95d5e7a06f8', prvKey3: '3d6822bf14115f47a5724b68c85160221eacbe664e892a4a9dd3b4dd64016ece', prvKey4: 'ba4c313bcf830b825adaa3ae08cfde86e79e15a84e6fdc3b1fe35a6bb82d9f22', prvKey5: 'fdb9ea1bb7f0120ce6eb7b047ac6744c4298f277756330e18dbd5419590a1ef2', + prvKey6: 'f66d30357e6a4180e9ab41865f0f347cbaffe60f9d499fe6c2f27046327652f6', }; export const addresses = { @@ -27,6 +29,23 @@ export const sender = { publicKey: 'c0c3b9dc09932121ee351b2448c50a3ae2571b12951245c85f3bd95d5e7a06f8', }; +export const tokenSender = { + address: 'UQCqQzfyg0cZ-8t9v2YoHmFFxG5jgjvQRTZ2yeDjO5z5ZUF4', + publicKey: 'd3530101d41e16d7d34546677776afc85b271bb3ecf6b19ae08e27a920724a69', + jettonAddress: 'UQACn6WjuRU-_ZJToT7Aswd4BnLO3vuCEZH4LUQoQNiMc3SE', + tonAmount: '5000000', + forwardTonAmount: '1000000', + message: 'jetton testing', + expireTime: 1234567890, +}; + +export const tokenRecipients: Recipient[] = [ + { + address: 'UQB-CM6DF-jpq9XVdiSdefAMU5KC1gpZuYBFp-Q65aUhn0OP', + amount: '1000000000', + }, +]; + export const recipients: Recipient[] = [ { address: addresses.validAddresses[0], @@ -52,6 +71,25 @@ export const signedSendTransaction = { }, }; +export const signedTokenSendTransaction = { + tx: 'te6cckECGgEABB0AAuGIAVSGb+UGjjP3lvt+zFA8wouI3McEd6CKbO2TwcZ3OfLKGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmpoxdJlgLSAAAAAAADgEXAgE0AhYBFP8A9KQT9LzyyAsDAgEgBBECAUgFCALm0AHQ0wMhcbCSXwTgItdJwSCSXwTgAtMfIYIQcGx1Z70ighBkc3RyvbCSXwXgA/pAMCD6RAHIygfL/8nQ7UTQgQFA1yH0BDBcgQEI9ApvoTGzkl8H4AXTP8glghBwbHVnupI4MOMNA4IQZHN0crqSXwbjDQYHAHgB+gD0BDD4J28iMFAKoSG+8uBQghBwbHVngx6xcIAYUATLBSbPFlj6Ahn0AMtpF8sfUmDLPyDJgED7AAYAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gIBIAkQAgEgCg8CAVgLDAA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA0OABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AABG4yX7UTQ1wsfgAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAT48oMI1xgg0x/TH9MfAvgju/Jk7UTQ0x/TH9P/9ATRUUO68qFRUbryogX5AVQQZPkQ8qP4ACSkyMsfUkDLH1Iwy/9SEPQAye1U+A8B0wchwACfbFGTINdKltMH1AL7AOgw4CHAAeMAIcAC4wABwAORMOMNA6TIyx8Syx/L/xITFBUAbtIH+gDU1CL5AAXIygcVy//J0Hd0gBjIywXLAiLPFlAF+gIUy2sSzMzJc/sAyEAUgQEI9FHypwIAcIEBCNcY+gDTP8hUIEeBAQj0UfKnghBub3RlcHSAGMjLBcsCUAbPFlAE+gIUy2oSyx/LP8lz+wACAGyBAQjXGPoA0z8wUiSBAQj0WfKnghBkc3RycHSAGMjLBcsCUAXPFlAD+gITy2rLHxLLP8lz+wAACvQAye1UAFEAAAAAKamjF9NTAQHUHhbX00VGZ3d2r8hbJxuz7PaxmuCOJ6kgckppQAFmQgABT9LR3Iqffskp0J9gWYO8Azlnb33BCMj8FqIUIGxGOZpiWgAAAAAAAAAAAAAAAAABGAGuD4p+pQAAAAAAAAAAQ7msoAgA/BGdBi/R01erquxJOvPgGKclBawUs3MAi0/IdctKQz8AKpDN/KDRxn7y32/ZigeYUXEbmOCO9BFNnbJ4OM7nPllGHoSBGQAkAAAAAGpldHRvbiB0ZXN0aW5nwHtw7A==', + tx2: 'te6cckECGgEABBQAAuGIAVSGb+UGjjP3lvt+zFA8wouI3McEd6CKbO2TwcZ3OfLKGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmpoxdJlgLSAAAAAAADgEXAgE0AhYBFP8A9KQT9LzyyAsDAgEgBBECAUgFCALm0AHQ0wMhcbCSXwTgItdJwSCSXwTgAtMfIYIQcGx1Z70ighBkc3RyvbCSXwXgA/pAMCD6RAHIygfL/8nQ7UTQgQFA1yH0BDBcgQEI9ApvoTGzkl8H4AXTP8glghBwbHVnupI4MOMNA4IQZHN0crqSXwbjDQYHAHgB+gD0BDD4J28iMFAKoSG+8uBQghBwbHVngx6xcIAYUATLBSbPFlj6Ahn0AMtpF8sfUmDLPyDJgED7AAYAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gIBIAkQAgEgCg8CAVgLDAA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA0OABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AABG4yX7UTQ1wsfgAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAT48oMI1xgg0x/TH9MfAvgju/Jk7UTQ0x/TH9P/9ATRUUO68qFRUbryogX5AVQQZPkQ8qP4ACSkyMsfUkDLH1Iwy/9SEPQAye1U+A8B0wchwACfbFGTINdKltMH1AL7AOgw4CHAAeMAIcAC4wABwAORMOMNA6TIyx8Syx/L/xITFBUAbtIH+gDU1CL5AAXIygcVy//J0Hd0gBjIywXLAiLPFlAF+gIUy2sSzMzJc/sAyEAUgQEI9FHypwIAcIEBCNcY+gDTP8hUIEeBAQj0UfKnghBub3RlcHSAGMjLBcsCUAbPFlAE+gIUy2oSyx/LP8lz+wACAGyBAQjXGPoA0z8wUiSBAQj0WfKnghBkc3RycHSAGMjLBcsCUAXPFlAD+gITy2rLHxLLP8lz+wAACvQAye1UAFEAAAAAKamjF9NTAQHUHhbX00VGZ3d2r8hbJxuz7PaxmuCOJ6kgckppQAFoYgABT9LR3Iqffskp0J9gWYO8Azlnb33BCMj8FqIUIGxGOaAX14QAAAAAAAAAAAAAAAAAARgBrg+KfqUAAAAAAAAAAEO5rKAIAPwRnQYv0dNXq6rsSTrz4BinJQWsFLNzAItPyHXLSkM/ACqQzfyg0cZ+8t9v2YoHmFFxG5jgjvQRTZ2yeDjO5z5ZRzEtARkAEAAAAAB0ZXN0MfeoHg==', + txBounceable: + 'te6cckECGgEABB0AAuGIAVSGb+UGjjP3lvt+zFA8wouI3McEd6CKbO2TwcZ3OfLKGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmpoxdJlgLSAAAAAAADgEXAgE0AhYBFP8A9KQT9LzyyAsDAgEgBBECAUgFCALm0AHQ0wMhcbCSXwTgItdJwSCSXwTgAtMfIYIQcGx1Z70ighBkc3RyvbCSXwXgA/pAMCD6RAHIygfL/8nQ7UTQgQFA1yH0BDBcgQEI9ApvoTGzkl8H4AXTP8glghBwbHVnupI4MOMNA4IQZHN0crqSXwbjDQYHAHgB+gD0BDD4J28iMFAKoSG+8uBQghBwbHVngx6xcIAYUATLBSbPFlj6Ahn0AMtpF8sfUmDLPyDJgED7AAYAilAEgQEI9Fkw7UTQgQFA1yDIAc8W9ADJ7VQBcrCOI4IQZHN0coMesXCAGFAFywVQA88WI/oCE8tqyx/LP8mAQPsAkl8D4gIBIAkQAgEgCg8CAVgLDAA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA0OABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AABG4yX7UTQ1wsfgAWb0kK29qJoQICga5D6AhhHDUCAhHpJN9KZEM5pA+n/mDeBKAG3gQFImHFZ8xhAT48oMI1xgg0x/TH9MfAvgju/Jk7UTQ0x/TH9P/9ATRUUO68qFRUbryogX5AVQQZPkQ8qP4ACSkyMsfUkDLH1Iwy/9SEPQAye1U+A8B0wchwACfbFGTINdKltMH1AL7AOgw4CHAAeMAIcAC4wABwAORMOMNA6TIyx8Syx/L/xITFBUAbtIH+gDU1CL5AAXIygcVy//J0Hd0gBjIywXLAiLPFlAF+gIUy2sSzMzJc/sAyEAUgQEI9FHypwIAcIEBCNcY+gDTP8hUIEeBAQj0UfKnghBub3RlcHSAGMjLBcsCUAbPFlAE+gIUy2oSyx/LP8lz+wACAGyBAQjXGPoA0z8wUiSBAQj0WfKnghBkc3RycHSAGMjLBcsCUAXPFlAD+gITy2rLHxLLP8lz+wAACvQAye1UAFEAAAAAKamjF9NTAQHUHhbX00VGZ3d2r8hbJxuz7PaxmuCOJ6kgckppQAFmYgABT9LR3Iqffskp0J9gWYO8Azlnb33BCMj8FqIUIGxGOZpiWgAAAAAAAAAAAAAAAAABGAGuD4p+pQAAAAAAAAAAQ7msoAgA/BGdBi/R01erquxJOvPgGKclBawUs3MAi0/IdctKQz8AKpDN/KDRxn7y32/ZigeYUXEbmOCO9BFNnbJ4OM7nPllGHoSBGQAkAAAAAGpldHRvbiB0ZXN0aW5ndUM5RQ==', + txId: 'J9ncpPEo7P5Lx3TLLhTFKQ2OroGQ53rv2nSB3jYgJLQ=', + txIdBounceable: '5AkPiyTMl5oUANd2UAzLmXmqIyU65xShhCooLq4igV8=', + signable: 'rq4tq/sFuXVLcQSfyxDd7QuxOif/5BQwpm0gwOa+sOE=', + bounceableSignable: 'eBYl/HjDEwBYsk9zRoppcKZ1hp2OrAMRuvchHV8MYuU=', + recipient: { + address: 'EQB-CM6DF-jpq9XVdiSdefAMU5KC1gpZuYBFp-Q65aUhnx5K', + amount: '1000000000', + }, + recipientBounceable: { + address: 'UQB-CM6DF-jpq9XVdiSdefAMU5KC1gpZuYBFp-Q65aUhn0OP', + amount: '1000000000', + }, +}; + export const signedSendTransactionForMemoId = { tx: 'te6cckEBAgEAqQAB4YgBJAxo7vqHF++LJ4bC/kJ8A1uVRskrKlrKJZ8rIB0tF+gCadlSX+hPo2mmhZyi0p3zTVUYVRkcmrCm97cSUFSa2vzvCArM3APg+ww92r3IcklNjnzfKOgysJVQXiCvj9SAaU1NGLsotvRwAAAAMAAcAQBmQgAaRefBOjTi/hwqDjv+7I6nGj9WEAe3ls/rFuBEQvggr5zEtAAAAAAAAAAAAAAAAAAAdfZO7w==', recipient: { diff --git a/modules/sdk-coin-ton/test/unit/tokenTransaction.ts b/modules/sdk-coin-ton/test/unit/tokenTransaction.ts new file mode 100644 index 0000000000..f00770445e --- /dev/null +++ b/modules/sdk-coin-ton/test/unit/tokenTransaction.ts @@ -0,0 +1,286 @@ +import * as sinon from 'sinon'; +import should from 'should'; +import Tonweb from 'tonweb'; +import { TransactionExplanation } from '@bitgo/sdk-core'; +import { TestBitGo } from '@bitgo/sdk-test'; +import { BitGoAPI } from '@bitgo/sdk-api'; +import { JettonToken, Ton, TonParseTransactionOptions } from '../../src'; +import * as testData from '../resources/ton'; + +describe('Jetton Transactions:', function () { + const testnetTokenName = 'tton:ukwny-us'; + const bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' }); + JettonToken.createTokenConstructors().forEach(({ name, coinConstructor }) => { + bitgo.safeRegister(name, coinConstructor); + }); + const testnetJettonToken = bitgo.coin(testnetTokenName); + bitgo.initializeTestVars(); + const txPrebuildList = [ + { + txHex: Buffer.from(testData.signedTokenSendTransaction.tx, 'base64').toString('hex'), + txInfo: {}, + }, + ]; + const txPrebuildBounceableList = [ + { + txHex: Buffer.from(testData.signedTokenSendTransaction.txBounceable, 'base64').toString('hex'), + txInfo: {}, + }, + ]; + + const txParamsList = [ + { + recipients: [testData.signedTokenSendTransaction.recipient], + }, + ]; + + const txParamsBounceableList = [ + { + recipients: [testData.signedTokenSendTransaction.recipientBounceable], + }, + ]; + + describe('Verify Jetton transaction: ', () => { + txParamsList.forEach((_, index) => { + const txParams = txParamsList[index]; + const txPrebuild = txPrebuildList[index]; + const txParamsBounceable = txParamsBounceableList[index]; + const txPrebuildBounceable = txPrebuildBounceableList[index]; + + it('should succeed to verify transaction', async function () { + const verification = {}; + const isTransactionVerified = await testnetJettonToken.verifyTransaction({ + txParams, + txPrebuild, + verification, + } as any); + isTransactionVerified.should.equal(true); + + const isBounceableTransactionVerified = await testnetJettonToken.verifyTransaction({ + txParams: txParamsBounceable, + txPrebuild: txPrebuildBounceable, + verification: {}, + } as any); + isBounceableTransactionVerified.should.equal(true); + }); + + it('should succeed to verify transaction when recipients amount are numbers', async function () { + const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams)); + txParamsWithNumberAmounts.recipients[0].amount = 20000000; + const verification = {}; + await testnetJettonToken + .verifyTransaction({ + txParams: txParamsWithNumberAmounts, + txPrebuild, + verification, + } as any) + .should.rejectedWith('Tx outputs does not match with expected txParams recipients'); + }); + + it('should succeed to verify transaction when recipients amount are strings', async function () { + const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams)); + txParamsWithNumberAmounts.recipients[0].amount = '20000000'; + const verification = {}; + await testnetJettonToken + .verifyTransaction({ + txParams: txParamsWithNumberAmounts, + txPrebuild, + verification, + } as any) + .should.rejectedWith('Tx outputs does not match with expected txParams recipients'); + }); + + it('should succeed to verify transaction when recipients amounts are number and amount is same', async function () { + const verification = {}; + await testnetJettonToken + .verifyTransaction({ + txParams, + txPrebuild, + verification, + } as any) + .should.resolvedWith(true); + }); + + it('should succeed to verify transaction when recipients amounts are string and amount is same', async function () { + const verification = {}; + await testnetJettonToken + .verifyTransaction({ + txParams, + txPrebuild, + verification, + } as any) + .should.resolvedWith(true); + }); + + it('should succeed to verify transaction when recipient address are non bounceable', async function () { + const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams)); + txParamsWithNumberAmounts.recipients[0].address = new Tonweb.Address( + txParamsWithNumberAmounts.recipients[0].address + ).toString(true, true, false); + const verification = {}; + const isVerified = await testnetJettonToken.verifyTransaction({ + txParams: txParamsWithNumberAmounts, + txPrebuild, + verification, + } as any); + isVerified.should.equal(true); + }); + + it('should fail to verify transaction with invalid param', async function () { + const txPrebuild = {}; + await testnetJettonToken + .verifyTransaction({ + txParams, + txPrebuild, + } as any) + .should.rejectedWith('missing required tx prebuild property txHex'); + }); + }); + }); + + describe('Explain Jetton Transaction: ', () => { + const testnetJettonToken = bitgo.coin(testnetTokenName); + it('should explain a jetton transfer transaction', async function () { + const explainedTransaction = (await testnetJettonToken.explainTransaction({ + txHex: Buffer.from(testData.signedTokenSendTransaction.tx, 'base64').toString('hex'), + })) as TransactionExplanation; + explainedTransaction.should.deepEqual({ + displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'], + id: testData.signedTokenSendTransaction.txId, + outputs: [ + { + address: testData.signedTokenSendTransaction.recipient.address, + amount: testData.signedTokenSendTransaction.recipient.amount, + }, + ], + outputAmount: testData.signedTokenSendTransaction.recipient.amount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: 'UNKNOWN' }, + withdrawAmount: undefined, + }); + }); + + it('should explain a non-bounceable jetton transfer transaction', async function () { + const explainedTransaction = (await testnetJettonToken.explainTransaction({ + txHex: Buffer.from(testData.signedTokenSendTransaction.txBounceable, 'base64').toString('hex'), + toAddressBounceable: false, + fromAddressBounceable: false, + })) as TransactionExplanation; + explainedTransaction.should.deepEqual({ + displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'], + id: testData.signedTokenSendTransaction.txIdBounceable, + outputs: [ + { + address: testData.signedTokenSendTransaction.recipientBounceable.address, + amount: testData.signedTokenSendTransaction.recipientBounceable.amount, + }, + ], + outputAmount: testData.signedTokenSendTransaction.recipientBounceable.amount, + changeOutputs: [], + changeAmount: '0', + fee: { fee: 'UNKNOWN' }, + withdrawAmount: undefined, + }); + }); + + it('should fail to explain transaction with missing params', async function () { + try { + await testnetJettonToken.explainTransaction({}); + } catch (error) { + should.equal(error.message, 'Invalid transaction'); + } + }); + + it('should fail to explain transaction with invalid params', async function () { + try { + await testnetJettonToken.explainTransaction({ txHex: 'randomString' }); + } catch (error) { + should.equal(error.message, 'Invalid transaction'); + } + }); + }); + + describe('Parse Jetton Transactions: ', () => { + const testnetJettonToken = bitgo.coin(testnetTokenName); + + const transactionsList = [testData.signedTokenSendTransaction.tx]; + + const transactionInputsResponseList = [ + [ + { + address: 'EQCqQzfyg0cZ-8t9v2YoHmFFxG5jgjvQRTZ2yeDjO5z5ZRy9', + amount: testData.tokenRecipients[0].amount, + }, + ], + ]; + + const transactionInputsResponseBounceableList = [ + [ + { + address: testData.tokenSender.address, + amount: testData.tokenRecipients[0].amount, + }, + ], + ]; + + const transactionOutputsResponseList = [ + [ + { + address: 'EQB-CM6DF-jpq9XVdiSdefAMU5KC1gpZuYBFp-Q65aUhnx5K', + amount: testData.tokenRecipients[0].amount, + }, + ], + ]; + + const transactionOutputsResponseBounceableList = [ + [ + { + address: testData.tokenRecipients[0].address, + amount: testData.tokenRecipients[0].amount, + }, + ], + ]; + + transactionsList.forEach((_, index) => { + const transaction = transactionsList[index]; + const transactionInputsResponse = transactionInputsResponseList[index]; + const transactionInputsResponseBounceable = transactionInputsResponseBounceableList[index]; + const transactionOutputsResponse = transactionOutputsResponseList[index]; + const transactionOutputsResponseBounceable = transactionOutputsResponseBounceableList[index]; + + it('should parse a TON transaction', async function () { + const parsedTransaction = await testnetJettonToken.parseTransaction({ + txHex: Buffer.from(transaction, 'base64').toString('hex'), + }); + + parsedTransaction.should.deepEqual({ + inputs: transactionInputsResponse, + outputs: transactionOutputsResponse, + }); + }); + + it('should parse a non-bounceable TON transaction', async function () { + const parsedTransaction = await testnetJettonToken.parseTransaction({ + txHex: Buffer.from(transaction, 'base64').toString('hex'), + toAddressBounceable: false, + fromAddressBounceable: false, + } as TonParseTransactionOptions); + + parsedTransaction.should.deepEqual({ + inputs: transactionInputsResponseBounceable, + outputs: transactionOutputsResponseBounceable, + }); + }); + + it('should fail to parse a TON transaction when explainTransaction response is undefined', async function () { + const stub = sinon.stub(Ton.prototype, 'explainTransaction'); + stub.resolves(undefined); + await testnetJettonToken + .parseTransaction({ txHex: transaction }) + .should.be.rejectedWith('invalid raw transaction'); + stub.restore(); + }); + }); + }); +}); diff --git a/modules/sdk-coin-ton/test/unit/tokenTransferBuilder.ts b/modules/sdk-coin-ton/test/unit/tokenTransferBuilder.ts new file mode 100644 index 0000000000..37efb529ce --- /dev/null +++ b/modules/sdk-coin-ton/test/unit/tokenTransferBuilder.ts @@ -0,0 +1,243 @@ +import should from 'should'; +import TonWeb from 'tonweb'; +import { TransactionType } from '@bitgo/sdk-core'; +import { coins } from '@bitgo/statics'; +import { TransactionBuilderFactory, KeyPair } from '../../src'; +import * as testData from '../resources/ton'; +import * as utils from '../../src/lib/utils'; + +describe('Ton Token Transfer Builder', () => { + const tokenName = 'tton:ukwny-us'; + const factory = new TransactionBuilderFactory(coins.get(tokenName)); + it('should build a unsigned transfer tx', async function () { + const txId = testData.signedTokenSendTransaction.txId.replace(/\//g, '_').replace(/\+/g, '-'); + const txBuilder = factory.getTokenTransferBuilder(); + txBuilder.sender(testData.tokenSender.address); + txBuilder.sequenceNumber(0); + txBuilder.publicKey(testData.tokenSender.publicKey); + txBuilder.expireTime(testData.tokenSender.expireTime); + txBuilder.send(testData.tokenRecipients[0]); + txBuilder.setSenderJettonWalletAddress(testData.tokenSender.jettonAddress); + txBuilder.setTonAmount(testData.tokenSender.tonAmount); // amount of TON to send to the sender's jetton wallet + txBuilder.setForwardTonAmount(testData.tokenSender.forwardTonAmount); // amount of TON to cover forward fees in case of notify transfer + txBuilder.setMessage(testData.tokenSender.message); + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.SendToken); + should.equal(tx.toJson().bounceable, false); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.tokenSender.address, + value: testData.tokenRecipients[0].amount, + coin: tokenName, + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.tokenRecipients[0].address, + value: testData.tokenRecipients[0].amount, + coin: tokenName, + }); + tx.id.should.equal(txId); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.equal(testData.signedTokenSendTransaction.tx); + }); + + it('should build a unsigned transfer tx with bounceable flag', async function () { + const txId = testData.signedTokenSendTransaction.txIdBounceable.replace(/\//g, '_').replace(/\+/g, '-'); + const txBuilder = factory.getTokenTransferBuilder(); + txBuilder.sender(testData.tokenSender.address); + txBuilder.sequenceNumber(0); + txBuilder.publicKey(testData.tokenSender.publicKey); + txBuilder.expireTime(testData.tokenSender.expireTime); + txBuilder.send(testData.tokenRecipients[0]); + txBuilder.setSenderJettonWalletAddress(testData.tokenSender.jettonAddress); + txBuilder.setTonAmount(testData.tokenSender.tonAmount); // amount of TON to send to the sender's jetton wallet + txBuilder.setForwardTonAmount(testData.tokenSender.forwardTonAmount); // amount of TON to cover forward fees in case of notify transfer + txBuilder.setMessage(testData.tokenSender.message); + txBuilder.bounceable(true); + + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.SendToken); + should.equal(tx.toJson().bounceable, true); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.tokenSender.address, + value: testData.tokenRecipients[0].amount, + coin: tokenName, + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address: testData.tokenRecipients[0].address, + value: testData.tokenRecipients[0].amount, + coin: tokenName, + }); + tx.id.should.equal(txId); + const rawTx = tx.toBroadcastFormat(); + rawTx.should.equal(testData.signedTokenSendTransaction.txBounceable); + }); + + it('should build a send from rawTx', async function () { + const txBuilder = factory.from(testData.signedTokenSendTransaction.tx); + const builtTx = await txBuilder.build(); + const jsonTx = builtTx.toJson(); + should.equal(builtTx.type, TransactionType.SendToken); + + should.equal(builtTx.signablePayload.toString('base64'), testData.signedTokenSendTransaction.signable); + should.equal(builtTx.id, testData.signedTokenSendTransaction.txId); + const builder2 = factory.from(builtTx.toBroadcastFormat()); + const builtTx2 = await builder2.build(); + should.equal(builtTx2.type, TransactionType.SendToken); + should.equal(builtTx.toBroadcastFormat(), testData.signedTokenSendTransaction.tx); + builtTx.inputs.length.should.equal(1); + builtTx.outputs.length.should.equal(1); + jsonTx.sender.should.equal('EQCqQzfyg0cZ-8t9v2YoHmFFxG5jgjvQRTZ2yeDjO5z5ZRy9'); + jsonTx.destination.should.equal('EQB-CM6DF-jpq9XVdiSdefAMU5KC1gpZuYBFp-Q65aUhnx5K'); + jsonTx.amount.should.equal(testData.tokenRecipients[0].amount); + jsonTx.seqno.should.equal(0); + jsonTx.expirationTime.should.equal(testData.tokenSender.expireTime); + + const builtTx3 = await txBuilder.bounceable(true).fromAddressBounceable(false).toAddressBounceable(false).build(); + txBuilder.from(testData.signedTokenSendTransaction.txBounceable); + const jsonTx3 = builtTx3.toJson(); + should.equal(jsonTx3.bounceable, true); + should.equal(builtTx3.signablePayload.toString('base64'), testData.signedTokenSendTransaction.bounceableSignable); + should.equal(builtTx3.id, testData.signedTokenSendTransaction.txIdBounceable); + should.equal(builtTx3.toBroadcastFormat(), testData.signedTokenSendTransaction.txBounceable); + jsonTx3.sender.should.equal(testData.tokenSender.address); + jsonTx3.destination.should.equal(testData.tokenRecipients[0].address); + jsonTx3.amount.should.equal(testData.tokenRecipients[0].amount); + jsonTx3.seqno.should.equal(0); + jsonTx3.expirationTime.should.equal(testData.tokenSender.expireTime); + }); + + it('should parse a raw transaction and set flags', async function () { + const factory = new TransactionBuilderFactory(coins.get(tokenName)); + const txBuilder = factory.from(testData.signedTokenSendTransaction.tx); + const txBuilderBounceable = factory.from(testData.signedTokenSendTransaction.txBounceable); + + const tx = await txBuilder.build(); + const txBounceable = await txBuilderBounceable.build(); + tx.toJson().bounceable.should.equal(false); + should.equal(tx.type, TransactionType.SendToken); + txBounceable.toJson().bounceable.should.equal(true); + should.equal(txBounceable.type, TransactionType.SendToken); + }); + + xit('should build a signed transfer tx and submit onchain', async function () { + const tonweb = new TonWeb(new TonWeb.HttpProvider('https://testnet.toncenter.com/api/v2/jsonRPC')); + const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey6 }); + const publicKey = keyPair.getKeys().pub; + const address = await utils.default.getAddressFromPublicKey(publicKey); + const txBuilder = factory.getTokenTransferBuilder(); + txBuilder.sender(address); + + const WalletClass = tonweb.wallet.all['v4R2']; + const wallet = new WalletClass(tonweb.provider, { + publicKey: tonweb.utils.hexToBytes(publicKey), + wc: 0, + }); + const seqno = await wallet.methods.seqno().call(); + txBuilder.sequenceNumber(seqno as number); + txBuilder.publicKey(publicKey); + const expireAt = Math.floor(Date.now() / 1e3) + 60 * 60 * 24 * 7; // 7 days + txBuilder.expireTime(expireAt); + txBuilder.send({ + address: testData.tokenRecipients[0].address, + amount: '1000000000', + }); + txBuilder.setSenderJettonWalletAddress(testData.tokenSender.jettonAddress); + txBuilder.setTonAmount('500000000'); // amount of TON to send to the sender's jetton wallet + txBuilder.setForwardTonAmount('100000000'); // amount of TON to cover forward fees in case of notify transfer + txBuilder.setMessage('test'); + + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.SendToken); + const signable = tx.signablePayload; + const signature = keyPair.signMessageinUint8Array(signable); + const signedTx = await txBuilder.build(); + + const builder2 = factory.from(signedTx.toBroadcastFormat()); + builder2.addSignature(keyPair.getKeys(), Buffer.from(signature)); + const tx2 = await builder2.build(); + const signature2 = keyPair.signMessageinUint8Array(tx2.signablePayload); + should.equal(Buffer.from(signature).toString('hex'), Buffer.from(signature2).toString('hex')); + await new Promise((resolve) => setTimeout(resolve, 2000)); + + try { + const result = await tonweb.provider.sendBoc(tx2.toBroadcastFormat()); + console.log('Network Response:', result); + } catch (error) { + console.error('Error Response:', error); + } + }); + + it('should build a signed transfer tx using add signature', async function () { + const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey6 }); + const publicKey = keyPair.getKeys().pub; + const address = await utils.default.getAddressFromPublicKey(publicKey); + const txBuilder = factory.getTokenTransferBuilder(); + txBuilder.sender(address); + txBuilder.sequenceNumber(0); + txBuilder.publicKey(publicKey); + const expireAt = Math.floor(Date.now() / 1e3) + 60 * 60 * 24 * 7; + txBuilder.expireTime(expireAt); + txBuilder.send(testData.tokenRecipients[0]); + txBuilder.setSenderJettonWalletAddress(testData.tokenSender.jettonAddress); + txBuilder.setTonAmount(testData.tokenSender.tonAmount); // amount of TON to send to the sender's jetton wallet + txBuilder.setForwardTonAmount(testData.tokenSender.forwardTonAmount); // amount of TON to cover forward fees in case of notify transfer + txBuilder.setMessage(testData.tokenSender.message); + + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.SendToken); + const signable = tx.signablePayload; + const signature = keyPair.signMessageinUint8Array(signable); + + txBuilder.addSignature(keyPair.getKeys(), Buffer.from(signature)); + const signedTx = await txBuilder.build(); + const builder2 = factory.from(signedTx.toBroadcastFormat()); + const tx2 = await builder2.build(); + + const signature2 = keyPair.signMessageinUint8Array(tx2.signablePayload); + should.equal(Buffer.from(signature).toString('hex'), Buffer.from(signature2).toString('hex')); + should.equal(tx.toBroadcastFormat(), tx2.toBroadcastFormat()); + }); + + it('should build transfer tx for non-bounceable address', async function () { + const txBuilder = factory.getTokenTransferBuilder(); + txBuilder.sender(testData.tokenSender.address); + txBuilder.sequenceNumber(0); + txBuilder.publicKey(testData.tokenSender.publicKey); + txBuilder.expireTime(testData.tokenSender.expireTime); + const address = 'EQAWzEKcdnykvXfUNouqdS62tvrp32bCxuKS6eQrS6ISgcLo'; + const otherFormat = 'UQAWzEKcdnykvXfUNouqdS62tvrp32bCxuKS6eQrS6ISgZ8t'; + const amount = testData.tokenRecipients[0].amount; + txBuilder.send({ address, amount }); + + txBuilder.setSenderJettonWalletAddress(testData.tokenSender.jettonAddress); + txBuilder.setTonAmount(testData.tokenSender.tonAmount); // amount of TON to send to the sender's jetton wallet + txBuilder.setForwardTonAmount(testData.tokenSender.forwardTonAmount); // amount of TON to cover forward fees in case of notify transfer + txBuilder.setMessage(testData.tokenSender.message); + + const tx = await txBuilder.build(); + should.equal(tx.type, TransactionType.SendToken); + tx.inputs.length.should.equal(1); + tx.inputs[0].should.deepEqual({ + address: testData.tokenSender.address, + value: amount, + coin: tokenName, + }); + tx.outputs.length.should.equal(1); + tx.outputs[0].should.deepEqual({ + address, + value: amount, + coin: tokenName, + }); + const txJson = tx.toJson(); + txJson.destination.should.equal(address); + txJson.destinationAlias.should.equal(otherFormat); + + const builder2 = factory.from(tx.toBroadcastFormat()); + const tx2 = await builder2.build(); + const txJson2 = tx2.toJson(); + txJson2.destinationAlias.should.equal(otherFormat); + }); +}); diff --git a/modules/sdk-coin-ton/test/unit/transferBuilder.ts b/modules/sdk-coin-ton/test/unit/transferBuilder.ts index 926c1a7802..732346b8d9 100644 --- a/modules/sdk-coin-ton/test/unit/transferBuilder.ts +++ b/modules/sdk-coin-ton/test/unit/transferBuilder.ts @@ -1,11 +1,10 @@ import should from 'should'; +import TonWeb from 'tonweb'; import { TransactionType } from '@bitgo/sdk-core'; -import { TransactionBuilderFactory } from '../../src/lib/transactionBuilderFactory'; import { coins } from '@bitgo/statics'; +import { TransactionBuilderFactory, KeyPair } from '../../src'; import * as testData from '../resources/ton'; -import { KeyPair } from '../../src/lib/keyPair'; import * as utils from '../../src/lib/utils'; -import TonWeb from 'tonweb'; describe('Ton Transfer Builder', () => { const factory = new TransactionBuilderFactory(coins.get('tton')); From e140bc77fadbb139466bf5945135c30eabbd7480 Mon Sep 17 00:00:00 2001 From: Venkat-Annavazzala Date: Mon, 22 Sep 2025 16:00:31 +0530 Subject: [PATCH 23/35] chore: added new tokens for baseeth, lineath, seievm and flow TICKET: WIN-7285 --- modules/bitgo/src/v2/coinFactory.ts | 15 ++ modules/statics/src/allCoinsAndTokens.ts | 177 ++++++++++++++++++++++- modules/statics/src/base.ts | 24 +++ modules/statics/src/coins.ts | 6 + modules/statics/src/tokenConfig.ts | 90 ++++++++++++ 5 files changed, 306 insertions(+), 6 deletions(-) diff --git a/modules/bitgo/src/v2/coinFactory.ts b/modules/bitgo/src/v2/coinFactory.ts index 23c4e7da07..0d42243917 100644 --- a/modules/bitgo/src/v2/coinFactory.ts +++ b/modules/bitgo/src/v2/coinFactory.ts @@ -962,6 +962,21 @@ export function getTokenConstructor(tokenConfig: TokenConfig): CoinConstructor | case 'apt': case 'tapt': return AptToken.createTokenConstructor(tokenConfig as AptTokenConfig); + case 'flow': + case 'tflow': { + const coinNames = { Mainnet: 'flow', Testnet: 'tflow' }; + return EthLikeErc20Token.createTokenConstructor(tokenConfig as EthLikeTokenConfig, coinNames); + } + case 'seievm': + case 'tseievm': { + const coinNames = { Mainnet: 'seievm', Testnet: 'tseievm' }; + return EthLikeErc20Token.createTokenConstructor(tokenConfig as EthLikeTokenConfig, coinNames); + } + case 'lineaeth': + case 'tlineaeth': { + const coinNames = { Mainnet: 'lineaeth', Testnet: 'tlineaeth' }; + return EthLikeErc20Token.createTokenConstructor(tokenConfig as EthLikeTokenConfig, coinNames); + } case 'stx': case 'tstx': return Sip10Token.createTokenConstructor(tokenConfig as Sip10TokenConfig); diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index af43f83c84..4da95b3691 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -825,6 +825,7 @@ export const allCoinsAndTokens = [ CoinFeature.EVM_COMPATIBLE_UI, CoinFeature.EVM_UNSIGNED_SWEEP_RECOVERY, CoinFeature.EVM_NON_BITGO_RECOVERY, + CoinFeature.SUPPORTS_ERC20, ] ), account( @@ -843,6 +844,7 @@ export const allCoinsAndTokens = [ CoinFeature.EVM_COMPATIBLE_UI, CoinFeature.EVM_NON_BITGO_RECOVERY, CoinFeature.EVM_UNSIGNED_SWEEP_RECOVERY, + CoinFeature.SUPPORTS_ERC20, ], KeyCurve.Secp256k1, '', @@ -1983,6 +1985,7 @@ export const allCoinsAndTokens = [ CoinFeature.EVM_COMPATIBLE_IMS, CoinFeature.EVM_COMPATIBLE_UI, CoinFeature.EVM_COMPATIBLE_WP, + CoinFeature.SUPPORTS_ERC20, ] ), account( @@ -2126,6 +2129,15 @@ export const allCoinsAndTokens = [ BaseUnit.ETH, CELO_FEATURES ), + erc20Token( + '16c438c1-714a-4ad7-bdb1-fb8d2575c466', + 'tbaseeth:usdc', + 'Testnet USDC', + 6, + '0x036cbd53842c5426634e7929541ec2318f3dcf7e', + UnderlyingAsset['tbaseeth:usdc'], + Networks.test.basechain + ), erc20Token( '03b67719-a5d5-4ae3-a050-252b948f4daa', 'baseeth:aero', @@ -2136,13 +2148,166 @@ export const allCoinsAndTokens = [ Networks.main.basechain ), erc20Token( - '16c438c1-714a-4ad7-bdb1-fb8d2575c466', - 'tbaseeth:usdc', - 'Testnet USDC', + '07e33515-183e-400b-a681-53a7e4b6df02', + 'baseeth:usdc', + 'USDC', 6, - '0x036cbd53842c5426634e7929541ec2318f3dcf7e', - UnderlyingAsset['tbaseeth:usdc'], - Networks.test.basechain + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + UnderlyingAsset['baseeth:usdc'], + Networks.main.basechain + ), + erc20Token( + '3d542986-403f-4302-aa57-95f4dec26727', + 'baseeth:wbtc', + 'Wrapped BTC', + 8, + '0x0555e30da8f98308edb960aa94c0db47230d2b9c', + UnderlyingAsset['baseeth:wbtc'], + Networks.main.basechain + ), + erc20Token( + 'b7e7a9f6-4563-45d0-ba5f-260c2f363638', + 'baseeth:usde', + 'Ethena USDe', + 18, + '0x5d3a1ff2b6bab83b63cd9ad0787074081a52ef34', + UnderlyingAsset['baseeth:usde'], + Networks.main.basechain + ), + erc20Token( + '525a07c9-4df0-4e79-8e65-9cf74e07cd5b', + 'baseeth:trust', + 'Trust', + 18, + '0x6cd905df2ed214b22e0d48ff17cd4200c1c6d8a3', + UnderlyingAsset['baseeth:trust'], + Networks.main.basechain + ), + erc20Token( + 'e8be1d67-4e15-4865-af1c-a0c4dc1902f3', + 'baseeth:flk', + 'Fleek', + 18, + '0xe0969ec84456b7e4d3dd2181fb5265edbb63f7bd', + UnderlyingAsset['baseeth:flk'], + Networks.main.basechain + ), + erc20Token( + '3842a6cf-1bd5-4741-ad09-1071e8f5e26c', + 'seievm:usdc', + 'USDC', + 6, + '0xe15fc38f6d8c56af07bbcbe3baf5708a2bf42392', + UnderlyingAsset['seievm:usdc'], + Networks.main.seievm + ), + erc20Token( + '94cbea4e-c56d-4b43-aa38-83c8806eda3e', + 'seievm:weth', + 'Wrapped Ether', + 18, + '0x160345fc359604fc6e70e3c5facbde5f7a9342d8', + UnderlyingAsset['seievm:weth'], + Networks.main.seievm + ), + erc20Token( + 'c4f2a3af-15df-4dc8-95ff-55150d150c30', + 'seievm:wbtc', + 'Wrapped BTC', + 8, + '0x0555e30da8f98308edb960aa94c0db47230d2b9c', + UnderlyingAsset['seievm:wbtc'], + Networks.main.seievm + ), + erc20Token( + 'af997171-f1c5-4938-b88c-0bfd2b98aed4', + 'seievm:usd0', + 'USD₮0', + 6, + '0x9151434b16b9763660705744891fa906f660ecc5', + UnderlyingAsset['seievm:usd0'], + Networks.main.seievm + ), + erc20Token( + '0ad7a932-bccf-4f37-a201-69ae3571bfa7', + 'lineaeth:linea', + 'Linea', + 18, + '0x1789e0043623282d5dcc7f213d703c6d8bafbb04', + UnderlyingAsset['lineaeth:linea'], + Networks.main.lineaeth + ), + erc20Token( + 'fa924bd1-eb96-4e40-aecc-447e64aea7dc', + 'lineaeth:usdt', + 'Linea USDT', + 6, + '0xa219439258ca9da29e9cc4ce5596924745e12b93', + UnderlyingAsset['lineaeth:usdt'], + Networks.main.lineaeth + ), + erc20Token( + '8a2e3d48-f8f2-441b-9c64-cbed6e607d1a', + 'lineaeth:usdc', + 'Linea USDC', + 6, + '0x176211869ca2b568f2a7d4ee941e073a821ee1ff', + UnderlyingAsset['lineaeth:usdc'], + Networks.main.lineaeth + ), + erc20Token( + '5fd24ec5-2312-4c44-8323-6a2a1fec401b', + 'flow:usdf', + 'USD Flow', + 6, + '0x2aabea2058b5ac2d339b163c6ab6f2b6d53aabed', + UnderlyingAsset['flow:usdf'], + Networks.main.flow + ), + erc20Token( + '107f05d3-fe76-40a0-97aa-72478eddbe39', + 'flow:wflow', + 'Wrapped Flow', + 18, + '0xd3bf53dac106a0290b0483ecbc89d40fcc961f3e', + UnderlyingAsset['flow:wflow'], + Networks.main.flow + ), + erc20Token( + 'cf416c79-0c47-4fe8-b534-1fff088332f3', + 'flow:weth', + 'WETH', + 18, + '0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590', + UnderlyingAsset['flow:weth'], + Networks.main.flow + ), + erc20Token( + '7c6e8a37-6f6a-4f9a-9b38-fa43d61bc3d9', + 'baseeth:icnt', + 'Impossible Cloud Network Token', + 18, + '0xe0cd4cacddcbf4f36e845407ce53e87717b6601d', + UnderlyingAsset['baseeth:icnt'], + Networks.main.basechain + ), + erc20Token( + 'f5df6b74-c009-4d28-95e6-3cc7e66427b6', + 'baseeth:weth', + 'Wrapped Ether', + 18, + '0x4200000000000000000000000000000000000006', + UnderlyingAsset['baseeth:weth'], + Networks.main.basechain + ), + erc20Token( + 'e8c95214-a0d1-42b7-8ea1-64857c324216', + 'baseeth:morpho', + 'Morpho Token', + 18, + '0xbaa5cc21fd487b8fcc2f632f3f4e8d37262a0842', + UnderlyingAsset['baseeth:morpho'], + Networks.main.basechain ), hederaCoin( '98aad956-27ee-45dd-aa43-6a23c9a1d1d0', diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index ac3ca04144..a862881180 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -2743,10 +2743,34 @@ export enum UnderlyingAsset { // BaseETH mainnet tokens 'baseeth:aero' = 'baseeth:aero', + 'baseeth:icnt' = 'baseeth:icnt', + 'baseeth:morpho' = 'baseeth:morpho', + 'baseeth:weth' = 'baseeth:weth', + 'baseeth:usdc' = 'baseeth:usdc', + 'baseeth:wbtc' = 'baseeth:wbtc', + 'baseeth:usde' = 'baseeth:usde', + 'baseeth:trust' = 'baseeth:trust', + 'baseeth:flk' = 'baseeth:flk', // BaseETH testnet tokens 'tbaseeth:usdc' = 'tbaseeth:usdc', + // Seievm mainnet tokens + 'seievm:usdc' = 'seievm:usdc', + 'seievm:weth' = 'seievm:weth', + 'seievm:wbtc' = 'seievm:wbtc', + 'seievm:usd0' = 'seievm:usd0', + + //Linea mainnet tokens + 'lineaeth:linea' = 'lineaeth:linea', + 'lineaeth:usdt' = 'lineaeth:usdt', + 'lineaeth:usdc' = 'lineaeth:usdc', + + // Flow mainnet tokens + 'flow:weth' = 'flow:weth', + 'flow:usdf' = 'flow:usdf', + 'flow:wflow' = 'flow:wflow', + // Arbitrum testnet tokens 'tarbeth:link' = 'tarbeth:link', 'tarbeth:xsgd' = 'tarbeth:xsgd', diff --git a/modules/statics/src/coins.ts b/modules/statics/src/coins.ts index 354fb32001..1d535f5856 100644 --- a/modules/statics/src/coins.ts +++ b/modules/statics/src/coins.ts @@ -48,6 +48,9 @@ export function createToken(token: AmsTokenConfig): Readonly | undefin avaxc: avaxErc20, baseeth: erc20Token, bera: beraErc20, + flow: erc20Token, + lineaeth: erc20Token, + seievm: erc20Token, bsc: bscToken, celo: celoToken, cosmos: cosmosToken, @@ -108,6 +111,9 @@ export function createToken(token: AmsTokenConfig): Readonly | undefin case 'baseeth': case 'bera': case 'bsc': + case 'flow': + case 'lineaeth': + case 'seievm': case 'celo': case 'eth': case 'opeth': diff --git a/modules/statics/src/tokenConfig.ts b/modules/statics/src/tokenConfig.ts index df8c566ea6..011105f98f 100644 --- a/modules/statics/src/tokenConfig.ts +++ b/modules/statics/src/tokenConfig.ts @@ -215,6 +215,15 @@ export interface Tokens { baseeth: { tokens: EthLikeTokenConfig[]; }; + flow: { + tokens: EthLikeTokenConfig[]; + }; + lineaeth: { + tokens: EthLikeTokenConfig[]; + }; + seievm: { + tokens: EthLikeTokenConfig[]; + }; coredao: { tokens: EthLikeTokenConfig[]; }; @@ -316,6 +325,15 @@ export interface Tokens { baseeth: { tokens: EthLikeTokenConfig[]; }; + flow: { + tokens: EthLikeTokenConfig[]; + }; + lineaeth: { + tokens: EthLikeTokenConfig[]; + }; + seievm: { + tokens: EthLikeTokenConfig[]; + }; sol: { tokens: SolTokenConfig[]; }; @@ -696,6 +714,60 @@ const getFormattedBaseethTokens = (customCoinMap = coins) => return acc; }, []); +function getSeievmTokenConfig(coin: EthLikeERC20Token): EthLikeTokenConfig { + return { + type: coin.name, + coin: coin.network.type === NetworkType.MAINNET ? 'seievm' : 'tseievm', + network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet', + name: coin.fullName, + tokenContractAddress: coin.contractAddress.toString().toLowerCase(), + decimalPlaces: coin.decimalPlaces, + }; +} +const getFormattedSeievmTokens = (customCoinMap = coins) => + customCoinMap.reduce((acc: EthLikeTokenConfig[], coin) => { + if (coin instanceof EthLikeERC20Token && (coin.name.includes('seievm:') || coin.name.includes('tseievm:'))) { + acc.push(getSeievmTokenConfig(coin)); + } + return acc; + }, []); + +function getFlowTokenConfig(coin: EthLikeERC20Token): EthLikeTokenConfig { + return { + type: coin.name, + coin: coin.network.type === NetworkType.MAINNET ? 'flow' : 'tflow', + network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet', + name: coin.fullName, + tokenContractAddress: coin.contractAddress.toString().toLowerCase(), + decimalPlaces: coin.decimalPlaces, + }; +} +const getFormattedFlowTokens = (customCoinMap = coins) => + customCoinMap.reduce((acc: EthLikeTokenConfig[], coin) => { + if (coin instanceof EthLikeERC20Token && (coin.name.includes('flow:') || coin.name.includes('tflow:'))) { + acc.push(getFlowTokenConfig(coin)); + } + return acc; + }, []); + +function getLineaethTokenConfig(coin: EthLikeERC20Token): EthLikeTokenConfig { + return { + type: coin.name, + coin: coin.network.type === NetworkType.MAINNET ? 'lineaeth' : 'tlineaeth', + network: coin.network.type === NetworkType.MAINNET ? 'Mainnet' : 'Testnet', + name: coin.fullName, + tokenContractAddress: coin.contractAddress.toString().toLowerCase(), + decimalPlaces: coin.decimalPlaces, + }; +} +const getFormattedLineaethTokens = (customCoinMap = coins) => + customCoinMap.reduce((acc: EthLikeTokenConfig[], coin) => { + if (coin instanceof EthLikeERC20Token && (coin.name.includes('lineaeth:') || coin.name.includes('tlineaeth:'))) { + acc.push(getLineaethTokenConfig(coin)); + } + return acc; + }, []); + function getZkethTokenConfig(coin: ZkethERC20Token): EthLikeTokenConfig { return { type: coin.name, @@ -1156,6 +1228,15 @@ export const getFormattedTokens = (coinMap = coins): Tokens => { baseeth: { tokens: getFormattedBaseethTokens(coinMap).filter((token) => token.network === 'Mainnet'), }, + flow: { + tokens: getFormattedFlowTokens(coinMap).filter((token) => token.network === 'Mainnet'), + }, + lineaeth: { + tokens: getFormattedLineaethTokens(coinMap).filter((token) => token.network === 'Mainnet'), + }, + seievm: { + tokens: getFormattedSeievmTokens(coinMap).filter((token) => token.network === 'Mainnet'), + }, zketh: { tokens: getFormattedZkethTokens(coinMap).filter((token) => token.network === 'Mainnet'), }, @@ -1263,6 +1344,15 @@ export const getFormattedTokens = (coinMap = coins): Tokens => { baseeth: { tokens: getFormattedBaseethTokens(coinMap).filter((token) => token.network === 'Testnet'), }, + flow: { + tokens: getFormattedFlowTokens(coinMap).filter((token) => token.network === 'Testnet'), + }, + lineaeth: { + tokens: getFormattedLineaethTokens(coinMap).filter((token) => token.network === 'Testnet'), + }, + seievm: { + tokens: getFormattedSeievmTokens(coinMap).filter((token) => token.network === 'Testnet'), + }, zketh: { tokens: getFormattedZkethTokens(coinMap).filter((token) => token.network === 'Testnet'), }, From 745219fef999b2df635caa1d8d5edc139cd53732 Mon Sep 17 00:00:00 2001 From: sasikumar-bitgo Date: Wed, 24 Sep 2025 10:15:14 +0530 Subject: [PATCH 24/35] fix(sdk-core): backup keychain creation to use correct privateMaterial TICKET: WP-6057 Replaces the use of userPrivateMaterial with backupPrivateMaterial when adding the backup keychain in EcdsaMPCv2Utils. This ensures the correct private material is used for backup keychain generation. --- modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts b/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts index 08eb0d7dc4..49980335e3 100644 --- a/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts +++ b/modules/sdk-core/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.ts @@ -321,7 +321,7 @@ export class EcdsaMPCv2Utils extends BaseEcdsaUtils { ); const backupKeychainPromise = this.addBackupKeychain( bitgoCommonKeychain, - userPrivateMaterial, + backupPrivateMaterial, backupReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode From 5f2771d611a674197b6078deb9f2caa06ce81ec1 Mon Sep 17 00:00:00 2001 From: Lokesh Chandra Date: Wed, 24 Sep 2025 12:43:50 +0530 Subject: [PATCH 25/35] feat(express): migrate calculateminerfeeinfo to typed routes Ticket: WP-5400 --- modules/express/src/clientRoutes.ts | 10 +- .../api/common/calculateMinerFeeInfo.ts | 54 +++ modules/express/src/typedRoutes/api/index.ts | 4 + .../unit/typedRoutes/calculateMinerFeeInfo.ts | 319 ++++++++++++++++++ 4 files changed, 381 insertions(+), 6 deletions(-) create mode 100644 modules/express/src/typedRoutes/api/common/calculateMinerFeeInfo.ts create mode 100644 modules/express/test/unit/typedRoutes/calculateMinerFeeInfo.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index 9f7a75eba6..971fcbfdc6 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -297,7 +297,7 @@ function handleFanOutUnspents(req: express.Request) { * @deprecated * @param req */ -function handleCalculateMinerFeeInfo(req: express.Request) { +function handleCalculateMinerFeeInfo(req: ExpressApiRouteRequest<'express.calculateminerfeeinfo', 'post'>) { return req.bitgo.calculateMinerFeeInfo({ bitgo: req.bitgo, feeRate: req.body.feeRate, @@ -1560,12 +1560,10 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { router.post('express.encrypt', [prepareBitGo(config), typedPromiseWrapper(handleEncrypt)]); router.post('express.verifyaddress', [prepareBitGo(config), typedPromiseWrapper(handleVerifyAddress)]); router.post('express.lightning.initWallet', [prepareBitGo(config), typedPromiseWrapper(handleInitLightningWallet)]); - app.post( - '/api/v[12]/calculateminerfeeinfo', - parseBody, + router.post('express.calculateminerfeeinfo', [ prepareBitGo(config), - promiseWrapper(handleCalculateMinerFeeInfo) - ); + typedPromiseWrapper(handleCalculateMinerFeeInfo), + ]); app.post('/api/v1/keychain/local', parseBody, prepareBitGo(config), promiseWrapper(handleCreateLocalKeyChain)); app.post('/api/v1/keychain/derive', parseBody, prepareBitGo(config), promiseWrapper(handleDeriveLocalKeyChain)); diff --git a/modules/express/src/typedRoutes/api/common/calculateMinerFeeInfo.ts b/modules/express/src/typedRoutes/api/common/calculateMinerFeeInfo.ts new file mode 100644 index 0000000000..bfac7395d9 --- /dev/null +++ b/modules/express/src/typedRoutes/api/common/calculateMinerFeeInfo.ts @@ -0,0 +1,54 @@ +import * as t from 'io-ts'; +import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; +import { BitgoExpressError } from '../../schemas/error'; + +export const CalculateMinerFeeInfoRequestBody = { + /** fee rate in satoshis per kilobyte, if not provided a fallback fee rate will be used */ + feeRate: optional(t.number), + /** number of P2SH (multisig) inputs in the transaction */ + nP2shInputs: t.number, + /** number of P2PKH (single sig) inputs in the transaction */ + nP2pkhInputs: t.number, + /** number of P2SH-P2WSH (segwit) inputs in the transaction */ + nP2shP2wshInputs: t.number, + /** number of outputs in the transaction */ + nOutputs: t.number, + /** whether the transaction contains uncompressed public keys (affects size calculation) */ + containsUncompressedPublicKeys: optional(t.boolean), +}; + +export const CalculateMinerFeeInfoResponse = t.type({ + /** estimated size of the transaction in bytes */ + size: t.number, + /** estimated fee in satoshis for the transaction */ + fee: t.number, + /** fee rate that was used to estimate the fee (in satoshis per kilobyte) */ + feeRate: t.number, +}); + +/** + * Calculate miner fee info + * + * Calculates the estimated size and fee for a transaction based on the number and types of inputs and outputs. + * This is useful for estimating the fee before creating a transaction. + * + * The calculation takes into account: + * 1. The number and types of inputs (P2SH, P2PKH, P2SH-P2WSH) + * 2. The number of outputs + * 3. Whether the transaction contains uncompressed public keys + * 4. The fee rate (in satoshis per kilobyte) + * + * @operationId express.calculateminerfeeinfo + */ +export const PostCalculateMinerFeeInfo = httpRoute({ + path: '/api/v[12]/calculateminerfeeinfo', + method: 'POST', + request: httpRequest({ + body: CalculateMinerFeeInfoRequestBody, + }), + response: { + 200: CalculateMinerFeeInfoResponse, + 400: BitgoExpressError, + 404: BitgoExpressError, + }, +}); diff --git a/modules/express/src/typedRoutes/api/index.ts b/modules/express/src/typedRoutes/api/index.ts index 947c1225cc..b8b9028b99 100644 --- a/modules/express/src/typedRoutes/api/index.ts +++ b/modules/express/src/typedRoutes/api/index.ts @@ -8,6 +8,7 @@ import { PostLogin } from './common/login'; import { PostDecrypt } from './common/decrypt'; import { PostEncrypt } from './common/encrypt'; import { PostVerifyAddress } from './common/verifyAddress'; +import { PostCalculateMinerFeeInfo } from './common/calculateMinerFeeInfo'; import { PostAcceptShare } from './v1/acceptShare'; import { PostSimpleCreate } from './v1/simpleCreate'; import { PutPendingApproval } from './v1/pendingApproval'; @@ -52,6 +53,9 @@ export const ExpressApi = apiSpec({ 'express.verifycoinaddress': { post: PostVerifyCoinAddress, }, + 'express.calculateminerfeeinfo': { + post: PostCalculateMinerFeeInfo, + }, }); export type ExpressApi = typeof ExpressApi; diff --git a/modules/express/test/unit/typedRoutes/calculateMinerFeeInfo.ts b/modules/express/test/unit/typedRoutes/calculateMinerFeeInfo.ts new file mode 100644 index 0000000000..156dcb9aee --- /dev/null +++ b/modules/express/test/unit/typedRoutes/calculateMinerFeeInfo.ts @@ -0,0 +1,319 @@ +import * as assert from 'assert'; +import * as t from 'io-ts'; +import { + CalculateMinerFeeInfoRequestBody, + CalculateMinerFeeInfoResponse, + PostCalculateMinerFeeInfo, +} from '../../../src/typedRoutes/api/common/calculateMinerFeeInfo'; +import { assertDecode } from './common'; + +describe('CalculateMinerFeeInfo codec tests', function () { + describe('CalculateMinerFeeInfoRequestBody', function () { + it('should validate body with all required fields', function () { + const validBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + const decoded = assertDecode(t.type(CalculateMinerFeeInfoRequestBody), validBody); + assert.strictEqual(decoded.nP2shInputs, validBody.nP2shInputs); + assert.strictEqual(decoded.nP2pkhInputs, validBody.nP2pkhInputs); + assert.strictEqual(decoded.nP2shP2wshInputs, validBody.nP2shP2wshInputs); + assert.strictEqual(decoded.nOutputs, validBody.nOutputs); + assert.strictEqual(decoded.feeRate, undefined); // Optional field + assert.strictEqual(decoded.containsUncompressedPublicKeys, undefined); // Optional field + }); + + it('should validate body with all fields including optional ones', function () { + const validBody = { + feeRate: 10000, + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + containsUncompressedPublicKeys: true, + }; + + const decoded = assertDecode(t.type(CalculateMinerFeeInfoRequestBody), validBody); + assert.strictEqual(decoded.feeRate, validBody.feeRate); + assert.strictEqual(decoded.nP2shInputs, validBody.nP2shInputs); + assert.strictEqual(decoded.nP2pkhInputs, validBody.nP2pkhInputs); + assert.strictEqual(decoded.nP2shP2wshInputs, validBody.nP2shP2wshInputs); + assert.strictEqual(decoded.nOutputs, validBody.nOutputs); + assert.strictEqual(decoded.containsUncompressedPublicKeys, validBody.containsUncompressedPublicKeys); + }); + + it('should reject body with missing nP2shInputs', function () { + const invalidBody = { + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with missing nP2pkhInputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with missing nP2shP2wshInputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with missing nOutputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-number nP2shInputs', function () { + const invalidBody = { + nP2shInputs: '1', // string instead of number + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-number nP2pkhInputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: '0', // string instead of number + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-number nP2shP2wshInputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: '2', // string instead of number + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-number nOutputs', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: '2', // string instead of number + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-number feeRate', function () { + const invalidBody = { + feeRate: '10000', // string instead of number + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + + it('should reject body with non-boolean containsUncompressedPublicKeys', function () { + const invalidBody = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + containsUncompressedPublicKeys: 'true', // string instead of boolean + }; + + assert.throws(() => { + assertDecode(t.type(CalculateMinerFeeInfoRequestBody), invalidBody); + }); + }); + }); + + describe('CalculateMinerFeeInfoResponse', function () { + it('should validate response with all required fields', function () { + const validResponse = { + size: 374, + fee: 3740, + feeRate: 10000, + }; + + const decoded = assertDecode(CalculateMinerFeeInfoResponse, validResponse); + assert.strictEqual(decoded.size, validResponse.size); + assert.strictEqual(decoded.fee, validResponse.fee); + assert.strictEqual(decoded.feeRate, validResponse.feeRate); + }); + + it('should reject response with missing size', function () { + const invalidResponse = { + fee: 3740, + feeRate: 10000, + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + + it('should reject response with missing fee', function () { + const invalidResponse = { + size: 374, + feeRate: 10000, + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + + it('should reject response with missing feeRate', function () { + const invalidResponse = { + size: 374, + fee: 3740, + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + + it('should reject response with non-number size', function () { + const invalidResponse = { + size: '374', // string instead of number + fee: 3740, + feeRate: 10000, + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + + it('should reject response with non-number fee', function () { + const invalidResponse = { + size: 374, + fee: '3740', // string instead of number + feeRate: 10000, + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + + it('should reject response with non-number feeRate', function () { + const invalidResponse = { + size: 374, + fee: 3740, + feeRate: '10000', // string instead of number + }; + + assert.throws(() => { + assertDecode(CalculateMinerFeeInfoResponse, invalidResponse); + }); + }); + }); + + describe('Edge cases', function () { + it('should handle zero values for number fields', function () { + const body = { + feeRate: 0, + nP2shInputs: 0, + nP2pkhInputs: 0, + nP2shP2wshInputs: 0, + nOutputs: 0, + }; + + // This should throw because the implementation requires at least one nP2shInputs or nP2shP2wshInputs + // and at least one nOutputs, but the codec itself allows zero values + const decoded = assertDecode(t.type(CalculateMinerFeeInfoRequestBody), body); + assert.strictEqual(decoded.feeRate, 0); + assert.strictEqual(decoded.nP2shInputs, 0); + assert.strictEqual(decoded.nP2pkhInputs, 0); + assert.strictEqual(decoded.nP2shP2wshInputs, 0); + assert.strictEqual(decoded.nOutputs, 0); + }); + + it('should handle additional unknown properties', function () { + const body = { + nP2shInputs: 1, + nP2pkhInputs: 0, + nP2shP2wshInputs: 2, + nOutputs: 2, + unknownProperty: 'some value', + }; + + // io-ts with t.exact() strips out additional properties + const decoded = assertDecode(t.exact(t.type(CalculateMinerFeeInfoRequestBody)), body); + assert.strictEqual(decoded.nP2shInputs, body.nP2shInputs); + // @ts-expect-error - unknownProperty doesn't exist on the type + assert.strictEqual(decoded.unknownProperty, undefined); + }); + }); + + describe('PostCalculateMinerFeeInfo route definition', function () { + it('should have the correct path', function () { + assert.strictEqual(PostCalculateMinerFeeInfo.path, '/api/v[12]/calculateminerfeeinfo'); + }); + + it('should have the correct HTTP method', function () { + assert.strictEqual(PostCalculateMinerFeeInfo.method, 'POST'); + }); + + it('should have the correct request configuration', function () { + // Verify the route is configured with a request property + assert.ok(PostCalculateMinerFeeInfo.request); + }); + + it('should have the correct response types', function () { + // Check that the response object has the expected status codes + assert.ok(PostCalculateMinerFeeInfo.response[200]); + assert.ok(PostCalculateMinerFeeInfo.response[400]); + assert.ok(PostCalculateMinerFeeInfo.response[404]); + }); + }); +}); From b084bb492e2dca4d68be0300fff0df1cd2d04bb8 Mon Sep 17 00:00:00 2001 From: Venkat-Annavazzala Date: Tue, 23 Sep 2025 18:33:00 +0530 Subject: [PATCH 26/35] chore: update regex for raw trx hex validation TICKET: WIN-7341 --- modules/abstract-eth/src/lib/transactionBuilder.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/abstract-eth/src/lib/transactionBuilder.ts b/modules/abstract-eth/src/lib/transactionBuilder.ts index 064e7b7a09..85c284fb6c 100644 --- a/modules/abstract-eth/src/lib/transactionBuilder.ts +++ b/modules/abstract-eth/src/lib/transactionBuilder.ts @@ -49,6 +49,7 @@ import { Transaction } from './transaction'; import { TransferBuilder } from './transferBuilder'; const DEFAULT_M = 3; +const RAW_TX_HEX_REGEX = /^(0x)?[0-9a-f]{1,}$/; /** * EthereumLike transaction builder. @@ -165,7 +166,7 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { /** @inheritdoc */ protected fromImplementation(rawTransaction: string, isFirstSigner?: boolean): Transaction { let tx: Transaction; - if (/^0x?[0-9a-f]{1,}$/.test(rawTransaction.toLowerCase())) { + if (RAW_TX_HEX_REGEX.test(rawTransaction.toLowerCase())) { tx = Transaction.fromSerialized(this._coinConfig, this._common, rawTransaction, isFirstSigner); this.loadBuilderInput(tx.toJson(), isFirstSigner); } else { @@ -343,7 +344,7 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { throw new InvalidTransactionError('Raw transaction is empty'); } if (typeof rawTransaction === 'string') { - if (/^0x?[0-9a-f]{1,}$/.test(rawTransaction.toLowerCase())) { + if (RAW_TX_HEX_REGEX.test(rawTransaction.toLowerCase())) { const txBytes = ethUtil.toBuffer(ethUtil.addHexPrefix(rawTransaction.toLowerCase())); if (!this.isEip1559Txn(txBytes) && !this.isRLPDecodable(txBytes)) { throw new ParseTransactionError('There was error in decoding the hex string'); From e046c3924881da4a0244a9638e7493c7bfa3ec15 Mon Sep 17 00:00:00 2001 From: Ranjna Ganesh Ram Date: Wed, 24 Sep 2025 11:55:09 +0530 Subject: [PATCH 27/35] feat(sdk-coin-ada): token build support Ticket: WIN-7353 --- modules/sdk-coin-ada/src/lib/transaction.ts | 3 +- .../src/lib/transactionBuilder.ts | 306 +++++++++++++++++- .../sdk-coin-ada/test/unit/tokenWithdrawal.ts | 294 +++++++++++++++++ 3 files changed, 598 insertions(+), 5 deletions(-) create mode 100644 modules/sdk-coin-ada/test/unit/tokenWithdrawal.ts diff --git a/modules/sdk-coin-ada/src/lib/transaction.ts b/modules/sdk-coin-ada/src/lib/transaction.ts index 971a1b5f00..ab17ee801a 100644 --- a/modules/sdk-coin-ada/src/lib/transaction.ts +++ b/modules/sdk-coin-ada/src/lib/transaction.ts @@ -20,12 +20,13 @@ export interface Asset { policy_id: string; asset_name: string; quantity: string; + fingerprint?: string; } export interface TransactionOutput { address: string; amount: string; - multiAssets?: CardanoWasm.MultiAsset; + multiAssets?: CardanoWasm.MultiAsset | Asset; } export interface Witness { diff --git a/modules/sdk-coin-ada/src/lib/transactionBuilder.ts b/modules/sdk-coin-ada/src/lib/transactionBuilder.ts index 1764d75164..4c1cb657a4 100644 --- a/modules/sdk-coin-ada/src/lib/transactionBuilder.ts +++ b/modules/sdk-coin-ada/src/lib/transactionBuilder.ts @@ -16,6 +16,18 @@ import util, { MIN_ADA_FOR_ONE_ASSET } from './utils'; import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs'; import { BigNum } from '@emurgo/cardano-serialization-lib-nodejs'; +/** + * Constants for transaction building + */ +const FEE_COEFFICIENTS = { + /** Linear fee parameter a */ + A_COEFFICIENT: '44', + /** Linear fee parameter b */ + B_COEFFICIENT: '155381', + /** Additional safety margin for the fee */ + SAFETY_MARGIN: '440', +}; + export abstract class TransactionBuilder extends BaseTransactionBuilder { protected _transaction!: Transaction; protected _signers: KeyPair[] = []; @@ -30,7 +42,18 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { protected _withdrawals: Withdrawal[] = []; protected _type: TransactionType; protected _multiAssets: Asset[] = []; + /** Address of the transaction recipient */ + protected _recipientAddress: string; + /** Map of sender's assets by asset name */ + protected _senderAssetList: Record = {}; private _fee: BigNum; + /** Flag indicating if this is a token transaction */ + private _isTokenTransaction = false; + /** Deep clone of _senderAssetList - for manipulating during two iterations + * - one for calculating the fee + * - one for the actual transaction build with the calculated fee + * */ + private _mutableSenderAssetList: Record = {}; constructor(_coinConfig: Readonly) { super(_coinConfig); @@ -58,17 +81,38 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { return this; } - changeAddress(addr: string, totalInputBalance: string): this { + /** + * Sets the change address and input balances for the transaction + * @param addr - The address where change will be sent + * @param totalInputBalance - The total ADA input balance in Lovelace + * @param inputAssetList - Optional map of token assets in the input + */ + changeAddress(addr: string, totalInputBalance: string, inputAssetList?: Record): this { this._changeAddress = addr; this._senderBalance = totalInputBalance; + this._senderAssetList = inputAssetList ?? {}; + this.setMutableSenderAssetList(); return this; } + setMutableSenderAssetList() { + this._mutableSenderAssetList = JSON.parse(JSON.stringify(this._senderAssetList)); + } + fee(fee: string): this { this._fee = BigNum.from_str(fee); return this; } + /** + * Marks this transaction as a token transaction + * Enables special handling for token transfers + */ + isTokenTransaction() { + this._isTokenTransaction = true; + return this; + } + /** * Initialize the transaction builder fields using the decoded transaction data * @@ -132,8 +176,261 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { return this.transaction; } + /** + * Builds a transaction that includes token assets + * @returns The built transaction + */ + private processTokenBuild(): Transaction { + const inputs = CardanoWasm.TransactionInputs.new(); + let outputs = CardanoWasm.TransactionOutputs.new(); + this.addInputs(inputs); + // Fee is never set so far from IMS + if (this._fee.is_zero()) { + this.addOutputs(outputs); + const txDraft = this.prepareAdaTransactionDraft(inputs, outputs, false); + this.calculateFee(txDraft); + this.setFeeInTransaction(); + } + // Reset outputs to add them back with the correct change + outputs = CardanoWasm.TransactionOutputs.new(); + this.setMutableSenderAssetList(); + this.addOutputs(outputs); + this._transaction.transaction = this.prepareAdaTransactionDraft(inputs, outputs, true); + return this.transaction; + } + + /** + * Adds transaction inputs to the transaction + * @param inputs - The inputs collection to add to + */ + private addInputs(inputs) { + this._transactionInputs.forEach((input) => { + inputs.add( + CardanoWasm.TransactionInput.new( + CardanoWasm.TransactionHash.from_bytes(Buffer.from(input.transaction_id, 'hex')), + input.transaction_index + ) + ); + }); + } + + /** + * Adds outputs to the transaction including token outputs and change + * @param outputs - The outputs collection to add to + */ + private addOutputs(outputs) { + const utxoBalance = CardanoWasm.BigNum.from_str(this._senderBalance); // Total UTXO balance + const change = utxoBalance.checked_sub(this._fee); + const changeAfterReceiverDeductions = this.addReceiverOutputs(outputs, change); + this.addChangeOutput(changeAfterReceiverDeductions, outputs); + } + + /** + * Adds receiver outputs to the transaction and calculates the remaining change + * @param outputs - Transaction outputs collection + * @param change - Current change amount in ADA + * @returns Remaining change after adding receiver outputs + */ + private addReceiverOutputs(outputs, change) { + this._transactionOutputs.forEach((output) => { + if (!output.address) { + throw new BuildTransactionError('Invalid output: missing address'); + } + + const receiverAddress = output.address; + const receiverAmount = output.amount; + + try { + const receiverAmountBN = CardanoWasm.BigNum.from_str(receiverAmount); + change = change.checked_sub(receiverAmountBN); + + if (change.less_than(CardanoWasm.BigNum.zero())) { + throw new BuildTransactionError( + 'Insufficient funds: not enough ADA to cover receiver output amounts and fees' + ); + } + + const multiAssets = output.multiAssets as Asset; + if (multiAssets) { + const policyId = multiAssets.policy_id; + const assetName = multiAssets.asset_name; + const quantity = multiAssets.quantity; + const fingerprint = multiAssets.fingerprint as string; + + const currentQty = this._mutableSenderAssetList[fingerprint].quantity; + const remainingQty = BigInt(currentQty) - BigInt(quantity); + this._mutableSenderAssetList[fingerprint].quantity = (remainingQty > 0n ? remainingQty : 0n).toString(); + + if (CardanoWasm.BigNum.from_str(this._mutableSenderAssetList[fingerprint].quantity).is_zero()) { + throw new BuildTransactionError('Insufficient qty: not enough token qty to cover receiver output'); + } + + const minAmountNeededForAssetOutput = this.addTokensToOutput(change, outputs, receiverAddress, { + policy_id: policyId, + asset_name: assetName, + quantity, + fingerprint, + }); + + change = change.checked_sub(minAmountNeededForAssetOutput); + } + } catch (e) { + if (e instanceof BuildTransactionError) { + throw e; + } + throw new BuildTransactionError(`Error processing output: ${e.message}`); + } + }); + return change; + } + + /** + * Adds tokens to a transaction output + * @param change - The current change amount in Lovelace + * @param outputs - The outputs collection to add to + * @param address - The recipient address + * @param asset - The asset to add + * @returns The minimum ADA amount needed for this asset output + */ + private addTokensToOutput(change: BigNum, outputs: CardanoWasm.TransactionOutputs, address, asset: Asset): BigNum { + const minAmountNeededForOneAssetOutput = CardanoWasm.BigNum.from_str(MIN_ADA_FOR_ONE_ASSET); + if (change.less_than(minAmountNeededForOneAssetOutput)) { + throw new BuildTransactionError( + `Insufficient funds: need a minimum of ${MIN_ADA_FOR_ONE_ASSET} lovelace per output to construct token transactions` + ); + } + this.buildTokens(asset, minAmountNeededForOneAssetOutput, outputs, address); + return minAmountNeededForOneAssetOutput; + } + + /** + * Builds token outputs for a transaction + * @param asset - The asset to include in the output + * @param minAmountNeededForOneAssetOutput - Minimum ADA required for this asset output + * @param outputs - Transaction outputs collection + * @param address - Recipient address + */ + private buildTokens(asset: Asset, minAmountNeededForOneAssetOutput, outputs, address) { + let txOutputBuilder = CardanoWasm.TransactionOutputBuilder.new(); + const toAddress = util.getWalletAddress(address); + txOutputBuilder = txOutputBuilder.with_address(toAddress); + let txOutputAmountBuilder = txOutputBuilder.next(); + const assetName = CardanoWasm.AssetName.new(Buffer.from(asset.asset_name, 'hex')); + const policyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(asset.policy_id, 'hex')); + const multiAsset = CardanoWasm.MultiAsset.new(); + const assets = CardanoWasm.Assets.new(); + assets.insert(assetName, CardanoWasm.BigNum.from_str(asset.quantity)); + multiAsset.insert(policyId, assets); + + txOutputAmountBuilder = txOutputAmountBuilder.with_coin_and_asset(minAmountNeededForOneAssetOutput, multiAsset); + + const txOutput = txOutputAmountBuilder.build(); + outputs.add(txOutput); + } + + /** + * Adds a change output to the transaction + * @param change - The change amount in Lovelace + * @param outputs - The outputs collection to add to + */ + private addChangeOutput(change, outputs) { + const changeAddress = util.getWalletAddress(this._changeAddress); + Object.keys(this._mutableSenderAssetList).forEach((fingerprint) => { + const asset = this._mutableSenderAssetList[fingerprint]; + const changeQty = asset.quantity; + const policyId = asset.policy_id; + const assetName = asset.asset_name; + + if (CardanoWasm.BigNum.from_str(changeQty).is_zero()) { + return; + } + + const minAmountNeededForAssetOutput = this.addTokensToOutput(change, outputs, this._changeAddress, { + policy_id: policyId, + asset_name: assetName, + quantity: changeQty, + fingerprint, + }); + change = change.checked_sub(minAmountNeededForAssetOutput); + }); + if (!change.is_zero()) { + const changeOutput = CardanoWasm.TransactionOutput.new(changeAddress, CardanoWasm.Value.new(change)); + outputs.add(changeOutput); + } + } + + /** + * Sets the calculated fee in the transaction + */ + private setFeeInTransaction() { + this._transaction.fee(this._fee.to_str()); + } + + /** + * Calculates the transaction fee based on transaction size + * @param txDraft - Draft transaction to calculate fee for + */ + private calculateFee(txDraft) { + const linearFee = CardanoWasm.LinearFee.new( + CardanoWasm.BigNum.from_str(FEE_COEFFICIENTS.A_COEFFICIENT), + CardanoWasm.BigNum.from_str(FEE_COEFFICIENTS.B_COEFFICIENT) + ); + + // Calculate the fee based off our dummy transaction + const fee = CardanoWasm.min_fee(txDraft, linearFee).checked_add(BigNum.from_str(FEE_COEFFICIENTS.SAFETY_MARGIN)); + this._fee = fee; + } + + private prepareAdaTransactionDraft(inputs, outputs, refreshSignatures = false) { + const txBody = CardanoWasm.TransactionBody.new_tx_body(inputs, outputs, this._fee); + txBody.set_ttl(CardanoWasm.BigNum.from_str(this._ttl.toString())); + const txHash = CardanoWasm.hash_transaction(txBody); + + // we add witnesses once so that we can get the appropriate amount of signers for calculating the fee + const witnessSet = CardanoWasm.TransactionWitnessSet.new(); + const vkeyWitnesses = CardanoWasm.Vkeywitnesses.new(); + this._signers.forEach((keyPair) => { + const prv = keyPair.getKeys().prv as string; + const vkeyWitness = CardanoWasm.make_vkey_witness( + txHash, + CardanoWasm.PrivateKey.from_normal_bytes(Buffer.from(prv, 'hex')) + ); + vkeyWitnesses.add(vkeyWitness); + }); + if (refreshSignatures) { + this._transaction.signature.length = 0; + } + this.getAllSignatures().forEach((signature) => { + const vkey = CardanoWasm.Vkey.new(CardanoWasm.PublicKey.from_bytes(Buffer.from(signature.publicKey.pub, 'hex'))); + const ed255Sig = CardanoWasm.Ed25519Signature.from_bytes(signature.signature); + vkeyWitnesses.add(CardanoWasm.Vkeywitness.new(vkey, ed255Sig)); + }); + if (vkeyWitnesses.len() === 0) { + const prv = CardanoWasm.PrivateKey.generate_ed25519(); + const vkeyWitness = CardanoWasm.make_vkey_witness(txHash, prv); + vkeyWitnesses.add(vkeyWitness); + if (this._type !== TransactionType.Send) { + vkeyWitnesses.add(vkeyWitness); + } + } + witnessSet.set_vkeys(vkeyWitnesses); + + // add in certificates to get mock size + const draftCerts = CardanoWasm.Certificates.new(); + for (const cert of this._certs) { + draftCerts.add(cert); + } + txBody.set_certs(draftCerts); + + const txDraft = CardanoWasm.Transaction.new(txBody, witnessSet); + return txDraft; + } + /** @inheritdoc */ protected async buildImplementation(): Promise { + if (this._isTokenTransaction) { + return this.processTokenBuild(); + } const inputs = CardanoWasm.TransactionInputs.new(); this._transactionInputs.forEach((input) => { inputs.add( @@ -291,9 +588,10 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { // reset the outputs collection because now our last output has changed outputs = CardanoWasm.TransactionOutputs.new(); this._transactionOutputs.forEach((output) => { - if (output.multiAssets) { - const policyId = output.multiAssets.keys().get(0); - const assets = output.multiAssets.get(policyId); + const multiAssets = output.multiAssets as CardanoWasm.MultiAsset; + if (multiAssets) { + const policyId = multiAssets.keys().get(0); + const assets = multiAssets.get(policyId); const assetName = assets!.keys().get(0); const quantity = assets!.get(assetName); let txOutputBuilder = CardanoWasm.TransactionOutputBuilder.new(); diff --git a/modules/sdk-coin-ada/test/unit/tokenWithdrawal.ts b/modules/sdk-coin-ada/test/unit/tokenWithdrawal.ts new file mode 100644 index 0000000000..9755bb1965 --- /dev/null +++ b/modules/sdk-coin-ada/test/unit/tokenWithdrawal.ts @@ -0,0 +1,294 @@ +import should from 'should'; +import { TransactionType } from '@bitgo/sdk-core'; +import * as testData from '../resources'; +import { TransactionBuilderFactory } from '../../src'; +import { coins } from '@bitgo/statics'; +import * as CardanoWasm from '@emurgo/cardano-serialization-lib-nodejs'; +import { Transaction } from '../../src/lib/transaction'; + +describe('ADA Token Operations', async () => { + const factory = new TransactionBuilderFactory(coins.get('tada')); + + const receiverAddress = testData.rawTx.outputAddress2.address; + const senderAddress = testData.rawTx.outputAddress1.address; + + const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72'; + const policyScriptHash = CardanoWasm.ScriptHash.from_hex(policyId); + const assetName = 'tada:water'; + const name = 'WATER'; + const asciiEncodedName = Buffer.from(name, 'ascii').toString('hex'); + const fingerprint = 'asset1n69xf60d0760xvn8v2ffd5frvsm0cl2r8hfjf6'; + + const unsupportedPolicyId = '279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f'; + const unsupportedPolicyScriptHash = CardanoWasm.ScriptHash.from_hex(unsupportedPolicyId); + const unsupportedName = 'BITGO'; + const unsupportedAsciiEncodedName = Buffer.from(unsupportedName, 'ascii').toString('hex'); + const unsupportedFingerprint = 'asset1m8h0gk7f6x5j5qg0x5m4q5f5j5qg0x5m4q5f5j'; + + it(`should build a transaction with token ${assetName} - ada + ${assetName}`, async () => { + const quantity = '20'; + const totalInput = 20000000; + const totalAssetList = { + [fingerprint]: { + quantity: '100', + policy_id: policyId, + asset_name: asciiEncodedName, + }, + }; + const expectedChangeAda = ( + totalInput - + 1500000 /* min ada for change token utxo */ - + 1500000 /* min ada for recipient token utxo*/ - + 173597 + ) /* fee */ + .toString(); + const expectedChangeToken = '80'; + + const txBuilder = factory.getTransferBuilder(); + txBuilder.input({ + transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21', + transaction_index: 1, + }); + + txBuilder.output({ + address: receiverAddress, + amount: '0', // Set ADA amount to 0 for token transfer (min ADA is handled in sdk build) + multiAssets: { + asset_name: asciiEncodedName, + policy_id: policyId, + quantity, + fingerprint, + }, + }); + + txBuilder.changeAddress(senderAddress, totalInput.toString(), totalAssetList); + txBuilder.ttl(800000000); + txBuilder.isTokenTransaction(); + const tx = (await txBuilder.build()) as Transaction; + + should.equal(tx.type, TransactionType.Send); + const txData = tx.toJson(); + + // Check outputs (should include multi-asset and regular change) + txData.outputs.length.should.equal(3); + txData.inputs.length.should.equal(1); + + // One output should have the multi-asset change and the other for the transfer + const assetOutput = txData.outputs.filter((output) => output.multiAssets !== undefined); + assetOutput!.length.should.equal(2); + + // Verify inputs and outputs + const input = txData.inputs[0]; + input.transaction_id.should.equal('3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21'); + input.transaction_index.should.equal(1); + + // Validate receiver output + const receiverOutput = txData.outputs.filter((output) => output.address === receiverAddress); + receiverOutput.length.should.equal(1); + receiverOutput[0].amount.should.equal('1500000'); // Minimum ADA for asset output + (receiverOutput[0].multiAssets! as CardanoWasm.MultiAsset) + .get_asset(policyScriptHash, CardanoWasm.AssetName.new(Buffer.from(asciiEncodedName, 'hex'))) + .to_str() + .should.equal(quantity); + + // Validate change outputs (one with asset and one without) + const changeOutput = txData.outputs.filter((output) => output.address === senderAddress); + changeOutput.length.should.equal(2); + const changeWithAsset = changeOutput.find((output) => output.multiAssets !== undefined); + should.exist(changeWithAsset); + changeWithAsset!.amount.should.equal('1500000'); // Minimum ADA for asset output + (changeWithAsset!.multiAssets! as CardanoWasm.MultiAsset) + .get_asset(policyScriptHash, CardanoWasm.AssetName.new(Buffer.from(asciiEncodedName, 'hex'))) + .to_str() + .should.equal(expectedChangeToken); + + const changeWithoutAsset = changeOutput.find((output) => output.multiAssets === undefined); + should.exist(changeWithoutAsset); + changeWithoutAsset!.amount.should.equal(expectedChangeAda); // Remaining ADA after fees and min ADAs + }); + + it(`should build a transaction with token ${assetName} - ada + ${assetName} + unsupported token`, async () => { + const quantity = '20'; + const totalInput = 20000000; + const totalAssetList = { + [fingerprint]: { + quantity: '100', + policy_id: policyId, + asset_name: asciiEncodedName, + }, + [unsupportedFingerprint]: { + quantity: '10000', + policy_id: unsupportedPolicyId, + asset_name: unsupportedAsciiEncodedName, + }, + }; + const expectedChangeAda = ( + totalInput - + 1500000 /* min ada for change token utxo */ - + 1500000 /* min ada for recipient token utxo*/ - + 1500000 /* min ada for unsupported token change utxo */ - + 179889 + ) /* fee */ + .toString(); + const expectedChangeToken = '80'; + + const txBuilder = factory.getTransferBuilder(); + txBuilder.input({ + transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21', + transaction_index: 1, + }); + txBuilder.input({ + transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba22', + transaction_index: 1, + }); + + txBuilder.output({ + address: receiverAddress, + amount: '0', // Set ADA amount to 0 for token transfer (min ADA is handled in sdk build) + multiAssets: { + asset_name: asciiEncodedName, + policy_id: policyId, + quantity, + fingerprint, + }, + }); + + txBuilder.changeAddress(senderAddress, totalInput.toString(), totalAssetList); + txBuilder.ttl(800000000); + txBuilder.isTokenTransaction(); + const tx = (await txBuilder.build()) as Transaction; + + should.equal(tx.type, TransactionType.Send); + const txData = tx.toJson(); + + // Check outputs (should include multi-asset and regular change) + txData.outputs.length.should.equal(4); + txData.inputs.length.should.equal(2); + + // One output should have the multi-asset change and the other for the transfer + const assetOutput = txData.outputs.filter((output) => output.multiAssets !== undefined); + assetOutput!.length.should.equal(3); + + // Verify inputs and outputs + txData.inputs[0].transaction_id.should.equal('3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21'); + txData.inputs[0].transaction_index.should.equal(1); + + txData.inputs[1].transaction_id.should.equal('3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba22'); + txData.inputs[1].transaction_index.should.equal(1); + + // Validate receiver output + const receiverOutput = txData.outputs.filter((output) => output.address === receiverAddress); + receiverOutput.length.should.equal(1); + receiverOutput[0].amount.should.equal('1500000'); // Minimum ADA for asset output + (receiverOutput[0].multiAssets! as CardanoWasm.MultiAsset) + .get_asset(policyScriptHash, CardanoWasm.AssetName.new(Buffer.from(asciiEncodedName, 'hex'))) + .to_str() + .should.equal(quantity); + + // Validate change outputs (one with supported token, one with unsupported token and one for pure ada) + const changeOutput = txData.outputs.filter((output) => output.address === senderAddress); + changeOutput.length.should.equal(3); + + const changeWithAsset = changeOutput.filter((output) => output.multiAssets !== undefined); + changeWithAsset.length.should.equal(2); + let tokens = 0; + changeWithAsset.forEach((output) => { + output!.amount.should.equal('1500000'); // Minimum ADA for asset output + const supportedTokenChangeQty = (output!.multiAssets! as CardanoWasm.MultiAsset) + .get_asset(policyScriptHash, CardanoWasm.AssetName.new(Buffer.from(asciiEncodedName, 'hex'))) + .to_str(); + const unsupportedTokenChangeQty = (output!.multiAssets! as CardanoWasm.MultiAsset) + .get_asset( + unsupportedPolicyScriptHash, + CardanoWasm.AssetName.new(Buffer.from(unsupportedAsciiEncodedName, 'hex')) + ) + .to_str(); + if (supportedTokenChangeQty !== '0') { + supportedTokenChangeQty.should.equal(expectedChangeToken); + tokens++; + } else { + unsupportedTokenChangeQty!.should.equal('10000'); + tokens++; + } + }); + tokens.should.equal(2); + + const changeWithoutAsset = changeOutput.find((output) => output.multiAssets === undefined); + should.exist(changeWithoutAsset); + changeWithoutAsset!.amount.should.equal(expectedChangeAda); // Remaining ADA after fees and min ADAs + }); + + it(`should fail to build a transaction with ${assetName} token and insufficient minimum ADA`, async () => { + const quantity = '20'; + const totalInput = 2000000; + const totalAssetList = { + [fingerprint]: { + quantity: '100', + policy_id: policyId, + asset_name: asciiEncodedName, + }, + }; + + const txBuilder = factory.getTransferBuilder(); + txBuilder.input({ + transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21', + transaction_index: 1, + }); + + txBuilder.output({ + address: receiverAddress, + amount: '0', // Set ADA amount to 0 for token transfer (min ADA is handled in sdk build) + multiAssets: { + asset_name: asciiEncodedName, + policy_id: policyId, + quantity, + fingerprint, + }, + }); + + txBuilder.changeAddress(senderAddress, totalInput.toString(), totalAssetList); + txBuilder.ttl(800000000); + txBuilder.isTokenTransaction(); + + await txBuilder + .build() + .should.rejectedWith( + 'Insufficient funds: need a minimum of 1500000 lovelace per output to construct token transactions' + ); + }); + + it(`should fail to build a transaction with ${assetName} and insufficient token qty`, async () => { + const quantity = '20'; + const totalInput = 20000000; + const totalAssetList = { + [fingerprint]: { + quantity: '5', + policy_id: policyId, + asset_name: asciiEncodedName, + }, + }; + + const txBuilder = factory.getTransferBuilder(); + txBuilder.input({ + transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21', + transaction_index: 1, + }); + + txBuilder.output({ + address: receiverAddress, + amount: '0', // Set ADA amount to 0 for token transfer (min ADA is handled in sdk build) + multiAssets: { + asset_name: asciiEncodedName, + policy_id: policyId, + quantity, + fingerprint, + }, + }); + + txBuilder.changeAddress(senderAddress, totalInput.toString(), totalAssetList); + txBuilder.ttl(800000000); + txBuilder.isTokenTransaction(); + + await txBuilder.build().should.rejectedWith('Insufficient qty: not enough token qty to cover receiver output'); + }); +}); From bb7e27aabfed5930ea7b5156afe465b92e41043c Mon Sep 17 00:00:00 2001 From: Chinmay Sharma Date: Wed, 24 Sep 2025 12:52:19 +0530 Subject: [PATCH 28/35] feat(statics): onboard new bsc token Ticket: COIN-5732 TICKET: COIN-5732 --- modules/statics/src/base.ts | 1 + modules/statics/src/coins/bscTokens.ts | 9 +++++++++ modules/statics/src/coins/ofcCoins.ts | 1 + 3 files changed, 11 insertions(+) diff --git a/modules/statics/src/base.ts b/modules/statics/src/base.ts index 5d265f3c18..07122b0030 100644 --- a/modules/statics/src/base.ts +++ b/modules/statics/src/base.ts @@ -2674,6 +2674,7 @@ export enum UnderlyingAsset { 'bsc:eden' = 'bsc:eden', 'bsc:m' = 'bsc:m', 'bsc:cashplus' = 'bsc:cashplus', + 'bsc:aster' = 'bsc:aster', // BSC NFTs // generic NFTs diff --git a/modules/statics/src/coins/bscTokens.ts b/modules/statics/src/coins/bscTokens.ts index e7327e6c04..d6847dba93 100644 --- a/modules/statics/src/coins/bscTokens.ts +++ b/modules/statics/src/coins/bscTokens.ts @@ -1392,4 +1392,13 @@ export const bscTokens = [ UnderlyingAsset['bsc:cashplus'], BSC_TOKEN_FEATURES ), + bscToken( + '9f5765c8-1bfa-4dca-b239-0ac0ba38147d', + 'bsc:aster', + 'Aster', + 18, + '0x000ae314e2a2172a039b26378814c252734f556a', + UnderlyingAsset['bsc:aster'], + BSC_TOKEN_FEATURES + ), ]; diff --git a/modules/statics/src/coins/ofcCoins.ts b/modules/statics/src/coins/ofcCoins.ts index ba968729e1..e842898800 100644 --- a/modules/statics/src/coins/ofcCoins.ts +++ b/modules/statics/src/coins/ofcCoins.ts @@ -2233,6 +2233,7 @@ export const ofcCoins = [ 18, UnderlyingAsset['bsc:cashplus'] ), + ofcBscToken('08974cb2-8081-4248-89d5-c74af0edf4bb', 'ofcbsc:aster', 'Aster', 18, UnderlyingAsset['bsc:aster']), tofcBscToken( 'e9174338-0d26-4f49-b111-3487b60c9912', From 64e3b38068b65ec6011cfc20e72bbdae8ce81ad1 Mon Sep 17 00:00:00 2001 From: Zeeshan Amjad Date: Wed, 24 Sep 2025 16:00:50 +0530 Subject: [PATCH 29/35] feat: replace asset id with fungible asset address Ticket: TMS-1274 TICKET: TMS-1274 --- modules/statics/src/allCoinsAndTokens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index 95ec650692..00ab33b4f6 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -4490,7 +4490,7 @@ export const allCoinsAndTokens = [ 'tapt:stgusd1', 'Test USD1 Token', 6, - '0x2356ad3e22c235a200a5df08282a65c42c2aafb0d8ec5b878a7192c5a2ba432a', + '0xa291072c398d4224abc2f4898ace15cc61a949a093c69e757d6fc8efcb62802b', UnderlyingAsset['tapt:stgusd1'], [...APT_FEATURES, CoinFeature.STABLECOIN] ), From ddcf0ee49478f747e81c69a8c2a17e672b9f1e0f Mon Sep 17 00:00:00 2001 From: Rohit Saw Date: Wed, 24 Sep 2025 18:32:28 +0530 Subject: [PATCH 30/35] chore: adding evm_compatible_ims feature to tstt ticket: win-7359 --- modules/statics/src/allCoinsAndTokens.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index 3a6d0ff50b..42058b0ef0 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -1830,7 +1830,7 @@ export const allCoinsAndTokens = [ 18, UnderlyingAsset.STT, BaseUnit.ETH, - [...EVM_FEATURES, CoinFeature.SHARED_EVM_SIGNING, CoinFeature.STAKING] + [...EVM_FEATURES, CoinFeature.SHARED_EVM_SIGNING, CoinFeature.STAKING, CoinFeature.EVM_COMPATIBLE_IMS] ), account( 'aaa25f54-24f8-41d9-ba4e-83465d7cc2ec', From 79c95cebaf0efef301198072c0dea201b01866f4 Mon Sep 17 00:00:00 2001 From: Sachu Shaji Abraham Date: Wed, 24 Sep 2025 20:34:39 +0530 Subject: [PATCH 31/35] feat: replace apt usd1 asset id with FA address BREAKING CHANGE: FA address gets indexed for transfers instead of move module address TICKET: TMS-1274 --- modules/statics/src/allCoinsAndTokens.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/statics/src/allCoinsAndTokens.ts b/modules/statics/src/allCoinsAndTokens.ts index 3a6d0ff50b..55319142f6 100644 --- a/modules/statics/src/allCoinsAndTokens.ts +++ b/modules/statics/src/allCoinsAndTokens.ts @@ -4683,7 +4683,7 @@ export const allCoinsAndTokens = [ 'apt:usd1', 'USD1', 6, - '0x6febdb5695dab42c3edf6baaebf7b49b4ae32fbb1411a5c33917f442ebe77daa', + '0x05fabd1b12e39967a3c24e91b7b8f67719a6dacee74f3c8b9fb7d93e855437d2', UnderlyingAsset['apt:usd1'], [...APT_FEATURES, CoinFeature.STABLECOIN] ), @@ -4755,7 +4755,7 @@ export const allCoinsAndTokens = [ 'tapt:usd1', 'Test USD1 Token', 6, - '0xc52f239bb28211c0340882b83cbc20f7a0e5bf31608f1ca46c2f4a5c6a856683', + '0x5b31c15a79ae79dfcaac6a591012f2dd83888e741c5a288ad1659f56097afe2a', UnderlyingAsset['tapt:usd1'], [...APT_FEATURES, CoinFeature.STABLECOIN] ), From 4381d1131c1037c25f39b1ad94296616a0a7ee1a Mon Sep 17 00:00:00 2001 From: danielzhao122 Date: Wed, 24 Sep 2025 15:32:24 -0400 Subject: [PATCH 32/35] feat(express): migrate signpayload to typed routes TICKET: WP-5443 --- modules/express/src/clientRoutes.ts | 23 +++------- modules/express/src/typedRoutes/api/index.ts | 4 ++ .../src/typedRoutes/api/v2/ofcSignPayload.ts | 43 +++++++++++++++++++ .../test/unit/clientRoutes/signPayload.ts | 14 ++++-- .../express/test/unit/typedRoutes/decode.ts | 33 ++++++++++++++ 5 files changed, 97 insertions(+), 20 deletions(-) create mode 100644 modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts diff --git a/modules/express/src/clientRoutes.ts b/modules/express/src/clientRoutes.ts index e8ce03422d..a45bf20d33 100755 --- a/modules/express/src/clientRoutes.ts +++ b/modules/express/src/clientRoutes.ts @@ -62,7 +62,6 @@ import { handleLightningWithdraw } from './lightning/lightningWithdrawRoutes'; import createExpressRouter from './typedRoutes'; import { ExpressApiRouteRequest } from './typedRoutes/api'; import { TypedRequestHandler, WrappedRequest, WrappedResponse } from '@api-ts/typed-express-router'; -import { isJsonString } from './utils'; const { version } = require('bitgo/package.json'); const pjson = require('../package.json'); @@ -590,10 +589,10 @@ export async function handleV2OFCSignPayloadInExtSigningMode( } } -export async function handleV2OFCSignPayload(req: express.Request): Promise<{ payload: string; signature: string }> { - const walletId = req.body.walletId; - const payload = req.body.payload; - const bodyWalletPassphrase = req.body.walletPassphrase; +export async function handleV2OFCSignPayload( + req: ExpressApiRouteRequest<'express.ofc.signPayload', 'post'> +): Promise<{ payload: string; signature: string }> { + const { walletId, payload, walletPassphrase: bodyWalletPassphrase } = req.decoded; const ofcCoinName = 'ofc'; // If the externalSignerUrl is set, forward the request to the express server hosted on the externalSignerUrl @@ -612,14 +611,6 @@ export async function handleV2OFCSignPayload(req: express.Request): Promise<{ pa return payloadWithSignature; } - if (!payload) { - throw new ApiResponseError('Missing required field: payload', 400); - } - - if (!walletId) { - throw new ApiResponseError('Missing required field: walletId', 400); - } - const bitgo = req.bitgo; // This is to set us up for multiple trading accounts per enterprise @@ -631,7 +622,7 @@ export async function handleV2OFCSignPayload(req: express.Request): Promise<{ pa const walletPassphrase = bodyWalletPassphrase || getWalletPwFromEnv(wallet.id()); const tradingAccount = wallet.toTradingAccount(); - const stringifiedPayload = isJsonString(req.body.payload) ? req.body.payload : JSON.stringify(req.body.payload); + const stringifiedPayload = JSON.stringify(payload); const signature = await tradingAccount.signPayload({ payload: stringifiedPayload, walletPassphrase, @@ -1559,6 +1550,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { router.post('express.decrypt', [prepareBitGo(config), typedPromiseWrapper(handleDecrypt)]); router.post('express.encrypt', [prepareBitGo(config), typedPromiseWrapper(handleEncrypt)]); router.post('express.verifyaddress', [prepareBitGo(config), typedPromiseWrapper(handleVerifyAddress)]); + router.post('express.ofc.signPayload', [prepareBitGo(config), typedPromiseWrapper(handleV2OFCSignPayload)]); router.post('express.lightning.initWallet', [prepareBitGo(config), typedPromiseWrapper(handleInitLightningWallet)]); router.post('express.calculateminerfeeinfo', [ prepareBitGo(config), @@ -1636,9 +1628,6 @@ export function setupAPIRoutes(app: express.Application, config: Config): void { promiseWrapper(handleV2AcceptWalletShare) ); - // sign arbitrary payloads w/ trading account key - app.post(`/api/v2/ofc/signPayload`, parseBody, prepareBitGo(config), promiseWrapper(handleV2OFCSignPayload)); - // sign transaction app.post('/api/v2/:coin/signtx', parseBody, prepareBitGo(config), promiseWrapper(handleV2SignTx)); app.post('/api/v2/:coin/wallet/:id/signtx', parseBody, prepareBitGo(config), promiseWrapper(handleV2SignTxWallet)); diff --git a/modules/express/src/typedRoutes/api/index.ts b/modules/express/src/typedRoutes/api/index.ts index d9791f9332..4e6230646b 100644 --- a/modules/express/src/typedRoutes/api/index.ts +++ b/modules/express/src/typedRoutes/api/index.ts @@ -16,6 +16,7 @@ import { PostSignTransaction } from './v1/signTransaction'; import { PostKeychainLocal } from './v2/keychainLocal'; import { PostLightningInitWallet } from './v2/lightningInitWallet'; import { PostVerifyCoinAddress } from './v2/verifyAddress'; +import { PostOfcSignPayload } from './v2/ofcSignPayload'; export const ExpressApi = apiSpec({ 'express.ping': { @@ -60,6 +61,9 @@ export const ExpressApi = apiSpec({ 'express.calculateminerfeeinfo': { post: PostCalculateMinerFeeInfo, }, + 'express.ofc.signPayload': { + post: PostOfcSignPayload, + }, }); export type ExpressApi = typeof ExpressApi; diff --git a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts new file mode 100644 index 0000000000..2d075a8ad8 --- /dev/null +++ b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts @@ -0,0 +1,43 @@ +import * as t from 'io-ts'; +import { Json, NonEmptyString, JsonFromString } from 'io-ts-types'; +import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; +import { BitgoExpressError } from '../../schemas/error'; + +/** + * Sign an arbitrary payload using an OFC trading account key. + */ +export const OfcSignPayloadBody = { + /** The ID of the OFC wallet to sign the payload with. */ + walletId: NonEmptyString, + /** The payload to sign. */ + payload: t.union([Json, t.string.pipe(JsonFromString)]), + /** The passphrase to decrypt the user key. */ + walletPassphrase: optional(t.string), +}; + +export const OfcSignPayloadResponse200 = t.type({ + payload: t.string, + signature: t.string, +}); + +/** + * Response for signing an arbitrary payload with an OFC wallet key. + */ +export const OfcSignPayloadResponse = { + /** Signed payload and signature */ + 200: OfcSignPayloadResponse200, + /** BitGo Express error payload. */ + 400: BitgoExpressError, +} as const; + +/** + * Request body for signing an arbitrary payload with an OFC wallet key. + * + * @operationId express.ofc.signPayload + */ +export const PostOfcSignPayload = httpRoute({ + path: '/api/v2/ofc/signPayload', + method: 'POST', + request: httpRequest({ body: OfcSignPayloadBody }), + response: OfcSignPayloadResponse, +}); diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index 67a997f518..351ee4a8da 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -5,9 +5,9 @@ import 'should'; import * as fs from 'fs'; import { Request } from 'express'; import { BitGo, Coin, BaseCoin, Wallet, Wallets } from 'bitgo'; - import '../../lib/asserts'; import { handleV2OFCSignPayload, handleV2OFCSignPayloadInExtSigningMode } from '../../../src/clientRoutes'; +import { ExpressApiRouteRequest } from '../../../src/typedRoutes/api'; describe('Sign an arbitrary payload with trading account key', function () { const coin = 'ofc'; @@ -53,8 +53,12 @@ describe('Sign an arbitrary payload with trading account key', function () { payload, walletId, }, + decoded: { + payload, + walletId, + }, query: {}, - } as unknown as Request; + } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); }); it('should return a signed payload with type as json string', async function () { @@ -68,8 +72,12 @@ describe('Sign an arbitrary payload with trading account key', function () { payload: stringifiedPayload, walletId, }, + decoded: { + payload, + walletId, + }, query: {}, - } as unknown as Request; + } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); }); }); diff --git a/modules/express/test/unit/typedRoutes/decode.ts b/modules/express/test/unit/typedRoutes/decode.ts index ccbf4ea02d..61a611bb9e 100644 --- a/modules/express/test/unit/typedRoutes/decode.ts +++ b/modules/express/test/unit/typedRoutes/decode.ts @@ -11,6 +11,7 @@ import { LightningInitWalletBody, LightningInitWalletParams, } from '../../../src/typedRoutes/api/v2/lightningInitWallet'; +import { OfcSignPayloadBody } from '../../../src/typedRoutes/api/v2/ofcSignPayload'; export function assertDecode(codec: t.Type, input: unknown): T { const result = codec.decode(input); @@ -126,6 +127,38 @@ describe('io-ts decode tests', function () { supportOldScriptHashVersion: true, }); }); + it('express.ofc.signPayload', function () { + // missing walletId + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + payload: { a: 1 }, + }) + ); + // empty walletId + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + walletId: '', + payload: { a: 1 }, + }) + ); + // missing payload + assert.throws(() => + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + }) + ); + // valid minimal + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + payload: { a: 1 }, + }); + // valid with nested and optional passphrase + assertDecode(t.type(OfcSignPayloadBody), { + walletId: 'w1', + payload: { nested: ['x', { y: true }] }, + walletPassphrase: 'secret', + }); + }); it('express.v1.wallet.simplecreate', function () { // passphrase is required assert.throws(() => assertDecode(t.type(SimpleCreateRequestBody), {})); From e58102796ea791c21bfc1ad84ed4ff289d3f08f3 Mon Sep 17 00:00:00 2001 From: danielzhao122 Date: Wed, 24 Sep 2025 15:42:19 -0400 Subject: [PATCH 33/35] refactor: code Added UT to test/unit/clientRoutes/signPayload.tsAlso it seems like this migration makes the UT for `Sign an arbitrary payload with trading account key` (ticket: https://bitgoinc.atlassian.net/browse/GO-1015) to pass. TICKET: WP-5443 --- .../test/unit/clientRoutes/signPayload.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index 351ee4a8da..ab11552018 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -8,6 +8,7 @@ import { BitGo, Coin, BaseCoin, Wallet, Wallets } from 'bitgo'; import '../../lib/asserts'; import { handleV2OFCSignPayload, handleV2OFCSignPayloadInExtSigningMode } from '../../../src/clientRoutes'; import { ExpressApiRouteRequest } from '../../../src/typedRoutes/api'; +import { OfcSignPayloadResponse } from '../../../src/typedRoutes/api/v2/ofcSignPayload'; describe('Sign an arbitrary payload with trading account key', function () { const coin = 'ofc'; @@ -23,7 +24,7 @@ describe('Sign an arbitrary payload with trading account key', function () { const walletId = 'myWalletId'; const walletStub = sinon.createStubInstance(Wallet as any, { - id: walletId, + id: sinon.stub().returns(walletId), coin: sinon.stub().returns(coin), toTradingAccount: sinon.stub().returns({ signPayload: sinon.stub().returns(signature), @@ -49,13 +50,9 @@ describe('Sign an arbitrary payload with trading account key', function () { }; const req = { bitgo: bitGoStub, - body: { - payload, - walletId, - }, decoded: { - payload, walletId, + payload, }, query: {}, } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; @@ -80,6 +77,23 @@ describe('Sign an arbitrary payload with trading account key', function () { } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); }); + + it('should decode handler response with OfcSignPayloadResponse codec', async function () { + const expected = { + payload: JSON.stringify(payload), + signature, + }; + const req = { + bitgo: bitGoStub, + decoded: { + walletId, + payload, + }, + } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; + const result = await handleV2OFCSignPayload(req); + result.should.eql(expected); + OfcSignPayloadResponse[200].is(result).should.be.true(); + }); }); describe('With the handler to sign an arbitrary payload in external signing mode', () => { From 100f88fbcd535cee468d9cd5fed828a04a7b5578 Mon Sep 17 00:00:00 2001 From: Daniel Zhao Date: Wed, 10 Sep 2025 18:08:17 -0400 Subject: [PATCH 34/35] refactor: added dependency io-ts-type to package.json TICKET: WP-5443 --- modules/express/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/express/package.json b/modules/express/package.json index 7589dc0444..a39b0f0359 100644 --- a/modules/express/package.json +++ b/modules/express/package.json @@ -51,6 +51,7 @@ "dotenv": "^16.0.0", "express": "4.21.2", "io-ts": "npm:@bitgo-forks/io-ts@2.1.4", + "io-ts-types": "^0.5.19", "lodash": "^4.17.20", "morgan": "^1.9.1", "proxy-agent": "6.4.0", From 936f87b4a63c308f45be34ff8436cb51c55e9137 Mon Sep 17 00:00:00 2001 From: danielzhao122 Date: Wed, 24 Sep 2025 15:48:47 -0400 Subject: [PATCH 35/35] refactor: added decoding to unit tests and addressed missing jsdocs TICKET: WP-5443 --- .../src/typedRoutes/api/v2/ofcSignPayload.ts | 2 ++ .../express/test/unit/clientRoutes/signPayload.ts | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts index 2d075a8ad8..32eaa5a6da 100644 --- a/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts +++ b/modules/express/src/typedRoutes/api/v2/ofcSignPayload.ts @@ -16,7 +16,9 @@ export const OfcSignPayloadBody = { }; export const OfcSignPayloadResponse200 = t.type({ + /** The canonical string form of the JSON payload that was signed. */ payload: t.string, + /** Hex-encoded signature generated by the trading account key. */ signature: t.string, }); diff --git a/modules/express/test/unit/clientRoutes/signPayload.ts b/modules/express/test/unit/clientRoutes/signPayload.ts index ab11552018..12538a11b2 100644 --- a/modules/express/test/unit/clientRoutes/signPayload.ts +++ b/modules/express/test/unit/clientRoutes/signPayload.ts @@ -4,7 +4,8 @@ import 'should-sinon'; import 'should'; import * as fs from 'fs'; import { Request } from 'express'; -import { BitGo, Coin, BaseCoin, Wallet, Wallets } from 'bitgo'; +import { BitGo, Coin, BaseCoin, Wallet, Wallets, decodeOrElse } from 'bitgo'; + import '../../lib/asserts'; import { handleV2OFCSignPayload, handleV2OFCSignPayloadInExtSigningMode } from '../../../src/clientRoutes'; import { ExpressApiRouteRequest } from '../../../src/typedRoutes/api'; @@ -75,7 +76,12 @@ describe('Sign an arbitrary payload with trading account key', function () { }, query: {}, } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; - await handleV2OFCSignPayload(req).should.be.resolvedWith(expectedResponse); + + const res = await handleV2OFCSignPayload(req); + decodeOrElse('OfcSignPayloadResponse200', OfcSignPayloadResponse[200], res, (_) => { + throw new Error(`Response did not match expected codec`); + }); + res.should.deepEqual(expectedResponse); }); it('should decode handler response with OfcSignPayloadResponse codec', async function () { @@ -90,7 +96,11 @@ describe('Sign an arbitrary payload with trading account key', function () { payload, }, } as unknown as ExpressApiRouteRequest<'express.ofc.signPayload', 'post'>; + const result = await handleV2OFCSignPayload(req); + decodeOrElse('OfcSignPayloadResponse200', OfcSignPayloadResponse[200], result, (_) => { + throw new Error(`Response did not match expected codec`); + }); result.should.eql(expected); OfcSignPayloadResponse[200].is(result).should.be.true(); });