From fad3ff4ab88f2d13ca17e38b784c088dba2d38aa Mon Sep 17 00:00:00 2001 From: "kody.low" Date: Thu, 21 Mar 2024 13:36:22 -0700 Subject: [PATCH] chore: tests script for fedimint-ts --- wrappers/fedimint-ts/FedimintClient.ts | 222 +++++++++++---------- wrappers/fedimint-ts/test.ts | 109 ++++++++++ wrappers/fedimint-ts/types/modules/ln.ts | 58 +++--- wrappers/fedimint-ts/types/modules/mint.ts | 97 +++------ 4 files changed, 279 insertions(+), 207 deletions(-) create mode 100644 wrappers/fedimint-ts/test.ts diff --git a/wrappers/fedimint-ts/FedimintClient.ts b/wrappers/fedimint-ts/FedimintClient.ts index ac89cff..86ea6ac 100644 --- a/wrappers/fedimint-ts/FedimintClient.ts +++ b/wrappers/fedimint-ts/FedimintClient.ts @@ -7,13 +7,11 @@ import type { } from "./types/common"; import type { AwaitInvoiceRequest, - AwaitLnPayRequest, Gateway, LnInvoiceRequest, LnInvoiceResponse, LnPayRequest, LnPayResponse, - SwitchGatewayRequest, } from "./types/modules/ln"; import type { CombineRequest, @@ -92,7 +90,7 @@ class FedimintClient { private activeFederationId: string; constructor(baseUrl: string, password: string, activeFederationId: string) { - this.baseUrl = baseUrl + "/fedimint/v2"; + this.baseUrl = baseUrl + "/v2"; this.password = password; this.activeFederationId = activeFederationId; } @@ -211,12 +209,10 @@ class FedimintClient { * Returns an array of federation IDs that the client is now connected to */ public async join( - inviteCode: string, - setDefault: boolean + inviteCode: string ): FedimintResponse { return await this.post("/admin/join", { inviteCode, - setDefault, }); } @@ -224,9 +220,11 @@ class FedimintClient { * Outputs a list of operations that have been performed on the federation */ public async listOperations( - request: ListOperationsRequest, + limit: number, federationId?: string ): FedimintResponse { + const request: ListOperationsRequest = { limit }; + return await this.postWithId( "/admin/list-operations", request, @@ -242,170 +240,190 @@ class FedimintClient { * Creates a lightning invoice to receive payment via gateway */ createInvoice: async ( - request: LnInvoiceRequest, + amountMsat: number, + description: string, + expiryTime?: number, federationId?: string - ): FedimintResponse => - await this.postWithId( + ): FedimintResponse => { + const request: LnInvoiceRequest = { amountMsat, description, expiryTime }; + + return await this.postWithId( "/ln/invoice", request, federationId - ), + ); + }, /** * Waits for a lightning invoice to be paid */ awaitInvoice: async ( - request: AwaitInvoiceRequest, + operationId: string, federationId?: string - ): FedimintResponse => - await this.postWithId( + ): FedimintResponse => { + const request: AwaitInvoiceRequest = { operationId }; + + return await this.postWithId( "/ln/await-invoice", request, federationId - ), + ); + }, /** * Pays a lightning invoice or lnurl via a gateway */ pay: async ( - request: LnPayRequest, + paymentInfo: string, + amountMsat?: number, + lnurlComment?: string, federationId?: string - ): FedimintResponse => - await this.postWithId("/ln/pay", request, federationId), - - /** - * Waits for a lightning payment to complete - */ - awaitPay: async ( - request: AwaitLnPayRequest, - federationId?: string - ): FedimintResponse => - await this.postWithId( - "/ln/await-pay", + ): FedimintResponse => { + const request: LnPayRequest = { + paymentInfo, + amountMsat, + lnurlComment, + }; + + return await this.postWithId( + "/ln/pay", request, federationId - ), + ); + }, /** * Outputs a list of registered lighting lightning gateways */ listGateways: async (): FedimintResponse => await this.postWithId("/ln/list-gateways", {}), - - /** - * Switches the active lightning gateway - */ - switchGateway: async ( - request: SwitchGatewayRequest, - federationId?: string - ): FedimintResponse => - await this.postWithId( - "/ln/switch-gateway", - request, - federationId - ), }; /** - * A module for creating a bitcoin deposit address + * A module for interacting with an ecash mint */ - public wallet = { + public mint = { /** - * Creates a new bitcoin deposit address + * Reissues an ecash note */ - createDepositAddress: async ( - request: DepositAddressRequest, + reissue: async ( + notes: string, federationId?: string - ): FedimintResponse => - await this.postWithId( - "/wallet/deposit-address", + ): FedimintResponse => { + const request: ReissueRequest = { notes }; + + return await this.postWithId( + "/mint/reissue", request, federationId - ), + ); + }, /** - * Waits for a bitcoin deposit to be confirmed + * Spends an ecash note */ - awaitDeposit: async ( - request: AwaitDepositRequest, + spend: async ( + amountMsat: number, + allowOverpay: boolean, + timeout: number, federationId?: string - ): FedimintResponse => - await this.postWithId( - "/wallet/await-deposit", + ): FedimintResponse => { + const request: SpendRequest = { amountMsat, allowOverpay, timeout }; + + return await this.postWithId( + "/mint/spend", request, federationId - ), + ); + }, /** - * Withdraws bitcoin from the federation + * Validates an ecash note */ - withdraw: async ( - request: WithdrawRequest, + validate: async ( + notes: string, federationId?: string - ): FedimintResponse => - await this.postWithId( - "/wallet/withdraw", + ): FedimintResponse => { + const request: ValidateRequest = { notes }; + + return await this.postWithId( + "/mint/validate", request, federationId - ), + ); + }, + + /** + * Splits an ecash note into smaller notes + */ + split: async (notes: string): FedimintResponse => { + const request: SplitRequest = { notes }; + + return await this.post("/mint/split", request); + }, + + /** + * Combines ecash notes + */ + combine: async (notesVec: string[]): FedimintResponse => { + const request: CombineRequest = { notesVec }; + + return await this.post("/mint/combine", request); + }, }; /** - * A module for interacting with an ecash mint + * A module for onchain bitcoin operations */ - public mint = { + public onchain = { /** - * Reissues an ecash note + * Creates a new bitcoin deposit address */ - reissue: async ( - request: ReissueRequest, + createDepositAddress: async ( + timeout: number, federationId?: string - ): FedimintResponse => - await this.postWithId( - "/mint/reissue", + ): FedimintResponse => { + const request: DepositAddressRequest = { timeout }; + + return await this.postWithId( + "/wallet/deposit-address", request, federationId - ), + ); + }, /** - * Spends an ecash note + * Waits for a bitcoin deposit to be confirmed */ - spend: async ( - request: SpendRequest, + awaitDeposit: async ( + operationId: string, federationId?: string - ): FedimintResponse => - await this.postWithId( - "/mint/spend", + ): FedimintResponse => { + const request: AwaitDepositRequest = { operationId }; + + return await this.postWithId( + "/wallet/await-deposit", request, federationId - ), + ); + }, /** - * Validates an ecash note + * Withdraws bitcoin from the federation */ - validate: async ( - request: ValidateRequest, + withdraw: async ( + address: string, + amountMsat: number | "all", federationId?: string - ): FedimintResponse => - await this.postWithId( - "/mint/validate", + ): FedimintResponse => { + const request: WithdrawRequest = { address, amountMsat }; + + return await this.postWithId( + "/wallet/withdraw", request, federationId - ), - - /** - * Splits an ecash note - */ - split: async (request: SplitRequest): FedimintResponse => - await this.post("/mint/split", request), - - /** - * Combines ecash notes - */ - combine: async ( - request: CombineRequest - ): FedimintResponse => - await this.post("/mint/combine", request), + ); + }, }; } diff --git a/wrappers/fedimint-ts/test.ts b/wrappers/fedimint-ts/test.ts new file mode 100644 index 0000000..8179038 --- /dev/null +++ b/wrappers/fedimint-ts/test.ts @@ -0,0 +1,109 @@ +import { FedimintClientBuilder } from "./FedimintClient"; +import dotenv from "dotenv"; + +dotenv.config(); + +const logMethodInputAndOutput = (method: string, input: any, output: any) => { + console.log("--------------------"); + console.log(`Method: ${method}`); + console.log("Input: ", input); + console.log("Output: ", output); + console.log("--------------------\n\n"); +}; + +async function buildTestClient() { + const baseUrl = process.env.BASE_URL || "http://localhost:3333"; + const password = process.env.PASSWORD || "password"; + const builder = new FedimintClientBuilder(); + builder.setBaseUrl(baseUrl).setPassword(password).setActiveFederationId( + "412d2a9338ebeee5957382eb06eac07fa5235087b5a7d5d0a6e18c635394e9ed" // Fedi Alpha Mutinynet + ); + + return await builder.build(); +} + +// Runs through all of the methods in the Fedimint Client +async function main() { + const fedimintClient = await buildTestClient(); + + // ADMIN METHODS + // `/v2/admin/config` + let data = await fedimintClient.config(); + logMethodInputAndOutput("/admin/config", {}, data); + // `/v2/admin/discover-version` + data = await fedimintClient.discoverVersion(); + logMethodInputAndOutput("/admin/discover-version", {}, data); + // `/v2/admin/federation-ids + const { federationIds } = await fedimintClient.federationIds(); + logMethodInputAndOutput("/admin/federation-ids", {}, federationIds); + // `/v2/admin/info` + data = await fedimintClient.info(); + logMethodInputAndOutput("/admin/info", {}, data); + // `/v2/admin/join` + let inviteCode = + process.env.INVITE_CODE || + "fed11qgqrgvnhwden5te0v9k8q6rp9ekh2arfdeukuet595cr2ttpd3jhq6rzve6zuer9wchxvetyd938gcewvdhk6tcqqysptkuvknc7erjgf4em3zfh90kffqf9srujn6q53d6r056e4apze5cw27h75"; + data = await fedimintClient.join(inviteCode); + logMethodInputAndOutput("/admin/join", { inviteCode }, data); + // `/v2/admin/list-operations` + data = await fedimintClient.listOperations(10); + logMethodInputAndOutput("/admin/list-operations", { limit: 10 }, data); + + // LIGHTNING METHODS + // `/v2/ln/list-gateways` + data = await fedimintClient.ln.listGateways(); + logMethodInputAndOutput("/ln/list-gateways", {}, data); + // `/v2/ln/invoice` + let { operationId, invoice } = await fedimintClient.ln.createInvoice( + 10000, + "test" + ); + logMethodInputAndOutput( + "/ln/invoice", + { amountMsat: 10000, description: "test" }, + { operationId, invoice } + ); + // `/v2/ln/pay` + let payResponse = await fedimintClient.ln.pay(invoice); + logMethodInputAndOutput("/ln/pay", { paymentInfo: invoice }, payResponse); + // `/v2/ln/await-invoice` + data = await fedimintClient.ln.awaitInvoice(operationId); + logMethodInputAndOutput("/ln/await-invoice", { operationId }, data); + + // MINT METHODS + // `/v2/mint/spend` + let mintData = await fedimintClient.mint.spend(3000, true, 1000); + logMethodInputAndOutput( + "/mint/spend", + { amountMsat: 3000, allowOverpay: true, timeout: 1000 }, + data + ); + // `/v2/mint/validate` + data = await fedimintClient.mint.validate(mintData.notes); + logMethodInputAndOutput("/mint/validate", { notes: mintData.notes }, data); + // `/v2/mint/reissue` + data = await fedimintClient.mint.reissue(mintData.notes); + logMethodInputAndOutput("/mint/reissue", { notes: mintData.notes }, data); + // `/v2/mint/split` + data = await fedimintClient.mint.split(mintData.notes); + logMethodInputAndOutput("/mint/split", { notes: mintData.notes }, data); + // `/v2/mint/combine` + const notesVec = Object.values(data.notes) as string[]; + data = await fedimintClient.mint.combine(notesVec); + logMethodInputAndOutput("/mint/combine", { notesVec }, data); + + // ONCHAIN METHODS + // `/v2/onchain/deposit-address` + data = await fedimintClient.onchain.createDepositAddress(1000); + logMethodInputAndOutput("/onchain/deposit-address", { timeout: 1000 }, data); + // `/v2/onchain/await-deposit` + data = await fedimintClient.onchain.awaitDeposit(data.operationId); + logMethodInputAndOutput( + "/onchain/await-deposit", + { operationId: data.operationId }, + data + ); + // `/v2/onchain/withdraw` +} + +main().catch(console.error); diff --git a/wrappers/fedimint-ts/types/modules/ln.ts b/wrappers/fedimint-ts/types/modules/ln.ts index ab44599..3c244d7 100644 --- a/wrappers/fedimint-ts/types/modules/ln.ts +++ b/wrappers/fedimint-ts/types/modules/ln.ts @@ -1,57 +1,51 @@ interface LnInvoiceRequest { - amountMsat: number; - description: string; - expiryTime?: number; + amountMsat: number; + description: string; + expiryTime?: number; } interface LnInvoiceResponse { - operationId: string; - invoice: string; + operationId: string; + invoice: string; } interface AwaitInvoiceRequest { - operationId: string; + operationId: string; } interface LnPayRequest { - paymentInfo: string; - amountMsat?: number; - finishInBackground: boolean; - lnurlComment?: string; + paymentInfo: string; + amountMsat?: number; + lnurlComment?: string; } interface LnPayResponse { - operationId: string; - paymentType: string; - contractId: string; - fee: number; -} - -interface AwaitLnPayRequest { - operationId: string; + operationId: string; + paymentType: string; + contractId: string; + fee: number; } interface Gateway { - nodePubKey: string; - active: boolean; + nodePubKey: string; + active: boolean; } interface ListGatewaysResponse { - [federationId: string]: Gateway[]; + [federationId: string]: Gateway[]; } interface SwitchGatewayRequest { - gatewayId: string; + gatewayId: string; } export type { - LnInvoiceRequest, - LnInvoiceResponse, - AwaitInvoiceRequest, - LnPayRequest, - LnPayResponse, - AwaitLnPayRequest, - Gateway, - ListGatewaysResponse, - SwitchGatewayRequest, -} + LnInvoiceRequest, + LnInvoiceResponse, + AwaitInvoiceRequest, + LnPayRequest, + LnPayResponse, + Gateway, + ListGatewaysResponse, + SwitchGatewayRequest, +}; diff --git a/wrappers/fedimint-ts/types/modules/mint.ts b/wrappers/fedimint-ts/types/modules/mint.ts index 6e08ea4..1eb0f6f 100644 --- a/wrappers/fedimint-ts/types/modules/mint.ts +++ b/wrappers/fedimint-ts/types/modules/mint.ts @@ -1,106 +1,57 @@ -interface FederationIdPrefix { - 0: number; // Assuming u8 is equivalent to number in TypeScript - 1: number; - 2: number; - 3: number; -} - -interface TieredMulti { - [amount: number]: T[]; // Assuming Amount is equivalent to number in TypeScript -} - -interface Signature { - 0: G1Affine; -} - -interface G1Affine { - x: Fp; - y: Fp; - infinity: Choice; -} - -interface Fp { - 0: number[]; // Assuming u64 is equivalent to number in TypeScript -} - -interface Choice { - 0: number; // Assuming u8 is equivalent to number in TypeScript -} - -interface KeyPair { - 0: number[]; // Assuming c_uchar is equivalent to number in TypeScript -} - -interface OOBNotesData { - Notes?: TieredMulti; - FederationIdPrefix?: FederationIdPrefix; - Default?: { - variant: number; // Assuming u64 is equivalent to number in TypeScript - bytes: number[]; // Assuming Vec is equivalent to number[] in TypeScript - }; -} - -interface OOBNotes { - 0: OOBNotesData[]; -} - -interface SpendableNote { - signature: Signature; - spendKey: KeyPair; -} +type FederationIdPrefix = string; interface ReissueRequest { - notes: string; + notes: string; } interface ReissueResponse { - amountMsat: number; + amountMsat: number; } interface SpendRequest { - amountMsat: number; - allowOverpay: boolean; - timeout: number; + amountMsat: number; + allowOverpay: boolean; + timeout: number; } interface SpendResponse { - operation: string; - notes: string; + operation: string; + notes: string; } interface ValidateRequest { - notes: string; + notes: string; } interface ValidateResponse { - amountMsat: number; + amountMsat: number; } interface SplitRequest { - notes: OOBNotes; + notes: string; } interface SplitResponse { - notes: Record; + notes: Record; } interface CombineRequest { - notes: string; + notesVec: string[]; } interface CombineResponse { - notes: string; + notes: string; } export type { - ReissueRequest, - ReissueResponse, - SpendRequest, - SpendResponse, - ValidateRequest, - ValidateResponse, - SplitRequest, - SplitResponse, - CombineRequest, - CombineResponse, + ReissueRequest, + ReissueResponse, + SpendRequest, + SpendResponse, + ValidateRequest, + ValidateResponse, + SplitRequest, + SplitResponse, + CombineRequest, + CombineResponse, };