Skip to content

Commit

Permalink
Merge branch 'development' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
Egge21M committed Jul 16, 2024
2 parents 4909e39 + b99ad29 commit 3bd7cea
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 103 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Format Check

on: [push]

jobs:
tests:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Check format
run: npm run check-format
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,31 @@ const tokens = await wallet.mintTokens(64, mintQuote.quote);

Contributions are very welcome.

If you want to contribute, please open an Issue or a PR.
If you want to contribute, please open an Issue or a PR.
If you open a PR, please do so from the `development` branch as the base branch.

### Version

```
* `main`
|\
|\ \
| | * `hotfix`
| |
| * `staging`
| |\
| |\ \
| | | * `bugfix`
| | |
| | * `development`
| | |\
| | | * `feature1`
| | | |
| | |/
| | *
| | |\
| | | * `feature2`
| | |/
| |/
|/ (create new version)
```
4 changes: 2 additions & 2 deletions migration-1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ To reduce complexity, simplify error handling and to prepare for token V4, this

Utility functions now have an `options` object for optional parameters, instead of passing them directly

**`requestMint(amount: number)` --> `mintQuote(amount: number)`**
**`requestMint(amount: number)` --> `createMintQuote(amount: number)`**
Now returns the following:

```typescript
Expand All @@ -51,7 +51,7 @@ where `request` is the invoice to be paid, and `quote` is the identifier used to

---

**`getMeltQuote(invoice: string)`** is now used to get fee estimation and conversion quotes instead of `getFee()` and returns:
**`createMeltQuote(invoice: string)`** is now used to get fee estimation and conversion quotes instead of `getFee()` and returns:

```typescript
type MeltQuoteResponse = {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"dev": "tsc --watch",
"lint": "eslint --ext .js,.ts . --fix",
"format": "prettier --write .",
"check-format": "prettier --check .",
"typedoc": "typedoc src/index.ts"
},
"keywords": [
Expand Down
78 changes: 52 additions & 26 deletions src/CashuMint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type {
CheckStateResponse,
GetInfoResponse,
MeltPayload,
MeltResponse,
MintActiveKeys,
MintAllKeysets,
PostRestoreResponse,
Expand All @@ -16,11 +15,21 @@ import type {
MintResponse,
PostRestorePayload,
MeltQuotePayload,
MeltQuoteResponse
MeltQuoteResponse,
MintContactInfo
} from './model/types/index.js';
import { MeltQuoteState } from './model/types/index.js';
import request from './request.js';
import { isObj, joinUrls, sanitizeUrl } from './utils.js';

import {
MeltQuoteResponsePaidDeprecated,
handleMeltQuoteResponseDeprecated
} from './legacy/nut-05.js';
import {
MintQuoteResponsePaidDeprecated,
handleMintQuoteResponseDeprecated
} from './legacy/nut-04.js';
import { handleMintInfoContactFieldDeprecated } from './legacy/nut-06.js';
/**
* Class represents Cashu Mint API. This class contains Lower level functions that are implemented by CashuWallet.
*/
Expand Down Expand Up @@ -48,7 +57,11 @@ class CashuMint {
customRequest?: typeof request
): Promise<GetInfoResponse> {
const requestInstance = customRequest || request;
return requestInstance<GetInfoResponse>({ endpoint: joinUrls(mintUrl, '/v1/info') });
const response = await requestInstance<GetInfoResponse>({
endpoint: joinUrls(mintUrl, '/v1/info')
});
const data = handleMintInfoContactFieldDeprecated(response);
return data;
}
/**
* fetches mints info at the /info endpoint
Expand Down Expand Up @@ -98,25 +111,27 @@ class CashuMint {
* @param customRequest
* @returns the mint will create and return a new mint quote containing a payment request for the specified amount and unit
*/
public static async mintQuote(
public static async createMintQuote(
mintUrl: string,
mintQuotePayload: MintQuotePayload,
customRequest?: typeof request
): Promise<MintQuoteResponse> {
const requestInstance = customRequest || request;
return requestInstance<MintQuoteResponse>({
const response = await requestInstance<MintQuoteResponse & MintQuoteResponsePaidDeprecated>({
endpoint: joinUrls(mintUrl, '/v1/mint/quote/bolt11'),
method: 'POST',
requestBody: mintQuotePayload
});
const data = handleMintQuoteResponseDeprecated(response);
return data;
}
/**
* Requests a new mint quote from the mint.
* @param mintQuotePayload Payload for creating a new mint quote
* @returns the mint will create and return a new mint quote containing a payment request for the specified amount and unit
*/
async mintQuote(mintQuotePayload: MintQuotePayload): Promise<MintQuoteResponse> {
return CashuMint.mintQuote(this._mintUrl, mintQuotePayload, this._customRequest);
async createMintQuote(mintQuotePayload: MintQuotePayload): Promise<MintQuoteResponse> {
return CashuMint.createMintQuote(this._mintUrl, mintQuotePayload, this._customRequest);
}

/**
Expand All @@ -126,24 +141,27 @@ class CashuMint {
* @param customRequest
* @returns the mint will create and return a Lightning invoice for the specified amount
*/
public static async getMintQuote(
public static async checkMintQuote(
mintUrl: string,
quote: string,
customRequest?: typeof request
): Promise<MintQuoteResponse> {
const requestInstance = customRequest || request;
return requestInstance<MintQuoteResponse>({
const response = await requestInstance<MintQuoteResponse & MintQuoteResponsePaidDeprecated>({
endpoint: joinUrls(mintUrl, '/v1/mint/quote/bolt11', quote),
method: 'GET'
});

const data = handleMintQuoteResponseDeprecated(response);
return data;
}
/**
* Gets an existing mint quote from the mint.
* @param quote Quote ID
* @returns the mint will create and return a Lightning invoice for the specified amount
*/
async getMintQuote(quote: string): Promise<MintQuoteResponse> {
return CashuMint.getMintQuote(this._mintUrl, quote, this._customRequest);
async checkMintQuote(quote: string): Promise<MintQuoteResponse> {
return CashuMint.checkMintQuote(this._mintUrl, quote, this._customRequest);
}

/**
Expand Down Expand Up @@ -186,18 +204,20 @@ class CashuMint {
* @param MeltQuotePayload
* @returns
*/
public static async meltQuote(
public static async createMeltQuote(
mintUrl: string,
meltQuotePayload: MeltQuotePayload,
customRequest?: typeof request
): Promise<MeltQuoteResponse> {
const requestInstance = customRequest || request;
const data = await requestInstance<MeltQuoteResponse>({
const response = await requestInstance<MeltQuoteResponse & MeltQuoteResponsePaidDeprecated>({
endpoint: joinUrls(mintUrl, '/v1/melt/quote/bolt11'),
method: 'POST',
requestBody: meltQuotePayload
});

const data = handleMeltQuoteResponseDeprecated(response);

if (
!isObj(data) ||
typeof data?.amount !== 'number' ||
Expand All @@ -213,8 +233,8 @@ class CashuMint {
* @param MeltQuotePayload
* @returns
*/
async meltQuote(meltQuotePayload: MeltQuotePayload): Promise<MeltQuoteResponse> {
return CashuMint.meltQuote(this._mintUrl, meltQuotePayload, this._customRequest);
async createMeltQuote(meltQuotePayload: MeltQuotePayload): Promise<MeltQuoteResponse> {
return CashuMint.createMeltQuote(this._mintUrl, meltQuotePayload, this._customRequest);
}

/**
Expand All @@ -223,22 +243,26 @@ class CashuMint {
* @param quote Quote ID
* @returns
*/
public static async getMeltQuote(
public static async checkMeltQuote(
mintUrl: string,
quote: string,
customRequest?: typeof request
): Promise<MeltQuoteResponse> {
const requestInstance = customRequest || request;
const data = await requestInstance<MeltQuoteResponse>({
const response = await requestInstance<MeltQuoteResponse & MeltQuoteResponsePaidDeprecated>({
endpoint: joinUrls(mintUrl, '/v1/melt/quote/bolt11', quote),
method: 'GET'
});

const data = handleMeltQuoteResponseDeprecated(response);

if (
!isObj(data) ||
typeof data?.amount !== 'number' ||
typeof data?.fee_reserve !== 'number' ||
typeof data?.quote !== 'string'
typeof data?.quote !== 'string' ||
typeof data?.state !== 'string' ||
!Object.values(MeltQuoteState).includes(data.state)
) {
throw new Error('bad response');
}
Expand All @@ -250,8 +274,8 @@ class CashuMint {
* @param quote Quote ID
* @returns
*/
async getMeltQuote(quote: string): Promise<MeltQuoteResponse> {
return CashuMint.getMeltQuote(this._mintUrl, quote, this._customRequest);
async checkMeltQuote(quote: string): Promise<MeltQuoteResponse> {
return CashuMint.checkMeltQuote(this._mintUrl, quote, this._customRequest);
}

/**
Expand All @@ -265,18 +289,20 @@ class CashuMint {
mintUrl: string,
meltPayload: MeltPayload,
customRequest?: typeof request
): Promise<MeltResponse> {
): Promise<MeltQuoteResponse> {
const requestInstance = customRequest || request;
const data = await requestInstance<MeltResponse>({
const response = await requestInstance<MeltQuoteResponse & MeltQuoteResponsePaidDeprecated>({
endpoint: joinUrls(mintUrl, '/v1/melt/bolt11'),
method: 'POST',
requestBody: meltPayload
});

const data = handleMeltQuoteResponseDeprecated(response);

if (
!isObj(data) ||
typeof data?.paid !== 'boolean' ||
(data?.payment_preimage !== null && typeof data?.payment_preimage !== 'string')
typeof data?.state !== 'string' ||
!Object.values(MeltQuoteState).includes(data.state)
) {
throw new Error('bad response');
}
Expand All @@ -288,7 +314,7 @@ class CashuMint {
* @param meltPayload
* @returns
*/
async melt(meltPayload: MeltPayload): Promise<MeltResponse> {
async melt(meltPayload: MeltPayload): Promise<MeltQuoteResponse> {
return CashuMint.melt(this._mintUrl, meltPayload, this._customRequest);
}
/**
Expand Down
31 changes: 20 additions & 11 deletions src/CashuWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
type Token,
type TokenEntry,
CheckStateEnum,
SerializedBlindedSignature
SerializedBlindedSignature,
MeltQuoteState
} from './model/types/index.js';
import {
bytesToNumber,
Expand Down Expand Up @@ -102,6 +103,14 @@ class CashuWallet {
this._unit = keys.unit;
}

/**
* Get information about the mint
* @returns mint info
*/
async getMintInfo() {
return this.mint.getInfo();
}

/**
* Receive an encoded or raw Cashu token (only supports single tokens. It will only process the first token in the token array)
* @param {(string|Token)} token - Cashu token
Expand Down Expand Up @@ -332,21 +341,21 @@ class CashuWallet {
* @param amount Amount requesting for mint.
* @returns the mint will return a mint quote with a Lightning invoice for minting tokens of the specified amount and unit
*/
async mintQuote(amount: number) {
async createMintQuote(amount: number) {
const mintQuotePayload: MintQuotePayload = {
unit: this._unit,
amount: amount
};
return await this.mint.mintQuote(mintQuotePayload);
return await this.mint.createMintQuote(mintQuotePayload);
}

/**
* Gets an existing mint quote from the mint.
* @param quote Quote ID
* @returns the mint will create and return a Lightning invoice for the specified amount
*/
async getMintQuote(quote: string) {
return await this.mint.getMintQuote(quote);
async checkMintQuote(quote: string) {
return await this.mint.checkMintQuote(quote);
}

/**
Expand Down Expand Up @@ -388,12 +397,12 @@ class CashuWallet {
* @param invoice LN invoice that needs to get a fee estimate
* @returns the mint will create and return a melt quote for the invoice with an amount and fee reserve
*/
async meltQuote(invoice: string): Promise<MeltQuoteResponse> {
async createMeltQuote(invoice: string): Promise<MeltQuoteResponse> {
const meltQuotePayload: MeltQuotePayload = {
unit: this._unit,
request: invoice
};
const meltQuote = await this.mint.meltQuote(meltQuotePayload);
const meltQuote = await this.mint.createMeltQuote(meltQuotePayload);
return meltQuote;
}

Expand All @@ -402,8 +411,8 @@ class CashuWallet {
* @param quote ID of the melt quote
* @returns the mint will return an existing melt quote
*/
async getMeltQuote(quote: string): Promise<MeltQuoteResponse> {
const meltQuote = await this.mint.getMeltQuote(quote);
async checkMeltQuote(quote: string): Promise<MeltQuoteResponse> {
const meltQuote = await this.mint.checkMeltQuote(quote);
return meltQuote;
}

Expand Down Expand Up @@ -439,7 +448,7 @@ class CashuWallet {
const meltResponse = await this.mint.melt(meltPayload);

return {
isPaid: meltResponse.paid ?? false,
isPaid: meltResponse.state === MeltQuoteState.PAID,
preimage: meltResponse.payment_preimage,
change: meltResponse?.change
? this.constructProofs(meltResponse.change, rs, secrets, keys)
Expand Down Expand Up @@ -467,7 +476,7 @@ class CashuWallet {
}
): Promise<MeltTokensResponse> {
if (!meltQuote) {
meltQuote = await this.mint.meltQuote({ unit: this._unit, request: invoice });
meltQuote = await this.mint.createMeltQuote({ unit: this._unit, request: invoice });
}
return await this.meltTokens(meltQuote, proofsToSend, {
keysetId: options?.keysetId,
Expand Down
Loading

0 comments on commit 3bd7cea

Please sign in to comment.