From 117ba2211687dcec3bae4568bc0ad0fc992fdd96 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Mon, 15 May 2023 07:29:36 +0200 Subject: [PATCH 1/7] ts docs --- .gitignore | 1 + src/CashuMint.ts | 106 +++++++++++++++- src/CashuWallet.ts | 83 +++++++++++- src/model/types/index.ts | 264 ++++++++++++++++++++++++++++++++++++--- src/utils.ts | 10 +- 5 files changed, 436 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 5de02b14..ce92d0ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coverage dist +docs node_modules \ No newline at end of file diff --git a/src/CashuMint.ts b/src/CashuMint.ts index 57255ba4..3ce2afaa 100644 --- a/src/CashuMint.ts +++ b/src/CashuMint.ts @@ -16,30 +16,59 @@ import { import { checkResponse, checkResponseError, isObj } from './utils.js'; /** - * Class represents Cashu Mint API. + * Class represents Cashu Mint API. This class contains Lower level functions that are implemented by CashuWallet. */ class CashuMint { + /** + * @param _mintUrl requires mint URL to create this object + */ constructor(private _mintUrl: string) {} + get mintUrl() { return this._mintUrl; } - + /** + * fetches mints info at the /info endpoint + * @param mintUrl + */ public static async getInfo(mintUrl: string): Promise { const { data } = await axios.get(`${mintUrl}/info`); return data; } + /** + * fetches mints info at the /info endpoint + */ async getInfo(): Promise { return CashuMint.getInfo(this._mintUrl); } + /** + * Starts a minting process by requesting an invoice from the mint + * @param mintUrl + * @param amount Amount requesting for mint. + * @returns the mint will create and return a Lightning invoice for the specified amount + */ public static async requestMint(mintUrl: string, amount: number): Promise { const { data } = await axios.get(`${mintUrl}/mint`, { params: { amount } }); return data; } + + /** + * Starts a minting process by requesting an invoice from the mint + * @param amount Amount requesting for mint. + * @returns the mint will create and return a Lightning invoice for the specified amount + */ async requestMint(amount: number): Promise { return CashuMint.requestMint(this._mintUrl, amount); } + /** + * Requests the mint to perform token minting after the LN invoice has been paid + * @param mintUrl + * @param payloads outputs (Blinded messages) that can be written + * @param hash hash (id) used for by the mint to keep track of wether the invoice has been paid yet + * @returns serialized blinded signatures + */ public static async mint( mintUrl: string, payloads: { outputs: Array }, @@ -67,9 +96,21 @@ class CashuMint { throw err; } } + /** + * Requests the mint to perform token minting after the LN invoice has been paid + * @param payloads outputs (Blinded messages) that can be written + * @param hash hash (id) used for by the mint to keep track of wether the invoice has been paid yet + * @returns serialized blinded signatures + */ async mint(payloads: { outputs: Array }, hash: string) { return CashuMint.mint(this._mintUrl, payloads, hash); } + /** + * Get the mints public keys + * @param mintUrl + * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched + * @returns + */ public static async getKeys(mintUrl: string, keysetId?: string): Promise { if (keysetId) { // make the keysetId url safe @@ -78,16 +119,38 @@ class CashuMint { const { data } = await axios.get(`${mintUrl}/keys${keysetId ? `/${keysetId}` : ''}`); return data; } + /** + * Get the mints public keys + * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched + * @returns the mints public keys + */ async getKeys(keysetId?: string): Promise { return CashuMint.getKeys(this._mintUrl, keysetId); } + /** + * Get the mints keysets in no specific order + * @param mintUrl + * @returns all the mints past and current keysets. + */ public static async getKeySets(mintUrl: string): Promise<{ keysets: Array }> { const { data } = await axios.get<{ keysets: Array }>(`${mintUrl}/keysets`); return data; } + + /** + * Get the mints keysets in no specific order + * @returns all the mints past and current keysets. + */ async getKeySets(): Promise<{ keysets: Array }> { return CashuMint.getKeySets(this._mintUrl); } + + /** + * Ask mint to perform a split operation + * @param mintUrl + * @param splitPayload data needed for performing a token split + * @returns split tokens + */ public static async split(mintUrl: string, splitPayload: SplitPayload): Promise { try { const { data } = await axios.post(`${mintUrl}/split`, splitPayload); @@ -101,9 +164,20 @@ class CashuMint { throw err; } } + /** + * Ask mint to perform a split operation + * @param splitPayload data needed for performing a token split + * @returns split tokens + */ async split(splitPayload: SplitPayload): Promise { return CashuMint.split(this._mintUrl, splitPayload); } + /** + * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees + * @param mintUrl + * @param meltPayload + * @returns + */ public static async melt(mintUrl: string, meltPayload: MeltPayload): Promise { try { const { data } = await axios.post(`${mintUrl}/melt`, meltPayload); @@ -121,9 +195,20 @@ class CashuMint { throw err; } } + /** + * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees + * @param meltPayload + * @returns + */ async melt(meltPayload: MeltPayload): Promise { return CashuMint.melt(this._mintUrl, meltPayload); } + /** + * Estimate fees for a given LN invoice + * @param mintUrl + * @param checkfeesPayload Payload containing LN invoice that needs to get a fee estimate + * @returns estimated Fee + */ public static async checkFees( mintUrl: string, checkfeesPayload: { pr: string } @@ -143,9 +228,21 @@ class CashuMint { throw err; } } + /** + * Estimate fees for a given LN invoice + * @param mintUrl + * @param checkfeesPayload Payload containing LN invoice that needs to get a fee estimate + * @returns estimated Fee + */ async checkFees(checkfeesPayload: { pr: string }): Promise<{ fee: number }> { return CashuMint.checkFees(this._mintUrl, checkfeesPayload); } + /** + * Checks if specific proofs have already been redeemed + * @param mintUrl + * @param checkPayload + * @returns redeemed and unredeemed ordered list of booleans + */ public static async check( mintUrl: string, checkPayload: CheckSpendablePayload @@ -162,6 +259,11 @@ class CashuMint { throw err; } } + /** + * Checks if specific proofs have already been redeemed + * @param checkPayload + * @returns redeemed and unredeemed ordered list of booleans + */ async check(checkPayload: CheckSpendablePayload): Promise { return CashuMint.check(this._mintUrl, checkPayload); } diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 70bf0fe3..ef400e77 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -21,6 +21,7 @@ import { cleanToken, deriveKeysetId, getDecodedToken, splitAmount } from './util /** * Class that represents a Cashu wallet. + * This class should act as the entry point for this library */ class CashuWallet { private _keys: MintKeys; @@ -63,7 +64,11 @@ class CashuWallet { const { spendable } = await this.mint.check(payload); return proofs.filter((_, i) => !spendable[i]); } - + /** + * Starts a minting process by requesting an invoice from the mint + * @param amount Amount requesting for mint. + * @returns the mint will create and return a Lightning invoice for the specified amount + */ requestMint(amount: number) { return this.mint.requestMint(amount); } @@ -74,7 +79,6 @@ class CashuWallet { * @param invoice * @param proofsToSend the exact amount to send including fees * @param feeReserve? optionally set LN routing fee reserve. If not set, fee reserve will get fetched at mint - * @returns */ async payLnInvoice( invoice: string, @@ -96,7 +100,11 @@ class CashuWallet { newKeys: await this.changedKeys(payData?.change) }; } - + /** + * Estimate fees for a given LN invoice + * @param invoice LN invoice that needs to get a fee estimate + * @returns estimated Fee + */ async getFee(invoice: string): Promise { const { fee } = await this.mint.checkFees({ pr: invoice }); return fee; @@ -108,7 +116,11 @@ class CashuWallet { proofs: proofs }; } - + /** + * Use a cashu token to pay an ln invoice + * @param invoice Lightning invoice + * @param token cashu token + */ payLnInvoiceWithToken(invoice: string, token: string): Promise { const decodedToken = getDecodedToken(token); const proofs = decodedToken.token @@ -116,7 +128,11 @@ class CashuWallet { .flatMap((t) => t.proofs); return this.payLnInvoice(invoice, proofs); } - + /** + * Receive an encoded Cashu token + * @param encodedToken Cashu token + * @returns New token with newly created proofs, token entries that had errors, and newKeys if they have changed + */ async receive(encodedToken: string): Promise { const { token } = cleanToken(getDecodedToken(encodedToken)); const tokenEntries: Array = []; @@ -152,6 +168,57 @@ class CashuWallet { }; } + /** + * Receive a single cashu token entry + * @param tokenEntry a single entry of a cashu token + * @returns New token entry with newly created proofs, proofs that had errors, and newKeys if they have changed + */ + private async receiveTokenEntry(tokenEntry: TokenEntry): Promise { + const proofsWithError: Array = []; + const proofs: Array = []; + let newKeys: MintKeys | undefined; + try { + const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0); + const { payload, amount1BlindedMessages, amount2BlindedMessages } = this.createSplitPayload( + 0, + amount, + tokenEntry.proofs + ); + const { fst, snd } = await CashuMint.split(tokenEntry.mint, payload); + const proofs1 = dhke.constructProofs( + fst, + amount1BlindedMessages.rs, + amount1BlindedMessages.secrets, + await this.getKeys(fst, tokenEntry.mint) + ); + const proofs2 = dhke.constructProofs( + snd, + amount2BlindedMessages.rs, + amount2BlindedMessages.secrets, + await this.getKeys(snd, tokenEntry.mint) + ); + proofs.push(...proofs1, ...proofs2); + newKeys = + tokenEntry.mint === this.mint.mintUrl + ? await this.changedKeys([...(fst || []), ...(snd || [])]) + : undefined; + } catch (error) { + console.error(error); + proofsWithError.push(...tokenEntry.proofs); + } + return { + proofs, + proofsWithError: proofsWithError.length ? proofsWithError : undefined, + newKeys + }; + } + + /** + * Splits and creates sendable tokens + * @param amount amount to send + * @param proofs proofs matching that amount + * @returns promise of the change- and send-proofs + */ async send(amount: number, proofs: Array): Promise { let amountAvailable = 0; const proofsToSend: Array = []; @@ -208,6 +275,7 @@ class CashuWallet { newKeys: await this.changedKeys(promises) }; } +<<<<<<< HEAD async receiveTokenEntry(tokenEntry: TokenEntry): Promise { const proofsWithError: Array = []; @@ -248,6 +316,9 @@ class CashuWallet { newKeys }; } +======= + +>>>>>>> ts docs private async initKeys() { if (!this.keysetId || !Object.keys(this.keys).length) { @@ -298,7 +369,7 @@ class CashuWallet { const amount1BlindedMessages = this.createRandomBlindedMessages(amount1); const amount2BlindedMessages = this.createRandomBlindedMessages(amount2); const allBlindedMessages: Array = []; - // the order of this array aparently matters if it's the other way around, + // the order of this array apparently matters if it's the other way around, // the mint complains that the split is not as expected allBlindedMessages.push(...amount1BlindedMessages.blindedMessages); allBlindedMessages.push(...amount2BlindedMessages.blindedMessages); diff --git a/src/model/types/index.ts b/src/model/types/index.ts index 51c06ca1..bbfdb158 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -1,64 +1,202 @@ +/** + * represents a single Cashu proof. + */ export type Proof = { + /** + * Keyset id, used to link proofs to a mint an its MintKeys. + */ id: string; + /** + * Amount denominated in Satoshis. Has to match the amount of the mints signing key. + */ amount: number; + /** + * The initial secret that was (randomly) chosen for the creation of this proof. + */ secret: string; + /** + * The unblinded signature for this secret, signed by the mints private key. + */ C: string; }; -export type BlindedMessageData = { - blindedMessages: Array; - secrets: Array; - rs: Array; -}; + + +/** + * A mints publickey-set. + */ export type MintKeys = { [k: number]: string }; + +/** + * response when after receiving a single TokenEntry + */ export type ReceiveTokenEntryResponse = { + /** + * Received proofs + */ proofs: Array; + /** + * Proofs that could not be received. Doesn't throw an error, but if this field is populated it should be handled by the implementation accordingly + */ proofsWithError: Array | undefined; + /** + * If the mint has rotated keys, this field will be populated with the new keys. + */ newKeys?: MintKeys; }; -export type PaymentPayload = { pr: string; proofs: Array }; +/** + * response after sending + */ export type SendResponse = { + /** + * Proofs that exceeded the needed amount + */ returnChange: Array; + /** + * Proofs to be sent, matching the chosen amount + */ send: Array; + /** + * If the mint has rotated keys, this field will be populated with the new keys. + */ newKeys?: MintKeys; }; +/** + * Response when receiving a complete token. + */ export type ReceiveResponse = { + /** + * Successfully received Cashu Token + */ token: Token; + /** + * TokenEntries that had errors. No error will be thrown, but clients can choose to handle tokens with errors accordingly. + */ tokensWithErrors: Token | undefined; - newKeys?: MintKeys; -}; -export type PayLnInvoiceResponse = { - isPaid: boolean; - preimage: string | null; - change: Array; + /** + * If the mint has rotated keys, this field will be populated with the new keys. + */ newKeys?: MintKeys; }; + +/** + * Payload that needs to be sent to the mint when paying a lightning invoice. + */ +export type PaymentPayload = { + /** + * Payment request/Lighting invoice that should get paid by the mint. + */ + pr: string; + /** + * Proofs, matching Lightning invoices amount + fees. + */ + proofs: Array }; + +/** + * Payload that needs to be sent to the mint when melting. Includes Return for overpaid fees + */ export type MeltPayload = { + /** + * Payment request/Lighting invoice that should get paid by the mint. + */ pr: string; + /** + * Proofs, matching Lightning invoices amount + fees. + */ proofs: Array; + /** + * Blank outputs (blinded messages) that can be filled by the mint to return overpaid fees + */ outputs: Array; }; +/** + * Response from the mint after paying a lightning invoice (melt) + */ export type MeltResponse = { + /** + * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs + */ paid: boolean; + /** + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + */ preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ change?: Array; } & ApiError; +/** + * Response after paying a Lightning invoice + */ +export type PayLnInvoiceResponse = { + /** + * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs + */ + isPaid: boolean; + /** + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + */ + preimage: string | null; + /** + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + */ + change: Array; + /** + * If the mint has rotated keys, this field will be populated with the new keys. + */ + newKeys?: MintKeys; +}; + +/** + * Payload that needs to be sent to the mint when performing a split action + */ export type SplitPayload = { + /** + * Proofs to be split + */ proofs: Array; + /** + * Amount that needs to be split from the total amount provided (in proofs) + */ amount: number; + /** + * Fresh blinded messages to be signed by the mint to create the split proofs + */ outputs: Array; }; - +/** + * Response from the mint after performing a split action + */ export type SplitResponse = { + /** + * represents the left-over amount after the split + */ fst: Array; + /** + * represents the specified amount when splitting + */ snd: Array; } & ApiError; + +/** + * Cashu api error + */ export type ApiError = { + /** + * Error message + */ error?: string; + /** + * HTTP error code + */ code?: number; + /** + * Detailed error message + */ detail?: string; }; @@ -67,43 +205,135 @@ export type RequestMintResponse = { hash: string; } & ApiError; +/** + * Payload that needs to be sent to the mint when checking for spendable proofs + */ export type CheckSpendablePayload = { + /** + * array of proofs. Only the secret is strictly needed. + * If the whole object is passed, it will be stripped of other objects before sending it to the mint. + */ proofs: Array<{ secret: string }>; }; -export type CheckSpendableResponse = { spendable: Array } & ApiError; +/** + * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. + */ +export type CheckSpendableResponse = { + /** + * Ordered list for checked proofs. True if the secret has not been redeemed at the mint before + */ + spendable: Array + } & ApiError; +/** + * blinded message for sending to the mint + */ export type SerializedBlindedMessage = { + /** + * amount + */ amount: number; + /** + * Blinded message + */ B_: string; }; - +/** + * Blinded signature as it is received from the mint + */ export type SerializedBlindedSignature = { + /** + * keyset id for indicating which public key was used to sign the blinded message + */ id: string; + /** + * Amount denominated in Satoshi + */ amount: number; + /** + * Blinded signature + */ C_: string; }; +/** + * A Cashu token + */ export type Token = { + /** + * token entries + */ token: Array; + /** + * a message to send along with the token + */ memo?: string; }; - +/** + * TokenEntry that stores proofs and mints + */ export type TokenEntry = { + /** + * a list of proofs + */ proofs: Array; + /** + * the mints URL + */ mint: string; }; - +/** + * @deprecated Token V2 + * should no longer be used + */ export type TokenV2 = { proofs: Array; mints: Array<{ url: string; ids: Array }>; }; +/** + * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. + */ export type BlindedTransaction = { + /** + * Blinded messages sent to the mint for signing. + */ blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ rs: Array; + /** + * amounts denominated in Satoshi + */ amounts: Array; }; + +/** + * Data that the library needs to hold in memory while it awaits the blinded signatures for the mint. It is later used for unblinding the signatures. + */ +export type BlindedMessageData = { + /** + * Blinded messages sent to the mint for signing. + */ + blindedMessages: Array; + /** + * secrets, kept client side for constructing proofs later. + */ + secrets: Array; + /** + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + */ + rs: Array; +}; + +/** + * Response from mint at /info endpoint + */ export type GetInfoResponse = { name: string; pubkey: string; diff --git a/src/utils.ts b/src/utils.ts index b7b6498f..4a4c3b39 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -31,15 +31,19 @@ function bigIntStringify(_key: unknown, value: T) { } /** - * to encode a v3 token - * @param proofs - * @param mints + * Helper function to encode a v3 cashu token + * @param token * @returns */ function getEncodedToken(token: Token): string { return TOKEN_PREFIX + TOKEN_VERSION + encodeJsonToBase64(token); } +/** + * Helper function to decode cashu tokens into object + * @param token an encoded cashu token (cashuAey...) + * @returns cashu token object + */ function getDecodedToken(token: string): Token { // remove prefixes const uriPrefixes = ['web+cashu://', 'cashu://', 'cashu:', 'cashuA']; From 186cc0d925017996f74af105e103a04e18571c8a Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Mon, 15 May 2023 07:41:53 +0200 Subject: [PATCH 2/7] add workflow --- .github/workflows/typedoc.yml | 31 ++++++ package-lock.json | 180 ++++++++++++++++++++++++++++++++++ package.json | 1 + src/axios.ts | 4 + src/utils.ts | 6 +- 5 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/typedoc.yml diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml new file mode 100644 index 00000000..ea3aa62e --- /dev/null +++ b/.github/workflows/typedoc.yml @@ -0,0 +1,31 @@ +name: Generate and Deploy Typedoc + +on: + push: + branches: + - docs # Modify this if your main branch has a different name + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 # Adjust the version based on your project + + - name: Install dependencies + run: npm install + + - name: Generate Typedoc + run: npm run typedoc + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index aab4a578..5adbee3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "ts-jest": "^29.1.0", "ts-jest-resolver": "^2.0.1", "ts-node": "^10.9.1", + "typedoc": "^0.24.7", "typescript": "^5.0.4" } }, @@ -1732,6 +1733,12 @@ "node": ">=8" } }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "dev": true + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4684,6 +4691,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -4754,6 +4767,12 @@ "yallist": "^3.0.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -4784,6 +4803,18 @@ "tmpl": "1.0.5" } }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -5464,6 +5495,18 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz", + "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -5919,6 +5962,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typedoc": { + "version": "0.24.7", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.7.tgz", + "integrity": "sha512-zzfKDFIZADA+XRIp2rMzLe9xZ6pt12yQOhCr7cD7/PBTjhPmMyMvGrkZ2lPNJitg3Hj1SeiYFNzCsSDrlpxpKw==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.0", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 14.14" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" + } + }, + "node_modules/typedoc/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", @@ -6008,6 +6096,18 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -7447,6 +7547,12 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, + "ansi-sequence-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", + "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -9583,6 +9689,12 @@ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -9641,6 +9753,12 @@ "yallist": "^3.0.2" } }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -9665,6 +9783,12 @@ "tmpl": "1.0.5" } }, + "marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -10127,6 +10251,18 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shiki": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz", + "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==", + "dev": true, + "requires": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10447,6 +10583,38 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, + "typedoc": { + "version": "0.24.7", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.7.tgz", + "integrity": "sha512-zzfKDFIZADA+XRIp2rMzLe9xZ6pt12yQOhCr7cD7/PBTjhPmMyMvGrkZ2lPNJitg3Hj1SeiYFNzCsSDrlpxpKw==", + "dev": true, + "requires": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.0", + "shiki": "^0.14.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", + "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", @@ -10509,6 +10677,18 @@ } } }, + "vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/package.json b/package.json index 60272ef9..cb9cc639 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "ts-jest": "^29.1.0", "ts-jest-resolver": "^2.0.1", "ts-node": "^10.9.1", + "typedoc": "^0.24.7", "typescript": "^5.0.4" }, "dependencies": { diff --git a/src/axios.ts b/src/axios.ts index e7c18158..dbf4ee8b 100644 --- a/src/axios.ts +++ b/src/axios.ts @@ -2,6 +2,10 @@ import * as _axios from 'axios'; import { CreateAxiosDefaults } from 'axios'; export let axios = _axios.default.create(); +/** + * Run axios with a custom config + * @param config custom config + */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function setupAxios(config?: CreateAxiosDefaults | undefined) { axios = _axios.default.create(config); diff --git a/src/utils.ts b/src/utils.ts index 4a4c3b39..ae5b0902 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -76,7 +76,11 @@ function handleTokens(token: string): Token { // if v2 token return v3 format return { token: [{ proofs: obj.proofs, mint: obj?.mints[0]?.url ?? '' }] }; } - +/** + * Returns the keyset id of a set of keys + * @param keys keys object to derive keyset id from + * @returns + */ export function deriveKeysetId(keys: MintKeys) { const pubkeysConcat = Object.entries(keys) .sort((a, b) => +a[0] - +b[0]) From 1f36a17eb955b54f5697ba526f33a1a145480e91 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Mon, 15 May 2023 07:43:58 +0200 Subject: [PATCH 3/7] add missing script --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index cb9cc639..0f315db8 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "test": "jest --coverage", "dev": "tsc --watch", "lint": "eslint --ext .js,.ts . --fix", - "format": "prettier --write ." + "format": "prettier --write .", + "typedoc": "typedoc src/index.ts" + }, "keywords": [ "cashu" From c26ad1228442ccd32816d002f594df9e7cecc697 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Tue, 16 May 2023 08:46:44 +0200 Subject: [PATCH 4/7] change typedoc branch to main --- .github/workflows/typedoc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml index ea3aa62e..db211b47 100644 --- a/.github/workflows/typedoc.yml +++ b/.github/workflows/typedoc.yml @@ -3,7 +3,7 @@ name: Generate and Deploy Typedoc on: push: branches: - - docs # Modify this if your main branch has a different name + - main jobs: build: @@ -16,7 +16,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v3 with: - node-version: 18 # Adjust the version based on your project + node-version: 18 - name: Install dependencies run: npm install From 8c2f4c51e3f272f31a8c293f44e41cb9832a09c3 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Tue, 16 May 2023 08:53:30 +0200 Subject: [PATCH 5/7] run checks only on pull request --- .github/workflows/node.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 9a85d728..22d5e49d 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -3,7 +3,7 @@ name: Node.js CI -on: [push, pull_request] +on: [pull_request] jobs: build: From ad235e13e69defe1eab5a5bb3d44e906088681a6 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Tue, 16 May 2023 08:54:06 +0200 Subject: [PATCH 6/7] format --- .github/workflows/typedoc.yml | 2 +- package.json | 1 - src/CashuMint.ts | 64 +++++++++++++++++------------------ src/CashuWallet.ts | 5 ++- src/model/types/index.ts | 51 ++++++++++++++-------------- src/utils.ts | 8 ++--- 6 files changed, 66 insertions(+), 65 deletions(-) diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml index db211b47..4c65222d 100644 --- a/.github/workflows/typedoc.yml +++ b/.github/workflows/typedoc.yml @@ -28,4 +28,4 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs \ No newline at end of file + publish_dir: ./docs diff --git a/package.json b/package.json index 0f315db8..b7396830 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "lint": "eslint --ext .js,.ts . --fix", "format": "prettier --write .", "typedoc": "typedoc src/index.ts" - }, "keywords": [ "cashu" diff --git a/src/CashuMint.ts b/src/CashuMint.ts index 3ce2afaa..9646bddf 100644 --- a/src/CashuMint.ts +++ b/src/CashuMint.ts @@ -16,20 +16,20 @@ import { import { checkResponse, checkResponseError, isObj } from './utils.js'; /** - * Class represents Cashu Mint API. This class contains Lower level functions that are implemented by CashuWallet. + * Class represents Cashu Mint API. This class contains Lower level functions that are implemented by CashuWallet. */ class CashuMint { /** * @param _mintUrl requires mint URL to create this object */ constructor(private _mintUrl: string) {} - + get mintUrl() { return this._mintUrl; } /** * fetches mints info at the /info endpoint - * @param mintUrl + * @param mintUrl */ public static async getInfo(mintUrl: string): Promise { const { data } = await axios.get(`${mintUrl}/info`); @@ -43,8 +43,8 @@ class CashuMint { } /** * Starts a minting process by requesting an invoice from the mint - * @param mintUrl - * @param amount Amount requesting for mint. + * @param mintUrl + * @param amount Amount requesting for mint. * @returns the mint will create and return a Lightning invoice for the specified amount */ public static async requestMint(mintUrl: string, amount: number): Promise { @@ -56,7 +56,7 @@ class CashuMint { /** * Starts a minting process by requesting an invoice from the mint - * @param amount Amount requesting for mint. + * @param amount Amount requesting for mint. * @returns the mint will create and return a Lightning invoice for the specified amount */ async requestMint(amount: number): Promise { @@ -64,8 +64,8 @@ class CashuMint { } /** * Requests the mint to perform token minting after the LN invoice has been paid - * @param mintUrl - * @param payloads outputs (Blinded messages) that can be written + * @param mintUrl + * @param payloads outputs (Blinded messages) that can be written * @param hash hash (id) used for by the mint to keep track of wether the invoice has been paid yet * @returns serialized blinded signatures */ @@ -98,7 +98,7 @@ class CashuMint { } /** * Requests the mint to perform token minting after the LN invoice has been paid - * @param payloads outputs (Blinded messages) that can be written + * @param payloads outputs (Blinded messages) that can be written * @param hash hash (id) used for by the mint to keep track of wether the invoice has been paid yet * @returns serialized blinded signatures */ @@ -107,9 +107,9 @@ class CashuMint { } /** * Get the mints public keys - * @param mintUrl - * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched - * @returns + * @param mintUrl + * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched + * @returns */ public static async getKeys(mintUrl: string, keysetId?: string): Promise { if (keysetId) { @@ -121,16 +121,16 @@ class CashuMint { } /** * Get the mints public keys - * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched - * @returns the mints public keys + * @param keysetId optional param to get the keys for a specific keyset. If not specified, the keys from the active keyset are fetched + * @returns the mints public keys */ async getKeys(keysetId?: string): Promise { return CashuMint.getKeys(this._mintUrl, keysetId); } /** * Get the mints keysets in no specific order - * @param mintUrl - * @returns all the mints past and current keysets. + * @param mintUrl + * @returns all the mints past and current keysets. */ public static async getKeySets(mintUrl: string): Promise<{ keysets: Array }> { const { data } = await axios.get<{ keysets: Array }>(`${mintUrl}/keysets`); @@ -139,7 +139,7 @@ class CashuMint { /** * Get the mints keysets in no specific order - * @returns all the mints past and current keysets. + * @returns all the mints past and current keysets. */ async getKeySets(): Promise<{ keysets: Array }> { return CashuMint.getKeySets(this._mintUrl); @@ -147,8 +147,8 @@ class CashuMint { /** * Ask mint to perform a split operation - * @param mintUrl - * @param splitPayload data needed for performing a token split + * @param mintUrl + * @param splitPayload data needed for performing a token split * @returns split tokens */ public static async split(mintUrl: string, splitPayload: SplitPayload): Promise { @@ -166,17 +166,17 @@ class CashuMint { } /** * Ask mint to perform a split operation - * @param splitPayload data needed for performing a token split + * @param splitPayload data needed for performing a token split * @returns split tokens */ async split(splitPayload: SplitPayload): Promise { return CashuMint.split(this._mintUrl, splitPayload); } /** - * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees - * @param mintUrl - * @param meltPayload - * @returns + * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees + * @param mintUrl + * @param meltPayload + * @returns */ public static async melt(mintUrl: string, meltPayload: MeltPayload): Promise { try { @@ -196,16 +196,16 @@ class CashuMint { } } /** - * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees - * @param meltPayload - * @returns + * Ask mint to perform a melt operation. This pays a lightning invoice and destroys tokens matching its amount + fees + * @param meltPayload + * @returns */ async melt(meltPayload: MeltPayload): Promise { return CashuMint.melt(this._mintUrl, meltPayload); } /** * Estimate fees for a given LN invoice - * @param mintUrl + * @param mintUrl * @param checkfeesPayload Payload containing LN invoice that needs to get a fee estimate * @returns estimated Fee */ @@ -230,7 +230,7 @@ class CashuMint { } /** * Estimate fees for a given LN invoice - * @param mintUrl + * @param mintUrl * @param checkfeesPayload Payload containing LN invoice that needs to get a fee estimate * @returns estimated Fee */ @@ -239,8 +239,8 @@ class CashuMint { } /** * Checks if specific proofs have already been redeemed - * @param mintUrl - * @param checkPayload + * @param mintUrl + * @param checkPayload * @returns redeemed and unredeemed ordered list of booleans */ public static async check( @@ -261,7 +261,7 @@ class CashuMint { } /** * Checks if specific proofs have already been redeemed - * @param checkPayload + * @param checkPayload * @returns redeemed and unredeemed ordered list of booleans */ async check(checkPayload: CheckSpendablePayload): Promise { diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index ef400e77..6bd6fc8b 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -66,7 +66,7 @@ class CashuWallet { } /** * Starts a minting process by requesting an invoice from the mint - * @param amount Amount requesting for mint. + * @param amount Amount requesting for mint. * @returns the mint will create and return a Lightning invoice for the specified amount */ requestMint(amount: number) { @@ -275,6 +275,7 @@ class CashuWallet { newKeys: await this.changedKeys(promises) }; } +<<<<<<< HEAD <<<<<<< HEAD async receiveTokenEntry(tokenEntry: TokenEntry): Promise { @@ -319,6 +320,8 @@ class CashuWallet { ======= >>>>>>> ts docs +======= +>>>>>>> format private async initKeys() { if (!this.keysetId || !Object.keys(this.keys).length) { diff --git a/src/model/types/index.ts b/src/model/types/index.ts index bbfdb158..f46c6575 100644 --- a/src/model/types/index.ts +++ b/src/model/types/index.ts @@ -1,5 +1,5 @@ /** - * represents a single Cashu proof. + * represents a single Cashu proof. */ export type Proof = { /** @@ -20,7 +20,6 @@ export type Proof = { C: string; }; - /** * A mints publickey-set. */ @@ -39,13 +38,13 @@ export type ReceiveTokenEntryResponse = { */ proofsWithError: Array | undefined; /** - * If the mint has rotated keys, this field will be populated with the new keys. + * If the mint has rotated keys, this field will be populated with the new keys. */ newKeys?: MintKeys; }; /** - * response after sending + * response after sending */ export type SendResponse = { /** @@ -57,7 +56,7 @@ export type SendResponse = { */ send: Array; /** - * If the mint has rotated keys, this field will be populated with the new keys. + * If the mint has rotated keys, this field will be populated with the new keys. */ newKeys?: MintKeys; }; @@ -74,16 +73,15 @@ export type ReceiveResponse = { */ tokensWithErrors: Token | undefined; /** - * If the mint has rotated keys, this field will be populated with the new keys. + * If the mint has rotated keys, this field will be populated with the new keys. */ newKeys?: MintKeys; }; - /** * Payload that needs to be sent to the mint when paying a lightning invoice. */ -export type PaymentPayload = { +export type PaymentPayload = { /** * Payment request/Lighting invoice that should get paid by the mint. */ @@ -91,7 +89,8 @@ export type PaymentPayload = { /** * Proofs, matching Lightning invoices amount + fees. */ - proofs: Array }; + proofs: Array; +}; /** * Payload that needs to be sent to the mint when melting. Includes Return for overpaid fees @@ -119,12 +118,12 @@ export type MeltResponse = { * if false, the proofs have not been invalidated and the payment can be tried later again with the same proofs */ paid: boolean; - /** - * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + /** + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses */ preimage: string | null; /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate */ change?: Array; } & ApiError; @@ -138,15 +137,15 @@ export type PayLnInvoiceResponse = { */ isPaid: boolean; /** - * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses + * preimage of the paid invoice. can be null, depending on which LN-backend the mint uses */ preimage: string | null; /** - * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate + * Return/Change from overpaid fees. This happens due to Lighting fee estimation being inaccurate */ change: Array; /** - * If the mint has rotated keys, this field will be populated with the new keys. + * If the mint has rotated keys, this field will be populated with the new keys. */ newKeys?: MintKeys; }; @@ -164,7 +163,7 @@ export type SplitPayload = { */ amount: number; /** - * Fresh blinded messages to be signed by the mint to create the split proofs + * Fresh blinded messages to be signed by the mint to create the split proofs */ outputs: Array; }; @@ -210,27 +209,27 @@ export type RequestMintResponse = { */ export type CheckSpendablePayload = { /** - * array of proofs. Only the secret is strictly needed. + * array of proofs. Only the secret is strictly needed. * If the whole object is passed, it will be stripped of other objects before sending it to the mint. */ proofs: Array<{ secret: string }>; }; /** - * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. + * Response when checking proofs if they are spendable. Should not rely on this for receiving, since it can be easily cheated. */ -export type CheckSpendableResponse = { +export type CheckSpendableResponse = { /** * Ordered list for checked proofs. True if the secret has not been redeemed at the mint before */ - spendable: Array - } & ApiError; + spendable: Array; +} & ApiError; /** * blinded message for sending to the mint */ export type SerializedBlindedMessage = { /** - * amount + * amount */ amount: number; /** @@ -239,7 +238,7 @@ export type SerializedBlindedMessage = { B_: string; }; /** - * Blinded signature as it is received from the mint + * Blinded signature as it is received from the mint */ export type SerializedBlindedSignature = { /** @@ -304,7 +303,7 @@ export type BlindedTransaction = { */ secrets: Array; /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. */ rs: Array; /** @@ -326,13 +325,13 @@ export type BlindedMessageData = { */ secrets: Array; /** - * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. + * Blinding factor used for blinding messages and unblinding signatures after they are received from the mint. */ rs: Array; }; /** - * Response from mint at /info endpoint + * Response from mint at /info endpoint */ export type GetInfoResponse = { name: string; diff --git a/src/utils.ts b/src/utils.ts index ae5b0902..1ebc2a4b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -32,7 +32,7 @@ function bigIntStringify(_key: unknown, value: T) { /** * Helper function to encode a v3 cashu token - * @param token + * @param token * @returns */ function getEncodedToken(token: Token): string { @@ -77,9 +77,9 @@ function handleTokens(token: string): Token { return { token: [{ proofs: obj.proofs, mint: obj?.mints[0]?.url ?? '' }] }; } /** - * Returns the keyset id of a set of keys - * @param keys keys object to derive keyset id from - * @returns + * Returns the keyset id of a set of keys + * @param keys keys object to derive keyset id from + * @returns */ export function deriveKeysetId(keys: MintKeys) { const pubkeysConcat = Object.entries(keys) From 61172f76a947495a120902d0b2892d1bfe008693 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Tue, 16 May 2023 09:55:25 +0200 Subject: [PATCH 7/7] resolve --- src/CashuWallet.ts | 49 +--------------------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 6bd6fc8b..c0c0a09a 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -173,7 +173,7 @@ class CashuWallet { * @param tokenEntry a single entry of a cashu token * @returns New token entry with newly created proofs, proofs that had errors, and newKeys if they have changed */ - private async receiveTokenEntry(tokenEntry: TokenEntry): Promise { + async receiveTokenEntry(tokenEntry: TokenEntry): Promise { const proofsWithError: Array = []; const proofs: Array = []; let newKeys: MintKeys | undefined; @@ -275,53 +275,6 @@ class CashuWallet { newKeys: await this.changedKeys(promises) }; } -<<<<<<< HEAD -<<<<<<< HEAD - - async receiveTokenEntry(tokenEntry: TokenEntry): Promise { - const proofsWithError: Array = []; - const proofs: Array = []; - let newKeys: MintKeys | undefined; - try { - const amount = tokenEntry.proofs.reduce((total, curr) => total + curr.amount, 0); - const { payload, amount1BlindedMessages, amount2BlindedMessages } = this.createSplitPayload( - 0, - amount, - tokenEntry.proofs - ); - const { fst, snd } = await CashuMint.split(tokenEntry.mint, payload); - const proofs1 = dhke.constructProofs( - fst, - amount1BlindedMessages.rs, - amount1BlindedMessages.secrets, - await this.getKeys(fst, tokenEntry.mint) - ); - const proofs2 = dhke.constructProofs( - snd, - amount2BlindedMessages.rs, - amount2BlindedMessages.secrets, - await this.getKeys(snd, tokenEntry.mint) - ); - proofs.push(...proofs1, ...proofs2); - newKeys = - tokenEntry.mint === this.mint.mintUrl - ? await this.changedKeys([...(fst || []), ...(snd || [])]) - : undefined; - } catch (error) { - console.error(error); - proofsWithError.push(...tokenEntry.proofs); - } - return { - proofs, - proofsWithError: proofsWithError.length ? proofsWithError : undefined, - newKeys - }; - } -======= - ->>>>>>> ts docs -======= ->>>>>>> format private async initKeys() { if (!this.keysetId || !Object.keys(this.keys).length) {