From 26a5c2fe1d8fd7429abf24fdb8a0ff03d1f0c733 Mon Sep 17 00:00:00 2001 From: Egge Date: Wed, 17 Jan 2024 06:44:14 +0100 Subject: [PATCH 1/3] raw token receive --- src/CashuWallet.ts | 12 +++++++++--- test/wallet.test.ts | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 890e4e7c..459f1bc3 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -16,6 +16,7 @@ import { SerializedBlindedMessage, SerializedBlindedSignature, SplitPayload, + Token, TokenEntry } from './model/types/index.js'; import { @@ -170,15 +171,20 @@ class CashuWallet { * @returns New token with newly created proofs, token entries that had errors, and newKeys if they have changed */ async receive( - encodedToken: string, + token: string | Token, preference?: Array, counter?: number ): Promise { - const { token } = cleanToken(getDecodedToken(encodedToken)); + let decodedToken: Array; + if (typeof token === 'string') { + decodedToken = cleanToken(getDecodedToken(token)).token; + } else { + decodedToken = token.token; + } const tokenEntries: Array = []; const tokenEntriesWithError: Array = []; let newKeys: MintKeys | undefined; - for (const tokenEntry of token) { + for (const tokenEntry of decodedToken) { if (!tokenEntry?.proofs?.length) { continue; } diff --git a/test/wallet.test.ts b/test/wallet.test.ts index 6bd0873d..a3b83744 100644 --- a/test/wallet.test.ts +++ b/test/wallet.test.ts @@ -2,6 +2,7 @@ import { decode } from '@gandlaf21/bolt11-decode'; import nock from 'nock'; import { CashuMint } from '../src/CashuMint.js'; import { CashuWallet } from '../src/CashuWallet.js'; +import { cleanToken, getDecodedToken } from '../src/utils.js'; const dummyKeysResp = { 1: '02f970b6ee058705c0dddc4313721cffb7efd3d142d96ea8e01d31c2b2ff09f181' }; const mintUrl = 'https://legend.lnbits.com/cashu/api/v1/4gr9Xcmz3XEkUNwiBiQGoC'; @@ -35,7 +36,7 @@ describe('test fees', () => { describe('receive', () => { const tokenInput = 'eyJwcm9vZnMiOlt7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifV0sIm1pbnRzIjpbeyJ1cmwiOiJodHRwczovL2xlZ2VuZC5sbmJpdHMuY29tL2Nhc2h1L2FwaS92MS80Z3I5WGNtejNYRWtVTndpQmlRR29DIiwiaWRzIjpbIi91WUIvNndXbllrVSJdfV19'; - test('test receive', async () => { + test('test receive encoded token', async () => { nock(mintUrl) .post('/split') .reply(200, { @@ -61,6 +62,36 @@ describe('receive', () => { expect(/[A-Za-z0-9+/]{43}=/.test(t.token[0].proofs[0].secret)).toBe(true); expect(tokensWithErrors).toBe(undefined); }); + + test('test receive raw token', async () => { + const decodedInput = cleanToken(getDecodedToken(tokenInput)); + + nock(mintUrl) + .post('/split') + .reply(200, { + promises: [ + { + id: 'z32vUtKgNCm1', + amount: 1, + C_: '021179b095a67380ab3285424b563b7aab9818bd38068e1930641b3dceb364d422' + } + ] + }); + const wallet = new CashuWallet(mint); + + + const { token: t, tokensWithErrors } = await wallet.receive(decodedInput); + + expect(t.token).toHaveLength(1); + expect(t.token[0].proofs).toHaveLength(1); + expect(t.token[0]).toMatchObject({ + proofs: [{ amount: 1, id: 'z32vUtKgNCm1' }], + mint: 'https://legend.lnbits.com/cashu/api/v1/4gr9Xcmz3XEkUNwiBiQGoC' + }); + expect(/[0-9a-f]{64}/.test(t.token[0].proofs[0].C)).toBe(true); + expect(/[A-Za-z0-9+/]{43}=/.test(t.token[0].proofs[0].secret)).toBe(true); + expect(tokensWithErrors).toBe(undefined); + }); test('test receive custom split', async () => { nock(mintUrl) .post('/split') @@ -84,6 +115,7 @@ describe('receive', () => { ] }); const wallet = new CashuWallet(mint); + const token3sat = 'eyJwcm9vZnMiOlt7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifSx7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifSx7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifV0sIm1pbnRzIjpbeyJ1cmwiOiJodHRwczovL2xlZ2VuZC5sbmJpdHMuY29tL2Nhc2h1L2FwaS92MS80Z3I5WGNtejNYRWtVTndpQmlRR29DIiwiaWRzIjpbIi91WUIvNndXbllrVSJdfV19'; const { token: t, tokensWithErrors } = await wallet.receive(token3sat, [ From cd1068b1f60e1dec9a31e4c8760f4df8e88dfd03 Mon Sep 17 00:00:00 2001 From: Egge Date: Wed, 17 Jan 2024 10:11:02 +0100 Subject: [PATCH 2/3] updated jsDoc --- src/CashuWallet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CashuWallet.ts b/src/CashuWallet.ts index 459f1bc3..8953ab8d 100644 --- a/src/CashuWallet.ts +++ b/src/CashuWallet.ts @@ -164,8 +164,8 @@ class CashuWallet { return this.payLnInvoice(invoice, proofs, undefined, counter); } /** - * Receive an encoded Cashu token - * @param encodedToken Cashu token + * Receive an encoded or raw Cashu token + * @param {(string|Token)} token - Cashu token * @param preference optional preference for splitting proofs into specific amounts * @param counter? optionally set counter to derive secret deterministically. CashuWallet class must be initialized with seed phrase to take effect * @returns New token with newly created proofs, token entries that had errors, and newKeys if they have changed From c53e79470252534949571d947f38807832e06fd1 Mon Sep 17 00:00:00 2001 From: gandlaf21 Date: Thu, 18 Jan 2024 12:03:09 +0900 Subject: [PATCH 3/3] format --- src/index.ts | 2 +- test/wallet.test.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index afe3b8a7..a321c040 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import { CashuWallet } from './CashuWallet.js'; import { setGlobalRequestOptions } from './request.js'; import { generateNewMnemonic, deriveSeedFromMnemonic } from './secrets.js'; import { getEncodedToken, getDecodedToken, deriveKeysetId, decodeInvoice } from './utils.js'; -import { decode} from '@gandlaf21/bolt11-decode'; +import { decode } from '@gandlaf21/bolt11-decode'; export * from './model/types/index.js'; diff --git a/test/wallet.test.ts b/test/wallet.test.ts index a3b83744..7f0d0599 100644 --- a/test/wallet.test.ts +++ b/test/wallet.test.ts @@ -79,7 +79,6 @@ describe('receive', () => { }); const wallet = new CashuWallet(mint); - const { token: t, tokensWithErrors } = await wallet.receive(decodedInput); expect(t.token).toHaveLength(1); @@ -115,7 +114,6 @@ describe('receive', () => { ] }); const wallet = new CashuWallet(mint); - const token3sat = 'eyJwcm9vZnMiOlt7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifSx7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifSx7ImlkIjoiL3VZQi82d1duWWtVIiwiYW1vdW50IjoxLCJzZWNyZXQiOiJBZmtRYlJYQUc1UU1tT3ArbG9vRzQ2OXBZWTdiaStqbEcxRXRDT2tIa2hZPSIsIkMiOiIwMmY4NWRkODRiMGY4NDE4NDM2NmNiNjkxNDYxMDZhZjdjMGYyNmYyZWUwYWQyODdhM2U1ZmE4NTI1MjhiYjI5ZGYifV0sIm1pbnRzIjpbeyJ1cmwiOiJodHRwczovL2xlZ2VuZC5sbmJpdHMuY29tL2Nhc2h1L2FwaS92MS80Z3I5WGNtejNYRWtVTndpQmlRR29DIiwiaWRzIjpbIi91WUIvNndXbllrVSJdfV19'; const { token: t, tokensWithErrors } = await wallet.receive(token3sat, [