diff --git a/src/CashuMint.ts b/src/CashuMint.ts index 32ded58a..804a7400 100644 --- a/src/CashuMint.ts +++ b/src/CashuMint.ts @@ -12,7 +12,7 @@ import { SplitResponse } from './model/types/index.js'; import request from './request.js'; -import { isObj } from './utils.js'; +import { isObj, joinUrls } from './utils.js'; /** * Class represents Cashu Mint API. This class contains Lower level functions that are implemented by CashuWallet. @@ -31,7 +31,7 @@ class CashuMint { * @param mintUrl */ public static async getInfo(mintUrl: string): Promise { - return request({ endpoint: `${mintUrl}/info` }); + return request({ endpoint: joinUrls(mintUrl, 'info') }); } /** * fetches mints info at the /info endpoint @@ -46,7 +46,9 @@ class CashuMint { * @returns the mint will create and return a Lightning invoice for the specified amount */ public static async requestMint(mintUrl: string, amount: number): Promise { - return request({ endpoint: `${mintUrl}/mint?amount=${amount}` }); + return request({ + endpoint: `${joinUrls(mintUrl, 'mint')}?amount=${amount}` + }); } /** @@ -70,7 +72,7 @@ class CashuMint { hash: string ) { const data = await request<{ promises: Array }>({ - endpoint: `${mintUrl}/mint?hash=${hash}`, + endpoint: `${joinUrls(mintUrl, 'mint')}?hash=${hash}`, method: 'POST', requestBody: payloads }); @@ -102,7 +104,7 @@ class CashuMint { keysetId = keysetId.replace(/\//g, '_').replace(/\+/g, '-'); } return request({ - endpoint: `${mintUrl}/keys${keysetId ? `/${keysetId}` : ''}` + endpoint: keysetId ? joinUrls(mintUrl, 'keys', keysetId) : joinUrls(mintUrl, 'keys') }); } /** @@ -119,7 +121,7 @@ class CashuMint { * @returns all the mints past and current keysets. */ public static async getKeySets(mintUrl: string): Promise<{ keysets: Array }> { - return request<{ keysets: Array }>({ endpoint: `${mintUrl}/keysets` }); + return request<{ keysets: Array }>({ endpoint: joinUrls(mintUrl, 'keysets') }); } /** @@ -138,7 +140,7 @@ class CashuMint { */ public static async split(mintUrl: string, splitPayload: SplitPayload): Promise { const data = await request({ - endpoint: `${mintUrl}/split`, + endpoint: joinUrls(mintUrl, 'split'), method: 'POST', requestBody: splitPayload }); @@ -165,7 +167,7 @@ class CashuMint { */ public static async melt(mintUrl: string, meltPayload: MeltPayload): Promise { const data = await request({ - endpoint: `${mintUrl}/melt`, + endpoint: joinUrls(mintUrl, 'melt'), method: 'POST', requestBody: meltPayload }); @@ -199,7 +201,7 @@ class CashuMint { checkfeesPayload: { pr: string } ): Promise<{ fee: number }> { const data = await request<{ fee: number }>({ - endpoint: `${mintUrl}/checkfees`, + endpoint: joinUrls(mintUrl, 'checkfees'), method: 'POST', requestBody: checkfeesPayload }); @@ -230,7 +232,7 @@ class CashuMint { checkPayload: CheckSpendablePayload ): Promise { const data = await request({ - endpoint: `${mintUrl}/check`, + endpoint: joinUrls(mintUrl, 'check'), method: 'POST', requestBody: checkPayload }); diff --git a/src/utils.ts b/src/utils.ts index dd0f9c6d..c9e0f381 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -131,6 +131,11 @@ export function checkResponse(data: { error?: string; detail?: string }) { throw new Error(data.detail); } } + +export function joinUrls(...parts: string[]): string { + return parts.map((part) => part.replace(/(^\/+|\/+$)/g, '')).join('/'); +} + export { hexToNumber, splitAmount, diff --git a/test/utils.test.ts b/test/utils.test.ts index 3fdbfcd9..2fc5bc52 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -256,4 +256,14 @@ describe('test cleanToken', () => { expect(result.token[0].proofs[1].id).toBe('I2yN+iRYfkzT'); expect(result.token[0].proofs[2].id).toBe('test'); }); + test('testing joining urls', () => { + const mint_url = 'https://8333.space:3338'; + const info_url = utils.joinUrls(mint_url, 'info'); + + expect(info_url).toBe('https://8333.space:3338/info'); + + const mint_url_trailing_slash = 'https://8333.space:3338/'; + const mint_info_url = utils.joinUrls(mint_url_trailing_slash, 'info'); + expect(mint_info_url).toBe('https://8333.space:3338/info'); + }); });